framework7rails 4.0.0 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- {"version":3,"sources":["wrap-start.js","f7-intro.js","views.js","navbars.js","searchbar.js","messagebar.js","xhr.js","pages.js","router.js","modals.js","panels.js","lazy-load.js","messages.js","swipeout.js","sortable.js","smart-select.js","virtual-list.js","pull-to-refresh.js","infinite-scroll.js","scroll-toolbars.js","tabs.js","accordion.js","fast-clicks.js","clicks.js","resize.js","forms-handler.js","push-state.js","swiper-init.js","photo-browser.js","picker.js","calendar.js","notifications.js","template7-templates.js","plugins.js","init.js","f7-outro.js","dom7-intro.js","dom7-methods.js","dom7-ajax.js","dom7-utils.js","dom7-outro.js","proto-support.js","proto-device.js","proto-plugins.js","template7.js","swiper.js","wrap-end.js"],"names":[],"mappings":"AAAA;AACA;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7gBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClkCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5hBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClkBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9zBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrDA;AACA;AACA;AACA;AACA;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9qBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5QA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxGA;AACA;AACA;AACA;AACA;AACA;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC19DA;AACA","file":"framework7.js","sourcesContent":["(function () {\n"," 'use strict';\n /*===========================\n Framework 7\n ===========================*/\n window.Framework7 = function (params) {\n \n // App\n var app = this;\n \n // Version\n app.version = '1.0.0';\n \n // Default Parameters\n app.params = {\n cache: true,\n cacheIgnore: [],\n cacheIgnoreGetParameters: false,\n cacheDuration: 1000 * 60 * 10, // Ten minutes \n preloadPreviousPage: true,\n uniqueHistory: false,\n uniqueHistoryIgnoreGetParameters: false,\n dynamicPageUrl: 'content-{{index}}',\n allowDuplicateUrls: false,\n router: true,\n // Push State\n pushState: false,\n pushStateRoot: undefined,\n pushStateNoAnimation: false,\n pushStateSeparator: '#!/',\n // Fast clicks\n fastClicks: true,\n fastClicksDistanceThreshold: 0,\n fastClicksDelayBetweenClicks: 50,\n // Active State\n activeState: true,\n activeStateElements: 'a, button, label, span',\n // Animate Nav Back Icon\n animateNavBackIcon: false,\n // Swipe Back\n swipeBackPage: true,\n swipeBackPageThreshold: 0,\n swipeBackPageActiveArea: 30,\n swipeBackPageAnimateShadow: true,\n swipeBackPageAnimateOpacity: true,\n // Ajax\n ajaxLinks: undefined, // or CSS selector\n // External Links\n externalLinks: '.external', // CSS selector\n // Sortable\n sortable: true,\n // Scroll toolbars\n hideNavbarOnPageScroll: false,\n hideToolbarOnPageScroll: false,\n hideTabbarOnPageScroll: false,\n showBarsOnPageScrollEnd: true,\n // Swipeout\n swipeout: true,\n swipeoutActionsNoFold: false,\n swipeoutNoFollow: false,\n // Smart Select Back link template\n smartSelectBackTemplate: '<div class=\"left sliding\"><a href=\"#\" class=\"back link\"><i class=\"icon icon-back\"></i><span>{{backText}}</span></a></div>',\n smartSelectBackText: 'Back',\n smartSelectInPopup: false,\n smartSelectPopupCloseTemplate: '<div class=\"left\"><a href=\"#\" class=\"link close-popup\"><i class=\"icon icon-back\"></i><span>{{closeText}}</span></a></div>',\n smartSelectPopupCloseText: 'Close',\n smartSelectSearchbar: false,\n smartSelectBackOnSelect: false,\n // Searchbar\n searchbarHideDividers: true,\n searchbarHideGroups: true,\n // Tap Navbar or Statusbar to scroll to top\n scrollTopOnNavbarClick: false,\n scrollTopOnStatusbarClick: false,\n // Panels\n swipePanel: false, // or 'left' or 'right'\n swipePanelActiveArea: 0,\n swipePanelCloseOpposite: true,\n swipePanelOnlyClose: false,\n swipePanelNoFollow: false,\n swipePanelThreshold: 0,\n panelsCloseByOutside: true,\n // Modals\n modalButtonOk: 'OK',\n modalButtonCancel: 'Cancel',\n modalUsernamePlaceholder: 'Username',\n modalPasswordPlaceholder: 'Password',\n modalTitle: 'Framework7',\n modalCloseByOutside: false,\n actionsCloseByOutside: true,\n popupCloseByOutside: true,\n modalPreloaderTitle: 'Loading... ',\n modalStack: true,\n // Lazy Load\n imagesLazyLoadThreshold: 0,\n imagesLazyLoadSequential: true,\n // Name space\n viewClass: 'view',\n viewMainClass: 'view-main',\n viewsClass: 'views',\n // Notifications defaults\n notificationCloseOnClick: false,\n notificationCloseIcon: true,\n // Animate Pages\n animatePages: true,\n // Template7\n templates: {},\n template7Data: {},\n template7Pages: false,\n precompileTemplates: false,\n // Auto init\n init: true,\n };\n \n // Extend defaults with parameters\n for (var param in params) {\n app.params[param] = params[param];\n }\n \n // DOM lib\n var $ = Dom7;\n \n // Template7 lib\n var t7 = Template7;\n app._compiledTemplates = {};\n \n // Touch events\n app.touchEvents = {\n start: app.support.touch ? 'touchstart' : 'mousedown',\n move: app.support.touch ? 'touchmove' : 'mousemove',\n end: app.support.touch ? 'touchend' : 'mouseup'\n };\n \n // Link to local storage\n app.ls = localStorage;\n \n // RTL\n app.rtl = $('body').css('direction') === 'rtl';\n if (app.rtl) $('html').attr('dir', 'rtl');\n \n // Overwrite statusbar overlay\n if (typeof app.params.statusbarOverlay !== 'undefined') {\n if (app.params.statusbarOverlay) $('html').addClass('with-statusbar-overlay');\n else $('html').removeClass('with-statusbar-overlay');\n }\n \n \n \n"," /*======================================================\n ************ Views ************\n ======================================================*/\n app.views = [];\n var View = function (selector, params) {\n var defaults = {\n dynamicNavbar: false,\n domCache: false,\n linksView: undefined,\n reloadPages: false,\n uniqueHistory: app.params.uniqueHistory,\n uniqueHistoryIgnoreGetParameters: app.params.uniqueHistoryIgnoreGetParameters,\n allowDuplicateUrls: app.params.allowDuplicateUrls,\n swipeBackPage: app.params.swipeBackPage,\n swipeBackPageAnimateShadow: app.params.swipeBackPageAnimateShadow,\n swipeBackPageAnimateOpacity: app.params.swipeBackPageAnimateOpacity,\n swipeBackPageActiveArea: app.params.swipeBackPageActiveArea,\n swipeBackPageThreshold: app.params.swipeBackPageThreshold,\n animatePages: app.params.animatePages,\n preloadPreviousPage: app.params.preloadPreviousPage\n };\n var i;\n \n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n // View\n var view = this;\n view.params = params;\n \n // Selector\n view.selector = selector;\n \n // Container\n var container = $(selector);\n view.container = container[0];\n \n // Content cache\n view.contentCache = {};\n \n // Pages cache\n view.pagesCache = {};\n \n // Store View in element for easy access\n container[0].f7View = view;\n \n // Pages\n view.pagesContainer = container.find('.pages')[0];\n view.initialPages = [];\n view.initialNavbars = [];\n if (view.params.domCache) {\n var initialPages = container.find('.page');\n for (i = 0; i < initialPages.length; i++) {\n view.initialPages.push(initialPages[i]);\n }\n if (view.params.dynamicNavbar) {\n var initialNavbars = container.find('.navbar-inner');\n for (i = 0; i < initialNavbars.length; i++) {\n view.initialNavbars.push(initialNavbars[i]);\n }\n }\n \n }\n \n view.allowPageChange = true;\n \n // Location\n var docLocation = document.location.href;\n \n // History\n view.history = [];\n var viewURL = docLocation;\n var pushStateSeparator = app.params.pushStateSeparator;\n var pushStateRoot = app.params.pushStateRoot;\n if (app.params.pushState) {\n if (pushStateRoot) {\n viewURL = pushStateRoot;\n }\n else {\n if (viewURL.indexOf(pushStateSeparator) >= 0 && viewURL.indexOf(pushStateSeparator + '#') < 0) viewURL = viewURL.split(pushStateSeparator)[0];\n }\n \n }\n \n // Active Page\n var currentPage, currentPageData;\n if (!view.activePage) {\n currentPage = $(view.pagesContainer).find('.page-on-center');\n if (currentPage.length === 0) {\n currentPage = $(view.pagesContainer).find('.page:not(.cached)');\n currentPage = currentPage.eq(currentPage.length - 1);\n }\n if (currentPage.length > 0) {\n currentPageData = currentPage[0].f7PageData;\n }\n }\n \n // View startup URL\n if (view.params.domCache && currentPage) {\n view.url = container.attr('data-url') || view.params.url || '#' + currentPage.attr('data-page'); \n view.pagesCache[view.url] = currentPage.attr('data-page');\n }\n else view.url = container.attr('data-url') || view.params.url || viewURL;\n \n // Update current page Data\n if (currentPageData) {\n currentPageData.view = view;\n currentPageData.url = view.url;\n view.activePage = currentPageData;\n currentPage[0].f7PageData = currentPageData;\n }\n \n // Store to history main view's url\n if (view.url) {\n view.history.push(view.url);\n }\n \n // Is main\n view.main = container.hasClass(app.params.viewMainClass);\n \n // Touch events\n var isTouched = false,\n isMoved = false,\n touchesStart = {},\n isScrolling,\n activePage = [],\n previousPage = [],\n viewContainerWidth,\n touchesDiff,\n allowViewTouchMove = true,\n touchStartTime,\n activeNavbar = [],\n previousNavbar = [],\n activeNavElements,\n previousNavElements,\n activeNavBackIcon,\n previousNavBackIcon,\n dynamicNavbar,\n el;\n \n view.handleTouchStart = function (e) {\n if (!allowViewTouchMove || !view.params.swipeBackPage || isTouched || app.swipeoutOpenedEl) return;\n isMoved = false;\n isTouched = true;\n isScrolling = undefined;\n touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n dynamicNavbar = view.params.dynamicNavbar && container.find('.navbar-inner').length > 1;\n };\n \n view.handleTouchMove = function (e) {\n if (!isTouched) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));\n }\n if (isScrolling || e.f7PreventSwipeBack || app.preventSwipeBack) {\n isTouched = false;\n return;\n }\n \n if (!isMoved) {\n var cancel = false;\n // Calc values during first move fired\n viewContainerWidth = container.width();\n var target = $(e.target);\n var swipeout = target.hasClass('swipeout') ? target : target.parents('.swipeout');\n if (swipeout.length > 0) {\n if (!app.rtl && swipeout.find('.swipeout-actions-left').length > 0) cancel = true;\n if (app.rtl && swipeout.find('.swipeout-actions-right').length > 0) cancel = true;\n }\n activePage = target.is('.page') ? target : target.parents('.page');\n if (activePage.hasClass('no-swipeback')) cancel = true;\n previousPage = container.find('.page-on-left:not(.cached)');\n var notFromBorder = touchesStart.x - container.offset().left > view.params.swipeBackPageActiveArea;\n if (app.rtl) {\n notFromBorder = touchesStart.x < container.offset().left - container[0].scrollLeft + viewContainerWidth - view.params.swipeBackPageActiveArea;\n }\n else {\n notFromBorder = touchesStart.x - container.offset().left > view.params.swipeBackPageActiveArea;\n }\n if (notFromBorder) cancel = true;\n if (previousPage.length === 0 || activePage.length === 0) cancel = true;\n if (cancel) {\n isTouched = false;\n return;\n }\n if (dynamicNavbar) {\n activeNavbar = container.find('.navbar-on-center:not(.cached)');\n previousNavbar = container.find('.navbar-on-left:not(.cached)');\n activeNavElements = activeNavbar.find('.left, .center, .right, .subnavbar, .fading');\n previousNavElements = previousNavbar.find('.left, .center, .right, .subnavbar, .fading');\n if (app.params.animateNavBackIcon) {\n activeNavBackIcon = activeNavbar.find('.left.sliding .back .icon');\n previousNavBackIcon = previousNavbar.find('.left.sliding .back .icon');\n }\n }\n }\n e.f7PreventPanelSwipe = true;\n isMoved = true;\n e.preventDefault();\n \n // RTL inverter\n var inverter = app.rtl ? -1 : 1;\n \n // Touches diff\n touchesDiff = (pageX - touchesStart.x - view.params.swipeBackPageThreshold) * inverter;\n if (touchesDiff < 0) touchesDiff = 0;\n var percentage = touchesDiff / viewContainerWidth;\n \n // Swipe Back Callback\n var callbackData = {\n percentage: percentage,\n activePage: activePage[0],\n previousPage: previousPage[0],\n activeNavbar: activeNavbar[0],\n previousNavbar: previousNavbar[0]\n };\n if (view.params.onSwipeBackMove) {\n view.params.onSwipeBackMove(callbackData);\n }\n container.trigger('swipebackmove', callbackData);\n \n // Transform pages\n var activePageTranslate = touchesDiff * inverter;\n var previousPageTranslate = (touchesDiff / 5 - viewContainerWidth / 5) * inverter;\n if (app.device.pixelRatio === 1) {\n activePageTranslate = Math.round(activePageTranslate);\n previousPageTranslate = Math.round(previousPageTranslate);\n }\n \n activePage.transform('translate3d(' + activePageTranslate + 'px,0,0)');\n if (view.params.swipeBackPageAnimateShadow && app.device.os !== 'android') activePage[0].style.boxShadow = '0px 0px 12px rgba(0,0,0,' + (0.5 - 0.5 * percentage) + ')';\n \n previousPage.transform('translate3d(' + previousPageTranslate + 'px,0,0)');\n if (view.params.swipeBackPageAnimateOpacity) previousPage[0].style.opacity = 0.9 + 0.1 * percentage;\n \n // Dynamic Navbars Animation\n if (dynamicNavbar) {\n var i;\n for (i = 0; i < activeNavElements.length; i++) {\n el = $(activeNavElements[i]);\n if (!el.is('.subnavbar.sliding')) el[0].style.opacity = (1 - percentage * 1.3);\n if (el[0].className.indexOf('sliding') >= 0) {\n var activeNavTranslate = percentage * el[0].f7NavbarRightOffset;\n if (app.device.pixelRatio === 1) activeNavTranslate = Math.round(activeNavTranslate);\n el.transform('translate3d(' + activeNavTranslate + 'px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (el[0].className.indexOf('left') >= 0 && activeNavBackIcon.length > 0) {\n activeNavBackIcon.transform('translate3d(' + -activeNavTranslate + 'px,0,0)');\n }\n }\n }\n }\n for (i = 0; i < previousNavElements.length; i++) {\n el = $(previousNavElements[i]);\n if (!el.is('.subnavbar.sliding')) el[0].style.opacity = percentage * 1.3 - 0.3;\n if (el[0].className.indexOf('sliding') >= 0) {\n var previousNavTranslate = el[0].f7NavbarLeftOffset * (1 - percentage);\n if (app.device.pixelRatio === 1) previousNavTranslate = Math.round(previousNavTranslate);\n el.transform('translate3d(' + previousNavTranslate + 'px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (el[0].className.indexOf('left') >= 0 && previousNavBackIcon.length > 0) {\n previousNavBackIcon.transform('translate3d(' + -previousNavTranslate + 'px,0,0)');\n }\n }\n }\n }\n }\n };\n \n view.handleTouchEnd = function (e) {\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n isTouched = false;\n isMoved = false;\n if (touchesDiff === 0) {\n $([activePage[0], previousPage[0]]).transform('').css({opacity: '', boxShadow: ''});\n if (dynamicNavbar) {\n activeNavElements.transform('').css({opacity: ''});\n previousNavElements.transform('').css({opacity: ''});\n if (activeNavBackIcon && activeNavBackIcon.length > 0) activeNavBackIcon.transform('');\n if (previousNavBackIcon && activeNavBackIcon.length > 0) previousNavBackIcon.transform('');\n }\n return;\n }\n var timeDiff = (new Date()).getTime() - touchStartTime;\n var pageChanged = false;\n // Swipe back to previous page\n if (\n timeDiff < 300 && touchesDiff > 10 ||\n timeDiff >= 300 && touchesDiff > viewContainerWidth / 2\n ) {\n activePage.removeClass('page-on-center').addClass('page-on-right');\n previousPage.removeClass('page-on-left').addClass('page-on-center');\n if (dynamicNavbar) {\n activeNavbar.removeClass('navbar-on-center').addClass('navbar-on-right');\n previousNavbar.removeClass('navbar-on-left').addClass('navbar-on-center');\n }\n pageChanged = true;\n }\n // Reset custom styles\n // Add transitioning class for transition-duration\n $([activePage[0], previousPage[0]]).transform('').css({opacity: '', boxShadow: ''}).addClass('page-transitioning');\n if (dynamicNavbar) {\n activeNavElements.css({opacity: ''})\n .each(function () {\n var translate = pageChanged ? this.f7NavbarRightOffset : 0;\n var sliding = $(this);\n sliding.transform('translate3d(' + translate + 'px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && activeNavBackIcon.length > 0) {\n activeNavBackIcon.addClass('page-transitioning').transform('translate3d(' + -translate + 'px,0,0)');\n }\n }\n \n }).addClass('page-transitioning');\n \n previousNavElements.transform('').css({opacity: ''}).each(function () {\n var translate = pageChanged ? 0 : this.f7NavbarLeftOffset;\n var sliding = $(this);\n sliding.transform('translate3d(' + translate + 'px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && previousNavBackIcon.length > 0) {\n previousNavBackIcon.addClass('page-transitioning').transform('translate3d(' + -translate + 'px,0,0)');\n }\n }\n }).addClass('page-transitioning');\n }\n allowViewTouchMove = false;\n view.allowPageChange = false;\n \n if (pageChanged) {\n // Update View's URL\n var url = view.history[view.history.length - 2];\n view.url = url;\n \n // Page before animation callback\n app.pageBackCallbacks('before', view, {pageContainer: activePage[0], url: url, position: 'center', newPage: previousPage, oldPage: activePage, swipeBack: true});\n app.pageAnimCallbacks('before', view, {pageContainer: previousPage[0], url: url, position: 'left', newPage: previousPage, oldPage: activePage, swipeBack: true});\n }\n \n activePage.transitionEnd(function () {\n $([activePage[0], previousPage[0]]).removeClass('page-transitioning');\n if (dynamicNavbar) {\n activeNavElements.removeClass('page-transitioning').css({opacity: ''});\n previousNavElements.removeClass('page-transitioning').css({opacity: ''});\n if (activeNavBackIcon && activeNavBackIcon.length > 0) activeNavBackIcon.removeClass('page-transitioning');\n if (previousNavBackIcon && previousNavBackIcon.length > 0) previousNavBackIcon.removeClass('page-transitioning');\n }\n allowViewTouchMove = true;\n view.allowPageChange = true;\n if (pageChanged) {\n if (app.params.pushState) history.back();\n // Page after animation callback\n app.pageBackCallbacks('after', view, {pageContainer: activePage[0], url: url, position: 'center', newPage: previousPage, oldPage: activePage, swipeBack: true});\n app.pageAnimCallbacks('after', view, {pageContainer: previousPage[0], url: url, position: 'left', newPage: previousPage, oldPage: activePage, swipeBack: true});\n app.router.afterBack(view, activePage, previousPage);\n }\n });\n };\n view.attachEvents = function (detach) {\n var action = detach ? 'off' : 'on';\n container[action](app.touchEvents.start, view.handleTouchStart);\n container[action](app.touchEvents.move, view.handleTouchMove);\n container[action](app.touchEvents.end, view.handleTouchEnd);\n };\n view.detachEvents = function () {\n view.attachEvents(true);\n };\n \n // Init\n if (view.params.swipeBackPage) {\n view.attachEvents();\n }\n \n // Add view to app\n app.views.push(view);\n if (view.main) app.mainView = view;\n \n // Router \n view.router = {\n load: function (options) {\n return app.router.load(view, options);\n },\n back: function (options) {\n return app.router.back(view, options); \n },\n // Shortcuts\n loadPage: function (options) {\n options = options || {};\n if (typeof options === 'string') {\n var url = options;\n options = {};\n if (url && url.indexOf('#') === 0 && view.params.domCache) {\n options.pageName = url.split('#')[1];\n }\n else options.url = url;\n }\n return app.router.load(view, options);\n },\n loadContent: function (content) {\n return app.router.load(view, {content: content});\n },\n reloadPage: function (url) {\n return app.router.load(view, {url: url, reload: true});\n },\n reloadContent: function (content) {\n return app.router.load(view, {content: content, reload: true});\n },\n reloadPreviousPage: function (url) {\n return app.router.load(view, {url: url, reloadPrevious: true, reload: true});\n },\n reloadPreviousContent: function (content) {\n return app.router.load(view, {content: content, reloadPrevious: true, reload: true});\n },\n refreshPage: function () {\n var options = {\n url: view.url,\n reload: true,\n ignoreCache: true\n };\n if (options.url && options.url.indexOf('#') === 0) {\n if (view.params.domCache && view.pagesCache[options.url]) {\n options.pageName = view.pagesCache[options.url];\n options.url = undefined;\n delete options.url;\n }\n else if (view.contentCache[options.url]) {\n options.content = view.contentCache[options.url];\n options.url = undefined;\n delete options.url;\n }\n }\n return app.router.load(view, options);\n },\n refreshPreviousPage: function () {\n var options = {\n url: view.history[view.history.length - 2],\n reload: true,\n reloadPrevious: true,\n ignoreCache: true\n };\n if (options.url && options.url.indexOf('#') === 0 && view.params.domCache && view.pagesCache[options.url]) {\n options.pageName = view.pagesCache[options.url];\n options.url = undefined;\n delete options.url;\n }\n return app.router.load(view, options);\n }\n };\n \n // Aliases for temporary backward compatibility\n view.loadPage = view.router.loadPage;\n view.loadContent = view.router.loadContent;\n view.reloadPage = view.router.reloadPage;\n view.reloadContent = view.router.reloadContent;\n view.reloadPreviousPage = view.router.reloadPreviousPage;\n view.reloadPreviousContent = view.router.reloadPreviousContent;\n view.refreshPage = view.router.refreshPage;\n view.refreshPreviousPage = view.router.refreshPreviousPage;\n view.back = view.router.back;\n \n // Bars methods\n view.hideNavbar = function () {\n return app.hideNavbar(container.find('.navbar'));\n };\n view.showNavbar = function () {\n return app.showNavbar(container.find('.navbar'));\n };\n view.hideToolbar = function () {\n return app.hideToolbar(container.find('.toolbar'));\n };\n view.showToolbar = function () {\n return app.showToolbar(container.find('.toolbar'));\n };\n \n // Push State on load\n if (app.params.pushState && view.main) {\n var pushStateUrl;\n if (pushStateRoot) {\n pushStateUrl = docLocation.split(app.params.pushStateRoot + pushStateSeparator)[1];\n }\n else if (docLocation.indexOf(pushStateSeparator) >= 0 && docLocation.indexOf(pushStateSeparator + '#') < 0) {\n pushStateUrl = docLocation.split(pushStateSeparator)[1];\n }\n var pushStateAnimatePages = app.params.pushStateNoAnimation ? false : undefined;\n \n if (pushStateUrl) {\n app.router.load(view, {url: pushStateUrl, animatePages: pushStateAnimatePages, pushState: false});\n }\n else if (docLocation.indexOf(pushStateSeparator + '#') >= 0) {\n var state = history.state;\n if (state.pageName && 'viewIndex' in state) {\n app.router.load(view, {pageName: state.pageName, pushState: false});\n }\n }\n \n }\n \n // Destroy\n view.destroy = function () {\n view.detachEvents();\n view = undefined;\n };\n \n // Plugin hook\n app.pluginHook('addView', view);\n \n // Return view\n return view;\n };\n \n app.addView = function (selector, params) {\n return new View(selector, params);\n };\n \n"," /*======================================================\n ************ Navbars && Toolbars ************\n ======================================================*/\n // On Navbar Init Callback\n app.navbarInitCallback = function (view, pageContainer, navbar, navbarInnerContainer, url, position) {\n var _navbar = {\n container: navbar,\n innerContainer: navbarInnerContainer\n };\n var _page = {\n url: url,\n query: $.parseUrlQuery(url || ''),\n container: pageContainer,\n name: $(pageContainer).attr('data-page'),\n view: view,\n from: position\n };\n var eventData = {\n navbar: _navbar,\n page: _page\n };\n \n // Plugin hook\n app.pluginHook('navbarInit', _navbar, _page);\n \n // Navbar Init Callback\n $(navbarInnerContainer).trigger('navbarInit', eventData);\n };\n app.sizeNavbars = function (viewContainer) {\n var navbarInner = viewContainer ? $(viewContainer).find('.navbar .navbar-inner:not(.cached)') : $('.navbar .navbar-inner:not(.cached)');\n navbarInner.each(function () {\n var n = $(this);\n if (n.hasClass('cached')) return;\n var left = app.rtl ? n.find('.right') : n.find('.left'),\n right = app.rtl ? n.find('.left') : n.find('.right'),\n center = n.find('.center'),\n subnavbar = n.find('.subnavbar'),\n noLeft = left.length === 0,\n noRight = right.length === 0,\n leftWidth = noLeft ? 0 : left.outerWidth(true),\n rightWidth = noRight ? 0 : right.outerWidth(true),\n centerWidth = center.outerWidth(true),\n navbarWidth = n[0].offsetWidth - parseInt(n.css('padding-left'), 10) - parseInt(n.css('padding-right'), 10),\n onLeft = n.hasClass('navbar-on-left'),\n currLeft, diff;\n \n if (noRight) {\n currLeft = navbarWidth - centerWidth;\n }\n if (noLeft) {\n currLeft = 0;\n }\n if (!noLeft && !noRight) {\n currLeft = (navbarWidth - rightWidth - centerWidth + leftWidth) / 2;\n }\n var requiredLeft = (navbarWidth - centerWidth) / 2;\n if (navbarWidth - leftWidth - rightWidth > centerWidth) {\n if (requiredLeft < leftWidth) {\n requiredLeft = leftWidth;\n }\n if (requiredLeft + centerWidth > navbarWidth - rightWidth) {\n requiredLeft = navbarWidth - rightWidth - centerWidth;\n }\n diff = requiredLeft - currLeft;\n }\n else {\n diff = 0;\n }\n // RTL inverter\n var inverter = app.rtl ? -1 : 1;\n \n // Center left\n var centerLeft = diff;\n if (app.rtl && noLeft && noRight && center.length > 0) centerLeft = -centerLeft;\n center.css({left: centerLeft + 'px'});\n \n if (center.hasClass('sliding')) {\n center[0].f7NavbarLeftOffset = -(currLeft + diff) * inverter;\n center[0].f7NavbarRightOffset = (navbarWidth - currLeft - diff - centerWidth) * inverter;\n if (onLeft) center.transform('translate3d(' + center[0].f7NavbarLeftOffset + 'px, 0, 0)');\n }\n if (!noLeft && left.hasClass('sliding')) {\n if (app.rtl) {\n left[0].f7NavbarLeftOffset = -(navbarWidth - left.outerWidth()) / 2 * inverter;\n left[0].f7NavbarRightOffset = leftWidth * inverter;\n }\n else {\n left[0].f7NavbarLeftOffset = -leftWidth;\n left[0].f7NavbarRightOffset = (navbarWidth - left.outerWidth()) / 2;\n }\n if (onLeft) left.transform('translate3d(' + left[0].f7NavbarLeftOffset + 'px, 0, 0)');\n }\n if (!noRight && right.hasClass('sliding')) {\n if (app.rtl) {\n right[0].f7NavbarLeftOffset = -rightWidth * inverter;\n right[0].f7NavbarRightOffset = (navbarWidth - right.outerWidth()) / 2 * inverter;\n }\n else {\n right[0].f7NavbarLeftOffset = -(navbarWidth - right.outerWidth()) / 2;\n right[0].f7NavbarRightOffset = rightWidth;\n }\n if (onLeft) right.transform('translate3d(' + right[0].f7NavbarLeftOffset + 'px, 0, 0)');\n }\n if (subnavbar.length && subnavbar.hasClass('sliding')) {\n subnavbar[0].f7NavbarLeftOffset = app.rtl ? subnavbar[0].offsetWidth : -subnavbar[0].offsetWidth;\n subnavbar[0].f7NavbarRightOffset = -subnavbar[0].f7NavbarLeftOffset;\n }\n \n });\n };\n app.hideNavbar = function (navbarContainer) {\n $(navbarContainer).addClass('navbar-hidden');\n return true;\n };\n app.showNavbar = function (navbarContainer) {\n var navbar = $(navbarContainer);\n navbar.addClass('navbar-hiding').removeClass('navbar-hidden').transitionEnd(function () {\n navbar.removeClass('navbar-hiding');\n });\n return true;\n };\n app.hideToolbar = function (toolbarContainer) {\n $(toolbarContainer).addClass('toolbar-hidden');\n return true;\n };\n app.showToolbar = function (toolbarContainer) {\n var toolbar = $(toolbarContainer);\n toolbar.addClass('toolbar-hiding').removeClass('toolbar-hidden').transitionEnd(function () {\n toolbar.removeClass('toolbar-hiding');\n });\n };\n \n"," /*======================================================\n ************ Searchbar ************\n ======================================================*/\n app.initSearchbar = function (pageContainer) {\n pageContainer = $(pageContainer);\n var searchbar = pageContainer.hasClass('searchbar') ? pageContainer : pageContainer.find('.searchbar');\n if (searchbar.length === 0) return;\n if (!pageContainer.hasClass('page')) pageContainer = searchbar.parents('.page').eq(0);\n var searchbarOverlay = pageContainer.hasClass('page') ? pageContainer.find('.searchbar-overlay') : $('.searchbar-overlay');\n var input = searchbar.find('input[type=\"search\"]');\n var clear = searchbar.find('.searchbar-clear');\n var cancel = searchbar.find('.searchbar-cancel');\n var searchList = $(searchbar.attr('data-search-list'));\n var isVirtualList = searchList.hasClass('virtual-list');\n var virtualList;\n var searchIn = searchbar.attr('data-search-in');\n var searchBy = searchbar.attr('data-search-by');\n var found = searchbar.attr('data-searchbar-found');\n if (!found) {\n found = pageContainer.find('.searchbar-found');\n if (found.length === 0) found = $('.searchbar-found');\n }\n else {\n found = $(found);\n }\n var notFound = searchbar.attr('data-searchbar-not-found');\n if (!notFound) {\n notFound = pageContainer.find('.searchbar-not-found');\n if (notFound.length === 0) notFound = $('.searchbar-not-found');\n }\n else {\n notFound = $(notFound);\n }\n \n // Cancel button\n var cancelMarginProp = app.rtl ? 'margin-left' : 'margin-right';\n if (cancel.length > 0) {\n cancel.show();\n cancel.css(cancelMarginProp, -cancel[0].offsetWidth + 'px');\n }\n \n \n // Handlers\n function disableSearchbar() {\n input.val('').trigger('change');\n searchbar.removeClass('searchbar-active searchbar-not-empty');\n if (cancel.length > 0) cancel.css(cancelMarginProp, -cancel[0].offsetWidth + 'px');\n \n if (searchList) searchbarOverlay.removeClass('searchbar-overlay-active');\n if (app.device.ios) {\n setTimeout(function () {\n input.blur();\n searchList.trigger('disableSearch');\n }, 400);\n }\n else {\n input.blur();\n searchList.trigger('disableSearch');\n }\n }\n \n // Activate\n function enableSearchbar() {\n if (app.device.ios) {\n setTimeout(function () {\n if (searchList && !searchbar.hasClass('searchbar-active')) searchbarOverlay.addClass('searchbar-overlay-active');\n searchbar.addClass('searchbar-active');\n if (cancel.length > 0) cancel.css(cancelMarginProp, '0px');\n searchList.trigger('enableSearch');\n \n }, 400);\n }\n else {\n if (searchList && !searchbar.hasClass('searchbar-active')) searchbarOverlay.addClass('searchbar-overlay-active');\n searchbar.addClass('searchbar-active');\n if (cancel.length > 0) cancel.css(cancelMarginProp, '0px');\n searchList.trigger('enableSearch');\n }\n }\n \n // Clear\n function clearSearchbar() {\n input.val('').trigger('change').focus();\n searchList.trigger('clearSearch');\n }\n \n // Change\n function searchValue() {\n setTimeout(function () {\n var value = input.val().trim();\n if (value.length === 0) {\n searchbar.removeClass('searchbar-not-empty');\n if (searchList && searchbar.hasClass('searchbar-active')) searchbarOverlay.addClass('searchbar-overlay-active');\n }\n else {\n searchbar.addClass('searchbar-not-empty');\n if (searchList && searchbar.hasClass('searchbar-active')) searchbarOverlay.removeClass('searchbar-overlay-active');\n }\n if (searchList.length > 0 && (searchIn || isVirtualList)) search(value);\n }, 0);\n }\n \n //Prevent submit\n function preventSubmit(e) {\n e.preventDefault();\n }\n \n function attachEvents(destroy) {\n var method = destroy ? 'off' : 'on';\n searchbar[method]('submit', preventSubmit);\n cancel[method]('click', disableSearchbar);\n searchbarOverlay[method]('click', disableSearchbar);\n input[method]('focus', enableSearchbar);\n input[method]('change keydown keypress keyup', searchValue);\n clear[method]('click', clearSearchbar);\n }\n function detachEvents() {\n attachEvents(true);\n }\n searchbar[0].f7DestroySearchbar = detachEvents;\n \n // Attach events\n attachEvents();\n \n // Search\n var previousQuery;\n function search(query) {\n if (query.trim() === previousQuery) return;\n previousQuery = query.trim();\n var values = query.trim().toLowerCase().split(' ');\n var foundItems = [];\n if (isVirtualList) {\n virtualList = searchList[0].f7VirtualList;\n if (query.trim() === '') {\n virtualList.resetFilter();\n notFound.hide();\n found.show();\n return;\n }\n if (virtualList.params.searchAll) {\n foundItems = virtualList.params.searchAll(query, virtualList.items) || [];\n }\n else if (virtualList.params.searchByItem) {\n for (var i = 0; i < virtualList.items.length; i++) {\n if(virtualList.params.searchByItem(query, i, virtualList.params.items[i])) {\n foundItems.push(i);\n }\n }\n }\n }\n else {\n searchIn = searchbar.attr('data-search-in');\n searchList.find('li').removeClass('hidden-by-searchbar').each(function (index, el) {\n el = $(el);\n var compareWithEl = el.find(searchIn);\n if (compareWithEl.length === 0) return;\n var compareWith;\n compareWith = compareWithEl.text().trim().toLowerCase();\n var wordsMatch = 0;\n for (var i = 0; i < values.length; i++) {\n if (compareWith.indexOf(values[i]) >= 0) wordsMatch++;\n }\n if (wordsMatch !== values.length) {\n el.addClass('hidden-by-searchbar');\n }\n else {\n foundItems.push(el[0]);\n }\n });\n \n if (app.params.searchbarHideDividers) {\n searchList.find('.item-divider, .list-group-title').each(function () {\n var title = $(this);\n var nextElements = title.nextAll('li');\n var hide = true;\n for (var i = 0; i < nextElements.length; i++) {\n var nextEl = $(nextElements[i]);\n if (nextEl.hasClass('list-group-title') || nextEl.hasClass('item-divider')) break;\n if (!nextEl.hasClass('hidden-by-searchbar')) {\n hide = false;\n }\n }\n if (hide) title.addClass('hidden-by-searchbar');\n else title.removeClass('hidden-by-searchbar');\n });\n }\n if (app.params.searchbarHideGroups) {\n searchList.find('.list-group').each(function () {\n var group = $(this);\n var notHidden = group.find('li:not(.hidden-by-searchbar)');\n if (notHidden.length === 0) {\n group.addClass('hidden-by-searchbar');\n }\n else {\n group.removeClass('hidden-by-searchbar');\n }\n });\n }\n }\n searchList.trigger('search', {query: query, foundItems: foundItems});\n if (foundItems.length === 0) {\n notFound.show();\n found.hide();\n }\n else {\n notFound.hide();\n found.show();\n }\n if (isVirtualList) {\n virtualList.filterItems(foundItems);\n }\n }\n \n // Destroy on page remove\n function pageBeforeRemove() {\n detachEvents();\n pageContainer.off('pageBeforeRemove', pageBeforeRemove);\n }\n if (pageContainer.hasClass('page')) {\n pageContainer.on('pageBeforeRemove', pageBeforeRemove);\n }\n \n };\n app.destroySearchbar = function (pageContainer) {\n pageContainer = $(pageContainer);\n var searchbar = pageContainer.hasClass('searchbar') ? pageContainer : pageContainer.find('.searchbar');\n if (searchbar.length === 0) return;\n if (searchbar[0].f7DestroySearchbar) searchbar[0].f7DestroySearchbar();\n };\n \n"," /*======================================================\n ************ Messagebar ************\n ======================================================*/\n app.initMessagebar = function (pageContainer) {\n pageContainer = $(pageContainer);\n var messagebar = pageContainer.hasClass('messagebar') ? pageContainer : pageContainer.find('.messagebar');\n if (messagebar.length === 0) return;\n var textarea = messagebar.find('textarea');\n var pageContent = messagebar.parents('.page').find('.page-content');\n var pageContentInitialPadding = parseInt(pageContent.css('padding-bottom'));\n var initialBarHeight = messagebar[0].offsetHeight;\n var initialAreaHeight = textarea[0].offsetHeight;\n \n //Prevent submit\n function preventSubmit(e) {\n e.preventDefault();\n }\n \n // Resize textarea\n function sizeTextarea() {\n // Reset\n textarea.css({'height': ''});\n \n var height = textarea[0].offsetHeight;\n var diff = height - textarea[0].clientHeight;\n var scrollHeight = textarea[0].scrollHeight;\n var addExtra = parseInt((messagebar.attr('data-keyboard-height') || 0), 10);\n // Update\n if (scrollHeight + diff > height) {\n var newAreaHeight = scrollHeight + diff;\n var newBarHeight = initialBarHeight + (newAreaHeight - initialAreaHeight);\n var maxBarHeight = messagebar.attr('data-max-height') || messagebar.parents('.view')[0].offsetHeight - 88;\n if (newBarHeight > maxBarHeight) {\n newBarHeight = parseInt(maxBarHeight, 10);\n newAreaHeight = newBarHeight - initialBarHeight + initialAreaHeight;\n }\n textarea.css('height', newAreaHeight + 'px');\n messagebar.css('height', newBarHeight + 'px');\n if (pageContent.length > 0) {\n pageContent.css('padding-bottom', newBarHeight + addExtra + 'px');\n pageContent.scrollTop(pageContent[0].scrollHeight - pageContent[0].offsetHeight);\n }\n }\n else {\n if (pageContent.length > 0) {\n messagebar.css({'height': ''});\n pageContent.css({'padding-bottom': addExtra ? pageContentInitialPadding + addExtra + 'px' : ''});\n }\n }\n }\n var to;\n function handleKey(e) {\n clearTimeout(to);\n to = setTimeout(function () {\n sizeTextarea();\n }, 0);\n \n }\n \n function attachEvents(destroy) {\n var method = destroy ? 'off' : 'on';\n messagebar[method]('submit', preventSubmit);\n textarea[method]('change keydown keypress keyup paste cut', handleKey);\n }\n function detachEvents() {\n attachEvents(true);\n }\n \n messagebar[0].f7DestroyMessagebar = detachEvents;\n \n // Attach events\n attachEvents();\n \n // Destroy on page remove\n function pageBeforeRemove() {\n detachEvents();\n pageContainer.off('pageBeforeRemove', pageBeforeRemove);\n }\n if (pageContainer.hasClass('page')) {\n pageContainer.on('pageBeforeRemove', pageBeforeRemove);\n }\n };\n app.destroyMessagebar = function (pageContainer) {\n pageContainer = $(pageContainer);\n var messagebar = pageContainer.hasClass('messagebar') ? pageContainer : pageContainer.find('.messagebar');\n if (messagebar.length === 0) return;\n if (messagebar[0].f7DestroyMessagebar) messagebar[0].f7DestroyMessagebar();\n };\n"," /*======================================================\n ************ XHR ************\n ======================================================*/\n // XHR Caching\n app.cache = [];\n app.removeFromCache = function (url) {\n var index = false;\n for (var i = 0; i < app.cache.length; i++) {\n if (app.cache[i].url === url) index = i;\n }\n if (index !== false) app.cache.splice(index, 1);\n };\n \n // XHR\n app.xhr = false;\n app.get = function (url, view, ignoreCache, callback) {\n // should we ignore get params or not\n var _url = url;\n if (app.params.cacheIgnoreGetParameters && url.indexOf('?') >= 0) {\n _url = url.split('?')[0];\n }\n if (app.params.cache && !ignoreCache && url.indexOf('nocache') < 0 && app.params.cacheIgnore.indexOf(_url) < 0) {\n // Check is the url cached\n for (var i = 0; i < app.cache.length; i++) {\n if (app.cache[i].url === _url) {\n // Check expiration\n if ((new Date()).getTime() - app.cache[i].time < app.params.cacheDuration) {\n // Load from cache\n callback(app.cache[i].content);\n return false;\n }\n }\n }\n }\n \n app.xhr = $.ajax({\n url: url,\n method: 'GET',\n beforeSend: app.params.onAjaxStart,\n complete: function (xhr) {\n if (xhr.status === 200 || xhr.status === 0) {\n if (app.params.cache && !ignoreCache) {\n app.removeFromCache(_url);\n app.cache.push({\n url: _url,\n time: (new Date()).getTime(),\n content: xhr.responseText\n });\n }\n callback(xhr.responseText, false);\n }\n else {\n callback(xhr.responseText, true);\n }\n if (app.params.onAjaxComplete) app.params.onAjaxComplete(xhr);\n },\n error: function (xhr) {\n callback(xhr.responseText, true);\n if (app.params.onAjaxError) app.params.onAjaxonAjaxError(xhr);\n }\n });\n if (view) view.xhr = app.xhr;\n \n return app.xhr;\n };\n \n"," /*======================================================\n ************ Pages ************\n ======================================================*/\n // Page Callbacks API\n app.pageCallbacks = {};\n \n app.onPage = function (callbackName, pageName, callback) {\n if (pageName && pageName.split(' ').length > 1) {\n var pageNames = pageName.split(' ');\n var returnCallbacks = [];\n for (var i = 0; i < pageNames.length; i++) {\n returnCallbacks.push(app.onPage(callbackName, pageNames[i], callback));\n }\n returnCallbacks.remove = function () {\n for (var i = 0; i < returnCallbacks.length; i++) {\n returnCallbacks[i].remove();\n }\n };\n returnCallbacks.trigger = function () {\n for (var i = 0; i < returnCallbacks.length; i++) {\n returnCallbacks[i].trigger();\n }\n };\n return returnCallbacks;\n }\n var callbacks = app.pageCallbacks[callbackName][pageName];\n if (!callbacks) {\n callbacks = app.pageCallbacks[callbackName][pageName] = [];\n }\n app.pageCallbacks[callbackName][pageName].push(callback);\n return {\n remove: function () {\n var removeIndex;\n for (var i = 0; i < callbacks.length; i++) {\n if (callbacks[i].toString() === callback.toString()) {\n removeIndex = i;\n }\n }\n if (typeof removeIndex !== 'undefined') callbacks.splice(removeIndex, 1);\n },\n trigger: callback\n };\n };\n \n //Create callbacks methods dynamically\n function createPageCallback(callbackName) {\n var capitalized = callbackName.replace(/^./, function (match) {\n return match.toUpperCase();\n });\n app['onPage' + capitalized] = function (pageName, callback) {\n return app.onPage(callbackName, pageName, callback);\n };\n }\n \n var pageCallbacksNames = ('beforeInit init reinit beforeAnimation afterAnimation back afterBack beforeRemove').split(' ');\n for (var i = 0; i < pageCallbacksNames.length; i++) {\n app.pageCallbacks[pageCallbacksNames[i]] = {};\n createPageCallback(pageCallbacksNames[i]);\n }\n \n app.triggerPageCallbacks = function (callbackName, pageName, pageData) {\n var allPagesCallbacks = app.pageCallbacks[callbackName]['*'];\n if (allPagesCallbacks) {\n for (var j = 0; j < allPagesCallbacks.length; j++) {\n allPagesCallbacks[j](pageData);\n }\n }\n var callbacks = app.pageCallbacks[callbackName][pageName];\n if (!callbacks || callbacks.length === 0) return;\n for (var i = 0; i < callbacks.length; i++) {\n callbacks[i](pageData);\n }\n };\n \n // On Page Init Callback\n app.pageInitCallback = function (view, params) {\n var pageContainer = params.pageContainer;\n if (pageContainer.f7PageInitialized && !view.params.domCache) return;\n \n // Page Data\n var pageData = {\n container: pageContainer,\n url: params.url,\n query: params.query || $.parseUrlQuery(params.url || ''),\n name: $(pageContainer).attr('data-page'),\n view: view,\n from: params.position,\n context: params.context,\n navbarInnerContainer: params.navbarInnerContainer,\n fromPage: params.fromPage\n };\n \n if (pageContainer.f7PageInitialized && view.params.domCache) {\n // Reinit Page\n app.reinitPage(pageContainer);\n \n // Callbacks\n app.pluginHook('pageReinit', pageData);\n if (app.params.onPageReinit) app.params.onPageBeforeInit(app, pageData);\n app.triggerPageCallbacks('reinit', pageData.name, pageData);\n $(pageData.container).trigger('pageReinit', {page: pageData});\n return;\n }\n pageContainer.f7PageInitialized = true;\n \n // Store pagedata in page\n pageContainer.f7PageData = pageData;\n \n // Update View's activePage\n if (view && !params.preloadOnly) view.activePage = pageData;\n \n // Before Init Callbacks\n app.pluginHook('pageBeforeInit', pageData);\n if (app.params.onPageBeforeInit) app.params.onPageBeforeInit(app, pageData);\n app.triggerPageCallbacks('beforeInit', pageData.name, pageData);\n $(pageData.container).trigger('pageBeforeInit', {page: pageData});\n \n // Init page\n app.initPage(pageContainer);\n \n // Init Callback\n app.pluginHook('pageInit', pageData);\n if (app.params.onPageInit) app.params.onPageInit(app, pageData);\n app.triggerPageCallbacks('init', pageData.name, pageData);\n $(pageData.container).trigger('pageInit', {page: pageData});\n };\n app.pageRemoveCallback = function (view, pageContainer, position) {\n var pageContext;\n if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;\n // Page Data\n var pageData = {\n container: pageContainer,\n name: $(pageContainer).attr('data-page'),\n view: view,\n url: pageContainer.f7PageData && pageContainer.f7PageData.url,\n query: pageContainer.f7PageData && pageContainer.f7PageData.query,\n from: position,\n context: pageContext\n };\n // Before Init Callback\n app.pluginHook('pageBeforeRemove', pageData);\n if (app.params.onPageBeforeRemove) app.params.onPageBeforeRemove(app, pageData);\n app.triggerPageCallbacks('beforeRemove', pageData.name, pageData);\n $(pageData.container).trigger('pageBeforeRemove', {page: pageData});\n };\n app.pageBackCallbacks = function (callback, view, params) {\n // Page Data\n var pageContainer = params.pageContainer;\n var pageContext;\n if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;\n \n var pageData = {\n container: pageContainer,\n name: $(pageContainer).attr('data-page'),\n url: pageContainer.f7PageData && pageContainer.f7PageData.url,\n query: pageContainer.f7PageData && pageContainer.f7PageData.query,\n view: view,\n from: params.position,\n context: pageContext,\n swipeBack: params.swipeBack\n };\n \n if (callback === 'after') {\n app.pluginHook('pageAfterBack', pageData);\n if (app.params.onPageAfterBack) app.params.onPageAfterBack(app, pageData);\n app.triggerPageCallbacks('afterBack', pageData.name, pageData);\n $(pageContainer).trigger('pageAfterBack', {page: pageData});\n \n }\n if (callback === 'before') {\n app.pluginHook('pageBack', pageData);\n if (app.params.onPageBack) app.params.onPageBack(app, pageData);\n app.triggerPageCallbacks('back', pageData.name, pageData);\n $(pageData.container).trigger('pageBack', {page: pageData});\n }\n };\n app.pageAnimCallbacks = function (callback, view, params) {\n var pageContainer = params.pageContainer;\n var pageContext;\n if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;\n // Page Data\n var pageData = {\n container: pageContainer,\n url: params.url,\n query: params.query || $.parseUrlQuery(params.url || ''),\n name: $(pageContainer).attr('data-page'),\n view: view,\n from: params.position,\n context: pageContext,\n swipeBack: params.swipeBack,\n fromPage: params.fromPage\n };\n var oldPage = params.oldPage,\n newPage = params.newPage;\n \n // Update page date\n pageContainer.f7PageData = pageData;\n \n if (callback === 'after') {\n app.pluginHook('pageAfterAnimation', pageData);\n if (app.params.onPageAfterAnimation) app.params.onPageAfterAnimation(app, pageData);\n app.triggerPageCallbacks('afterAnimation', pageData.name, pageData);\n $(pageData.container).trigger('pageAfterAnimation', {page: pageData});\n \n }\n if (callback === 'before') {\n // Add data-page on view\n $(view.container).attr('data-page', pageData.name);\n \n // Update View's activePage\n if (view) view.activePage = pageData;\n \n // Hide/show navbar dynamically\n if (newPage.hasClass('no-navbar') && !oldPage.hasClass('no-navbar')) {\n view.hideNavbar();\n }\n if (!newPage.hasClass('no-navbar') && (oldPage.hasClass('no-navbar') || oldPage.hasClass('no-navbar-by-scroll'))) {\n view.showNavbar();\n }\n // Hide/show navbar toolbar\n if (newPage.hasClass('no-toolbar') && !oldPage.hasClass('no-toolbar')) {\n view.hideToolbar();\n }\n if (!newPage.hasClass('no-toolbar') && (oldPage.hasClass('no-toolbar') || oldPage.hasClass('no-toolbar-by-scroll'))) {\n view.showToolbar();\n }\n // Hide/show tabbar\n var tabBar;\n if (newPage.hasClass('no-tabbar') && !oldPage.hasClass('no-tabbar')) {\n tabBar = $(view.container).find('.tabbar');\n if (tabBar.length === 0) tabBar = $(view.container).parents('.' + app.params.viewsClass).find('.tabbar');\n app.hideToolbar(tabBar);\n }\n if (!newPage.hasClass('no-tabbar') && (oldPage.hasClass('no-tabbar') || oldPage.hasClass('no-tabbar-by-scroll'))) {\n tabBar = $(view.container).find('.tabbar');\n if (tabBar.length === 0) tabBar = $(view.container).parents('.' + app.params.viewsClass).find('.tabbar');\n app.showToolbar(tabBar);\n }\n \n oldPage.removeClass('no-navbar-by-scroll no-toolbar-by-scroll');\n // Callbacks\n app.pluginHook('pageBeforeAnimation', pageData);\n if (app.params.onPageBeforeAnimation) app.params.onPageBeforeAnimation(app, pageData);\n app.triggerPageCallbacks('beforeAnimation', pageData.name, pageData);\n $(pageData.container).trigger('pageBeforeAnimation', {page: pageData});\n }\n };\n \n // Init Page Events and Manipulations\n app.initPage = function (pageContainer) {\n // Size navbars on page load\n if (app.sizeNavbars) app.sizeNavbars($(pageContainer).parents('.' + app.params.viewClass)[0]);\n // Init messages\n if (app.initMessages) app.initMessages(pageContainer);\n // Init forms storage\n if (app.initFormsStorage) app.initFormsStorage(pageContainer);\n // Init smart select\n if (app.initSmartSelects) app.initSmartSelects(pageContainer);\n // Init slider\n if (app.initSlider) app.initSlider(pageContainer);\n if (app.initSwiper) app.initSwiper(pageContainer);\n // Init pull to refres\n if (app.initPullToRefresh) app.initPullToRefresh(pageContainer);\n // Init infinite scroll\n if (app.initInfiniteScroll) app.initInfiniteScroll(pageContainer);\n // Init searchbar\n if (app.initSearchbar) app.initSearchbar(pageContainer);\n // Init message bar\n if (app.initMessagebar) app.initMessagebar(pageContainer);\n // Init scroll toolbars\n if (app.initScrollToolbars) app.initScrollToolbars(pageContainer);\n // Init scroll toolbars\n if (app.initImagesLazyLoad) app.initImagesLazyLoad(pageContainer);\n };\n app.reinitPage = function (pageContainer) {\n // Size navbars on page reinit\n if (app.sizeNavbars) app.sizeNavbars($(pageContainer).parents('.' + app.params.viewClass)[0]);\n // Reinit slider\n if (app.reinitSlider) app.reinitSlider(pageContainer);\n if (app.reinitSwiper) app.reinitSwiper(pageContainer);\n // Reinit lazy load\n if (app.reinitLazyLoad) app.reinitLazyLoad(pageContainer);\n };\n"," /*======================================================\n ************ Navigation / Router ************\n ======================================================*/\n app.router = {\n // Temporary DOM Element\n temporaryDom: document.createElement('div'),\n \n // Find page or navbar in passed container which are related to View\n findElement: function (selector, container, view, notCached) {\n container = $(container);\n if (notCached) selector = selector + ':not(.cached)';\n var found = container.find(selector);\n if (found.length > 1) {\n if (typeof view.selector === 'string') {\n // Search in related view\n found = container.find(view.selector + ' ' + selector);\n }\n if (found.length > 1) {\n // Search in main view\n found = container.find('.' + app.params.viewMainClass + ' ' + selector);\n }\n }\n if (found.length === 1) return found;\n else {\n // Try to find non cached\n if (!notCached) found = app.router.findElement(selector, container, view, true);\n if (found && found.length === 1) return found;\n else return undefined;\n }\n },\n \n // Set pages classess for animationEnd\n animatePages: function (leftPage, rightPage, direction, view) {\n // Loading new page\n var removeClasses = 'page-on-center page-on-right page-on-left';\n if (direction === 'to-left') {\n // leftPage.removeClass('page-on-center').addClass('page-from-center-to-left');\n // rightPage.removeClass('page-on-left').addClass('page-from-right-to-center');\n leftPage.removeClass(removeClasses).addClass('page-from-center-to-left');\n rightPage.removeClass(removeClasses).addClass('page-from-right-to-center');\n }\n // Go back\n if (direction === 'to-right') {\n // leftPage.removeClass('page-on-left').addClass('page-from-left-to-center');\n // rightPage.removeClass('page-on-center').addClass('page-from-center-to-right');\n leftPage.removeClass(removeClasses).addClass('page-from-left-to-center');\n rightPage.removeClass(removeClasses).addClass('page-from-center-to-right');\n \n }\n },\n \n // Prepare navbar before animarion\n prepareNavbar: function (newNavbarInner, oldNavbarInner, newNavbarPosition) {\n $(newNavbarInner).find('.sliding').each(function () {\n var sliding = $(this);\n var slidingOffset = newNavbarPosition === 'right' ? this.f7NavbarRightOffset : this.f7NavbarLeftOffset;\n \n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(' + (-slidingOffset) + 'px,0,0)');\n }\n if (newNavbarPosition === 'left' && sliding.hasClass('center') && $(oldNavbarInner).find('.left .back .icon ~ span').length > 0) {\n slidingOffset += $(oldNavbarInner).find('.left .back span')[0].offsetLeft;\n }\n }\n \n sliding.transform('translate3d(' + slidingOffset + 'px,0,0)');\n });\n },\n \n // Set navbars classess for animation\n animateNavbars: function (leftNavbarInner, rightNavbarInner, direction, view) {\n // Loading new page\n var removeClasses = 'navbar-on-right navbar-on-center navbar-on-left';\n if (direction === 'to-left') {\n rightNavbarInner.removeClass(removeClasses).addClass('navbar-from-right-to-center');\n rightNavbarInner.find('.sliding').each(function () {\n var sliding = $(this);\n sliding.transform('translate3d(0px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(0px,0,0)');\n }\n }\n });\n \n leftNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-left');\n leftNavbarInner.find('.sliding').each(function () {\n var sliding = $(this);\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('center') && rightNavbarInner.find('.sliding.left .back .icon').length > 0) {\n this.f7NavbarLeftOffset += rightNavbarInner.find('.sliding.left .back span')[0].offsetLeft;\n }\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(' + (-this.f7NavbarLeftOffset) + 'px,0,0)');\n }\n }\n sliding.transform('translate3d(' + (this.f7NavbarLeftOffset) + 'px,0,0)');\n });\n }\n // Go back\n if (direction === 'to-right') {\n leftNavbarInner.removeClass(removeClasses).addClass('navbar-from-left-to-center');\n leftNavbarInner.find('.sliding').each(function () {\n var sliding = $(this);\n sliding.transform('translate3d(0px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(0px,0,0)');\n }\n }\n });\n \n rightNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-right');\n rightNavbarInner.find('.sliding').each(function () {\n var sliding = $(this);\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(' + (-this.f7NavbarRightOffset) + 'px,0,0)');\n }\n }\n sliding.transform('translate3d(' + (this.f7NavbarRightOffset) + 'px,0,0)');\n });\n }\n },\n \n preprocess: function(content, url, next) {\n // Plugin hook\n app.pluginHook('routerPreprocess', content, url, next);\n \n // Preprocess by plugin\n content = app.pluginProcess('preprocess', content);\n \n if (app.params.preprocess) {\n content = app.params.preprocess(content, url, next);\n if (typeof content !== 'undefined') {\n next(content);\n }\n } else {\n next(content);\n }\n },\n \n template7Render: function (view, options) {\n var url = options.url,\n content = options.content, //initial content\n t7_rendered_content = options.content, // will be rendered using Template7\n context = options.context, // Context data for Template7\n contextName = options.contextName, \n template = options.template, // Template 7 compiled template\n pageName = options.pageName;\n \n var t7_ctx, t7_template;\n if (typeof content === 'string') {\n if (url) {\n if (app.template7Cache[url]) t7_template = t7.cache[url];\n else {\n t7_template = t7.compile(content);\n t7.cache[url] = t7_template;\n }\n }\n else t7_template = t7.compile(content);\n }\n else if (template) {\n t7_template = template;\n }\n \n if (context) t7_ctx = context;\n else {\n if (contextName) {\n if (contextName.indexOf('.') >= 0) {\n var _ctx_path = contextName.split('.');\n var _ctx = t7.data[_ctx_path[0]];\n for (var i = 1; i < _ctx_path.length; i++) {\n if (_ctx_path[i]) _ctx = _ctx[_ctx_path[i]];\n }\n t7_ctx = _ctx;\n }\n else t7_ctx = t7.data[contextName];\n }\n if (!t7_ctx && url) {\n t7_ctx = t7.data['url:' + url];\n }\n if (!t7_ctx && typeof content === 'string' && !template) {\n //try to find by page name in content\n var pageNameMatch = content.match(/(data-page=[\"'][^\"^']*[\"'])/);\n if (pageNameMatch) {\n var page = pageNameMatch[0].split('data-page=')[1].replace(/['\"]/g, '');\n if (page) t7_ctx = t7.data['page:' + page];\n }\n }\n if (!t7_ctx && template && t7.templates) {\n // Try to find matched template name in t7.templates\n for (var templateName in t7.templates) {\n if (t7.templates[templateName] === template) t7_ctx = t7.data[templateName];\n }\n }\n if (!t7_ctx) t7_ctx = {};\n }\n \n if (t7_template && t7_ctx) {\n if (typeof t7_ctx === 'function') t7_ctx = t7_ctx();\n if (url) {\n // Extend data with URL query\n var query = $.parseUrlQuery(url);\n t7_ctx.url_query = {};\n for (var key in query) {\n t7_ctx.url_query[key] = query[key];\n }\n }\n t7_rendered_content = t7_template(t7_ctx);\n }\n \n return {content: t7_rendered_content, context: t7_ctx};\n }\n };\n \n \n app.router._load = function (view, options) {\n options = options || {};\n \n var url = options.url,\n content = options.content, //initial content\n t7_rendered = {content: options.content},\n template = options.template, // Template 7 compiled template\n pageName = options.pageName,\n viewContainer = $(view.container), \n pagesContainer = $(view.pagesContainer),\n animatePages = options.animatePages,\n newPage, oldPage, pagesInView, i, oldNavbarInner, newNavbarInner, navbar, dynamicNavbar, reloadPosition,\n isDynamicPage = typeof url === 'undefined' && content || template, \n pushState = options.pushState;\n \n if (typeof animatePages === 'undefined') animatePages = view.params.animatePages;\n \n // Plugin hook\n app.pluginHook('routerLoad', view, options);\n \n // Render with Template7\n if (app.params.template7Pages && typeof content === 'string' || template) {\n t7_rendered = app.router.template7Render(view, options);\n if (t7_rendered.content && !content) {\n content = t7_rendered.content;\n }\n }\n \n app.router.temporaryDom.innerHTML = '';\n \n // Parse DOM\n if (!pageName) {\n if (url || (typeof content === 'string')) {\n app.router.temporaryDom.innerHTML = t7_rendered.content;\n } else {\n if ('length' in content && content.length > 1) {\n for (var ci = 0; ci < content.length; ci++) {\n $(app.router.temporaryDom).append(content[ci]);\n }\n } else {\n $(app.router.temporaryDom).append(content);\n }\n }\n }\n \n // Reload position\n reloadPosition = options.reload && (options.reloadPrevious ? 'left' : 'center');\n \n // Find new page\n if (pageName) newPage = pagesContainer.find('.page[data-page=\"' + pageName + '\"]');\n else {\n newPage = app.router.findElement('.page', app.router.temporaryDom, view);\n }\n \n // If page not found exit\n if (!newPage || newPage.length === 0 || (pageName && view.activePage && view.activePage.name === pageName)) {\n view.allowPageChange = true;\n return;\n }\n \n newPage.addClass(options.reload ? 'page-on-' + reloadPosition : 'page-on-right');\n \n // Find old page (should be the last one) and remove older pages\n pagesInView = pagesContainer.children('.page:not(.cached)');\n \n if (options.reload && options.reloadPrevious && pagesInView.length === 1) {\n view.allowPageChange = true;\n return;\n }\n \n if (options.reload) {\n oldPage = pagesInView.eq(pagesInView.length - 1);\n }\n else {\n if (pagesInView.length > 1) {\n for (i = 0; i < pagesInView.length - 2; i++) {\n if (!view.params.domCache) {\n app.pageRemoveCallback(view, pagesInView[i], 'left');\n $(pagesInView[i]).remove();\n }\n else {\n $(pagesInView[i]).addClass('cached');\n }\n }\n if (!view.params.domCache) {\n app.pageRemoveCallback(view, pagesInView[i], 'left');\n $(pagesInView[i]).remove();\n }\n else {\n $(pagesInView[i]).addClass('cached');\n }\n }\n oldPage = pagesContainer.children('.page:not(.cached)');\n }\n if(view.params.domCache) newPage.removeClass('cached');\n \n // Dynamic navbar\n if (view.params.dynamicNavbar) {\n dynamicNavbar = true;\n // Find navbar\n if (pageName) {\n newNavbarInner = viewContainer.find('.navbar-inner[data-page=\"' + pageName + '\"]');\n }\n else {\n newNavbarInner = app.router.findElement('.navbar-inner', app.router.temporaryDom, view); \n }\n if (!newNavbarInner || newNavbarInner.length === 0) {\n dynamicNavbar = false;\n }\n navbar = viewContainer.find('.navbar');\n if (options.reload) {\n oldNavbarInner = navbar.find('.navbar-inner:not(.cached):last-child');\n }\n else {\n oldNavbarInner = navbar.find('.navbar-inner:not(.cached)'); \n \n if (oldNavbarInner.length > 0) {\n for (i = 0; i < oldNavbarInner.length - 1; i++) {\n if (!view.params.domCache)\n $(oldNavbarInner[i]).remove();\n else\n $(oldNavbarInner[i]).addClass('cached');\n }\n if (!newNavbarInner && oldNavbarInner.length === 1) {\n if (!view.params.domCache)\n $(oldNavbarInner[0]).remove();\n else\n $(oldNavbarInner[0]).addClass('cached');\n }\n oldNavbarInner = navbar.find('.navbar-inner:not(.cached)');\n }\n }\n }\n if (dynamicNavbar) {\n newNavbarInner.addClass(options.reload ? 'navbar-on-' + reloadPosition : 'navbar-on-right');\n if(view.params.domCache) newNavbarInner.removeClass('cached');\n newPage[0].f7RelatedNavbar = newNavbarInner[0];\n newNavbarInner[0].f7RelatedPage = newPage[0];\n }\n \n // save content areas into view's cache\n if (!url) {\n var newPageName = pageName || newPage.attr('data-page');\n if (isDynamicPage) url = '#' + app.params.dynamicPageUrl.replace(/{{name}}/g, newPageName).replace(/{{index}}/g, view.history.length - (options.reload ? 1 : 0));\n else url = '#' + newPageName;\n if (!view.params.domCache) {\n view.contentCache[url] = content;\n }\n if (view.params.domCache && pageName) {\n view.pagesCache[url] = pageName;\n }\n }\n \n // Push State\n if (app.params.pushState && !options.reloadPrevious && view.main) {\n if (typeof pushState === 'undefined') pushState = true;\n var pushStateRoot = app.params.pushStateRoot || '';\n var method = options.reload ? 'replaceState' : 'pushState';\n if (pushState) {\n if (!isDynamicPage && !pageName) {\n history[method]({url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);\n }\n else if (isDynamicPage && content) {\n history[method]({content: content, url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);\n }\n else if (pageName) {\n history[method]({pageName: pageName, url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);\n }\n }\n }\n \n // Update View history\n view.url = url;\n if (options.reload) {\n var lastUrl = view.history[view.history.length - (options.reloadPrevious ? 2 : 1)];\n if (lastUrl && lastUrl.indexOf('#') === 0 && lastUrl in view.contentCache && lastUrl !== url) {\n view.contentCache[lastUrl] = null;\n delete view.contentCache[lastUrl];\n }\n view.history[view.history.length - (options.reloadPrevious ? 2 : 1)] = url;\n }\n else {\n view.history.push(url);\n }\n \n // Unique history\n var historyBecameUnique = false;\n if (view.params.uniqueHistory) {\n var _history = view.history;\n var _url = url;\n if (view.params.uniqueHistoryIgnoreGetParameters) {\n _history = [];\n _url = url.split('?')[0];\n for (i = 0; i < view.history.length; i++) {\n _history.push(view.history[i].split('?')[0]);\n }\n }\n \n if (_history.indexOf(_url) !== _history.lastIndexOf(_url)) {\n view.history = view.history.slice(0, _history.indexOf(_url));\n view.history.push(url);\n historyBecameUnique = true;\n }\n }\n // Dom manipulations\n if (options.reloadPrevious) {\n oldPage = oldPage.prev('.page');\n newPage.insertBefore(oldPage);\n if (dynamicNavbar) {\n oldNavbarInner = oldNavbarInner.prev('.navbar-inner');\n newNavbarInner.insertAfter(oldNavbarInner);\n }\n }\n else {\n pagesContainer.append(newPage[0]);\n if (dynamicNavbar) navbar.append(newNavbarInner[0]);\n }\n // Remove Old Page And Navbar\n if (options.reload) {\n if (view.params.domCache && view.initialPages.indexOf(oldPage[0]) >= 0) {\n oldPage.addClass('cached');\n if (dynamicNavbar) oldNavbarInner.addClass('cached');\n }\n else {\n app.pageRemoveCallback(view, oldPage[0], reloadPosition);\n oldPage.remove();\n if (dynamicNavbar) oldNavbarInner.remove();\n }\n }\n \n // Page Init Events\n app.pageInitCallback(view, {\n pageContainer: newPage[0], \n url: url, \n position: options.reload ? reloadPosition : 'right', \n navbarInnerContainer: dynamicNavbar ? newNavbarInner[0] : undefined, \n context: t7_rendered.context,\n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n \n // Navbar init event\n if (dynamicNavbar) {\n app.navbarInitCallback(view, newPage[0], navbar[0], newNavbarInner[0], url, options.reload ? reloadPosition : 'right');\n }\n \n if (options.reload) {\n view.allowPageChange = true;\n if (historyBecameUnique) view.refreshPreviousPage();\n return;\n }\n \n if (dynamicNavbar && animatePages) {\n app.router.prepareNavbar(newNavbarInner, oldNavbarInner, 'right');\n }\n // Force reLayout\n var clientLeft = newPage[0].clientLeft;\n \n // Before Anim Callback\n app.pageAnimCallbacks('before', view, {\n pageContainer: newPage[0], \n url: url, \n position: 'right', \n oldPage: oldPage, \n newPage: newPage, \n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n \n function afterAnimation() {\n view.allowPageChange = true;\n newPage.removeClass('page-from-right-to-center page-on-right').addClass('page-on-center');\n oldPage.removeClass('page-from-center-to-left page-on-center').addClass('page-on-left');\n if (dynamicNavbar) {\n newNavbarInner.removeClass('navbar-from-right-to-center navbar-on-left navbar-on-right').addClass('navbar-on-center');\n oldNavbarInner.removeClass('navbar-from-center-to-left navbar-on-center').addClass('navbar-on-left');\n }\n app.pageAnimCallbacks('after', view, {\n pageContainer: newPage[0], \n url: url, \n position: 'right', \n oldPage: oldPage, \n newPage: newPage, \n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n if (app.params.pushState) app.pushStateClearQueue();\n if (!(view.params.swipeBackPage || view.params.preloadPreviousPage)) {\n if (view.params.domCache) {\n oldPage.addClass('cached');\n oldNavbarInner.addClass('cached');\n }\n else {\n if (!(url.indexOf('#') === 0 && newPage.attr('data-page').indexOf('smart-select-') === 0)) {\n app.pageRemoveCallback(view, oldPage[0], 'left');\n oldPage.remove();\n if (dynamicNavbar) oldNavbarInner.remove(); \n }\n }\n }\n if (view.params.uniqueHistory && historyBecameUnique) {\n view.refreshPreviousPage();\n }\n }\n \n if (animatePages) {\n // Set pages before animation\n app.router.animatePages(oldPage, newPage, 'to-left', view);\n \n // Dynamic navbar animation\n if (dynamicNavbar) {\n setTimeout(function () {\n app.router.animateNavbars(oldNavbarInner, newNavbarInner, 'to-left', view);\n }, 0);\n \n }\n newPage.animationEnd(function (e) {\n afterAnimation();\n });\n }\n else {\n newNavbarInner.find('.sliding, .sliding .back .icon').transform('');\n afterAnimation();\n }\n };\n \n app.router.load = function (view, options) {\n options = options || {};\n var url = options.url;\n var content = options.content;\n var pageName = options.pageName;\n if (pageName) {\n if (pageName.indexOf('?') > 0) {\n options.query = $.parseUrlQuery(pageName);\n options.pageName = pageName = pageName.split('?')[0];\n }\n }\n var template = options.template;\n if (view.params.reloadPages === true) options.reload = true;\n \n if (!view.allowPageChange) return false;\n if (url && view.url === url && !options.reload && !view.params.allowDuplicateUrls) return false;\n view.allowPageChange = false;\n if (app.xhr && view.xhr && view.xhr === app.xhr) {\n app.xhr.abort();\n app.xhr = false;\n }\n function proceed(content) {\n app.router.preprocess(content, url, function (content) {\n options.content = content;\n app.router._load(view, options);\n });\n }\n if (content || pageName) {\n proceed(content);\n return;\n }\n else if (template) {\n app.router._load(view, options);\n return;\n }\n \n if (!options.url || options.url === '#') {\n view.allowPageChange = true;\n return;\n }\n app.get(options.url, view, options.ignoreCache, function (content, error) {\n if (error) {\n view.allowPageChange = true;\n return;\n }\n proceed(content);\n });\n };\n \n app.router._back = function (view, options) {\n options = options || {};\n var url = options.url,\n content = options.content, \n t7_rendered = {content: options.content}, // will be rendered using Template7\n template = options.template, // Template 7 compiled template\n animatePages = options.animatePages, \n preloadOnly = options.preloadOnly, \n pushState = options.pushState, \n ignoreCache = options.ignoreCache,\n force = options.force,\n pageName = options.pageName;\n \n var viewContainer = $(view.container),\n pagesContainer = $(view.pagesContainer),\n pagesInView = pagesContainer.children('.page:not(.cached)'),\n oldPage, newPage, oldNavbarInner, newNavbarInner, navbar, navbarInners, dynamicNavbar, manipulateDom = true;\n \n if (typeof animatePages === 'undefined') animatePages = view.params.animatePages;\n \n app.pluginHook('routerBack', view, options);\n \n // Render with Template7\n if (app.params.template7Pages && typeof content === 'string' || template) {\n t7_rendered = app.router.template7Render(view, options);\n if (t7_rendered.content && !content) {\n content = t7_rendered.content;\n }\n }\n \n // Push state\n if (app.params.pushState) {\n if (typeof pushState === 'undefined') pushState = true;\n if (!preloadOnly && history.state && pushState) {\n history.back();\n }\n }\n \n // Animation\n function afterAnimation() {\n app.pageBackCallbacks('after', view, {\n pageContainer: oldPage[0], \n url: url, \n position: 'center', \n oldPage: oldPage, \n newPage: newPage, \n });\n app.pageAnimCallbacks('after', view, {\n pageContainer: newPage[0], \n url: url, \n position: 'left', \n oldPage: oldPage, \n newPage: newPage, \n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n app.router.afterBack(view, oldPage[0], newPage[0]);\n }\n function animateBack() {\n // Page before animation callback\n app.pageBackCallbacks('before', view, {\n pageContainer: oldPage[0], \n url: url, \n position: 'center', \n oldPage: oldPage, \n newPage: newPage, \n });\n app.pageAnimCallbacks('before', view, {\n pageContainer: newPage[0], \n url: url, \n position: 'left', \n oldPage: oldPage, \n newPage: newPage, \n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n \n if (animatePages) {\n // Set pages before animation\n app.router.animatePages(newPage, oldPage, 'to-right', view);\n \n // Dynamic navbar animation\n if (dynamicNavbar) {\n setTimeout(function () {\n app.router.animateNavbars(newNavbarInner, oldNavbarInner, 'to-right', view);\n }, 0);\n }\n \n newPage.animationEnd(function () {\n afterAnimation();\n });\n }\n else {\n newNavbarInner.find('.sliding, .sliding .back .icon').transform('');\n afterAnimation();\n }\n }\n \n function parseNewPage() {\n app.router.temporaryDom.innerHTML = '';\n // Parse DOM\n if (url || (typeof content === 'string')) {\n app.router.temporaryDom.innerHTML = t7_rendered.content;\n } else {\n if ('length' in content && content.length > 1) {\n for (var ci = 0; ci < content.length; ci++) {\n $(app.router.temporaryDom).append(content[ci]);\n }\n } else {\n $(app.router.temporaryDom).append(content);\n }\n }\n newPage = app.router.findElement('.page', app.router.temporaryDom, view);\n \n if (view.params.dynamicNavbar) {\n // Find navbar\n newNavbarInner = app.router.findElement('.navbar-inner', app.router.temporaryDom, view);\n }\n }\n function setPages() {\n // If pages not found or there are still more than one, exit\n if (!newPage || newPage.length === 0) {\n view.allowPageChange = true;\n return;\n }\n if (view.params.dynamicNavbar && typeof dynamicNavbar === 'undefined') {\n if (!newNavbarInner || newNavbarInner.length === 0) {\n dynamicNavbar = false;\n }\n else {\n dynamicNavbar = true;\n }\n }\n \n newPage.addClass('page-on-left').removeClass('cached');\n if (dynamicNavbar) {\n navbar = viewContainer.find('.navbar');\n navbarInners = viewContainer.find('.navbar-inner:not(.cached)');\n newNavbarInner.addClass('navbar-on-left').removeClass('cached');\n }\n // Remove/hide previous page in force mode\n if (force) {\n var pageToRemove, navbarToRemove;\n pageToRemove = $(pagesInView[pagesInView.length - 2]);\n \n if (dynamicNavbar) navbarToRemove = $(pageToRemove[0] && pageToRemove[0].f7RelatedNavbar || navbarInners[navbarInners.length - 2]);\n if (view.params.domCache && view.initialPages.indexOf(pageToRemove[0]) >= 0) {\n if (pageToRemove.length && pageToRemove[0] !== newPage[0]) pageToRemove.addClass('cached');\n if (dynamicNavbar && navbarToRemove.length && navbarToRemove[0] !== newNavbarInner[0]) {\n navbarToRemove.addClass('cached');\n }\n }\n else {\n if (pageToRemove.length) pageToRemove.remove();\n if (dynamicNavbar && navbarToRemove.length) {\n navbarToRemove.remove();\n } \n }\n pagesInView = pagesContainer.children('.page:not(.cached)');\n if (dynamicNavbar) {\n navbarInners = viewContainer.find('.navbar-inner:not(.cached)');\n }\n if (view.history.indexOf(url) >= 0) {\n view.history = view.history.slice(0, view.history.indexOf(url) + 2);\n }\n else {\n if (view.history[[view.history.length - 2]]) {\n view.history[view.history.length - 2] = url; \n }\n else {\n view.history.unshift(url);\n }\n }\n }\n \n oldPage = $(pagesInView[pagesInView.length - 1]);\n if (view.params.domCache) {\n if (oldPage[0] === newPage[0]) {\n oldPage = pagesContainer.children('.page.page-on-center');\n if (oldPage.length === 0 && view.activePage) oldPage = $(view.activePage.container);\n }\n }\n \n if (dynamicNavbar && !oldNavbarInner) {\n oldNavbarInner = $(navbarInners[navbarInners.length - 1]);\n if (view.params.domCache) {\n if (oldNavbarInner[0] === newNavbarInner[0]) {\n oldNavbarInner = navbar.children('.navbar-inner.navbar-on-center:not(.cached)');\n }\n if (oldNavbarInner.length === 0) {\n oldNavbarInner = navbar.children('.navbar-inner[data-page=\"'+oldPage.attr('data-page')+'\"]');\n }\n }\n if (oldNavbarInner.length === 0 || newNavbarInner[0] === oldNavbarInner[0]) dynamicNavbar = false;\n }\n \n if (dynamicNavbar) {\n if (manipulateDom) newNavbarInner.insertBefore(oldNavbarInner);\n newNavbarInner[0].f7RelatedPage = newPage[0];\n newPage[0].f7RelatedNavbar = newNavbarInner[0];\n }\n if (manipulateDom) newPage.insertBefore(oldPage);\n \n // Page Init Events\n app.pageInitCallback(view, {\n pageContainer: newPage[0], \n url: url, \n position: 'left', \n navbarInnerContainer: dynamicNavbar ? newNavbarInner[0] : undefined, \n context: t7_rendered.context,\n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData,\n preloadOnly: preloadOnly\n });\n if (dynamicNavbar) {\n app.navbarInitCallback(view, newPage[0], navbar[0], newNavbarInner[0], url, 'right');\n }\n \n if (dynamicNavbar && newNavbarInner.hasClass('navbar-on-left') && animatePages) {\n app.router.prepareNavbar(newNavbarInner, oldNavbarInner, 'left');\n }\n \n if (preloadOnly) {\n view.allowPageChange = true;\n return;\n }\n \n // Update View's URL\n view.url = url;\n \n // Force reLayout\n var clientLeft = newPage[0].clientLeft;\n \n animateBack();\n return;\n }\n \n // Simple go back when we have pages on left\n if (pagesInView.length > 1 && !force) {\n // Exit if only preloadOnly\n if (preloadOnly) {\n view.allowPageChange = true;\n return;\n }\n // Update View's URL\n view.url = view.history[view.history.length - 2];\n url = view.url;\n \n // Define old and new pages\n newPage = $(pagesInView[pagesInView.length - 2]);\n oldPage = $(pagesInView[pagesInView.length - 1]);\n \n // Dynamic navbar\n if (view.params.dynamicNavbar) {\n dynamicNavbar = true;\n // Find navbar\n navbarInners = viewContainer.find('.navbar-inner:not(.cached)');\n newNavbarInner = $(navbarInners[0]);\n oldNavbarInner = $(navbarInners[1]);\n if (newNavbarInner.length === 0 || oldNavbarInner.length === 0 || oldNavbarInner[0] === newNavbarInner[0]) {\n dynamicNavbar = false;\n }\n }\n manipulateDom = false;\n setPages();\n return;\n }\n \n if (!force) {\n // Go back when there is no pages on left\n if (!preloadOnly) {\n view.url = view.history[view.history.length - 2];\n url = view.url;\n }\n \n if (content) {\n parseNewPage();\n setPages();\n return;\n }\n else if (pageName) {\n // Get dom cached pages\n newPage = $(viewContainer).find('.page[data-page=\"' + pageName + '\"]');\n if (view.params.dynamicNavbar) {\n newNavbarInner = $(viewContainer).find('.navbar-inner[data-page=\"' + pageName + '\"]');\n }\n setPages();\n return;\n }\n else {\n view.allowPageChange = true;\n return;\n }\n }\n else {\n if (url && url === view.url || pageName && view.activePage && view.activePage.name === pageName) {\n view.allowPageChange = true;\n return;\n }\n // Go back with force url\n if (content) {\n parseNewPage();\n setPages();\n return;\n }\n else if (pageName && view.params.domCache) {\n if (pageName) url = '#' + pageName;\n \n newPage = $(viewContainer).find('.page[data-page=\"' + pageName + '\"]');\n if (newPage[0].f7PageData && newPage[0].f7PageData.url) {\n url = newPage[0].f7PageData.url;\n }\n if (view.params.dynamicNavbar) {\n newNavbarInner = $(viewContainer).find('.navbar-inner[data-page=\"' + pageName + '\"]');\n if (newNavbarInner.length === 0) {\n newNavbarInner = $(newPage[0].f7RelatedNavbar);\n }\n }\n setPages();\n return;\n }\n else {\n view.allowPageChange = true;\n return;\n }\n }\n \n };\n app.router.back = function (view, options) {\n options = options || {};\n var url = options.url;\n var content = options.content;\n var pageName = options.pageName;\n if (pageName) {\n if (pageName.indexOf('?') > 0) {\n options.query = $.parseUrlQuery(pageName);\n options.pageName = pageName = pageName.split('?')[0];\n }\n }\n var force = options.force;\n if (!view.allowPageChange) return false;\n view.allowPageChange = false;\n if (app.xhr && view.xhr && view.xhr === app.xhr) {\n app.xhr.abort();\n app.xhr = false;\n }\n var pagesInView = $(view.pagesContainer).find('.page:not(.cached)');\n \n function proceed(content) {\n app.router.preprocess(content, url, function (content) {\n options.content = content;\n app.router._back(view, options);\n });\n }\n if (pagesInView.length > 1 && !force) {\n // Simple go back to previos page in view\n app.router._back(view, options);\n return;\n }\n if (!force) {\n url = options.url = view.history[view.history.length - 2];\n if (!url) {\n view.allowPageChange = true;\n return;\n }\n if (url.indexOf('#') === 0 && view.contentCache[url]) {\n proceed(view.contentCache[url]);\n return;\n }\n else if (url.indexOf('#') === 0 && view.params.domCache) {\n if (!pageName) options.pageName = url.split('#')[1];\n proceed();\n return;\n }\n else if (url.indexOf('#') !== 0) {\n // Load ajax page\n app.get(options.url, view, options.ignoreCache, function (content, error) {\n if (error) {\n view.allowPageChange = true;\n return;\n }\n proceed(content);\n });\n return;\n }\n }\n else {\n // Go back with force url\n if (!url && content) {\n proceed(content);\n return;\n }\n else if (!url && pageName) {\n if (pageName) url = '#' + pageName;\n proceed();\n return;\n }\n else if (url) {\n app.get(options.url, view, options.ignoreCache, function (content, error) {\n if (error) {\n view.allowPageChange = true;\n return;\n }\n proceed(content);\n });\n return;\n }\n }\n view.allowPageChange = true;\n return;\n };\n \n app.router.afterBack = function (view, oldPage, newPage) {\n // Remove old page and set classes on new one\n oldPage = $(oldPage);\n newPage = $(newPage);\n \n if (view.params.domCache && view.initialPages.indexOf(oldPage[0]) >= 0) {\n oldPage.removeClass('page-from-center-to-right').addClass('cached');\n }\n else {\n oldPage.remove();\n app.pageRemoveCallback(view, oldPage[0], 'right');\n }\n \n newPage.removeClass('page-from-left-to-center page-on-left').addClass('page-on-center');\n view.allowPageChange = true;\n \n // Update View's History\n var previousURL = view.history.pop();\n \n var newNavbar;\n \n // Updated dynamic navbar\n if (view.params.dynamicNavbar) {\n var inners = $(view.container).find('.navbar-inner:not(.cached)');\n var oldNavbar = $(oldPage[0].f7RelatedNavbar || inners[1]);\n if (view.params.domCache && view.initialNavbars.indexOf(oldNavbar[0]) >= 0) {\n oldNavbar.removeClass('navbar-from-center-to-right').addClass('cached');\n }\n else {\n oldNavbar.remove();\n }\n newNavbar = $(inners[0]).removeClass('navbar-on-left navbar-from-left-to-center').addClass('navbar-on-center');\n }\n \n // Remove pages in dom cache\n if (view.params.domCache) {\n $(view.container).find('.page.cached').each(function () {\n var page = $(this);\n var index = page.index();\n var pageUrl = page[0].f7PageData && page[0].f7PageData.url;\n if (pageUrl && view.history.indexOf(pageUrl) < 0 && view.initialPages.indexOf(this) < 0) {\n if (page[0].f7RelatedNavbar) $(page[0].f7RelatedNavbar).remove();\n page.remove();\n }\n });\n }\n \n // Check previous page is content based only and remove it from content cache\n if (!view.params.domCache && previousURL && previousURL.indexOf('#') > -1 && (previousURL in view.contentCache)) {\n view.contentCache[previousURL] = null;\n delete view.contentCache[previousURL];\n }\n \n if (app.params.pushState) app.pushStateClearQueue();\n \n // Preload previous page\n if (view.params.preloadPreviousPage) {\n if (view.params.domCache && view.history.length > 1) {\n var preloadUrl = view.history[view.history.length - 2];\n var previousPage;\n var previousNavbar;\n if (preloadUrl && view.pagesCache[preloadUrl]) {\n // Load by page name\n previousPage = $(view.container).find('.page[data-page=\"' + view.pagesCache[preloadUrl] + '\"]');\n previousPage.insertBefore(newPage);\n if (newNavbar) {\n previousNavbar = $(view.container).find('.navbar-inner[data-page=\"' + view.pagesCache[preloadUrl] + '\"]');\n previousNavbar.insertBefore(newNavbar);\n if(!previousNavbar || previousNavbar.length === 0) previousNavbar = newNavbar.prev('.navbar-inner.cached');\n }\n }\n else {\n // Just load previous page\n previousPage = newPage.prev('.page.cached');\n if (newNavbar) previousNavbar = newNavbar.prev('.navbar-inner.cached');\n }\n if (previousPage && previousPage.length > 0) previousPage.removeClass('cached page-on-right page-on-center').addClass('page-on-left');\n if (previousNavbar && previousNavbar.length > 0) previousNavbar.removeClass('cached navbar-on-right navbar-on-center').addClass('navbar-on-left');\n }\n else {\n app.router.back(view, {preloadOnly: true}); \n }\n }\n };\n \n"," /*======================================================\n ************ Modals ************\n ======================================================*/\n var _modalTemplateTempDiv = document.createElement('div');\n app.modalStack = [];\n app.modalStackClearQueue = function () {\n if (app.modalStack.length) {\n (app.modalStack.shift())();\n }\n };\n app.modal = function (params) {\n params = params || {};\n var modalHTML = '';\n if (app.params.modalTemplate) {\n if (!app._compiledTemplates.modal) app._compiledTemplates.modal = t7.compile(app.params.modalTemplate);\n modalHTML = app._compiledTemplates.modal(params);\n }\n else {\n var buttonsHTML = '';\n if (params.buttons && params.buttons.length > 0) {\n for (var i = 0; i < params.buttons.length; i++) {\n buttonsHTML += '<span class=\"modal-button' + (params.buttons[i].bold ? ' modal-button-bold' : '') + '\">' + params.buttons[i].text + '</span>';\n }\n }\n var titleHTML = params.title ? '<div class=\"modal-title\">' + params.title + '</div>' : '';\n var textHTML = params.text ? '<div class=\"modal-text\">' + params.text + '</div>' : '';\n var afterTextHTML = params.afterText ? params.afterText : '';\n var noButtons = !params.buttons || params.buttons.length === 0 ? 'modal-no-buttons' : '';\n var verticalButtons = params.verticalButtons ? 'modal-buttons-vertical' : '';\n modalHTML = '<div class=\"modal ' + noButtons + '\"><div class=\"modal-inner\">' + (titleHTML + textHTML + afterTextHTML) + '</div><div class=\"modal-buttons ' + verticalButtons + '\">' + buttonsHTML + '</div></div>';\n }\n \n _modalTemplateTempDiv.innerHTML = modalHTML;\n \n var modal = $(_modalTemplateTempDiv).children();\n \n $('body').append(modal[0]);\n \n // Add events on buttons\n modal.find('.modal-button').each(function (index, el) {\n $(el).on('click', function (e) {\n if (params.buttons[index].close !== false) app.closeModal(modal);\n if (params.buttons[index].onClick) params.buttons[index].onClick(modal, e);\n if (params.onClick) params.onClick(modal, index);\n });\n });\n app.openModal(modal);\n return modal[0];\n };\n app.alert = function (text, title, callbackOk) {\n if (typeof title === 'function') {\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n buttons: [ {text: app.params.modalButtonOk, bold: true, onClick: callbackOk} ]\n });\n };\n app.confirm = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n buttons: [\n {text: app.params.modalButtonCancel, onClick: callbackCancel},\n {text: app.params.modalButtonOk, bold: true, onClick: callbackOk}\n ]\n });\n };\n app.prompt = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n afterText: '<input type=\"text\" class=\"modal-text-input\">',\n buttons: [\n {\n text: app.params.modalButtonCancel\n },\n {\n text: app.params.modalButtonOk,\n bold: true\n }\n ],\n onClick: function (modal, index) {\n if (index === 0 && callbackCancel) callbackCancel($(modal).find('.modal-text-input').val());\n if (index === 1 && callbackOk) callbackOk($(modal).find('.modal-text-input').val());\n }\n });\n };\n app.modalLogin = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n afterText: '<input type=\"text\" name=\"modal-username\" placeholder=\"' + app.params.modalUsernamePlaceholder + '\" class=\"modal-text-input modal-text-input-double\"><input type=\"password\" name=\"modal-password\" placeholder=\"' + app.params.modalPasswordPlaceholder + '\" class=\"modal-text-input modal-text-input-double\">',\n buttons: [\n {\n text: app.params.modalButtonCancel\n },\n {\n text: app.params.modalButtonOk,\n bold: true\n }\n ],\n onClick: function (modal, index) {\n var username = $(modal).find('.modal-text-input[name=\"modal-username\"]').val();\n var password = $(modal).find('.modal-text-input[name=\"modal-password\"]').val();\n if (index === 0 && callbackCancel) callbackCancel(username, password);\n if (index === 1 && callbackOk) callbackOk(username, password);\n }\n });\n };\n app.modalPassword = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n afterText: '<input type=\"password\" name=\"modal-password\" placeholder=\"' + app.params.modalPasswordPlaceholder + '\" class=\"modal-text-input\">',\n buttons: [\n {\n text: app.params.modalButtonCancel\n },\n {\n text: app.params.modalButtonOk,\n bold: true\n }\n ],\n onClick: function (modal, index) {\n var password = $(modal).find('.modal-text-input[name=\"modal-password\"]').val();\n if (index === 0 && callbackCancel) callbackCancel(password);\n if (index === 1 && callbackOk) callbackOk(password);\n }\n });\n };\n app.showPreloader = function (title) {\n return app.modal({\n title: title || app.params.modalPreloaderTitle,\n text: '<div class=\"preloader\"></div>'\n });\n };\n app.hidePreloader = function () {\n app.closeModal('.modal.modal-in');\n };\n app.showIndicator = function () {\n $('body').append('<div class=\"preloader-indicator-overlay\"></div><div class=\"preloader-indicator-modal\"><span class=\"preloader preloader-white\"></span></div>');\n };\n app.hideIndicator = function () {\n $('.preloader-indicator-overlay, .preloader-indicator-modal').remove();\n };\n // Action Sheet\n app.actions = function (target, params) {\n var toPopover = false, modal, groupSelector, buttonSelector;\n if (arguments.length === 1) {\n // Actions\n params = target;\n } \n else {\n // Popover\n if (app.device.ios) {\n if (app.device.ipad) toPopover = true;\n }\n else {\n if ($(window).width() >= 768) toPopover = true;\n }\n }\n params = params || [];\n \n if (params.length > 0 && !$.isArray(params[0])) {\n params = [params];\n }\n var modalHTML;\n if (toPopover) {\n var actionsPopoverTemplate = \n '<div class=\"popover actions-popover\">' +\n '<div class=\"popover-inner\">' +\n '{{#each this}}' +\n '<div class=\"list-block\">' +\n '<ul>' +\n '{{#each this}}' +\n '{{#if label}}' +\n '<li class=\"actions-popover-label {{#if color}}color-{{color}}{{/if}} {{#if bold}}actions-popover-bold{{/if}}\">{{text}}</li>' +\n '{{else}}' +\n '<li><a href=\"#\" class=\"item-link list-button {{#if color}}color-{{color}}{{/if}} {{#if bg}}bg-{{bg}}{{/if}} {{#if bold}}actions-popover-bold{{/if}}\">{{text}}</a></li>' +\n '{{/if}}' +\n '{{/each}}' +\n '</ul>' +\n '</div>' +\n '{{/each}}' +\n '</div>' +\n '</div>';\n if (!app._compiledTemplates.actionsPopover) {\n app._compiledTemplates.actionsPopover = t7.compile(actionsPopoverTemplate);\n }\n var popoverHTML = app._compiledTemplates.actionsPopover(params);\n modal = $(app.popover(popoverHTML, target, true));\n groupSelector = '.list-block ul';\n buttonSelector = '.list-button';\n }\n else {\n if (app.params.modalActionsTemplate) {\n if (!app._compiledTemplates.actions) app._compiledTemplates.actions = t7.compile(app.params.modalActionsTemplate);\n modalHTML = app._compiledTemplates.actions(params);\n }\n else {\n var buttonsHTML = '';\n for (var i = 0; i < params.length; i++) {\n for (var j = 0; j < params[i].length; j++) {\n if (j === 0) buttonsHTML += '<div class=\"actions-modal-group\">';\n var button = params[i][j];\n var buttonClass = button.label ? 'actions-modal-label' : 'actions-modal-button';\n if (button.bold) buttonClass += ' actions-modal-button-bold';\n if (button.color) buttonClass += ' color-' + button.color;\n if (button.bg) buttonClass += ' bg-' + button.bg;\n buttonsHTML += '<span class=\"' + buttonClass + '\">' + button.text + '</span>';\n if (j === params[i].length - 1) buttonsHTML += '</div>';\n }\n }\n modalHTML = '<div class=\"actions-modal\">' + buttonsHTML + '</div>';\n }\n _modalTemplateTempDiv.innerHTML = modalHTML;\n modal = $(_modalTemplateTempDiv).children();\n $('body').append(modal[0]);\n groupSelector = '.actions-modal-group';\n buttonSelector = '.actions-modal-button';\n }\n \n var groups = modal.find(groupSelector);\n groups.each(function (index, el) {\n var groupIndex = index;\n $(el).children().each(function (index, el) {\n var buttonIndex = index;\n var buttonParams = params[groupIndex][buttonIndex];\n var clickTarget;\n if (!toPopover && $(el).is(buttonSelector)) clickTarget = $(el);\n if (toPopover && $(el).find(buttonSelector).length > 0) clickTarget = $(el).find(buttonSelector);\n \n if (clickTarget) {\n clickTarget.on('click', function (e) {\n if (buttonParams.close !== false) app.closeModal(modal);\n if (buttonParams.onClick) buttonParams.onClick(modal, e);\n });\n }\n });\n });\n if (!toPopover) app.openModal(modal);\n return modal[0];\n };\n app.popover = function (modal, target, removeOnClose) {\n if (typeof removeOnClose === 'undefined') removeOnClose = true;\n if (typeof modal === 'string' && modal.indexOf('<') >= 0) {\n var _modal = document.createElement('div');\n _modal.innerHTML = modal.trim();\n if (_modal.childNodes.length > 0) {\n modal = _modal.childNodes[0];\n if (removeOnClose) modal.classList.add('remove-on-close');\n $('body').append(modal);\n }\n else return false; //nothing found\n }\n modal = $(modal);\n target = $(target);\n if (modal.length === 0 || target.length === 0) return false;\n if (modal.find('.popover-angle').length === 0) {\n modal.append('<div class=\"popover-angle\"></div>');\n }\n modal.show();\n \n function sizePopover() {\n modal.css({left: '', top: ''});\n var modalWidth = modal.width();\n var modalHeight = modal.height(); // 13 - height of angle\n var modalAngle = modal.find('.popover-angle');\n var modalAngleSize = modalAngle.width() / 2;\n var modalAngleLeft, modalAngleTop;\n modalAngle.removeClass('on-left on-right on-top on-bottom').css({left: '', top: ''});\n \n var targetWidth = target.outerWidth();\n var targetHeight = target.outerHeight();\n var targetOffset = target.offset();\n var targetParentPage = target.parents('.page');\n if (targetParentPage.length > 0) {\n targetOffset.top = targetOffset.top - targetParentPage[0].scrollTop;\n }\n \n var windowHeight = $(window).height();\n var windowWidth = $(window).width();\n \n var modalTop = 0;\n var modalLeft = 0;\n var diff = 0;\n // Top Position\n var modalPosition = 'top';\n \n if ((modalHeight + modalAngleSize) < targetOffset.top) {\n // On top\n modalTop = targetOffset.top - modalHeight - modalAngleSize;\n }\n else if ((modalHeight + modalAngleSize) < windowHeight - targetOffset.top - targetHeight) {\n // On bottom\n modalPosition = 'bottom';\n modalTop = targetOffset.top + targetHeight + modalAngleSize;\n }\n else {\n // On middle\n modalPosition = 'middle';\n modalTop = targetHeight / 2 + targetOffset.top - modalHeight / 2;\n diff = modalTop;\n if (modalTop < 0) {\n modalTop = 5;\n }\n else if (modalTop + modalHeight > windowHeight) {\n modalTop = windowHeight - modalHeight - 5;\n }\n diff = diff - modalTop;\n }\n // Horizontal Position\n if (modalPosition === 'top' || modalPosition === 'bottom') {\n modalLeft = targetWidth / 2 + targetOffset.left - modalWidth / 2;\n diff = modalLeft;\n if (modalLeft < 5) modalLeft = 5;\n if (modalLeft + modalWidth > windowWidth) modalLeft = windowWidth - modalWidth - 5;\n if (modalPosition === 'top') modalAngle.addClass('on-bottom');\n if (modalPosition === 'bottom') modalAngle.addClass('on-top');\n diff = diff - modalLeft;\n modalAngleLeft = (modalWidth / 2 - modalAngleSize + diff);\n modalAngleLeft = Math.max(Math.min(modalAngleLeft, modalWidth - modalAngleSize * 2 - 6), 6);\n modalAngle.css({left: modalAngleLeft + 'px'});\n }\n else if (modalPosition === 'middle') {\n modalLeft = targetOffset.left - modalWidth - modalAngleSize;\n modalAngle.addClass('on-right');\n if (modalLeft < 5) {\n modalLeft = targetOffset.left + targetWidth + modalAngleSize;\n modalAngle.removeClass('on-right').addClass('on-left');\n }\n if (modalLeft + modalWidth > windowWidth) {\n modalLeft = windowWidth - modalWidth - 5;\n modalAngle.removeClass('on-right').addClass('on-left');\n }\n modalAngleTop = (modalHeight / 2 - modalAngleSize + diff);\n modalAngleTop = Math.max(Math.min(modalAngleTop, modalHeight - modalAngleSize * 2 - 6), 6);\n modalAngle.css({top: modalAngleTop + 'px'});\n }\n \n // Apply Styles\n modal.css({top: modalTop + 'px', left: modalLeft + 'px'});\n }\n sizePopover();\n \n $(window).on('resize', sizePopover);\n modal.on('close', function () {\n $(window).off('resize', sizePopover);\n });\n \n if (modal.find('.' + app.params.viewClass).length > 0) {\n app.sizeNavbars(modal.find('.' + app.params.viewClass)[0]);\n }\n \n app.openModal(modal);\n return modal[0];\n };\n app.popup = function (modal, removeOnClose) {\n if (typeof removeOnClose === 'undefined') removeOnClose = true;\n if (typeof modal === 'string' && modal.indexOf('<') >= 0) {\n var _modal = document.createElement('div');\n _modal.innerHTML = modal.trim();\n if (_modal.childNodes.length > 0) {\n modal = _modal.childNodes[0];\n if (removeOnClose) modal.classList.add('remove-on-close');\n $('body').append(modal);\n }\n else return false; //nothing found\n }\n modal = $(modal);\n if (modal.length === 0) return false;\n modal.show();\n if (modal.find('.' + app.params.viewClass).length > 0) {\n app.sizeNavbars(modal.find('.' + app.params.viewClass)[0]);\n }\n app.openModal(modal);\n return modal[0];\n };\n app.pickerModal = function (pickerModal, removeOnClose) {\n if (typeof removeOnClose === 'undefined') removeOnClose = true;\n if (typeof pickerModal === 'string' && pickerModal.indexOf('<') >= 0) {\n pickerModal = $(pickerModal);\n if (pickerModal.length > 0) {\n if (removeOnClose) pickerModal.addClass('remove-on-close');\n $('body').append(pickerModal[0]);\n }\n else return false; //nothing found\n }\n pickerModal = $(pickerModal);\n if (pickerModal.length === 0) return false;\n pickerModal.show();\n app.openModal(pickerModal);\n return pickerModal[0];\n };\n app.loginScreen = function (modal) {\n if (!modal) modal = '.login-screen';\n modal = $(modal);\n if (modal.length === 0) return false;\n modal.show();\n if (modal.find('.' + app.params.viewClass).length > 0) {\n app.sizeNavbars(modal.find('.' + app.params.viewClass)[0]);\n }\n app.openModal(modal);\n return modal[0];\n };\n app.openModal = function (modal) {\n modal = $(modal);\n var isModal = modal.hasClass('modal');\n if ($('.modal.modal-in:not(.modal-out)').length && app.params.modalStack && isModal) {\n app.modalStack.push(function () {\n app.openModal(modal);\n });\n return;\n }\n var isPopover = modal.hasClass('popover');\n var isPopup = modal.hasClass('popup');\n var isLoginScreen = modal.hasClass('login-screen');\n var isPickerModal = modal.hasClass('picker-modal');\n if (isModal) {\n modal.show();\n modal.css({\n marginTop: - Math.round(modal.outerHeight() / 2) + 'px'\n });\n }\n \n var overlay;\n if (!isLoginScreen && !isPickerModal) {\n if ($('.modal-overlay').length === 0 && !isPopup) {\n $('body').append('<div class=\"modal-overlay\"></div>');\n }\n if ($('.popup-overlay').length === 0 && isPopup) {\n $('body').append('<div class=\"popup-overlay\"></div>');\n }\n overlay = isPopup ? $('.popup-overlay') : $('.modal-overlay');\n }\n \n //Make sure that styles are applied, trigger relayout;\n var clientLeft = modal[0].clientLeft;\n \n // Trugger open event\n modal.trigger('open');\n \n // Picker modal body class\n if (isPickerModal) {\n $('body').addClass('with-picker-modal');\n }\n \n // Classes for transition in\n if (!isLoginScreen && !isPickerModal) overlay.addClass('modal-overlay-visible');\n modal.removeClass('modal-out').addClass('modal-in').transitionEnd(function (e) {\n if (modal.hasClass('modal-out')) modal.trigger('closed');\n else modal.trigger('opened');\n });\n return true;\n };\n app.closeModal = function (modal) {\n modal = $(modal || '.modal-in');\n if (typeof modal !== 'undefined' && modal.length === 0) {\n return;\n }\n var isModal = modal.hasClass('modal');\n var isPopover = modal.hasClass('popover');\n var isPopup = modal.hasClass('popup');\n var isLoginScreen = modal.hasClass('login-screen');\n var isPickerModal = modal.hasClass('picker-modal');\n \n var removeOnClose = modal.hasClass('remove-on-close');\n \n var overlay = isPopup ? $('.popup-overlay') : $('.modal-overlay');\n if (isPopup){\n if (modal.length === $('.popup.modal-in').length) {\n overlay.removeClass('modal-overlay-visible'); \n } \n }\n else if (!isPickerModal) {\n overlay.removeClass('modal-overlay-visible');\n }\n \n modal.trigger('close');\n \n // Picker modal body class\n if (isPickerModal) {\n $('body').removeClass('with-picker-modal');\n $('body').addClass('picker-modal-closing');\n }\n \n if (!isPopover) {\n modal.removeClass('modal-in').addClass('modal-out').transitionEnd(function (e) {\n if (modal.hasClass('modal-out')) modal.trigger('closed');\n else modal.trigger('opened');\n \n if (isPickerModal) {\n $('body').removeClass('picker-modal-closing');\n }\n if (isPopup || isLoginScreen || isPickerModal) {\n modal.removeClass('modal-out').hide();\n if (removeOnClose && modal.length > 0) {\n modal.remove();\n }\n }\n else {\n modal.remove();\n }\n });\n if (isModal && app.params.modalStack) {\n app.modalStackClearQueue();\n }\n }\n else {\n modal.removeClass('modal-in modal-out').trigger('closed').hide();\n if (removeOnClose) {\n modal.remove();\n }\n }\n return true;\n };\n \n"," /*======================================================\n ************ Panels ************\n ======================================================*/\n app.allowPanelOpen = true;\n app.openPanel = function (panelPosition) {\n if (!app.allowPanelOpen) return false;\n var panel = $('.panel-' + panelPosition);\n if (panel.length === 0 || panel.hasClass('active')) return false;\n app.closePanel(); // Close if some panel is opened\n app.allowPanelOpen = false;\n var effect = panel.hasClass('panel-reveal') ? 'reveal' : 'cover';\n panel.css({display: 'block'}).addClass('active');\n panel.trigger('open');\n if (panel.find('.' + app.params.viewClass).length > 0) {\n if (app.sizeNavbars) app.sizeNavbars(panel.find('.' + app.params.viewClass)[0]);\n }\n \n // Trigger reLayout\n var clientLeft = panel[0].clientLeft;\n \n // Transition End;\n var transitionEndTarget = effect === 'reveal' ? $('.' + app.params.viewsClass) : panel;\n var openedTriggered = false;\n \n function panelTransitionEnd() {\n transitionEndTarget.transitionEnd(function (e) {\n if ($(e.target).is(transitionEndTarget)) {\n if (panel.hasClass('active')) {\n panel.trigger('opened');\n }\n else {\n panel.trigger('closed');\n }\n app.allowPanelOpen = true;\n }\n else panelTransitionEnd();\n });\n }\n panelTransitionEnd();\n \n $('body').addClass('with-panel-' + panelPosition + '-' + effect);\n return true;\n };\n app.closePanel = function () {\n var activePanel = $('.panel.active');\n if (activePanel.length === 0) return false;\n var effect = activePanel.hasClass('panel-reveal') ? 'reveal' : 'cover';\n var panelPosition = activePanel.hasClass('panel-left') ? 'left' : 'right';\n activePanel.removeClass('active');\n var transitionEndTarget = effect === 'reveal' ? $('.' + app.params.viewsClass) : activePanel;\n activePanel.trigger('close');\n app.allowPanelOpen = false;\n \n transitionEndTarget.transitionEnd(function () {\n if (activePanel.hasClass('active')) return;\n activePanel.css({display: ''});\n activePanel.trigger('closed');\n $('body').removeClass('panel-closing');\n app.allowPanelOpen = true;\n });\n \n $('body').addClass('panel-closing').removeClass('with-panel-' + panelPosition + '-' + effect);\n };\n /*======================================================\n ************ Swipe panels ************\n ======================================================*/\n app.initSwipePanels = function () {\n var panel, side;\n if (app.params.swipePanel) {\n panel = $('.panel.panel-' + app.params.swipePanel);\n side = app.params.swipePanel;\n if (panel.length === 0) return;\n }\n else {\n if (app.params.swipePanelOnlyClose) {\n if ($('.panel').length === 0) return;\n }\n else return;\n }\n \n var panelOverlay = $('.panel-overlay');\n var isTouched, isMoved, isScrolling, touchesStart = {}, touchStartTime, touchesDiff, translate, opened, panelWidth, effect, direction;\n var views = $('.' + app.params.viewsClass);\n \n function handleTouchStart(e) {\n if (!app.allowPanelOpen || (!app.params.swipePanel && !app.params.swipePanelOnlyClose) || isTouched) return;\n if ($('.modal-in, .photo-browser-in').length > 0) return;\n if (!(app.params.swipePanelCloseOpposite || app.params.swipePanelOnlyClose)) {\n if ($('.panel.active').length > 0 && !panel.hasClass('active')) return;\n }\n touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n if (app.params.swipePanelCloseOpposite || app.params.swipePanelOnlyClose) {\n if ($('.panel.active').length > 0) {\n side = $('.panel.active').hasClass('panel-left') ? 'left' : 'right';\n }\n else {\n side = app.params.swipePanel;\n }\n }\n panel = $('.panel.panel-' + side);\n opened = panel.hasClass('active');\n if (app.params.swipePanelActiveArea && !opened) {\n if (side === 'left') {\n if (touchesStart.x > app.params.swipePanelActiveArea) return;\n }\n if (side === 'right') {\n if (touchesStart.x < window.innerWidth - app.params.swipePanelActiveArea) return;\n }\n }\n isMoved = false;\n isTouched = true;\n isScrolling = undefined;\n \n touchStartTime = (new Date()).getTime();\n direction = undefined;\n }\n function handleTouchMove(e) {\n if (!isTouched) return;\n if (e.f7PreventPanelSwipe) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));\n }\n if (isScrolling) {\n isTouched = false;\n return;\n }\n if (!direction) {\n if (pageX > touchesStart.x) {\n direction = 'to-right';\n }\n else {\n direction = 'to-left';\n }\n \n if (\n side === 'left' &&\n (\n direction === 'to-left' && !panel.hasClass('active')\n ) ||\n side === 'right' &&\n (\n direction === 'to-right' && !panel.hasClass('active')\n )\n )\n {\n isTouched = false;\n return;\n }\n }\n \n if (app.params.swipePanelNoFollow) {\n var timeDiff = (new Date()).getTime() - touchStartTime;\n if (timeDiff < 300) {\n if (direction === 'to-left') {\n if (side === 'right') app.openPanel(side);\n if (side === 'left' && panel.hasClass('active')) app.closePanel();\n }\n if (direction === 'to-right') {\n if (side === 'left') app.openPanel(side);\n if (side === 'right' && panel.hasClass('active')) app.closePanel();\n }\n }\n isTouched = false;\n isMoved = false;\n return;\n }\n \n if (!isMoved) {\n effect = panel.hasClass('panel-cover') ? 'cover' : 'reveal';\n if (!opened) {\n panel.show();\n panelOverlay.show();\n }\n panelWidth = panel[0].offsetWidth;\n panel.transition(0);\n if (panel.find('.' + app.params.viewClass).length > 0) {\n if (app.sizeNavbars) app.sizeNavbars(panel.find('.' + app.params.viewClass)[0]);\n }\n }\n \n isMoved = true;\n \n e.preventDefault();\n var threshold = opened ? 0 : -app.params.swipePanelThreshold;\n if (side === 'right') threshold = -threshold;\n \n touchesDiff = pageX - touchesStart.x + threshold;\n \n if (side === 'right') {\n translate = touchesDiff - (opened ? panelWidth : 0);\n if (translate > 0) translate = 0;\n if (translate < -panelWidth) {\n translate = -panelWidth;\n }\n }\n else {\n translate = touchesDiff + (opened ? panelWidth : 0);\n if (translate < 0) translate = 0;\n if (translate > panelWidth) {\n translate = panelWidth;\n }\n }\n if (effect === 'reveal') {\n views.transform('translate3d(' + translate + 'px,0,0)').transition(0);\n panelOverlay.transform('translate3d(' + translate + 'px,0,0)');\n app.pluginHook('swipePanelSetTransform', views[0], panel[0], Math.abs(translate / panelWidth));\n }\n else {\n panel.transform('translate3d(' + translate + 'px,0,0)').transition(0);\n app.pluginHook('swipePanelSetTransform', views[0], panel[0], Math.abs(translate / panelWidth));\n }\n }\n function handleTouchEnd(e) {\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n isTouched = false;\n isMoved = false;\n var timeDiff = (new Date()).getTime() - touchStartTime;\n var action;\n var edge = (translate === 0 || Math.abs(translate) === panelWidth);\n \n if (!opened) {\n if (translate === 0) {\n action = 'reset';\n }\n else if (\n timeDiff < 300 && Math.abs(translate) > 0 ||\n timeDiff >= 300 && (Math.abs(translate) >= panelWidth / 2)\n ) {\n action = 'swap';\n }\n else {\n action = 'reset';\n }\n }\n else {\n if (translate === -panelWidth) {\n action = 'reset';\n }\n else if (\n timeDiff < 300 && Math.abs(translate) >= 0 ||\n timeDiff >= 300 && (Math.abs(translate) <= panelWidth / 2)\n ) {\n if (side === 'left' && translate === panelWidth) action = 'reset';\n else action = 'swap';\n }\n else {\n action = 'reset';\n }\n }\n if (action === 'swap') {\n app.allowPanelOpen = true;\n if (opened) {\n app.closePanel();\n if (edge) {\n panel.css({display: ''});\n $('body').removeClass('panel-closing');\n }\n }\n else {\n app.openPanel(side);\n }\n if (edge) app.allowPanelOpen = true;\n }\n if (action === 'reset') {\n if (opened) {\n app.allowPanelOpen = true;\n app.openPanel(side);\n }\n else {\n app.closePanel();\n if (edge) {\n app.allowPanelOpen = true;\n panel.css({display: ''});\n }\n else {\n var target = effect === 'reveal' ? views : panel;\n $('body').addClass('panel-closing');\n target.transitionEnd(function () {\n app.allowPanelOpen = true;\n panel.css({display: ''});\n $('body').removeClass('panel-closing');\n });\n }\n }\n }\n if (effect === 'reveal') {\n views.transition('');\n views.transform('');\n }\n panel.transition('').transform('');\n panelOverlay.css({display: ''}).transform('');\n }\n $(document).on(app.touchEvents.start, handleTouchStart);\n $(document).on(app.touchEvents.move, handleTouchMove);\n $(document).on(app.touchEvents.end, handleTouchEnd);\n };\n \n"," /*======================================================\n ************ Image Lazy Loading ************\n ************ Based on solution by Marc Godard, https://github.com/MarcGodard ************\n ======================================================*/\n app.initImagesLazyLoad = function (pageContainer) {\n pageContainer = $(pageContainer);\n \n // Lazy images\n var lazyLoadImages;\n if (pageContainer.hasClass('lazy')) {\n lazyLoadImages = pageContainer;\n pageContainer = lazyLoadImages.parents('.page');\n }\n else {\n lazyLoadImages = pageContainer.find('.lazy');\n }\n if (lazyLoadImages.length === 0) return;\n \n // Scrollable page content\n var pageContent;\n if (pageContainer.hasClass('page-content')) {\n pageContent = pageContainer;\n pageContainer = pageContainer.parents('.page');\n }\n else {\n pageContent = pageContainer.find('.page-content');\n }\n if (pageContent.length === 0) return;\n \n // Placeholder\n var placeholderSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEXCwsK592mkAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==';\n if (typeof app.params.imagesLazyLoadPlaceholder === 'string') {\n placeholderSrc = app.params.imagesLazyLoadPlaceholder;\n }\n if (app.params.imagesLazyLoadPlaceholder !== false) lazyLoadImages.attr('src', placeholderSrc);\n \n // load image\n var imagesSequence = [];\n var imageIsLoading = false;\n function loadImage(el) {\n el = $(el);\n \n var bg = el.attr('data-background');\n var src = bg ? bg : el.attr('data-src');\n if (!src) return;\n \n function onLoad() {\n el.removeClass('lazy').addClass('lazy-loaded');\n if (bg) {\n el.css('background-image', 'url(' + src + ')');\n }\n else {\n el.attr('src', src);\n }\n \n if (app.params.imagesLazyLoadSequential) {\n imageIsLoading = false;\n if (imagesSequence.length > 0) {\n loadImage(imagesSequence.shift());\n }\n }\n }\n \n if (!app.params.imagesLazyLoadSequential) {\n onLoad();\n return;\n }\n \n if (imageIsLoading) {\n if (imagesSequence.indexOf(el[0]) < 0) imagesSequence.push(el[0]);\n return;\n }\n \n // Loading flag\n imageIsLoading = true;\n \n var image = new Image();\n image.onload = onLoad;\n image.onerror = onLoad;\n image.src =src;\n }\n function lazyHandler() {\n lazyLoadImages = pageContainer.find('.lazy');\n lazyLoadImages.each(function(index, el) {\n el = $(el);\n if (isElementInViewport(el[0])) {\n loadImage(el);\n }\n });\n }\n \n function isElementInViewport (el) {\n var rect = el.getBoundingClientRect();\n var threshold = app.params.imagesLazyLoadThreshold || 0;\n return (\n rect.top >= (0 - threshold) &&\n rect.left >= (0 - threshold) &&\n rect.top <= (window.innerHeight + threshold) &&\n rect.left <= (window.innerWidth + threshold)\n );\n }\n \n function attachEvents(destroy) {\n var method = destroy ? 'off' : 'on';\n lazyLoadImages[method]('lazy', lazyHandler);\n pageContent[method]('lazy', lazyHandler);\n pageContent[method]('scroll', lazyHandler);\n $(window)[method]('resize', lazyHandler);\n }\n function detachEvents() {\n attachEvents(true);\n }\n \n // Store detach function\n pageContainer[0].f7DestroyImagesLazyLoad = detachEvents;\n \n // Attach events\n attachEvents();\n \n // Destroy on page remove\n if (pageContainer.hasClass('page')) {\n pageContainer.once('pageBeforeRemove', detachEvents);\n }\n \n // Run loader on page load/init\n lazyHandler();\n \n // Run after page animation\n pageContainer.once('pageAfterAnimation', lazyHandler);\n };\n app.destroyImagesLazyLoad = function (pageContainer) {\n pageContainer = $(pageContainer);\n if (pageContainer.length > 0 && pageContainer[0].f7DestroyImagesLazyLoad) {\n pageContainer[0].f7DestroyLazyLoad();\n }\n };\n app.reinitImagesLazyLoad = function (pageContainer) {\n pageContainer = $(pageContainer);\n if (pageContainer.length > 0) {\n pageContainer.trigger('lazy');\n }\n };\n"," /*======================================================\n ************ Messages ************\n ======================================================*/\n app.initMessages = function (pageContainer) {\n var page = $(pageContainer);\n var messages = page.find('.messages');\n if (messages.length === 0) return;\n var pageContent = page.find('.page-content');\n if (messages.hasClass('messages-auto-layout')) app.updateMessagesLayout(messages);\n if (!messages.hasClass('new-messages-first')) pageContent[0].scrollTop = pageContent[0].scrollHeight - pageContent[0].offsetHeight;\n };\n app.addMessage = function (props, messagesContent, addToTop) {\n props = props || {};\n props.type = props.type || 'sent';\n if (!props.text || props.length === 0) return false;\n messagesContent = $(messagesContent || '.messages-content');\n if (messagesContent.length === 0) return false;\n var messages = messagesContent.find('.messages');\n var newOnTop = messages.hasClass('new-messages-first');\n \n if (typeof addToTop === 'undefined') {\n addToTop = newOnTop ? true : false;\n }\n var method = addToTop ? 'prepend' : 'append';\n \n var html = '';\n if (props.day) {\n html += '<div class=\"messages-date\">' + props.day + (props.time ? ',' : '') + (props.time ? ' <span>' + props.time + '</span>' : '') + '</div>';\n }\n var isPic = props.text.indexOf('<img') >= 0 ? 'message-pic' : '';\n var withAvatar = props.avatar ? 'message-with-avatar' : '';\n var messageClass = 'message' + ' message-' + props.type + ' ' + isPic + ' ' + withAvatar + ' message-appear-from-' + (method === 'append' ? 'bottom' : 'top');\n html += '<div class=\"' + messageClass + '\">' +\n (props.name ? '<div class=\"message-name\">' + props.name + '</div>' : '') +\n '<div class=\"message-text\">' + props.text + '</div>' +\n (props.avatar ? '<div class=\"message-avatar\" style=\"background-image:url(' + props.avatar + ')\"></div>' : '') +\n (props.label ? '<div class=\"message-label\">' + props.label + '</div>' : '') +\n '</div>';\n messages[method](html);\n if (messages.hasClass('messages-auto-layout')) app.updateMessagesLayout(messages);\n if ((method === 'append' && !newOnTop) || (method === 'prepend' && newOnTop)) {\n app.scrollMessagesContainer(messagesContent);\n }\n };\n app.updateMessagesLayout = function (messages) {\n messages.find('.message').each(function () {\n var message = $(this);\n if (message.find('.message-text img').length > 0) message.addClass('message-pic');\n if (message.find('.message-avatar').length > 0) message.addClass('message-with-avatar');\n });\n messages.find('.message-sent').each(function () {\n var message = $(this);\n var next = message.next('.message-sent');\n var prev = message.prev('.message-sent');\n if (next.length === 0) {\n message.addClass('message-last message-with-tail');\n }\n else message.removeClass('message-last message-with-tail');\n \n if (prev.length === 0) {\n message.addClass('message-first');\n }\n else message.removeClass('message-first');\n // Search for changed names\n if (prev.length > 0 && prev.find('.message-name').length > 0 && message.find('.message-name').length > 0) {\n if (prev.find('.message-name').text() !== message.find('.message-name').text()) {\n prev.addClass('message-last message-with-tail');\n message.addClass('message-first');\n }\n }\n });\n messages.find('.message-received').each(function () {\n var message = $(this);\n var next = message.next('.message-received');\n var prev = message.prev('.message-received');\n if (next.length === 0) {\n message.addClass('message-last message-with-tail');\n }\n else message.removeClass('message-last message-with-tail');\n \n if (prev.length === 0) {\n message.addClass('message-first');\n }\n else message.removeClass('message-first');\n \n // Search for changed names\n if (prev.length > 0 && prev.find('.message-name').length > 0 && message.find('.message-name').length > 0) {\n if (prev.find('.message-name').text() !== message.find('.message-name').text()) {\n prev.addClass('message-last message-with-tail');\n message.addClass('message-first');\n }\n }\n });\n };\n app.scrollMessagesContainer = function (messagesContent) {\n messagesContent = $(messagesContent || '.messages-content');\n if (messagesContent.length === 0) return;\n var messages = messagesContent.find('.messages');\n var newOnTop = messages.hasClass('new-messages-first');\n var currentScroll = messagesContent[0].scrollTop;\n var newScroll = newOnTop ? 0 : messagesContent[0].scrollHeight - messagesContent[0].offsetHeight;\n if (newScroll === currentScroll) return;\n messagesContent.scrollTop(newScroll, 400);\n };\n \n"," /*===============================================================================\n ************ Swipeout Actions (Swipe to delete) ************\n ===============================================================================*/\n app.swipeoutOpenedEl = undefined;\n app.allowSwipeout = true;\n app.initSwipeout = function (swipeoutEl) {\n var isTouched, isMoved, isScrolling, touchesStart = {}, touchStartTime, touchesDiff, swipeOutEl, swipeOutContent, actionsRight, actionsLeft, actionsLeftWidth, actionsRightWidth, translate, opened, openedActions, buttonsLeft, buttonsRight, direction, overswipeLeftButton, overswipeRightButton, overswipeLeft, overswipeRight, noFoldLeft, noFoldRight;\n $(document).on(app.touchEvents.start, function (e) {\n if (app.swipeoutOpenedEl) {\n var target = $(e.target);\n if (!(\n app.swipeoutOpenedEl.is(target[0]) ||\n target.parents('.swipeout').is(app.swipeoutOpenedEl) ||\n target.hasClass('modal-in') ||\n target.parents('.modal.modal-in').length > 0 ||\n target.hasClass('modal-overlay')\n )) {\n app.swipeoutClose(app.swipeoutOpenedEl);\n }\n }\n });\n \n function handleTouchStart(e) {\n if (!app.allowSwipeout) return;\n isMoved = false;\n isTouched = true;\n isScrolling = undefined;\n touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n }\n function handleTouchMove(e) {\n if (!isTouched) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));\n }\n if (isScrolling) {\n isTouched = false;\n return;\n }\n \n if (!isMoved) {\n if ($('.list-block.sortable-opened').length > 0) return;\n /*jshint validthis:true */\n swipeOutEl = $(this);\n swipeOutContent = swipeOutEl.find('.swipeout-content');\n actionsRight = swipeOutEl.find('.swipeout-actions-right');\n actionsLeft = swipeOutEl.find('.swipeout-actions-left');\n actionsLeftWidth = actionsRightWidth = buttonsLeft = buttonsRight = overswipeRightButton = overswipeLeftButton = null;\n noFoldLeft = actionsLeft.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;\n noFoldRight = actionsRight.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;\n if (actionsLeft.length > 0) {\n actionsLeftWidth = actionsLeft.outerWidth();\n buttonsLeft = actionsLeft.children('a');\n overswipeLeftButton = actionsLeft.find('.swipeout-overswipe');\n }\n if (actionsRight.length > 0) {\n actionsRightWidth = actionsRight.outerWidth();\n buttonsRight = actionsRight.children('a');\n overswipeRightButton = actionsRight.find('.swipeout-overswipe');\n }\n opened = swipeOutEl.hasClass('swipeout-opened');\n if (opened) {\n openedActions = swipeOutEl.find('.swipeout-actions-left.swipeout-actions-opened').length > 0 ? 'left' : 'right';\n }\n swipeOutEl.removeClass('transitioning');\n if (!app.params.swipeoutNoFollow) {\n swipeOutEl.find('.swipeout-actions-opened').removeClass('swipeout-actions-opened');\n swipeOutEl.removeClass('swipeout-opened');\n }\n }\n isMoved = true;\n e.preventDefault();\n \n touchesDiff = pageX - touchesStart.x;\n translate = touchesDiff;\n \n if (opened) {\n if (openedActions === 'right') translate = translate - actionsRightWidth;\n else translate = translate + actionsLeftWidth;\n }\n \n if (translate > 0 && actionsLeft.length === 0 || translate < 0 && actionsRight.length === 0) {\n if (!opened) {\n isTouched = isMoved = false;\n return;\n }\n translate = 0;\n }\n \n if (translate < 0) direction = 'to-left';\n else if (translate > 0) direction = 'to-right';\n else {\n if (direction) direction = direction;\n else direction = 'to-left';\n }\n \n var i, buttonOffset, progress;\n \n e.f7PreventPanelSwipe = true;\n if (app.params.swipeoutNoFollow) {\n if (opened) {\n if (openedActions === 'right' && touchesDiff > 0) {\n app.swipeoutClose(swipeOutEl);\n }\n if (openedActions === 'left' && touchesDiff < 0) {\n app.swipeoutClose(swipeOutEl);\n }\n }\n else {\n if (touchesDiff < 0 && actionsRight.length > 0) {\n app.swipeoutOpen(swipeOutEl, 'right');\n }\n if (touchesDiff > 0 && actionsLeft.length > 0) {\n app.swipeoutOpen(swipeOutEl, 'left');\n }\n }\n isTouched = false;\n isMoved = false;\n return;\n }\n overswipeLeft = false;\n overswipeRight = false;\n var $button;\n if (actionsRight.length > 0) {\n // Show right actions\n progress = translate / actionsRightWidth;\n if (translate < -actionsRightWidth) {\n translate = -actionsRightWidth - Math.pow(-translate - actionsRightWidth, 0.8);\n if (overswipeRightButton.length > 0) {\n overswipeRight = true;\n }\n }\n for (i = 0; i < buttonsRight.length; i++) {\n if (typeof buttonsRight[i]._buttonOffset === 'undefined') {\n buttonsRight[i]._buttonOffset = buttonsRight[i].offsetLeft;\n }\n buttonOffset = buttonsRight[i]._buttonOffset;\n $button = $(buttonsRight[i]);\n if (overswipeRightButton.length > 0 && $button.hasClass('swipeout-overswipe')) {\n $button.css({left: (overswipeRight ? -buttonOffset : 0) + 'px'});\n }\n $button.transform('translate3d(' + (translate - buttonOffset * (1 + Math.max(progress, -1))) + 'px,0,0)');\n }\n }\n if (actionsLeft.length > 0) {\n // Show left actions\n progress = translate / actionsLeftWidth;\n if (translate > actionsLeftWidth) {\n translate = actionsLeftWidth + Math.pow(translate - actionsLeftWidth, 0.8);\n if (overswipeLeftButton.length > 0) {\n overswipeLeft = true;\n }\n }\n for (i = 0; i < buttonsLeft.length; i++) {\n if (typeof buttonsLeft[i]._buttonOffset === 'undefined') {\n buttonsLeft[i]._buttonOffset = actionsLeftWidth - buttonsLeft[i].offsetLeft - buttonsLeft[i].offsetWidth;\n }\n buttonOffset = buttonsLeft[i]._buttonOffset;\n $button = $(buttonsLeft[i]);\n if (overswipeLeftButton.length > 0 && $button.hasClass('swipeout-overswipe')) {\n $button.css({left: (overswipeLeft ? buttonOffset : 0) + 'px'});\n }\n if (buttonsLeft.length > 1) {\n $button.css('z-index', buttonsLeft.length - i); \n }\n $button.transform('translate3d(' + (translate + buttonOffset * (1 - Math.min(progress, 1))) + 'px,0,0)');\n }\n }\n swipeOutContent.transform('translate3d(' + translate + 'px,0,0)');\n }\n function handleTouchEnd(e) {\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n \n isTouched = false;\n isMoved = false;\n var timeDiff = (new Date()).getTime() - touchStartTime;\n var action, actionsWidth, actions, buttons, i, noFold;\n \n noFold = direction === 'to-left' ? noFoldRight : noFoldLeft;\n actions = direction === 'to-left' ? actionsRight : actionsLeft;\n actionsWidth = direction === 'to-left' ? actionsRightWidth : actionsLeftWidth;\n \n if (\n timeDiff < 300 && (touchesDiff < -10 && direction === 'to-left' || touchesDiff > 10 && direction === 'to-right') ||\n timeDiff >= 300 && Math.abs(translate) > actionsWidth / 2\n ) {\n action = 'open';\n }\n else {\n action = 'close';\n }\n if (timeDiff < 300) {\n if (Math.abs(translate) === 0) action = 'close';\n if (Math.abs(translate) === actionsWidth) action = 'open';\n }\n \n if (action === 'open') {\n app.swipeoutOpenedEl = swipeOutEl;\n swipeOutEl.trigger('open');\n swipeOutEl.addClass('swipeout-opened transitioning');\n var newTranslate = direction === 'to-left' ? -actionsWidth : actionsWidth;\n swipeOutContent.transform('translate3d(' + newTranslate + 'px,0,0)');\n actions.addClass('swipeout-actions-opened');\n buttons = direction === 'to-left' ? buttonsRight : buttonsLeft;\n if (buttons) {\n for (i = 0; i < buttons.length; i++) {\n $(buttons[i]).transform('translate3d(' + newTranslate + 'px,0,0)');\n }\n }\n if (overswipeRight) {\n actionsRight.find('.swipeout-overswipe')[0].click();\n }\n if (overswipeLeft) {\n actionsLeft.find('.swipeout-overswipe')[0].click();\n }\n }\n else {\n swipeOutEl.trigger('close');\n app.swipeoutOpenedEl = undefined;\n swipeOutEl.addClass('transitioning').removeClass('swipeout-opened');\n swipeOutContent.transform('');\n actions.removeClass('swipeout-actions-opened');\n }\n \n var buttonOffset;\n if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) {\n for (i = 0; i < buttonsLeft.length; i++) {\n buttonOffset = buttonsLeft[i]._buttonOffset;\n if (typeof buttonOffset === 'undefined') {\n buttonsLeft[i]._buttonOffset = actionsLeftWidth - buttonsLeft[i].offsetLeft - buttonsLeft[i].offsetWidth;\n }\n $(buttonsLeft[i]).transform('translate3d(' + (buttonOffset) + 'px,0,0)');\n }\n }\n if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) {\n for (i = 0; i < buttonsRight.length; i++) {\n buttonOffset = buttonsRight[i]._buttonOffset;\n if (typeof buttonOffset === 'undefined') {\n buttonsRight[i]._buttonOffset = buttonsRight[i].offsetLeft;\n }\n $(buttonsRight[i]).transform('translate3d(' + (-buttonOffset) + 'px,0,0)');\n }\n }\n swipeOutContent.transitionEnd(function (e) {\n if (opened && action === 'open' || closed && action === 'close') return;\n swipeOutEl.trigger(action === 'open' ? 'opened' : 'closed');\n if (opened && action === 'close') {\n if (actionsRight.length > 0) {\n buttonsRight.transform('');\n }\n if (actionsLeft.length > 0) {\n buttonsLeft.transform('');\n }\n }\n });\n }\n if (swipeoutEl) {\n $(swipeoutEl).on(app.touchEvents.start, handleTouchStart);\n $(swipeoutEl).on(app.touchEvents.move, handleTouchMove);\n $(swipeoutEl).on(app.touchEvents.end, handleTouchEnd);\n }\n else {\n $(document).on(app.touchEvents.start, '.list-block li.swipeout', handleTouchStart);\n $(document).on(app.touchEvents.move, '.list-block li.swipeout', handleTouchMove);\n $(document).on(app.touchEvents.end, '.list-block li.swipeout', handleTouchEnd);\n }\n \n };\n app.swipeoutOpen = function (el, dir, callback) {\n el = $(el);\n if (arguments.length === 2) {\n if (typeof arguments[1] === 'function') {\n callback = dir;\n }\n }\n \n if (el.length === 0) return;\n if (el.length > 1) el = $(el[0]);\n if (!el.hasClass('swipeout') || el.hasClass('swipeout-opened')) return;\n if (!dir) {\n if (el.find('.swipeout-actions-right').length > 0) dir = 'right';\n else dir = 'left';\n }\n var swipeOutActions = el.find('.swipeout-actions-' + dir);\n if (swipeOutActions.length === 0) return;\n var noFold = swipeOutActions.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;\n el.trigger('open').addClass('swipeout-opened').removeClass('transitioning');\n swipeOutActions.addClass('swipeout-actions-opened');\n var buttons = swipeOutActions.children('a');\n var swipeOutActionsWidth = swipeOutActions.outerWidth();\n var translate = dir === 'right' ? -swipeOutActionsWidth : swipeOutActionsWidth;\n var i;\n if (buttons.length > 1) {\n for (i = 0; i < buttons.length; i++) {\n if (dir === 'right') {\n $(buttons[i]).transform('translate3d(' + (- buttons[i].offsetLeft) + 'px,0,0)');\n }\n else {\n $(buttons[i]).css('z-index', buttons.length - i).transform('translate3d(' + (swipeOutActionsWidth - buttons[i].offsetWidth - buttons[i].offsetLeft) + 'px,0,0)');\n }\n }\n var clientLeft = buttons[1].clientLeft;\n }\n el.addClass('transitioning');\n for (i = 0; i < buttons.length; i++) {\n $(buttons[i]).transform('translate3d(' + (translate) + 'px,0,0)');\n }\n el.find('.swipeout-content').transform('translate3d(' + translate + 'px,0,0)').transitionEnd(function () {\n el.trigger('opened');\n if (callback) callback.call(el[0]);\n });\n app.swipeoutOpenedEl = el;\n };\n app.swipeoutClose = function (el, callback) {\n el = $(el);\n if (el.length === 0) return;\n if (!el.hasClass('swipeout-opened')) return;\n var dir = el.find('.swipeout-actions-opened').hasClass('swipeout-actions-right') ? 'right' : 'left';\n var swipeOutActions = el.find('.swipeout-actions-opened').removeClass('swipeout-actions-opened');\n var noFold = swipeOutActions.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;\n var buttons = swipeOutActions.children('a');\n var swipeOutActionsWidth = swipeOutActions.outerWidth();\n app.allowSwipeout = false;\n el.trigger('close');\n el.removeClass('swipeout-opened').addClass('transitioning');\n el.find('.swipeout-content').transform('translate3d(' + 0 + 'px,0,0)').transitionEnd(function () {\n app.allowSwipeout = true;\n buttons.transform('');\n el.trigger('closed');\n if (callback) callback.call(el[0]);\n });\n for (var i = 0; i < buttons.length; i++) {\n if (dir === 'right') {\n $(buttons[i]).transform('translate3d(' + (-buttons[i].offsetLeft) + 'px,0,0)');\n }\n else {\n $(buttons[i]).transform('translate3d(' + (swipeOutActionsWidth - buttons[i].offsetWidth - buttons[i].offsetLeft) + 'px,0,0)');\n }\n $(buttons[i]).css({left:0 + 'px'});\n }\n if (app.swipeoutOpenedEl && app.swipeoutOpenedEl[0] === el[0]) app.swipeoutOpenedEl = undefined;\n };\n app.swipeoutDelete = function (el, callback) {\n el = $(el);\n if (el.length === 0) return;\n if (el.length > 1) el = $(el[0]);\n app.swipeoutOpenedEl = undefined;\n el.trigger('delete');\n el.css({height: el.outerHeight() + 'px'});\n var clientLeft = el[0].clientLeft;\n el.css({height: 0 + 'px'}).addClass('deleting transitioning').transitionEnd(function () {\n el.trigger('deleted');\n if (callback) callback.call(el[0]);\n if (el.parents('.virtual-list').length > 0) {\n var virtualList = el.parents('.virtual-list')[0].f7VirtualList;\n var virtualIndex = el[0].f7VirtualListIndex;\n if (virtualList && typeof virtualIndex !== 'undefined') virtualList.deleteItem(virtualIndex);\n }\n else {\n el.remove();\n }\n });\n var translate = '-100%';\n el.find('.swipeout-content').transform('translate3d(' + translate + ',0,0)');\n };\n \n"," /*===============================================================================\n ************ Sortable ************\n ===============================================================================*/\n app.sortableToggle = function (sortableContainer) {\n sortableContainer = $(sortableContainer);\n if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');\n sortableContainer.toggleClass('sortable-opened');\n if (sortableContainer.hasClass('sortable-opened')) {\n sortableContainer.trigger('open');\n }\n else {\n sortableContainer.trigger('close');\n }\n return sortableContainer;\n };\n app.sortableOpen = function (sortableContainer) {\n sortableContainer = $(sortableContainer);\n if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');\n sortableContainer.addClass('sortable-opened');\n sortableContainer.trigger('open');\n return sortableContainer;\n };\n app.sortableClose = function (sortableContainer) {\n sortableContainer = $(sortableContainer);\n if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');\n sortableContainer.removeClass('sortable-opened');\n sortableContainer.trigger('close');\n return sortableContainer;\n };\n app.initSortable = function () {\n var isTouched, isMoved, touchStartY, touchesDiff, sortingEl, sortingElHeight, sortingItems, minTop, maxTop, insertAfter, insertBefore, sortableContainer;\n \n function handleTouchStart(e) {\n isMoved = false;\n isTouched = true;\n touchStartY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n /*jshint validthis:true */\n sortingEl = $(this).parent();\n sortingItems = sortingEl.parent().find('li');\n sortableContainer = sortingEl.parents('.sortable');\n e.preventDefault();\n app.allowPanelOpen = app.allowSwipeout = false;\n }\n function handleTouchMove(e) {\n if (!isTouched || !sortingEl) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (!isMoved) {\n sortingEl.addClass('sorting');\n sortableContainer.addClass('sortable-sorting');\n minTop = sortingEl[0].offsetTop;\n maxTop = sortingEl.parent().height() - sortingEl[0].offsetTop - sortingEl.height();\n sortingElHeight = sortingEl[0].offsetHeight;\n }\n isMoved = true;\n \n e.preventDefault();\n e.f7PreventPanelSwipe = true;\n touchesDiff = pageY - touchStartY;\n var translate = touchesDiff;\n if (translate < -minTop) translate = -minTop;\n if (translate > maxTop) translate = maxTop;\n sortingEl.transform('translate3d(0,' + translate + 'px,0)');\n \n insertBefore = insertAfter = undefined;\n \n sortingItems.each(function () {\n var currentEl = $(this);\n if (currentEl[0] === sortingEl[0]) return;\n var currentElOffset = currentEl[0].offsetTop;\n var currentElHeight = currentEl.height();\n var sortingElOffset = sortingEl[0].offsetTop + translate;\n \n if ((sortingElOffset >= currentElOffset - currentElHeight / 2) && sortingEl.index() < currentEl.index()) {\n currentEl.transform('translate3d(0, '+(-sortingElHeight)+'px,0)');\n insertAfter = currentEl;\n insertBefore = undefined;\n }\n else if ((sortingElOffset <= currentElOffset + currentElHeight / 2) && sortingEl.index() > currentEl.index()) {\n currentEl.transform('translate3d(0, '+(sortingElHeight)+'px,0)');\n insertAfter = undefined;\n if (!insertBefore) insertBefore = currentEl;\n }\n else {\n $(this).transform('translate3d(0, 0%,0)');\n }\n });\n }\n function handleTouchEnd(e) {\n app.allowPanelOpen = app.allowSwipeout = true;\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n e.preventDefault();\n sortingItems.transform('');\n sortingEl.removeClass('sorting');\n sortableContainer.removeClass('sortable-sorting');\n var virtualList, oldIndex, newIndex;\n if (insertAfter) {\n sortingEl.insertAfter(insertAfter);\n sortingEl.trigger('sort');\n }\n if (insertBefore) {\n sortingEl.insertBefore(insertBefore);\n sortingEl.trigger('sort');\n }\n if ((insertAfter || insertBefore) && sortableContainer.hasClass('virtual-list')) {\n virtualList = sortableContainer[0].f7VirtualList;\n oldIndex = sortingEl[0].f7VirtualListIndex;\n newIndex = insertBefore ? insertBefore[0].f7VirtualListIndex : insertAfter[0].f7VirtualListIndex;\n if (virtualList) virtualList.moveItem(oldIndex, newIndex);\n }\n insertAfter = insertBefore = undefined;\n isTouched = false;\n isMoved = false;\n }\n $(document).on(app.touchEvents.start, '.list-block.sortable .sortable-handler', handleTouchStart);\n if (app.support.touch) {\n $(document).on(app.touchEvents.move, '.list-block.sortable .sortable-handler', handleTouchMove);\n $(document).on(app.touchEvents.end, '.list-block.sortable .sortable-handler', handleTouchEnd);\n }\n else {\n $(document).on(app.touchEvents.move, handleTouchMove);\n $(document).on(app.touchEvents.end, handleTouchEnd);\n }\n \n };\n \n"," /*===============================================================================\n ************ Smart Select ************\n ===============================================================================*/\n app.initSmartSelects = function (pageContainer) {\n var page = $(pageContainer);\n if (page.length === 0) return;\n \n var selects = page.find('.smart-select');\n if (selects.length === 0) return;\n \n selects.each(function () {\n var smartSelect = $(this);\n \n var $select = smartSelect.find('select');\n if ($select.length === 0) return;\n \n var select = $select[0];\n if (select.length === 0) return;\n \n var valueText = [];\n for (var i = 0; i < select.length; i++) {\n if (select[i].selected) valueText.push(select[i].textContent.trim());\n }\n \n var itemAfter = smartSelect.find('.item-after');\n if (itemAfter.length === 0) {\n smartSelect.find('.item-inner').append('<div class=\"item-after\">' + valueText.join(', ') + '</div>');\n }\n else {\n var selectedText = itemAfter.text();\n if (itemAfter.hasClass('smart-select-value')) {\n for (i = 0; i < select.length; i++) {\n select[i].selected = select[i].textContent.trim() === selectedText.trim();\n }\n } else {\n itemAfter.text(valueText);\n }\n }\n \n });\n \n };\n app.smartSelectOpen = function (smartSelect) {\n smartSelect = $(smartSelect);\n if (smartSelect.length === 0) return;\n \n // Find related view\n var view = smartSelect.parents('.' + app.params.viewClass);\n if (view.length === 0) return;\n view = view[0].f7View;\n if (!view) return;\n \n // Parameters\n var openIn = smartSelect.attr('data-open-in');\n if (!openIn) openIn = app.params.smartSelectInPopup ? 'popup' : 'page';\n \n var pageTitle = smartSelect.attr('data-page-title') || smartSelect.find('.item-title').text();\n var backText = smartSelect.attr('data-back-text') || app.params.smartSelectBackText;\n var closeText = smartSelect.attr('data-popup-close-text') || smartSelect.attr('data-back-text') || app.params.smartSelectPopupCloseText ;\n var backOnSelect = smartSelect.attr('data-back-onselect') ? (smartSelect.attr('data-back-onselect') === 'true' ? true : false) : app.params.smartSelectBackOnSelect;\n var formTheme = smartSelect.attr('data-form-theme') || app.params.smartSelectFormTheme;\n var navbarTheme = smartSelect.attr('data-navbar-theme') || app.params.smartSelectNavbarTheme;\n var virtualList = smartSelect.attr('data-virtual-list') === 'true';\n var virtualListItemHeight = smartSelect.attr('data-virtual-list-height');\n \n // Collect all options/values\n var select = smartSelect.find('select')[0];\n var $select = $(select);\n if (select.disabled || smartSelect.hasClass('disabled') || $select.hasClass('disabled')) {\n return;\n }\n var values = [];\n var id = (new Date()).getTime();\n var inputType = select.multiple ? 'checkbox' : 'radio';\n var inputName = inputType + '-' + id;\n var option, optionHasMedia, optionImage, optionIcon, optionGroup, optionGroupLabel, optionPreviousGroup, optionShowGroupLabel, previousGroup;\n for (var i = 0; i < select.length; i++) {\n option = $(select[i]);\n if (option[0].disabled) continue;\n optionImage = option.attr('data-option-image') || $select.attr('data-option-image');\n optionIcon = option.attr('data-option-icon') || $select.attr('data-option-icon');\n optionHasMedia = optionImage || optionIcon || inputType === 'checkbox';\n optionGroup = option.parent('optgroup')[0];\n optionGroupLabel = optionGroup && optionGroup.label;\n optionShowGroupLabel = false;\n if (optionGroup) {\n if (optionGroup !== previousGroup) {\n optionShowGroupLabel = true;\n previousGroup = optionGroup;\n }\n }\n values.push({\n value: option[0].value,\n text: option[0].textContent.trim(),\n selected: option[0].selected,\n group: optionGroup,\n groupLabel: optionGroupLabel,\n showGroupLabel: optionShowGroupLabel,\n image: optionImage,\n icon: optionIcon,\n disabled: option[0].disabled,\n inputType: inputType,\n id: id,\n hasMedia: optionHasMedia,\n checkbox: inputType === 'checkbox',\n inputName: inputName,\n test: this\n });\n }\n \n \n // Item template/HTML\n if (!app._compiledTemplates.smartSelectItem) {\n app._compiledTemplates.smartSelectItem = t7.compile(app.params.smartSelectItemTemplate || \n '{{#if showGroupLabel}}' +\n '<li class=\"item-divider\">{{groupLabel}}</li>' +\n '{{/if}}' +\n '<li>' +\n '<label class=\"label-{{inputType}} item-content\">' +\n '<input type=\"{{inputType}}\" name=\"{{inputName}}\" value=\"{{value}}\" {{#if selected}}checked{{/if}}>' +\n '{{#if hasMedia}}' +\n '<div class=\"item-media\">' +\n '{{#if checkbox}}<i class=\"icon icon-form-checkbox\"></i>{{/if}}' +\n '{{#if icon}}<i class=\"icon {{icon}}\"></i>{{/if}}' +\n '{{#if image}}<img src=\"{{image}}\">{{/if}}' +\n '</div>' +\n '{{/if}}' +\n '<div class=\"item-inner\">' +\n '<div class=\"item-title\">{{text}}</div>' +\n '</div>' +\n '</label>' +\n '</li>'\n );\n }\n var smartSelectItemTemplate = app._compiledTemplates.smartSelectItem;\n \n var inputsHTML = '';\n if (!virtualList) {\n for (var j = 0; j < values.length; j++) {\n inputsHTML += smartSelectItemTemplate(values[j]);\n }\n }\n \n // Navbar HTML\n if (!app._compiledTemplates.smartSelectNavbar) {\n app._compiledTemplates.smartSelectNavbar = t7.compile(app.params.smartSelectNavbarTemplate || \n '<div class=\"navbar {{#if navbarTheme}}theme-{{navbarTheme}}{{/if}}\">' +\n '<div class=\"navbar-inner\">' +\n '{{leftTemplate}}' +\n '<div class=\"center sliding\">{{pageTitle}}</div>' +\n '</div>' +\n '</div>'\n );\n }\n var navbarHTML = app._compiledTemplates.smartSelectNavbar({\n pageTitle: pageTitle,\n backText: backText,\n closeText: closeText,\n openIn: openIn,\n navbarTheme: navbarTheme,\n inPopup: openIn === 'popup',\n inPage: openIn === 'page',\n leftTemplate: openIn === 'popup' ? app.params.smartSelectPopupCloseTemplate.replace(/{{closeText}}/g, closeText) : app.params.smartSelectBackTemplate.replace(/{{backText}}/g, backText)\n });\n \n \n // Determine navbar layout type - static/fixed/through\n var noNavbar = '', noToolbar = '', navbarLayout;\n if (openIn === 'page') {\n navbarLayout = 'static';\n if (smartSelect.parents('.navbar-through').length > 0) navbarLayout = 'through';\n if (smartSelect.parents('.navbar-fixed').length > 0) navbarLayout = 'fixed';\n noToolbar = smartSelect.parents('.page').hasClass('no-toolbar') ? 'no-toolbar' : '';\n noNavbar = smartSelect.parents('.page').hasClass('no-navbar') ? 'no-navbar' : 'navbar-' + navbarLayout;\n }\n else {\n navbarLayout = 'fixed';\n }\n \n \n // Page Layout\n var pageName = 'smart-select-' + inputName;\n \n var useSearchbar = typeof smartSelect.data('searchbar') === 'undefined' ? app.params.smartSelectSearchbar : (smartSelect.data('searchbar') === 'true' ? true : false);\n var searchbarPlaceholder, searchbarCancel;\n \n if (useSearchbar) {\n searchbarPlaceholder = smartSelect.data('searchbar-placeholder') || 'Search';\n searchbarCancel = smartSelect.data('searchbar-cancel') || 'Cancel';\n }\n \n var searchbarHTML = '<form class=\"searchbar\" data-search-list=\".smart-select-list-' + id + '\" data-search-in=\".item-title\">' +\n '<div class=\"searchbar-input\">' +\n '<input type=\"search\" placeholder=\"' + searchbarPlaceholder + '\">' +\n '<a href=\"#\" class=\"searchbar-clear\"></a>' +\n '</div>' +\n '<a href=\"#\" class=\"searchbar-cancel\">' + searchbarCancel + '</a>' +\n '</form>' +\n '<div class=\"searchbar-overlay\"></div>';\n \n var pageHTML =\n (navbarLayout === 'through' ? navbarHTML : '') +\n '<div class=\"pages\">' +\n ' <div data-page=\"' + pageName + '\" class=\"page smart-select-page ' + noNavbar + ' ' + noToolbar + '\">' +\n (navbarLayout === 'fixed' ? navbarHTML : '') +\n (useSearchbar ? searchbarHTML : '') +\n ' <div class=\"page-content\">' +\n (navbarLayout === 'static' ? navbarHTML : '') +\n ' <div class=\"list-block ' + (virtualList ? 'virtual-list' : '') + ' smart-select-list-' + id + ' ' + (formTheme ? 'theme-' + formTheme : '') + '\">' +\n ' <ul>' +\n (virtualList ? '' : inputsHTML) +\n ' </ul>' +\n ' </div>' +\n ' </div>' +\n ' </div>' +\n '</div>';\n \n // Define popup\n var popup;\n \n // Event Listeners on new page\n function handleInputs(container) {\n if (virtualList) {\n var virtualListInstance = app.virtualList($(container).find('.virtual-list'), {\n items: values,\n template: smartSelectItemTemplate,\n height: virtualListItemHeight || undefined,\n searchByItem: function (query, index, item) {\n if (item.text.toLowerCase().indexOf(query.trim()) >=0 ) return true;\n return false;\n }\n });\n $(container).once(openIn === 'popup' ? 'closed': 'pageBeforeRemove', function () {\n if (virtualListInstance && virtualListInstance.destroy) virtualListInstance.destroy();\n });\n }\n $(container).on('change', 'input[name=\"' + inputName + '\"]', function () {\n var input = this;\n var value = input.value;\n var optionText = [];\n if (input.type === 'checkbox') {\n var values = [];\n for (var i = 0; i < select.options.length; i++) {\n var option = select.options[i];\n if (option.value === value) {\n option.selected = input.checked;\n }\n if (option.selected) {\n optionText.push(option.textContent.trim());\n }\n }\n }\n else {\n optionText = [smartSelect.find('option[value=\"' + value + '\"]').text()];\n select.value = value;\n }\n \n $select.trigger('change');\n smartSelect.find('.item-after').text(optionText.join(', '));\n if (backOnSelect && inputType === 'radio') {\n if (openIn === 'popup') app.closeModal(popup);\n else view.router.back();\n }\n });\n }\n function pageInit(e) {\n var page = e.detail.page;\n if (page.name === pageName) {\n $(document).off('pageInit', pageInit);\n handleInputs(page.container);\n }\n }\n \n // Load content\n if (openIn === 'popup') {\n popup = app.popup(\n '<div class=\"popup smart-select-popup smart-select-popup-' + inputName + '\">' +\n '<div class=\"view navbar-fixed\">' +\n pageHTML +\n '</div>' +\n '</div>'\n );\n app.initPage($(popup).find('.page'));\n handleInputs(popup);\n }\n else {\n $(document).on('pageInit', pageInit);\n view.router.load({content: pageHTML});\n }\n };\n \n"," /*===============================================================================\n ************ Virtual List ************\n ===============================================================================*/\n var VirtualList = function (listBlock, params) {\n var defaults = {\n cols: 1,\n height: 44,\n cache: true,\n dynamicHeightBufferSize: 1\n };\n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n \n // Preparation\n var vl = this;\n vl.listBlock = $(listBlock);\n vl.params = params;\n vl.items = params.items;\n if (params.template) {\n if (typeof params.template === 'string') vl.template = t7.compile(params.template);\n else if (typeof params.template === 'function') vl.template = params.template;\n }\n vl.pageContent = vl.listBlock.parents('.page-content');\n \n // Bad scroll\n var updatableScroll;\n if (typeof vl.params.updatableScroll !== 'undefined') {\n updatableScroll = vl.params.updatableScroll;\n }\n else {\n updatableScroll = true;\n if (app.device.ios && app.device.osVersion.split('.')[0] < 8) {\n updatableScroll = false;\n }\n }\n \n // Append <ul>\n vl.ul = vl.params.ul ? $(vl.params.ul) : vl.listBlock.children('ul');\n if (vl.ul.length === 0) {\n vl.listBlock.append('<ul></ul>');\n vl.ul = vl.listBlock.children('ul');\n }\n \n // DOM cached items\n vl.domCache = {};\n vl.displayDomCache = {};\n \n // Temporary DOM Element\n vl.tempDomElement = document.createElement('ul');\n \n // Last repain position\n vl.lastRepaintY = null;\n \n // Fragment\n vl.fragment = document.createDocumentFragment();\n \n // Filter\n vl.filterItems = function (indexes, resetScrollTop) {\n vl.filteredItems = [];\n var firstIndex = indexes[0];\n var lastIndex = indexes[indexes.length - 1];\n for (var i = 0; i < indexes.length; i++) {\n vl.filteredItems.push(vl.items[indexes[i]]);\n }\n if (typeof resetScrollTop === 'undefined') resetScrollTop = true;\n if (resetScrollTop) {\n vl.pageContent[0].scrollTop = 0;\n }\n vl.update();\n };\n vl.resetFilter = function () {\n vl.filteredItems = null;\n delete vl.filteredItems;\n vl.update();\n };\n \n var pageHeight, rowsPerScreen, rowsBefore, rowsAfter, rowsToRender, maxBufferHeight = 0, listHeight;\n var dynamicHeight = typeof vl.params.height === 'function';\n \n // Set list size\n vl.setListSize = function () {\n var items = vl.filteredItems || vl.items;\n pageHeight = vl.pageContent[0].offsetHeight;\n if (dynamicHeight) {\n listHeight = 0;\n vl.heights = [];\n for (var i = 0; i < items.length; i++) {\n var itemHeight = vl.params.height(items[i]);\n listHeight += itemHeight;\n vl.heights.push(itemHeight);\n }\n }\n else {\n listHeight = items.length * vl.params.height / vl.params.cols;\n rowsPerScreen = Math.ceil(pageHeight / vl.params.height);\n rowsBefore = vl.params.rowsBefore || rowsPerScreen * 2;\n rowsAfter = vl.params.rowsAfter || rowsPerScreen;\n rowsToRender = (rowsPerScreen + rowsBefore + rowsAfter);\n maxBufferHeight = rowsBefore / 2 * vl.params.height;\n }\n \n if (updatableScroll) {\n vl.ul.css({height: listHeight + 'px'});\n }\n };\n \n // Render items\n vl.render = function (force, forceScrollTop) {\n if (force) vl.lastRepaintY = null;\n \n var scrollTop = -(vl.listBlock[0].getBoundingClientRect().top + vl.pageContent[0].getBoundingClientRect().top);\n if (typeof forceScrollTop !== 'undefined') scrollTop = forceScrollTop;\n \n if (vl.lastRepaintY === null || Math.abs(scrollTop - vl.lastRepaintY) > maxBufferHeight || (!updatableScroll && (vl.pageContent[0].scrollTop + pageHeight >= vl.pageContent[0].scrollHeight))) {\n vl.lastRepaintY = scrollTop;\n }\n else {\n return;\n }\n \n var items = vl.filteredItems || vl.items, \n fromIndex, toIndex, heightBeforeFirstItem = 0, heightBeforeLastItem = 0;\n if (dynamicHeight) {\n var itemTop = 0, j, itemHeight; \n maxBufferHeight = pageHeight;\n \n for (j = 0; j < vl.heights.length; j++) {\n itemHeight = vl.heights[j];\n if (typeof fromIndex === 'undefined') {\n if (itemTop + itemHeight >= scrollTop - pageHeight * 2 * vl.params.dynamicHeightBufferSize) fromIndex = j;\n else heightBeforeFirstItem += itemHeight;\n }\n \n if (typeof toIndex === 'undefined') {\n if (itemTop + itemHeight >= scrollTop + pageHeight * 2 * vl.params.dynamicHeightBufferSize || j === vl.heights.length - 1) toIndex = j + 1;\n heightBeforeLastItem += itemHeight;\n }\n itemTop += itemHeight;\n }\n toIndex = Math.min(toIndex, items.length);\n }\n else {\n fromIndex = (parseInt(scrollTop / vl.params.height) - rowsBefore) * vl.params.cols;\n if (fromIndex < 0) {\n fromIndex = 0;\n }\n toIndex = Math.min(fromIndex + rowsToRender * vl.params.cols, items.length);\n }\n \n var topPosition;\n vl.reachEnd = false;\n for (var i = fromIndex; i < toIndex; i++) {\n var item, index;\n // Define real item index\n index = vl.items.indexOf(items[i]);\n \n if (i === fromIndex) vl.currentFromIndex = index;\n if (i === toIndex - 1) vl.currentToIndex = index;\n if (index === vl.items.length - 1) vl.reachEnd = true;\n \n // Find items\n if (vl.domCache[index]) {\n item = vl.domCache[index];\n }\n else {\n if (vl.template) {\n vl.tempDomElement.innerHTML = vl.template(items[i], {index: index});\n }\n else if (vl.params.renderItem) {\n vl.tempDomElement.innerHTML = vl.params.renderItem(index, items[i]); \n }\n else {\n vl.tempDomElement.innerHTML = items[i];\n }\n item = vl.tempDomElement.childNodes[0];\n if (vl.params.cache) vl.domCache[index] = item;\n }\n item.f7VirtualListIndex = index;\n \n // Set item top position\n if (i === fromIndex) {\n if (dynamicHeight) {\n topPosition = heightBeforeFirstItem;\n }\n else {\n topPosition = (i * vl.params.height / vl.params.cols);\n }\n }\n item.style.top = topPosition + 'px';\n \n // Before item insert\n if (vl.params.onItemBeforeInsert) vl.params.onItemBeforeInsert(vl, item);\n \n // Append item to fragment\n vl.fragment.appendChild(item);\n \n \n }\n \n // Update list height with not updatable scroll\n if (!updatableScroll) {\n if (dynamicHeight) {\n vl.ul[0].style.height = heightBeforeLastItem + 'px';\n }\n else {\n vl.ul[0].style.height = i * vl.params.height / vl.params.cols + 'px';\n }\n }\n \n \n // Update list html\n if (vl.params.onBeforeClear) vl.params.onBeforeClear(vl, vl.fragment);\n vl.ul[0].innerHTML = '';\n \n if (vl.params.onItemsBeforeInsert) vl.params.onItemsBeforeInsert(vl, vl.fragment);\n vl.ul[0].appendChild(vl.fragment);\n if (vl.params.onItemsAfterInsert) vl.params.onFragmentAfterInsert(vl, vl.fragment);\n \n if (typeof forceScrollTop !== 'undefined' && force) {\n vl.pageContent.scrollTop(forceScrollTop, 0);\n }\n };\n \n vl.scrollToItem = function (index) {\n if (index > vl.items.length) return false;\n \n var itemTop = 0, listTop;\n if (dynamicHeight) {\n for (var i = 0; i < index; i++) {\n itemTop += vl.heights[i];\n }\n }\n else {\n itemTop = index * vl.params.height;\n }\n listTop = vl.listBlock[0].offsetTop;\n vl.render(true, listTop + itemTop - parseInt(vl.pageContent.css('padding-top'), 10));\n return true;\n };\n \n // Handle scroll event\n vl.handleScroll = function (e) {\n vl.render();\n };\n // Handle resize event\n vl.handleResize = function (e) {\n vl.setListSize();\n vl.render(true);\n };\n \n vl.attachEvents = function (detach) {\n var action = detach ? 'off' : 'on';\n vl.pageContent[action]('scroll', vl.handleScroll);\n $(window)[action]('resize', vl.handleResize);\n };\n \n // Init Virtual List\n vl.init = function () {\n vl.attachEvents();\n vl.setListSize();\n vl.render();\n };\n \n // Append\n vl.appendItems = function (items) {\n for (var i = 0; i < items.length; i++) {\n vl.items.push(items[i]);\n }\n vl.update();\n };\n vl.appendItem = function (item) {\n vl.appendItems([item]);\n };\n // Replace\n vl.replaceAllItems = function (items) {\n vl.items = items;\n delete vl.filteredItems;\n vl.domCache = {};\n vl.update();\n };\n vl.replaceItem = function (index, item) {\n vl.items[index] = item;\n if (vl.params.cache) delete vl.domCache[index];\n vl.update();\n };\n // Prepend\n vl.prependItems = function (items) {\n for (var i = items.length - 1; i >= 0; i--) {\n vl.items.unshift(items[i]);\n }\n if (vl.params.cache) {\n var newCache = {};\n for (var cached in vl.domCache) {\n newCache[parseInt(cached, 10) + items.length] = vl.domCache[cached];\n }\n vl.domCache = newCache;\n }\n vl.update();\n };\n vl.prependItem = function (item) {\n vl.prependItems([item]);\n };\n \n // Move\n vl.moveItem = function (oldIndex, newIndex) {\n if (oldIndex === newIndex) return;\n // remove item from array\n var item = vl.items.splice(oldIndex, 1)[0];\n if (newIndex >= vl.items.length) {\n // Add item to the end\n vl.items.push(item);\n newIndex = vl.items.length - 1;\n }\n else {\n // Add item to new index\n vl.items.splice(newIndex, 0, item);\n }\n // Update cache\n if (vl.params.cache) {\n var newCache = {};\n for (var cached in vl.domCache) {\n var cachedIndex = parseInt(cached, 10);\n var leftIndex = oldIndex < newIndex ? oldIndex : newIndex;\n var rightIndex = oldIndex < newIndex ? newIndex : oldIndex;\n var indexShift = oldIndex < newIndex ? -1 : 1;\n if (cachedIndex < leftIndex || cachedIndex > rightIndex) newCache[cachedIndex] = vl.domCache[cachedIndex];\n if (cachedIndex === leftIndex) newCache[rightIndex] = vl.domCache[cachedIndex];\n if (cachedIndex > leftIndex && cachedIndex <= rightIndex) newCache[cachedIndex + indexShift] = vl.domCache[cachedIndex];\n }\n vl.domCache = newCache;\n }\n vl.update();\n };\n // Insert before\n vl.insertItemBefore = function (index, item) {\n if (index === 0) {\n vl.prependItem(item);\n return;\n }\n if (index >= vl.items.length) {\n vl.appendItem(item);\n return;\n }\n vl.items.splice(index, 0, item);\n // Update cache\n if (vl.params.cache) {\n var newCache = {};\n for (var cached in vl.domCache) {\n var cachedIndex = parseInt(cached, 10);\n if (cachedIndex >= index) {\n newCache[cachedIndex + 1] = vl.domCache[cachedIndex];\n }\n }\n vl.domCache = newCache;\n }\n vl.update();\n };\n // Delete\n vl.deleteItems = function (indexes) {\n var prevIndex, indexShift = 0;\n for (var i = 0; i < indexes.length; i++) {\n var index = indexes[i];\n if (typeof prevIndex !== 'undefined') {\n if (index > prevIndex) {\n indexShift = -i;\n }\n }\n index = index + indexShift;\n prevIndex = indexes[i];\n // Delete item\n var deletedItem = vl.items.splice(index, 1)[0];\n \n // Delete from filtered\n if (vl.filteredItems && vl.filteredItems.indexOf(deletedItem) >= 0) {\n vl.filteredItems.splice(vl.filteredItems.indexOf(deletedItem), 1);\n }\n // Update cache\n if (vl.params.cache) {\n var newCache = {};\n for (var cached in vl.domCache) {\n var cachedIndex = parseInt(cached, 10);\n if (cachedIndex === index) {\n delete vl.domCache[index];\n }\n else if (parseInt(cached, 10) > index) {\n newCache[cachedIndex - 1] = vl.domCache[cached];\n }\n else {\n newCache[cachedIndex] = vl.domCache[cached]; \n }\n }\n vl.domCache = newCache;\n }\n }\n vl.update();\n };\n vl.deleteAllItems = function () {\n vl.items = [];\n delete vl.filteredItems;\n if (vl.params.cache) vl.domCache = {};\n vl.update();\n };\n vl.deleteItem = function (index) {\n vl.deleteItems([index]);\n };\n \n // Clear cache\n vl.clearCache = function () {\n vl.domCache = {};\n };\n \n // Update Virtual List\n vl.update = function () {\n vl.setListSize();\n vl.render(true);\n };\n \n // Destroy\n vl.destroy = function () {\n vl.attachEvents(true);\n delete vl.items;\n delete vl.domCache;\n };\n \n // Init Virtual List\n vl.init();\n \n // Store vl in container\n vl.listBlock[0].f7VirtualList = vl;\n return vl;\n };\n \n // App Method\n app.virtualList = function (listBlock, params) {\n return new VirtualList(listBlock, params);\n };\n \n app.reinitVirtualList = function (pageContainer) {\n var page = $(pageContainer);\n var vlists = page.find('.virtual-list');\n if (vlists.length === 0) return;\n for (var i = 0; i < vlists.length; i++) {\n var vlistInstance = vlistInstance[0].f7VirtualList;\n if (vlistInstance) {\n vlistInstance.update();\n }\n }\n };\n"," /*======================================================\n ************ Pull To Refresh ************\n ======================================================*/\n app.initPullToRefresh = function (pageContainer) {\n var eventsTarget = $(pageContainer);\n if (!eventsTarget.hasClass('pull-to-refresh-content')) {\n eventsTarget = eventsTarget.find('.pull-to-refresh-content');\n }\n if (!eventsTarget || eventsTarget.length === 0) return;\n \n var isTouched, isMoved, touchesStart = {}, isScrolling, touchesDiff, touchStartTime, container, refresh = false, useTranslate = false, startTranslate = 0, translate, scrollTop, wasScrolled, layer, triggerDistance, dynamicTriggerDistance;\n var page = eventsTarget.hasClass('page') ? eventsTarget : eventsTarget.parents('.page');\n var hasNavbar = false;\n if (page.find('.navbar').length > 0 || page.parents('.navbar-fixed, .navbar-through').length > 0 || page.hasClass('navbar-fixed') || page.hasClass('navbar-through')) hasNavbar = true;\n if (page.hasClass('no-navbar')) hasNavbar = false;\n if (!hasNavbar) eventsTarget.addClass('pull-to-refresh-no-navbar');\n \n container = eventsTarget;\n \n // Define trigger distance\n if (container.attr('data-ptr-distance')) {\n dynamicTriggerDistance = true;\n }\n else {\n triggerDistance = 44; \n }\n \n function handleTouchStart(e) {\n if (isTouched) {\n if (app.device.os === 'android') {\n if ('targetTouches' in e && e.targetTouches.length > 1) return;\n }\n else return;\n }\n isMoved = false;\n isTouched = true;\n isScrolling = undefined;\n wasScrolled = undefined;\n touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n /*jshint validthis:true */\n container = $(this);\n }\n \n function handleTouchMove(e) {\n if (!isTouched) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));\n }\n if (!isScrolling) {\n isTouched = false;\n return;\n }\n \n scrollTop = container[0].scrollTop;\n if (typeof wasScrolled === 'undefined' && scrollTop !== 0) wasScrolled = true; \n \n if (!isMoved) {\n /*jshint validthis:true */\n container.removeClass('transitioning');\n if (scrollTop > container[0].offsetHeight) {\n isTouched = false;\n return;\n }\n if (dynamicTriggerDistance) {\n triggerDistance = container.attr('data-ptr-distance');\n if (triggerDistance.indexOf('%') >= 0) triggerDistance = container[0].offsetHeight * parseInt(triggerDistance, 10) / 100;\n }\n startTranslate = container.hasClass('refreshing') ? triggerDistance : 0;\n if (container[0].scrollHeight === container[0].offsetHeight || app.device.os !== 'ios') {\n useTranslate = true;\n }\n else {\n useTranslate = false;\n }\n }\n isMoved = true;\n touchesDiff = pageY - touchesStart.y;\n \n if (touchesDiff > 0 && scrollTop <= 0 || scrollTop < 0) {\n // iOS 8 fix\n if (app.device.os === 'ios' && parseInt(app.device.osVersion.split('.')[0], 10) > 7 && scrollTop === 0 && !wasScrolled) useTranslate = true;\n \n if (useTranslate) {\n e.preventDefault();\n translate = (Math.pow(touchesDiff, 0.85) + startTranslate);\n container.transform('translate3d(0,' + translate + 'px,0)');\n }\n else {\n }\n if ((useTranslate && Math.pow(touchesDiff, 0.85) > triggerDistance) || (!useTranslate && touchesDiff >= triggerDistance * 2)) {\n refresh = true;\n container.addClass('pull-up').removeClass('pull-down');\n }\n else {\n refresh = false;\n container.removeClass('pull-up').addClass('pull-down');\n }\n }\n else {\n \n container.removeClass('pull-up pull-down');\n refresh = false;\n return;\n }\n }\n function handleTouchEnd(e) {\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n if (translate) {\n container.addClass('transitioning');\n translate = 0;\n }\n container.transform('');\n if (refresh) {\n container.addClass('refreshing');\n container.trigger('refresh', {\n done: function () {\n app.pullToRefreshDone(container);\n }\n });\n }\n else {\n container.removeClass('pull-down');\n }\n isTouched = false;\n isMoved = false;\n }\n \n // Attach Events\n eventsTarget.on(app.touchEvents.start, handleTouchStart);\n eventsTarget.on(app.touchEvents.move, handleTouchMove);\n eventsTarget.on(app.touchEvents.end, handleTouchEnd);\n \n // Detach Events on page remove\n if (page.length === 0) return;\n function destroyPullToRefresh() {\n eventsTarget.off(app.touchEvents.start, handleTouchStart);\n eventsTarget.off(app.touchEvents.move, handleTouchMove);\n eventsTarget.off(app.touchEvents.end, handleTouchEnd);\n }\n eventsTarget[0].f7DestroyPullToRefresh = destroyPullToRefresh;\n function detachEvents() {\n destroyPullToRefresh();\n page.off('pageBeforeRemove', detachEvents);\n }\n page.on('pageBeforeRemove', detachEvents);\n \n };\n \n app.pullToRefreshDone = function (container) {\n container = $(container);\n if (container.length === 0) container = $('.pull-to-refresh-content.refreshing');\n container.removeClass('refreshing').addClass('transitioning');\n container.transitionEnd(function () {\n container.removeClass('transitioning pull-up pull-down');\n });\n };\n app.pullToRefreshTrigger = function (container) {\n container = $(container);\n if (container.length === 0) container = $('.pull-to-refresh-content');\n if (container.hasClass('refreshing')) return;\n container.addClass('transitioning refreshing');\n container.trigger('refresh', {\n done: function () {\n app.pullToRefreshDone(container);\n }\n });\n };\n \n app.destroyPullToRefresh = function (pageContainer) {\n pageContainer = $(pageContainer);\n var pullToRefreshContent = pageContainer.hasClass('pull-to-refresh-content') ? pageContainer : pageContainer.find('.pull-to-refresh-content');\n if (pullToRefreshContent.length === 0) return;\n if (pullToRefreshContent[0].f7DestroyPullToRefresh) pullToRefreshContent[0].f7DestroyPullToRefresh();\n };\n \n"," /* ===============================================================================\n ************ Infinite Scroll ************\n =============================================================================== */\n function handleInfiniteScroll() {\n /*jshint validthis:true */\n var inf = $(this);\n var scrollTop = inf[0].scrollTop;\n var scrollHeight = inf[0].scrollHeight;\n var height = inf[0].offsetHeight;\n var distance = inf[0].getAttribute('data-distance');\n var virtualListContainer = inf.find('.virtual-list');\n var virtualList;\n var onTop = inf.hasClass('infinite-scroll-top');\n if (!distance) distance = 50;\n if (typeof distance === 'string' && distance.indexOf('%') >= 0) {\n distance = parseInt(distance, 10) / 100 * height;\n }\n if (distance > height) distance = height;\n if (onTop) {\n if (scrollTop < distance) {\n inf.trigger('infinite');\n }\n }\n else {\n if (scrollTop + height >= scrollHeight - distance) {\n if (virtualListContainer.length > 0) {\n virtualList = virtualListContainer[0].f7VirtualList;\n if (virtualList && !virtualList.reachEnd) return;\n }\n inf.trigger('infinite');\n }\n }\n \n }\n app.attachInfiniteScroll = function (infiniteContent) {\n $(infiniteContent).on('scroll', handleInfiniteScroll);\n };\n app.detachInfiniteScroll = function (infiniteContent) {\n $(infiniteContent).off('scroll', handleInfiniteScroll);\n };\n \n app.initInfiniteScroll = function (pageContainer) {\n pageContainer = $(pageContainer);\n var infiniteContent = pageContainer.find('.infinite-scroll');\n if (infiniteContent.length === 0) return;\n app.attachInfiniteScroll(infiniteContent);\n function detachEvents() {\n app.detachInfiniteScroll(infiniteContent);\n pageContainer.off('pageBeforeRemove', detachEvents);\n }\n pageContainer.on('pageBeforeRemove', detachEvents);\n };\n"," /*=============================================================\n ************ Hide/show Toolbar/Navbar on scroll ************\n =============================================================*/\n app.initScrollToolbars = function (pageContainer) {\n pageContainer = $(pageContainer);\n var scrollContent = pageContainer.find('.page-content');\n if (scrollContent.length === 0) return;\n var hideNavbar = (app.params.hideNavbarOnPageScroll || scrollContent.hasClass('hide-navbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll')) && !(scrollContent.hasClass('keep-navbar-on-scroll') || scrollContent.hasClass('keep-bars-on-scroll'));\n var hideToolbar = (app.params.hideToolbarOnPageScroll || scrollContent.hasClass('hide-toolbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll')) && !(scrollContent.hasClass('keep-toolbar-on-scroll') || scrollContent.hasClass('keep-bars-on-scroll'));\n var hideTabbar = (app.params.hideTabbarOnPageScroll || scrollContent.hasClass('hide-tabbar-on-scroll')) && !(scrollContent.hasClass('keep-tabbar-on-scroll'));\n \n if (!(hideNavbar || hideToolbar || hideTabbar)) return;\n \n var viewContainer = scrollContent.parents('.' + app.params.viewClass);\n if (viewContainer.length === 0) return;\n \n var navbar = viewContainer.find('.navbar'), \n toolbar = viewContainer.find('.toolbar'), \n tabbar;\n if (hideTabbar) {\n tabbar = viewContainer.find('.tabbar');\n if (tabbar.length === 0) tabbar = viewContainer.parents('.' + app.params.viewsClass).find('.tabbar');\n }\n \n var hasNavbar = navbar.length > 0,\n hasToolbar = toolbar.length > 0,\n hasTabbar = tabbar && tabbar.length > 0;\n \n var previousScroll, currentScroll;\n previousScroll = currentScroll = scrollContent[0].scrollTop;\n \n var scrollHeight, offsetHeight, reachEnd, action, navbarHidden, toolbarHidden, tabbarHidden;\n \n var toolbarHeight = (hasToolbar && hideToolbar) ? toolbar[0].offsetHeight : 0;\n var tabbarHeight = (hasTabbar && hideTabbar) ? tabbar[0].offsetHeight : 0;\n var bottomBarHeight = tabbarHeight || toolbarHeight;\n \n function handleScroll(e) {\n if (pageContainer.hasClass('page-on-left')) return;\n currentScroll = scrollContent[0].scrollTop;\n scrollHeight = scrollContent[0].scrollHeight;\n offsetHeight = scrollContent[0].offsetHeight;\n reachEnd = app.params.showBarsOnPageScrollEnd && (currentScroll + offsetHeight >= scrollHeight - bottomBarHeight);\n navbarHidden = navbar.hasClass('navbar-hidden');\n toolbarHidden = toolbar.hasClass('toolbar-hidden');\n tabbarHidden = tabbar && tabbar.hasClass('toolbar-hidden');\n \n \n if (previousScroll > currentScroll || reachEnd) {\n action = 'show';\n }\n else {\n if (currentScroll > 44) {\n action = 'hide';\n }\n else {\n action = 'show';\n }\n }\n \n if (action === 'show') {\n if (hasNavbar && hideNavbar && navbarHidden) {\n app.showNavbar(navbar);\n pageContainer.removeClass('no-navbar-by-scroll'); \n navbarHidden = false;\n }\n if (hasToolbar && hideToolbar && toolbarHidden) {\n app.showToolbar(toolbar);\n pageContainer.removeClass('no-toolbar-by-scroll'); \n toolbarHidden = false;\n }\n if (hasTabbar && hideTabbar && tabbarHidden) {\n app.showToolbar(tabbar);\n pageContainer.removeClass('no-tabbar-by-scroll'); \n tabbarHidden = false;\n }\n }\n else {\n if (hasNavbar && hideNavbar && !navbarHidden) {\n app.hideNavbar(navbar);\n pageContainer.addClass('no-navbar-by-scroll'); \n navbarHidden = true;\n }\n if (hasToolbar && hideToolbar && !toolbarHidden) {\n app.hideToolbar(toolbar);\n pageContainer.addClass('no-toolbar-by-scroll'); \n toolbarHidden = true;\n }\n if (hasTabbar && hideTabbar && !tabbarHidden) {\n app.hideToolbar(tabbar);\n pageContainer.addClass('no-tabbar-by-scroll'); \n tabbarHidden = true;\n }\n }\n \n previousScroll = currentScroll;\n }\n scrollContent.on('scroll', handleScroll);\n scrollContent[0].f7ScrollToolbarsHandler = handleScroll;\n };\n app.destroyScrollToolbars = function (pageContainer) {\n pageContainer = $(pageContainer);\n var scrollContent = pageContainer.find('.page-content');\n if (scrollContent.length === 0) return;\n var handler = scrollContent[0].f7ScrollToolbarsHandler;\n if (!handler) return;\n scrollContent.off('scroll', scrollContent[0].f7ScrollToolbarsHandler);\n };\n"," /* ===============================================================================\n ************ Tabs ************\n =============================================================================== */\n app.showTab = function (tab, tabLink, force) {\n var newTab = $(tab);\n if (arguments.length === 2) {\n if (typeof tabLink === 'boolean') {\n force = tabLink;\n }\n }\n if (newTab.length === 0) return false;\n if (newTab.hasClass('active')) {\n if (force) newTab.trigger('show');\n return false;\n }\n var tabs = newTab.parent('.tabs');\n if (tabs.length === 0) return false;\n \n // Return swipeouts in hidden tabs\n app.allowSwipeout = true;\n \n // Animated tabs\n var isAnimatedTabs = tabs.parent().hasClass('tabs-animated-wrap');\n if (isAnimatedTabs) {\n tabs.transform('translate3d(' + -newTab.index() * 100 + '%,0,0)');\n }\n \n // Remove active class from old tabs\n var oldTab = tabs.children('.tab.active').removeClass('active');\n // Add active class to new tab\n newTab.addClass('active');\n // Trigger 'show' event on new tab\n newTab.trigger('show');\n \n // Update navbars in new tab\n if (!isAnimatedTabs && newTab.find('.navbar').length > 0) {\n // Find tab's view\n var viewContainer;\n if (newTab.hasClass(app.params.viewClass)) viewContainer = newTab[0];\n else viewContainer = newTab.parents('.' + app.params.viewClass)[0];\n app.sizeNavbars(viewContainer);\n }\n \n // Find related link for new tab\n if (tabLink) tabLink = $(tabLink);\n else {\n // Search by id\n if (typeof tab === 'string') tabLink = $('.tab-link[href=\"' + tab + '\"]');\n else tabLink = $('.tab-link[href=\"#' + newTab.attr('id') + '\"]');\n // Search by data-tab\n if (!tabLink || tabLink && tabLink.length === 0) {\n $('[data-tab]').each(function () {\n if (newTab.is($(this).attr('data-tab'))) tabLink = $(this);\n });\n }\n }\n if (tabLink.length === 0) return;\n \n // Find related link for old tab\n var oldTabLink;\n if (oldTab && oldTab.length > 0) {\n // Search by id\n var oldTabId = oldTab.attr('id');\n if (oldTabId) oldTabLink = $('.tab-link[href=\"#' + oldTabId + '\"]');\n // Search by data-tab\n if (!oldTabLink || oldTabLink && oldTabLink.length === 0) {\n $('[data-tab]').each(function () {\n if (oldTab.is($(this).attr('data-tab'))) oldTabLink = $(this);\n });\n }\n }\n \n // Update links' classes\n if (tabLink && tabLink.length > 0) tabLink.addClass('active');\n if (oldTabLink && oldTabLink.length > 0) oldTabLink.removeClass('active');\n \n return true;\n };\n"," /*===============================================================================\n ************ Accordion ************\n ===============================================================================*/\n app.accordionToggle = function (item) {\n item = $(item);\n if (item.length === 0) return;\n if (item.hasClass('accordion-item-expanded')) app.accordionClose(item);\n else app.accordionOpen(item);\n };\n app.accordionOpen = function (item) {\n item = $(item);\n var list = item.parents('.accordion-list').eq(0);\n var content = item.children('.accordion-item-content');\n if (content.length === 0) content = item.find('.accordion-item-content');\n var expandedItem = list.length > 0 && item.parent().children('.accordion-item-expanded');\n if (expandedItem.length > 0) {\n app.accordionClose(expandedItem);\n }\n content.css('height', content[0].scrollHeight + 'px').transitionEnd(function () {\n if (item.hasClass('accordion-item-expanded')) {\n content.transition(0);\n content.css('height', 'auto');\n var clientLeft = content[0].clientLeft;\n content.transition('');\n item.trigger('opened');\n }\n else {\n content.css('height', '');\n item.trigger('closed');\n }\n });\n item.trigger('open');\n item.addClass('accordion-item-expanded');\n };\n app.accordionClose = function (item) {\n item = $(item);\n var content = item.children('.accordion-item-content');\n if (content.length === 0) content = item.find('.accordion-item-content');\n item.removeClass('accordion-item-expanded');\n content.transition(0);\n content.css('height', content[0].scrollHeight + 'px');\n // Relayout\n var clientLeft = content[0].clientLeft;\n // Close\n content.transition('');\n content.css('height', '').transitionEnd(function () {\n if (item.hasClass('accordion-item-expanded')) {\n content.transition(0);\n content.css('height', 'auto');\n var clientLeft = content[0].clientLeft;\n content.transition('');\n item.trigger('opened');\n }\n else {\n content.css('height', '');\n item.trigger('closed');\n }\n });\n item.trigger('close');\n };\n"," /*===============================================================================\n ************ Fast Clicks ************\n ************ Inspired by https://github.com/ftlabs/fastclick ************\n ===============================================================================*/\n app.initFastClicks = function () {\n if (app.params.activeState) {\n $('html').addClass('watch-active-state');\n }\n \n var touchStartX, touchStartY, touchStartTime, targetElement, trackClick, activeSelection, scrollParent, lastClickTime, isMoved;\n var activableElement, activeTimeout, needsFastClick;\n \n function findActivableElement(e) {\n var target = $(e.target);\n var parents = target.parents(app.params.activeStateElements);\n var activable;\n if (target.is(app.params.activeStateElements)) {\n activable = target;\n }\n if (parents.length > 0) {\n activable = activable ? activable.add(parents) : parents;\n }\n return activable ? activable : target;\n }\n function isInsideScrollableView() {\n var pageContent = activableElement.parents('.page-content, .panel');\n \n if (pageContent.length === 0) {\n return false;\n }\n \n // This event handler covers the \"tap to stop scrolling\".\n if (pageContent.prop('scrollHandlerSet') !== 'yes') {\n pageContent.on('scroll', function() {\n clearTimeout(activeTimeout);\n });\n pageContent.prop('scrollHandlerSet', 'yes');\n }\n \n return true;\n }\n function addActive() {\n activableElement.addClass('active-state');\n }\n function removeActive(el) {\n activableElement.removeClass('active-state');\n }\n \n function androidNeedsBlur(el) {\n var noBlur = ('button checkbox file image radio submit input textarea').split(' ');\n if (document.activeElement && el !== document.activeElement && document.activeElement !== document.body) {\n if (noBlur.indexOf(el.nodeName.toLowerCase()) >= 0) {\n return false;\n }\n else {\n return true;\n }\n }\n else {\n return false;\n }\n }\n function targetNeedsFastClick(el) {\n var $el = $(el);\n if (el.nodeName.toLowerCase() === 'input' && el.type === 'file') return false;\n if ($el.hasClass('no-fastclick') || $el.parents('.no-fastclick').length > 0) return false;\n return true;\n }\n function targetNeedsFocus(el) {\n if (document.activeElement === el) {\n return false;\n }\n var tag = el.nodeName.toLowerCase();\n var skipInputs = ('button checkbox file image radio submit').split(' ');\n if (el.disabled || el.readOnly) return false;\n if (tag === 'textarea') return true;\n if (tag === 'select') {\n if (app.device.os === 'android') return false;\n else return true;\n }\n if (tag === 'input' && skipInputs.indexOf(el.type) < 0) return true;\n }\n function targetNeedsPrevent(el) {\n el = $(el);\n if (el.is('label') || el.parents('label').length > 0) {\n if (app.device.os === 'android') {\n var osv = app.device.osVersion.split('.');\n if (osv[0] * 1 > 4 || (osv[0] * 1 === 4 && osv[1] * 1 >= 4)) {\n return false;\n }\n else return true;\n }\n else return false;\n }\n return true;\n }\n \n // Mouse Handlers\n function handleMouseDown (e) {\n findActivableElement(e).addClass('active-state');\n if ('which' in e && e.which === 3) {\n setTimeout(function () {\n $('.active-state').removeClass('active-state');\n }, 0);\n }\n }\n function handleMouseMove (e) {\n $('.active-state').removeClass('active-state');\n }\n function handleMouseUp (e) {\n $('.active-state').removeClass('active-state');\n }\n \n // Touch Handlers\n function handleTouchStart(e) {\n isMoved = false;\n if (e.targetTouches.length > 1) {\n return true;\n }\n needsFastClick = targetNeedsFastClick(e.target);\n \n if (!needsFastClick) {\n trackClick = false;\n return true;\n }\n if (app.device.os === 'ios') {\n var selection = window.getSelection();\n if (selection.rangeCount && selection.focusNode !== document.body && (!selection.isCollapsed || document.activeElement === selection.focusNode)) {\n activeSelection = true;\n return true;\n }\n else {\n activeSelection = false;\n }\n }\n if (app.device.os === 'android') {\n if (androidNeedsBlur(e.target)) {\n document.activeElement.blur();\n }\n }\n \n trackClick = true;\n targetElement = e.target;\n touchStartTime = (new Date()).getTime();\n touchStartX = e.targetTouches[0].pageX;\n touchStartY = e.targetTouches[0].pageY;\n \n // Detect scroll parent\n if (app.device.os === 'ios') {\n scrollParent = undefined;\n $(targetElement).parents().each(function () {\n var parent = this;\n if (parent.scrollHeight > parent.offsetHeight && !scrollParent) {\n scrollParent = parent;\n scrollParent.f7ScrollTop = scrollParent.scrollTop;\n }\n });\n }\n if ((e.timeStamp - lastClickTime) < app.params.fastClicksDelayBetweenClicks) {\n e.preventDefault();\n }\n if (app.params.activeState) {\n activableElement = findActivableElement(e);\n // If it's inside a scrollable view, we don't trigger active-state yet,\n // because it can be a scroll instead. Based on the link:\n // http://labnote.beedesk.com/click-scroll-and-pseudo-active-on-mobile-webk\n if (!isInsideScrollableView(e)) {\n addActive();\n } else {\n activeTimeout = setTimeout(addActive, 80);\n }\n }\n }\n function handleTouchMove(e) {\n if (!trackClick) return;\n var _isMoved = false;\n var distance = app.params.fastClicksDistanceThreshold;\n if (distance) {\n var pageX = e.targetTouches[0].pageX;\n var pageY = e.targetTouches[0].pageY;\n if (Math.abs(pageX - touchStartX) > distance || Math.abs(pageY - touchStartY) > distance) {\n _isMoved = true;\n }\n }\n else {\n _isMoved = true;\n }\n if (_isMoved) {\n trackClick = false;\n targetElement = null;\n isMoved = true;\n }\n \n if (app.params.activeState) {\n clearTimeout(activeTimeout);\n removeActive();\n }\n }\n function handleTouchEnd(e) {\n clearTimeout(activeTimeout);\n \n if (!trackClick) {\n if (!activeSelection && needsFastClick) e.preventDefault();\n return true;\n }\n \n if (document.activeElement === e.target) {\n return true;\n }\n \n if (!activeSelection) {\n e.preventDefault();\n }\n \n if ((e.timeStamp - lastClickTime) < app.params.fastClicksDelayBetweenClicks) {\n setTimeout(removeActive, 0);\n return true;\n }\n \n lastClickTime = e.timeStamp;\n \n trackClick = false;\n \n if (app.device.os === 'ios' && scrollParent) {\n if (scrollParent.scrollTop !== scrollParent.f7ScrollTop) {\n return false;\n }\n }\n \n // Add active-state here because, in a very fast tap, the timeout didn't\n // have the chance to execute. Removing active-state in a timeout gives \n // the chance to the animation execute.\n if (app.params.activeState) {\n addActive();\n setTimeout(removeActive, 0);\n }\n \n // Trigger focus when required\n if (targetNeedsFocus(targetElement)) {\n targetElement.focus();\n }\n \n // Blur active elements\n if (document.activeElement && targetElement !== document.activeElement && document.activeElement !== document.body && targetElement.nodeName.toLowerCase() !== 'label') {\n document.activeElement.blur();\n }\n \n // Send click\n e.preventDefault();\n var touch = e.changedTouches[0];\n var evt = document.createEvent('MouseEvents');\n var eventType = 'click';\n if (app.device.os === 'android' && targetElement.nodeName.toLowerCase() === 'select') {\n eventType = 'mousedown';\n }\n evt.initMouseEvent(eventType, true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);\n evt.forwardedTouchEvent = true;\n targetElement.dispatchEvent(evt);\n \n return false;\n }\n function handleTouchCancel(e) {\n trackClick = false;\n targetElement = null;\n }\n \n function handleClick(e) {\n var allowClick = false;\n \n if (trackClick) {\n targetElement = null;\n trackClick = false;\n return true;\n }\n \n if (e.target.type === 'submit' && e.detail === 0) {\n return true;\n }\n \n if (!targetElement) {\n allowClick = true;\n }\n if (document.activeElement === targetElement) {\n allowClick = true;\n }\n if (e.forwardedTouchEvent) {\n allowClick = true;\n }\n if (!e.cancelable) {\n allowClick = true;\n }\n \n if (!allowClick) {\n e.stopImmediatePropagation();\n e.stopPropagation();\n if (targetElement) {\n if (targetNeedsPrevent(targetElement) || isMoved) {\n e.preventDefault();\n }\n }\n else {\n e.preventDefault();\n }\n targetElement = null;\n }\n \n return allowClick;\n }\n if (app.support.touch) {\n document.addEventListener('click', handleClick, true);\n \n document.addEventListener('touchstart', handleTouchStart);\n document.addEventListener('touchmove', handleTouchMove);\n document.addEventListener('touchend', handleTouchEnd);\n document.addEventListener('touchcancel', handleTouchCancel);\n }\n else {\n if (app.params.activeState) {\n document.addEventListener('mousedown', handleMouseDown);\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n }\n }\n \n };\n \n"," /*===============================================================================\n ************ Handle clicks and make them fast (on tap); ************\n ===============================================================================*/\n app.initClickEvents = function () {\n function handleScrollTop(e) {\n /*jshint validthis:true */\n var clicked = $(this);\n var target = $(e.target);\n var isLink = clicked[0].nodeName.toLowerCase() === 'a' ||\n clicked.parents('a').length > 0 ||\n target[0].nodeName.toLowerCase() === 'a' ||\n target.parents('a').length > 0;\n \n if (isLink) return;\n var pageContent, page;\n if (app.params.scrollTopOnNavbarClick && clicked.is('.navbar .center')) {\n // Find active page\n var navbar = clicked.parents('.navbar');\n \n // Static Layout\n pageContent = navbar.parents('.page-content');\n \n if (pageContent.length === 0) {\n // Fixed Layout\n if (navbar.parents('.page').length > 0) {\n pageContent = navbar.parents('.page').find('.page-content');\n }\n // Through Layout\n if (pageContent.length === 0) {\n if (navbar.nextAll('.pages').length > 0) {\n pageContent = navbar.nextAll('.pages').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');\n }\n }\n }\n }\n if (app.params.scrollTopOnStatusbarClick && clicked.is('.statusbar-overlay')) {\n if ($('.popup.modal-in').length > 0) {\n // Check for opened popup\n pageContent = $('.popup.modal-in').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');\n }\n else if ($('.panel.active').length > 0) {\n // Check for opened panel\n pageContent = $('.panel.active').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');\n }\n else if ($('.views > .view.active').length > 0) {\n // View in tab bar app layout\n pageContent = $('.views > .view.active').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');\n }\n else {\n // Usual case\n pageContent = $('.views').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content'); \n }\n }\n \n if (pageContent && pageContent.length > 0) {\n // Check for tab\n if (pageContent.hasClass('tab')) {\n pageContent = pageContent.parent('.tabs').children('.page-content.active');\n }\n if (pageContent.length > 0) pageContent.scrollTop(0, 300);\n }\n }\n function handleClicks(e) {\n /*jshint validthis:true */\n var clicked = $(this);\n var url = clicked.attr('href');\n var isLink = clicked[0].nodeName.toLowerCase() === 'a';\n \n // Str to boolean for data attributes\n function toBoolean(str) {\n if (str === 'false') return false;\n if (str === 'true') return true;\n return undefined;\n }\n // Check if link is external \n if (isLink) {\n if (clicked.is(app.params.externalLinks)) {\n if(clicked.attr('target') === '_system') {\n e.preventDefault();\n window.open(url, '_system');\n }\n return;\n }\n }\n \n // Smart Select\n if (clicked.hasClass('smart-select')) {\n if (app.smartSelectOpen) app.smartSelectOpen(clicked);\n }\n \n // Open Panel\n if (clicked.hasClass('open-panel')) {\n if ($('.panel').length === 1) {\n if ($('.panel').hasClass('panel-left')) app.openPanel('left');\n else app.openPanel('right');\n }\n else {\n if (clicked.attr('data-panel') === 'right') app.openPanel('right');\n else app.openPanel('left');\n }\n }\n // Close Panel\n if (clicked.hasClass('close-panel')) {\n app.closePanel();\n }\n \n if (clicked.hasClass('panel-overlay') && app.params.panelsCloseByOutside) {\n app.closePanel();\n }\n // Popover\n if (clicked.hasClass('open-popover')) {\n var popover;\n if (clicked.attr('data-popover')) {\n popover = clicked.attr('data-popover');\n }\n else popover = '.popover';\n app.popover(popover, clicked);\n }\n if (clicked.hasClass('close-popover')) {\n app.closeModal('.popover.modal-in');\n }\n // Popup\n var popup;\n if (clicked.hasClass('open-popup')) {\n if (clicked.attr('data-popup')) {\n popup = clicked.attr('data-popup');\n }\n else popup = '.popup';\n app.popup(popup);\n }\n if (clicked.hasClass('close-popup')) {\n if (clicked.attr('data-popup')) {\n popup = clicked.attr('data-popup');\n }\n else popup = '.popup.modal-in';\n app.closeModal(popup);\n }\n // Login Screen\n var loginScreen;\n if (clicked.hasClass('open-login-screen')) {\n if (clicked.attr('data-login-screen')) {\n loginScreen = clicked.attr('data-login-screen');\n }\n else loginScreen = '.login-screen';\n app.loginScreen(loginScreen);\n }\n if (clicked.hasClass('close-login-screen')) {\n app.closeModal('.login-screen.modal-in');\n }\n // Close Modal\n if (clicked.hasClass('modal-overlay')) {\n if ($('.modal.modal-in').length > 0 && app.params.modalCloseByOutside)\n app.closeModal('.modal.modal-in');\n if ($('.actions-modal.modal-in').length > 0 && app.params.actionsCloseByOutside)\n app.closeModal('.actions-modal.modal-in');\n \n if ($('.popover.modal-in').length > 0) app.closeModal('.popover.modal-in');\n }\n if (clicked.hasClass('popup-overlay')) {\n if ($('.popup.modal-in').length > 0 && app.params.popupCloseByOutside)\n app.closeModal('.popup.modal-in');\n }\n \n // Picker\n if (clicked.hasClass('close-picker')) {\n var pickerToClose = $('.picker-modal.modal-in');\n if (pickerToClose.length > 0) {\n app.closeModal(pickerToClose);\n }\n else {\n pickerToClose = $('.popover.modal-in .picker-modal');\n if (pickerToClose.length > 0) {\n app.closeModal(pickerToClose.parents('.popover'));\n }\n }\n }\n if (clicked.hasClass('open-picker')) {\n var pickerToOpen;\n if (clicked.attr('data-picker')) {\n pickerToOpen = clicked.attr('data-picker');\n }\n else pickerToOpen = '.picker-modal';\n app.pickerModal(pickerToOpen, clicked);\n }\n \n // Tabs\n var isTabLink;\n if (clicked.hasClass('tab-link')) {\n isTabLink = true;\n app.showTab(clicked.attr('data-tab') || clicked.attr('href'), clicked);\n }\n // Swipeout Close\n if (clicked.hasClass('swipeout-close')) {\n app.swipeoutClose(clicked.parents('.swipeout-opened'));\n }\n // Swipeout Delete\n if (clicked.hasClass('swipeout-delete')) {\n if (clicked.attr('data-confirm')) {\n var text = clicked.attr('data-confirm');\n var title = clicked.attr('data-confirm-title');\n if (title) {\n app.confirm(text, title, function () {\n app.swipeoutDelete(clicked.parents('.swipeout'));\n });\n }\n else {\n app.confirm(text, function () {\n app.swipeoutDelete(clicked.parents('.swipeout'));\n });\n }\n }\n else {\n app.swipeoutDelete(clicked.parents('.swipeout'));\n }\n \n }\n // Sortable\n if (clicked.hasClass('toggle-sortable')) {\n app.sortableToggle(clicked.data('sortable'));\n }\n if (clicked.hasClass('open-sortable')) {\n app.sortableOpen(clicked.data('sortable'));\n }\n if (clicked.hasClass('close-sortable')) {\n app.sortableClose(clicked.data('sortable'));\n }\n // Accordion\n if (clicked.hasClass('accordion-item-toggle') || (clicked.hasClass('item-link') && clicked.parent().hasClass('accordion-item'))) {\n var accordionItem = clicked.parent('.accordion-item');\n if (accordionItem.length === 0) accordionItem = clicked.parents('.accordion-item');\n if (accordionItem.length === 0) accordionItem = clicked.parents('li');\n app.accordionToggle(accordionItem);\n }\n \n // Load Page\n if (app.params.ajaxLinks && !clicked.is(app.params.ajaxLinks) || !isLink || !app.params.router) {\n return;\n }\n if (isLink) {\n e.preventDefault();\n }\n \n var validUrl = url && url.length > 0 && url !== '#' && !isTabLink;\n var template = clicked.attr('data-template');\n if (validUrl || clicked.hasClass('back') || template) {\n var view;\n if (clicked.attr('data-view')) {\n view = $(clicked.attr('data-view'))[0].f7View;\n }\n else {\n view = clicked.parents('.' + app.params.viewClass)[0] && clicked.parents('.' + app.params.viewClass)[0].f7View;\n if (view && view.params.linksView) {\n if (typeof view.params.linksView === 'string') view = $(view.params.linksView)[0].f7View;\n else if (view.params.linksView instanceof View) view = view.params.linksView;\n }\n }\n if (!view) {\n if (app.mainView) view = app.mainView;\n }\n if (!view) return;\n \n var pageName;\n if (!template) {\n if (url.indexOf('#') === 0 && url !== '#') {\n if (view.params.domCache) {\n pageName = url.split('#')[1];\n url = undefined;\n }\n else return;\n }\n if (url === '#' && !clicked.hasClass('back')) return;\n }\n else {\n url = undefined;\n }\n \n var animatePages;\n if (clicked.attr('data-animatePages')) {\n animatePages = toBoolean(clicked.attr('data-animatePages'));\n }\n else {\n if (clicked.hasClass('with-animation')) animatePages = true;\n if (clicked.hasClass('no-animation')) animatePages = false;\n }\n \n var options = {\n animatePages: animatePages,\n ignoreCache: toBoolean(clicked.attr('data-ignoreCache')),\n force: toBoolean(clicked.attr('data-force')),\n reload: toBoolean(clicked.attr('data-reload')),\n reloadPrevious: toBoolean(clicked.attr('data-reloadPrevious')),\n pageName: pageName,\n url: url\n };\n \n if (app.params.template7Pages) {\n options.contextName = clicked.attr('data-contextName');\n var context = clicked.attr('data-context');\n if (context) {\n options.context = JSON.parse(context);\n }\n }\n if (template && template in t7.templates) {\n options.template = t7.templates[template];\n }\n \n if (clicked.hasClass('back')) view.router.back(options);\n else view.router.load(options);\n }\n }\n $(document).on('click', 'a, .open-panel, .close-panel, .panel-overlay, .modal-overlay, .popup-overlay, .swipeout-delete, .swipeout-close, .close-popup, .open-popup, .open-popover, .open-login-screen, .close-login-screen .smart-select, .toggle-sortable, .open-sortable, .close-sortable, .accordion-item-toggle, .close-picker', handleClicks);\n if (app.params.scrollTopOnNavbarClick || app.params.scrollTopOnStatusbarClick) {\n $(document).on('click', '.statusbar-overlay, .navbar .center', handleScrollTop);\n }\n \n // Prevent scrolling on overlays\n function preventScrolling(e) {\n e.preventDefault();\n }\n if (app.support.touch) {\n $(document).on('touchstart', '.panel-overlay, .modal-overlay, .preloader-indicator-overlay, .popup-overlay, .searchbar-overlay', preventScrolling);\n }\n };\n \n"," /*======================================================\n ************ App Resize Actions ************\n ======================================================*/\n // Prevent iPad horizontal body scrolling when soft keyboard is opened\n function _fixIpadBodyScrolLeft() {\n if (app.device.ipad) {\n document.body.scrollLeft = 0;\n setTimeout(function () {\n document.body.scrollLeft = 0;\n }, 0);\n }\n }\n app.initResize = function () {\n $(window).on('resize', app.resize);\n $(window).on('orientationchange', app.orientationchange);\n };\n app.resize = function () {\n if (app.sizeNavbars) app.sizeNavbars();\n _fixIpadBodyScrolLeft();\n \n };\n app.orientationchange = function () {\n if (app.device && app.device.minimalUi) {\n if (window.orientation === 90 || window.orientation === -90) document.body.scrollTop = 0;\n }\n _fixIpadBodyScrolLeft();\n };\n \n"," /*===============================================================================\n ************ Store and parse forms data ************\n ===============================================================================*/\n app.formsData = {};\n app.formStoreData = function (formId, formJSON) {\n // Store form data in app.formsData\n app.formsData[formId] = formJSON;\n \n // Store form data in local storage also\n app.ls['f7form-' + formId] = JSON.stringify(formJSON);\n };\n app.formDeleteData = function (formId) {\n // Delete form data from app.formsData\n if (app.formsData[formId]) {\n app.formsData[formId] = '';\n delete app.formsData[formId];\n }\n \n // Delete form data from local storage also\n if (app.ls['f7form-' + formId]) {\n app.ls['f7form-' + formId] = '';\n app.ls.removeItem('f7form-' + formId);\n }\n };\n app.formGetData = function (formId) {\n // First of all check in local storage\n if (app.ls['f7form-' + formId]) {\n return JSON.parse(app.ls['f7form-' + formId]);\n }\n // Try to get it from formsData obj\n else if (app.formsData[formId]) return app.formsData[formId];\n };\n app.formToJSON = function (form) {\n form = $(form);\n if (form.length !== 1) return false;\n \n // Form data\n var formData = {};\n \n // Skip input types\n var skipTypes = ['submit', 'image', 'button', 'file'];\n var skipNames = [];\n form.find('input, select, textarea').each(function () {\n var input = $(this);\n var name = input.attr('name');\n var type = input.attr('type');\n var tag = this.nodeName.toLowerCase();\n if (skipTypes.indexOf(type) >= 0) return;\n if (skipNames.indexOf(name) >= 0 || !name) return;\n if (tag === 'select' && input.attr('multiple')) {\n skipNames.push(name);\n formData[name] = [];\n form.find('select[name=\"' + name + '\"] option').each(function () {\n if (this.selected) formData[name].push(this.value);\n });\n }\n else {\n switch (type) {\n case 'checkbox' :\n skipNames.push(name);\n formData[name] = [];\n form.find('input[name=\"' + name + '\"]').each(function () {\n if (this.checked) formData[name].push(this.value);\n });\n break;\n case 'radio' :\n skipNames.push(name);\n form.find('input[name=\"' + name + '\"]').each(function () {\n if (this.checked) formData[name] = this.value;\n });\n break;\n default :\n formData[name] = input.val();\n break;\n }\n }\n \n });\n form.trigger('formToJSON', {formData: formData});\n \n return formData;\n };\n app.formFromJSON = function (form, formData) {\n form = $(form);\n if (form.length !== 1) return false;\n \n // Skip input types\n var skipTypes = ['submit', 'image', 'button', 'file'];\n var skipNames = [];\n \n form.find('input, select, textarea').each(function () {\n var input = $(this);\n var name = input.attr('name');\n var type = input.attr('type');\n var tag = this.nodeName.toLowerCase();\n if (!formData[name]) return;\n if (skipTypes.indexOf(type) >= 0) return;\n if (skipNames.indexOf(name) >= 0 || !name) return;\n if (tag === 'select' && input.attr('multiple')) {\n skipNames.push(name);\n form.find('select[name=\"' + name + '\"] option').each(function () {\n if (formData[name].indexOf(this.value) >= 0) this.selected = true;\n else this.selected = false;\n });\n }\n else {\n switch (type) {\n case 'checkbox' :\n skipNames.push(name);\n form.find('input[name=\"' + name + '\"]').each(function () {\n if (formData[name].indexOf(this.value) >= 0) this.checked = true;\n else this.checked = false;\n });\n break;\n case 'radio' :\n skipNames.push(name);\n form.find('input[name=\"' + name + '\"]').each(function () {\n if (formData[name] === this.value) this.checked = true;\n else this.checked = false;\n });\n break;\n default :\n input.val(formData[name]);\n break;\n }\n }\n \n });\n form.trigger('formFromJSON', {formData: formData});\n };\n app.initFormsStorage = function (pageContainer) {\n pageContainer = $(pageContainer);\n if (pageContainer.length === 0) return;\n \n var forms = pageContainer.find('form.store-data');\n if (forms.length === 0) return;\n \n // Parse forms data and fill form if there is such data\n forms.each(function () {\n var id = this.getAttribute('id');\n if (!id) return;\n var formData = app.formGetData(id);\n if (formData) app.formFromJSON(this, formData);\n });\n // Update forms data on inputs change\n function storeForm() {\n /*jshint validthis:true */\n var form = $(this);\n var formId = form[0].id;\n if (!formId) return;\n var formJSON = app.formToJSON(form);\n if (!formJSON) return;\n app.formStoreData(formId, formJSON);\n form.trigger('store', {data: formJSON});\n }\n forms.on('change submit', storeForm);\n \n // Detach Listeners\n function pageBeforeRemove() {\n forms.off('change submit', storeForm);\n pageContainer.off('pageBeforeRemove', pageBeforeRemove);\n }\n pageContainer.on('pageBeforeRemove', pageBeforeRemove);\n };\n \n // Ajax submit on forms\n $(document).on('submit change', 'form.ajax-submit, form.ajax-submit-onchange', function (e) {\n var form = $(this);\n if (e.type === 'change' && !form.hasClass('ajax-submit-onchange')) return;\n if (e.type === 'submit') e.preventDefault();\n \n var method = form.attr('method') || 'GET';\n var contentType = form.attr('enctype');\n \n var url = form.attr('action');\n if (!url) return;\n \n var data;\n if (method === 'POST') data = new FormData(form[0]);\n else data = $.serializeObject(app.formToJSON(form[0]));\n \n var xhr = $.ajax({\n method: method,\n url: url,\n contentType: contentType,\n data: data,\n beforeSend: function (xhr) {\n form.trigger('beforeSubmit', {data:data, xhr: xhr});\n },\n error: function (xhr) {\n form.trigger('submitError', {data:data, xhr: xhr}); \n },\n success: function (data) {\n form.trigger('submitted', {data: data, xhr: xhr});\n }\n });\n });\n \n \n"," /*======================================================\n ************ Handle Browser's History ************\n ======================================================*/\n app.pushStateQueue = [];\n app.pushStateClearQueue = function () {\n if (app.pushStateQueue.length === 0) return;\n var queue = app.pushStateQueue.pop();\n var animatePages;\n if (app.params.pushStateNoAnimation === true) animatePages = false;\n if (queue.action === 'back') {\n app.router.back(queue.view, {animatePages: animatePages});\n }\n if (queue.action === 'loadPage') {\n app.router.load(queue.view, {url: queue.stateUrl, animatePages: animatePages, pushState: false});\n }\n if (queue.action === 'loadContent') {\n app.router.load(queue.view, {content: queue.stateContent, animatePages: animatePages, pushState: false});\n }\n if (queue.action === 'loadPageName') {\n app.router.load(queue.view, {pageName: queue.statePageName, animatePages: animatePages, pushState: false});\n }\n };\n \n app.initPushState = function () {\n var blockPopstate = true;\n $(window).on('load', function () {\n setTimeout(function () {\n blockPopstate = false;\n }, 0);\n });\n function handlePopState(e) {\n if (blockPopstate) return;\n var mainView = app.mainView;\n if (!mainView) return;\n var state = e.state;\n if (!state) {\n state = {\n viewIndex: app.views.indexOf(mainView),\n url : mainView.history[0]\n };\n }\n if (state.viewIndex < 0) return;\n var view = app.views[state.viewIndex];\n var stateUrl = state && state.url || undefined;\n var stateContent = state && state.content || undefined;\n var statePageName = state && state.pageName || undefined;\n var animatePages;\n \n if (app.params.pushStateNoAnimation === true) animatePages = false;\n \n if (stateUrl !== view.url) {\n if (view.history.indexOf(stateUrl) >= 0) {\n // Go Back\n if (view.allowPageChange) {\n app.router.back(view, {url:undefined, animatePages: animatePages, pushState: false, preloadOnly:false});\n }\n else {\n app.pushStateQueue.push({\n action: 'back',\n view: view\n });\n }\n }\n else if (stateContent) {\n // Load Page\n if (view.allowPageChange) {\n app.router.load(view, {content:stateContent, animatePages: animatePages, pushState: false});\n }\n else {\n app.pushStateQueue.unshift({\n action: 'loadContent',\n stateContent: stateContent,\n view: view\n });\n }\n \n }\n else if (statePageName) {\n // Load Page by page name with Dom Cache\n if (view.allowPageChange) {\n app.router.load(view, {pageName:statePageName, animatePages: animatePages, pushState: false});\n }\n else {\n app.pushStateQueue.unshift({\n action: 'loadPageName',\n statePageName: statePageName,\n view: view\n });\n }\n }\n else {\n // Load Page\n if (view.allowPageChange) {\n app.router.load(view, {url:stateUrl, animatePages: animatePages, pushState: false});\n }\n else {\n app.pushStateQueue.unshift({\n action: 'loadPage',\n stateUrl: stateUrl,\n view: view\n });\n }\n }\n }\n }\n $(window).on('popstate', handlePopState);\n };\n \n"," /*===========================\n Framework7 Swiper Additions\n ===========================*/\n app.swiper = function (container, params) {\n return new Swiper(container, params);\n };\n app.initSwiper = function (pageContainer) {\n var page = $(pageContainer);\n var swipers = page.find('.swiper-init');\n if (swipers.length === 0) return;\n function destroySwiperOnRemove(slider) {\n function destroySwiper() {\n slider.destroy();\n page.off('pageBeforeRemove', destroySwiper);\n }\n page.on('pageBeforeRemove', destroySwiper);\n }\n for (var i = 0; i < swipers.length; i++) {\n var swiper = swipers.eq(i);\n var params;\n if (swiper.data('swiper')) {\n params = JSON.parse(swiper.data('swiper'));\n }\n else {\n params = {\n initialSlide: parseInt(swiper.data('initialSlide'), 10) || undefined,\n spaceBetween: parseInt(swiper.data('spaceBetween'), 10) || undefined,\n speed: parseInt(swiper.data('speed'), 10) || undefined,\n slidesPerView: swiper.data('slidesPerView') || undefined,\n slidesPerColumn: parseInt(swiper.data('slidesPerColumn'), 10) || undefined,\n centeredSlides: swiper.data('centeredSlides') && (swiper.data('centeredSlides') === 'true' ? true : false),\n direction: swiper.data('direction'),\n pagination: swiper.data('pagination'),\n paginationHide: swiper.data('paginationHide') && (swiper.data('paginationHide') === 'true' ? true : false),\n paginationClickable: swiper.data('paginationClickable') && (swiper.data('paginationClickable') === 'true' ? true : false),\n scrollbar: swiper.data('scrollbar'),\n scrollbarHide: swiper.data('scrollbarHide') && (swiper.data('scrollbarHide') === 'true' ? true : false),\n loop: swiper.data('loop') && (swiper.data('loop') === 'true' ? true : false),\n effect: swiper.data('effect') || 'slide',\n freeMode: swiper.data('freeMode') && (swiper.data('freeMode') === 'true' ? true : false),\n onlyExternal: swiper.data('onlyExternal') && (swiper.data('onlyExternal') === 'true' ? true : false),\n nextButton: swiper.data('nextButton'),\n prevButton: swiper.data('prevButton'),\n autoplay: swiper.data('autoplay')\n };\n }\n var _slider = app.swiper(swiper[0], params);\n destroySwiperOnRemove(_slider);\n }\n };\n app.reinitSwiper = function (pageContainer) {\n var page = $(pageContainer);\n var sliders = page.find('.swiper-init');\n if (sliders.length === 0) return;\n for (var i = 0; i < sliders.length; i++) {\n var sliderInstance = sliders[0].swiper;\n if (sliderInstance) {\n sliderInstance.onResize();\n }\n }\n };\n \n"," /*======================================================\n ************ Photo Browser ************\n ======================================================*/\n var PhotoBrowser = function (params) {\n var pb = this, i;\n \n var defaults = {\n photos : [],\n initialSlide: 0,\n spaceBetween: 20,\n speed: 300,\n zoom: true,\n maxZoom: 3,\n minZoom: 1,\n exposition: true,\n expositionHideCaptions: false,\n type: 'standalone',\n navbar: true,\n toolbar: true,\n theme: 'light',\n swipeToClose: true,\n backLinkText: 'Close',\n ofText: 'of',\n loop: false,\n lazyLoading: false,\n lazyLoadingInPrevNext: false,\n lazyLoadingOnTransitionStart: false\n };\n \n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n \n pb.params = params;\n \n var iconColor = pb.params.theme === 'dark' ? 'color-white' : '';\n \n var navbarTemplate = pb.params.navbarTemplate ||\n '<div class=\"navbar\">' +\n '<div class=\"navbar-inner\">' +\n '<div class=\"left sliding\"><a href=\"#\" class=\"link ' + (pb.params.type === 'page' && 'back') + ' close-popup photo-browser-close-link\" data-popup=\".photo-browser-popup\"><i class=\"icon icon-back ' + iconColor + '\"></i><span>' + pb.params.backLinkText + '</span></a></div>' +\n '<div class=\"center sliding\"><span class=\"photo-browser-current\"></span> <span class=\"photo-browser-of\">' + pb.params.ofText + '</span> <span class=\"photo-browser-total\"></span></div>' +\n '<div class=\"right\"></div>' +\n '</div>' +\n '</div>';\n var toolbarTemplate = pb.params.toolbarTemplate ||\n '<div class=\"toolbar tabbar\">' +\n '<div class=\"toolbar-inner\">' +\n '<a href=\"#\" class=\"link photo-browser-prev\"><i class=\"icon icon-prev ' + iconColor + '\"></i></a>' +\n '<a href=\"#\" class=\"link photo-browser-next\"><i class=\"icon icon-next ' + iconColor + '\"></i></a>' +\n '</div>' +\n '</div>';\n \n var template = pb.params.template ||\n '<div class=\"photo-browser photo-browser-' + pb.params.theme + '\">' +\n '<div class=\"view navbar-fixed toolbar-fixed\">' +\n '{{navbar}}' +\n '<div data-page=\"photo-browser-slides\" class=\"page no-toolbar {{noNavbar}} toolbar-fixed navbar-fixed\">' +\n '{{toolbar}}' +\n '{{captions}}' +\n '<div class=\"photo-browser-swiper-container swiper-container\">' +\n '<div class=\"photo-browser-swiper-wrapper swiper-wrapper\">' +\n '{{photos}}' +\n '</div>' +\n '</div>' +\n '</div>' +\n '</div>' +\n '</div>';\n \n var photoTemplate = !pb.params.lazyLoading ? \n (pb.params.photoTemplate || '<div class=\"photo-browser-slide swiper-slide\"><span class=\"photo-browser-zoom-container\"><img src=\"{{url}}\"></span></div>') : \n (pb.params.photoLazyTemplate || '<div class=\"photo-browser-slide photo-browser-slide-lazy swiper-slide\"><div class=\"preloader' + (pb.params.theme === 'dark' ? ' preloader-white' : '') + '\"></div><span class=\"photo-browser-zoom-container\"><img data-src=\"{{url}}\"></span></div>');\n \n var captionsTheme = pb.params.captionsTheme || pb.params.theme;\n var captionsTemplate = pb.params.captionsTemplate || '<div class=\"photo-browser-captions photo-browser-captions-' + captionsTheme + '\">{{captions}}</div>';\n var captionTemplate = pb.params.captionTemplate || '<div class=\"photo-browser-caption\" data-caption-index=\"{{captionIndex}}\">{{caption}}</div>';\n \n var objectTemplate = pb.params.objectTemplate || '<div class=\"photo-browser-slide photo-browser-object-slide swiper-slide\">{{html}}</div>';\n var photosHtml = '';\n var captionsHtml = '';\n for (i = 0; i < pb.params.photos.length; i ++) {\n var photo = pb.params.photos[i];\n var thisTemplate = '';\n \n //check if photo is a string or string-like object, for backwards compatibility \n if (typeof(photo) === 'string' || photo instanceof String) {\n \n //check if \"photo\" is html object\n if (photo.indexOf('<') >= 0 || photo.indexOf('>') >= 0) {\n thisTemplate = objectTemplate.replace(/{{html}}/g, photo);\n } else {\n thisTemplate = photoTemplate.replace(/{{url}}/g, photo);\n }\n \n //photo is a string, thus has no caption, so remove the caption template placeholder\n //otherwise check if photo is an object with a url property\n } else if (typeof(photo) === 'object') {\n \n //check if \"photo\" is html object\n if (photo.hasOwnProperty('html') && photo.html.length > 0) {\n thisTemplate = objectTemplate.replace(/{{html}}/g, photo.html);\n } else if (photo.hasOwnProperty('url') && photo.url.length > 0) {\n thisTemplate = photoTemplate.replace(/{{url}}/g, photo.url);\n }\n \n //check if photo has a caption\n if (photo.hasOwnProperty('caption') && photo.caption.length > 0) {\n captionsHtml += captionTemplate.replace(/{{caption}}/g, photo.caption).replace(/{{captionIndex}}/g, i);\n } else {\n thisTemplate = thisTemplate.replace(/{{caption}}/g, '');\n }\n }\n \n photosHtml += thisTemplate;\n \n }\n \n var htmlTemplate = template\n .replace('{{navbar}}', (pb.params.navbar ? navbarTemplate : ''))\n .replace('{{noNavbar}}', (pb.params.navbar ? '' : 'no-navbar'))\n .replace('{{photos}}', photosHtml)\n .replace('{{captions}}', captionsTemplate.replace(/{{captions}}/g, captionsHtml))\n .replace('{{toolbar}}', (pb.params.toolbar ? toolbarTemplate : ''));\n \n pb.activeIndex = pb.params.initialSlide;\n pb.openIndex = pb.activeIndex;\n pb.opened = false;\n \n pb.open = function (index) {\n if (typeof index === 'undefined') index = pb.activeIndex;\n index = parseInt(index, 10);\n if (pb.opened && pb.swiper) {\n pb.swiper.slideTo(index);\n return;\n }\n pb.opened = true;\n pb.openIndex = index;\n pb.initialLazyLoaded = false;\n if (pb.params.type === 'standalone') {\n $('body').append(htmlTemplate);\n }\n if (pb.params.type === 'popup') {\n pb.popup = app.popup('<div class=\"popup photo-browser-popup\">' + htmlTemplate + '</div>');\n $(pb.popup).on('closed', pb.onPopupClose);\n }\n if (pb.params.type === 'page') {\n $(document).on('pageBeforeInit', pb.onPageBeforeInit);\n $(document).on('pageBeforeRemove', pb.onPageBeforeRemove);\n if (!pb.params.view) pb.params.view = app.mainView;\n pb.params.view.loadContent(htmlTemplate);\n return;\n }\n pb.layout(pb.openIndex);\n if (pb.params.onOpen) {\n pb.params.onOpen(pb);\n }\n \n };\n pb.close = function () {\n pb.opened = false;\n if (!pb.swiperContainer || pb.swiperContainer.length === 0) {\n return;\n }\n if (pb.params.onClose) {\n pb.params.onClose(pb);\n }\n // Detach events\n pb.attachEvents(true);\n // Delete from DOM\n if (pb.params.type === 'standalone') {\n pb.container.removeClass('photo-browser-in').addClass('photo-browser-out').animationEnd(function () {\n pb.container.remove();\n });\n }\n // Destroy slider\n pb.swiper.destroy();\n // Delete references\n pb.swiper = pb.swiperContainer = pb.swiperWrapper = pb.slides = gestureSlide = gestureImg = gestureImgWrap = undefined;\n };\n \n pb.onPopupClose = function (e) {\n pb.close();\n $(pb.popup).off('pageBeforeInit', pb.onPopupClose);\n };\n pb.onPageBeforeInit = function (e) {\n if (e.detail.page.name === 'photo-browser-slides') {\n pb.layout(pb.openIndex);\n }\n $(document).off('pageBeforeInit', pb.onPageBeforeInit);\n };\n pb.onPageBeforeRemove = function (e) {\n if (e.detail.page.name === 'photo-browser-slides') {\n pb.close();\n }\n $(document).off('pageBeforeRemove', pb.onPageBeforeRemove);\n };\n \n pb.loadImageInSlide = function (swiper, index) {\n if (!swiper || typeof index === 'undefined') return;\n if (swiper.slides.length === 0) return;\n \n var slide = swiper.slides.eq(index);\n if (!slide.hasClass('photo-browser-slide-lazy')) return;\n \n var img = slide.find('img');\n if (img.length === 0) return;\n \n var image = new Image();\n var src = img.attr('data-src');\n \n image.onload = function () {\n img.attr('src', src);\n img.removeAttr('data-src');\n slide.removeClass('photo-browser-slide-lazy').find('.preloader').remove();\n if (pb.params.onImageLoaded) {\n pb.params.onImageLoaded(pb, slide[0], img[0]);\n }\n };\n image.src = src;\n \n if (pb.params.onImageLoad) {\n pb.params.onImageLoad(pb, slide[0], img[0]);\n }\n };\n \n pb.lazyLoading = function (swiper, activeIndex) {\n pb.loadImageInSlide(swiper, activeIndex);\n if (pb.params.lazyLoadingInPrevNext) {\n var nextSlide = swiper.wrapper.find('.swiper-slide-next.photo-browser-slide-lazy');\n if (nextSlide.length > 0) pb.loadImageInSlide(swiper, nextSlide.index());\n \n var prevSlide = swiper.wrapper.find('.swiper-slide-prev.photo-browser-slide-lazy');\n if (prevSlide.length > 0) pb.loadImageInSlide(swiper, prevSlide.index());\n }\n };\n \n pb.onSliderTransitionStart = function (swiper) {\n pb.activeIndex = swiper.activeIndex;\n \n var current = swiper.activeIndex + 1;\n var total = swiper.slides.length;\n if (pb.params.loop) {\n total = total - 2;\n current = current - swiper.loopedSlides;\n if (current < 1) current = total + current;\n if (current > total) current = current - total;\n }\n pb.container.find('.photo-browser-current').text(current);\n pb.container.find('.photo-browser-total').text(total);\n \n $('.photo-browser-prev, .photo-browser-next').removeClass('photo-browser-link-inactive');\n \n if (swiper.isBeginning && !pb.params.loop) {\n $('.photo-browser-prev').addClass('photo-browser-link-inactive');\n }\n if (swiper.isEnd && !pb.params.loop) {\n $('.photo-browser-next').addClass('photo-browser-link-inactive');\n }\n \n // Update captions\n if (pb.captions.length > 0) {\n pb.captionsContainer.find('.photo-browser-caption-active').removeClass('photo-browser-caption-active');\n var captionIndex = pb.params.loop ? swiper.slides.eq(swiper.activeIndex).attr('data-swiper-slide-index') : pb.activeIndex;\n pb.captionsContainer.find('[data-caption-index=\"' + captionIndex + '\"]').addClass('photo-browser-caption-active');\n }\n \n // Lazy loading\n if (pb.params.lazyLoading){\n if (pb.params.lazyLoadingOnTransitionStart || (!pb.params.lazyLoadingOnTransitionStart && !pb.initialLazyLoaded)) {\n pb.initialLazyLoaded = true;\n pb.lazyLoading(swiper, pb.activeIndex);\n }\n }\n \n // Stop Video\n var previousSlideVideo = swiper.slides.eq(swiper.previousIndex).find('video');\n if (previousSlideVideo.length > 0) {\n if ('pause' in previousSlideVideo[0]) previousSlideVideo[0].pause();\n }\n // Callback\n if (pb.params.onSlideChangeStart) pb.params.onSlideChangeStart(swiper);\n };\n pb.onSliderTransitionEnd = function (swiper) {\n if (pb.params.lazyLoading && !pb.params.lazyLoadingOnTransitionStart) {\n pb.lazyLoading(swiper, pb.activeIndex);\n }\n // Reset zoom\n if (pb.params.zoom && gestureSlide && swiper.previousIndex !== swiper.activeIndex) {\n gestureImg.transform('translate3d(0,0,0) scale(1)');\n gestureImgWrap.transform('translate3d(0,0,0)');\n gestureSlide = gestureImg = gestureImgWrap = undefined;\n scale = currentScale = 1;\n }\n if (pb.params.onSlideChangeEnd) pb.params.onSlideChangeEnd(swiper);\n };\n \n pb.layout = function (index) {\n if (pb.params.type === 'page') {\n pb.container = $('.photo-browser-swiper-container').parents('.view');\n }\n else {\n pb.container = $('.photo-browser');\n }\n if (pb.params.type === 'standalone') {\n pb.container.addClass('photo-browser-in');\n app.sizeNavbars(pb.container);\n }\n pb.swiperContainer = pb.container.find('.photo-browser-swiper-container');\n pb.swiperWrapper = pb.container.find('.photo-browser-swiper-wrapper');\n pb.slides = pb.container.find('.photo-browser-slide');\n pb.captionsContainer = pb.container.find('.photo-browser-captions');\n pb.captions = pb.container.find('.photo-browser-caption');\n \n var sliderSettings = {\n nextButton: pb.params.nextButton || '.photo-browser-next',\n prevButton: pb.params.prevButton || '.photo-browser-prev',\n indexButton: pb.params.indexButton,\n initialSlide: index,\n spaceBetween: pb.params.spaceBetween,\n speed: pb.params.speed,\n loop: pb.params.loop,\n onTap: function (swiper, e) {\n if (pb.params.onTap) pb.params.onTap(swiper, e);\n },\n onClick: function (swiper, e) {\n if (pb.params.exposition) pb.toggleExposition();\n if (pb.params.onClick) pb.params.onClick(swiper, e);\n },\n onDoubleTap: function (swiper, e) {\n pb.toggleZoom($(e.target).parents('.photo-browser-slide'));\n if (pb.params.onDoubleTap) pb.params.onDoubleTap(swiper, e);\n },\n onTransitionStart: function (swiper) {\n pb.onSliderTransitionStart(swiper);\n },\n onTransitionEnd: function (swiper) {\n pb.onSliderTransitionEnd(swiper); \n }\n };\n \n if (pb.params.swipeToClose && pb.params.type !== 'page') {\n sliderSettings.onTouchStart = pb.swipeCloseTouchStart;\n sliderSettings.onOppositeTouchMove = pb.swipeCloseTouchMove;\n sliderSettings.onTouchEnd = pb.swipeCloseTouchEnd;\n }\n \n pb.swiper = app.swiper(pb.swiperContainer, sliderSettings);\n if (index === 0) {\n pb.onSliderTransitionStart(pb.swiper);\n }\n pb.attachEvents();\n };\n pb.attachEvents = function (detach) {\n var action = detach ? 'off' : 'on';\n // Slide between photos\n \n if (pb.params.zoom) {\n var target = pb.params.loop ? pb.swiper.slides : pb.slides;\n // Scale image\n target[action]('gesturestart', pb.onSlideGestureStart);\n target[action]('gesturechange', pb.onSlideGestureChange);\n target[action]('gestureend', pb.onSlideGestureEnd);\n \n // Move image\n target[action](app.touchEvents.start, pb.onSlideTouchStart);\n target[action](app.touchEvents.move, pb.onSlideTouchMove);\n target[action](app.touchEvents.end, pb.onSlideTouchEnd);\n }\n pb.container.find('.photo-browser-close-link')[action]('click', pb.close);\n };\n \n var isTouched, isMoved, touchesStart = {}, touchesCurrent = {}, touchStartTime, isScrolling, animating = false, currentTranslate;\n var allowClick = true;\n \n // Expose\n pb.exposed = false;\n pb.toggleExposition = function () {\n if (pb.container) pb.container.toggleClass('photo-browser-exposed');\n if (pb.params.expositionHideCaptions) pb.captionsContainer.toggleClass('photo-browser-captions-exposed');\n pb.exposed = !pb.exposed;\n };\n pb.enableExposition = function () {\n if (pb.container) pb.container.addClass('photo-browser-exposed');\n if (pb.params.expositionHideCaptions) pb.captionsContainer.addClass('photo-browser-captions-exposed');\n pb.exposed = true;\n };\n pb.disableExposition = function () {\n if (pb.container) pb.container.removeClass('photo-browser-exposed');\n if (pb.params.expositionHideCaptions) pb.captionsContainer.removeClass('photo-browser-captions-exposed');\n pb.exposed = false;\n };\n \n // Gestures\n var gestureSlide, gestureImg, gestureImgWrap, scale = 1, currentScale = 1, isScaling = false;\n pb.onSlideGestureStart = function (e) {\n if (!gestureSlide) {\n gestureSlide = $(this);\n gestureImg = gestureSlide.find('img, svg, canvas');\n gestureImgWrap = gestureImg.parent('.photo-browser-zoom-container');\n if (gestureImgWrap.length === 0) {\n gestureImg = undefined;\n return;\n }\n }\n gestureImg.transition(0);\n isScaling = true;\n };\n pb.onSlideGestureChange = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n scale = e.scale * currentScale;\n if (scale > pb.params.maxZoom) {\n scale = pb.params.maxZoom - 1 + Math.pow((scale - pb.params.maxZoom + 1), 0.5);\n }\n if (scale < pb.params.minZoom) {\n scale = pb.params.minZoom + 1 - Math.pow((pb.params.minZoom - scale + 1), 0.5);\n }\n gestureImg.transform('translate3d(0,0,0) scale(' + scale + ')');\n };\n pb.onSlideGestureEnd = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n scale = Math.max(Math.min(scale, pb.params.maxZoom), pb.params.minZoom);\n gestureImg.transition(pb.params.speed).transform('translate3d(0,0,0) scale(' + scale + ')');\n currentScale = scale;\n isScaling = false;\n if (scale === 1) gestureSlide = undefined;\n };\n pb.toggleZoom = function () {\n if (!gestureSlide) {\n gestureSlide = pb.swiper.slides.eq(pb.swiper.activeIndex);\n gestureImg = gestureSlide.find('img, svg, canvas');\n gestureImgWrap = gestureImg.parent('.photo-browser-zoom-container');\n }\n if (!gestureImg || gestureImg.length === 0) return;\n gestureImgWrap.transition(300).transform('translate3d(0,0,0)');\n if (scale && scale !== 1) {\n scale = currentScale = 1;\n gestureImg.transition(300).transform('translate3d(0,0,0) scale(1)');\n gestureSlide = undefined;\n }\n else {\n scale = currentScale = pb.params.maxZoom;\n gestureImg.transition(300).transform('translate3d(0,0,0) scale(' + scale + ')');\n }\n };\n \n var imageIsTouched, imageIsMoved, imageCurrentX, imageCurrentY, imageMinX, imageMinY, imageMaxX, imageMaxY, imageWidth, imageHeight, imageTouchesStart = {}, imageTouchesCurrent = {}, imageStartX, imageStartY, velocityPrevPositionX, velocityPrevTime, velocityX, velocityPrevPositionY, velocityY;\n \n pb.onSlideTouchStart = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n if (imageIsTouched) return;\n if (app.device.os === 'android') e.preventDefault();\n imageIsTouched = true;\n imageTouchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n imageTouchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n };\n pb.onSlideTouchMove = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n pb.swiper.allowClick = false;\n if (!imageIsTouched || !gestureSlide) return;\n \n if (!imageIsMoved) {\n imageWidth = gestureImg[0].offsetWidth;\n imageHeight = gestureImg[0].offsetHeight;\n imageStartX = $.getTranslate(gestureImgWrap[0], 'x') || 0;\n imageStartY = $.getTranslate(gestureImgWrap[0], 'y') || 0;\n gestureImgWrap.transition(0);\n }\n // Define if we need image drag\n var scaledWidth = imageWidth * scale;\n var scaledHeight = imageHeight * scale;\n \n if (scaledWidth < pb.swiper.width && scaledHeight < pb.swiper.height) return;\n \n imageMinX = Math.min((pb.swiper.width / 2 - scaledWidth / 2), 0);\n imageMaxX = -imageMinX;\n imageMinY = Math.min((pb.swiper.height / 2 - scaledHeight / 2), 0);\n imageMaxY = -imageMinY;\n \n imageTouchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n imageTouchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n \n if (!imageIsMoved && !isScaling) {\n if (\n (Math.floor(imageMinX) === Math.floor(imageStartX) && imageTouchesCurrent.x < imageTouchesStart.x) ||\n (Math.floor(imageMaxX) === Math.floor(imageStartX) && imageTouchesCurrent.x > imageTouchesStart.x)\n ) {\n imageIsTouched = false;\n return;\n }\n }\n e.preventDefault();\n e.stopPropagation();\n imageIsMoved = true;\n imageCurrentX = imageTouchesCurrent.x - imageTouchesStart.x + imageStartX;\n imageCurrentY = imageTouchesCurrent.y - imageTouchesStart.y + imageStartY;\n \n if (imageCurrentX < imageMinX) {\n imageCurrentX = imageMinX + 1 - Math.pow((imageMinX - imageCurrentX + 1), 0.8);\n }\n if (imageCurrentX > imageMaxX) {\n imageCurrentX = imageMaxX - 1 + Math.pow((imageCurrentX - imageMaxX + 1), 0.8);\n }\n \n if (imageCurrentY < imageMinY) {\n imageCurrentY = imageMinY + 1 - Math.pow((imageMinY - imageCurrentY + 1), 0.8);\n }\n if (imageCurrentY > imageMaxY) {\n imageCurrentY = imageMaxY - 1 + Math.pow((imageCurrentY - imageMaxY + 1), 0.8);\n }\n \n //Velocity\n if (!velocityPrevPositionX) velocityPrevPositionX = imageTouchesCurrent.x;\n if (!velocityPrevPositionY) velocityPrevPositionY = imageTouchesCurrent.y;\n if (!velocityPrevTime) velocityPrevTime = Date.now();\n velocityX = (imageTouchesCurrent.x - velocityPrevPositionX) / (Date.now() - velocityPrevTime) / 2;\n velocityY = (imageTouchesCurrent.y - velocityPrevPositionY) / (Date.now() - velocityPrevTime) / 2;\n if (Math.abs(imageTouchesCurrent.x - velocityPrevPositionX) < 2) velocityX = 0;\n if (Math.abs(imageTouchesCurrent.y - velocityPrevPositionY) < 2) velocityY = 0;\n velocityPrevPositionX = imageTouchesCurrent.x;\n velocityPrevPositionY = imageTouchesCurrent.y;\n velocityPrevTime = Date.now();\n \n gestureImgWrap.transform('translate3d(' + imageCurrentX + 'px, ' + imageCurrentY + 'px,0)');\n };\n pb.onSlideTouchEnd = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n if (!imageIsTouched || !imageIsMoved) {\n imageIsTouched = false;\n imageIsMoved = false;\n return;\n }\n imageIsTouched = false;\n imageIsMoved = false;\n var momentumDurationX = 300;\n var momentumDurationY = 300;\n var momentumDistanceX = velocityX * momentumDurationX;\n var newPositionX = imageCurrentX + momentumDistanceX;\n var momentumDistanceY = velocityY * momentumDurationY;\n var newPositionY = imageCurrentY + momentumDistanceY;\n \n //Fix duration\n if (velocityX !== 0) momentumDurationX = Math.abs((newPositionX - imageCurrentX) / velocityX);\n if (velocityY !== 0) momentumDurationY = Math.abs((newPositionY - imageCurrentY) / velocityY);\n var momentumDuration = Math.max(momentumDurationX, momentumDurationY);\n \n imageCurrentX = newPositionX;\n imageCurrentY = newPositionY;\n \n // Define if we need image drag\n var scaledWidth = imageWidth * scale;\n var scaledHeight = imageHeight * scale;\n imageMinX = Math.min((pb.swiper.width / 2 - scaledWidth / 2), 0);\n imageMaxX = -imageMinX;\n imageMinY = Math.min((pb.swiper.height / 2 - scaledHeight / 2), 0);\n imageMaxY = -imageMinY;\n imageCurrentX = Math.max(Math.min(imageCurrentX, imageMaxX), imageMinX);\n imageCurrentY = Math.max(Math.min(imageCurrentY, imageMaxY), imageMinY);\n \n gestureImgWrap.transition(momentumDuration).transform('translate3d(' + imageCurrentX + 'px, ' + imageCurrentY + 'px,0)');\n };\n \n // Swipe Up To Close\n var swipeToCloseIsTouched = false;\n var allowSwipeToClose = true;\n var swipeToCloseDiff, swipeToCloseStart, swipeToCloseCurrent, swipeToCloseStarted = false, swipeToCloseActiveSlide, swipeToCloseTimeStart;\n pb.swipeCloseTouchStart = function (swiper, e) {\n if (!allowSwipeToClose) return;\n swipeToCloseIsTouched = true;\n };\n pb.swipeCloseTouchMove = function (swiper, e) {\n if (!swipeToCloseIsTouched) return;\n if (!swipeToCloseStarted) {\n swipeToCloseStarted = true;\n swipeToCloseStart = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n swipeToCloseActiveSlide = pb.swiper.slides.eq(pb.swiper.activeIndex);\n swipeToCloseTimeStart = (new Date()).getTime();\n }\n e.preventDefault();\n swipeToCloseCurrent = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n swipeToCloseDiff = swipeToCloseStart - swipeToCloseCurrent;\n var opacity = 1 - Math.abs(swipeToCloseDiff) / 300;\n swipeToCloseActiveSlide.transform('translate3d(0,' + (-swipeToCloseDiff) + 'px,0)');\n pb.swiper.container.css('opacity', opacity).transition(0);\n };\n pb.swipeCloseTouchEnd = function (swiper, e) {\n swipeToCloseIsTouched = false;\n if (!swipeToCloseStarted) {\n swipeToCloseStarted = false;\n return;\n }\n swipeToCloseStarted = false;\n allowSwipeToClose = false;\n var diff = Math.abs(swipeToCloseDiff);\n var timeDiff = (new Date()).getTime() - swipeToCloseTimeStart;\n if ((timeDiff < 300 && diff > 20) || (timeDiff >= 300 && diff > 100)) {\n setTimeout(function () {\n if (pb.params.type === 'standalone') {\n pb.close();\n }\n if (pb.params.type === 'popup') {\n app.closeModal(pb.popup);\n }\n if (pb.params.onSwipeToClose) {\n pb.params.onSwipeToClose(pb);\n }\n allowSwipeToClose = true;\n }, 0);\n return;\n }\n if (diff !== 0) {\n swipeToCloseActiveSlide.addClass('transitioning').transitionEnd(function () {\n allowSwipeToClose = true;\n swipeToCloseActiveSlide.removeClass('transitioning');\n });\n }\n else {\n allowSwipeToClose = true;\n }\n pb.swiper.container.css('opacity', '').transition('');\n swipeToCloseActiveSlide.transform('');\n };\n \n return pb;\n };\n \n app.photoBrowser = function (params) {\n return new PhotoBrowser(params);\n };\n \n"," /*======================================================\n ************ Picker ************\n ======================================================*/\n var Picker = function (params) {\n var p = this;\n var defaults = {\n updateValuesOnMomentum: false,\n updateValuesOnTouchmove: true,\n rotateEffect: false,\n momentumRatio: 7,\n freeMode: false,\n // Common settings\n scrollToInput: true,\n inputReadOnly: true,\n convertToPopover: true,\n toolbar: true,\n toolbarCloseText: 'Done',\n toolbarTemplate: \n '<div class=\"toolbar\">' +\n '<div class=\"toolbar-inner\">' +\n '<div class=\"left\"></div>' +\n '<div class=\"right\">' +\n '<a href=\"#\" class=\"link close-picker\">{{closeText}}</a>' +\n '</div>' +\n '</div>' +\n '</div>'\n };\n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n p.params = params;\n p.cols = [];\n p.initialized = false;\n \n // Inline flag\n p.inline = p.params.container ? true : false;\n \n // 3D Transforms origin bug, only on safari\n var originBug = app.device.ios || (navigator.userAgent.toLowerCase().indexOf('safari') >= 0 && navigator.userAgent.toLowerCase().indexOf('chrome') < 0) && !app.device.android;\n \n // Should be converted to popover\n function isPopover() {\n var toPopover = false;\n if (!p.params.convertToPopover) return toPopover;\n if (!p.inline && p.params.input) {\n if (app.device.ios) {\n toPopover = app.device.ipad ? true : false;\n }\n else {\n if ($(window).width() >= 768) toPopover = true;\n }\n } \n return toPopover; \n }\n function inPopover() {\n if (p.opened && p.container && p.container.length > 0 && p.container.parents('.popover').length > 0) return true;\n else return false;\n }\n \n // Value\n p.setValue = function (arrValues, transition) {\n var valueIndex = 0;\n for (var i = 0; i < p.cols.length; i++) {\n if (p.cols[i] && !p.cols[i].divider) {\n p.cols[i].setValue(arrValues[valueIndex], transition);\n valueIndex++;\n }\n }\n };\n p.updateValue = function () {\n var newValue = [];\n var newDisplayValue = [];\n for (var i = 0; i < p.cols.length; i++) {\n if (!p.cols[i].divider) {\n newValue.push(p.cols[i].value);\n newDisplayValue.push(p.cols[i].displayValue);\n }\n }\n if (newValue.indexOf(undefined) >= 0) {\n return;\n }\n p.value = newValue;\n p.displayValue = newDisplayValue;\n if (p.params.onChange) {\n p.params.onChange(p, p.value, p.displayValue);\n }\n if (p.input && p.input.length > 0) {\n $(p.input).val(p.params.formatValue ? p.params.formatValue(p, p.value, p.displayValue) : p.value.join(' '));\n $(p.input).trigger('change');\n }\n };\n \n // Columns Handlers\n p.initPickerCol = function (colElement, updateItems) {\n var colContainer = $(colElement);\n var colIndex = colContainer.index();\n var col = p.cols[colIndex];\n if (col.divider) return;\n col.container = colContainer;\n col.wrapper = col.container.find('.picker-items-col-wrapper');\n col.items = col.wrapper.find('.picker-item');\n \n var i, j;\n var wrapperHeight, itemHeight, itemsHeight, minTranslate, maxTranslate;\n col.replaceValues = function (values, displayValues) {\n col.values = values;\n col.displayValues = displayValues;\n var newItemsHTML = p.columnHTML(col, true);\n col.wrapper.html(newItemsHTML);\n col.items = col.wrapper.find('.picker-item');\n col.calcSize();\n col.setValue(col.values[0], 0, true);\n };\n col.calcSize = function () {\n if (p.params.rotateEffect) {\n col.container.removeClass('picker-items-col-absolute');\n if (!col.width) col.container.css({width:''});\n }\n var colWidth, colHeight;\n colWidth = 0;\n colHeight = col.container[0].offsetHeight;\n wrapperHeight = col.wrapper[0].offsetHeight;\n itemHeight = col.items[0].offsetHeight;\n itemsHeight = itemHeight * col.items.length;\n minTranslate = colHeight / 2 - itemsHeight + itemHeight / 2;\n maxTranslate = colHeight / 2 - itemHeight / 2; \n if (col.width) {\n colWidth = col.width;\n if (parseInt(colWidth, 10) === colWidth) colWidth = colWidth + 'px';\n col.container.css({width: colWidth});\n }\n if (p.params.rotateEffect) {\n if (!col.width) {\n col.items.each(function () {\n var item = $(this);\n item.css({width:'auto'});\n colWidth = Math.max(colWidth, item[0].offsetWidth);\n item.css({width:''});\n });\n col.container.css({width: (colWidth + 2) + 'px'});\n }\n col.container.addClass('picker-items-col-absolute');\n }\n };\n col.calcSize();\n \n col.wrapper.transform('translate3d(0,' + maxTranslate + 'px,0)').transition(0);\n \n \n var activeIndex = 0;\n var animationFrameId;\n \n // Set Value Function\n col.setValue = function (newValue, transition, valueCallbacks) {\n if (typeof transition === 'undefined') transition = '';\n var newActiveIndex = col.wrapper.find('.picker-item[data-picker-value=\"' + newValue + '\"]').index();\n if(typeof newActiveIndex === 'undefined' || newActiveIndex === -1) {\n return;\n }\n var newTranslate = -newActiveIndex * itemHeight + maxTranslate;\n // Update wrapper\n col.wrapper.transition(transition);\n col.wrapper.transform('translate3d(0,' + (newTranslate) + 'px,0)');\n \n // Watch items\n if (p.params.updateValuesOnMomentum && col.activeIndex && col.activeIndex !== newActiveIndex ) {\n $.cancelAnimationFrame(animationFrameId);\n col.wrapper.transitionEnd(function(){\n $.cancelAnimationFrame(animationFrameId);\n });\n updateDuringScroll();\n }\n \n // Update items\n col.updateItems(newActiveIndex, newTranslate, transition, valueCallbacks);\n };\n \n col.updateItems = function (activeIndex, translate, transition, valueCallbacks) {\n if (typeof translate === 'undefined') {\n translate = $.getTranslate(col.wrapper[0], 'y');\n }\n if(typeof activeIndex === 'undefined') activeIndex = -Math.round((translate - maxTranslate)/itemHeight);\n if (activeIndex < 0) activeIndex = 0;\n if (activeIndex >= col.items.length) activeIndex = col.items.length - 1;\n var previousActiveIndex = col.activeIndex;\n col.activeIndex = activeIndex;\n col.wrapper.find('.picker-selected, .picker-after-selected, .picker-before-selected').removeClass('picker-selected picker-after-selected picker-before-selected');\n \n col.items.transition(transition);\n var selectedItem = col.items.eq(activeIndex).addClass('picker-selected').transform('');\n var prevItems = selectedItem.prevAll().addClass('picker-before-selected');\n var nextItems = selectedItem.nextAll().addClass('picker-after-selected');\n \n if (valueCallbacks || typeof valueCallbacks === 'undefined') {\n // Update values\n col.value = selectedItem.attr('data-picker-value');\n col.displayValue = col.displayValues ? col.displayValues[activeIndex] : col.value;\n // On change callback\n if (previousActiveIndex !== activeIndex) {\n if (col.onChange) {\n col.onChange(p, col.value, col.displayValue);\n }\n p.updateValue();\n }\n }\n \n // Set 3D rotate effect\n if (!p.params.rotateEffect) {\n return;\n }\n var percentage = (translate - (Math.floor((translate - maxTranslate)/itemHeight) * itemHeight + maxTranslate)) / itemHeight;\n \n col.items.each(function () {\n var item = $(this);\n var itemOffsetTop = item.index() * itemHeight;\n var translateOffset = maxTranslate - translate;\n var itemOffset = itemOffsetTop - translateOffset;\n var percentage = itemOffset / itemHeight;\n \n var itemsFit = Math.ceil(col.height / itemHeight / 2) + 1;\n \n var angle = (-18*percentage);\n if (angle > 180) angle = 180;\n if (angle < -180) angle = -180;\n // Far class\n if (Math.abs(percentage) > itemsFit) item.addClass('picker-item-far');\n else item.removeClass('picker-item-far');\n // Set transform\n item.transform('translate3d(0, ' + (-translate + maxTranslate) + 'px, ' + (originBug ? -110 : 0) + 'px) rotateX(' + angle + 'deg)');\n });\n };\n \n function updateDuringScroll() {\n animationFrameId = $.requestAnimationFrame(function () {\n col.updateItems(undefined, undefined, 0);\n updateDuringScroll();\n });\n }\n \n // Update items on init\n if (updateItems) col.updateItems(0, maxTranslate, 0);\n \n var allowItemClick = true;\n var isTouched, isMoved, touchStartY, touchCurrentY, touchStartTime, touchEndTime, startTranslate, returnTo, currentTranslate, prevTranslate, velocityTranslate, velocityTime;\n function handleTouchStart (e) {\n if (isMoved || isTouched) return;\n e.preventDefault();\n isTouched = true;\n touchStartY = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n \n allowItemClick = true;\n startTranslate = currentTranslate = $.getTranslate(col.wrapper[0], 'y');\n }\n function handleTouchMove (e) {\n if (!isTouched) return;\n e.preventDefault();\n allowItemClick = false;\n touchCurrentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (!isMoved) {\n // First move\n $.cancelAnimationFrame(animationFrameId);\n isMoved = true;\n startTranslate = currentTranslate = $.getTranslate(col.wrapper[0], 'y');\n col.wrapper.transition(0);\n }\n e.preventDefault();\n \n var diff = touchCurrentY - touchStartY;\n currentTranslate = startTranslate + diff;\n returnTo = undefined;\n \n // Normalize translate\n if (currentTranslate < minTranslate) {\n currentTranslate = minTranslate - Math.pow(minTranslate - currentTranslate, 0.8);\n returnTo = 'min';\n }\n if (currentTranslate > maxTranslate) {\n currentTranslate = maxTranslate + Math.pow(currentTranslate - maxTranslate, 0.8);\n returnTo = 'max';\n }\n // Transform wrapper\n col.wrapper.transform('translate3d(0,' + currentTranslate + 'px,0)');\n \n // Update items\n col.updateItems(undefined, currentTranslate, 0, p.params.updateValuesOnTouchmove);\n \n // Calc velocity\n velocityTranslate = currentTranslate - prevTranslate || currentTranslate;\n velocityTime = (new Date()).getTime();\n prevTranslate = currentTranslate;\n }\n function handleTouchEnd (e) {\n if (!isTouched || !isMoved) {\n isTouched = isMoved = false;\n return;\n }\n isTouched = isMoved = false;\n col.wrapper.transition('');\n if (returnTo) {\n if (returnTo === 'min') {\n col.wrapper.transform('translate3d(0,' + minTranslate + 'px,0)');\n }\n else col.wrapper.transform('translate3d(0,' + maxTranslate + 'px,0)');\n }\n touchEndTime = new Date().getTime();\n var velocity, newTranslate;\n if (touchEndTime - touchStartTime > 300) {\n newTranslate = currentTranslate;\n }\n else {\n velocity = Math.abs(velocityTranslate / (touchEndTime - velocityTime));\n newTranslate = currentTranslate + velocityTranslate * p.params.momentumRatio;\n }\n \n newTranslate = Math.max(Math.min(newTranslate, maxTranslate), minTranslate);\n \n // Active Index\n var activeIndex = -Math.floor((newTranslate - maxTranslate)/itemHeight);\n \n // Normalize translate\n if (!p.params.freeMode) newTranslate = -activeIndex * itemHeight + maxTranslate;\n \n // Transform wrapper\n col.wrapper.transform('translate3d(0,' + (parseInt(newTranslate,10)) + 'px,0)');\n \n // Update items\n col.updateItems(activeIndex, newTranslate, '', true);\n \n // Watch items\n if (p.params.updateValuesOnMomentum) {\n updateDuringScroll();\n col.wrapper.transitionEnd(function(){\n $.cancelAnimationFrame(animationFrameId);\n });\n }\n \n // Allow click\n setTimeout(function () {\n allowItemClick = true;\n }, 100);\n }\n \n function handleClick(e) {\n if (!allowItemClick) return;\n $.cancelAnimationFrame(animationFrameId);\n /*jshint validthis:true */\n var value = $(this).attr('data-picker-value');\n col.setValue(value);\n }\n \n col.container.on(app.touchEvents.start, handleTouchStart);\n col.container.on(app.touchEvents.move, handleTouchMove);\n col.container.on(app.touchEvents.end, handleTouchEnd);\n col.items.on('click', handleClick);\n \n col.container[0].f7DestroyPickerCol = function () {\n col.container.off(app.touchEvents.start, handleTouchStart);\n col.container.off(app.touchEvents.move, handleTouchMove);\n col.container.off(app.touchEvents.end, handleTouchEnd);\n col.items.off('click', handleClick);\n };\n \n };\n p.destroyPickerCol = function (colContainer) {\n colContainer = $(colContainer);\n if ('f7DestroyPickerCol' in colContainer[0]) colContainer[0].f7DestroyPickerCol();\n };\n // Resize cols\n function resizeCols() {\n if (!p.opened) return;\n for (var i = 0; i < p.cols.length; i++) {\n if (!p.cols[i].divider) {\n p.cols[i].calcSize();\n p.cols[i].setValue(p.cols[i].value, 0, false);\n }\n }\n }\n $(window).on('resize', resizeCols);\n \n // HTML Layout\n p.columnHTML = function (col, onlyItems) {\n var columnItemsHTML = '';\n var columnHTML = '';\n if (col.divider) {\n columnHTML += '<div class=\"picker-items-col picker-items-col-divider ' + (col.textAlign ? 'picker-items-col-' + col.textAlign : '') + ' ' + (col.cssClass || '') + '\">' + col.content + '</div>';\n }\n else {\n for (var j = 0; j < col.values.length; j++) {\n columnItemsHTML += '<div class=\"picker-item\" data-picker-value=\"' + col.values[j] + '\">' + (col.displayValues ? col.displayValues[j] : col.values[j]) + '</div>';\n }\n columnHTML += '<div class=\"picker-items-col ' + (col.textAlign ? 'picker-items-col-' + col.textAlign : '') + ' ' + (col.cssClass || '') + '\"><div class=\"picker-items-col-wrapper\">' + columnItemsHTML + '</div></div>';\n }\n return onlyItems ? columnItemsHTML : columnHTML;\n };\n p.layout = function () {\n var pickerHTML = '';\n var pickerClass = '';\n var i;\n p.cols = [];\n var colsHTML = '';\n for (i = 0; i < p.params.cols.length; i++) {\n var col = p.params.cols[i];\n colsHTML += p.columnHTML(p.params.cols[i]);\n p.cols.push(col);\n }\n pickerClass = 'picker-modal picker-columns ' + (p.params.cssClass || '') + (p.params.rotateEffect ? ' picker-3d' : '');\n pickerHTML =\n '<div class=\"' + (pickerClass) + '\">' +\n (p.params.toolbar ? p.params.toolbarTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText) : '') +\n '<div class=\"picker-modal-inner picker-items\">' +\n colsHTML +\n '<div class=\"picker-center-highlight\"></div>' +\n '</div>' +\n '</div>';\n \n p.pickerHTML = pickerHTML; \n };\n \n // Input Events\n function openOnInput(e) {\n e.preventDefault();\n if (p.opened) return;\n p.open();\n if (p.params.scrollToInput && !isPopover()) {\n var pageContent = p.input.parents('.page-content');\n if (pageContent.length === 0) return;\n \n var paddingTop = parseInt(pageContent.css('padding-top'), 10),\n paddingBottom = parseInt(pageContent.css('padding-bottom'), 10),\n pageHeight = pageContent[0].offsetHeight - paddingTop - p.container.height(),\n pageScrollHeight = pageContent[0].scrollHeight - paddingTop - p.container.height(),\n newPaddingBottom;\n var inputTop = p.input.offset().top - paddingTop + p.input[0].offsetHeight;\n if (inputTop > pageHeight) {\n var scrollTop = pageContent.scrollTop() + inputTop - pageHeight;\n if (scrollTop + pageHeight > pageScrollHeight) {\n newPaddingBottom = scrollTop + pageHeight - pageScrollHeight + paddingBottom;\n if (pageHeight === pageScrollHeight) {\n newPaddingBottom = p.container.height();\n }\n pageContent.css({'padding-bottom': (newPaddingBottom) + 'px'});\n }\n pageContent.scrollTop(scrollTop, 300);\n }\n }\n }\n function closeOnHTMLClick(e) {\n if (inPopover()) return;\n if (p.input && p.input.length > 0) {\n if (e.target !== p.input[0] && $(e.target).parents('.picker-modal').length === 0) p.close();\n }\n else {\n if ($(e.target).parents('.picker-modal').length === 0) p.close(); \n }\n }\n \n if (p.params.input) {\n p.input = $(p.params.input);\n if (p.params.inputReadOnly) p.input.prop('readOnly', true);\n if (!p.inline) {\n p.input.on('click', openOnInput); \n }\n if (p.params.inputReadOnly) {\n p.input.on('focus mousedown', function (e) {\n e.preventDefault();\n });\n }\n }\n \n if (!p.inline) $('html').on('click', closeOnHTMLClick);\n \n // Open\n function onPickerClose() {\n p.opened = false;\n p.input.parents('.page-content').css({'padding-bottom': ''});\n if (p.params.onClose) p.params.onClose(p);\n \n // Destroy events\n p.container.find('.picker-items-col').each(function () {\n p.destroyPickerCol(this);\n });\n }\n \n p.opened = false;\n p.open = function () {\n var toPopover = isPopover();\n \n if (!p.opened) {\n \n // Layout\n p.layout();\n \n // Append\n if (toPopover) {\n p.pickerHTML = '<div class=\"popover popover-picker-columns\"><div class=\"popover-inner\">' + p.pickerHTML + '</div></div>';\n p.popover = app.popover(p.pickerHTML, p.params.input, true);\n p.container = $(p.popover).find('.picker-modal');\n $(p.popover).on('close', function () {\n onPickerClose();\n });\n }\n else if (p.inline) {\n p.container = $(p.pickerHTML);\n p.container.addClass('picker-modal-inline');\n $(p.params.container).append(p.container);\n }\n else {\n p.container = $(app.pickerModal(p.pickerHTML));\n $(p.container)\n .on('close', function () {\n onPickerClose();\n });\n }\n \n // Store picker instance\n p.container[0].f7Picker = p;\n \n // Init Events\n p.container.find('.picker-items-col').each(function () {\n var updateItems = true;\n if ((!p.initialized && p.params.value) || (p.initialized && p.value)) updateItems = false;\n p.initPickerCol(this, updateItems);\n });\n \n // Set value\n if (!p.initialized) {\n if (p.params.value) {\n p.setValue(p.params.value, 0);\n }\n }\n else {\n if (p.value) p.setValue(p.value, 0);\n }\n }\n \n // Set flag\n p.opened = true;\n p.initialized = true;\n \n if (p.params.onOpen) p.params.onOpen(p);\n };\n \n // Close\n p.close = function () {\n if (!p.opened || p.inline) return;\n if (inPopover()) {\n app.closeModal(p.popover);\n return;\n }\n else {\n app.closeModal(p.container);\n return;\n }\n };\n \n // Destroy\n p.destroy = function () {\n p.close();\n if (p.params.input) {\n p.input.off('click focus', openOnInput);\n }\n $('html').off('click', closeOnHTMLClick);\n $(window).off('resize', resizeCols);\n };\n \n if (p.inline) {\n p.open();\n }\n \n return p;\n };\n app.picker = function (params) {\n return new Picker(params);\n };\n"," /*======================================================\n ************ Calendar ************\n ======================================================*/\n var Calendar = function (params) {\n var p = this;\n var defaults = {\n monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August' , 'September' , 'October', 'November', 'December'],\n monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n firstDay: 1, // First day of the week, Monday\n weekendDays: [0, 6], // Sunday and Saturday\n multiple: false,\n dateFormat: 'yyyy-mm-dd',\n direction: 'horizontal', // or 'vertical'\n minDate: null,\n maxDate: null,\n touchMove: true,\n animate: true,\n closeOnSelect: false,\n monthPicker: true,\n monthPickerTemplate: \n '<div class=\"picker-calendar-month-picker\">' +\n '<a href=\"#\" class=\"link icon-only picker-calendar-prev-month\"><i class=\"icon icon-prev\"></i></a>' +\n '<span class=\"current-month-value\">August</span>' +\n '<a href=\"#\" class=\"link icon-only picker-calendar-next-month\"><i class=\"icon icon-next\"></i></a>' +\n '</div>',\n yearPicker: true,\n yearPickerTemplate: \n '<div class=\"picker-calendar-year-picker\">' +\n '<a href=\"#\" class=\"link icon-only picker-calendar-prev-year\"><i class=\"icon icon-prev\"></i></a>' +\n '<span class=\"current-year-value\">2015</span>' +\n '<a href=\"#\" class=\"link icon-only picker-calendar-next-year\"><i class=\"icon icon-next\"></i></a>' +\n '</div>',\n weekHeader: true,\n // Common settings\n scrollToInput: true,\n inputReadOnly: true,\n convertToPopover: true,\n toolbar: true,\n toolbarCloseText: 'Done',\n toolbarTemplate: \n '<div class=\"toolbar\">' +\n '<div class=\"toolbar-inner\">' +\n '{{monthPicker}}' +\n '{{yearPicker}}' +\n // '<a href=\"#\" class=\"link close-picker\">{{closeText}}</a>' +\n '</div>' +\n '</div>',\n /* Callbacks\n onMonthAdd\n onChange\n onOpen\n onClose\n onDayClick\n onMonthYearChangeStart\n onMonthYearChangeEnd\n */\n };\n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n p.params = params;\n p.initialized = false;\n \n // Inline flag\n p.inline = p.params.container ? true : false;\n \n // Is horizontal\n p.isH = p.params.direction === 'horizontal';\n \n // RTL inverter\n var inverter = p.isH ? (app.rtl ? -1 : 1) : 1;\n \n // Animating flag\n p.animating = false;\n \n // Should be converted to popover\n function isPopover() {\n var toPopover = false;\n if (!p.params.convertToPopover) return toPopover;\n if (!p.inline && p.params.input) {\n if (app.device.ios) {\n toPopover = app.device.ipad ? true : false;\n }\n else {\n if ($(window).width() >= 768) toPopover = true;\n }\n } \n return toPopover; \n }\n function inPopover() {\n if (p.opened && p.container && p.container.length > 0 && p.container.parents('.popover').length > 0) return true;\n else return false;\n }\n \n // Format date\n function formatDate(date) {\n date = new Date(date);\n var year = date.getFullYear();\n var month = date.getMonth();\n var month1 = month + 1;\n var day = date.getDate();\n var weekDay = date.getDay();\n return p.params.dateFormat\n .replace(/yyyy/g, year)\n .replace(/yy/g, (year + '').substring(2))\n .replace(/mm/g, month1 < 10 ? '0' + month1 : month1)\n .replace(/m/g, month1)\n .replace(/MM/g, p.params.monthNames[month])\n .replace(/M/g, p.params.monthNamesShort[month])\n .replace(/dd/g, day < 10 ? '0' + day : day)\n .replace(/d/g, day)\n .replace(/DD/g, p.params.dayNames[weekDay])\n .replace(/D/g, p.params.dayNamesShort[weekDay]);\n }\n \n \n // Value\n p.addValue = function (value) {\n if (p.params.multiple) {\n if (!p.value) p.value = [];\n var inValuesIndex;\n for (var i = 0; i < p.value.length; i++) {\n if (new Date(value).getTime() === new Date(p.value[i]).getTime()) {\n inValuesIndex = i;\n }\n }\n if (typeof inValuesIndex === 'undefined') {\n p.value.push(value);\n }\n else {\n p.value.splice(inValuesIndex, 1);\n }\n p.updateValue();\n }\n else {\n p.value = [value];\n p.updateValue();\n }\n };\n p.setValue = function (arrValues) {\n p.value = arrValues;\n p.updateValue(); \n };\n p.updateValue = function () {\n p.wrapper.find('.picker-calendar-day-selected').removeClass('picker-calendar-day-selected');\n var i, inputValue;\n for (i = 0; i < p.value.length; i++) {\n var valueDate = new Date(p.value[i]);\n p.wrapper.find('.picker-calendar-day[data-date=\"' + valueDate.getFullYear() + '-' + valueDate.getMonth() + '-' + valueDate.getDate() + '\"]').addClass('picker-calendar-day-selected');\n }\n if (p.params.onChange) {\n p.params.onChange(p, p.value);\n }\n if (p.input && p.input.length > 0) {\n if (p.params.formatValue) inputValue = p.params.formatValue(p, p.value);\n else {\n inputValue = [];\n for (i = 0; i < p.value.length; i++) {\n inputValue.push(formatDate(p.value[i]));\n }\n inputValue = inputValue.join(', ');\n } \n $(p.input).val(inputValue);\n $(p.input).trigger('change');\n }\n };\n \n // Columns Handlers\n p.initCalendarEvents = function () {\n var col;\n var allowItemClick = true;\n var isTouched, isMoved, touchStartX, touchStartY, touchCurrentX, touchCurrentY, touchStartTime, touchEndTime, startTranslate, currentTranslate, wrapperWidth, wrapperHeight, percentage, touchesDiff, isScrolling;\n function handleTouchStart (e) {\n if (isMoved || isTouched) return;\n // e.preventDefault();\n isTouched = true;\n touchStartX = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchStartY = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n percentage = 0;\n allowItemClick = true;\n isScrolling = undefined;\n startTranslate = currentTranslate = p.monthsTranslate;\n }\n function handleTouchMove (e) {\n if (!isTouched) return;\n \n touchCurrentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n touchCurrentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(touchCurrentY - touchStartY) > Math.abs(touchCurrentX - touchStartX));\n }\n if (p.isH && isScrolling) {\n isTouched = false;\n return;\n }\n e.preventDefault();\n if (p.animating) {\n isTouched = false;\n return; \n }\n allowItemClick = false;\n if (!isMoved) {\n // First move\n isMoved = true;\n wrapperWidth = p.wrapper[0].offsetWidth;\n wrapperHeight = p.wrapper[0].offsetHeight;\n p.wrapper.transition(0);\n }\n e.preventDefault();\n \n touchesDiff = p.isH ? touchCurrentX - touchStartX : touchCurrentY - touchStartY;\n percentage = touchesDiff/(p.isH ? wrapperWidth : wrapperHeight);\n currentTranslate = (p.monthsTranslate * inverter + percentage) * 100;\n \n // Transform wrapper\n p.wrapper.transform('translate3d(' + (p.isH ? currentTranslate : 0) + '%, ' + (p.isH ? 0 : currentTranslate) + '%, 0)');\n \n }\n function handleTouchEnd (e) {\n if (!isTouched || !isMoved) {\n isTouched = isMoved = false;\n return;\n }\n isTouched = isMoved = false;\n \n touchEndTime = new Date().getTime();\n if (touchEndTime - touchStartTime < 300) {\n if (Math.abs(touchesDiff) < 10) {\n p.resetMonth();\n }\n else if (touchesDiff >= 10) {\n if (app.rtl) p.nextMonth();\n else p.prevMonth();\n }\n else {\n if (app.rtl) p.prevMonth();\n else p.nextMonth(); \n }\n }\n else {\n if (percentage <= -0.5) {\n if (app.rtl) p.prevMonth();\n else p.nextMonth();\n }\n else if (percentage >= 0.5) {\n if (app.rtl) p.nextMonth();\n else p.prevMonth();\n }\n else {\n p.resetMonth();\n }\n }\n \n // Allow click\n setTimeout(function () {\n allowItemClick = true;\n }, 100);\n }\n \n function handleDayClick(e) {\n if (!allowItemClick) return;\n var day = $(e.target).parents('.picker-calendar-day');\n if (day.length === 0 && $(e.target).hasClass('picker-calendar-day')) {\n day = $(e.target);\n }\n if (day.length === 0) return;\n if (day.hasClass('picker-calendar-day-selected') && !p.params.multiple) return;\n if (day.hasClass('picker-calendar-day-disabled')) return;\n if (day.hasClass('picker-calendar-day-next')) p.nextMonth();\n if (day.hasClass('picker-calendar-day-prev')) p.prevMonth();\n var dateYear = day.attr('data-year');\n var dateMonth = day.attr('data-month');\n var dateDay = day.attr('data-day');\n if (p.params.onDayClick) {\n p.params.onDayClick(p, day[0], dateYear, dateMonth, dateDay);\n }\n p.addValue(new Date(dateYear, dateMonth, dateDay).getTime());\n if (p.params.closeOnSelect) p.close();\n }\n \n p.container.find('.picker-calendar-prev-month').on('click', p.prevMonth);\n p.container.find('.picker-calendar-next-month').on('click', p.nextMonth);\n p.container.find('.picker-calendar-prev-year').on('click', p.prevYear);\n p.container.find('.picker-calendar-next-year').on('click', p.nextYear);\n p.wrapper.on('click', handleDayClick);\n if (p.params.touchMove) {\n p.wrapper.on(app.touchEvents.start, handleTouchStart);\n p.wrapper.on(app.touchEvents.move, handleTouchMove);\n p.wrapper.on(app.touchEvents.end, handleTouchEnd);\n }\n \n p.container[0].f7DestroyCalendarEvents = function () {\n p.container.find('.picker-calendar-prev-month').off('click', p.prevMonth);\n p.container.find('.picker-calendar-next-month').off('click', p.nextMonth);\n p.container.find('.picker-calendar-prev-year').off('click', p.prevYear);\n p.container.find('.picker-calendar-next-year').off('click', p.nextYear);\n p.wrapper.off('click', handleDayClick);\n if (p.params.touchMove) {\n p.wrapper.off(app.touchEvents.start, handleTouchStart);\n p.wrapper.off(app.touchEvents.move, handleTouchMove);\n p.wrapper.off(app.touchEvents.end, handleTouchEnd);\n }\n };\n \n \n };\n p.destroyCalendarEvents = function (colContainer) {\n if ('f7DestroyCalendarEvents' in p.container[0]) p.container[0].f7DestroyCalendarEvents();\n };\n \n // Calendar Methods\n p.daysInMonth = function (date) {\n var d = new Date(date);\n return new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();\n };\n p.monthHTML = function (date, offset) {\n date = new Date(date);\n var year = date.getFullYear(),\n month = date.getMonth(),\n day = date.getDate();\n if (offset === 'next') {\n if (month === 11) date = new Date(year + 1, 0);\n else date = new Date(year, month + 1, 1);\n }\n if (offset === 'prev') {\n if (month === 0) date = new Date(year - 1, 11);\n else date = new Date(year, month - 1, 1);\n }\n if (offset === 'next' || offset === 'prev') {\n month = date.getMonth();\n year = date.getFullYear();\n }\n var daysInPrevMonth = p.daysInMonth(new Date(date.getFullYear(), date.getMonth()).getTime() - 10 * 24 * 60 * 60 * 1000),\n daysInMonth = p.daysInMonth(date),\n firstDayOfMonthIndex = new Date(date.getFullYear(), date.getMonth()).getDay();\n if (firstDayOfMonthIndex === 0) firstDayOfMonthIndex = 7;\n \n var dayDate, currentValues = [], i, j,\n rows = 6, cols = 7,\n monthHTML = '',\n dayIndex = 0 + (p.params.firstDay - 1), \n today = new Date().setHours(0,0,0,0),\n minDate = p.params.minDate ? new Date(p.params.minDate).getTime() : null,\n maxDate = p.params.maxDate ? new Date(p.params.maxDate).getTime() : null;\n \n if (p.value && p.value.length) {\n for (i = 0; i < p.value.length; i++) {\n currentValues.push(new Date(p.value[i]).setHours(0,0,0,0));\n }\n }\n \n for (i = 1; i <= rows; i++) {\n var rowHTML = '';\n var row = i;\n for (j = 1; j <= cols; j++) {\n var col = j;\n dayIndex ++;\n var dayNumber = dayIndex - firstDayOfMonthIndex;\n var addClass = '';\n if (dayNumber < 0) {\n dayNumber = daysInPrevMonth + dayNumber + 1;\n addClass += ' picker-calendar-day-prev';\n dayDate = new Date(month - 1 < 0 ? year - 1 : year, month - 1 < 0 ? 11 : month - 1, dayNumber).getTime();\n }\n else {\n dayNumber = dayNumber + 1;\n if (dayNumber > daysInMonth) {\n dayNumber = dayNumber - daysInMonth;\n addClass += ' picker-calendar-day-next';\n dayDate = new Date(month + 1 > 11 ? year + 1 : year, month + 1 > 11 ? 0 : month + 1, dayNumber).getTime();\n }\n else {\n dayDate = new Date(year, month, dayNumber).getTime(); \n }\n }\n // Today\n if (dayDate === today) addClass += ' picker-calendar-day-today';\n // Selected\n if (currentValues.indexOf(dayDate) >= 0) addClass += ' picker-calendar-day-selected';\n // Weekend\n if (p.params.weekendDays.indexOf(col - 1) >= 0) {\n addClass += ' picker-calendar-day-weekend';\n }\n // Disabled\n if ((minDate && dayDate < minDate) || (maxDate && dayDate > maxDate)) {\n addClass += ' picker-calendar-day-disabled'; \n }\n \n dayDate = new Date(dayDate);\n var dayYear = dayDate.getFullYear();\n var dayMonth = dayDate.getMonth();\n rowHTML += '<div data-year=\"' + dayYear + '\" data-month=\"' + dayMonth + '\" data-day=\"' + dayNumber + '\" class=\"picker-calendar-day' + (addClass) + '\" data-date=\"' + (dayYear + '-' + dayMonth + '-' + dayNumber) + '\"><span>'+dayNumber+'</span></div>';\n }\n monthHTML += '<div class=\"picker-calendar-row\">' + rowHTML + '</div>';\n }\n monthHTML = '<div class=\"picker-calendar-month\" data-year=\"' + year + '\" data-month=\"' + month + '\">' + monthHTML + '</div>';\n return monthHTML;\n };\n p.animating = false;\n p.updateCurrentMonthYear = function (dir) {\n if (typeof dir === 'undefined') {\n p.currentMonth = parseInt(p.months.eq(1).attr('data-month'), 10);\n p.currentYear = parseInt(p.months.eq(1).attr('data-year'), 10); \n }\n else {\n p.currentMonth = parseInt(p.months.eq(dir === 'next' ? (p.months.length - 1) : 0).attr('data-month'), 10);\n p.currentYear = parseInt(p.months.eq(dir === 'next' ? (p.months.length - 1) : 0).attr('data-year'), 10);\n }\n p.container.find('.current-month-value').text(p.params.monthNames[p.currentMonth]);\n p.container.find('.current-year-value').text(p.currentYear);\n \n };\n p.onMonthChangeStart = function (dir) {\n p.updateCurrentMonthYear(dir);\n p.months.removeClass('picker-calendar-month-current picker-calendar-month-prev picker-calendar-month-next');\n var currentIndex = dir === 'next' ? p.months.length - 1 : 0;\n \n p.months.eq(currentIndex).addClass('picker-calendar-month-current');\n p.months.eq(dir === 'next' ? currentIndex - 1 : currentIndex + 1).addClass(dir === 'next' ? 'picker-calendar-month-prev' : 'picker-calendar-month-next');\n \n if (p.params.onMonthYearChangeStart) {\n p.params.onMonthYearChangeStart(p, p.currentYear, p.currentMonth);\n }\n };\n p.onMonthChangeEnd = function (dir, rebuildBoth) {\n p.animating = false;\n var nextMonthHTML, prevMonthHTML, newMonthHTML;\n p.wrapper.find('.picker-calendar-month:not(.picker-calendar-month-prev):not(.picker-calendar-month-current):not(.picker-calendar-month-next)').remove();\n \n if (typeof dir === 'undefined') {\n dir = 'next';\n rebuildBoth = true;\n }\n if (!rebuildBoth) {\n newMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), dir);\n }\n else {\n p.wrapper.find('.picker-calendar-month-next, .picker-calendar-month-prev').remove();\n prevMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), 'prev');\n nextMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), 'next');\n }\n if (dir === 'next' || rebuildBoth) {\n p.wrapper.append(newMonthHTML || nextMonthHTML);\n }\n if (dir === 'prev' || rebuildBoth) {\n p.wrapper.prepend(newMonthHTML || prevMonthHTML);\n }\n p.months = p.wrapper.find('.picker-calendar-month');\n p.setMonthsTranslate(p.monthsTranslate);\n if (p.params.onMonthAdd) {\n p.params.onMonthAdd(p, dir === 'next' ? p.months.eq(p.months.length - 1)[0] : p.months.eq(0)[0]);\n }\n if (p.params.onMonthYearChangeEnd) {\n p.params.onMonthYearChangeEnd(p, p.currentYear, p.currentMonth);\n }\n };\n p.setMonthsTranslate = function (translate) {\n translate = translate || p.monthsTranslate || 0;\n if (typeof p.monthsTranslate === 'undefined') p.monthsTranslate = translate;\n p.months.removeClass('picker-calendar-month-current picker-calendar-month-prev picker-calendar-month-next');\n var prevMonthTranslate = -(translate + 1) * 100 * inverter;\n var currentMonthTranslate = -translate * 100 * inverter;\n var nextMonthTranslate = -(translate - 1) * 100 * inverter;\n p.months.eq(0).transform('translate3d(' + (p.isH ? prevMonthTranslate : 0) + '%, ' + (p.isH ? 0 : prevMonthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');\n p.months.eq(1).transform('translate3d(' + (p.isH ? currentMonthTranslate : 0) + '%, ' + (p.isH ? 0 : currentMonthTranslate) + '%, 0)').addClass('picker-calendar-month-current');\n p.months.eq(2).transform('translate3d(' + (p.isH ? nextMonthTranslate : 0) + '%, ' + (p.isH ? 0 : nextMonthTranslate) + '%, 0)').addClass('picker-calendar-month-next');\n };\n p.nextMonth = function (transition) {\n if (typeof transition === 'undefined' || typeof transition === 'object') {\n transition = '';\n if (!p.params.animate) transition = 0;\n }\n var nextMonth = parseInt(p.months.eq(p.months.length - 1).attr('data-month'), 10);\n var nextYear = parseInt(p.months.eq(p.months.length - 1).attr('data-year'), 10);\n var nextDate = new Date(nextYear, nextMonth);\n var nextDateTime = nextDate.getTime();\n var transitionEndCallback = p.animating ? false : true;\n if (p.params.maxDate) {\n if (nextDateTime > new Date(p.params.maxDate).getTime()) {\n return p.resetMonth();\n }\n }\n p.monthsTranslate --;\n if (nextMonth === p.currentMonth) {\n var nextMonthTranslate = -(p.monthsTranslate) * 100 * inverter;\n var nextMonthHTML = $(p.monthHTML(nextDateTime, 'next')).transform('translate3d(' + (p.isH ? nextMonthTranslate : 0) + '%, ' + (p.isH ? 0 : nextMonthTranslate) + '%, 0)').addClass('picker-calendar-month-next');\n p.wrapper.append(nextMonthHTML[0]);\n p.months = p.wrapper.find('.picker-calendar-month');\n if (p.params.onMonthAdd) {\n p.params.onMonthAdd(p, p.months.eq(p.months.length - 1)[0]);\n }\n }\n p.animating = true;\n p.onMonthChangeStart('next');\n var translate = (p.monthsTranslate * 100) * inverter;\n \n p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');\n if (transitionEndCallback) {\n p.wrapper.transitionEnd(function () {\n p.onMonthChangeEnd('next');\n });\n }\n if (!p.params.animate) {\n p.onMonthChangeEnd('next');\n }\n };\n p.prevMonth = function (transition) {\n if (typeof transition === 'undefined' || typeof transition === 'object') {\n transition = '';\n if (!p.params.animate) transition = 0;\n }\n var prevMonth = parseInt(p.months.eq(0).attr('data-month'), 10);\n var prevYear = parseInt(p.months.eq(0).attr('data-year'), 10);\n var prevDate = new Date(prevYear, prevMonth + 1, -1);\n var prevDateTime = prevDate.getTime();\n var transitionEndCallback = p.animating ? false : true;\n if (p.params.minDate) {\n if (prevDateTime < new Date(p.params.minDate).getTime()) {\n return p.resetMonth();\n }\n }\n p.monthsTranslate ++;\n if (prevMonth === p.currentMonth) {\n var prevMonthTranslate = -(p.monthsTranslate) * 100 * inverter;\n var prevMonthHTML = $(p.monthHTML(prevDateTime, 'prev')).transform('translate3d(' + (p.isH ? prevMonthTranslate : 0) + '%, ' + (p.isH ? 0 : prevMonthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');\n p.wrapper.prepend(prevMonthHTML[0]);\n p.months = p.wrapper.find('.picker-calendar-month');\n if (p.params.onMonthAdd) {\n p.params.onMonthAdd(p, p.months.eq(0)[0]);\n }\n }\n p.animating = true;\n p.onMonthChangeStart('prev');\n var translate = (p.monthsTranslate * 100) * inverter;\n p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');\n if (transitionEndCallback) {\n p.wrapper.transitionEnd(function () {\n p.onMonthChangeEnd('prev');\n });\n }\n if (!p.params.animate) {\n p.onMonthChangeEnd('prev');\n }\n };\n p.resetMonth = function (transition) {\n if (typeof transition === 'undefined') transition = '';\n var translate = (p.monthsTranslate * 100) * inverter;\n p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');\n };\n p.setYearMonth = function (year, month, transition) {\n if (typeof year === 'undefined') year = p.currentYear;\n if (typeof month === 'undefined') month = p.currentMonth;\n if (typeof transition === 'undefined' || typeof transition === 'object') {\n transition = '';\n if (!p.params.animate) transition = 0;\n }\n var targetDate = new Date(year, month).getTime();\n if (p.params.maxDate && targetDate > new Date(p.params.maxDate).getTime()) {\n return false;\n }\n if (p.params.minDate && targetDate < new Date(p.params.minDate).getTime()) {\n return false;\n }\n var currentDate = new Date(p.currentYear, p.currentMonth).getTime();\n var dir;\n var newMonthHTML = p.monthHTML(new Date(year, month));\n p.monthsTranslate = p.monthsTranslate || 0;\n var prevTranslate = p.monthsTranslate;\n var monthTranslate, wrapperTranslate;\n var transitionEndCallback = p.animating ? false : true;\n if (targetDate > currentDate) {\n // To next\n p.monthsTranslate --;\n dir = 'next';\n if (!p.animating) p.months.eq(p.months.length - 1).remove();\n p.wrapper.append(newMonthHTML);\n p.months = p.wrapper.find('.picker-calendar-month');\n monthTranslate = -(prevTranslate - 1) * 100 * inverter;\n p.months.eq(p.months.length - 1).transform('translate3d(' + (p.isH ? monthTranslate : 0) + '%, ' + (p.isH ? 0 : monthTranslate) + '%, 0)').addClass('picker-calendar-month-next');\n }\n else {\n // To prev\n p.monthsTranslate ++;\n dir = 'prev';\n if (!p.animating) p.months.eq(0).remove();\n p.wrapper.prepend(newMonthHTML);\n p.months = p.wrapper.find('.picker-calendar-month');\n monthTranslate = -(prevTranslate + 1) * 100 * inverter;\n p.months.eq(0).transform('translate3d(' + (p.isH ? monthTranslate : 0) + '%, ' + (p.isH ? 0 : monthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');\n }\n if (p.params.onMonthAdd) {\n p.params.onMonthAdd(p, dir === 'next' ? p.months.eq(p.months.length - 1)[0] : p.months.eq(0)[0]);\n }\n p.animating = true;\n p.onMonthChangeStart(dir);\n wrapperTranslate = (p.monthsTranslate * 100) * inverter;\n p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? wrapperTranslate : 0) + '%, ' + (p.isH ? 0 : wrapperTranslate) + '%, 0)');\n if (transitionEndCallback) {\n p.wrapper.transitionEnd(function () {\n p.onMonthChangeEnd(dir, true);\n }); \n }\n if (!p.params.animate) {\n p.onMonthChangeEnd(dir);\n }\n };\n p.nextYear = function () {\n p.setYearMonth(p.currentYear + 1);\n };\n p.prevYear = function () {\n p.setYearMonth(p.currentYear - 1);\n };\n \n \n // HTML Layout\n p.layout = function () {\n var pickerHTML = '';\n var pickerClass = '';\n var i;\n \n var layoutDate = p.value && p.value.length ? p.value[0] : new Date().setHours(0,0,0,0);\n var prevMonthHTML = p.monthHTML(layoutDate, 'prev');\n var currentMonthHTML = p.monthHTML(layoutDate);\n var nextMonthHTML = p.monthHTML(layoutDate, 'next');\n var monthsHTML = '<div class=\"picker-calendar-months\"><div class=\"picker-calendar-months-wrapper\">' + (prevMonthHTML + currentMonthHTML + nextMonthHTML) + '</div></div>';\n // Week days header\n var weekHeaderHTML = '';\n if (p.params.weekHeader) {\n for (i = 0; i < 7; i++) {\n var weekDayIndex = (i + p.params.firstDay > 6) ? (i - 7 + p.params.firstDay) : (i + p.params.firstDay);\n var dayName = p.params.dayNamesShort[weekDayIndex];\n weekHeaderHTML += '<div class=\"picker-calendar-week-day ' + ((p.params.weekendDays.indexOf(weekDayIndex) >= 0) ? 'picker-calendar-week-day-weekend' : '') + '\"> ' + dayName + '</div>';\n \n }\n weekHeaderHTML = '<div class=\"picker-calendar-week-days\">' + weekHeaderHTML + '</div>';\n }\n pickerClass = 'picker-modal picker-calendar ' + (p.params.cssClass || '');\n var toolbarHTML = p.params.toolbar ? p.params.toolbarTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText) : '';\n if (p.params.toolbar) {\n toolbarHTML = p.params.toolbarTemplate\n .replace(/{{closeText}}/g, p.params.toolbarCloseText)\n .replace(/{{monthPicker}}/g, (p.params.monthPicker ? p.params.monthPickerTemplate : ''))\n .replace(/{{yearPicker}}/g, (p.params.yearPicker ? p.params.yearPickerTemplate : ''));\n }\n \n pickerHTML =\n '<div class=\"' + (pickerClass) + '\">' +\n toolbarHTML +\n '<div class=\"picker-modal-inner\">' +\n weekHeaderHTML +\n monthsHTML +\n '</div>' +\n '</div>';\n \n \n p.pickerHTML = pickerHTML; \n };\n \n // Input Events\n function openOnInput(e) {\n e.preventDefault();\n if (p.opened) return;\n p.open();\n if (p.params.scrollToInput && !isPopover()) {\n var pageContent = p.input.parents('.page-content');\n if (pageContent.length === 0) return;\n \n var paddingTop = parseInt(pageContent.css('padding-top'), 10),\n paddingBottom = parseInt(pageContent.css('padding-bottom'), 10),\n pageHeight = pageContent[0].offsetHeight - paddingTop - p.container.height(),\n pageScrollHeight = pageContent[0].scrollHeight - paddingTop - p.container.height(),\n newPaddingBottom;\n \n var inputTop = p.input.offset().top - paddingTop + p.input[0].offsetHeight;\n if (inputTop > pageHeight) {\n var scrollTop = pageContent.scrollTop() + inputTop - pageHeight;\n if (scrollTop + pageHeight > pageScrollHeight) {\n newPaddingBottom = scrollTop + pageHeight - pageScrollHeight + paddingBottom;\n if (pageHeight === pageScrollHeight) {\n newPaddingBottom = p.container.height();\n }\n pageContent.css({'padding-bottom': (newPaddingBottom) + 'px'});\n }\n pageContent.scrollTop(scrollTop, 300);\n }\n }\n }\n function closeOnHTMLClick(e) {\n if (inPopover()) return;\n if (p.input && p.input.length > 0) {\n if (e.target !== p.input[0] && $(e.target).parents('.picker-modal').length === 0) p.close();\n }\n else {\n if ($(e.target).parents('.picker-modal').length === 0) p.close(); \n }\n }\n \n if (p.params.input) {\n p.input = $(p.params.input);\n if (p.params.inputReadOnly) p.input.prop('readOnly', true);\n if (!p.inline) {\n p.input.on('click', openOnInput); \n }\n if (p.params.inputReadOnly) {\n p.input.on('focus mousedown', function (e) {\n e.preventDefault();\n });\n }\n }\n \n if (!p.inline) $('html').on('click', closeOnHTMLClick);\n \n // Open\n function onPickerClose() {\n p.opened = false;\n p.input.parents('.page-content').css({'padding-bottom': ''});\n if (p.params.onClose) p.params.onClose(p);\n \n // Destroy events\n p.destroyCalendarEvents();\n }\n \n p.opened = false;\n p.open = function () {\n var toPopover = isPopover();\n var updateValue = false;\n if (!p.opened) {\n // Set date value\n if (!p.value) {\n if (p.params.value) {\n p.value = p.params.value;\n updateValue = true;\n }\n }\n \n // Layout\n p.layout();\n \n // Append\n if (toPopover) {\n p.pickerHTML = '<div class=\"popover popover-picker-calendar\"><div class=\"popover-inner\">' + p.pickerHTML + '</div></div>';\n p.popover = app.popover(p.pickerHTML, p.params.input, true);\n p.container = $(p.popover).find('.picker-modal');\n $(p.popover).on('close', function () {\n onPickerClose();\n });\n }\n else if (p.inline) {\n p.container = $(p.pickerHTML);\n p.container.addClass('picker-modal-inline');\n $(p.params.container).append(p.container);\n }\n else {\n p.container = $(app.pickerModal(p.pickerHTML));\n $(p.container)\n .on('close', function () {\n onPickerClose();\n });\n }\n \n // Store calendar instance\n p.container[0].f7Calendar = p;\n p.wrapper = p.container.find('.picker-calendar-months-wrapper');\n \n // Months\n p.months = p.wrapper.find('.picker-calendar-month');\n \n // Update current month and year\n p.updateCurrentMonthYear();\n \n // Set initial translate\n p.monthsTranslate = 0;\n p.setMonthsTranslate();\n \n // Init events\n p.initCalendarEvents();\n \n // Update input value\n if (updateValue) p.updateValue();\n \n }\n \n // Set flag\n p.opened = true;\n p.initialized = true;\n if (p.params.onMonthAdd) {\n p.months.each(function () {\n p.params.onMonthAdd(p, this);\n });\n }\n if (p.params.onOpen) p.params.onOpen(p);\n };\n \n // Close\n p.close = function () {\n if (!p.opened || p.inline) return;\n if (inPopover()) {\n app.closeModal(p.popover);\n return;\n }\n else {\n app.closeModal(p.container);\n return;\n }\n };\n \n // Destroy\n p.destroy = function () {\n p.close();\n if (p.params.input) {\n p.input.off('click focus', openOnInput);\n }\n $('html').off('click', closeOnHTMLClick);\n };\n \n if (p.inline) {\n p.open();\n }\n \n return p;\n };\n app.calendar = function (params) {\n return new Calendar(params);\n };\n"," /*======================================================\n ************ Notifications ************\n ======================================================*/\n var _tempNotificationElement;\n app.addNotification = function (params) {\n if (!params) return;\n \n if (typeof params.media === 'undefined') params.media = app.params.notificationMedia;\n if (typeof params.title === 'undefined') params.title = app.params.notificationTitle;\n if (typeof params.subtitle === 'undefined') params.subtitle = app.params.notificationSubtitle;\n if (typeof params.closeIcon === 'undefined') params.closeIcon = app.params.notificationCloseIcon;\n if (typeof params.hold === 'undefined') params.hold = app.params.notificationHold;\n if (typeof params.closeOnClick === 'undefined') params.closeOnClick = app.params.notificationCloseOnClick;\n \n if (!_tempNotificationElement) _tempNotificationElement = document.createElement('div');\n \n var container = $('.notifications');\n if (container.length === 0) {\n $('body').append('<div class=\"notifications list-block media-list\"><ul></ul></div>');\n container = $('.notifications');\n }\n var list = container.children('ul');\n \n var itemHTML;\n if (params.custom) {\n itemHTML = '<li>' + params.custom + '</li>';\n }\n else {\n itemHTML = '<li class=\"notification-item notification-hidden\"><div class=\"item-content\">' +\n (params.media ?\n '<div class=\"item-media\">' +\n params.media +\n '</div>' : '') +\n '<div class=\"item-inner\">' +\n '<div class=\"item-title-row\">' +\n (params.title ? '<div class=\"item-title\">' + params.title + '</div>' : '') +\n (params.closeIcon ? '<div class=\"item-after\"><a href=\"#\" class=\"close-notification\"><span></span></a></div>' : '') +\n '</div>' +\n (params.subtitle ? '<div class=\"item-subtitle\">' + params.subtitle + '</div>' : '') +\n (params.message ? '<div class=\"item-text\">' + params.message + '</div>' : '') +\n '</div>' +\n '</div></li>';\n }\n _tempNotificationElement.innerHTML = itemHTML;\n \n var item = $(_tempNotificationElement).children();\n \n item.on('click', function (e) {\n var close = false;\n if ($(e.target).is('.close-notification') || $(e.target).parents('.close-notification').length > 0) {\n close = true;\n }\n else {\n if (params.onClick) params.onClick(e, item[0]);\n if (params.closeOnClick) close = true;\n }\n if (close) app.closeNotification(item[0]);\n });\n if (params.onClose) {\n item.data('f7NotificationOnClose', function () {\n params.onClose(item[0]);\n });\n }\n if (params.additionalClass) {\n item.addClass(params.additionalClass);\n }\n if (params.hold) {\n setTimeout(function () {\n if (item.length > 0) app.closeNotification(item[0]);\n }, params.hold);\n }\n \n list.prepend(item[0]);\n container.show();\n \n var itemHeight = item.outerHeight();\n item.css('marginTop', -itemHeight + 'px');\n item.transition(0);\n \n var clientLeft = item[0].clientLeft;\n item.transition('');\n item.css('marginTop', '0px');\n \n container.transform('translate3d(0, 0,0)');\n item.removeClass('notification-hidden');\n \n return item[0];\n };\n app.closeNotification = function (item) {\n item = $(item);\n if (item.length === 0) return;\n if (item.hasClass('notification-item-removing')) return;\n var container = $('.notifications');\n \n var itemHeight = item.outerHeight();\n item.css('height', itemHeight + 'px').transition(0);\n var clientLeft = item[0].clientLeft;\n \n item.css('height', '0px').transition('').addClass('notification-item-removing');\n if (item.data('f7NotificationOnClose')) item.data('f7NotificationOnClose')();\n \n if (container.find('.notification-item:not(.notification-item-removing)').length === 0) {\n container.transform('');\n }\n \n item.addClass('notification-hidden').transitionEnd(function () {\n item.remove();\n if (container.find('.notification-item').length === 0) {\n container.hide();\n }\n });\n };\n"," /*===========================\n Compile Template7 Templates On App Init\n ===========================*/\n app.initTemplate7Templates = function () {\n if (!window.Template7) return;\n Template7.templates = Template7.templates || app.params.templates || {};\n Template7.data = Template7.data || app.params.template7Data || {};\n Template7.cache = Template7.cache || {};\n \n app.templates = Template7.templates;\n app.template7Data = Template7.data;\n app.template7Cache = Template7.cache;\n \n // Precompile templates on app init\n if (!app.params.precompileTemplates) return;\n $('script[type=\"text/template7\"]').each(function () {\n var id = $(this).attr('id');\n if (!id) return;\n Template7.templates[id] = Template7.compile($(this).html());\n });\n };\n \n"," /*=======================================\n ************ Plugins API ************\n =======================================*/\n var _plugins = [];\n app.initPlugins = function () {\n // Initialize plugins\n for (var plugin in app.plugins) {\n var p = app.plugins[plugin](app, app.params[plugin]);\n if (p) _plugins.push(p);\n }\n };\n // Plugin Hooks\n app.pluginHook = function (hook) {\n for (var i = 0; i < _plugins.length; i++) {\n if (_plugins[i].hooks && hook in _plugins[i].hooks) {\n _plugins[i].hooks[hook](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n }\n }\n };\n // Prevented by plugin\n app.pluginPrevent = function (action) {\n var prevent = false;\n for (var i = 0; i < _plugins.length; i++) {\n if (_plugins[i].prevents && action in _plugins[i].prevents) {\n if (_plugins[i].prevents[action](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5])) prevent = true;\n }\n }\n return prevent;\n };\n // Preprocess content by plugin\n app.pluginProcess = function (action, data) {\n var processed = data;\n for (var i = 0; i < _plugins.length; i++) {\n if (_plugins[i].preprocess && process in _plugins[i].preprocess) {\n processed = _plugins[i].preprocess[process](data, arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);\n }\n }\n return processed;\n };\n \n \n"," /*======================================================\n ************ App Init ************\n ======================================================*/\n app.init = function () {\n // Compile Template7 templates on app load\n if (app.initTemplate7Templates) app.initTemplate7Templates();\n \n // Init Plugins\n if (app.initPlugins) app.initPlugins();\n \n // Init Device\n if (app.getDeviceInfo) app.getDeviceInfo();\n \n // Init Click events\n if (app.initFastClicks && app.params.fastClicks) app.initFastClicks();\n if (app.initClickEvents) app.initClickEvents();\n \n // Init each page callbacks\n $('.page:not(.cached)').each(function () {\n var pageContainer = $(this);\n var viewContainer = pageContainer.parents('.' + app.params.viewClass);\n if (viewContainer.length === 0) return;\n var view = viewContainer[0].f7View || false;\n var url = view && view.url ? view.url : false;\n if (viewContainer) {\n viewContainer.attr('data-page', pageContainer.attr('data-page') || undefined);\n }\n app.pageInitCallback(view, {pageContainer: this, url: url, position: 'center'});\n });\n \n // Init resize events\n if (app.initResize) app.initResize();\n \n // Init push state\n if (app.initPushState && app.params.pushState) app.initPushState();\n \n // Init Live Swipeouts events\n if (app.initSwipeout && app.params.swipeout) app.initSwipeout();\n \n // Init Live Sortable events\n if (app.initSortable && app.params.sortable) app.initSortable();\n \n // Init Live Swipe Panels\n if (app.initSwipePanels && (app.params.swipePanel || app.params.swipePanelOnlyClose)) app.initSwipePanels();\n \n // App Init callback\n if (app.params.onAppInit) app.params.onAppInit();\n \n // Plugin app init hook\n app.pluginHook('appInit');\n };\n if (app.params.init) app.init();\n \n"," //Return instance \n return app;\n };\n \n"," /*===========================\n Dom7 Library\n ===========================*/\n var Dom7 = (function () {\n var Dom7 = function (arr) {\n var _this = this, i = 0;\n // Create array-like object\n for (i = 0; i < arr.length; i++) {\n _this[i] = arr[i];\n }\n _this.length = arr.length;\n // Return collection with methods\n return this;\n };\n var $ = function (selector, context) {\n var arr = [], i = 0;\n if (selector && !context) {\n if (selector instanceof Dom7) {\n return selector;\n }\n }\n if (selector) {\n // String\n if (typeof selector === 'string') {\n var els, tempParent, html = selector.trim();\n if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n var toCreate = 'div';\n if (html.indexOf('<li') === 0) toCreate = 'ul';\n if (html.indexOf('<tr') === 0) toCreate = 'tbody';\n if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';\n if (html.indexOf('<tbody') === 0) toCreate = 'table';\n if (html.indexOf('<option') === 0) toCreate = 'select';\n tempParent = document.createElement(toCreate);\n tempParent.innerHTML = selector;\n for (i = 0; i < tempParent.childNodes.length; i++) {\n arr.push(tempParent.childNodes[i]);\n }\n }\n else {\n if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {\n // Pure ID selector\n els = [document.getElementById(selector.split('#')[1])];\n }\n else {\n // Other selectors\n els = (context || document).querySelectorAll(selector);\n }\n for (i = 0; i < els.length; i++) {\n if (els[i]) arr.push(els[i]);\n }\n }\n }\n // Node/element\n else if (selector.nodeType || selector === window || selector === document) {\n arr.push(selector);\n }\n //Array of elements or instance of Dom\n else if (selector.length > 0 && selector[0].nodeType) {\n for (i = 0; i < selector.length; i++) {\n arr.push(selector[i]);\n }\n }\n }\n return new Dom7(arr);\n };\n"," Dom7.prototype = {\n // Classes and attriutes\n addClass: function (className) {\n if (typeof className === 'undefined') {\n return this;\n }\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i++) {\n for (var j = 0; j < this.length; j++) {\n this[j].classList.add(classes[i]);\n }\n }\n return this;\n },\n removeClass: function (className) {\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i++) {\n for (var j = 0; j < this.length; j++) {\n this[j].classList.remove(classes[i]);\n }\n }\n return this;\n },\n hasClass: function (className) {\n if (!this[0]) return false;\n else return this[0].classList.contains(className);\n },\n toggleClass: function (className) {\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i++) {\n for (var j = 0; j < this.length; j++) {\n this[j].classList.toggle(classes[i]);\n }\n }\n return this;\n },\n attr: function (attrs, value) {\n if (arguments.length === 1 && typeof attrs === 'string') {\n // Get attr\n if (this[0]) return this[0].getAttribute(attrs);\n else return undefined;\n }\n else {\n // Set attrs\n for (var i = 0; i < this.length; i++) {\n if (arguments.length === 2) {\n // String\n this[i].setAttribute(attrs, value);\n }\n else {\n // Object\n for (var attrName in attrs) {\n this[i][attrName] = attrs[attrName];\n this[i].setAttribute(attrName, attrs[attrName]);\n }\n }\n }\n return this;\n }\n },\n removeAttr: function (attr) {\n for (var i = 0; i < this.length; i++) {\n this[i].removeAttribute(attr);\n }\n },\n prop: function (props, value) {\n if (arguments.length === 1 && typeof props === 'string') {\n // Get prop\n if (this[0]) return this[0][props];\n else return undefined;\n }\n else {\n // Set props\n for (var i = 0; i < this.length; i++) {\n if (arguments.length === 2) {\n // String\n this[i][props] = value;\n }\n else {\n // Object\n for (var propName in props) {\n this[i][propName] = props[propName];\n }\n }\n }\n return this;\n }\n },\n data: function (key, value) {\n if (typeof value === 'undefined') {\n // Get value\n if (this[0]) {\n var dataKey = this[0].getAttribute('data-' + key);\n if (dataKey) return dataKey;\n else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];\n else return undefined;\n }\n else return undefined;\n }\n else {\n // Set value\n for (var i = 0; i < this.length; i++) {\n var el = this[i];\n if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};\n el.dom7ElementDataStorage[key] = value;\n }\n return this;\n }\n },\n val: function (value) {\n if (typeof value === 'undefined') {\n if (this[0]) return this[0].value;\n else return undefined;\n }\n else {\n for (var i = 0; i < this.length; i++) {\n this[i].value = value;\n }\n return this;\n }\n },\n // Transforms\n transform : function (transform) {\n for (var i = 0; i < this.length; i++) {\n var elStyle = this[i].style;\n elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n }\n return this;\n },\n transition: function (duration) {\n if (typeof duration !== 'string') {\n duration = duration + 'ms';\n }\n for (var i = 0; i < this.length; i++) {\n var elStyle = this[i].style;\n elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n }\n return this;\n },\n //Events\n on: function (eventName, targetSelector, listener, capture) {\n function handleLiveEvent(e) {\n var target = e.target;\n if ($(target).is(targetSelector)) listener.call(target, e);\n else {\n var parents = $(target).parents();\n for (var k = 0; k < parents.length; k++) {\n if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);\n }\n }\n }\n var events = eventName.split(' ');\n var i, j;\n for (i = 0; i < this.length; i++) {\n if (typeof targetSelector === 'function' || targetSelector === false) {\n // Usual events\n if (typeof targetSelector === 'function') {\n listener = arguments[1];\n capture = arguments[2] || false;\n }\n for (j = 0; j < events.length; j++) {\n this[i].addEventListener(events[j], listener, capture);\n }\n }\n else {\n //Live events\n for (j = 0; j < events.length; j++) {\n if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];\n this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});\n this[i].addEventListener(events[j], handleLiveEvent, capture);\n }\n }\n }\n \n return this;\n },\n off: function (eventName, targetSelector, listener, capture) {\n var events = eventName.split(' ');\n for (var i = 0; i < events.length; i++) {\n for (var j = 0; j < this.length; j++) {\n if (typeof targetSelector === 'function' || targetSelector === false) {\n // Usual events\n if (typeof targetSelector === 'function') {\n listener = arguments[1];\n capture = arguments[2] || false;\n }\n this[j].removeEventListener(events[i], listener, capture);\n }\n else {\n // Live event\n if (this[j].dom7LiveListeners) {\n for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {\n if (this[j].dom7LiveListeners[k].listener === listener) {\n this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);\n }\n }\n }\n }\n }\n }\n return this;\n },\n once: function (eventName, targetSelector, listener, capture) {\n var dom = this;\n if (typeof targetSelector === 'function') {\n targetSelector = false;\n listener = arguments[1];\n capture = arguments[2];\n }\n function proxy(e) {\n listener(e);\n dom.off(eventName, targetSelector, proxy, capture);\n }\n dom.on(eventName, targetSelector, proxy, capture);\n },\n trigger: function (eventName, eventData) {\n for (var i = 0; i < this.length; i++) {\n var evt;\n try {\n evt = new CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});\n }\n catch (e) {\n evt = document.createEvent('Event');\n evt.initEvent(eventName, true, true);\n evt.detail = eventData;\n }\n this[i].dispatchEvent(evt);\n }\n return this;\n },\n transitionEnd: function (callback) {\n var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n i, j, dom = this;\n function fireCallBack(e) {\n /*jshint validthis:true */\n if (e.target !== this) return;\n callback.call(this, e);\n for (i = 0; i < events.length; i++) {\n dom.off(events[i], fireCallBack);\n }\n }\n if (callback) {\n for (i = 0; i < events.length; i++) {\n dom.on(events[i], fireCallBack);\n }\n }\n return this;\n },\n animationEnd: function (callback) {\n var events = ['webkitAnimationEnd', 'OAnimationEnd', 'MSAnimationEnd', 'animationend'],\n i, j, dom = this;\n function fireCallBack(e) {\n callback(e);\n for (i = 0; i < events.length; i++) {\n dom.off(events[i], fireCallBack);\n }\n }\n if (callback) {\n for (i = 0; i < events.length; i++) {\n dom.on(events[i], fireCallBack);\n }\n }\n return this;\n },\n // Sizing/Styles\n width: function () {\n if (this[0] === window) {\n return window.innerWidth;\n }\n else {\n if (this.length > 0) {\n return parseFloat(this.css('width'));\n }\n else {\n return null;\n }\n }\n },\n outerWidth: function (includeMargins) {\n if (this.length > 0) {\n if (includeMargins)\n return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));\n else\n return this[0].offsetWidth;\n }\n else return null;\n },\n height: function () {\n if (this[0] === window) {\n return window.innerHeight;\n }\n else {\n if (this.length > 0) {\n return parseFloat(this.css('height'));\n }\n else {\n return null;\n }\n }\n },\n outerHeight: function (includeMargins) {\n if (this.length > 0) {\n if (includeMargins)\n return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));\n else\n return this[0].offsetHeight;\n }\n else return null;\n },\n offset: function () {\n if (this.length > 0) {\n var el = this[0];\n var box = el.getBoundingClientRect();\n var body = document.body;\n var clientTop = el.clientTop || body.clientTop || 0;\n var clientLeft = el.clientLeft || body.clientLeft || 0;\n var scrollTop = window.pageYOffset || el.scrollTop;\n var scrollLeft = window.pageXOffset || el.scrollLeft;\n return {\n top: box.top + scrollTop - clientTop,\n left: box.left + scrollLeft - clientLeft\n };\n }\n else {\n return null;\n }\n },\n hide: function () {\n for (var i = 0; i < this.length; i++) {\n this[i].style.display = 'none';\n }\n return this;\n },\n show: function () {\n for (var i = 0; i < this.length; i++) {\n this[i].style.display = 'block';\n }\n return this;\n },\n css: function (props, value) {\n var i;\n if (arguments.length === 1) {\n if (typeof props === 'string') {\n if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);\n }\n else {\n for (i = 0; i < this.length; i++) {\n for (var prop in props) {\n this[i].style[prop] = props[prop];\n }\n }\n return this;\n }\n }\n if (arguments.length === 2 && typeof props === 'string') {\n for (i = 0; i < this.length; i++) {\n this[i].style[props] = value;\n }\n return this;\n }\n return this;\n },\n \n //Dom manipulation\n each: function (callback) {\n for (var i = 0; i < this.length; i++) {\n callback.call(this[i], i, this[i]);\n }\n return this;\n },\n html: function (html) {\n if (typeof html === 'undefined') {\n return this[0] ? this[0].innerHTML : undefined;\n }\n else {\n for (var i = 0; i < this.length; i++) {\n this[i].innerHTML = html;\n }\n return this;\n }\n },\n text: function (text) {\n if (typeof text === 'undefined') {\n if (this[0]) {\n return this[0].textContent.trim();\n }\n else return null;\n }\n else {\n for (var i = 0; i < this.length; i++) {\n this[i].textContent = text;\n }\n }\n },\n is: function (selector) {\n if (!this[0]) return false;\n var compareWith, i;\n if (typeof selector === 'string') {\n var el = this[0];\n if (el === document) return selector === document;\n if (el === window) return selector === window;\n \n if (el.matches) return el.matches(selector);\n else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);\n else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);\n else if (el.msMatchesSelector) return el.msMatchesSelector(selector);\n else {\n compareWith = $(selector);\n for (i = 0; i < compareWith.length; i++) {\n if (compareWith[i] === this[0]) return true;\n }\n return false;\n }\n }\n else if (selector === document) return this[0] === document;\n else if (selector === window) return this[0] === window;\n else {\n if (selector.nodeType || selector instanceof Dom7) {\n compareWith = selector.nodeType ? [selector] : selector;\n for (i = 0; i < compareWith.length; i++) {\n if (compareWith[i] === this[0]) return true;\n }\n return false;\n }\n return false;\n }\n \n },\n indexOf: function (el) {\n for (var i = 0; i < this.length; i++) {\n if (this[i] === el) return i;\n }\n },\n index: function () {\n if (this[0]) {\n var child = this[0];\n var i = 0;\n while ((child = child.previousSibling) !== null) {\n if (child.nodeType === 1) i++;\n }\n return i;\n }\n else return undefined;\n },\n eq: function (index) {\n if (typeof index === 'undefined') return this;\n var length = this.length;\n var returnIndex;\n if (index > length - 1) {\n return new Dom7([]);\n }\n if (index < 0) {\n returnIndex = length + index;\n if (returnIndex < 0) return new Dom7([]);\n else return new Dom7([this[returnIndex]]);\n }\n return new Dom7([this[index]]);\n },\n append: function (newChild) {\n var i, j;\n for (i = 0; i < this.length; i++) {\n if (typeof newChild === 'string') {\n var tempDiv = document.createElement('div');\n tempDiv.innerHTML = newChild;\n while (tempDiv.firstChild) {\n this[i].appendChild(tempDiv.firstChild);\n }\n }\n else if (newChild instanceof Dom7) {\n for (j = 0; j < newChild.length; j++) {\n this[i].appendChild(newChild[j]);\n }\n }\n else {\n this[i].appendChild(newChild);\n }\n }\n return this;\n },\n prepend: function (newChild) {\n var i, j;\n for (i = 0; i < this.length; i++) {\n if (typeof newChild === 'string') {\n var tempDiv = document.createElement('div');\n tempDiv.innerHTML = newChild;\n for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {\n this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n }\n // this[i].insertAdjacentHTML('afterbegin', newChild);\n }\n else if (newChild instanceof Dom7) {\n for (j = 0; j < newChild.length; j++) {\n this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n }\n }\n else {\n this[i].insertBefore(newChild, this[i].childNodes[0]);\n }\n }\n return this;\n },\n insertBefore: function (selector) {\n var before = $(selector);\n for (var i = 0; i < this.length; i++) {\n if (before.length === 1) {\n before[0].parentNode.insertBefore(this[i], before[0]);\n }\n else if (before.length > 1) {\n for (var j = 0; j < before.length; j++) {\n before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);\n }\n }\n }\n },\n insertAfter: function (selector) {\n var after = $(selector);\n for (var i = 0; i < this.length; i++) {\n if (after.length === 1) {\n after[0].parentNode.insertBefore(this[i], after[0].nextSibling);\n }\n else if (after.length > 1) {\n for (var j = 0; j < after.length; j++) {\n after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);\n }\n }\n }\n },\n next: function (selector) {\n if (this.length > 0) {\n if (selector) {\n if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);\n else return new Dom7([]);\n }\n else {\n if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);\n else return new Dom7([]);\n }\n }\n else return new Dom7([]);\n },\n nextAll: function (selector) {\n var nextEls = [];\n var el = this[0];\n if (!el) return new Dom7([]);\n while (el.nextElementSibling) {\n var next = el.nextElementSibling;\n if (selector) {\n if($(next).is(selector)) nextEls.push(next);\n }\n else nextEls.push(next);\n el = next;\n }\n return new Dom7(nextEls);\n },\n prev: function (selector) {\n if (this.length > 0) {\n if (selector) {\n if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);\n else return new Dom7([]);\n }\n else {\n if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);\n else return new Dom7([]);\n }\n }\n else return new Dom7([]);\n },\n prevAll: function (selector) {\n var prevEls = [];\n var el = this[0];\n if (!el) return new Dom7([]);\n while (el.previousElementSibling) {\n var prev = el.previousElementSibling;\n if (selector) {\n if($(prev).is(selector)) prevEls.push(prev);\n }\n else prevEls.push(prev);\n el = prev;\n }\n return new Dom7(prevEls);\n },\n parent: function (selector) {\n var parents = [];\n for (var i = 0; i < this.length; i++) {\n if (selector) {\n if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);\n }\n else {\n parents.push(this[i].parentNode);\n }\n }\n return $($.unique(parents));\n },\n parents: function (selector) {\n var parents = [];\n for (var i = 0; i < this.length; i++) {\n var parent = this[i].parentNode;\n while (parent) {\n if (selector) {\n if ($(parent).is(selector)) parents.push(parent);\n }\n else {\n parents.push(parent);\n }\n parent = parent.parentNode;\n }\n }\n return $($.unique(parents));\n },\n find : function (selector) {\n var foundElements = [];\n for (var i = 0; i < this.length; i++) {\n var found = this[i].querySelectorAll(selector);\n for (var j = 0; j < found.length; j++) {\n foundElements.push(found[j]);\n }\n }\n return new Dom7(foundElements);\n },\n children: function (selector) {\n var children = [];\n for (var i = 0; i < this.length; i++) {\n var childNodes = this[i].childNodes;\n \n for (var j = 0; j < childNodes.length; j++) {\n if (!selector) {\n if (childNodes[j].nodeType === 1) children.push(childNodes[j]);\n }\n else {\n if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);\n }\n }\n }\n return new Dom7($.unique(children));\n },\n remove: function () {\n for (var i = 0; i < this.length; i++) {\n if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);\n }\n return this;\n },\n detach: function () {\n return this.remove();\n },\n add: function () {\n var dom = this;\n var i, j;\n for (i = 0; i < arguments.length; i++) {\n var toAdd = $(arguments[i]);\n for (j = 0; j < toAdd.length; j++) {\n dom[dom.length] = toAdd[j];\n dom.length++;\n }\n }\n return dom;\n }\n };\n \n // Shortcuts\n (function () {\n var shortcuts = ('click blur focus focusin focusout keyup keydown keypress submit change mousedown mousemove mouseup mouseenter mouseleave mouseout mouseover touchstart touchend touchmove resize scroll').split(' ');\n var notTrigger = ('resize scroll').split(' ');\n function createMethod(name) {\n Dom7.prototype[name] = function (handler) {\n var i;\n if (typeof handler === 'undefined') {\n for (i = 0; i < this.length; i++) {\n if (notTrigger.indexOf(name) < 0) {\n if (name in this[i]) this[i][name]();\n else {\n $(this[i]).trigger(name);\n }\n }\n }\n return this;\n }\n else {\n return this.on(name, handler);\n }\n };\n }\n for (var i = 0; i < shortcuts.length; i++) {\n createMethod(shortcuts[i]);\n }\n })();\n \n"," // Global Ajax Setup\n var globalAjaxOptions = {};\n $.ajaxSetup = function (options) {\n if (options.type) options.method = options.type;\n for (var option in options) {\n globalAjaxOptions[option] = options[option];\n }\n };\n \n // Ajax\n var _jsonpRequests = 0;\n $.ajax = function (options) {\n var defaults = {\n method: 'GET',\n data: false,\n async: true,\n cache: true,\n user: '',\n password: '',\n headers: {},\n xhrFields: {},\n statusCode: {},\n processData: true,\n dataType: 'text',\n contentType: 'application/x-www-form-urlencoded',\n timeout: 0\n };\n var callbacks = ['beforeSend', 'error', 'complete', 'success', 'statusCode'];\n \n //For jQuery guys\n if (options.type) options.method = options.type;\n \n // Merge global and defaults\n for (var globalOption in globalAjaxOptions) {\n if (callbacks.indexOf(globalOption) < 0) defaults[globalOption] = globalAjaxOptions[globalOption];\n }\n // Function to run XHR callbacks and events\n function fireAjaxCallback (eventName, eventData, callbackName) {\n var a = arguments;\n if (eventName) $(document).trigger(eventName, eventData);\n if (callbackName) {\n // Global callback\n if (callbackName in globalAjaxOptions) globalAjaxOptions[callbackName](a[3], a[4], a[5], a[6]);\n // Options callback\n if (options[callbackName]) options[callbackName](a[3], a[4], a[5], a[6]);\n }\n }\n \n // Merge options and defaults\n for (var prop in defaults) {\n if (!(prop in options)) options[prop] = defaults[prop];\n }\n \n // Default URL\n if (!options.url) {\n options.url = window.location.toString();\n }\n // UC method\n var _method = options.method.toUpperCase();\n // Data to modify GET URL\n if ((_method === 'GET' || _method === 'HEAD') && options.data) {\n var stringData;\n if (typeof options.data === 'string') {\n // Should be key=value string\n if (options.data.indexOf('?') >= 0) stringData = options.data.split('?')[1];\n else stringData = options.data;\n }\n else {\n // Should be key=value object\n stringData = $.serializeObject(options.data);\n }\n if (options.url.indexOf('?') >= 0) options.url += '&' + stringData;\n else options.url += '?' + stringData;\n }\n // JSONP\n if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {\n \n var callbackName = 'f7jsonp_' + Date.now() + (_jsonpRequests++);\n var requestUrl, abortTimeout;\n var callbackSplit = options.url.split('callback=');\n if (callbackSplit[1].indexOf('&') >= 0) {\n var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');\n requestUrl = callbackSplit[0] + 'callback=' + callbackName + (addVars.length > 0 ? '&' + addVars : '');\n }\n else {\n requestUrl = callbackSplit[0] + 'callback=' + callbackName;\n }\n \n // Create script\n var script = document.createElement('script');\n script.type = 'text/javascript';\n script.onerror = function() {\n clearTimeout(abortTimeout);\n fireAjaxCallback(undefined, undefined, 'error', null, 'scripterror');\n };\n script.src = requestUrl;\n \n // Handler\n window[callbackName] = function (data) {\n clearTimeout(abortTimeout);\n fireAjaxCallback(undefined, undefined, 'success', data);\n script.parentNode.removeChild(script);\n script = null;\n delete window[callbackName];\n };\n document.querySelector('head').appendChild(script);\n \n if (options.timeout > 0) {\n abortTimeout = setTimeout(function () {\n script.parentNode.removeChild(script);\n script = null;\n fireAjaxCallback(undefined, undefined, 'error', null, 'timeout');\n }, options.timeout);\n }\n \n return;\n }\n \n // Cache for GET/HEAD requests\n if (_method === 'GET' || _method === 'HEAD') {\n if (options.cache === false) options.url += ('_nocache=' + Date.now());\n }\n \n // Create XHR\n var xhr = new XMLHttpRequest();\n \n // Save Request URL\n xhr.requestUrl = options.url;\n \n // Open XHR\n xhr.open(_method, options.url, options.async, options.user, options.password);\n \n // Create POST Data\n var postData = null;\n \n if ((_method === 'POST' || _method === 'PUT') && options.data) {\n if (options.processData) {\n var postDataInstances = [ArrayBuffer, Blob, Document, FormData];\n // Post Data\n if (postDataInstances.indexOf(options.data.constructor) >= 0) {\n postData = options.data;\n }\n else {\n // POST Headers\n var boundary = '---------------------------' + Date.now().toString(16);\n \n if (options.contentType === 'multipart\\/form-data') {\n xhr.setRequestHeader('Content-Type', 'multipart\\/form-data; boundary=' + boundary);\n }\n else {\n xhr.setRequestHeader('Content-Type', options.contentType);\n }\n postData = '';\n var _data = $.serializeObject(options.data);\n if (options.contentType === 'multipart\\/form-data') {\n boundary = '---------------------------' + Date.now().toString(16);\n _data = _data.split('&');\n var _newData = [];\n for (var i = 0; i < _data.length; i++) {\n _newData.push('Content-Disposition: form-data; name=\"' + _data[i].split('=')[0] + '\"\\r\\n\\r\\n' + _data[i].split('=')[1] + '\\r\\n');\n }\n postData = '--' + boundary + '\\r\\n' + _newData.join('--' + boundary + '\\r\\n') + '--' + boundary + '--\\r\\n';\n }\n else {\n postData = options.contentType === 'application/x-www-form-urlencoded' ? _data : _data.replace(/&/g, '\\r\\n');\n }\n }\n }\n else {\n postData = options.data;\n }\n \n }\n \n // Additional headers\n if (options.headers) {\n for (var header in options.headers) {\n xhr.setRequestHeader(header, options.headers[header]);\n }\n }\n \n // Check for crossDomain\n if (typeof options.crossDomain === 'undefined') {\n options.crossDomain = /^([\\w-]+:)?\\/\\/([^\\/]+)/.test(options.url) && RegExp.$2 !== window.location.host;\n }\n \n if (!options.crossDomain) {\n xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n }\n \n if (options.xhrFields) {\n for (var field in options.xhrFields) {\n xhr[field] = options.xhrFields[field];\n }\n }\n \n var xhrTimeout;\n // Handle XHR\n xhr.onload = function (e) {\n if (xhrTimeout) clearTimeout(xhrTimeout);\n if (xhr.status === 200 || xhr.status === 0) {\n var isSuccess, responseData;\n if (options.dataType === 'json') {\n try {\n responseData = JSON.parse(xhr.responseText);\n fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', responseData, xhr.status, xhr);\n }\n catch (e) {\n fireAjaxCallback('ajaxError', {xhr: xhr, parseerror: true}, 'error', xhr, 'parseerror');\n }\n }\n else {\n fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', xhr.responseText, xhr.status, xhr);\n }\n }\n else {\n fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);\n }\n if (options.statusCode) {\n if (globalAjaxOptions.statusCode && globalAjaxOptions.statusCode[xhr.status]) globalAjaxOptions.statusCode[xhr.status](xhr);\n if (options.statusCode[xhr.status]) options.statusCode[xhr.status](xhr);\n }\n fireAjaxCallback('ajaxComplete', {xhr: xhr}, 'complete', xhr, xhr.status);\n };\n \n xhr.onerror = function (e) {\n if (xhrTimeout) clearTimeout(xhrTimeout);\n fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);\n };\n \n // Ajax start callback\n fireAjaxCallback('ajaxStart', {xhr: xhr}, 'start', xhr);\n fireAjaxCallback(undefined, undefined, 'beforeSend', xhr);\n \n \n // Send XHR\n xhr.send(postData);\n \n // Timeout\n if (options.timeout > 0) {\n xhrTimeout = setTimeout(function () {\n xhr.abort();\n fireAjaxCallback('ajaxError', {xhr: xhr, timeout: true}, 'error', xhr, 'timeout');\n fireAjaxCallback('complete', {xhr: xhr, timeout: true}, 'complete', xhr, 'timeout');\n }, options.timeout);\n }\n \n // Return XHR object\n return xhr;\n };\n // Shrotcuts\n (function () {\n var methods = ('get post getJSON').split(' ');\n function createMethod(method) {\n $[method] = function (url, data, success) {\n return $.ajax({\n url: url,\n method: method === 'post' ? 'POST' : 'GET',\n data: typeof data === 'function' ? undefined : data,\n success: typeof data === 'function' ? data : success,\n dataType: method === 'getJSON' ? 'json' : undefined\n });\n };\n }\n for (var i = 0; i < methods.length; i++) {\n createMethod(methods[i]);\n }\n })();\n"," // DOM Library Utilites\n $.parseUrlQuery = function (url) {\n var query = {}, i, params, param;\n if (url.indexOf('?') >= 0) url = url.split('?')[1];\n else return query;\n params = url.split('&');\n for (i = 0; i < params.length; i++) {\n param = params[i].split('=');\n query[param[0]] = param[1];\n }\n return query;\n };\n $.isArray = function (arr) {\n if (Object.prototype.toString.apply(arr) === '[object Array]') return true;\n else return false;\n };\n $.unique = function (arr) {\n var unique = [];\n for (var i = 0; i < arr.length; i++) {\n if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);\n }\n return unique;\n };\n $.trim = function (str) {\n return str.trim();\n };\n $.serializeObject = function (obj) {\n if (typeof obj === 'string') return obj;\n var resultArray = [];\n var separator = '&';\n for (var prop in obj) {\n if ($.isArray(obj[prop])) {\n var toPush = [];\n for (var i = 0; i < obj[prop].length; i ++) {\n toPush.push(prop + '=' + obj[prop][i]);\n }\n resultArray.push(toPush.join(separator));\n }\n else {\n // Should be string\n resultArray.push(prop + '=' + obj[prop]);\n }\n }\n \n return resultArray.join(separator);\n };\n \n $.getTranslate = function (el, axis) {\n var matrix, curTransform, curStyle, transformMatrix;\n \n // automatic axis detection\n if (typeof axis === 'undefined') {\n axis = 'x';\n }\n \n curStyle = window.getComputedStyle(el, null);\n if (window.WebKitCSSMatrix) {\n // Some old versions of Webkit choke when 'none' is passed; pass\n // empty string instead in this case\n transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);\n }\n else {\n transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n matrix = transformMatrix.toString().split(',');\n }\n \n if (axis === 'x') {\n //Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix)\n curTransform = transformMatrix.m41;\n //Crazy IE10 Matrix\n else if (matrix.length === 16)\n curTransform = parseFloat(matrix[12]);\n //Normal Browsers\n else\n curTransform = parseFloat(matrix[4]);\n }\n if (axis === 'y') {\n //Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix)\n curTransform = transformMatrix.m42;\n //Crazy IE10 Matrix\n else if (matrix.length === 16)\n curTransform = parseFloat(matrix[13]);\n //Normal Browsers\n else\n curTransform = parseFloat(matrix[5]);\n }\n \n return curTransform || 0;\n };\n \n $.requestAnimationFrame = function (callback) {\n if (window.requestAnimationFrame) return window.requestAnimationFrame(callback);\n else if (window.webkitRequestAnimationFrame) return window.webkitRequestAnimationFrame(callback);\n else if (window.mozRequestAnimationFrame) return window.mozRequestAnimationFrame(callback);\n else {\n return window.setTimeout(callback, 1000 / 60);\n }\n };\n $.cancelAnimationFrame = function (id) {\n if (window.cancelAnimationFrame) return window.cancelAnimationFrame(id);\n else if (window.webkitCancelAnimationFrame) return window.webkitCancelAnimationFrame(id);\n else if (window.mozCancelAnimationFrame) return window.mozCancelAnimationFrame(id);\n else {\n return window.clearTimeout(id);\n } \n };\n $.supportTouch = !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n \n // Link to prototype\n $.fn = Dom7.prototype;\n \n // Plugins\n $.fn.scrollTo = function (left, top, duration, easing) {\n return this.each(function () {\n var el = this;\n var currentTop, currentLeft, maxTop, maxLeft, newTop, newLeft, scrollTop, scrollLeft;\n var animateTop = top > 0 || top === 0;\n var animateLeft = left > 0 || left === 0;\n if (typeof easing === 'undefined') {\n easing = 'swing';\n }\n if (animateTop) {\n currentTop = el.scrollTop;\n if (!duration) {\n el.scrollTop = top;\n }\n }\n if (animateLeft) {\n currentLeft = el.scrollLeft;\n if (!duration) {\n el.scrollLeft = left;\n }\n }\n if (!duration) return;\n if (animateTop) {\n maxTop = el.scrollHeight - el.offsetHeight;\n newTop = Math.max(Math.min(top, maxTop), 0);\n }\n if (animateLeft) {\n maxLeft = el.scrollWidth - el.offsetWidth;\n newLeft = Math.max(Math.min(left, maxLeft), 0);\n }\n var startTime = null;\n if (animateTop && newTop === currentTop) animateTop = false;\n if (animateLeft && newLeft === currentLeft) animateLeft = false;\n function render(time) {\n if (time === undefined) {\n time = new Date().getTime();\n }\n if (startTime === null) {\n startTime = time;\n }\n var doneLeft, doneTop, done;\n var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);\n var easeProgress = easing === 'linear' ? progress : (0.5 - Math.cos( progress * Math.PI ) / 2);\n if (animateTop) scrollTop = currentTop + (easeProgress * (newTop - currentTop));\n if (animateLeft) scrollLeft = currentLeft + (easeProgress * (newLeft - currentLeft));\n if (animateTop && newTop > currentTop && scrollTop >= newTop) {\n el.scrollTop = newTop;\n done = true;\n }\n if (animateTop && newTop < currentTop && scrollTop <= newTop) {\n el.scrollTop = newTop;\n done = true;\n }\n \n if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {\n el.scrollLeft = newLeft;\n done = true;\n }\n if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {\n el.scrollLeft = newLeft;\n done = true;\n }\n \n if (done) return;\n if (animateTop) el.scrollTop = scrollTop;\n if (animateLeft) el.scrollLeft = scrollLeft;\n $.requestAnimationFrame(render);\n }\n $.requestAnimationFrame(render);\n });\n };\n $.fn.scrollTop = function (top, duration, easing) {\n var dom = this;\n if (typeof top === 'undefined') {\n if (dom.length > 0) return dom[0].scrollTop;\n else return null;\n }\n return dom.scrollTo(undefined, top, duration, easing);\n };\n $.fn.scrollLeft = function (left, duration, easing) {\n var dom = this;\n if (typeof left === 'undefined') {\n if (dom.length > 0) return dom[0].scrollLeft;\n else return null;\n }\n return dom.scrollTo(left, undefined, duration, easing);\n };\n"," return $;\n })();\n \n // Export Dom7 to Framework7\n Framework7.$ = Dom7;\n \n // Export to local scope\n var $ = Dom7;\n \n // Export to Window\n window.Dom7 = Dom7;\n \n"," /*===========================\n Features Support Detection\n ===========================*/\n Framework7.prototype.support = (function () {\n var support = {\n touch: !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch)\n };\n \n // Export object\n return support;\n })();\n \n"," /*===========================\n Device/OS Detection\n ===========================*/\n Framework7.prototype.device = (function () {\n var device = {};\n var ua = navigator.userAgent;\n var $ = Dom7;\n \n var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n \n device.ios = device.android = device.iphone = device.ipad = false;\n \n // Android\n if (android) {\n device.os = 'android';\n device.osVersion = android[2];\n device.android = true;\n }\n if (ipad || iphone || ipod) {\n device.os = 'ios';\n device.ios = true;\n }\n // iOS\n if (iphone && !ipod) {\n device.osVersion = iphone[2].replace(/_/g, '.');\n device.iphone = true;\n }\n if (ipad) {\n device.osVersion = ipad[2].replace(/_/g, '.');\n device.ipad = true;\n }\n if (ipod) {\n device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;\n device.iphone = true;\n }\n // iOS 8+ changed UA\n if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {\n if (device.osVersion.split('.')[0] === '10') {\n device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];\n }\n }\n \n // Webview\n device.webView = (iphone || ipad || ipod) && ua.match(/.*AppleWebKit(?!.*Safari)/i);\n \n // Minimal UI\n if (device.os && device.os === 'ios') {\n var osVersionArr = device.osVersion.split('.');\n device.minimalUi = !device.webView &&\n (ipod || iphone) &&\n (osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7) &&\n $('meta[name=\"viewport\"]').length > 0 && $('meta[name=\"viewport\"]').attr('content').indexOf('minimal-ui') >= 0;\n }\n \n // Check for status bar and fullscreen app mode\n var windowWidth = $(window).width();\n var windowHeight = $(window).height();\n device.statusBar = false;\n if (device.webView && (windowWidth * windowHeight === screen.width * screen.height)) {\n device.statusBar = true;\n }\n else {\n device.statusBar = false;\n }\n \n // Classes\n var classNames = [];\n \n // Pixel Ratio\n device.pixelRatio = window.devicePixelRatio || 1;\n classNames.push('pixel-ratio-' + Math.floor(device.pixelRatio));\n if (device.pixelRatio >= 2) {\n classNames.push('retina');\n }\n \n // OS classes\n if (device.os) {\n classNames.push(device.os, device.os + '-' + device.osVersion.split('.')[0], device.os + '-' + device.osVersion.replace(/\\./g, '-'));\n if (device.os === 'ios') {\n var major = parseInt(device.osVersion.split('.')[0], 10);\n for (var i = major - 1; i >= 6; i--) {\n classNames.push('ios-gt-' + i);\n }\n }\n \n }\n // Status bar classes\n if (device.statusBar) {\n classNames.push('with-statusbar-overlay');\n }\n else {\n $('html').removeClass('with-statusbar-overlay');\n }\n \n // Add html classes\n if (classNames.length > 0) $('html').addClass(classNames.join(' '));\n \n // Export object\n return device;\n })();\n \n"," /*===========================\n Plugins prototype\n ===========================*/\n Framework7.prototype.plugins = {};\n \n"," /*===========================\n Template7 Template engine\n ===========================*/\n window.Template7 = (function () {\n function isArray(arr) {\n return Object.prototype.toString.apply(arr) === '[object Array]';\n }\n function isObject(obj) {\n return obj instanceof Object;\n }\n function isFunction(func) {\n return typeof func === 'function';\n }\n var cache = {};\n function helperToSlices(string) {\n var helperParts = string.replace(/[{}#}]/g, '').split(' ');\n var slices = [];\n var shiftIndex, i, j;\n for (i = 0; i < helperParts.length; i++) {\n var part = helperParts[i];\n if (i === 0) slices.push(part);\n else {\n if (part.indexOf('\"') === 0) {\n // Plain String\n if (part.match(/\"/g).length === 2) {\n // One word string\n slices.push(part);\n }\n else {\n // Find closed Index\n shiftIndex = 0;\n for (j = i + 1; j < helperParts.length; j++) {\n part += ' ' + helperParts[j];\n if (helperParts[j].indexOf('\"') >= 0) {\n shiftIndex = j;\n slices.push(part);\n break;\n }\n }\n if (shiftIndex) i = shiftIndex;\n }\n }\n else {\n if (part.indexOf('=') > 0) {\n // Hash\n var hashParts = part.split('=');\n var hashName = hashParts[0];\n var hashContent = hashParts[1];\n if (hashContent.match(/\"/g).length !== 2) {\n shiftIndex = 0;\n for (j = i + 1; j < helperParts.length; j++) {\n hashContent += ' ' + helperParts[j];\n if (helperParts[j].indexOf('\"') >= 0) {\n shiftIndex = j;\n break;\n }\n }\n if (shiftIndex) i = shiftIndex;\n }\n var hash = [hashName, hashContent.replace(/\"/g,'')];\n slices.push(hash);\n }\n else {\n // Plain variable\n slices.push(part);\n }\n }\n }\n }\n return slices;\n }\n function stringToBlocks(string) {\n var blocks = [], i, j, k;\n if (!string) return [];\n var _blocks = string.split(/({{[^{^}]*}})/);\n for (i = 0; i < _blocks.length; i++) {\n var block = _blocks[i];\n if (block === '') continue;\n if (block.indexOf('{{') < 0) {\n blocks.push({\n type: 'plain',\n content: block\n });\n }\n else {\n if (block.indexOf('{/') >= 0) {\n continue;\n }\n if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) {\n // Simple variable\n blocks.push({\n type: 'variable',\n contextName: block.replace(/[{}]/g, '')\n });\n continue;\n }\n // Helpers\n var helperSlices = helperToSlices(block);\n var helperName = helperSlices[0];\n var helperContext = [];\n var helperHash = {};\n for (j = 1; j < helperSlices.length; j++) {\n var slice = helperSlices[j];\n if (isArray(slice)) {\n // Hash\n helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1];\n }\n else {\n helperContext.push(slice);\n }\n }\n \n if (block.indexOf('{#') >= 0) {\n // Condition/Helper\n var helperStartIndex = i;\n var helperContent = '';\n var elseContent = '';\n var toSkip = 0;\n var shiftIndex;\n var foundClosed = false, foundElse = false, foundClosedElse = false, depth = 0;\n for (j = i + 1; j < _blocks.length; j++) {\n if (_blocks[j].indexOf('{{#') >= 0) {\n depth ++;\n }\n if (_blocks[j].indexOf('{{/') >= 0) {\n depth --;\n }\n if (_blocks[j].indexOf('{{#' + helperName) >= 0) {\n helperContent += _blocks[j];\n if (foundElse) elseContent += _blocks[j];\n toSkip ++;\n }\n else if (_blocks[j].indexOf('{{/' + helperName) >= 0) {\n if (toSkip > 0) {\n toSkip--;\n helperContent += _blocks[j];\n if (foundElse) elseContent += _blocks[j];\n }\n else {\n shiftIndex = j;\n foundClosed = true;\n break;\n }\n }\n else if (_blocks[j].indexOf('else') >= 0 && depth === 0) {\n foundElse = true;\n }\n else {\n if (!foundElse) helperContent += _blocks[j];\n if (foundElse) elseContent += _blocks[j];\n }\n \n }\n if (foundClosed) {\n if (shiftIndex) i = shiftIndex;\n blocks.push({\n type: 'helper',\n helperName: helperName,\n contextName: helperContext,\n content: helperContent,\n inverseContent: elseContent,\n hash: helperHash\n });\n }\n }\n else if (block.indexOf(' ') > 0) {\n blocks.push({\n type: 'helper',\n helperName: helperName,\n contextName: helperContext,\n hash: helperHash\n });\n }\n }\n }\n return blocks;\n }\n var Template7 = function (template) {\n var t = this;\n t.template = template;\n \n function getCompileFn(block, depth) {\n if (block.content) return compile(block.content, depth);\n else return function () {return ''; };\n }\n function getCompileInverse(block, depth) {\n if (block.inverseContent) return compile(block.inverseContent, depth);\n else return function () {return ''; };\n }\n function getCompileVar(name, ctx) {\n var parents, variable, context;\n if (name.indexOf('@global') >= 0) {\n variable = '(Template7.global && Template7.global.' + (name.split('@global.')[1]) + ')';\n }\n else if (name.indexOf('@') >= 0) {\n variable = '(data && data.' + name.replace('@', '') + ')';\n }\n else {\n if (name.indexOf('.') > 0) {\n if (name.indexOf('this') === 0) variable = name.replace('this', ctx);\n else variable = ctx + '.' + name;\n }\n else if (name.indexOf('../') === 0) {\n var levelUp = name.split('../').length - 1;\n var newName = name.split('../')[name.split('../').length - 1];\n var newDepth = ctx.split('_')[1] - levelUp;\n variable = 'ctx_' + (newDepth >= 1 ? newDepth : 1) + '.' + newName;\n }\n else {\n variable = name === 'this' ? ctx : ctx + '.' + name;\n }\n }\n return variable;\n }\n function getCompiledArguments(contextArray, ctx) {\n var arr = [];\n for (var i = 0; i < contextArray.length; i++) {\n if (contextArray[i].indexOf('\"') === 0) arr.push(contextArray[i]);\n else {\n arr.push(getCompileVar(contextArray[i], ctx));\n }\n }\n return arr.join(', ');\n }\n function compile(template, depth) {\n depth = depth || 1;\n template = template || t.template;\n if (typeof template !== 'string') {\n throw new Error('Template7: Template must be a string');\n }\n var blocks = stringToBlocks(template);\n \n if (blocks.length === 0) {\n return function () { return ''; };\n }\n var ctx = 'ctx_' + depth;\n var resultString = '(function (' + ctx + ', data) {\\n';\n if (depth === 1) {\n resultString += 'function isArray(arr){return Object.prototype.toString.apply(arr) === \\'[object Array]\\';}\\n';\n resultString += 'function isFunction(func){return (typeof func === \\'function\\');}\\n';\n resultString += 'function c(val, ctx) {if (typeof val !== \"undefined\") {if (isFunction(val)) {return val.call(ctx);} else return val;} else return \"\";}\\n';\n }\n resultString += 'var r = \\'\\';\\n';\n var i, j, context;\n for (i = 0; i < blocks.length; i++) {\n var block = blocks[i];\n // Plain block\n if (block.type === 'plain') {\n resultString += 'r +=\\'' + (block.content).replace(/\\r/g, '\\\\r').replace(/\\n/g, '\\\\n').replace(/'/g, '\\\\' + '\\'') + '\\';';\n continue;\n }\n var variable, compiledArguments;\n // Variable block\n if (block.type === 'variable') {\n variable = getCompileVar(block.contextName, ctx);\n resultString += 'r += c(' + variable + ', ' + ctx + ');';\n }\n // Helpers block\n if (block.type === 'helper') {\n if (block.helperName in t.helpers) {\n compiledArguments = getCompiledArguments(block.contextName, ctx);\n resultString += 'r += (Template7.helpers.' + block.helperName + ').call(' + ctx + ', ' + (compiledArguments && (compiledArguments + ',')) +'{hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';\n }\n else {\n if (block.contextName.length > 0) {\n throw new Error('Template7: Missing helper: \"' + block.helperName + '\"');\n }\n else {\n variable = getCompileVar(block.helperName, ctx);\n resultString += 'if (' + variable + ') {';\n resultString += 'if (isArray(' + variable + ')) {';\n resultString += 'r += (Template7.helpers.each).call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';\n resultString += '}else {';\n resultString += 'r += (Template7.helpers.with).call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';\n resultString += '}}';\n }\n }\n }\n }\n resultString += '\\nreturn r;})';\n return eval.call(window, resultString);\n }\n t.compile = function (template) {\n if (!t.compiled) {\n t.compiled = compile(template);\n }\n return t.compiled;\n };\n };\n Template7.prototype = {\n options: {},\n helpers: {\n 'if': function (context, options) {\n if (isFunction(context)) { context = context.call(this); }\n if (context) {\n return options.fn(this, options.data);\n }\n else {\n return options.inverse(this, options.data);\n }\n },\n 'unless': function (context, options) {\n if (isFunction(context)) { context = context.call(this); }\n if (!context) {\n return options.fn(this, options.data);\n }\n else {\n return options.inverse(this, options.data);\n }\n },\n 'each': function (context, options) {\n var ret = '', i = 0;\n if (isFunction(context)) { context = context.call(this); }\n if (isArray(context)) {\n if (options.hash.reverse) {\n context = context.reverse();\n }\n for (i = 0; i < context.length; i++) {\n ret += options.fn(context[i], {first: i === 0, last: i === context.length - 1, index: i});\n }\n if (options.hash.reverse) {\n context = context.reverse();\n }\n }\n else {\n for (var key in context) {\n i++;\n ret += options.fn(context[key], {key: key});\n }\n }\n if (i > 0) return ret;\n else return options.inverse(this);\n },\n 'with': function (context, options) {\n if (isFunction(context)) { context = context.call(this); }\n return options.fn(context);\n },\n 'join': function (context, options) {\n if (isFunction(context)) { context = context.call(this); }\n return context.join(options.hash.delimiter || options.hash.delimeter);\n }\n }\n };\n var t7 = function (template, data) {\n if (arguments.length === 2) {\n var instance = new Template7(template);\n var rendered = instance.compile()(data);\n instance = null;\n return (rendered);\n }\n else return new Template7(template);\n };\n t7.registerHelper = function (name, fn) {\n Template7.prototype.helpers[name] = fn;\n };\n t7.unregisterHelper = function (name) {\n Template7.prototype.helpers[name] = undefined; \n delete Template7.prototype.helpers[name];\n };\n \n t7.compile = function (template, options) {\n var instance = new Template7(template, options);\n return instance.compile();\n };\n \n t7.options = Template7.prototype.options;\n t7.helpers = Template7.prototype.helpers;\n return t7;\n })();\n"," /*===========================\n Swiper\n ===========================*/\n window.Swiper = function (container, params) {\n var defaults = {\n direction: 'horizontal',\n touchEventsTarget: 'container',\n initialSlide: 0,\n speed: 300,\n // autoplay\n autoplay: false,\n autoplayDisableOnInteraction: true,\n // Free mode\n freeMode: false,\n freeModeMomentum: true,\n freeModeMomentumRatio: 1,\n freeModeMomentumBounce: true,\n freeModeMomentumBounceRatio: 1,\n // Effects\n effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow'\n coverflow: {\n rotate: 50,\n stretch: 0,\n depth: 100,\n modifier: 1,\n slideShadows : true\n },\n cube: {\n slideShadows: true,\n shadow: true,\n shadowOffset: 20,\n shadowScale: 0.94\n },\n // Scrollbar\n scrollbar: null,\n scrollbarHide: true,\n // Keyboard Mousewheel\n keyboardControl: false,\n mousewheelControl: false,\n mousewheelForceToAxis: false,\n // Hash Navigation\n hashnav: false,\n // Slides grid\n spaceBetween: 0,\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerColumnFill: 'column',\n slidesPerGroup: 1,\n centeredSlides: false,\n // Touches\n touchRatio: 1,\n touchAngle: 45,\n simulateTouch: true,\n shortSwipes: true,\n longSwipes: true,\n longSwipesRatio: 0.5,\n longSwipesMs: 300,\n followFinger: true,\n onlyExternal: false,\n threshold: 0,\n touchMoveStopPropagation: true,\n // Pagination\n pagination: null,\n paginationClickable: false,\n paginationHide: false,\n // Resistance\n resistance: true,\n resistanceRatio: 0.85,\n // Next/prev buttons\n nextButton: null,\n prevButton: null,\n // Progress\n watchSlidesProgress: false,\n watchVisibility: false,\n // Cursor\n grabCursor: false,\n // Clicks\n preventClicks: true,\n clicksStopPropagation: true,\n releaseFormElements: true,\n slideToClickedSlide: false,\n // Images\n updateOnImagesReady: true,\n // loop\n loop: false,\n loopAdditionalSlides: 0,\n loopedSlides: null,\n // Control\n control: undefined,\n controlInverse: false,\n // Swiping/no swiping\n allowSwipeToPrev: true,\n allowSwipeToNext: true,\n swipeHandler: null, //'.swipe-handler',\n noSwiping: true,\n noSwipingClass: 'swiper-no-swiping',\n // NS\n slideClass: 'swiper-slide',\n slideActiveClass: 'swiper-slide-active',\n slideVisibleClass: 'swiper-slide-visible',\n slideDuplicateClass: 'swiper-slide-duplicate',\n slideNextClass: 'swiper-slide-next',\n slidePrevClass: 'swiper-slide-prev',\n wrapperClass: 'swiper-wrapper',\n bulletClass: 'swiper-pagination-bullet',\n bulletActiveClass: 'swiper-pagination-bullet-active',\n buttonDisabledClass: 'swiper-button-disabled',\n paginationHiddenClass: 'swiper-pagination-hidden',\n // Observer\n observer: false,\n observeParents: false,\n /*\n Callbacks:\n onClick: function (swiper, e) \n onTap: function (swiper, e) \n onDoubleTap: function (swiper, e) \n onSliderMove: function (swiper, e) \n onSlideChangeStart: function (swiper) \n onSlideChangeEnd: function (swiper) \n onTransitionStart: function (swiper) \n onTransitionEnd: function (swiper) \n onImagesReady: function (swiper) \n onProgress: function (swiper, progress) \n onDestroy: function () \n onTouchStart: function (swiper, e) \n onTouchMove: function (swiper, e) \n onTouchEnd: function (swiper, e) \n onReachBeginning: function (swiper) \n onReachEnd: function (swiper) \n onSetTransition: function (swiper, duration) \n onSetTranslate: function (swiper, translate) \n */\n };\n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n else if (typeof params[def] === 'object') {\n for (var deepDef in defaults[def]) {\n if (typeof params[def][deepDef] === 'undefined') {\n params[def][deepDef] = defaults[def][deepDef];\n }\n }\n }\n }\n \n // Swiper\n var s = this;\n \n // Params\n s.params = params;\n /*=========================\n Dom Library and plugins\n ===========================*/\n var $;\n if (typeof Dom7 === 'undefined') {\n $ = window.Dom7 || window.Zepto || window.jQuery;\n }\n else {\n $ = Dom7;\n }\n if (!$) return;\n \n /*=========================\n Preparation - Define Container, Wrapper and Pagination\n ===========================*/\n s.container = $(container);\n if (s.container.length === 0) return;\n if (s.container.length > 1) {\n s.container.each(function () {\n new Swiper(this, params);\n });\n return;\n }\n \n // Save instance in container HTML Element and in data\n s.container[0].swiper = s;\n s.container.data('swiper', s);\n \n s.container.addClass('swiper-container-' + s.params.direction);\n \n if (s.params.freeMode) {\n s.container.addClass('swiper-container-free-mode');\n }\n \n // Coverflow / 3D\n if (['cube', 'coverflow'].indexOf(s.params.effect) >= 0) {\n if (s.support.transforms3d) {\n s.params.watchSlidesProgress = true;\n s.container.addClass('swiper-container-3d');\n }\n else {\n s.params.effect = 'slide';\n }\n }\n if (s.params.effect !== 'slide') {\n s.container.addClass('swiper-container-' + s.params.effect);\n }\n if (s.params.effect === 'cube') {\n s.params.resistanceRatio = 0;\n s.params.slidesPerView = 1;\n s.params.slidesPerColumn = 1;\n s.params.slidesPerGroup = 1;\n s.params.centeredSlides = false;\n s.params.spaceBetween = 0;\n }\n if (s.params.effect === 'fade') {\n s.params.watchSlidesProgress = true;\n s.params.spaceBetween = 0;\n }\n \n // Grab Cursor\n if (s.params.grabCursor && s.support.touch) {\n s.params.grabCursor = false;\n }\n \n // Wrapper\n s.wrapper = s.container.children('.' + s.params.wrapperClass);\n \n // Pagination\n if (s.params.pagination) {\n s.paginationContainer = $(s.params.pagination);\n if (s.params.paginationClickable) {\n s.paginationContainer.addClass('swiper-pagination-clickable');\n }\n }\n \n // Is Horizontal\n function isH() {\n return s.params.direction === 'horizontal';\n }\n \n // RTL\n s.rtl = isH() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n \n // Translate\n s.translate = 0;\n \n // Progress\n s.progress = 0;\n \n // Velocity\n s.velocity = 0;\n \n // Locks, unlocks\n s.lockSwipeToNext = function () {\n s.params.allowSwipeToNext = false;\n };\n s.lockSwipeToPrev = function () {\n s.params.allowSwipeToPrev = false;\n };\n s.lockSwipes = function () {\n s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n };\n s.unlockSwipeToNext = function () {\n s.params.allowSwipeToNext = true;\n };\n s.unlockSwipeToPrev = function () {\n s.params.allowSwipeToPrev = true;\n };\n s.unlockSwipes = function () {\n s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n };\n \n // Columns\n if (s.params.slidesPerColumn > 1) {\n s.container.addClass('swiper-container-multirow');\n }\n \n \n /*=========================\n Set grab cursor\n ===========================*/\n if (s.params.grabCursor) {\n s.container[0].style.cursor = 'move';\n s.container[0].style.cursor = '-webkit-grab';\n s.container[0].style.cursor = '-moz-grab';\n s.container[0].style.cursor = 'grab';\n }\n /*=========================\n Update on Images Ready\n ===========================*/\n s.imagesToLoad = [];\n s.imagesLoaded = 0;\n \n function loadImage(img) {\n var image, src;\n var onReady = function () {\n if (typeof s === 'undefined' || s === null) return;\n if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n if (s.imagesLoaded === s.imagesToLoad.length) {\n s.update();\n if (s.params.onImagesReady) s.params.onImagesReady(s);\n }\n };\n \n if (!img.complete) {\n src = (img.currentSrc || img.getAttribute('src'));\n if (src) {\n image = new Image();\n image.onload = onReady;\n image.onerror = onReady;\n image.src = src;\n } else {\n onReady();\n }\n \n } else {//image already loaded...\n onReady();\n }\n }\n s.preloadImages = function () {\n s.imagesToLoad = s.container.find('img');\n \n for (var i = 0; i < s.imagesToLoad.length; i++) {\n loadImage(s.imagesToLoad[i]);\n }\n };\n \n /*=========================\n Autoplay\n ===========================*/\n s.autoplayTimeoutId = undefined;\n s.autoplaying = false;\n s.autoplayPaused = false;\n function autoplay() {\n s.autoplayTimeoutId = setTimeout(function () {\n if (s.params.loop) {\n s.fixLoop();\n s._slideNext();\n }\n else {\n if (!s.isEnd) {\n s._slideNext();\n }\n else {\n if (!params.autoplayStopOnLast) {\n s._slideTo(0);\n }\n else {\n s.stopAutoplay();\n }\n }\n }\n }, s.params.autoplay);\n }\n s.startAutoplay = function () {\n if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n if (!s.params.autoplay) return;\n if (s.autoplaying) return;\n s.autoplaying = true;\n if (s.params.onAutoplayStart) s.params.onAutoplayStart(s);\n autoplay();\n };\n s.stopAutoplay = function (internal) {\n if (!s.autoplayTimeoutId) return;\n if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n s.autoplaying = false;\n s.autoplayTimeoutId = undefined;\n if (s.params.onAutoplayStop) s.params.onAutoplayStop(s);\n };\n s.pauseAutoplay = function (speed) {\n if (s.autoplayPaused) return;\n if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n s.autoplayPaused = true;\n if (speed === 0) {\n s.autoplayPaused = false;\n autoplay();\n }\n else {\n s.wrapper.transitionEnd(function () {\n s.autoplayPaused = false;\n autoplay();\n });\n }\n };\n /*=========================\n Slider/slides sizes\n ===========================*/\n s.updateContainerSize = function () {\n s.width = s.container[0].clientWidth;\n s.height = s.container[0].clientHeight;\n s.size = isH() ? s.width : s.height;\n };\n \n s.updateSlidesSize = function () {\n s.slides = s.wrapper.children('.' + s.params.slideClass);\n s.snapGrid = [];\n s.slidesGrid = [];\n s.slidesSizesGrid = [];\n \n var spaceBetween = s.params.spaceBetween,\n slidePosition = 0,\n i,\n prevSlideSize = 0,\n index = 0;\n if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n }\n \n s.virtualWidth = -spaceBetween;\n // reset margins\n if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n else s.slides.css({marginRight: '', marginBottom: ''});\n \n var slidesNumberEvenToRows;\n if (s.params.slidesPerColumn > 1) {\n if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n slidesNumberEvenToRows = s.slides.length;\n }\n else {\n slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n }\n }\n \n // Calc slides\n var slideSize;\n for (i = 0; i < s.slides.length; i++) {\n slideSize = 0;\n var slide = s.slides.eq(i);\n if (s.params.slidesPerColumn > 1) {\n // Set slides order\n var newSlideOrderIndex;\n var column, row;\n var slidesPerColumn = s.params.slidesPerColumn;\n var slidesPerRow;\n if (s.params.slidesPerColumnFill === 'column') {\n column = Math.floor(i / slidesPerColumn);\n row = i - column * slidesPerColumn;\n newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n slide\n .css({\n '-webkit-box-ordinal-group': newSlideOrderIndex,\n '-moz-box-ordinal-group': newSlideOrderIndex,\n '-ms-flex-order': newSlideOrderIndex,\n '-webkit-order': newSlideOrderIndex,\n 'order': newSlideOrderIndex\n });\n }\n else {\n slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n row = Math.floor(i / slidesPerRow);\n column = i - row * slidesPerRow;\n \n }\n slide\n .css({\n 'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n })\n .attr('data-swiper-column', column)\n .attr('data-swiper-row', row);\n \n }\n if (slide.css('display') === 'none') continue;\n if (s.params.slidesPerView === 'auto') {\n slideSize = isH() ? slide.outerWidth(true) : slide.outerHeight(true);\n }\n else {\n slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n if (isH()) {\n s.slides[i].style.width = slideSize + 'px';\n }\n else {\n s.slides[i].style.height = slideSize + 'px';\n }\n }\n s.slides[i].swiperSlideSize = slideSize;\n s.slidesSizesGrid.push(slideSize);\n \n \n if (s.params.centeredSlides) {\n slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n s.slidesGrid.push(slidePosition);\n }\n else {\n if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n s.slidesGrid.push(slidePosition);\n slidePosition = slidePosition + slideSize + spaceBetween;\n }\n \n s.virtualWidth += slideSize + spaceBetween;\n \n prevSlideSize = slideSize;\n \n index ++;\n }\n s.virtualWidth = Math.max(s.virtualWidth, s.size);\n \n var newSlidesGrid;\n \n if (s.params.slidesPerColumn > 1) {\n s.virtualWidth = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n s.virtualWidth = Math.ceil(s.virtualWidth / s.params.slidesPerColumn) - s.params.spaceBetween;\n s.wrapper.css({width: s.virtualWidth + s.params.spaceBetween + 'px'});\n if (s.params.centeredSlides) {\n newSlidesGrid = [];\n for (i = 0; i < s.snapGrid.length; i++) {\n if (s.snapGrid[i] < s.virtualWidth + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n }\n s.snapGrid = newSlidesGrid;\n }\n }\n \n // Remove last grid elements depending on width\n if (!s.params.centeredSlides) {\n newSlidesGrid = [];\n for (i = 0; i < s.snapGrid.length; i++) {\n if (s.snapGrid[i] <= s.virtualWidth - s.size) {\n newSlidesGrid.push(s.snapGrid[i]);\n }\n }\n s.snapGrid = newSlidesGrid;\n if (Math.floor(s.virtualWidth - s.size) > Math.floor(s.snapGrid[s.snapGrid.length - 1])) {\n s.snapGrid.push(s.virtualWidth - s.size);\n }\n }\n if (s.snapGrid.length === 0) s.snapGrid = [0];\n \n if (s.params.spaceBetween !== 0) {\n if (isH()) {\n if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n else s.slides.css({marginRight: spaceBetween + 'px'});\n }\n else s.slides.css({marginBottom: spaceBetween + 'px'});\n }\n if (s.params.watchSlidesProgress) {\n s.updateSlidesOffset();\n }\n };\n s.updateSlidesOffset = function () {\n for (var i = 0; i < s.slides.length; i++) {\n s.slides[i].swiperSlideOffset = isH() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n }\n };\n \n s.update = function () {\n s.updateContainerSize();\n s.updateSlidesSize();\n s.updateProgress();\n s.updatePagination();\n s.updateClasses();\n };\n \n // Min/max translates\n s.minTranslate = function () {\n return (-s.snapGrid[0]);\n };\n s.maxTranslate = function () {\n return (-s.snapGrid[s.snapGrid.length - 1]);\n };\n \n /*=========================\n Slider/slides progress\n ===========================*/\n s.updateSlidesProgress = function (translate) {\n if (typeof translate === 'undefined') {\n translate = s.translate || 0;\n }\n if (s.slides.length === 0) return;\n if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n \n var offsetCenter = s.params.centeredSlides ? -translate + s.size / 2 : -translate;\n \n // Visible Slides\n var containerBox = s.container[0].getBoundingClientRect();\n var sideBefore = isH() ? 'left' : 'top';\n var sideAfter = isH() ? 'right' : 'bottom';\n s.slides.removeClass(s.params.slideVisibleClass);\n for (var i = 0; i < s.slides.length; i++) {\n var slide = s.slides[i];\n var slideCenterOffset = (s.params.centeredSlides === true) ? slide.swiperSlideSize / 2 : 0;\n var slideProgress = (offsetCenter - slide.swiperSlideOffset - slideCenterOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n if (s.params.watchVisibility) {\n var slideBefore = -(offsetCenter - slide.swiperSlideOffset - slideCenterOffset);\n var slideAfter = slideBefore + s.slidesSizesGrid[i];\n var isVisible =\n (slideBefore >= 0 && slideBefore < s.size) ||\n (slideAfter > 0 && slideAfter <= s.size) ||\n (slideBefore <= 0 && slideAfter >= s.size);\n if (isVisible) {\n s.slides.eq(i).addClass(s.params.slideVisibleClass);\n }\n }\n slide.progress = slideProgress;\n }\n };\n s.updateProgress = function (translate) {\n if (typeof translate === 'undefined') {\n translate = s.translate || 0;\n }\n s.progress = (translate - s.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n s.isBeginning = s.isEnd = false;\n \n if (s.progress <= 0) {\n s.isBeginning = true;\n if (s.params.onReachBeginning) s.params.onReachBeginning(s);\n }\n if (s.progress >= 1) {\n s.isEnd = true;\n if (s.params.onReachEnd) s.params.onReachEnd(s);\n }\n if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n if (s.params.onProgress) s.params.onProgress(s, s.progress);\n };\n s.updateActiveIndex = function () {\n var translate = s.rtl ? s.translate : -s.translate;\n var newActiveIndex, i, snapIndex;\n for (i = 0; i < s.slidesGrid.length; i ++) {\n if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n newActiveIndex = i;\n }\n else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n newActiveIndex = i + 1;\n }\n }\n else {\n if (translate >= s.slidesGrid[i]) {\n newActiveIndex = i;\n }\n }\n }\n // Normalize slideIndex\n if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n // for (i = 0; i < s.slidesGrid.length; i++) {\n // if (- translate >= s.slidesGrid[i]) {\n // newActiveIndex = i;\n // }\n // }\n snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n \n if (newActiveIndex === s.activeIndex) {\n return;\n }\n s.snapIndex = snapIndex;\n s.previousIndex = s.activeIndex;\n s.activeIndex = newActiveIndex;\n s.updateClasses();\n };\n \n /*=========================\n Classes\n ===========================*/\n s.updateClasses = function () {\n s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n var activeSlide = s.slides.eq(s.activeIndex);\n // Active classes\n activeSlide.addClass(s.params.slideActiveClass);\n activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n \n // Pagination\n if (s.bullets && s.bullets.length > 0) {\n s.bullets.removeClass(s.params.bulletActiveClass);\n var bulletIndex;\n if (s.params.loop) {\n bulletIndex = s.activeIndex - s.loopedSlides;\n if (bulletIndex > s.slides.length - 1 - s.loopedSlides * 2) {\n bulletIndex = bulletIndex - (s.slides.length - s.loopedSlides * 2);\n }\n }\n else {\n if (typeof s.snapIndex !== 'undefined') {\n bulletIndex = s.snapIndex;\n }\n else {\n bulletIndex = s.activeIndex || 0;\n }\n }\n s.bullets.eq(bulletIndex).addClass(s.params.bulletActiveClass);\n }\n \n // Next/active buttons\n if (!s.params.loop) {\n if (s.params.prevButton) {\n if (s.isBeginning) $(s.params.prevButton).addClass(s.params.buttonDisabledClass);\n else $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n }\n if (s.params.nextButton) {\n if (s.isEnd) $(s.params.nextButton).addClass(s.params.buttonDisabledClass);\n else $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n }\n }\n };\n \n /*=========================\n Pagination\n ===========================*/\n s.updatePagination = function () {\n if (!s.params.pagination) return;\n if (s.paginationContainer && s.paginationContainer.length > 0) {\n var bulletsHTML = '';\n var numberOfBullets = s.params.loop ? s.slides.length - s.loopedSlides * 2 : s.snapGrid.length;\n for (var i = 0; i < numberOfBullets; i++) {\n bulletsHTML += '<span class=\"' + s.params.bulletClass + '\"></span>';\n }\n s.paginationContainer.html(bulletsHTML);\n s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n }\n };\n \n \n /*=========================\n Resize Handler\n ===========================*/\n s.onResize = function () {\n s.updateContainerSize();\n s.updateSlidesSize();\n s.updateProgress();\n s.updateClasses();\n if (s.params.slidesPerView === 'auto') s.updatePagination();\n if (s.isEnd) {\n s.slideTo(s.slides.length - 1, 0, false);\n }\n else {\n s.slideTo(s.activeIndex, 0, false);\n }\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.init();\n }\n };\n \n /*=========================\n Events\n ===========================*/\n \n //Define Touch Events\n var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\n if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\n else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n \n s.touchEvents = {\n start : s.support.touch || !s.params.simulateTouch ? 'touchstart' : desktopEvents[0],\n move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n };\n \n // WP8 Touch Events Fix\n if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n }\n \n // Attach/detach events\n s.events = function (detach) {\n var action = detach ? 'off' : 'on';\n var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container : s.wrapper;\n var target = s.support.touch ? touchEventsTarget : $(document);\n \n var moveCapture = s.params.nested ? true : false;\n // Touch events\n touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n target[action](s.touchEvents.end, s.onTouchEnd, false);\n $(window)[action]('resize', s.onResize);\n \n // Next, Prev, Index\n if (s.params.nextButton) $(s.params.nextButton)[action]('click', s.onClickNext);\n if (s.params.prevButton) $(s.params.prevButton)[action]('click', s.onClickPrev);\n if (s.params.pagination && s.params.paginationClickable) {\n $(s.paginationContainer)[action]('click', '.' + s.params.bulletClass, s.onClickIndex);\n }\n \n // Prevent Links Clicks\n if (s.params.preventClicks || s.params.clicksStopPropagation) touchEventsTarget[action]('click', 'a', s.preventClicks, true);\n };\n s.attachEvents = function (detach) {\n s.events();\n };\n s.detachEvents = function () {\n s.events(true);\n };\n \n /*=========================\n Handle Clicks\n ===========================*/\n // Prevent Clicks\n s.allowClick = true;\n s.preventClicks = function (e) {\n if (!s.allowClick) {\n if (s.params.preventClicks) e.preventDefault();\n if (s.params.clicksStopPropagation) {\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n };\n // Clicks\n s.onClickNext = function (e) {\n e.preventDefault();\n s.slideNext();\n };\n s.onClickPrev = function (e) {\n e.preventDefault();\n s.slidePrev();\n };\n s.onClickIndex = function (e) {\n e.preventDefault();\n var index = $(this).index() * s.params.slidesPerGroup;\n if (s.params.loop) index = index + s.loopedSlides;\n s.slideTo(index);\n };\n \n /*=========================\n Handle Touches\n ===========================*/\n function findElementInEvent(e, selector) {\n var el = $(e.target);\n if (!el.is(selector)) {\n if (typeof selector === 'string') {\n el = el.parents(selector);\n }\n else if (selector.nodeType) {\n var found;\n el.parents().each(function (index, _el) {\n if (_el === selector) found = selector;\n });\n if (!found) return undefined;\n else return selector;\n }\n }\n if (el.length === 0) {\n return undefined;\n }\n return el[0];\n }\n s.updateClickedSlide = function (e) {\n var slide = findElementInEvent(e, '.' + s.params.slideClass);\n if (slide) {\n s.clickedSlide = slide;\n s.clickedIndex = $(slide).index();\n }\n if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n var slideToIndex = s.clickedIndex,\n realIndex;\n if (s.params.loop) {\n realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n s.fixLoop();\n slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]').eq(0).index();\n setTimeout(function () {\n s.slideTo(slideToIndex);\n }, 0);\n }\n else if (slideToIndex < s.params.slidesPerView - 1) {\n s.fixLoop();\n var duplicatedSlides = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]');\n slideToIndex = duplicatedSlides.eq(duplicatedSlides.length - 1).index();\n setTimeout(function () {\n s.slideTo(slideToIndex);\n }, 0);\n }\n else {\n s.slideTo(slideToIndex);\n }\n }\n else {\n s.slideTo(slideToIndex);\n }\n }\n };\n \n var isTouched, isMoved, touchesStart = {}, touchesCurrent = {}, touchStartTime, isScrolling, currentTranslate, startTranslate, allowThresholdMove;\n s.animating = false;\n var lastClickTime = Date.now(), clickTimeout;\n var velocities = [], allowMomentumBounce;\n // Form elements to match\n var formElements = 'input, select, textarea, button';\n \n // Touch handlers\n s.onTouchStart = function (e) {\n if (e.originalEvent) e = e.originalEvent; //jQuery fix\n if (e.type === 'mousedown' && 'which' in e && e.which === 3) return;\n if (e.originalEvent) e = e.originalEvent;\n if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) return;\n if (s.params.swipeHandler) {\n if (!findElementInEvent(e, s.params.swipeHandler)) return;\n }\n isTouched = true;\n isMoved = false;\n isScrolling = undefined;\n touchesStart.x = touchesCurrent.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = touchesCurrent.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = Date.now();\n s.allowClick = true;\n s.updateContainerSize();\n s.swipeDirection = undefined;\n if (s.params.threshold > 0) allowThresholdMove = false;\n if (e.type === 'mousedown') {\n var preventDefault = true;\n if ($(e.target).is(formElements)) preventDefault = false;\n if (document.activeElement && $(document.activeElement).is(formElements)) document.activeElement.blur();\n }\n if (s.params.onTouchStart) s.params.onTouchStart(s, e);\n };\n \n s.onTouchMove = function (e) {\n if (e.originalEvent) e = e.originalEvent; //jQuery fix\n if (e.preventedByNestedSwiper) return;\n if (s.params.onlyExternal) {\n isMoved = true;\n s.allowClick = false;\n return;\n }\n if (s.params.onTouchMove) s.params.onTouchMove(s, e);\n s.allowClick = false;\n if (!isTouched) return;\n if (e.targetTouches && e.targetTouches.length > 1) return;\n \n touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n \n var touchAngle = Math.atan2(Math.abs(touchesCurrent.y - touchesStart.y), Math.abs(touchesCurrent.x - touchesStart.x)) * 180 / Math.PI;\n if (typeof isScrolling === 'undefined') {\n isScrolling = isH() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n // isScrolling = !!(isScrolling || Math.abs(touchesCurrent.y - touchesStart.y) > Math.abs(touchesCurrent.x - touchesStart.x));\n }\n if (isScrolling) {\n isTouched = false;\n return;\n }\n if (s.params.onSliderMove) s.params.onSliderMove(s, e);\n \n e.preventDefault();\n if (s.params.touchMoveStopPropagation && !s.params.nested) {\n e.stopPropagation();\n }\n \n if (!isMoved) {\n if (params.loop) {\n s.fixLoop();\n }\n startTranslate = s.params.effect === 'cube' ? (s.translate || 0) : s.getWrapperTranslate();\n s.setWrapperTransition(0);\n if (s.animating) {\n s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n }\n if (s.params.autoplay && s.autoplaying) {\n if (s.params.autoplayDisableOnInteraction) {\n s.stopAutoplay();\n }\n else {\n s.pauseAutoplay();\n }\n }\n allowMomentumBounce = false;\n //Grab Cursor\n if (s.params.grabCursor) {\n s.container[0].style.cursor = 'move';\n s.container[0].style.cursor = '-webkit-grabbing';\n s.container[0].style.cursor = '-moz-grabbin';\n s.container[0].style.cursor = 'grabbing';\n }\n }\n isMoved = true;\n \n var diff = isH() ? touchesCurrent.x - touchesStart.x : touchesCurrent.y - touchesStart.y;\n \n diff = diff * s.params.touchRatio;\n if (s.rtl) diff = -diff;\n \n s.swipeDirection = diff > 0 ? 'prev' : 'next';\n currentTranslate = diff + startTranslate;\n \n var disableParentSwiper = true;\n if ((diff > 0 && currentTranslate > s.minTranslate())) {\n disableParentSwiper = false;\n if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n }\n else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n disableParentSwiper = false;\n if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n }\n \n if (disableParentSwiper) {\n e.preventedByNestedSwiper = true;\n }\n \n // Directions locks\n if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n currentTranslate = startTranslate;\n }\n if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n currentTranslate = startTranslate;\n }\n \n if (!s.params.followFinger) return;\n \n // Threshold\n if (s.params.threshold > 0) {\n if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n if (!allowThresholdMove) {\n allowThresholdMove = true;\n touchesStart.x = touchesCurrent.x;\n touchesStart.y = touchesCurrent.y;\n currentTranslate = startTranslate;\n return;\n }\n }\n else {\n currentTranslate = startTranslate;\n return;\n }\n }\n // Update active index in free mode\n if (s.params.freeMode || s.params.watchSlidesProgress) {\n s.updateActiveIndex();\n }\n if (s.params.freeMode) {\n //Velocity\n if (velocities.length === 0) {\n velocities.push({\n position: touchesStart[isH() ? 'x' : 'y'],\n time: touchStartTime\n });\n }\n velocities.push({\n position: touchesCurrent[isH() ? 'x' : 'y'],\n time: (new Date()).getTime()\n });\n }\n // Update progress\n s.updateProgress(currentTranslate);\n // Update translate\n s.setWrapperTranslate(currentTranslate);\n };\n s.onTouchEnd = function (e) {\n if (e.originalEvent) e = e.originalEvent; //jQuery fix\n if (!isTouched) return;\n if (s.params.onTouchEnd) s.params.onTouchEnd(s, e);\n \n //Return Grab Cursor\n if (s.params.grabCursor && isMoved && isTouched) {\n s.container[0].style.cursor = 'move';\n s.container[0].style.cursor = '-webkit-grab';\n s.container[0].style.cursor = '-moz-grab';\n s.container[0].style.cursor = 'grab';\n }\n \n // Time diff\n var touchEndTime = Date.now();\n var timeDiff = touchEndTime - touchStartTime;\n \n // Tap, doubleTap, Click\n if (s.allowClick) {\n s.updateClickedSlide(e);\n if (s.params.onTap) s.params.onTap(s, e);\n if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n if (clickTimeout) clearTimeout(clickTimeout);\n clickTimeout = setTimeout(function () {\n if (!s) return;\n if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n }\n if (s.params.onClick) s.params.onClick(s, e);\n }, 300);\n \n }\n if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n if (clickTimeout) clearTimeout(clickTimeout);\n if (s.params.onDoubleTap) {\n s.params.onDoubleTap(s, e);\n }\n }\n }\n \n lastClickTime = Date.now();\n setTimeout(function () {\n if (s && s.allowClick) s.allowClick = true;\n }, 0);\n \n var touchesDiff = isH() ? touchesCurrent.x - touchesStart.x : touchesCurrent.y - touchesStart.y;\n \n if (!isTouched || !isMoved || !s.swipeDirection || touchesDiff === 0 || currentTranslate === startTranslate) {\n isTouched = isMoved = false;\n return;\n }\n isTouched = isMoved = false;\n \n var currentPos;\n if (s.params.followFinger) {\n currentPos = s.rtl ? s.translate : -s.translate;\n }\n else {\n currentPos = -currentTranslate;\n }\n if (s.params.freeMode) {\n if (currentPos < -s.minTranslate()) {\n s.slideTo(s.activeIndex);\n return;\n }\n else if (currentPos > -s.maxTranslate()) {\n s.slideTo(s.slides.length - 1);\n return;\n }\n \n if (s.params.freeModeMomentum) {\n if (velocities.length > 1) {\n var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n \n var distance = lastMoveEvent.position - velocityEvent.position;\n var time = lastMoveEvent.time - velocityEvent.time;\n \n s.velocity = distance / time;\n s.velocity = s.velocity / 2;\n if (Math.abs(s.velocity) < 0.02) {\n s.velocity = 0;\n }\n // this implies that the user stopped moving a finger then released.\n // There would be no events with distance zero, so the last event is stale.\n // if (Math.abs(s.velocity) < 0.1 & time > 150 || timeDiff > 300) {\n if (time > 150 || timeDiff > 300) {\n s.velocity = 0;\n }\n } else {\n s.velocity = 0;\n }\n \n velocities.length = 0;\n \n var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n var momentumDistance = s.velocity * momentumDuration;\n \n var newPosition = s.translate + momentumDistance;\n var doBounce = false;\n var afterBouncePosition;\n var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n if (newPosition < s.maxTranslate()) {\n if (s.params.freeModeMomentumBounce) {\n if (newPosition + s.maxTranslate() < -bounceAmount) newPosition = s.maxTranslate() - bounceAmount;\n afterBouncePosition = s.maxTranslate();\n doBounce = true;\n allowMomentumBounce = true;\n }\n else newPosition = s.maxTranslate();\n }\n if (newPosition > s.minTranslate()) {\n if (s.params.freeModeMomentumBounce) {\n if (newPosition - s.minTranslate() > bounceAmount) {\n newPosition = s.minTranslate() + bounceAmount;\n }\n afterBouncePosition = s.minTranslate();\n doBounce = true;\n allowMomentumBounce = true;\n }\n else newPosition = s.minTranslate();\n }\n //Fix duration\n if (s.velocity !== 0) {\n momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n }\n \n if (s.params.freeModeMomentumBounce && doBounce) {\n s.updateProgress(afterBouncePosition);\n s.setWrapperTranslate(newPosition);\n s.setWrapperTransition(momentumDuration);\n s.onTransitionStart();\n s.animating = true;\n s.wrapper.transitionEnd(function () {\n if (!allowMomentumBounce) return;\n if (s.params.onMomentumBounce) s.params.onMomentumBounce(s);\n \n s.setWrapperTranslate(afterBouncePosition);\n s.setWrapperTransition(s.params.speed);\n s.wrapper.transitionEnd(function () {\n s.onTransitionEnd();\n });\n });\n } else if (s.velocity) {\n s.updateProgress(newPosition);\n s.setWrapperTranslate(newPosition);\n s.setWrapperTransition(momentumDuration);\n s.onTransitionStart();\n if (!s.animating) {\n s.animating = true;\n s.wrapper.transitionEnd(function () {\n s.onTransitionEnd();\n });\n }\n \n } else {\n s.updateProgress(newPosition);\n }\n \n s.updateActiveIndex();\n }\n if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n s.updateProgress();\n s.updateActiveIndex();\n }\n return;\n }\n \n // Find current slide\n var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n stopIndex = i;\n groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n }\n }\n else {\n if (currentPos >= s.slidesGrid[i]) {\n stopIndex = i;\n groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n }\n }\n }\n \n // Find current slide size\n var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n \n if (timeDiff > s.params.longSwipesMs) {\n // Long touches\n if (!s.params.longSwipes) {\n s.slideTo(s.activeIndex);\n return;\n }\n if (s.swipeDirection === 'next') {\n if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n else s.slideTo(stopIndex);\n \n }\n if (s.swipeDirection === 'prev') {\n if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n else s.slideTo(stopIndex);\n }\n }\n else {\n // Short swipes\n if (!s.params.shortSwipes) {\n s.slideTo(s.activeIndex);\n return;\n }\n if (s.swipeDirection === 'next') {\n s.slideTo(stopIndex + s.params.slidesPerGroup);\n \n }\n if (s.swipeDirection === 'prev') {\n s.slideTo(stopIndex);\n }\n }\n };\n /*=========================\n Transitions\n ===========================*/\n s._slideTo = function (slideIndex, speed) {\n return s.slideTo(slideIndex, speed, true, true);\n };\n s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n if (typeof runCallbacks === 'undefined') runCallbacks = true;\n if (typeof slideIndex === 'undefined') slideIndex = 0;\n if (slideIndex < 0) slideIndex = 0;\n s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n \n var translate = - s.snapGrid[s.snapIndex];\n \n // Stop autoplay\n \n if (s.params.autoplay && s.autoplaying) {\n if (internal || !s.params.autoplayDisableOnInteraction) {\n s.pauseAutoplay(speed);\n }\n else {\n s.stopAutoplay();\n }\n }\n // Update progress\n s.updateProgress(translate);\n \n // Normalize slideIndex\n for (var i = 0; i < s.slidesGrid.length; i++) {\n if (- translate >= s.slidesGrid[i]) {\n slideIndex = i;\n }\n }\n \n if (typeof speed === 'undefined') speed = s.params.speed;\n s.previousIndex = s.activeIndex || 0;\n s.activeIndex = slideIndex;\n \n if (translate === s.translate) {\n s.updateClasses();\n return false;\n }\n if (runCallbacks) s.onTransitionStart();\n var translateX = isH() ? translate : 0, translateY = isH() ? 0 : translate;\n if (speed === 0) {\n s.setWrapperTransition(0);\n s.setWrapperTranslate(translate);\n if (runCallbacks) s.onTransitionEnd();\n }\n else {\n s.setWrapperTransition(speed);\n s.setWrapperTranslate(translate);\n if (!s.animating) {\n s.animating = true;\n s.wrapper.transitionEnd(function () {\n if (runCallbacks) s.onTransitionEnd();\n });\n }\n \n }\n s.updateClasses();\n };\n \n s.onTransitionStart = function () {\n if (s.params.onTransitionStart) s.params.onTransitionStart(s);\n if (s.params.onSlideChangeStart && s.activeIndex !== s.previousIndex) s.params.onSlideChangeStart(s);\n };\n s.onTransitionEnd = function () {\n s.animating = false;\n s.setWrapperTransition(0);\n if (s.params.onTransitionEnd) s.params.onTransitionEnd(s);\n if (s.params.onSlideChangeEnd && s.activeIndex !== s.previousIndex) s.params.onSlideChangeEnd(s);\n };\n s.slideNext = function (runCallbacks, speed, internal) {\n if (s.params.loop) {\n if (s.animating) return false;\n s.fixLoop();\n setTimeout(function () {\n return s.slideTo(s.activeIndex + 1, speed, runCallbacks, internal);\n }, 0);\n }\n else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n };\n s._slideNext = function (speed) {\n return s.slideNext(true, speed, true);\n };\n s.slidePrev = function (runCallbacks, speed, internal) {\n if (s.params.loop) {\n if (s.animating) return false;\n s.fixLoop();\n setTimeout(function () {\n return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n }, 0);\n }\n else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n };\n s._slidePrev = function (speed) {\n return s.slidePrev(true, speed, true);\n };\n s.slideReset = function (runCallbacks, speed, internal) {\n return s.slideTo(s.activeIndex, speed, runCallbacks);\n };\n \n /*=========================\n Translate/transition helpers\n ===========================*/\n s.setWrapperTransition = function (duration, byController) {\n s.wrapper.transition(duration);\n if (s.params.onSetTransition) s.params.onSetTransition(s, duration);\n if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n s.effects[s.params.effect].setTransition(duration);\n }\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.setTransition(duration);\n }\n if (s.params.control && s.controller) {\n s.controller.setTransition(duration, byController);\n }\n };\n s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n var x = 0, y = 0, z = 0;\n if (isH()) {\n x = s.rtl ? -translate : translate;\n }\n else {\n y = translate;\n }\n \n if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n s.translate = isH() ? x : y;\n if (updateActiveIndex) s.updateActiveIndex();\n if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n s.effects[s.params.effect].setTranslate(s.translate);\n }\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.setTranslate(s.translate);\n }\n if (s.params.control && s.controller) {\n s.controller.setTranslate(s.translate, byController);\n }\n if (s.params.hashnav && s.hashnav) {\n s.hashnav.setHash();\n }\n if (s.params.onSetTranslate) s.params.onSetTranslate(s, s.translate);\n };\n \n s.getTranslate = function (el, axis) {\n var matrix, curTransform, curStyle, transformMatrix;\n \n // automatic axis detection\n if (typeof axis === 'undefined') {\n axis = 'x';\n }\n \n curStyle = window.getComputedStyle(el, null);\n if (window.WebKitCSSMatrix) {\n // Some old versions of Webkit choke when 'none' is passed; pass\n // empty string instead in this case\n transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);\n }\n else {\n transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n matrix = transformMatrix.toString().split(',');\n }\n \n if (axis === 'x') {\n //Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix)\n curTransform = transformMatrix.m41;\n //Crazy IE10 Matrix\n else if (matrix.length === 16)\n curTransform = parseFloat(matrix[12]);\n //Normal Browsers\n else\n curTransform = parseFloat(matrix[4]);\n }\n if (axis === 'y') {\n //Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix)\n curTransform = transformMatrix.m42;\n //Crazy IE10 Matrix\n else if (matrix.length === 16)\n curTransform = parseFloat(matrix[13]);\n //Normal Browsers\n else\n curTransform = parseFloat(matrix[5]);\n }\n if (s.rtl && curTransform) curTransform = -curTransform;\n return curTransform || 0;\n };\n s.getWrapperTranslate = function (axis) {\n if (typeof axis === 'undefined') {\n axis = isH() ? 'x' : 'y';\n }\n return s.getTranslate(s.wrapper[0], axis);\n };\n \n /*=========================\n Observer\n ===========================*/\n s.observers = [];\n function initObserver(target, options) {\n options = options || {};\n // create an observer instance\n var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n var observer = new ObserverFunc(function (mutations) {\n mutations.forEach(function (mutation) {\n s.onResize();\n });\n });\n \n observer.observe(target, {\n attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n childList: typeof options.childList === 'undefined' ? true : options.childList,\n characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n });\n \n s.observers.push(observer);\n }\n s.initObservers = function () {\n if (s.params.observeParents) {\n var containerParents = s.container.parents();\n for (var i = 0; i < containerParents.length; i++) {\n initObserver(containerParents[i]);\n }\n }\n \n // Observe container\n initObserver(s.container[0], {childList: false});\n \n // Observe wrapper\n initObserver(s.wrapper[0], {attributes: false});\n };\n s.disconnectObservers = function () {\n for (var i = 0; i < s.observers.length; i++) {\n s.observers[i].disconnect();\n }\n s.observers = [];\n };\n /*=========================\n Loop\n ===========================*/\n // Create looped slides\n s.createLoop = function () {\n // Remove duplicated slides\n s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n \n var slides = s.wrapper.children('.' + s.params.slideClass);\n s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n if (s.loopedSlides > slides.length) {\n s.loopedSlides = slides.length;\n }\n \n var prependSlides = [], appendSlides = [], i;\n slides.each(function (index, el) {\n var slide = $(this);\n if (index < s.loopedSlides) appendSlides.push(el);\n if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n slide.attr('data-swiper-slide-index', index);\n });\n for (i = 0; i < appendSlides.length; i++) {\n s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n }\n for (i = prependSlides.length - 1; i >= 0; i--) {\n s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n }\n };\n s.deleteLoop = function () {\n s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n };\n s.fixLoop = function () {\n var newIndex;\n //Fix For Negative Oversliding\n if (s.activeIndex < s.loopedSlides) {\n newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n newIndex = newIndex + s.loopedSlides;\n s.slideTo(newIndex, 0, false, true);\n }\n //Fix For Positive Oversliding\n else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n newIndex = newIndex + s.loopedSlides;\n s.slideTo(newIndex, 0, false, true);\n }\n };\n /*=========================\n Append/Prepend Slides\n ===========================*/\n s.appendSlide = function (slides) {\n if (s.params.loop) {\n s.deleteLoop();\n }\n if (typeof slides === 'object' && slides.length) {\n for (var i = 0; i < slides.length; i++) {\n if (slides[i]) s.wrapper.append(slides[i]);\n }\n }\n else {\n s.wrapper.append(slides);\n }\n if (s.params.loop) {\n s.createLoop();\n }\n if (!(s.params.observer && s.support.observer)) {\n s.update();\n }\n };\n s.prependSlide = function (slides) {\n if (s.params.loop) {\n s.deleteLoop();\n }\n var newActiveIndex = s.activeIndex + 1;\n if (typeof slides === 'object' && slides.length) {\n for (var i = 0; i < slides.length; i++) {\n if (slides[i]) s.wrapper.prepend(slides[i]);\n }\n newActiveIndex = s.activeIndex + slides.length;\n }\n else {\n s.wrapper.prepend(slides);\n }\n if (s.params.loop) {\n s.createLoop();\n }\n if (!(s.params.observer && s.support.observer)) {\n s.update();\n }\n s.slideTo(newActiveIndex, 0, false);\n };\n \n \n /*=========================\n Effects\n ===========================*/\n s.effects = {\n fade: {\n setTranslate: function () {\n for (var i = 0; i < s.slides.length; i++) {\n var slide = s.slides.eq(i);\n var offset = slide[0].swiperSlideOffset;\n var tx = -offset - s.translate;\n var ty = 0;\n if (!isH()) {\n ty = tx;\n tx = 0;\n }\n slide\n .css({\n opacity: 1 + Math.min(Math.max(slide[0].progress, -1), 0)\n })\n .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n \n }\n },\n setTransition: function (duration) {\n s.slides.transition(duration);\n }\n },\n cube: {\n setTranslate: function () {\n var wrapperRotate = 0, cubeShadow;\n if (s.params.cube.shadow) {\n if (isH()) {\n cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n if (cubeShadow.length === 0) {\n cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n s.wrapper.append(cubeShadow);\n }\n cubeShadow.css({height: s.width + 'px'});\n }\n else {\n cubeShadow = s.container.find('.swiper-cube-shadow');\n if (cubeShadow.length === 0) {\n cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n s.container.append(cubeShadow);\n }\n }\n }\n for (var i = 0; i < s.slides.length; i++) {\n var slide = s.slides.eq(i);\n var slideAngle = i * 90;\n var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n var tx = 0, ty = 0, tz = 0;\n var round = Math.floor(slideAngle / 360);\n if (i % 4 === 0) {\n tx = - round * 4 * s.size;\n tz = 0;\n }\n else if ((i - 1) % 4 === 0) {\n tx = 0;\n tz = - round * 4 * s.size;\n }\n else if ((i - 2) % 4 === 0) {\n tx = s.size + round * 4 * s.size;\n tz = s.size;\n }\n else if ((i - 3) % 4 === 0) {\n tx = - s.size;\n tz = 3 * s.size + s.size * 4 * round;\n }\n if (!isH()) {\n ty = tx;\n tx = 0;\n }\n \n var transform = 'rotateX(' + (isH() ? 0 : -slideAngle) + 'deg) rotateY(' + (isH() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n if (progress <= 1 && progress > -1) {\n wrapperRotate = i * 90 + progress * 90;\n }\n slide.transform(transform);\n if (s.params.cube.slideShadows) {\n //Set shadows\n var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n if (shadowBefore.length === 0) {\n shadowBefore = $('<div class=\"swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '\"></div>');\n slide.append(shadowBefore);\n }\n if (shadowAfter.length === 0) {\n shadowAfter = $('<div class=\"swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '\"></div>');\n slide.append(shadowAfter);\n }\n var shadowOpacity = slide[0].progress;\n if (shadowBefore.length) shadowBefore[0].style.opacity = -slide[0].progress;\n if (shadowAfter.length) shadowAfter[0].style.opacity = slide[0].progress;\n }\n }\n s.wrapper.css({\n '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n 'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n });\n \n if (s.params.cube.shadow) {\n if (isH()) {\n cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n }\n else {\n var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n var scale1 = s.params.cube.shadowScale,\n scale2 = s.params.cube.shadowScale / multiplier,\n offset = s.params.cube.shadowOffset;\n cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n }\n }\n var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (isH() ? 0 : wrapperRotate) + 'deg) rotateY(' + (isH() ? -wrapperRotate : 0) + 'deg)');\n },\n setTransition: function (duration) {\n s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n if (s.params.cube.shadow && !isH()) {\n s.container.find('.swiper-cube-shadow').transition(duration);\n }\n }\n },\n coverflow: {\n setTranslate: function () {\n var transform = s.translate;\n var center = isH() ? -transform + s.width / 2 : -transform + s.height / 2;\n var rotate = isH() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n var translate = s.params.coverflow.depth;\n //Each slide offset from center\n for (var i = 0, length = s.slides.length; i < length; i++) {\n var slide = s.slides.eq(i);\n var slideSize = s.slidesSizesGrid[i];\n var slideOffset = slide[0].swiperSlideOffset;\n var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n \n var rotateY = isH() ? rotate * offsetMultiplier : 0;\n var rotateX = isH() ? 0 : rotate * offsetMultiplier;\n // var rotateZ = 0\n var translateZ = -translate * Math.abs(offsetMultiplier);\n \n var translateY = isH() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n var translateX = isH() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n \n //Fix for ultra small values\n if (Math.abs(translateX) < 0.001) translateX = 0;\n if (Math.abs(translateY) < 0.001) translateY = 0;\n if (Math.abs(translateZ) < 0.001) translateZ = 0;\n if (Math.abs(rotateY) < 0.001) rotateY = 0;\n if (Math.abs(rotateX) < 0.001) rotateX = 0;\n \n var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n \n slide.transform(slideTransform);\n slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n if (s.params.coverflow.slideShadows) {\n //Set shadows\n var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n if (shadowBefore.length === 0) {\n shadowBefore = $('<div class=\"swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '\"></div>');\n slide.append(shadowBefore);\n }\n if (shadowAfter.length === 0) {\n shadowAfter = $('<div class=\"swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '\"></div>');\n slide.append(shadowAfter);\n }\n if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n }\n }\n \n //Set correct perspective for IE10\n if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n var ws = s.wrapper.style;\n ws.perspectiveOrigin = center + 'px 50%';\n }\n },\n setTransition: function (duration) {\n s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n }\n }\n };\n \n /*=========================\n Scrollbar\n ===========================*/\n s.scrollbar = {\n init: function () {\n if (!s.params.scrollbar) return;\n var sb = s.scrollbar;\n sb.track = $(s.params.scrollbar);\n sb.drag = sb.track.find('.swiper-scrollbar-drag');\n if (sb.drag.length === 0) {\n sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n sb.track.append(sb.drag);\n }\n sb.drag[0].style.width = '';\n sb.drag[0].style.height = '';\n sb.trackSize = isH() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n \n sb.divider = s.size / s.virtualWidth;\n sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n sb.dragSize = sb.trackSize * sb.divider;\n \n if (isH()) {\n sb.drag[0].style.width = sb.dragSize + 'px';\n }\n else {\n sb.drag[0].style.height = sb.dragSize + 'px';\n }\n \n if (sb.divider >= 1) {\n sb.track[0].style.display = 'none';\n }\n else {\n sb.track[0].style.display = '';\n }\n if (s.params.scrollbarHide) {\n sb.track[0].style.opacity = 0;\n }\n },\n setTranslate: function () {\n if (!s.params.scrollbar) return;\n var diff;\n var sb = s.scrollbar;\n var translate = s.translate || 0;\n var newPos;\n \n var newSize = sb.dragSize;\n newPos = (sb.trackSize - sb.dragSize) * s.progress;\n if (s.rtl && isH()) {\n newPos = -newPos;\n if (newPos > 0) {\n newSize = sb.dragSize - newPos;\n newPos = 0;\n }\n else if (-newPos + sb.dragSize > sb.trackSize) {\n newSize = sb.trackSize + newPos;\n }\n }\n else {\n if (newPos < 0) {\n newSize = sb.dragSize + newPos;\n newPos = 0;\n }\n else if (newPos + sb.dragSize > sb.trackSize) {\n newSize = sb.trackSize - newPos;\n }\n }\n if (isH()) {\n sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n sb.drag[0].style.width = newSize + 'px';\n }\n else {\n sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n sb.drag[0].style.height = newSize + 'px';\n }\n if (s.params.scrollbarHide) {\n clearTimeout(sb.timeout);\n sb.track[0].style.opacity = 1;\n sb.timeout = setTimeout(function () {\n sb.track[0].style.opacity = 0;\n sb.track.transition(400);\n }, 1000);\n }\n },\n setTransition: function (duration) {\n if (!s.params.scrollbar) return;\n s.scrollbar.drag.transition(duration);\n }\n };\n \n /*=========================\n Controller\n ===========================*/\n s.controller = {\n setTranslate: function (translate, byController) {\n var controlled = s.params.control;\n var multiplier, controlledTranslate;\n if (s.isArray(controlled)) {\n for (var i = 0; i < controlled.length; i++) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n translate = controlled[i].rtl && controlled[i].params.direction === 'horizontal' ? -s.translate : s.translate;\n multiplier = (controlled[i].maxTranslate() - controlled[i].minTranslate()) / (s.maxTranslate() - s.minTranslate());\n controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled[i].minTranslate();\n if (s.params.controlInverse) {\n controlledTranslate = controlled[i].maxTranslate() - controlledTranslate;\n }\n controlled[i].updateProgress(controlledTranslate);\n controlled[i].setWrapperTranslate(controlledTranslate, false, s);\n controlled[i].updateActiveIndex();\n }\n }\n }\n else if (controlled instanceof Swiper && byController !== controlled) {\n translate = controlled.rtl && controlled.params.direction === 'horizontal' ? -s.translate : s.translate;\n multiplier = (controlled.maxTranslate() - controlled.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled.minTranslate();\n if (s.params.controlInverse) {\n controlledTranslate = controlled.maxTranslate() - controlledTranslate;\n }\n controlled.updateProgress(controlledTranslate);\n controlled.setWrapperTranslate(controlledTranslate, false, s);\n controlled.updateActiveIndex();\n }\n },\n setTransition: function (duration, byController) {\n var controlled = s.params.control;\n if (s.isArray(controlled)) {\n for (var i = 0; i < controlled.length; i++) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n controlled[i].setWrapperTransition(duration, s);\n }\n }\n }\n else if (controlled instanceof Swiper && byController !== controlled) {\n controlled.setWrapperTransition(duration, s);\n }\n }\n };\n \n /*=========================\n Init/Destroy\n ===========================*/\n s.init = function () {\n if (s.params.loop) s.createLoop();\n s.updateContainerSize();\n s.updateSlidesSize();\n s.updatePagination();\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.init();\n }\n if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n if (!s.params.loop) s.updateProgress();\n s.effects[s.params.effect].setTranslate();\n }\n if (s.params.loop) {\n s.slideTo(s.params.initialSlide + s.loopedSlides, 0, false);\n }\n else {\n s.slideTo(s.params.initialSlide, 0, false);\n }\n s.attachEvents();\n if (s.params.observer && s.support.observer) {\n s.initObservers();\n }\n if (s.params.updateOnImagesReady) {\n s.preloadImages();\n }\n if (s.params.autoplay) {\n s.startAutoplay();\n }\n if (s.params.keyboardControl) {\n if (s.enableKeyboardControl) s.enableKeyboardControl();\n }\n if (s.params.mousewheelControl) {\n if (s.enableMousewheelControl) s.enableMousewheelControl();\n }\n if (s.params.hashnav) {\n if (s.hashnav) s.hashnav.init();\n }\n };\n \n // Destroy\n s.destroy = function (deleteInstance) {\n s.detachEvents();\n s.disconnectObservers();\n if (s.params.keyboardControl) {\n if (s.disableKeyboard) s.disableKeyboard();\n }\n if (s.params.mousewheelControl) {\n if (s.disableMousewheel) s.disableMousewheel();\n }\n if (s.params.onDestroy) s.params.onDestroy();\n if (deleteInstance !== false) s = null;\n };\n \n s.init();\n \n \n \n \n // Return swiper instance\n return s;\n };\n \n /*==================================================\n Prototype\n ====================================================*/\n Swiper.prototype = {\n isSafari: (function () {\n var ua = navigator.userAgent.toLowerCase();\n return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n })(),\n isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n isArray: function (arr) {\n return Object.prototype.toString.apply(arr) === '[object Array]';\n },\n /*==================================================\n Feature Detection\n ====================================================*/\n support: {\n touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n })(),\n \n transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n var div = document.createElement('div').style;\n return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n })(),\n \n flexbox: (function () {\n var div = document.createElement('div').style;\n var styles = ('WebkitBox msFlexbox MsFlexbox WebkitFlex MozBox fles').split(' ');\n for (var i = 0; i < styles.length; i++) {\n if (styles[i] in div) return true;\n }\n })(),\n \n observer: (function () {\n return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n })()\n },\n };\n","})();\n"],"sourceRoot":"/source/"}
1
+ {"version":3,"sources":["wrap-start.js","f7-intro.js","views.js","navbars.js","searchbar.js","messagebar.js","xhr.js","pages.js","router.js","modals.js","panels.js","lazy-load.js","messages.js","swipeout.js","sortable.js","smart-select.js","virtual-list.js","pull-to-refresh.js","infinite-scroll.js","scroll-toolbars.js","tabs.js","accordion.js","fast-clicks.js","clicks.js","resize.js","forms-handler.js","push-state.js","swiper-init.js","photo-browser.js","picker.js","calendar.js","notifications.js","template7-templates.js","plugins.js","init.js","f7-outro.js","dom7-intro.js","dom7-methods.js","dom7-ajax.js","dom7-utils.js","dom7-outro.js","proto-support.js","proto-device.js","proto-plugins.js","template7.js","swiper.js","wrap-end.js"],"names":[],"mappings":"AAAA;AACA;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxhBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7jCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5hBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClkBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9zBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7CA;AACA;AACA;AACA;AACA;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9qBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzGA;AACA;AACA;AACA;AACA;AACA;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7kEA;AACA","file":"framework7.js","sourcesContent":["(function () {\n"," 'use strict';\n /*===========================\n Framework 7\n ===========================*/\n window.Framework7 = function (params) {\n \n // App\n var app = this;\n \n // Version\n app.version = '1.0.2';\n \n // Default Parameters\n app.params = {\n cache: true,\n cacheIgnore: [],\n cacheIgnoreGetParameters: false,\n cacheDuration: 1000 * 60 * 10, // Ten minutes \n preloadPreviousPage: true,\n uniqueHistory: false,\n uniqueHistoryIgnoreGetParameters: false,\n dynamicPageUrl: 'content-{{index}}',\n allowDuplicateUrls: false,\n router: true,\n // Push State\n pushState: false,\n pushStateRoot: undefined,\n pushStateNoAnimation: false,\n pushStateSeparator: '#!/',\n // Fast clicks\n fastClicks: true,\n fastClicksDistanceThreshold: 0,\n fastClicksDelayBetweenClicks: 50,\n // Active State\n activeState: true,\n activeStateElements: 'a, button, label, span',\n // Animate Nav Back Icon\n animateNavBackIcon: false,\n // Swipe Back\n swipeBackPage: true,\n swipeBackPageThreshold: 0,\n swipeBackPageActiveArea: 30,\n swipeBackPageAnimateShadow: true,\n swipeBackPageAnimateOpacity: true,\n // Ajax\n ajaxLinks: undefined, // or CSS selector\n // External Links\n externalLinks: '.external', // CSS selector\n // Sortable\n sortable: true,\n // Scroll toolbars\n hideNavbarOnPageScroll: false,\n hideToolbarOnPageScroll: false,\n hideTabbarOnPageScroll: false,\n showBarsOnPageScrollEnd: true,\n // Swipeout\n swipeout: true,\n swipeoutActionsNoFold: false,\n swipeoutNoFollow: false,\n // Smart Select Back link template\n smartSelectBackTemplate: '<div class=\"left sliding\"><a href=\"#\" class=\"back link\"><i class=\"icon icon-back\"></i><span>{{backText}}</span></a></div>',\n smartSelectBackText: 'Back',\n smartSelectInPopup: false,\n smartSelectPopupCloseTemplate: '<div class=\"left\"><a href=\"#\" class=\"link close-popup\"><i class=\"icon icon-back\"></i><span>{{closeText}}</span></a></div>',\n smartSelectPopupCloseText: 'Close',\n smartSelectSearchbar: false,\n smartSelectBackOnSelect: false,\n // Searchbar\n searchbarHideDividers: true,\n searchbarHideGroups: true,\n // Tap Navbar or Statusbar to scroll to top\n scrollTopOnNavbarClick: false,\n scrollTopOnStatusbarClick: false,\n // Panels\n swipePanel: false, // or 'left' or 'right'\n swipePanelActiveArea: 0,\n swipePanelCloseOpposite: true,\n swipePanelOnlyClose: false,\n swipePanelNoFollow: false,\n swipePanelThreshold: 0,\n panelsCloseByOutside: true,\n // Modals\n modalButtonOk: 'OK',\n modalButtonCancel: 'Cancel',\n modalUsernamePlaceholder: 'Username',\n modalPasswordPlaceholder: 'Password',\n modalTitle: 'Framework7',\n modalCloseByOutside: false,\n actionsCloseByOutside: true,\n popupCloseByOutside: true,\n modalPreloaderTitle: 'Loading... ',\n modalStack: true,\n // Lazy Load\n imagesLazyLoadThreshold: 0,\n imagesLazyLoadSequential: true,\n // Name space\n viewClass: 'view',\n viewMainClass: 'view-main',\n viewsClass: 'views',\n // Notifications defaults\n notificationCloseOnClick: false,\n notificationCloseIcon: true,\n // Animate Pages\n animatePages: true,\n // Template7\n templates: {},\n template7Data: {},\n template7Pages: false,\n precompileTemplates: false,\n // Auto init\n init: true,\n };\n \n // Extend defaults with parameters\n for (var param in params) {\n app.params[param] = params[param];\n }\n \n // DOM lib\n var $ = Dom7;\n \n // Template7 lib\n var t7 = Template7;\n app._compiledTemplates = {};\n \n // Touch events\n app.touchEvents = {\n start: app.support.touch ? 'touchstart' : 'mousedown',\n move: app.support.touch ? 'touchmove' : 'mousemove',\n end: app.support.touch ? 'touchend' : 'mouseup'\n };\n \n // Link to local storage\n app.ls = window.localStorage;\n \n // RTL\n app.rtl = $('body').css('direction') === 'rtl';\n if (app.rtl) $('html').attr('dir', 'rtl');\n \n // Overwrite statusbar overlay\n if (typeof app.params.statusbarOverlay !== 'undefined') {\n if (app.params.statusbarOverlay) $('html').addClass('with-statusbar-overlay');\n else $('html').removeClass('with-statusbar-overlay');\n }\n \n \n \n"," /*======================================================\n ************ Views ************\n ======================================================*/\n app.views = [];\n var View = function (selector, params) {\n var defaults = {\n dynamicNavbar: false,\n domCache: false,\n linksView: undefined,\n reloadPages: false,\n uniqueHistory: app.params.uniqueHistory,\n uniqueHistoryIgnoreGetParameters: app.params.uniqueHistoryIgnoreGetParameters,\n allowDuplicateUrls: app.params.allowDuplicateUrls,\n swipeBackPage: app.params.swipeBackPage,\n swipeBackPageAnimateShadow: app.params.swipeBackPageAnimateShadow,\n swipeBackPageAnimateOpacity: app.params.swipeBackPageAnimateOpacity,\n swipeBackPageActiveArea: app.params.swipeBackPageActiveArea,\n swipeBackPageThreshold: app.params.swipeBackPageThreshold,\n animatePages: app.params.animatePages,\n preloadPreviousPage: app.params.preloadPreviousPage\n };\n var i;\n \n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n // View\n var view = this;\n view.params = params;\n \n // Selector\n view.selector = selector;\n \n // Container\n var container = $(selector);\n view.container = container[0];\n \n // Content cache\n view.contentCache = {};\n \n // Pages cache\n view.pagesCache = {};\n \n // Store View in element for easy access\n container[0].f7View = view;\n \n // Pages\n view.pagesContainer = container.find('.pages')[0];\n view.initialPages = [];\n view.initialNavbars = [];\n if (view.params.domCache) {\n var initialPages = container.find('.page');\n for (i = 0; i < initialPages.length; i++) {\n view.initialPages.push(initialPages[i]);\n }\n if (view.params.dynamicNavbar) {\n var initialNavbars = container.find('.navbar-inner');\n for (i = 0; i < initialNavbars.length; i++) {\n view.initialNavbars.push(initialNavbars[i]);\n }\n }\n \n }\n \n view.allowPageChange = true;\n \n // Location\n var docLocation = document.location.href;\n \n // History\n view.history = [];\n var viewURL = docLocation;\n var pushStateSeparator = app.params.pushStateSeparator;\n var pushStateRoot = app.params.pushStateRoot;\n if (app.params.pushState) {\n if (pushStateRoot) {\n viewURL = pushStateRoot;\n }\n else {\n if (viewURL.indexOf(pushStateSeparator) >= 0 && viewURL.indexOf(pushStateSeparator + '#') < 0) viewURL = viewURL.split(pushStateSeparator)[0];\n }\n \n }\n \n // Active Page\n var currentPage, currentPageData;\n if (!view.activePage) {\n currentPage = $(view.pagesContainer).find('.page-on-center');\n if (currentPage.length === 0) {\n currentPage = $(view.pagesContainer).find('.page:not(.cached)');\n currentPage = currentPage.eq(currentPage.length - 1);\n }\n if (currentPage.length > 0) {\n currentPageData = currentPage[0].f7PageData;\n }\n }\n \n // View startup URL\n if (view.params.domCache && currentPage) {\n view.url = container.attr('data-url') || view.params.url || '#' + currentPage.attr('data-page'); \n view.pagesCache[view.url] = currentPage.attr('data-page');\n }\n else view.url = container.attr('data-url') || view.params.url || viewURL;\n \n // Update current page Data\n if (currentPageData) {\n currentPageData.view = view;\n currentPageData.url = view.url;\n view.activePage = currentPageData;\n currentPage[0].f7PageData = currentPageData;\n }\n \n // Store to history main view's url\n if (view.url) {\n view.history.push(view.url);\n }\n \n // Is main\n view.main = container.hasClass(app.params.viewMainClass);\n \n // Touch events\n var isTouched = false,\n isMoved = false,\n touchesStart = {},\n isScrolling,\n activePage = [],\n previousPage = [],\n viewContainerWidth,\n touchesDiff,\n allowViewTouchMove = true,\n touchStartTime,\n activeNavbar = [],\n previousNavbar = [],\n activeNavElements,\n previousNavElements,\n activeNavBackIcon,\n previousNavBackIcon,\n dynamicNavbar,\n pageShadow,\n el;\n \n view.handleTouchStart = function (e) {\n if (!allowViewTouchMove || !view.params.swipeBackPage || isTouched || app.swipeoutOpenedEl) return;\n isMoved = false;\n isTouched = true;\n isScrolling = undefined;\n touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n dynamicNavbar = view.params.dynamicNavbar && container.find('.navbar-inner').length > 1;\n };\n \n view.handleTouchMove = function (e) {\n if (!isTouched) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));\n }\n if (isScrolling || e.f7PreventSwipeBack || app.preventSwipeBack) {\n isTouched = false;\n return;\n }\n \n if (!isMoved) {\n var cancel = false;\n // Calc values during first move fired\n viewContainerWidth = container.width();\n var target = $(e.target);\n var swipeout = target.hasClass('swipeout') ? target : target.parents('.swipeout');\n if (swipeout.length > 0) {\n if (!app.rtl && swipeout.find('.swipeout-actions-left').length > 0) cancel = true;\n if (app.rtl && swipeout.find('.swipeout-actions-right').length > 0) cancel = true;\n }\n activePage = target.is('.page') ? target : target.parents('.page');\n if (activePage.hasClass('no-swipeback')) cancel = true;\n previousPage = container.find('.page-on-left:not(.cached)');\n var notFromBorder = touchesStart.x - container.offset().left > view.params.swipeBackPageActiveArea;\n if (app.rtl) {\n notFromBorder = touchesStart.x < container.offset().left - container[0].scrollLeft + viewContainerWidth - view.params.swipeBackPageActiveArea;\n }\n else {\n notFromBorder = touchesStart.x - container.offset().left > view.params.swipeBackPageActiveArea;\n }\n if (notFromBorder) cancel = true;\n if (previousPage.length === 0 || activePage.length === 0) cancel = true;\n if (cancel) {\n isTouched = false;\n return;\n }\n \n if (view.params.swipeBackPageAnimateShadow && !app.device.android) {\n pageShadow = activePage.find('.swipeback-page-shadow');\n if (pageShadow.length === 0) {\n pageShadow = $('<div class=\"swipeback-page-shadow\"></div>');\n activePage.append(pageShadow);\n }\n }\n \n if (dynamicNavbar) {\n activeNavbar = container.find('.navbar-on-center:not(.cached)');\n previousNavbar = container.find('.navbar-on-left:not(.cached)');\n activeNavElements = activeNavbar.find('.left, .center, .right, .subnavbar, .fading');\n previousNavElements = previousNavbar.find('.left, .center, .right, .subnavbar, .fading');\n if (app.params.animateNavBackIcon) {\n activeNavBackIcon = activeNavbar.find('.left.sliding .back .icon');\n previousNavBackIcon = previousNavbar.find('.left.sliding .back .icon');\n }\n }\n }\n e.f7PreventPanelSwipe = true;\n isMoved = true;\n e.preventDefault();\n \n // RTL inverter\n var inverter = app.rtl ? -1 : 1;\n \n // Touches diff\n touchesDiff = (pageX - touchesStart.x - view.params.swipeBackPageThreshold) * inverter;\n if (touchesDiff < 0) touchesDiff = 0;\n var percentage = touchesDiff / viewContainerWidth;\n \n // Swipe Back Callback\n var callbackData = {\n percentage: percentage,\n activePage: activePage[0],\n previousPage: previousPage[0],\n activeNavbar: activeNavbar[0],\n previousNavbar: previousNavbar[0]\n };\n if (view.params.onSwipeBackMove) {\n view.params.onSwipeBackMove(callbackData);\n }\n container.trigger('swipebackmove', callbackData);\n \n // Transform pages\n var activePageTranslate = touchesDiff * inverter;\n var previousPageTranslate = (touchesDiff / 5 - viewContainerWidth / 5) * inverter;\n if (app.device.pixelRatio === 1) {\n activePageTranslate = Math.round(activePageTranslate);\n previousPageTranslate = Math.round(previousPageTranslate);\n }\n \n activePage.transform('translate3d(' + activePageTranslate + 'px,0,0)');\n if (view.params.swipeBackPageAnimateShadow && !app.device.android) pageShadow[0].style.opacity = 1 - 1 * percentage;\n \n previousPage.transform('translate3d(' + previousPageTranslate + 'px,0,0)');\n if (view.params.swipeBackPageAnimateOpacity) previousPage[0].style.opacity = 0.9 + 0.1 * percentage;\n \n // Dynamic Navbars Animation\n if (dynamicNavbar) {\n var i;\n for (i = 0; i < activeNavElements.length; i++) {\n el = $(activeNavElements[i]);\n if (!el.is('.subnavbar.sliding')) el[0].style.opacity = (1 - percentage * 1.3);\n if (el[0].className.indexOf('sliding') >= 0) {\n var activeNavTranslate = percentage * el[0].f7NavbarRightOffset;\n if (app.device.pixelRatio === 1) activeNavTranslate = Math.round(activeNavTranslate);\n el.transform('translate3d(' + activeNavTranslate + 'px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (el[0].className.indexOf('left') >= 0 && activeNavBackIcon.length > 0) {\n activeNavBackIcon.transform('translate3d(' + -activeNavTranslate + 'px,0,0)');\n }\n }\n }\n }\n for (i = 0; i < previousNavElements.length; i++) {\n el = $(previousNavElements[i]);\n if (!el.is('.subnavbar.sliding')) el[0].style.opacity = percentage * 1.3 - 0.3;\n if (el[0].className.indexOf('sliding') >= 0) {\n var previousNavTranslate = el[0].f7NavbarLeftOffset * (1 - percentage);\n if (app.device.pixelRatio === 1) previousNavTranslate = Math.round(previousNavTranslate);\n el.transform('translate3d(' + previousNavTranslate + 'px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (el[0].className.indexOf('left') >= 0 && previousNavBackIcon.length > 0) {\n previousNavBackIcon.transform('translate3d(' + -previousNavTranslate + 'px,0,0)');\n }\n }\n }\n }\n }\n };\n \n view.handleTouchEnd = function (e) {\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n isTouched = false;\n isMoved = false;\n if (touchesDiff === 0) {\n $([activePage[0], previousPage[0]]).transform('').css({opacity: '', boxShadow: ''});\n if (dynamicNavbar) {\n activeNavElements.transform('').css({opacity: ''});\n previousNavElements.transform('').css({opacity: ''});\n if (activeNavBackIcon && activeNavBackIcon.length > 0) activeNavBackIcon.transform('');\n if (previousNavBackIcon && activeNavBackIcon.length > 0) previousNavBackIcon.transform('');\n }\n return;\n }\n var timeDiff = (new Date()).getTime() - touchStartTime;\n var pageChanged = false;\n // Swipe back to previous page\n if (\n timeDiff < 300 && touchesDiff > 10 ||\n timeDiff >= 300 && touchesDiff > viewContainerWidth / 2\n ) {\n activePage.removeClass('page-on-center').addClass('page-on-right');\n previousPage.removeClass('page-on-left').addClass('page-on-center');\n if (dynamicNavbar) {\n activeNavbar.removeClass('navbar-on-center').addClass('navbar-on-right');\n previousNavbar.removeClass('navbar-on-left').addClass('navbar-on-center');\n }\n pageChanged = true;\n }\n // Reset custom styles\n // Add transitioning class for transition-duration\n $([activePage[0], previousPage[0]]).transform('').css({opacity: '', boxShadow: ''}).addClass('page-transitioning');\n if (dynamicNavbar) {\n activeNavElements.css({opacity: ''})\n .each(function () {\n var translate = pageChanged ? this.f7NavbarRightOffset : 0;\n var sliding = $(this);\n sliding.transform('translate3d(' + translate + 'px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && activeNavBackIcon.length > 0) {\n activeNavBackIcon.addClass('page-transitioning').transform('translate3d(' + -translate + 'px,0,0)');\n }\n }\n \n }).addClass('page-transitioning');\n \n previousNavElements.transform('').css({opacity: ''}).each(function () {\n var translate = pageChanged ? 0 : this.f7NavbarLeftOffset;\n var sliding = $(this);\n sliding.transform('translate3d(' + translate + 'px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && previousNavBackIcon.length > 0) {\n previousNavBackIcon.addClass('page-transitioning').transform('translate3d(' + -translate + 'px,0,0)');\n }\n }\n }).addClass('page-transitioning');\n }\n allowViewTouchMove = false;\n view.allowPageChange = false;\n \n if (pageChanged) {\n // Update View's URL\n var url = view.history[view.history.length - 2];\n view.url = url;\n \n // Page before animation callback\n app.pageBackCallbacks('before', view, {pageContainer: activePage[0], url: url, position: 'center', newPage: previousPage, oldPage: activePage, swipeBack: true});\n app.pageAnimCallbacks('before', view, {pageContainer: previousPage[0], url: url, position: 'left', newPage: previousPage, oldPage: activePage, swipeBack: true});\n }\n \n activePage.transitionEnd(function () {\n $([activePage[0], previousPage[0]]).removeClass('page-transitioning');\n if (dynamicNavbar) {\n activeNavElements.removeClass('page-transitioning').css({opacity: ''});\n previousNavElements.removeClass('page-transitioning').css({opacity: ''});\n if (activeNavBackIcon && activeNavBackIcon.length > 0) activeNavBackIcon.removeClass('page-transitioning');\n if (previousNavBackIcon && previousNavBackIcon.length > 0) previousNavBackIcon.removeClass('page-transitioning');\n }\n allowViewTouchMove = true;\n view.allowPageChange = true;\n if (pageChanged) {\n if (app.params.pushState) history.back();\n // Page after animation callback\n app.pageBackCallbacks('after', view, {pageContainer: activePage[0], url: url, position: 'center', newPage: previousPage, oldPage: activePage, swipeBack: true});\n app.pageAnimCallbacks('after', view, {pageContainer: previousPage[0], url: url, position: 'left', newPage: previousPage, oldPage: activePage, swipeBack: true});\n app.router.afterBack(view, activePage, previousPage);\n }\n if (pageShadow && pageShadow.length > 0) pageShadow.remove();\n });\n };\n view.attachEvents = function (detach) {\n var action = detach ? 'off' : 'on';\n container[action](app.touchEvents.start, view.handleTouchStart);\n container[action](app.touchEvents.move, view.handleTouchMove);\n container[action](app.touchEvents.end, view.handleTouchEnd);\n };\n view.detachEvents = function () {\n view.attachEvents(true);\n };\n \n // Init\n if (view.params.swipeBackPage) {\n view.attachEvents();\n }\n \n // Add view to app\n app.views.push(view);\n if (view.main) app.mainView = view;\n \n // Router \n view.router = {\n load: function (options) {\n return app.router.load(view, options);\n },\n back: function (options) {\n return app.router.back(view, options); \n },\n // Shortcuts\n loadPage: function (options) {\n options = options || {};\n if (typeof options === 'string') {\n var url = options;\n options = {};\n if (url && url.indexOf('#') === 0 && view.params.domCache) {\n options.pageName = url.split('#')[1];\n }\n else options.url = url;\n }\n return app.router.load(view, options);\n },\n loadContent: function (content) {\n return app.router.load(view, {content: content});\n },\n reloadPage: function (url) {\n return app.router.load(view, {url: url, reload: true});\n },\n reloadContent: function (content) {\n return app.router.load(view, {content: content, reload: true});\n },\n reloadPreviousPage: function (url) {\n return app.router.load(view, {url: url, reloadPrevious: true, reload: true});\n },\n reloadPreviousContent: function (content) {\n return app.router.load(view, {content: content, reloadPrevious: true, reload: true});\n },\n refreshPage: function () {\n var options = {\n url: view.url,\n reload: true,\n ignoreCache: true\n };\n if (options.url && options.url.indexOf('#') === 0) {\n if (view.params.domCache && view.pagesCache[options.url]) {\n options.pageName = view.pagesCache[options.url];\n options.url = undefined;\n delete options.url;\n }\n else if (view.contentCache[options.url]) {\n options.content = view.contentCache[options.url];\n options.url = undefined;\n delete options.url;\n }\n }\n return app.router.load(view, options);\n },\n refreshPreviousPage: function () {\n var options = {\n url: view.history[view.history.length - 2],\n reload: true,\n reloadPrevious: true,\n ignoreCache: true\n };\n if (options.url && options.url.indexOf('#') === 0 && view.params.domCache && view.pagesCache[options.url]) {\n options.pageName = view.pagesCache[options.url];\n options.url = undefined;\n delete options.url;\n }\n return app.router.load(view, options);\n }\n };\n \n // Aliases for temporary backward compatibility\n view.loadPage = view.router.loadPage;\n view.loadContent = view.router.loadContent;\n view.reloadPage = view.router.reloadPage;\n view.reloadContent = view.router.reloadContent;\n view.reloadPreviousPage = view.router.reloadPreviousPage;\n view.reloadPreviousContent = view.router.reloadPreviousContent;\n view.refreshPage = view.router.refreshPage;\n view.refreshPreviousPage = view.router.refreshPreviousPage;\n view.back = view.router.back;\n \n // Bars methods\n view.hideNavbar = function () {\n return app.hideNavbar(container.find('.navbar'));\n };\n view.showNavbar = function () {\n return app.showNavbar(container.find('.navbar'));\n };\n view.hideToolbar = function () {\n return app.hideToolbar(container.find('.toolbar'));\n };\n view.showToolbar = function () {\n return app.showToolbar(container.find('.toolbar'));\n };\n \n // Push State on load\n if (app.params.pushState && view.main) {\n var pushStateUrl;\n if (pushStateRoot) {\n pushStateUrl = docLocation.split(app.params.pushStateRoot + pushStateSeparator)[1];\n }\n else if (docLocation.indexOf(pushStateSeparator) >= 0 && docLocation.indexOf(pushStateSeparator + '#') < 0) {\n pushStateUrl = docLocation.split(pushStateSeparator)[1];\n }\n var pushStateAnimatePages = app.params.pushStateNoAnimation ? false : undefined;\n \n if (pushStateUrl) {\n app.router.load(view, {url: pushStateUrl, animatePages: pushStateAnimatePages, pushState: false});\n }\n else if (docLocation.indexOf(pushStateSeparator + '#') >= 0) {\n var state = history.state;\n if (state.pageName && 'viewIndex' in state) {\n app.router.load(view, {pageName: state.pageName, pushState: false});\n }\n }\n \n }\n \n // Destroy\n view.destroy = function () {\n view.detachEvents();\n view = undefined;\n };\n \n // Plugin hook\n app.pluginHook('addView', view);\n \n // Return view\n return view;\n };\n \n app.addView = function (selector, params) {\n return new View(selector, params);\n };\n \n"," /*======================================================\n ************ Navbars && Toolbars ************\n ======================================================*/\n // On Navbar Init Callback\n app.navbarInitCallback = function (view, pageContainer, navbar, navbarInnerContainer, url, position) {\n var _navbar = {\n container: navbar,\n innerContainer: navbarInnerContainer\n };\n var _page = {\n url: url,\n query: $.parseUrlQuery(url || ''),\n container: pageContainer,\n name: $(pageContainer).attr('data-page'),\n view: view,\n from: position\n };\n var eventData = {\n navbar: _navbar,\n page: _page\n };\n \n // Plugin hook\n app.pluginHook('navbarInit', _navbar, _page);\n \n // Navbar Init Callback\n $(navbarInnerContainer).trigger('navbarInit', eventData);\n };\n app.sizeNavbars = function (viewContainer) {\n var navbarInner = viewContainer ? $(viewContainer).find('.navbar .navbar-inner:not(.cached)') : $('.navbar .navbar-inner:not(.cached)');\n navbarInner.each(function () {\n var n = $(this);\n if (n.hasClass('cached')) return;\n var left = app.rtl ? n.find('.right') : n.find('.left'),\n right = app.rtl ? n.find('.left') : n.find('.right'),\n center = n.find('.center'),\n subnavbar = n.find('.subnavbar'),\n noLeft = left.length === 0,\n noRight = right.length === 0,\n leftWidth = noLeft ? 0 : left.outerWidth(true),\n rightWidth = noRight ? 0 : right.outerWidth(true),\n centerWidth = center.outerWidth(true),\n navbarWidth = n[0].offsetWidth - parseInt(n.css('padding-left'), 10) - parseInt(n.css('padding-right'), 10),\n onLeft = n.hasClass('navbar-on-left'),\n currLeft, diff;\n \n if (noRight) {\n currLeft = navbarWidth - centerWidth;\n }\n if (noLeft) {\n currLeft = 0;\n }\n if (!noLeft && !noRight) {\n currLeft = (navbarWidth - rightWidth - centerWidth + leftWidth) / 2;\n }\n var requiredLeft = (navbarWidth - centerWidth) / 2;\n if (navbarWidth - leftWidth - rightWidth > centerWidth) {\n if (requiredLeft < leftWidth) {\n requiredLeft = leftWidth;\n }\n if (requiredLeft + centerWidth > navbarWidth - rightWidth) {\n requiredLeft = navbarWidth - rightWidth - centerWidth;\n }\n diff = requiredLeft - currLeft;\n }\n else {\n diff = 0;\n }\n // RTL inverter\n var inverter = app.rtl ? -1 : 1;\n \n // Center left\n var centerLeft = diff;\n if (app.rtl && noLeft && noRight && center.length > 0) centerLeft = -centerLeft;\n center.css({left: centerLeft + 'px'});\n \n if (center.hasClass('sliding')) {\n center[0].f7NavbarLeftOffset = -(currLeft + diff) * inverter;\n center[0].f7NavbarRightOffset = (navbarWidth - currLeft - diff - centerWidth) * inverter;\n if (onLeft) center.transform('translate3d(' + center[0].f7NavbarLeftOffset + 'px, 0, 0)');\n }\n if (!noLeft && left.hasClass('sliding')) {\n if (app.rtl) {\n left[0].f7NavbarLeftOffset = -(navbarWidth - left.outerWidth()) / 2 * inverter;\n left[0].f7NavbarRightOffset = leftWidth * inverter;\n }\n else {\n left[0].f7NavbarLeftOffset = -leftWidth;\n left[0].f7NavbarRightOffset = (navbarWidth - left.outerWidth()) / 2;\n }\n if (onLeft) left.transform('translate3d(' + left[0].f7NavbarLeftOffset + 'px, 0, 0)');\n }\n if (!noRight && right.hasClass('sliding')) {\n if (app.rtl) {\n right[0].f7NavbarLeftOffset = -rightWidth * inverter;\n right[0].f7NavbarRightOffset = (navbarWidth - right.outerWidth()) / 2 * inverter;\n }\n else {\n right[0].f7NavbarLeftOffset = -(navbarWidth - right.outerWidth()) / 2;\n right[0].f7NavbarRightOffset = rightWidth;\n }\n if (onLeft) right.transform('translate3d(' + right[0].f7NavbarLeftOffset + 'px, 0, 0)');\n }\n if (subnavbar.length && subnavbar.hasClass('sliding')) {\n subnavbar[0].f7NavbarLeftOffset = app.rtl ? subnavbar[0].offsetWidth : -subnavbar[0].offsetWidth;\n subnavbar[0].f7NavbarRightOffset = -subnavbar[0].f7NavbarLeftOffset;\n }\n \n });\n };\n app.hideNavbar = function (navbarContainer) {\n $(navbarContainer).addClass('navbar-hidden');\n return true;\n };\n app.showNavbar = function (navbarContainer) {\n var navbar = $(navbarContainer);\n navbar.addClass('navbar-hiding').removeClass('navbar-hidden').transitionEnd(function () {\n navbar.removeClass('navbar-hiding');\n });\n return true;\n };\n app.hideToolbar = function (toolbarContainer) {\n $(toolbarContainer).addClass('toolbar-hidden');\n return true;\n };\n app.showToolbar = function (toolbarContainer) {\n var toolbar = $(toolbarContainer);\n toolbar.addClass('toolbar-hiding').removeClass('toolbar-hidden').transitionEnd(function () {\n toolbar.removeClass('toolbar-hiding');\n });\n };\n \n"," /*======================================================\n ************ Searchbar ************\n ======================================================*/\n app.initSearchbar = function (pageContainer) {\n pageContainer = $(pageContainer);\n var searchbar = pageContainer.hasClass('searchbar') ? pageContainer : pageContainer.find('.searchbar');\n if (searchbar.length === 0) return;\n if (!pageContainer.hasClass('page')) pageContainer = searchbar.parents('.page').eq(0);\n var searchbarOverlay = pageContainer.hasClass('page') ? pageContainer.find('.searchbar-overlay') : $('.searchbar-overlay');\n var input = searchbar.find('input[type=\"search\"]');\n var clear = searchbar.find('.searchbar-clear');\n var cancel = searchbar.find('.searchbar-cancel');\n var searchList = $(searchbar.attr('data-search-list'));\n var isVirtualList = searchList.hasClass('virtual-list');\n var virtualList;\n var searchIn = searchbar.attr('data-search-in');\n var searchBy = searchbar.attr('data-search-by');\n var found = searchbar.attr('data-searchbar-found');\n if (!found) {\n found = pageContainer.find('.searchbar-found');\n if (found.length === 0) found = $('.searchbar-found');\n }\n else {\n found = $(found);\n }\n var notFound = searchbar.attr('data-searchbar-not-found');\n if (!notFound) {\n notFound = pageContainer.find('.searchbar-not-found');\n if (notFound.length === 0) notFound = $('.searchbar-not-found');\n }\n else {\n notFound = $(notFound);\n }\n \n // Cancel button\n var cancelMarginProp = app.rtl ? 'margin-left' : 'margin-right';\n if (cancel.length > 0) {\n cancel.show();\n cancel.css(cancelMarginProp, -cancel[0].offsetWidth + 'px');\n }\n \n \n // Handlers\n function disableSearchbar() {\n input.val('').trigger('change');\n searchbar.removeClass('searchbar-active searchbar-not-empty');\n if (cancel.length > 0) cancel.css(cancelMarginProp, -cancel[0].offsetWidth + 'px');\n \n if (searchList) searchbarOverlay.removeClass('searchbar-overlay-active');\n if (app.device.ios) {\n setTimeout(function () {\n input.blur();\n searchList.trigger('disableSearch');\n }, 400);\n }\n else {\n input.blur();\n searchList.trigger('disableSearch');\n }\n }\n \n // Activate\n function enableSearchbar() {\n if (app.device.ios) {\n setTimeout(function () {\n if (searchList && !searchbar.hasClass('searchbar-active')) searchbarOverlay.addClass('searchbar-overlay-active');\n searchbar.addClass('searchbar-active');\n if (cancel.length > 0) cancel.css(cancelMarginProp, '0px');\n searchList.trigger('enableSearch');\n \n }, 400);\n }\n else {\n if (searchList && !searchbar.hasClass('searchbar-active')) searchbarOverlay.addClass('searchbar-overlay-active');\n searchbar.addClass('searchbar-active');\n if (cancel.length > 0) cancel.css(cancelMarginProp, '0px');\n searchList.trigger('enableSearch');\n }\n }\n \n // Clear\n function clearSearchbar() {\n input.val('').trigger('change').focus();\n searchList.trigger('clearSearch');\n }\n \n // Change\n function searchValue() {\n setTimeout(function () {\n var value = input.val().trim();\n if (value.length === 0) {\n searchbar.removeClass('searchbar-not-empty');\n if (searchList && searchbar.hasClass('searchbar-active')) searchbarOverlay.addClass('searchbar-overlay-active');\n }\n else {\n searchbar.addClass('searchbar-not-empty');\n if (searchList && searchbar.hasClass('searchbar-active')) searchbarOverlay.removeClass('searchbar-overlay-active');\n }\n if (searchList.length > 0 && (searchIn || isVirtualList)) search(value);\n }, 0);\n }\n \n //Prevent submit\n function preventSubmit(e) {\n e.preventDefault();\n }\n \n function attachEvents(destroy) {\n var method = destroy ? 'off' : 'on';\n searchbar[method]('submit', preventSubmit);\n cancel[method]('click', disableSearchbar);\n searchbarOverlay[method]('click', disableSearchbar);\n input[method]('focus', enableSearchbar);\n input[method]('change keydown keypress keyup', searchValue);\n clear[method]('click', clearSearchbar);\n }\n function detachEvents() {\n attachEvents(true);\n }\n searchbar[0].f7DestroySearchbar = detachEvents;\n \n // Attach events\n attachEvents();\n \n // Search\n var previousQuery;\n function search(query) {\n if (query.trim() === previousQuery) return;\n previousQuery = query.trim();\n var values = query.trim().toLowerCase().split(' ');\n var foundItems = [];\n if (isVirtualList) {\n virtualList = searchList[0].f7VirtualList;\n if (query.trim() === '') {\n virtualList.resetFilter();\n notFound.hide();\n found.show();\n return;\n }\n if (virtualList.params.searchAll) {\n foundItems = virtualList.params.searchAll(query, virtualList.items) || [];\n }\n else if (virtualList.params.searchByItem) {\n for (var i = 0; i < virtualList.items.length; i++) {\n if(virtualList.params.searchByItem(query, i, virtualList.params.items[i])) {\n foundItems.push(i);\n }\n }\n }\n }\n else {\n searchIn = searchbar.attr('data-search-in');\n searchList.find('li').removeClass('hidden-by-searchbar').each(function (index, el) {\n el = $(el);\n var compareWithEl = el.find(searchIn);\n if (compareWithEl.length === 0) return;\n var compareWith;\n compareWith = compareWithEl.text().trim().toLowerCase();\n var wordsMatch = 0;\n for (var i = 0; i < values.length; i++) {\n if (compareWith.indexOf(values[i]) >= 0) wordsMatch++;\n }\n if (wordsMatch !== values.length) {\n el.addClass('hidden-by-searchbar');\n }\n else {\n foundItems.push(el[0]);\n }\n });\n \n if (app.params.searchbarHideDividers) {\n searchList.find('.item-divider, .list-group-title').each(function () {\n var title = $(this);\n var nextElements = title.nextAll('li');\n var hide = true;\n for (var i = 0; i < nextElements.length; i++) {\n var nextEl = $(nextElements[i]);\n if (nextEl.hasClass('list-group-title') || nextEl.hasClass('item-divider')) break;\n if (!nextEl.hasClass('hidden-by-searchbar')) {\n hide = false;\n }\n }\n if (hide) title.addClass('hidden-by-searchbar');\n else title.removeClass('hidden-by-searchbar');\n });\n }\n if (app.params.searchbarHideGroups) {\n searchList.find('.list-group').each(function () {\n var group = $(this);\n var notHidden = group.find('li:not(.hidden-by-searchbar)');\n if (notHidden.length === 0) {\n group.addClass('hidden-by-searchbar');\n }\n else {\n group.removeClass('hidden-by-searchbar');\n }\n });\n }\n }\n searchList.trigger('search', {query: query, foundItems: foundItems});\n if (foundItems.length === 0) {\n notFound.show();\n found.hide();\n }\n else {\n notFound.hide();\n found.show();\n }\n if (isVirtualList) {\n virtualList.filterItems(foundItems);\n }\n }\n \n // Destroy on page remove\n function pageBeforeRemove() {\n detachEvents();\n pageContainer.off('pageBeforeRemove', pageBeforeRemove);\n }\n if (pageContainer.hasClass('page')) {\n pageContainer.on('pageBeforeRemove', pageBeforeRemove);\n }\n \n };\n app.destroySearchbar = function (pageContainer) {\n pageContainer = $(pageContainer);\n var searchbar = pageContainer.hasClass('searchbar') ? pageContainer : pageContainer.find('.searchbar');\n if (searchbar.length === 0) return;\n if (searchbar[0].f7DestroySearchbar) searchbar[0].f7DestroySearchbar();\n };\n \n"," /*======================================================\n ************ Messagebar ************\n ======================================================*/\n app.initMessagebar = function (pageContainer) {\n pageContainer = $(pageContainer);\n var messagebar = pageContainer.hasClass('messagebar') ? pageContainer : pageContainer.find('.messagebar');\n if (messagebar.length === 0) return;\n var textarea = messagebar.find('textarea');\n var pageContent = messagebar.parents('.page').find('.page-content');\n var pageContentInitialPadding = parseInt(pageContent.css('padding-bottom'));\n var initialBarHeight = messagebar[0].offsetHeight;\n var initialAreaHeight = textarea[0].offsetHeight;\n \n //Prevent submit\n function preventSubmit(e) {\n e.preventDefault();\n }\n \n // Resize textarea\n function sizeTextarea() {\n // Reset\n textarea.css({'height': ''});\n \n var height = textarea[0].offsetHeight;\n var diff = height - textarea[0].clientHeight;\n var scrollHeight = textarea[0].scrollHeight;\n var addExtra = parseInt((messagebar.attr('data-keyboard-height') || 0), 10);\n // Update\n if (scrollHeight + diff > height) {\n var newAreaHeight = scrollHeight + diff;\n var newBarHeight = initialBarHeight + (newAreaHeight - initialAreaHeight);\n var maxBarHeight = messagebar.attr('data-max-height') || messagebar.parents('.view')[0].offsetHeight - 88;\n if (newBarHeight > maxBarHeight) {\n newBarHeight = parseInt(maxBarHeight, 10);\n newAreaHeight = newBarHeight - initialBarHeight + initialAreaHeight;\n }\n textarea.css('height', newAreaHeight + 'px');\n messagebar.css('height', newBarHeight + 'px');\n if (pageContent.length > 0) {\n pageContent.css('padding-bottom', newBarHeight + addExtra + 'px');\n pageContent.scrollTop(pageContent[0].scrollHeight - pageContent[0].offsetHeight);\n }\n }\n else {\n if (pageContent.length > 0) {\n messagebar.css({'height': ''});\n pageContent.css({'padding-bottom': addExtra ? pageContentInitialPadding + addExtra + 'px' : ''});\n }\n }\n }\n var to;\n function handleKey(e) {\n clearTimeout(to);\n to = setTimeout(function () {\n sizeTextarea();\n }, 0);\n \n }\n \n function attachEvents(destroy) {\n var method = destroy ? 'off' : 'on';\n messagebar[method]('submit', preventSubmit);\n textarea[method]('change keydown keypress keyup paste cut', handleKey);\n }\n function detachEvents() {\n attachEvents(true);\n }\n \n messagebar[0].f7DestroyMessagebar = detachEvents;\n \n // Attach events\n attachEvents();\n \n // Destroy on page remove\n function pageBeforeRemove() {\n detachEvents();\n pageContainer.off('pageBeforeRemove', pageBeforeRemove);\n }\n if (pageContainer.hasClass('page')) {\n pageContainer.on('pageBeforeRemove', pageBeforeRemove);\n }\n };\n app.destroyMessagebar = function (pageContainer) {\n pageContainer = $(pageContainer);\n var messagebar = pageContainer.hasClass('messagebar') ? pageContainer : pageContainer.find('.messagebar');\n if (messagebar.length === 0) return;\n if (messagebar[0].f7DestroyMessagebar) messagebar[0].f7DestroyMessagebar();\n };\n"," /*======================================================\n ************ XHR ************\n ======================================================*/\n // XHR Caching\n app.cache = [];\n app.removeFromCache = function (url) {\n var index = false;\n for (var i = 0; i < app.cache.length; i++) {\n if (app.cache[i].url === url) index = i;\n }\n if (index !== false) app.cache.splice(index, 1);\n };\n \n // XHR\n app.xhr = false;\n app.get = function (url, view, ignoreCache, callback) {\n // should we ignore get params or not\n var _url = url;\n if (app.params.cacheIgnoreGetParameters && url.indexOf('?') >= 0) {\n _url = url.split('?')[0];\n }\n if (app.params.cache && !ignoreCache && url.indexOf('nocache') < 0 && app.params.cacheIgnore.indexOf(_url) < 0) {\n // Check is the url cached\n for (var i = 0; i < app.cache.length; i++) {\n if (app.cache[i].url === _url) {\n // Check expiration\n if ((new Date()).getTime() - app.cache[i].time < app.params.cacheDuration) {\n // Load from cache\n callback(app.cache[i].content);\n return false;\n }\n }\n }\n }\n \n app.xhr = $.ajax({\n url: url,\n method: 'GET',\n beforeSend: app.params.onAjaxStart,\n complete: function (xhr) {\n if (xhr.status === 200 || xhr.status === 0) {\n if (app.params.cache && !ignoreCache) {\n app.removeFromCache(_url);\n app.cache.push({\n url: _url,\n time: (new Date()).getTime(),\n content: xhr.responseText\n });\n }\n callback(xhr.responseText, false);\n }\n else {\n callback(xhr.responseText, true);\n }\n if (app.params.onAjaxComplete) app.params.onAjaxComplete(xhr);\n },\n error: function (xhr) {\n callback(xhr.responseText, true);\n if (app.params.onAjaxError) app.params.onAjaxError(xhr);\n }\n });\n if (view) view.xhr = app.xhr;\n \n return app.xhr;\n };\n \n"," /*======================================================\n ************ Pages ************\n ======================================================*/\n // Page Callbacks API\n app.pageCallbacks = {};\n \n app.onPage = function (callbackName, pageName, callback) {\n if (pageName && pageName.split(' ').length > 1) {\n var pageNames = pageName.split(' ');\n var returnCallbacks = [];\n for (var i = 0; i < pageNames.length; i++) {\n returnCallbacks.push(app.onPage(callbackName, pageNames[i], callback));\n }\n returnCallbacks.remove = function () {\n for (var i = 0; i < returnCallbacks.length; i++) {\n returnCallbacks[i].remove();\n }\n };\n returnCallbacks.trigger = function () {\n for (var i = 0; i < returnCallbacks.length; i++) {\n returnCallbacks[i].trigger();\n }\n };\n return returnCallbacks;\n }\n var callbacks = app.pageCallbacks[callbackName][pageName];\n if (!callbacks) {\n callbacks = app.pageCallbacks[callbackName][pageName] = [];\n }\n app.pageCallbacks[callbackName][pageName].push(callback);\n return {\n remove: function () {\n var removeIndex;\n for (var i = 0; i < callbacks.length; i++) {\n if (callbacks[i].toString() === callback.toString()) {\n removeIndex = i;\n }\n }\n if (typeof removeIndex !== 'undefined') callbacks.splice(removeIndex, 1);\n },\n trigger: callback\n };\n };\n \n //Create callbacks methods dynamically\n function createPageCallback(callbackName) {\n var capitalized = callbackName.replace(/^./, function (match) {\n return match.toUpperCase();\n });\n app['onPage' + capitalized] = function (pageName, callback) {\n return app.onPage(callbackName, pageName, callback);\n };\n }\n \n var pageCallbacksNames = ('beforeInit init reinit beforeAnimation afterAnimation back afterBack beforeRemove').split(' ');\n for (var i = 0; i < pageCallbacksNames.length; i++) {\n app.pageCallbacks[pageCallbacksNames[i]] = {};\n createPageCallback(pageCallbacksNames[i]);\n }\n \n app.triggerPageCallbacks = function (callbackName, pageName, pageData) {\n var allPagesCallbacks = app.pageCallbacks[callbackName]['*'];\n if (allPagesCallbacks) {\n for (var j = 0; j < allPagesCallbacks.length; j++) {\n allPagesCallbacks[j](pageData);\n }\n }\n var callbacks = app.pageCallbacks[callbackName][pageName];\n if (!callbacks || callbacks.length === 0) return;\n for (var i = 0; i < callbacks.length; i++) {\n callbacks[i](pageData);\n }\n };\n \n // On Page Init Callback\n app.pageInitCallback = function (view, params) {\n var pageContainer = params.pageContainer;\n if (pageContainer.f7PageInitialized && !view.params.domCache) return;\n \n // Page Data\n var pageData = {\n container: pageContainer,\n url: params.url,\n query: params.query || $.parseUrlQuery(params.url || ''),\n name: $(pageContainer).attr('data-page'),\n view: view,\n from: params.position,\n context: params.context,\n navbarInnerContainer: params.navbarInnerContainer,\n fromPage: params.fromPage\n };\n \n if (pageContainer.f7PageInitialized && view.params.domCache) {\n // Reinit Page\n app.reinitPage(pageContainer);\n \n // Callbacks\n app.pluginHook('pageReinit', pageData);\n if (app.params.onPageReinit) app.params.onPageBeforeInit(app, pageData);\n app.triggerPageCallbacks('reinit', pageData.name, pageData);\n $(pageData.container).trigger('pageReinit', {page: pageData});\n return;\n }\n pageContainer.f7PageInitialized = true;\n \n // Store pagedata in page\n pageContainer.f7PageData = pageData;\n \n // Update View's activePage\n if (view && !params.preloadOnly) view.activePage = pageData;\n \n // Before Init Callbacks\n app.pluginHook('pageBeforeInit', pageData);\n if (app.params.onPageBeforeInit) app.params.onPageBeforeInit(app, pageData);\n app.triggerPageCallbacks('beforeInit', pageData.name, pageData);\n $(pageData.container).trigger('pageBeforeInit', {page: pageData});\n \n // Init page\n app.initPage(pageContainer);\n \n // Init Callback\n app.pluginHook('pageInit', pageData);\n if (app.params.onPageInit) app.params.onPageInit(app, pageData);\n app.triggerPageCallbacks('init', pageData.name, pageData);\n $(pageData.container).trigger('pageInit', {page: pageData});\n };\n app.pageRemoveCallback = function (view, pageContainer, position) {\n var pageContext;\n if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;\n // Page Data\n var pageData = {\n container: pageContainer,\n name: $(pageContainer).attr('data-page'),\n view: view,\n url: pageContainer.f7PageData && pageContainer.f7PageData.url,\n query: pageContainer.f7PageData && pageContainer.f7PageData.query,\n navbarInnerContainer: pageContainer.f7PageData && pageContainer.f7PageData.navbarInnerContainer,\n from: position,\n context: pageContext\n };\n // Before Init Callback\n app.pluginHook('pageBeforeRemove', pageData);\n if (app.params.onPageBeforeRemove) app.params.onPageBeforeRemove(app, pageData);\n app.triggerPageCallbacks('beforeRemove', pageData.name, pageData);\n $(pageData.container).trigger('pageBeforeRemove', {page: pageData});\n };\n app.pageBackCallbacks = function (callback, view, params) {\n // Page Data\n var pageContainer = params.pageContainer;\n var pageContext;\n if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;\n \n var pageData = {\n container: pageContainer,\n name: $(pageContainer).attr('data-page'),\n url: pageContainer.f7PageData && pageContainer.f7PageData.url,\n query: pageContainer.f7PageData && pageContainer.f7PageData.query,\n view: view,\n from: params.position,\n context: pageContext,\n navbarInnerContainer: pageContainer.f7PageData && pageContainer.f7PageData.navbarInnerContainer,\n swipeBack: params.swipeBack\n };\n \n if (callback === 'after') {\n app.pluginHook('pageAfterBack', pageData);\n if (app.params.onPageAfterBack) app.params.onPageAfterBack(app, pageData);\n app.triggerPageCallbacks('afterBack', pageData.name, pageData);\n $(pageContainer).trigger('pageAfterBack', {page: pageData});\n \n }\n if (callback === 'before') {\n app.pluginHook('pageBack', pageData);\n if (app.params.onPageBack) app.params.onPageBack(app, pageData);\n app.triggerPageCallbacks('back', pageData.name, pageData);\n $(pageData.container).trigger('pageBack', {page: pageData});\n }\n };\n app.pageAnimCallbacks = function (callback, view, params) {\n var pageContainer = params.pageContainer;\n var pageContext;\n if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;\n // Page Data\n var pageData = {\n container: pageContainer,\n url: params.url,\n query: params.query || $.parseUrlQuery(params.url || ''),\n name: $(pageContainer).attr('data-page'),\n view: view,\n from: params.position,\n context: pageContext,\n swipeBack: params.swipeBack,\n navbarInnerContainer: pageContainer.f7PageData && pageContainer.f7PageData.navbarInnerContainer,\n fromPage: params.fromPage\n };\n var oldPage = params.oldPage,\n newPage = params.newPage;\n \n // Update page date\n pageContainer.f7PageData = pageData;\n \n if (callback === 'after') {\n app.pluginHook('pageAfterAnimation', pageData);\n if (app.params.onPageAfterAnimation) app.params.onPageAfterAnimation(app, pageData);\n app.triggerPageCallbacks('afterAnimation', pageData.name, pageData);\n $(pageData.container).trigger('pageAfterAnimation', {page: pageData});\n \n }\n if (callback === 'before') {\n // Add data-page on view\n $(view.container).attr('data-page', pageData.name);\n \n // Update View's activePage\n if (view) view.activePage = pageData;\n \n // Hide/show navbar dynamically\n if (newPage.hasClass('no-navbar') && !oldPage.hasClass('no-navbar')) {\n view.hideNavbar();\n }\n if (!newPage.hasClass('no-navbar') && (oldPage.hasClass('no-navbar') || oldPage.hasClass('no-navbar-by-scroll'))) {\n view.showNavbar();\n }\n // Hide/show navbar toolbar\n if (newPage.hasClass('no-toolbar') && !oldPage.hasClass('no-toolbar')) {\n view.hideToolbar();\n }\n if (!newPage.hasClass('no-toolbar') && (oldPage.hasClass('no-toolbar') || oldPage.hasClass('no-toolbar-by-scroll'))) {\n view.showToolbar();\n }\n // Hide/show tabbar\n var tabBar;\n if (newPage.hasClass('no-tabbar') && !oldPage.hasClass('no-tabbar')) {\n tabBar = $(view.container).find('.tabbar');\n if (tabBar.length === 0) tabBar = $(view.container).parents('.' + app.params.viewsClass).find('.tabbar');\n app.hideToolbar(tabBar);\n }\n if (!newPage.hasClass('no-tabbar') && (oldPage.hasClass('no-tabbar') || oldPage.hasClass('no-tabbar-by-scroll'))) {\n tabBar = $(view.container).find('.tabbar');\n if (tabBar.length === 0) tabBar = $(view.container).parents('.' + app.params.viewsClass).find('.tabbar');\n app.showToolbar(tabBar);\n }\n \n oldPage.removeClass('no-navbar-by-scroll no-toolbar-by-scroll');\n // Callbacks\n app.pluginHook('pageBeforeAnimation', pageData);\n if (app.params.onPageBeforeAnimation) app.params.onPageBeforeAnimation(app, pageData);\n app.triggerPageCallbacks('beforeAnimation', pageData.name, pageData);\n $(pageData.container).trigger('pageBeforeAnimation', {page: pageData});\n }\n };\n \n // Init Page Events and Manipulations\n app.initPage = function (pageContainer) {\n pageContainer = $(pageContainer);\n // Size navbars on page load\n if (app.sizeNavbars) app.sizeNavbars(pageContainer.parents('.' + app.params.viewClass)[0]);\n // Init messages\n if (app.initMessages) app.initMessages(pageContainer);\n // Init forms storage\n if (app.initFormsStorage) app.initFormsStorage(pageContainer);\n // Init smart select\n if (app.initSmartSelects) app.initSmartSelects(pageContainer);\n // Init slider\n if (app.initSlider) app.initSlider(pageContainer);\n if (app.initSwiper) app.initSwiper(pageContainer);\n // Init pull to refres\n if (app.initPullToRefresh) app.initPullToRefresh(pageContainer);\n // Init infinite scroll\n if (app.initInfiniteScroll) app.initInfiniteScroll(pageContainer);\n // Init searchbar\n if (app.initSearchbar) app.initSearchbar(pageContainer);\n // Init message bar\n if (app.initMessagebar) app.initMessagebar(pageContainer);\n // Init scroll toolbars\n if (app.initScrollToolbars) app.initScrollToolbars(pageContainer);\n // Init scroll toolbars\n if (app.initImagesLazyLoad) app.initImagesLazyLoad(pageContainer);\n };\n app.reinitPage = function (pageContainer) {\n pageContainer = $(pageContainer);\n // Size navbars on page reinit\n if (app.sizeNavbars) app.sizeNavbars(pageContainer.parents('.' + app.params.viewClass)[0]);\n // Reinit slider\n if (app.reinitSlider) app.reinitSlider(pageContainer);\n if (app.reinitSwiper) app.reinitSwiper(pageContainer);\n // Reinit lazy load\n if (app.reinitLazyLoad) app.reinitLazyLoad(pageContainer);\n };\n app.initPageWithCallback = function (pageContainer) {\n pageContainer = $(pageContainer);\n var viewContainer = pageContainer.parents('.' + app.params.viewClass);\n if (viewContainer.length === 0) return;\n var view = viewContainer[0].f7View || false;\n var url = view && view.url ? view.url : false;\n if (viewContainer) {\n viewContainer.attr('data-page', pageContainer.attr('data-page') || undefined);\n }\n app.pageInitCallback(view, {pageContainer: pageContainer[0], url: url, position: 'center'});\n };\n"," /*======================================================\n ************ Navigation / Router ************\n ======================================================*/\n app.router = {\n // Temporary DOM Element\n temporaryDom: document.createElement('div'),\n \n // Find page or navbar in passed container which are related to View\n findElement: function (selector, container, view, notCached) {\n container = $(container);\n if (notCached) selector = selector + ':not(.cached)';\n var found = container.find(selector);\n if (found.length > 1) {\n if (typeof view.selector === 'string') {\n // Search in related view\n found = container.find(view.selector + ' ' + selector);\n }\n if (found.length > 1) {\n // Search in main view\n found = container.find('.' + app.params.viewMainClass + ' ' + selector);\n }\n }\n if (found.length === 1) return found;\n else {\n // Try to find non cached\n if (!notCached) found = app.router.findElement(selector, container, view, true);\n if (found && found.length === 1) return found;\n else return undefined;\n }\n },\n \n // Set pages classess for animationEnd\n animatePages: function (leftPage, rightPage, direction, view) {\n // Loading new page\n var removeClasses = 'page-on-center page-on-right page-on-left';\n if (direction === 'to-left') {\n leftPage.removeClass(removeClasses).addClass('page-from-center-to-left');\n rightPage.removeClass(removeClasses).addClass('page-from-right-to-center');\n }\n // Go back\n if (direction === 'to-right') {\n leftPage.removeClass(removeClasses).addClass('page-from-left-to-center');\n rightPage.removeClass(removeClasses).addClass('page-from-center-to-right');\n \n }\n },\n \n // Prepare navbar before animarion\n prepareNavbar: function (newNavbarInner, oldNavbarInner, newNavbarPosition) {\n $(newNavbarInner).find('.sliding').each(function () {\n var sliding = $(this);\n var slidingOffset = newNavbarPosition === 'right' ? this.f7NavbarRightOffset : this.f7NavbarLeftOffset;\n \n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(' + (-slidingOffset) + 'px,0,0)');\n }\n if (newNavbarPosition === 'left' && sliding.hasClass('center') && $(oldNavbarInner).find('.left .back .icon ~ span').length > 0) {\n slidingOffset += $(oldNavbarInner).find('.left .back span')[0].offsetLeft;\n }\n }\n \n sliding.transform('translate3d(' + slidingOffset + 'px,0,0)');\n });\n },\n \n // Set navbars classess for animation\n animateNavbars: function (leftNavbarInner, rightNavbarInner, direction, view) {\n // Loading new page\n var removeClasses = 'navbar-on-right navbar-on-center navbar-on-left';\n if (direction === 'to-left') {\n rightNavbarInner.removeClass(removeClasses).addClass('navbar-from-right-to-center');\n rightNavbarInner.find('.sliding').each(function () {\n var sliding = $(this);\n sliding.transform('translate3d(0px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(0px,0,0)');\n }\n }\n });\n \n leftNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-left');\n leftNavbarInner.find('.sliding').each(function () {\n var sliding = $(this);\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('center') && rightNavbarInner.find('.sliding.left .back .icon').length > 0) {\n this.f7NavbarLeftOffset += rightNavbarInner.find('.sliding.left .back span')[0].offsetLeft;\n }\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(' + (-this.f7NavbarLeftOffset) + 'px,0,0)');\n }\n }\n sliding.transform('translate3d(' + (this.f7NavbarLeftOffset) + 'px,0,0)');\n });\n }\n // Go back\n if (direction === 'to-right') {\n leftNavbarInner.removeClass(removeClasses).addClass('navbar-from-left-to-center');\n leftNavbarInner.find('.sliding').each(function () {\n var sliding = $(this);\n sliding.transform('translate3d(0px,0,0)');\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(0px,0,0)');\n }\n }\n });\n \n rightNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-right');\n rightNavbarInner.find('.sliding').each(function () {\n var sliding = $(this);\n if (app.params.animateNavBackIcon) {\n if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {\n sliding.find('.back .icon').transform('translate3d(' + (-this.f7NavbarRightOffset) + 'px,0,0)');\n }\n }\n sliding.transform('translate3d(' + (this.f7NavbarRightOffset) + 'px,0,0)');\n });\n }\n },\n \n preprocess: function(content, url, next) {\n // Plugin hook\n app.pluginHook('routerPreprocess', content, url, next);\n \n // Preprocess by plugin\n content = app.pluginProcess('preprocess', content);\n \n if (app.params.preprocess) {\n content = app.params.preprocess(content, url, next);\n if (typeof content !== 'undefined') {\n next(content);\n }\n } else {\n next(content);\n }\n },\n \n template7Render: function (view, options) {\n var url = options.url,\n content = options.content, //initial content\n t7_rendered_content = options.content, // will be rendered using Template7\n context = options.context, // Context data for Template7\n contextName = options.contextName, \n template = options.template, // Template 7 compiled template\n pageName = options.pageName;\n \n var t7_ctx, t7_template;\n if (typeof content === 'string') {\n if (url) {\n if (app.template7Cache[url]) t7_template = t7.cache[url];\n else {\n t7_template = t7.compile(content);\n t7.cache[url] = t7_template;\n }\n }\n else t7_template = t7.compile(content);\n }\n else if (template) {\n t7_template = template;\n }\n \n if (context) t7_ctx = context;\n else {\n if (contextName) {\n if (contextName.indexOf('.') >= 0) {\n var _ctx_path = contextName.split('.');\n var _ctx = t7.data[_ctx_path[0]];\n for (var i = 1; i < _ctx_path.length; i++) {\n if (_ctx_path[i]) _ctx = _ctx[_ctx_path[i]];\n }\n t7_ctx = _ctx;\n }\n else t7_ctx = t7.data[contextName];\n }\n if (!t7_ctx && url) {\n t7_ctx = t7.data['url:' + url];\n }\n if (!t7_ctx && typeof content === 'string' && !template) {\n //try to find by page name in content\n var pageNameMatch = content.match(/(data-page=[\"'][^\"^']*[\"'])/);\n if (pageNameMatch) {\n var page = pageNameMatch[0].split('data-page=')[1].replace(/['\"]/g, '');\n if (page) t7_ctx = t7.data['page:' + page];\n }\n }\n if (!t7_ctx && template && t7.templates) {\n // Try to find matched template name in t7.templates\n for (var templateName in t7.templates) {\n if (t7.templates[templateName] === template) t7_ctx = t7.data[templateName];\n }\n }\n if (!t7_ctx) t7_ctx = {};\n }\n \n if (t7_template && t7_ctx) {\n if (typeof t7_ctx === 'function') t7_ctx = t7_ctx();\n if (url) {\n // Extend data with URL query\n var query = $.parseUrlQuery(url);\n t7_ctx.url_query = {};\n for (var key in query) {\n t7_ctx.url_query[key] = query[key];\n }\n }\n t7_rendered_content = t7_template(t7_ctx);\n }\n \n return {content: t7_rendered_content, context: t7_ctx};\n }\n };\n \n \n app.router._load = function (view, options) {\n options = options || {};\n \n var url = options.url,\n content = options.content, //initial content\n t7_rendered = {content: options.content},\n template = options.template, // Template 7 compiled template\n pageName = options.pageName,\n viewContainer = $(view.container), \n pagesContainer = $(view.pagesContainer),\n animatePages = options.animatePages,\n newPage, oldPage, pagesInView, i, oldNavbarInner, newNavbarInner, navbar, dynamicNavbar, reloadPosition,\n isDynamicPage = typeof url === 'undefined' && content || template, \n pushState = options.pushState;\n \n if (typeof animatePages === 'undefined') animatePages = view.params.animatePages;\n \n // Plugin hook\n app.pluginHook('routerLoad', view, options);\n \n // Render with Template7\n if (app.params.template7Pages && typeof content === 'string' || template) {\n t7_rendered = app.router.template7Render(view, options);\n if (t7_rendered.content && !content) {\n content = t7_rendered.content;\n }\n }\n \n app.router.temporaryDom.innerHTML = '';\n \n // Parse DOM\n if (!pageName) {\n if (url || (typeof content === 'string')) {\n app.router.temporaryDom.innerHTML = t7_rendered.content;\n } else {\n if ('length' in content && content.length > 1) {\n for (var ci = 0; ci < content.length; ci++) {\n $(app.router.temporaryDom).append(content[ci]);\n }\n } else {\n $(app.router.temporaryDom).append(content);\n }\n }\n }\n \n // Reload position\n reloadPosition = options.reload && (options.reloadPrevious ? 'left' : 'center');\n \n // Find new page\n if (pageName) newPage = pagesContainer.find('.page[data-page=\"' + pageName + '\"]');\n else {\n newPage = app.router.findElement('.page', app.router.temporaryDom, view);\n }\n \n // If page not found exit\n if (!newPage || newPage.length === 0 || (pageName && view.activePage && view.activePage.name === pageName)) {\n view.allowPageChange = true;\n return;\n }\n \n newPage.addClass(options.reload ? 'page-on-' + reloadPosition : 'page-on-right');\n \n // Find old page (should be the last one) and remove older pages\n pagesInView = pagesContainer.children('.page:not(.cached)');\n \n if (options.reload && options.reloadPrevious && pagesInView.length === 1) {\n view.allowPageChange = true;\n return;\n }\n \n if (options.reload) {\n oldPage = pagesInView.eq(pagesInView.length - 1);\n }\n else {\n if (pagesInView.length > 1) {\n for (i = 0; i < pagesInView.length - 2; i++) {\n if (!view.params.domCache) {\n app.pageRemoveCallback(view, pagesInView[i], 'left');\n $(pagesInView[i]).remove();\n }\n else {\n $(pagesInView[i]).addClass('cached');\n }\n }\n if (!view.params.domCache) {\n app.pageRemoveCallback(view, pagesInView[i], 'left');\n $(pagesInView[i]).remove();\n }\n else {\n $(pagesInView[i]).addClass('cached');\n }\n }\n oldPage = pagesContainer.children('.page:not(.cached)');\n }\n if(view.params.domCache) newPage.removeClass('cached');\n \n // Dynamic navbar\n if (view.params.dynamicNavbar) {\n dynamicNavbar = true;\n // Find navbar\n if (pageName) {\n newNavbarInner = viewContainer.find('.navbar-inner[data-page=\"' + pageName + '\"]');\n }\n else {\n newNavbarInner = app.router.findElement('.navbar-inner', app.router.temporaryDom, view); \n }\n if (!newNavbarInner || newNavbarInner.length === 0) {\n dynamicNavbar = false;\n }\n navbar = viewContainer.find('.navbar');\n if (options.reload) {\n oldNavbarInner = navbar.find('.navbar-inner:not(.cached):last-child');\n }\n else {\n oldNavbarInner = navbar.find('.navbar-inner:not(.cached)'); \n \n if (oldNavbarInner.length > 0) {\n for (i = 0; i < oldNavbarInner.length - 1; i++) {\n if (!view.params.domCache)\n $(oldNavbarInner[i]).remove();\n else\n $(oldNavbarInner[i]).addClass('cached');\n }\n if (!newNavbarInner && oldNavbarInner.length === 1) {\n if (!view.params.domCache)\n $(oldNavbarInner[0]).remove();\n else\n $(oldNavbarInner[0]).addClass('cached');\n }\n oldNavbarInner = navbar.find('.navbar-inner:not(.cached)');\n }\n }\n }\n if (dynamicNavbar) {\n newNavbarInner.addClass(options.reload ? 'navbar-on-' + reloadPosition : 'navbar-on-right');\n if(view.params.domCache) newNavbarInner.removeClass('cached');\n newPage[0].f7RelatedNavbar = newNavbarInner[0];\n newNavbarInner[0].f7RelatedPage = newPage[0];\n }\n \n // save content areas into view's cache\n if (!url) {\n var newPageName = pageName || newPage.attr('data-page');\n if (isDynamicPage) url = '#' + app.params.dynamicPageUrl.replace(/{{name}}/g, newPageName).replace(/{{index}}/g, view.history.length - (options.reload ? 1 : 0));\n else url = '#' + newPageName;\n if (!view.params.domCache) {\n view.contentCache[url] = content;\n }\n if (view.params.domCache && pageName) {\n view.pagesCache[url] = pageName;\n }\n }\n \n // Push State\n if (app.params.pushState && !options.reloadPrevious && view.main) {\n if (typeof pushState === 'undefined') pushState = true;\n var pushStateRoot = app.params.pushStateRoot || '';\n var method = options.reload ? 'replaceState' : 'pushState';\n if (pushState) {\n if (!isDynamicPage && !pageName) {\n history[method]({url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);\n }\n else if (isDynamicPage && content) {\n history[method]({content: content, url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);\n }\n else if (pageName) {\n history[method]({pageName: pageName, url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);\n }\n }\n }\n \n // Update View history\n view.url = url;\n if (options.reload) {\n var lastUrl = view.history[view.history.length - (options.reloadPrevious ? 2 : 1)];\n if (lastUrl && lastUrl.indexOf('#') === 0 && lastUrl in view.contentCache && lastUrl !== url) {\n view.contentCache[lastUrl] = null;\n delete view.contentCache[lastUrl];\n }\n view.history[view.history.length - (options.reloadPrevious ? 2 : 1)] = url;\n }\n else {\n view.history.push(url);\n }\n \n // Unique history\n var historyBecameUnique = false;\n if (view.params.uniqueHistory) {\n var _history = view.history;\n var _url = url;\n if (view.params.uniqueHistoryIgnoreGetParameters) {\n _history = [];\n _url = url.split('?')[0];\n for (i = 0; i < view.history.length; i++) {\n _history.push(view.history[i].split('?')[0]);\n }\n }\n \n if (_history.indexOf(_url) !== _history.lastIndexOf(_url)) {\n view.history = view.history.slice(0, _history.indexOf(_url));\n view.history.push(url);\n historyBecameUnique = true;\n }\n }\n // Dom manipulations\n if (options.reloadPrevious) {\n oldPage = oldPage.prev('.page');\n newPage.insertBefore(oldPage);\n if (dynamicNavbar) {\n oldNavbarInner = oldNavbarInner.prev('.navbar-inner');\n newNavbarInner.insertAfter(oldNavbarInner);\n }\n }\n else {\n pagesContainer.append(newPage[0]);\n if (dynamicNavbar) navbar.append(newNavbarInner[0]);\n }\n // Remove Old Page And Navbar\n if (options.reload) {\n if (view.params.domCache && view.initialPages.indexOf(oldPage[0]) >= 0) {\n oldPage.addClass('cached');\n if (dynamicNavbar) oldNavbarInner.addClass('cached');\n }\n else {\n app.pageRemoveCallback(view, oldPage[0], reloadPosition);\n oldPage.remove();\n if (dynamicNavbar) oldNavbarInner.remove();\n }\n }\n \n // Page Init Events\n app.pageInitCallback(view, {\n pageContainer: newPage[0], \n url: url, \n position: options.reload ? reloadPosition : 'right', \n navbarInnerContainer: dynamicNavbar ? newNavbarInner[0] : undefined, \n context: t7_rendered.context,\n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n \n // Navbar init event\n if (dynamicNavbar) {\n app.navbarInitCallback(view, newPage[0], navbar[0], newNavbarInner[0], url, options.reload ? reloadPosition : 'right');\n }\n \n if (options.reload) {\n view.allowPageChange = true;\n if (historyBecameUnique) view.refreshPreviousPage();\n return;\n }\n \n if (dynamicNavbar && animatePages) {\n app.router.prepareNavbar(newNavbarInner, oldNavbarInner, 'right');\n }\n // Force reLayout\n var clientLeft = newPage[0].clientLeft;\n \n // Before Anim Callback\n app.pageAnimCallbacks('before', view, {\n pageContainer: newPage[0], \n url: url, \n position: 'right', \n oldPage: oldPage, \n newPage: newPage, \n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n \n function afterAnimation() {\n view.allowPageChange = true;\n newPage.removeClass('page-from-right-to-center page-on-right').addClass('page-on-center');\n oldPage.removeClass('page-from-center-to-left page-on-center').addClass('page-on-left');\n if (dynamicNavbar) {\n newNavbarInner.removeClass('navbar-from-right-to-center navbar-on-left navbar-on-right').addClass('navbar-on-center');\n oldNavbarInner.removeClass('navbar-from-center-to-left navbar-on-center').addClass('navbar-on-left');\n }\n app.pageAnimCallbacks('after', view, {\n pageContainer: newPage[0], \n url: url, \n position: 'right', \n oldPage: oldPage, \n newPage: newPage, \n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n if (app.params.pushState) app.pushStateClearQueue();\n if (!(view.params.swipeBackPage || view.params.preloadPreviousPage)) {\n if (view.params.domCache) {\n oldPage.addClass('cached');\n oldNavbarInner.addClass('cached');\n }\n else {\n if (!(url.indexOf('#') === 0 && newPage.attr('data-page').indexOf('smart-select-') === 0)) {\n app.pageRemoveCallback(view, oldPage[0], 'left');\n oldPage.remove();\n if (dynamicNavbar) oldNavbarInner.remove(); \n }\n }\n }\n if (view.params.uniqueHistory && historyBecameUnique) {\n view.refreshPreviousPage();\n }\n }\n if (animatePages) {\n // Set pages before animation\n app.router.animatePages(oldPage, newPage, 'to-left', view);\n \n // Dynamic navbar animation\n if (dynamicNavbar) {\n setTimeout(function() {\n app.router.animateNavbars(oldNavbarInner, newNavbarInner, 'to-left', view);\n }, 0);\n }\n newPage.animationEnd(function (e) {\n afterAnimation();\n });\n }\n else {\n newNavbarInner.find('.sliding, .sliding .back .icon').transform('');\n afterAnimation();\n }\n \n };\n \n app.router.load = function (view, options) {\n options = options || {};\n var url = options.url;\n var content = options.content;\n var pageName = options.pageName;\n if (pageName) {\n if (pageName.indexOf('?') > 0) {\n options.query = $.parseUrlQuery(pageName);\n options.pageName = pageName = pageName.split('?')[0];\n }\n }\n var template = options.template;\n if (view.params.reloadPages === true) options.reload = true;\n \n if (!view.allowPageChange) return false;\n if (url && view.url === url && !options.reload && !view.params.allowDuplicateUrls) return false;\n view.allowPageChange = false;\n if (app.xhr && view.xhr && view.xhr === app.xhr) {\n app.xhr.abort();\n app.xhr = false;\n }\n function proceed(content) {\n app.router.preprocess(content, url, function (content) {\n options.content = content;\n app.router._load(view, options);\n });\n }\n if (content || pageName) {\n proceed(content);\n return;\n }\n else if (template) {\n app.router._load(view, options);\n return;\n }\n \n if (!options.url || options.url === '#') {\n view.allowPageChange = true;\n return;\n }\n app.get(options.url, view, options.ignoreCache, function (content, error) {\n if (error) {\n view.allowPageChange = true;\n return;\n }\n proceed(content);\n });\n };\n \n app.router._back = function (view, options) {\n options = options || {};\n var url = options.url,\n content = options.content, \n t7_rendered = {content: options.content}, // will be rendered using Template7\n template = options.template, // Template 7 compiled template\n animatePages = options.animatePages, \n preloadOnly = options.preloadOnly, \n pushState = options.pushState, \n ignoreCache = options.ignoreCache,\n force = options.force,\n pageName = options.pageName;\n \n var viewContainer = $(view.container),\n pagesContainer = $(view.pagesContainer),\n pagesInView = pagesContainer.children('.page:not(.cached)'),\n oldPage, newPage, oldNavbarInner, newNavbarInner, navbar, navbarInners, dynamicNavbar, manipulateDom = true;\n \n if (typeof animatePages === 'undefined') animatePages = view.params.animatePages;\n \n app.pluginHook('routerBack', view, options);\n \n // Render with Template7\n if (app.params.template7Pages && typeof content === 'string' || template) {\n t7_rendered = app.router.template7Render(view, options);\n if (t7_rendered.content && !content) {\n content = t7_rendered.content;\n }\n }\n \n // Push state\n if (app.params.pushState) {\n if (typeof pushState === 'undefined') pushState = true;\n if (!preloadOnly && history.state && pushState) {\n history.back();\n }\n }\n \n // Animation\n function afterAnimation() {\n app.pageBackCallbacks('after', view, {\n pageContainer: oldPage[0], \n url: url, \n position: 'center', \n oldPage: oldPage, \n newPage: newPage, \n });\n app.pageAnimCallbacks('after', view, {\n pageContainer: newPage[0], \n url: url, \n position: 'left', \n oldPage: oldPage, \n newPage: newPage, \n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n app.router.afterBack(view, oldPage[0], newPage[0]);\n }\n function animateBack() {\n // Page before animation callback\n app.pageBackCallbacks('before', view, {\n pageContainer: oldPage[0], \n url: url, \n position: 'center', \n oldPage: oldPage, \n newPage: newPage, \n });\n app.pageAnimCallbacks('before', view, {\n pageContainer: newPage[0], \n url: url, \n position: 'left', \n oldPage: oldPage, \n newPage: newPage, \n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData\n });\n \n if (animatePages) {\n // Set pages before animation\n app.router.animatePages(newPage, oldPage, 'to-right', view);\n \n // Dynamic navbar animation\n if (dynamicNavbar) {\n setTimeout(function () {\n app.router.animateNavbars(newNavbarInner, oldNavbarInner, 'to-right', view);\n }, 0);\n }\n \n newPage.animationEnd(function () {\n afterAnimation();\n });\n }\n else {\n newNavbarInner.find('.sliding, .sliding .back .icon').transform('');\n afterAnimation();\n }\n }\n \n function parseNewPage() {\n app.router.temporaryDom.innerHTML = '';\n // Parse DOM\n if (url || (typeof content === 'string')) {\n app.router.temporaryDom.innerHTML = t7_rendered.content;\n } else {\n if ('length' in content && content.length > 1) {\n for (var ci = 0; ci < content.length; ci++) {\n $(app.router.temporaryDom).append(content[ci]);\n }\n } else {\n $(app.router.temporaryDom).append(content);\n }\n }\n newPage = app.router.findElement('.page', app.router.temporaryDom, view);\n \n if (view.params.dynamicNavbar) {\n // Find navbar\n newNavbarInner = app.router.findElement('.navbar-inner', app.router.temporaryDom, view);\n }\n }\n function setPages() {\n // If pages not found or there are still more than one, exit\n if (!newPage || newPage.length === 0) {\n view.allowPageChange = true;\n return;\n }\n if (view.params.dynamicNavbar && typeof dynamicNavbar === 'undefined') {\n if (!newNavbarInner || newNavbarInner.length === 0) {\n dynamicNavbar = false;\n }\n else {\n dynamicNavbar = true;\n }\n }\n \n newPage.addClass('page-on-left').removeClass('cached');\n if (dynamicNavbar) {\n navbar = viewContainer.find('.navbar');\n navbarInners = viewContainer.find('.navbar-inner:not(.cached)');\n newNavbarInner.addClass('navbar-on-left').removeClass('cached');\n }\n // Remove/hide previous page in force mode\n if (force) {\n var pageToRemove, navbarToRemove;\n pageToRemove = $(pagesInView[pagesInView.length - 2]);\n \n if (dynamicNavbar) navbarToRemove = $(pageToRemove[0] && pageToRemove[0].f7RelatedNavbar || navbarInners[navbarInners.length - 2]);\n if (view.params.domCache && view.initialPages.indexOf(pageToRemove[0]) >= 0) {\n if (pageToRemove.length && pageToRemove[0] !== newPage[0]) pageToRemove.addClass('cached');\n if (dynamicNavbar && navbarToRemove.length && navbarToRemove[0] !== newNavbarInner[0]) {\n navbarToRemove.addClass('cached');\n }\n }\n else {\n if (pageToRemove.length) pageToRemove.remove();\n if (dynamicNavbar && navbarToRemove.length) {\n navbarToRemove.remove();\n } \n }\n pagesInView = pagesContainer.children('.page:not(.cached)');\n if (dynamicNavbar) {\n navbarInners = viewContainer.find('.navbar-inner:not(.cached)');\n }\n if (view.history.indexOf(url) >= 0) {\n view.history = view.history.slice(0, view.history.indexOf(url) + 2);\n }\n else {\n if (view.history[[view.history.length - 2]]) {\n view.history[view.history.length - 2] = url; \n }\n else {\n view.history.unshift(url);\n }\n }\n }\n \n oldPage = $(pagesInView[pagesInView.length - 1]);\n if (view.params.domCache) {\n if (oldPage[0] === newPage[0]) {\n oldPage = pagesContainer.children('.page.page-on-center');\n if (oldPage.length === 0 && view.activePage) oldPage = $(view.activePage.container);\n }\n }\n \n if (dynamicNavbar && !oldNavbarInner) {\n oldNavbarInner = $(navbarInners[navbarInners.length - 1]);\n if (view.params.domCache) {\n if (oldNavbarInner[0] === newNavbarInner[0]) {\n oldNavbarInner = navbar.children('.navbar-inner.navbar-on-center:not(.cached)');\n }\n if (oldNavbarInner.length === 0) {\n oldNavbarInner = navbar.children('.navbar-inner[data-page=\"'+oldPage.attr('data-page')+'\"]');\n }\n }\n if (oldNavbarInner.length === 0 || newNavbarInner[0] === oldNavbarInner[0]) dynamicNavbar = false;\n }\n \n if (dynamicNavbar) {\n if (manipulateDom) newNavbarInner.insertBefore(oldNavbarInner);\n newNavbarInner[0].f7RelatedPage = newPage[0];\n newPage[0].f7RelatedNavbar = newNavbarInner[0];\n }\n if (manipulateDom) newPage.insertBefore(oldPage);\n \n // Page Init Events\n app.pageInitCallback(view, {\n pageContainer: newPage[0], \n url: url, \n position: 'left', \n navbarInnerContainer: dynamicNavbar ? newNavbarInner[0] : undefined, \n context: t7_rendered.context,\n query: options.query,\n fromPage: oldPage && oldPage.length && oldPage[0].f7PageData,\n preloadOnly: preloadOnly\n });\n if (dynamicNavbar) {\n app.navbarInitCallback(view, newPage[0], navbar[0], newNavbarInner[0], url, 'right');\n }\n \n if (dynamicNavbar && newNavbarInner.hasClass('navbar-on-left') && animatePages) {\n app.router.prepareNavbar(newNavbarInner, oldNavbarInner, 'left');\n }\n \n if (preloadOnly) {\n view.allowPageChange = true;\n return;\n }\n \n // Update View's URL\n view.url = url;\n \n // Force reLayout\n var clientLeft = newPage[0].clientLeft;\n \n animateBack();\n return;\n }\n \n // Simple go back when we have pages on left\n if (pagesInView.length > 1 && !force) {\n // Exit if only preloadOnly\n if (preloadOnly) {\n view.allowPageChange = true;\n return;\n }\n // Update View's URL\n view.url = view.history[view.history.length - 2];\n url = view.url;\n \n // Define old and new pages\n newPage = $(pagesInView[pagesInView.length - 2]);\n oldPage = $(pagesInView[pagesInView.length - 1]);\n \n // Dynamic navbar\n if (view.params.dynamicNavbar) {\n dynamicNavbar = true;\n // Find navbar\n navbarInners = viewContainer.find('.navbar-inner:not(.cached)');\n newNavbarInner = $(navbarInners[0]);\n oldNavbarInner = $(navbarInners[1]);\n if (newNavbarInner.length === 0 || oldNavbarInner.length === 0 || oldNavbarInner[0] === newNavbarInner[0]) {\n dynamicNavbar = false;\n }\n }\n manipulateDom = false;\n setPages();\n return;\n }\n \n if (!force) {\n // Go back when there is no pages on left\n if (!preloadOnly) {\n view.url = view.history[view.history.length - 2];\n url = view.url;\n }\n \n if (content) {\n parseNewPage();\n setPages();\n return;\n }\n else if (pageName) {\n // Get dom cached pages\n newPage = $(viewContainer).find('.page[data-page=\"' + pageName + '\"]');\n if (view.params.dynamicNavbar) {\n newNavbarInner = $(viewContainer).find('.navbar-inner[data-page=\"' + pageName + '\"]');\n }\n setPages();\n return;\n }\n else {\n view.allowPageChange = true;\n return;\n }\n }\n else {\n if (url && url === view.url || pageName && view.activePage && view.activePage.name === pageName) {\n view.allowPageChange = true;\n return;\n }\n // Go back with force url\n if (content) {\n parseNewPage();\n setPages();\n return;\n }\n else if (pageName && view.params.domCache) {\n if (pageName) url = '#' + pageName;\n \n newPage = $(viewContainer).find('.page[data-page=\"' + pageName + '\"]');\n if (newPage[0].f7PageData && newPage[0].f7PageData.url) {\n url = newPage[0].f7PageData.url;\n }\n if (view.params.dynamicNavbar) {\n newNavbarInner = $(viewContainer).find('.navbar-inner[data-page=\"' + pageName + '\"]');\n if (newNavbarInner.length === 0) {\n newNavbarInner = $(newPage[0].f7RelatedNavbar);\n }\n }\n setPages();\n return;\n }\n else {\n view.allowPageChange = true;\n return;\n }\n }\n \n };\n app.router.back = function (view, options) {\n options = options || {};\n var url = options.url;\n var content = options.content;\n var pageName = options.pageName;\n if (pageName) {\n if (pageName.indexOf('?') > 0) {\n options.query = $.parseUrlQuery(pageName);\n options.pageName = pageName = pageName.split('?')[0];\n }\n }\n var force = options.force;\n if (!view.allowPageChange) return false;\n view.allowPageChange = false;\n if (app.xhr && view.xhr && view.xhr === app.xhr) {\n app.xhr.abort();\n app.xhr = false;\n }\n var pagesInView = $(view.pagesContainer).find('.page:not(.cached)');\n \n function proceed(content) {\n app.router.preprocess(content, url, function (content) {\n options.content = content;\n app.router._back(view, options);\n });\n }\n if (pagesInView.length > 1 && !force) {\n // Simple go back to previos page in view\n app.router._back(view, options);\n return;\n }\n if (!force) {\n url = options.url = view.history[view.history.length - 2];\n if (!url) {\n view.allowPageChange = true;\n return;\n }\n if (url.indexOf('#') === 0 && view.contentCache[url]) {\n proceed(view.contentCache[url]);\n return;\n }\n else if (url.indexOf('#') === 0 && view.params.domCache) {\n if (!pageName) options.pageName = url.split('#')[1];\n proceed();\n return;\n }\n else if (url.indexOf('#') !== 0) {\n // Load ajax page\n app.get(options.url, view, options.ignoreCache, function (content, error) {\n if (error) {\n view.allowPageChange = true;\n return;\n }\n proceed(content);\n });\n return;\n }\n }\n else {\n // Go back with force url\n if (!url && content) {\n proceed(content);\n return;\n }\n else if (!url && pageName) {\n if (pageName) url = '#' + pageName;\n proceed();\n return;\n }\n else if (url) {\n app.get(options.url, view, options.ignoreCache, function (content, error) {\n if (error) {\n view.allowPageChange = true;\n return;\n }\n proceed(content);\n });\n return;\n }\n }\n view.allowPageChange = true;\n return;\n };\n \n app.router.afterBack = function (view, oldPage, newPage) {\n // Remove old page and set classes on new one\n oldPage = $(oldPage);\n newPage = $(newPage);\n \n if (view.params.domCache && view.initialPages.indexOf(oldPage[0]) >= 0) {\n oldPage.removeClass('page-from-center-to-right').addClass('cached');\n }\n else {\n oldPage.remove();\n app.pageRemoveCallback(view, oldPage[0], 'right');\n }\n \n newPage.removeClass('page-from-left-to-center page-on-left').addClass('page-on-center');\n view.allowPageChange = true;\n \n // Update View's History\n var previousURL = view.history.pop();\n \n var newNavbar;\n \n // Updated dynamic navbar\n if (view.params.dynamicNavbar) {\n var inners = $(view.container).find('.navbar-inner:not(.cached)');\n var oldNavbar = $(oldPage[0].f7RelatedNavbar || inners[1]);\n if (view.params.domCache && view.initialNavbars.indexOf(oldNavbar[0]) >= 0) {\n oldNavbar.removeClass('navbar-from-center-to-right').addClass('cached');\n }\n else {\n oldNavbar.remove();\n }\n newNavbar = $(inners[0]).removeClass('navbar-on-left navbar-from-left-to-center').addClass('navbar-on-center');\n }\n \n // Remove pages in dom cache\n if (view.params.domCache) {\n $(view.container).find('.page.cached').each(function () {\n var page = $(this);\n var index = page.index();\n var pageUrl = page[0].f7PageData && page[0].f7PageData.url;\n if (pageUrl && view.history.indexOf(pageUrl) < 0 && view.initialPages.indexOf(this) < 0) {\n if (page[0].f7RelatedNavbar) $(page[0].f7RelatedNavbar).remove();\n page.remove();\n }\n });\n }\n \n // Check previous page is content based only and remove it from content cache\n if (!view.params.domCache && previousURL && previousURL.indexOf('#') > -1 && (previousURL in view.contentCache)) {\n view.contentCache[previousURL] = null;\n delete view.contentCache[previousURL];\n }\n \n if (app.params.pushState) app.pushStateClearQueue();\n \n // Preload previous page\n if (view.params.preloadPreviousPage) {\n if (view.params.domCache && view.history.length > 1) {\n var preloadUrl = view.history[view.history.length - 2];\n var previousPage;\n var previousNavbar;\n if (preloadUrl && view.pagesCache[preloadUrl]) {\n // Load by page name\n previousPage = $(view.container).find('.page[data-page=\"' + view.pagesCache[preloadUrl] + '\"]');\n previousPage.insertBefore(newPage);\n if (newNavbar) {\n previousNavbar = $(view.container).find('.navbar-inner[data-page=\"' + view.pagesCache[preloadUrl] + '\"]');\n previousNavbar.insertBefore(newNavbar);\n if(!previousNavbar || previousNavbar.length === 0) previousNavbar = newNavbar.prev('.navbar-inner.cached');\n }\n }\n else {\n // Just load previous page\n previousPage = newPage.prev('.page.cached');\n if (newNavbar) previousNavbar = newNavbar.prev('.navbar-inner.cached');\n }\n if (previousPage && previousPage.length > 0) previousPage.removeClass('cached page-on-right page-on-center').addClass('page-on-left');\n if (previousNavbar && previousNavbar.length > 0) previousNavbar.removeClass('cached navbar-on-right navbar-on-center').addClass('navbar-on-left');\n }\n else {\n app.router.back(view, {preloadOnly: true}); \n }\n }\n };\n \n"," /*======================================================\n ************ Modals ************\n ======================================================*/\n var _modalTemplateTempDiv = document.createElement('div');\n app.modalStack = [];\n app.modalStackClearQueue = function () {\n if (app.modalStack.length) {\n (app.modalStack.shift())();\n }\n };\n app.modal = function (params) {\n params = params || {};\n var modalHTML = '';\n if (app.params.modalTemplate) {\n if (!app._compiledTemplates.modal) app._compiledTemplates.modal = t7.compile(app.params.modalTemplate);\n modalHTML = app._compiledTemplates.modal(params);\n }\n else {\n var buttonsHTML = '';\n if (params.buttons && params.buttons.length > 0) {\n for (var i = 0; i < params.buttons.length; i++) {\n buttonsHTML += '<span class=\"modal-button' + (params.buttons[i].bold ? ' modal-button-bold' : '') + '\">' + params.buttons[i].text + '</span>';\n }\n }\n var titleHTML = params.title ? '<div class=\"modal-title\">' + params.title + '</div>' : '';\n var textHTML = params.text ? '<div class=\"modal-text\">' + params.text + '</div>' : '';\n var afterTextHTML = params.afterText ? params.afterText : '';\n var noButtons = !params.buttons || params.buttons.length === 0 ? 'modal-no-buttons' : '';\n var verticalButtons = params.verticalButtons ? 'modal-buttons-vertical' : '';\n modalHTML = '<div class=\"modal ' + noButtons + '\"><div class=\"modal-inner\">' + (titleHTML + textHTML + afterTextHTML) + '</div><div class=\"modal-buttons ' + verticalButtons + '\">' + buttonsHTML + '</div></div>';\n }\n \n _modalTemplateTempDiv.innerHTML = modalHTML;\n \n var modal = $(_modalTemplateTempDiv).children();\n \n $('body').append(modal[0]);\n \n // Add events on buttons\n modal.find('.modal-button').each(function (index, el) {\n $(el).on('click', function (e) {\n if (params.buttons[index].close !== false) app.closeModal(modal);\n if (params.buttons[index].onClick) params.buttons[index].onClick(modal, e);\n if (params.onClick) params.onClick(modal, index);\n });\n });\n app.openModal(modal);\n return modal[0];\n };\n app.alert = function (text, title, callbackOk) {\n if (typeof title === 'function') {\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n buttons: [ {text: app.params.modalButtonOk, bold: true, onClick: callbackOk} ]\n });\n };\n app.confirm = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n buttons: [\n {text: app.params.modalButtonCancel, onClick: callbackCancel},\n {text: app.params.modalButtonOk, bold: true, onClick: callbackOk}\n ]\n });\n };\n app.prompt = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n afterText: '<input type=\"text\" class=\"modal-text-input\">',\n buttons: [\n {\n text: app.params.modalButtonCancel\n },\n {\n text: app.params.modalButtonOk,\n bold: true\n }\n ],\n onClick: function (modal, index) {\n if (index === 0 && callbackCancel) callbackCancel($(modal).find('.modal-text-input').val());\n if (index === 1 && callbackOk) callbackOk($(modal).find('.modal-text-input').val());\n }\n });\n };\n app.modalLogin = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n afterText: '<input type=\"text\" name=\"modal-username\" placeholder=\"' + app.params.modalUsernamePlaceholder + '\" class=\"modal-text-input modal-text-input-double\"><input type=\"password\" name=\"modal-password\" placeholder=\"' + app.params.modalPasswordPlaceholder + '\" class=\"modal-text-input modal-text-input-double\">',\n buttons: [\n {\n text: app.params.modalButtonCancel\n },\n {\n text: app.params.modalButtonOk,\n bold: true\n }\n ],\n onClick: function (modal, index) {\n var username = $(modal).find('.modal-text-input[name=\"modal-username\"]').val();\n var password = $(modal).find('.modal-text-input[name=\"modal-password\"]').val();\n if (index === 0 && callbackCancel) callbackCancel(username, password);\n if (index === 1 && callbackOk) callbackOk(username, password);\n }\n });\n };\n app.modalPassword = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return app.modal({\n text: text || '',\n title: typeof title === 'undefined' ? app.params.modalTitle : title,\n afterText: '<input type=\"password\" name=\"modal-password\" placeholder=\"' + app.params.modalPasswordPlaceholder + '\" class=\"modal-text-input\">',\n buttons: [\n {\n text: app.params.modalButtonCancel\n },\n {\n text: app.params.modalButtonOk,\n bold: true\n }\n ],\n onClick: function (modal, index) {\n var password = $(modal).find('.modal-text-input[name=\"modal-password\"]').val();\n if (index === 0 && callbackCancel) callbackCancel(password);\n if (index === 1 && callbackOk) callbackOk(password);\n }\n });\n };\n app.showPreloader = function (title) {\n return app.modal({\n title: title || app.params.modalPreloaderTitle,\n text: '<div class=\"preloader\"></div>'\n });\n };\n app.hidePreloader = function () {\n app.closeModal('.modal.modal-in');\n };\n app.showIndicator = function () {\n $('body').append('<div class=\"preloader-indicator-overlay\"></div><div class=\"preloader-indicator-modal\"><span class=\"preloader preloader-white\"></span></div>');\n };\n app.hideIndicator = function () {\n $('.preloader-indicator-overlay, .preloader-indicator-modal').remove();\n };\n // Action Sheet\n app.actions = function (target, params) {\n var toPopover = false, modal, groupSelector, buttonSelector;\n if (arguments.length === 1) {\n // Actions\n params = target;\n } \n else {\n // Popover\n if (app.device.ios) {\n if (app.device.ipad) toPopover = true;\n }\n else {\n if ($(window).width() >= 768) toPopover = true;\n }\n }\n params = params || [];\n \n if (params.length > 0 && !$.isArray(params[0])) {\n params = [params];\n }\n var modalHTML;\n if (toPopover) {\n var actionsPopoverTemplate = \n '<div class=\"popover actions-popover\">' +\n '<div class=\"popover-inner\">' +\n '{{#each this}}' +\n '<div class=\"list-block\">' +\n '<ul>' +\n '{{#each this}}' +\n '{{#if label}}' +\n '<li class=\"actions-popover-label {{#if color}}color-{{color}}{{/if}} {{#if bold}}actions-popover-bold{{/if}}\">{{text}}</li>' +\n '{{else}}' +\n '<li><a href=\"#\" class=\"item-link list-button {{#if color}}color-{{color}}{{/if}} {{#if bg}}bg-{{bg}}{{/if}} {{#if bold}}actions-popover-bold{{/if}}\">{{text}}</a></li>' +\n '{{/if}}' +\n '{{/each}}' +\n '</ul>' +\n '</div>' +\n '{{/each}}' +\n '</div>' +\n '</div>';\n if (!app._compiledTemplates.actionsPopover) {\n app._compiledTemplates.actionsPopover = t7.compile(actionsPopoverTemplate);\n }\n var popoverHTML = app._compiledTemplates.actionsPopover(params);\n modal = $(app.popover(popoverHTML, target, true));\n groupSelector = '.list-block ul';\n buttonSelector = '.list-button';\n }\n else {\n if (app.params.modalActionsTemplate) {\n if (!app._compiledTemplates.actions) app._compiledTemplates.actions = t7.compile(app.params.modalActionsTemplate);\n modalHTML = app._compiledTemplates.actions(params);\n }\n else {\n var buttonsHTML = '';\n for (var i = 0; i < params.length; i++) {\n for (var j = 0; j < params[i].length; j++) {\n if (j === 0) buttonsHTML += '<div class=\"actions-modal-group\">';\n var button = params[i][j];\n var buttonClass = button.label ? 'actions-modal-label' : 'actions-modal-button';\n if (button.bold) buttonClass += ' actions-modal-button-bold';\n if (button.color) buttonClass += ' color-' + button.color;\n if (button.bg) buttonClass += ' bg-' + button.bg;\n buttonsHTML += '<span class=\"' + buttonClass + '\">' + button.text + '</span>';\n if (j === params[i].length - 1) buttonsHTML += '</div>';\n }\n }\n modalHTML = '<div class=\"actions-modal\">' + buttonsHTML + '</div>';\n }\n _modalTemplateTempDiv.innerHTML = modalHTML;\n modal = $(_modalTemplateTempDiv).children();\n $('body').append(modal[0]);\n groupSelector = '.actions-modal-group';\n buttonSelector = '.actions-modal-button';\n }\n \n var groups = modal.find(groupSelector);\n groups.each(function (index, el) {\n var groupIndex = index;\n $(el).children().each(function (index, el) {\n var buttonIndex = index;\n var buttonParams = params[groupIndex][buttonIndex];\n var clickTarget;\n if (!toPopover && $(el).is(buttonSelector)) clickTarget = $(el);\n if (toPopover && $(el).find(buttonSelector).length > 0) clickTarget = $(el).find(buttonSelector);\n \n if (clickTarget) {\n clickTarget.on('click', function (e) {\n if (buttonParams.close !== false) app.closeModal(modal);\n if (buttonParams.onClick) buttonParams.onClick(modal, e);\n });\n }\n });\n });\n if (!toPopover) app.openModal(modal);\n return modal[0];\n };\n app.popover = function (modal, target, removeOnClose) {\n if (typeof removeOnClose === 'undefined') removeOnClose = true;\n if (typeof modal === 'string' && modal.indexOf('<') >= 0) {\n var _modal = document.createElement('div');\n _modal.innerHTML = modal.trim();\n if (_modal.childNodes.length > 0) {\n modal = _modal.childNodes[0];\n if (removeOnClose) modal.classList.add('remove-on-close');\n $('body').append(modal);\n }\n else return false; //nothing found\n }\n modal = $(modal);\n target = $(target);\n if (modal.length === 0 || target.length === 0) return false;\n if (modal.find('.popover-angle').length === 0) {\n modal.append('<div class=\"popover-angle\"></div>');\n }\n modal.show();\n \n function sizePopover() {\n modal.css({left: '', top: ''});\n var modalWidth = modal.width();\n var modalHeight = modal.height(); // 13 - height of angle\n var modalAngle = modal.find('.popover-angle');\n var modalAngleSize = modalAngle.width() / 2;\n var modalAngleLeft, modalAngleTop;\n modalAngle.removeClass('on-left on-right on-top on-bottom').css({left: '', top: ''});\n \n var targetWidth = target.outerWidth();\n var targetHeight = target.outerHeight();\n var targetOffset = target.offset();\n var targetParentPage = target.parents('.page');\n if (targetParentPage.length > 0) {\n targetOffset.top = targetOffset.top - targetParentPage[0].scrollTop;\n }\n \n var windowHeight = $(window).height();\n var windowWidth = $(window).width();\n \n var modalTop = 0;\n var modalLeft = 0;\n var diff = 0;\n // Top Position\n var modalPosition = 'top';\n \n if ((modalHeight + modalAngleSize) < targetOffset.top) {\n // On top\n modalTop = targetOffset.top - modalHeight - modalAngleSize;\n }\n else if ((modalHeight + modalAngleSize) < windowHeight - targetOffset.top - targetHeight) {\n // On bottom\n modalPosition = 'bottom';\n modalTop = targetOffset.top + targetHeight + modalAngleSize;\n }\n else {\n // On middle\n modalPosition = 'middle';\n modalTop = targetHeight / 2 + targetOffset.top - modalHeight / 2;\n diff = modalTop;\n if (modalTop < 0) {\n modalTop = 5;\n }\n else if (modalTop + modalHeight > windowHeight) {\n modalTop = windowHeight - modalHeight - 5;\n }\n diff = diff - modalTop;\n }\n // Horizontal Position\n if (modalPosition === 'top' || modalPosition === 'bottom') {\n modalLeft = targetWidth / 2 + targetOffset.left - modalWidth / 2;\n diff = modalLeft;\n if (modalLeft < 5) modalLeft = 5;\n if (modalLeft + modalWidth > windowWidth) modalLeft = windowWidth - modalWidth - 5;\n if (modalPosition === 'top') modalAngle.addClass('on-bottom');\n if (modalPosition === 'bottom') modalAngle.addClass('on-top');\n diff = diff - modalLeft;\n modalAngleLeft = (modalWidth / 2 - modalAngleSize + diff);\n modalAngleLeft = Math.max(Math.min(modalAngleLeft, modalWidth - modalAngleSize * 2 - 6), 6);\n modalAngle.css({left: modalAngleLeft + 'px'});\n }\n else if (modalPosition === 'middle') {\n modalLeft = targetOffset.left - modalWidth - modalAngleSize;\n modalAngle.addClass('on-right');\n if (modalLeft < 5) {\n modalLeft = targetOffset.left + targetWidth + modalAngleSize;\n modalAngle.removeClass('on-right').addClass('on-left');\n }\n if (modalLeft + modalWidth > windowWidth) {\n modalLeft = windowWidth - modalWidth - 5;\n modalAngle.removeClass('on-right').addClass('on-left');\n }\n modalAngleTop = (modalHeight / 2 - modalAngleSize + diff);\n modalAngleTop = Math.max(Math.min(modalAngleTop, modalHeight - modalAngleSize * 2 - 6), 6);\n modalAngle.css({top: modalAngleTop + 'px'});\n }\n \n // Apply Styles\n modal.css({top: modalTop + 'px', left: modalLeft + 'px'});\n }\n sizePopover();\n \n $(window).on('resize', sizePopover);\n modal.on('close', function () {\n $(window).off('resize', sizePopover);\n });\n \n if (modal.find('.' + app.params.viewClass).length > 0) {\n app.sizeNavbars(modal.find('.' + app.params.viewClass)[0]);\n }\n \n app.openModal(modal);\n return modal[0];\n };\n app.popup = function (modal, removeOnClose) {\n if (typeof removeOnClose === 'undefined') removeOnClose = true;\n if (typeof modal === 'string' && modal.indexOf('<') >= 0) {\n var _modal = document.createElement('div');\n _modal.innerHTML = modal.trim();\n if (_modal.childNodes.length > 0) {\n modal = _modal.childNodes[0];\n if (removeOnClose) modal.classList.add('remove-on-close');\n $('body').append(modal);\n }\n else return false; //nothing found\n }\n modal = $(modal);\n if (modal.length === 0) return false;\n modal.show();\n if (modal.find('.' + app.params.viewClass).length > 0) {\n app.sizeNavbars(modal.find('.' + app.params.viewClass)[0]);\n }\n app.openModal(modal);\n return modal[0];\n };\n app.pickerModal = function (pickerModal, removeOnClose) {\n if (typeof removeOnClose === 'undefined') removeOnClose = true;\n if (typeof pickerModal === 'string' && pickerModal.indexOf('<') >= 0) {\n pickerModal = $(pickerModal);\n if (pickerModal.length > 0) {\n if (removeOnClose) pickerModal.addClass('remove-on-close');\n $('body').append(pickerModal[0]);\n }\n else return false; //nothing found\n }\n pickerModal = $(pickerModal);\n if (pickerModal.length === 0) return false;\n pickerModal.show();\n app.openModal(pickerModal);\n return pickerModal[0];\n };\n app.loginScreen = function (modal) {\n if (!modal) modal = '.login-screen';\n modal = $(modal);\n if (modal.length === 0) return false;\n modal.show();\n if (modal.find('.' + app.params.viewClass).length > 0) {\n app.sizeNavbars(modal.find('.' + app.params.viewClass)[0]);\n }\n app.openModal(modal);\n return modal[0];\n };\n app.openModal = function (modal) {\n modal = $(modal);\n var isModal = modal.hasClass('modal');\n if ($('.modal.modal-in:not(.modal-out)').length && app.params.modalStack && isModal) {\n app.modalStack.push(function () {\n app.openModal(modal);\n });\n return;\n }\n var isPopover = modal.hasClass('popover');\n var isPopup = modal.hasClass('popup');\n var isLoginScreen = modal.hasClass('login-screen');\n var isPickerModal = modal.hasClass('picker-modal');\n if (isModal) {\n modal.show();\n modal.css({\n marginTop: - Math.round(modal.outerHeight() / 2) + 'px'\n });\n }\n \n var overlay;\n if (!isLoginScreen && !isPickerModal) {\n if ($('.modal-overlay').length === 0 && !isPopup) {\n $('body').append('<div class=\"modal-overlay\"></div>');\n }\n if ($('.popup-overlay').length === 0 && isPopup) {\n $('body').append('<div class=\"popup-overlay\"></div>');\n }\n overlay = isPopup ? $('.popup-overlay') : $('.modal-overlay');\n }\n \n //Make sure that styles are applied, trigger relayout;\n var clientLeft = modal[0].clientLeft;\n \n // Trugger open event\n modal.trigger('open');\n \n // Picker modal body class\n if (isPickerModal) {\n $('body').addClass('with-picker-modal');\n }\n \n // Classes for transition in\n if (!isLoginScreen && !isPickerModal) overlay.addClass('modal-overlay-visible');\n modal.removeClass('modal-out').addClass('modal-in').transitionEnd(function (e) {\n if (modal.hasClass('modal-out')) modal.trigger('closed');\n else modal.trigger('opened');\n });\n return true;\n };\n app.closeModal = function (modal) {\n modal = $(modal || '.modal-in');\n if (typeof modal !== 'undefined' && modal.length === 0) {\n return;\n }\n var isModal = modal.hasClass('modal');\n var isPopover = modal.hasClass('popover');\n var isPopup = modal.hasClass('popup');\n var isLoginScreen = modal.hasClass('login-screen');\n var isPickerModal = modal.hasClass('picker-modal');\n \n var removeOnClose = modal.hasClass('remove-on-close');\n \n var overlay = isPopup ? $('.popup-overlay') : $('.modal-overlay');\n if (isPopup){\n if (modal.length === $('.popup.modal-in').length) {\n overlay.removeClass('modal-overlay-visible'); \n } \n }\n else if (!isPickerModal) {\n overlay.removeClass('modal-overlay-visible');\n }\n \n modal.trigger('close');\n \n // Picker modal body class\n if (isPickerModal) {\n $('body').removeClass('with-picker-modal');\n $('body').addClass('picker-modal-closing');\n }\n \n if (!isPopover) {\n modal.removeClass('modal-in').addClass('modal-out').transitionEnd(function (e) {\n if (modal.hasClass('modal-out')) modal.trigger('closed');\n else modal.trigger('opened');\n \n if (isPickerModal) {\n $('body').removeClass('picker-modal-closing');\n }\n if (isPopup || isLoginScreen || isPickerModal) {\n modal.removeClass('modal-out').hide();\n if (removeOnClose && modal.length > 0) {\n modal.remove();\n }\n }\n else {\n modal.remove();\n }\n });\n if (isModal && app.params.modalStack) {\n app.modalStackClearQueue();\n }\n }\n else {\n modal.removeClass('modal-in modal-out').trigger('closed').hide();\n if (removeOnClose) {\n modal.remove();\n }\n }\n return true;\n };\n \n"," /*======================================================\n ************ Panels ************\n ======================================================*/\n app.allowPanelOpen = true;\n app.openPanel = function (panelPosition) {\n if (!app.allowPanelOpen) return false;\n var panel = $('.panel-' + panelPosition);\n if (panel.length === 0 || panel.hasClass('active')) return false;\n app.closePanel(); // Close if some panel is opened\n app.allowPanelOpen = false;\n var effect = panel.hasClass('panel-reveal') ? 'reveal' : 'cover';\n panel.css({display: 'block'}).addClass('active');\n panel.trigger('open');\n if (panel.find('.' + app.params.viewClass).length > 0) {\n if (app.sizeNavbars) app.sizeNavbars(panel.find('.' + app.params.viewClass)[0]);\n }\n \n // Trigger reLayout\n var clientLeft = panel[0].clientLeft;\n \n // Transition End;\n var transitionEndTarget = effect === 'reveal' ? $('.' + app.params.viewsClass) : panel;\n var openedTriggered = false;\n \n function panelTransitionEnd() {\n transitionEndTarget.transitionEnd(function (e) {\n if ($(e.target).is(transitionEndTarget)) {\n if (panel.hasClass('active')) {\n panel.trigger('opened');\n }\n else {\n panel.trigger('closed');\n }\n app.allowPanelOpen = true;\n }\n else panelTransitionEnd();\n });\n }\n panelTransitionEnd();\n \n $('body').addClass('with-panel-' + panelPosition + '-' + effect);\n return true;\n };\n app.closePanel = function () {\n var activePanel = $('.panel.active');\n if (activePanel.length === 0) return false;\n var effect = activePanel.hasClass('panel-reveal') ? 'reveal' : 'cover';\n var panelPosition = activePanel.hasClass('panel-left') ? 'left' : 'right';\n activePanel.removeClass('active');\n var transitionEndTarget = effect === 'reveal' ? $('.' + app.params.viewsClass) : activePanel;\n activePanel.trigger('close');\n app.allowPanelOpen = false;\n \n transitionEndTarget.transitionEnd(function () {\n if (activePanel.hasClass('active')) return;\n activePanel.css({display: ''});\n activePanel.trigger('closed');\n $('body').removeClass('panel-closing');\n app.allowPanelOpen = true;\n });\n \n $('body').addClass('panel-closing').removeClass('with-panel-' + panelPosition + '-' + effect);\n };\n /*======================================================\n ************ Swipe panels ************\n ======================================================*/\n app.initSwipePanels = function () {\n var panel, side;\n if (app.params.swipePanel) {\n panel = $('.panel.panel-' + app.params.swipePanel);\n side = app.params.swipePanel;\n if (panel.length === 0) return;\n }\n else {\n if (app.params.swipePanelOnlyClose) {\n if ($('.panel').length === 0) return;\n }\n else return;\n }\n \n var panelOverlay = $('.panel-overlay');\n var isTouched, isMoved, isScrolling, touchesStart = {}, touchStartTime, touchesDiff, translate, opened, panelWidth, effect, direction;\n var views = $('.' + app.params.viewsClass);\n \n function handleTouchStart(e) {\n if (!app.allowPanelOpen || (!app.params.swipePanel && !app.params.swipePanelOnlyClose) || isTouched) return;\n if ($('.modal-in, .photo-browser-in').length > 0) return;\n if (!(app.params.swipePanelCloseOpposite || app.params.swipePanelOnlyClose)) {\n if ($('.panel.active').length > 0 && !panel.hasClass('active')) return;\n }\n touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n if (app.params.swipePanelCloseOpposite || app.params.swipePanelOnlyClose) {\n if ($('.panel.active').length > 0) {\n side = $('.panel.active').hasClass('panel-left') ? 'left' : 'right';\n }\n else {\n if (app.params.swipePanelOnlyClose) return;\n side = app.params.swipePanel;\n }\n if (!side) return;\n }\n panel = $('.panel.panel-' + side);\n opened = panel.hasClass('active');\n if (app.params.swipePanelActiveArea && !opened) {\n if (side === 'left') {\n if (touchesStart.x > app.params.swipePanelActiveArea) return;\n }\n if (side === 'right') {\n if (touchesStart.x < window.innerWidth - app.params.swipePanelActiveArea) return;\n }\n }\n isMoved = false;\n isTouched = true;\n isScrolling = undefined;\n \n touchStartTime = (new Date()).getTime();\n direction = undefined;\n }\n function handleTouchMove(e) {\n if (!isTouched) return;\n if (e.f7PreventPanelSwipe) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));\n }\n if (isScrolling) {\n isTouched = false;\n return;\n }\n if (!direction) {\n if (pageX > touchesStart.x) {\n direction = 'to-right';\n }\n else {\n direction = 'to-left';\n }\n \n if (\n side === 'left' &&\n (\n direction === 'to-left' && !panel.hasClass('active')\n ) ||\n side === 'right' &&\n (\n direction === 'to-right' && !panel.hasClass('active')\n )\n )\n {\n isTouched = false;\n return;\n }\n }\n \n if (app.params.swipePanelNoFollow) {\n var timeDiff = (new Date()).getTime() - touchStartTime;\n if (timeDiff < 300) {\n if (direction === 'to-left') {\n if (side === 'right') app.openPanel(side);\n if (side === 'left' && panel.hasClass('active')) app.closePanel();\n }\n if (direction === 'to-right') {\n if (side === 'left') app.openPanel(side);\n if (side === 'right' && panel.hasClass('active')) app.closePanel();\n }\n }\n isTouched = false;\n isMoved = false;\n return;\n }\n \n if (!isMoved) {\n effect = panel.hasClass('panel-cover') ? 'cover' : 'reveal';\n if (!opened) {\n panel.show();\n panelOverlay.show();\n }\n panelWidth = panel[0].offsetWidth;\n panel.transition(0);\n if (panel.find('.' + app.params.viewClass).length > 0) {\n if (app.sizeNavbars) app.sizeNavbars(panel.find('.' + app.params.viewClass)[0]);\n }\n }\n \n isMoved = true;\n \n e.preventDefault();\n var threshold = opened ? 0 : -app.params.swipePanelThreshold;\n if (side === 'right') threshold = -threshold;\n \n touchesDiff = pageX - touchesStart.x + threshold;\n \n if (side === 'right') {\n translate = touchesDiff - (opened ? panelWidth : 0);\n if (translate > 0) translate = 0;\n if (translate < -panelWidth) {\n translate = -panelWidth;\n }\n }\n else {\n translate = touchesDiff + (opened ? panelWidth : 0);\n if (translate < 0) translate = 0;\n if (translate > panelWidth) {\n translate = panelWidth;\n }\n }\n if (effect === 'reveal') {\n views.transform('translate3d(' + translate + 'px,0,0)').transition(0);\n panelOverlay.transform('translate3d(' + translate + 'px,0,0)');\n app.pluginHook('swipePanelSetTransform', views[0], panel[0], Math.abs(translate / panelWidth));\n }\n else {\n panel.transform('translate3d(' + translate + 'px,0,0)').transition(0);\n app.pluginHook('swipePanelSetTransform', views[0], panel[0], Math.abs(translate / panelWidth));\n }\n }\n function handleTouchEnd(e) {\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n isTouched = false;\n isMoved = false;\n var timeDiff = (new Date()).getTime() - touchStartTime;\n var action;\n var edge = (translate === 0 || Math.abs(translate) === panelWidth);\n \n if (!opened) {\n if (translate === 0) {\n action = 'reset';\n }\n else if (\n timeDiff < 300 && Math.abs(translate) > 0 ||\n timeDiff >= 300 && (Math.abs(translate) >= panelWidth / 2)\n ) {\n action = 'swap';\n }\n else {\n action = 'reset';\n }\n }\n else {\n if (translate === -panelWidth) {\n action = 'reset';\n }\n else if (\n timeDiff < 300 && Math.abs(translate) >= 0 ||\n timeDiff >= 300 && (Math.abs(translate) <= panelWidth / 2)\n ) {\n if (side === 'left' && translate === panelWidth) action = 'reset';\n else action = 'swap';\n }\n else {\n action = 'reset';\n }\n }\n if (action === 'swap') {\n app.allowPanelOpen = true;\n if (opened) {\n app.closePanel();\n if (edge) {\n panel.css({display: ''});\n $('body').removeClass('panel-closing');\n }\n }\n else {\n app.openPanel(side);\n }\n if (edge) app.allowPanelOpen = true;\n }\n if (action === 'reset') {\n if (opened) {\n app.allowPanelOpen = true;\n app.openPanel(side);\n }\n else {\n app.closePanel();\n if (edge) {\n app.allowPanelOpen = true;\n panel.css({display: ''});\n }\n else {\n var target = effect === 'reveal' ? views : panel;\n $('body').addClass('panel-closing');\n target.transitionEnd(function () {\n app.allowPanelOpen = true;\n panel.css({display: ''});\n $('body').removeClass('panel-closing');\n });\n }\n }\n }\n if (effect === 'reveal') {\n views.transition('');\n views.transform('');\n }\n panel.transition('').transform('');\n panelOverlay.css({display: ''}).transform('');\n }\n $(document).on(app.touchEvents.start, handleTouchStart);\n $(document).on(app.touchEvents.move, handleTouchMove);\n $(document).on(app.touchEvents.end, handleTouchEnd);\n };\n \n"," /*======================================================\n ************ Image Lazy Loading ************\n ************ Based on solution by Marc Godard, https://github.com/MarcGodard ************\n ======================================================*/\n app.initImagesLazyLoad = function (pageContainer) {\n pageContainer = $(pageContainer);\n \n // Lazy images\n var lazyLoadImages;\n if (pageContainer.hasClass('lazy')) {\n lazyLoadImages = pageContainer;\n pageContainer = lazyLoadImages.parents('.page');\n }\n else {\n lazyLoadImages = pageContainer.find('.lazy');\n }\n if (lazyLoadImages.length === 0) return;\n \n // Scrollable page content\n var pageContent;\n if (pageContainer.hasClass('page-content')) {\n pageContent = pageContainer;\n pageContainer = pageContainer.parents('.page');\n }\n else {\n pageContent = pageContainer.find('.page-content');\n }\n if (pageContent.length === 0) return;\n \n // Placeholder\n var placeholderSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEXCwsK592mkAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==';\n if (typeof app.params.imagesLazyLoadPlaceholder === 'string') {\n placeholderSrc = app.params.imagesLazyLoadPlaceholder;\n }\n if (app.params.imagesLazyLoadPlaceholder !== false) lazyLoadImages.attr('src', placeholderSrc);\n \n // load image\n var imagesSequence = [];\n var imageIsLoading = false;\n function loadImage(el) {\n el = $(el);\n \n var bg = el.attr('data-background');\n var src = bg ? bg : el.attr('data-src');\n if (!src) return;\n \n function onLoad() {\n el.removeClass('lazy').addClass('lazy-loaded');\n if (bg) {\n el.css('background-image', 'url(' + src + ')');\n }\n else {\n el.attr('src', src);\n }\n \n if (app.params.imagesLazyLoadSequential) {\n imageIsLoading = false;\n if (imagesSequence.length > 0) {\n loadImage(imagesSequence.shift());\n }\n }\n }\n \n if (!app.params.imagesLazyLoadSequential) {\n onLoad();\n return;\n }\n \n if (imageIsLoading) {\n if (imagesSequence.indexOf(el[0]) < 0) imagesSequence.push(el[0]);\n return;\n }\n \n // Loading flag\n imageIsLoading = true;\n \n var image = new Image();\n image.onload = onLoad;\n image.onerror = onLoad;\n image.src =src;\n }\n function lazyHandler() {\n lazyLoadImages = pageContainer.find('.lazy');\n lazyLoadImages.each(function(index, el) {\n el = $(el);\n if (isElementInViewport(el[0])) {\n loadImage(el);\n }\n });\n }\n \n function isElementInViewport (el) {\n var rect = el.getBoundingClientRect();\n var threshold = app.params.imagesLazyLoadThreshold || 0;\n return (\n rect.top >= (0 - threshold) &&\n rect.left >= (0 - threshold) &&\n rect.top <= (window.innerHeight + threshold) &&\n rect.left <= (window.innerWidth + threshold)\n );\n }\n \n function attachEvents(destroy) {\n var method = destroy ? 'off' : 'on';\n lazyLoadImages[method]('lazy', lazyHandler);\n pageContent[method]('lazy', lazyHandler);\n pageContent[method]('scroll', lazyHandler);\n $(window)[method]('resize', lazyHandler);\n }\n function detachEvents() {\n attachEvents(true);\n }\n \n // Store detach function\n pageContainer[0].f7DestroyImagesLazyLoad = detachEvents;\n \n // Attach events\n attachEvents();\n \n // Destroy on page remove\n if (pageContainer.hasClass('page')) {\n pageContainer.once('pageBeforeRemove', detachEvents);\n }\n \n // Run loader on page load/init\n lazyHandler();\n \n // Run after page animation\n pageContainer.once('pageAfterAnimation', lazyHandler);\n };\n app.destroyImagesLazyLoad = function (pageContainer) {\n pageContainer = $(pageContainer);\n if (pageContainer.length > 0 && pageContainer[0].f7DestroyImagesLazyLoad) {\n pageContainer[0].f7DestroyLazyLoad();\n }\n };\n app.reinitImagesLazyLoad = function (pageContainer) {\n pageContainer = $(pageContainer);\n if (pageContainer.length > 0) {\n pageContainer.trigger('lazy');\n }\n };\n"," /*======================================================\n ************ Messages ************\n ======================================================*/\n app.initMessages = function (pageContainer) {\n var page = $(pageContainer);\n var messages = page.find('.messages');\n if (messages.length === 0) return;\n var pageContent = page.find('.page-content');\n if (messages.hasClass('messages-auto-layout')) app.updateMessagesLayout(messages);\n if (!messages.hasClass('new-messages-first')) pageContent[0].scrollTop = pageContent[0].scrollHeight - pageContent[0].offsetHeight;\n };\n app.addMessage = function (props, messagesContent, addToTop) {\n props = props || {};\n props.type = props.type || 'sent';\n if (!props.text || props.length === 0) return false;\n messagesContent = $(messagesContent || '.messages-content');\n if (messagesContent.length === 0) return false;\n var messages = messagesContent.find('.messages');\n var newOnTop = messages.hasClass('new-messages-first');\n \n if (typeof addToTop === 'undefined') {\n addToTop = newOnTop ? true : false;\n }\n var method = addToTop ? 'prepend' : 'append';\n \n var html = '';\n if (props.day) {\n html += '<div class=\"messages-date\">' + props.day + (props.time ? ',' : '') + (props.time ? ' <span>' + props.time + '</span>' : '') + '</div>';\n }\n var isPic = props.text.indexOf('<img') >= 0 ? 'message-pic' : '';\n var withAvatar = props.avatar ? 'message-with-avatar' : '';\n var messageClass = 'message' + ' message-' + props.type + ' ' + isPic + ' ' + withAvatar + ' message-appear-from-' + (method === 'append' ? 'bottom' : 'top');\n html += '<div class=\"' + messageClass + '\">' +\n (props.name ? '<div class=\"message-name\">' + props.name + '</div>' : '') +\n '<div class=\"message-text\">' + props.text + '</div>' +\n (props.avatar ? '<div class=\"message-avatar\" style=\"background-image:url(' + props.avatar + ')\"></div>' : '') +\n (props.label ? '<div class=\"message-label\">' + props.label + '</div>' : '') +\n '</div>';\n messages[method](html);\n if (messages.hasClass('messages-auto-layout')) app.updateMessagesLayout(messages);\n if ((method === 'append' && !newOnTop) || (method === 'prepend' && newOnTop)) {\n app.scrollMessagesContainer(messagesContent);\n }\n };\n app.updateMessagesLayout = function (messages) {\n messages.find('.message').each(function () {\n var message = $(this);\n if (message.find('.message-text img').length > 0) message.addClass('message-pic');\n if (message.find('.message-avatar').length > 0) message.addClass('message-with-avatar');\n });\n messages.find('.message-sent').each(function () {\n var message = $(this);\n var next = message.next('.message-sent');\n var prev = message.prev('.message-sent');\n if (next.length === 0) {\n message.addClass('message-last message-with-tail');\n }\n else message.removeClass('message-last message-with-tail');\n \n if (prev.length === 0) {\n message.addClass('message-first');\n }\n else message.removeClass('message-first');\n // Search for changed names\n if (prev.length > 0 && prev.find('.message-name').length > 0 && message.find('.message-name').length > 0) {\n if (prev.find('.message-name').text() !== message.find('.message-name').text()) {\n prev.addClass('message-last message-with-tail');\n message.addClass('message-first');\n }\n }\n });\n messages.find('.message-received').each(function () {\n var message = $(this);\n var next = message.next('.message-received');\n var prev = message.prev('.message-received');\n if (next.length === 0) {\n message.addClass('message-last message-with-tail');\n }\n else message.removeClass('message-last message-with-tail');\n \n if (prev.length === 0) {\n message.addClass('message-first');\n }\n else message.removeClass('message-first');\n \n // Search for changed names\n if (prev.length > 0 && prev.find('.message-name').length > 0 && message.find('.message-name').length > 0) {\n if (prev.find('.message-name').text() !== message.find('.message-name').text()) {\n prev.addClass('message-last message-with-tail');\n message.addClass('message-first');\n }\n }\n });\n };\n app.scrollMessagesContainer = function (messagesContent) {\n messagesContent = $(messagesContent || '.messages-content');\n if (messagesContent.length === 0) return;\n var messages = messagesContent.find('.messages');\n var newOnTop = messages.hasClass('new-messages-first');\n var currentScroll = messagesContent[0].scrollTop;\n var newScroll = newOnTop ? 0 : messagesContent[0].scrollHeight - messagesContent[0].offsetHeight;\n if (newScroll === currentScroll) return;\n messagesContent.scrollTop(newScroll, 400);\n };\n \n"," /*===============================================================================\n ************ Swipeout Actions (Swipe to delete) ************\n ===============================================================================*/\n app.swipeoutOpenedEl = undefined;\n app.allowSwipeout = true;\n app.initSwipeout = function (swipeoutEl) {\n var isTouched, isMoved, isScrolling, touchesStart = {}, touchStartTime, touchesDiff, swipeOutEl, swipeOutContent, actionsRight, actionsLeft, actionsLeftWidth, actionsRightWidth, translate, opened, openedActions, buttonsLeft, buttonsRight, direction, overswipeLeftButton, overswipeRightButton, overswipeLeft, overswipeRight, noFoldLeft, noFoldRight;\n $(document).on(app.touchEvents.start, function (e) {\n if (app.swipeoutOpenedEl) {\n var target = $(e.target);\n if (!(\n app.swipeoutOpenedEl.is(target[0]) ||\n target.parents('.swipeout').is(app.swipeoutOpenedEl) ||\n target.hasClass('modal-in') ||\n target.parents('.modal.modal-in').length > 0 ||\n target.hasClass('modal-overlay')\n )) {\n app.swipeoutClose(app.swipeoutOpenedEl);\n }\n }\n });\n \n function handleTouchStart(e) {\n if (!app.allowSwipeout) return;\n isMoved = false;\n isTouched = true;\n isScrolling = undefined;\n touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n }\n function handleTouchMove(e) {\n if (!isTouched) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));\n }\n if (isScrolling) {\n isTouched = false;\n return;\n }\n \n if (!isMoved) {\n if ($('.list-block.sortable-opened').length > 0) return;\n /*jshint validthis:true */\n swipeOutEl = $(this);\n swipeOutContent = swipeOutEl.find('.swipeout-content');\n actionsRight = swipeOutEl.find('.swipeout-actions-right');\n actionsLeft = swipeOutEl.find('.swipeout-actions-left');\n actionsLeftWidth = actionsRightWidth = buttonsLeft = buttonsRight = overswipeRightButton = overswipeLeftButton = null;\n noFoldLeft = actionsLeft.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;\n noFoldRight = actionsRight.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;\n if (actionsLeft.length > 0) {\n actionsLeftWidth = actionsLeft.outerWidth();\n buttonsLeft = actionsLeft.children('a');\n overswipeLeftButton = actionsLeft.find('.swipeout-overswipe');\n }\n if (actionsRight.length > 0) {\n actionsRightWidth = actionsRight.outerWidth();\n buttonsRight = actionsRight.children('a');\n overswipeRightButton = actionsRight.find('.swipeout-overswipe');\n }\n opened = swipeOutEl.hasClass('swipeout-opened');\n if (opened) {\n openedActions = swipeOutEl.find('.swipeout-actions-left.swipeout-actions-opened').length > 0 ? 'left' : 'right';\n }\n swipeOutEl.removeClass('transitioning');\n if (!app.params.swipeoutNoFollow) {\n swipeOutEl.find('.swipeout-actions-opened').removeClass('swipeout-actions-opened');\n swipeOutEl.removeClass('swipeout-opened');\n }\n }\n isMoved = true;\n e.preventDefault();\n \n touchesDiff = pageX - touchesStart.x;\n translate = touchesDiff;\n \n if (opened) {\n if (openedActions === 'right') translate = translate - actionsRightWidth;\n else translate = translate + actionsLeftWidth;\n }\n \n if (translate > 0 && actionsLeft.length === 0 || translate < 0 && actionsRight.length === 0) {\n if (!opened) {\n isTouched = isMoved = false;\n return;\n }\n translate = 0;\n }\n \n if (translate < 0) direction = 'to-left';\n else if (translate > 0) direction = 'to-right';\n else {\n if (direction) direction = direction;\n else direction = 'to-left';\n }\n \n var i, buttonOffset, progress;\n \n e.f7PreventPanelSwipe = true;\n if (app.params.swipeoutNoFollow) {\n if (opened) {\n if (openedActions === 'right' && touchesDiff > 0) {\n app.swipeoutClose(swipeOutEl);\n }\n if (openedActions === 'left' && touchesDiff < 0) {\n app.swipeoutClose(swipeOutEl);\n }\n }\n else {\n if (touchesDiff < 0 && actionsRight.length > 0) {\n app.swipeoutOpen(swipeOutEl, 'right');\n }\n if (touchesDiff > 0 && actionsLeft.length > 0) {\n app.swipeoutOpen(swipeOutEl, 'left');\n }\n }\n isTouched = false;\n isMoved = false;\n return;\n }\n overswipeLeft = false;\n overswipeRight = false;\n var $button;\n if (actionsRight.length > 0) {\n // Show right actions\n progress = translate / actionsRightWidth;\n if (translate < -actionsRightWidth) {\n translate = -actionsRightWidth - Math.pow(-translate - actionsRightWidth, 0.8);\n if (overswipeRightButton.length > 0) {\n overswipeRight = true;\n }\n }\n for (i = 0; i < buttonsRight.length; i++) {\n if (typeof buttonsRight[i]._buttonOffset === 'undefined') {\n buttonsRight[i]._buttonOffset = buttonsRight[i].offsetLeft;\n }\n buttonOffset = buttonsRight[i]._buttonOffset;\n $button = $(buttonsRight[i]);\n if (overswipeRightButton.length > 0 && $button.hasClass('swipeout-overswipe')) {\n $button.css({left: (overswipeRight ? -buttonOffset : 0) + 'px'});\n }\n $button.transform('translate3d(' + (translate - buttonOffset * (1 + Math.max(progress, -1))) + 'px,0,0)');\n }\n }\n if (actionsLeft.length > 0) {\n // Show left actions\n progress = translate / actionsLeftWidth;\n if (translate > actionsLeftWidth) {\n translate = actionsLeftWidth + Math.pow(translate - actionsLeftWidth, 0.8);\n if (overswipeLeftButton.length > 0) {\n overswipeLeft = true;\n }\n }\n for (i = 0; i < buttonsLeft.length; i++) {\n if (typeof buttonsLeft[i]._buttonOffset === 'undefined') {\n buttonsLeft[i]._buttonOffset = actionsLeftWidth - buttonsLeft[i].offsetLeft - buttonsLeft[i].offsetWidth;\n }\n buttonOffset = buttonsLeft[i]._buttonOffset;\n $button = $(buttonsLeft[i]);\n if (overswipeLeftButton.length > 0 && $button.hasClass('swipeout-overswipe')) {\n $button.css({left: (overswipeLeft ? buttonOffset : 0) + 'px'});\n }\n if (buttonsLeft.length > 1) {\n $button.css('z-index', buttonsLeft.length - i); \n }\n $button.transform('translate3d(' + (translate + buttonOffset * (1 - Math.min(progress, 1))) + 'px,0,0)');\n }\n }\n swipeOutContent.transform('translate3d(' + translate + 'px,0,0)');\n }\n function handleTouchEnd(e) {\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n \n isTouched = false;\n isMoved = false;\n var timeDiff = (new Date()).getTime() - touchStartTime;\n var action, actionsWidth, actions, buttons, i, noFold;\n \n noFold = direction === 'to-left' ? noFoldRight : noFoldLeft;\n actions = direction === 'to-left' ? actionsRight : actionsLeft;\n actionsWidth = direction === 'to-left' ? actionsRightWidth : actionsLeftWidth;\n \n if (\n timeDiff < 300 && (touchesDiff < -10 && direction === 'to-left' || touchesDiff > 10 && direction === 'to-right') ||\n timeDiff >= 300 && Math.abs(translate) > actionsWidth / 2\n ) {\n action = 'open';\n }\n else {\n action = 'close';\n }\n if (timeDiff < 300) {\n if (Math.abs(translate) === 0) action = 'close';\n if (Math.abs(translate) === actionsWidth) action = 'open';\n }\n \n if (action === 'open') {\n app.swipeoutOpenedEl = swipeOutEl;\n swipeOutEl.trigger('open');\n swipeOutEl.addClass('swipeout-opened transitioning');\n var newTranslate = direction === 'to-left' ? -actionsWidth : actionsWidth;\n swipeOutContent.transform('translate3d(' + newTranslate + 'px,0,0)');\n actions.addClass('swipeout-actions-opened');\n buttons = direction === 'to-left' ? buttonsRight : buttonsLeft;\n if (buttons) {\n for (i = 0; i < buttons.length; i++) {\n $(buttons[i]).transform('translate3d(' + newTranslate + 'px,0,0)');\n }\n }\n if (overswipeRight) {\n actionsRight.find('.swipeout-overswipe')[0].click();\n }\n if (overswipeLeft) {\n actionsLeft.find('.swipeout-overswipe')[0].click();\n }\n }\n else {\n swipeOutEl.trigger('close');\n app.swipeoutOpenedEl = undefined;\n swipeOutEl.addClass('transitioning').removeClass('swipeout-opened');\n swipeOutContent.transform('');\n actions.removeClass('swipeout-actions-opened');\n }\n \n var buttonOffset;\n if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) {\n for (i = 0; i < buttonsLeft.length; i++) {\n buttonOffset = buttonsLeft[i]._buttonOffset;\n if (typeof buttonOffset === 'undefined') {\n buttonsLeft[i]._buttonOffset = actionsLeftWidth - buttonsLeft[i].offsetLeft - buttonsLeft[i].offsetWidth;\n }\n $(buttonsLeft[i]).transform('translate3d(' + (buttonOffset) + 'px,0,0)');\n }\n }\n if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) {\n for (i = 0; i < buttonsRight.length; i++) {\n buttonOffset = buttonsRight[i]._buttonOffset;\n if (typeof buttonOffset === 'undefined') {\n buttonsRight[i]._buttonOffset = buttonsRight[i].offsetLeft;\n }\n $(buttonsRight[i]).transform('translate3d(' + (-buttonOffset) + 'px,0,0)');\n }\n }\n swipeOutContent.transitionEnd(function (e) {\n if (opened && action === 'open' || closed && action === 'close') return;\n swipeOutEl.trigger(action === 'open' ? 'opened' : 'closed');\n if (opened && action === 'close') {\n if (actionsRight.length > 0) {\n buttonsRight.transform('');\n }\n if (actionsLeft.length > 0) {\n buttonsLeft.transform('');\n }\n }\n });\n }\n if (swipeoutEl) {\n $(swipeoutEl).on(app.touchEvents.start, handleTouchStart);\n $(swipeoutEl).on(app.touchEvents.move, handleTouchMove);\n $(swipeoutEl).on(app.touchEvents.end, handleTouchEnd);\n }\n else {\n $(document).on(app.touchEvents.start, '.list-block li.swipeout', handleTouchStart);\n $(document).on(app.touchEvents.move, '.list-block li.swipeout', handleTouchMove);\n $(document).on(app.touchEvents.end, '.list-block li.swipeout', handleTouchEnd);\n }\n \n };\n app.swipeoutOpen = function (el, dir, callback) {\n el = $(el);\n if (arguments.length === 2) {\n if (typeof arguments[1] === 'function') {\n callback = dir;\n }\n }\n \n if (el.length === 0) return;\n if (el.length > 1) el = $(el[0]);\n if (!el.hasClass('swipeout') || el.hasClass('swipeout-opened')) return;\n if (!dir) {\n if (el.find('.swipeout-actions-right').length > 0) dir = 'right';\n else dir = 'left';\n }\n var swipeOutActions = el.find('.swipeout-actions-' + dir);\n if (swipeOutActions.length === 0) return;\n var noFold = swipeOutActions.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;\n el.trigger('open').addClass('swipeout-opened').removeClass('transitioning');\n swipeOutActions.addClass('swipeout-actions-opened');\n var buttons = swipeOutActions.children('a');\n var swipeOutActionsWidth = swipeOutActions.outerWidth();\n var translate = dir === 'right' ? -swipeOutActionsWidth : swipeOutActionsWidth;\n var i;\n if (buttons.length > 1) {\n for (i = 0; i < buttons.length; i++) {\n if (dir === 'right') {\n $(buttons[i]).transform('translate3d(' + (- buttons[i].offsetLeft) + 'px,0,0)');\n }\n else {\n $(buttons[i]).css('z-index', buttons.length - i).transform('translate3d(' + (swipeOutActionsWidth - buttons[i].offsetWidth - buttons[i].offsetLeft) + 'px,0,0)');\n }\n }\n var clientLeft = buttons[1].clientLeft;\n }\n el.addClass('transitioning');\n for (i = 0; i < buttons.length; i++) {\n $(buttons[i]).transform('translate3d(' + (translate) + 'px,0,0)');\n }\n el.find('.swipeout-content').transform('translate3d(' + translate + 'px,0,0)').transitionEnd(function () {\n el.trigger('opened');\n if (callback) callback.call(el[0]);\n });\n app.swipeoutOpenedEl = el;\n };\n app.swipeoutClose = function (el, callback) {\n el = $(el);\n if (el.length === 0) return;\n if (!el.hasClass('swipeout-opened')) return;\n var dir = el.find('.swipeout-actions-opened').hasClass('swipeout-actions-right') ? 'right' : 'left';\n var swipeOutActions = el.find('.swipeout-actions-opened').removeClass('swipeout-actions-opened');\n var noFold = swipeOutActions.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;\n var buttons = swipeOutActions.children('a');\n var swipeOutActionsWidth = swipeOutActions.outerWidth();\n app.allowSwipeout = false;\n el.trigger('close');\n el.removeClass('swipeout-opened').addClass('transitioning');\n el.find('.swipeout-content').transform('translate3d(' + 0 + 'px,0,0)').transitionEnd(function () {\n app.allowSwipeout = true;\n buttons.transform('');\n el.trigger('closed');\n if (callback) callback.call(el[0]);\n });\n for (var i = 0; i < buttons.length; i++) {\n if (dir === 'right') {\n $(buttons[i]).transform('translate3d(' + (-buttons[i].offsetLeft) + 'px,0,0)');\n }\n else {\n $(buttons[i]).transform('translate3d(' + (swipeOutActionsWidth - buttons[i].offsetWidth - buttons[i].offsetLeft) + 'px,0,0)');\n }\n $(buttons[i]).css({left:0 + 'px'});\n }\n if (app.swipeoutOpenedEl && app.swipeoutOpenedEl[0] === el[0]) app.swipeoutOpenedEl = undefined;\n };\n app.swipeoutDelete = function (el, callback) {\n el = $(el);\n if (el.length === 0) return;\n if (el.length > 1) el = $(el[0]);\n app.swipeoutOpenedEl = undefined;\n el.trigger('delete');\n el.css({height: el.outerHeight() + 'px'});\n var clientLeft = el[0].clientLeft;\n el.css({height: 0 + 'px'}).addClass('deleting transitioning').transitionEnd(function () {\n el.trigger('deleted');\n if (callback) callback.call(el[0]);\n if (el.parents('.virtual-list').length > 0) {\n var virtualList = el.parents('.virtual-list')[0].f7VirtualList;\n var virtualIndex = el[0].f7VirtualListIndex;\n if (virtualList && typeof virtualIndex !== 'undefined') virtualList.deleteItem(virtualIndex);\n }\n else {\n el.remove();\n }\n });\n var translate = '-100%';\n el.find('.swipeout-content').transform('translate3d(' + translate + ',0,0)');\n };\n \n"," /*===============================================================================\n ************ Sortable ************\n ===============================================================================*/\n app.sortableToggle = function (sortableContainer) {\n sortableContainer = $(sortableContainer);\n if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');\n sortableContainer.toggleClass('sortable-opened');\n if (sortableContainer.hasClass('sortable-opened')) {\n sortableContainer.trigger('open');\n }\n else {\n sortableContainer.trigger('close');\n }\n return sortableContainer;\n };\n app.sortableOpen = function (sortableContainer) {\n sortableContainer = $(sortableContainer);\n if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');\n sortableContainer.addClass('sortable-opened');\n sortableContainer.trigger('open');\n return sortableContainer;\n };\n app.sortableClose = function (sortableContainer) {\n sortableContainer = $(sortableContainer);\n if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');\n sortableContainer.removeClass('sortable-opened');\n sortableContainer.trigger('close');\n return sortableContainer;\n };\n app.initSortable = function () {\n var isTouched, isMoved, touchStartY, touchesDiff, sortingEl, sortingElHeight, sortingItems, minTop, maxTop, insertAfter, insertBefore, sortableContainer;\n \n function handleTouchStart(e) {\n isMoved = false;\n isTouched = true;\n touchStartY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n /*jshint validthis:true */\n sortingEl = $(this).parent();\n sortingItems = sortingEl.parent().find('li');\n sortableContainer = sortingEl.parents('.sortable');\n e.preventDefault();\n app.allowPanelOpen = app.allowSwipeout = false;\n }\n function handleTouchMove(e) {\n if (!isTouched || !sortingEl) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (!isMoved) {\n sortingEl.addClass('sorting');\n sortableContainer.addClass('sortable-sorting');\n minTop = sortingEl[0].offsetTop;\n maxTop = sortingEl.parent().height() - sortingEl[0].offsetTop - sortingEl.height();\n sortingElHeight = sortingEl[0].offsetHeight;\n }\n isMoved = true;\n \n e.preventDefault();\n e.f7PreventPanelSwipe = true;\n touchesDiff = pageY - touchStartY;\n var translate = touchesDiff;\n if (translate < -minTop) translate = -minTop;\n if (translate > maxTop) translate = maxTop;\n sortingEl.transform('translate3d(0,' + translate + 'px,0)');\n \n insertBefore = insertAfter = undefined;\n \n sortingItems.each(function () {\n var currentEl = $(this);\n if (currentEl[0] === sortingEl[0]) return;\n var currentElOffset = currentEl[0].offsetTop;\n var currentElHeight = currentEl.height();\n var sortingElOffset = sortingEl[0].offsetTop + translate;\n \n if ((sortingElOffset >= currentElOffset - currentElHeight / 2) && sortingEl.index() < currentEl.index()) {\n currentEl.transform('translate3d(0, '+(-sortingElHeight)+'px,0)');\n insertAfter = currentEl;\n insertBefore = undefined;\n }\n else if ((sortingElOffset <= currentElOffset + currentElHeight / 2) && sortingEl.index() > currentEl.index()) {\n currentEl.transform('translate3d(0, '+(sortingElHeight)+'px,0)');\n insertAfter = undefined;\n if (!insertBefore) insertBefore = currentEl;\n }\n else {\n $(this).transform('translate3d(0, 0%,0)');\n }\n });\n }\n function handleTouchEnd(e) {\n app.allowPanelOpen = app.allowSwipeout = true;\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n e.preventDefault();\n sortingItems.transform('');\n sortingEl.removeClass('sorting');\n sortableContainer.removeClass('sortable-sorting');\n var virtualList, oldIndex, newIndex;\n if (insertAfter) {\n sortingEl.insertAfter(insertAfter);\n sortingEl.trigger('sort');\n }\n if (insertBefore) {\n sortingEl.insertBefore(insertBefore);\n sortingEl.trigger('sort');\n }\n if ((insertAfter || insertBefore) && sortableContainer.hasClass('virtual-list')) {\n virtualList = sortableContainer[0].f7VirtualList;\n oldIndex = sortingEl[0].f7VirtualListIndex;\n newIndex = insertBefore ? insertBefore[0].f7VirtualListIndex : insertAfter[0].f7VirtualListIndex;\n if (virtualList) virtualList.moveItem(oldIndex, newIndex);\n }\n insertAfter = insertBefore = undefined;\n isTouched = false;\n isMoved = false;\n }\n $(document).on(app.touchEvents.start, '.list-block.sortable .sortable-handler', handleTouchStart);\n if (app.support.touch) {\n $(document).on(app.touchEvents.move, '.list-block.sortable .sortable-handler', handleTouchMove);\n $(document).on(app.touchEvents.end, '.list-block.sortable .sortable-handler', handleTouchEnd);\n }\n else {\n $(document).on(app.touchEvents.move, handleTouchMove);\n $(document).on(app.touchEvents.end, handleTouchEnd);\n }\n \n };\n \n"," /*===============================================================================\n ************ Smart Select ************\n ===============================================================================*/\n app.initSmartSelects = function (pageContainer) {\n var page = $(pageContainer);\n if (page.length === 0) return;\n \n var selects = page.find('.smart-select');\n if (selects.length === 0) return;\n \n selects.each(function () {\n var smartSelect = $(this);\n \n var $select = smartSelect.find('select');\n if ($select.length === 0) return;\n \n var select = $select[0];\n if (select.length === 0) return;\n \n var valueText = [];\n for (var i = 0; i < select.length; i++) {\n if (select[i].selected) valueText.push(select[i].textContent.trim());\n }\n \n var itemAfter = smartSelect.find('.item-after');\n if (itemAfter.length === 0) {\n smartSelect.find('.item-inner').append('<div class=\"item-after\">' + valueText.join(', ') + '</div>');\n }\n else {\n var selectedText = itemAfter.text();\n if (itemAfter.hasClass('smart-select-value')) {\n for (i = 0; i < select.length; i++) {\n select[i].selected = select[i].textContent.trim() === selectedText.trim();\n }\n } else {\n itemAfter.text(valueText.join(', '));\n }\n }\n \n });\n \n };\n app.smartSelectOpen = function (smartSelect) {\n smartSelect = $(smartSelect);\n if (smartSelect.length === 0) return;\n \n // Find related view\n var view = smartSelect.parents('.' + app.params.viewClass);\n if (view.length === 0) return;\n view = view[0].f7View;\n if (!view) return;\n \n // Parameters\n var openIn = smartSelect.attr('data-open-in');\n if (!openIn) openIn = app.params.smartSelectInPopup ? 'popup' : 'page';\n \n var pageTitle = smartSelect.attr('data-page-title') || smartSelect.find('.item-title').text();\n var backText = smartSelect.attr('data-back-text') || app.params.smartSelectBackText;\n var closeText = smartSelect.attr('data-popup-close-text') || smartSelect.attr('data-back-text') || app.params.smartSelectPopupCloseText ;\n var backOnSelect = smartSelect.attr('data-back-onselect') ? (smartSelect.attr('data-back-onselect') === 'true' ? true : false) : app.params.smartSelectBackOnSelect;\n var formTheme = smartSelect.attr('data-form-theme') || app.params.smartSelectFormTheme;\n var navbarTheme = smartSelect.attr('data-navbar-theme') || app.params.smartSelectNavbarTheme;\n var virtualList = smartSelect.attr('data-virtual-list') === 'true';\n var virtualListItemHeight = smartSelect.attr('data-virtual-list-height');\n \n // Collect all options/values\n var select = smartSelect.find('select')[0];\n var $select = $(select);\n if (select.disabled || smartSelect.hasClass('disabled') || $select.hasClass('disabled')) {\n return;\n }\n var values = [];\n var id = (new Date()).getTime();\n var inputType = select.multiple ? 'checkbox' : 'radio';\n var inputName = inputType + '-' + id;\n var option, optionHasMedia, optionImage, optionIcon, optionGroup, optionGroupLabel, optionPreviousGroup, optionShowGroupLabel, previousGroup;\n for (var i = 0; i < select.length; i++) {\n option = $(select[i]);\n if (option[0].disabled) continue;\n optionImage = option.attr('data-option-image') || $select.attr('data-option-image');\n optionIcon = option.attr('data-option-icon') || $select.attr('data-option-icon');\n optionHasMedia = optionImage || optionIcon || inputType === 'checkbox';\n optionGroup = option.parent('optgroup')[0];\n optionGroupLabel = optionGroup && optionGroup.label;\n optionShowGroupLabel = false;\n if (optionGroup) {\n if (optionGroup !== previousGroup) {\n optionShowGroupLabel = true;\n previousGroup = optionGroup;\n }\n }\n values.push({\n value: option[0].value,\n text: option[0].textContent.trim(),\n selected: option[0].selected,\n group: optionGroup,\n groupLabel: optionGroupLabel,\n showGroupLabel: optionShowGroupLabel,\n image: optionImage,\n icon: optionIcon,\n disabled: option[0].disabled,\n inputType: inputType,\n id: id,\n hasMedia: optionHasMedia,\n checkbox: inputType === 'checkbox',\n inputName: inputName,\n test: this\n });\n }\n \n \n // Item template/HTML\n if (!app._compiledTemplates.smartSelectItem) {\n app._compiledTemplates.smartSelectItem = t7.compile(app.params.smartSelectItemTemplate || \n '{{#if showGroupLabel}}' +\n '<li class=\"item-divider\">{{groupLabel}}</li>' +\n '{{/if}}' +\n '<li>' +\n '<label class=\"label-{{inputType}} item-content\">' +\n '<input type=\"{{inputType}}\" name=\"{{inputName}}\" value=\"{{value}}\" {{#if selected}}checked{{/if}}>' +\n '{{#if hasMedia}}' +\n '<div class=\"item-media\">' +\n '{{#if checkbox}}<i class=\"icon icon-form-checkbox\"></i>{{/if}}' +\n '{{#if icon}}<i class=\"icon {{icon}}\"></i>{{/if}}' +\n '{{#if image}}<img src=\"{{image}}\">{{/if}}' +\n '</div>' +\n '{{/if}}' +\n '<div class=\"item-inner\">' +\n '<div class=\"item-title\">{{text}}</div>' +\n '</div>' +\n '</label>' +\n '</li>'\n );\n }\n var smartSelectItemTemplate = app._compiledTemplates.smartSelectItem;\n \n var inputsHTML = '';\n if (!virtualList) {\n for (var j = 0; j < values.length; j++) {\n inputsHTML += smartSelectItemTemplate(values[j]);\n }\n }\n \n // Navbar HTML\n if (!app._compiledTemplates.smartSelectNavbar) {\n app._compiledTemplates.smartSelectNavbar = t7.compile(app.params.smartSelectNavbarTemplate || \n '<div class=\"navbar {{#if navbarTheme}}theme-{{navbarTheme}}{{/if}}\">' +\n '<div class=\"navbar-inner\">' +\n '{{leftTemplate}}' +\n '<div class=\"center sliding\">{{pageTitle}}</div>' +\n '</div>' +\n '</div>'\n );\n }\n var navbarHTML = app._compiledTemplates.smartSelectNavbar({\n pageTitle: pageTitle,\n backText: backText,\n closeText: closeText,\n openIn: openIn,\n navbarTheme: navbarTheme,\n inPopup: openIn === 'popup',\n inPage: openIn === 'page',\n leftTemplate: openIn === 'popup' ? app.params.smartSelectPopupCloseTemplate.replace(/{{closeText}}/g, closeText) : app.params.smartSelectBackTemplate.replace(/{{backText}}/g, backText)\n });\n \n \n // Determine navbar layout type - static/fixed/through\n var noNavbar = '', noToolbar = '', navbarLayout;\n if (openIn === 'page') {\n navbarLayout = 'static';\n if (smartSelect.parents('.navbar-through').length > 0) navbarLayout = 'through';\n if (smartSelect.parents('.navbar-fixed').length > 0) navbarLayout = 'fixed';\n noToolbar = smartSelect.parents('.page').hasClass('no-toolbar') ? 'no-toolbar' : '';\n noNavbar = smartSelect.parents('.page').hasClass('no-navbar') ? 'no-navbar' : 'navbar-' + navbarLayout;\n }\n else {\n navbarLayout = 'fixed';\n }\n \n \n // Page Layout\n var pageName = 'smart-select-' + inputName;\n \n var useSearchbar = typeof smartSelect.data('searchbar') === 'undefined' ? app.params.smartSelectSearchbar : (smartSelect.data('searchbar') === 'true' ? true : false);\n var searchbarPlaceholder, searchbarCancel;\n \n if (useSearchbar) {\n searchbarPlaceholder = smartSelect.data('searchbar-placeholder') || 'Search';\n searchbarCancel = smartSelect.data('searchbar-cancel') || 'Cancel';\n }\n \n var searchbarHTML = '<form class=\"searchbar\" data-search-list=\".smart-select-list-' + id + '\" data-search-in=\".item-title\">' +\n '<div class=\"searchbar-input\">' +\n '<input type=\"search\" placeholder=\"' + searchbarPlaceholder + '\">' +\n '<a href=\"#\" class=\"searchbar-clear\"></a>' +\n '</div>' +\n '<a href=\"#\" class=\"searchbar-cancel\">' + searchbarCancel + '</a>' +\n '</form>' +\n '<div class=\"searchbar-overlay\"></div>';\n \n var pageHTML =\n (navbarLayout === 'through' ? navbarHTML : '') +\n '<div class=\"pages\">' +\n ' <div data-page=\"' + pageName + '\" class=\"page smart-select-page ' + noNavbar + ' ' + noToolbar + '\">' +\n (navbarLayout === 'fixed' ? navbarHTML : '') +\n (useSearchbar ? searchbarHTML : '') +\n ' <div class=\"page-content\">' +\n (navbarLayout === 'static' ? navbarHTML : '') +\n ' <div class=\"list-block ' + (virtualList ? 'virtual-list' : '') + ' smart-select-list-' + id + ' ' + (formTheme ? 'theme-' + formTheme : '') + '\">' +\n ' <ul>' +\n (virtualList ? '' : inputsHTML) +\n ' </ul>' +\n ' </div>' +\n ' </div>' +\n ' </div>' +\n '</div>';\n \n // Define popup\n var popup;\n \n // Event Listeners on new page\n function handleInputs(container) {\n if (virtualList) {\n var virtualListInstance = app.virtualList($(container).find('.virtual-list'), {\n items: values,\n template: smartSelectItemTemplate,\n height: virtualListItemHeight || undefined,\n searchByItem: function (query, index, item) {\n if (item.text.toLowerCase().indexOf(query.trim()) >=0 ) return true;\n return false;\n }\n });\n $(container).once(openIn === 'popup' ? 'closed': 'pageBeforeRemove', function () {\n if (virtualListInstance && virtualListInstance.destroy) virtualListInstance.destroy();\n });\n }\n $(container).on('change', 'input[name=\"' + inputName + '\"]', function () {\n var input = this;\n var value = input.value;\n var optionText = [];\n if (input.type === 'checkbox') {\n var values = [];\n for (var i = 0; i < select.options.length; i++) {\n var option = select.options[i];\n if (option.value === value) {\n option.selected = input.checked;\n }\n if (option.selected) {\n optionText.push(option.textContent.trim());\n }\n }\n }\n else {\n optionText = [smartSelect.find('option[value=\"' + value + '\"]').text()];\n select.value = value;\n }\n \n $select.trigger('change');\n smartSelect.find('.item-after').text(optionText.join(', '));\n if (backOnSelect && inputType === 'radio') {\n if (openIn === 'popup') app.closeModal(popup);\n else view.router.back();\n }\n });\n }\n function pageInit(e) {\n var page = e.detail.page;\n if (page.name === pageName) {\n $(document).off('pageInit', pageInit);\n handleInputs(page.container);\n }\n }\n \n // Load content\n if (openIn === 'popup') {\n popup = app.popup(\n '<div class=\"popup smart-select-popup smart-select-popup-' + inputName + '\">' +\n '<div class=\"view navbar-fixed\">' +\n pageHTML +\n '</div>' +\n '</div>'\n );\n app.initPage($(popup).find('.page'));\n handleInputs(popup);\n }\n else {\n $(document).on('pageInit', pageInit);\n view.router.load({content: pageHTML});\n }\n };\n \n"," /*===============================================================================\n ************ Virtual List ************\n ===============================================================================*/\n var VirtualList = function (listBlock, params) {\n var defaults = {\n cols: 1,\n height: 44,\n cache: true,\n dynamicHeightBufferSize: 1\n };\n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n \n // Preparation\n var vl = this;\n vl.listBlock = $(listBlock);\n vl.params = params;\n vl.items = params.items;\n if (params.template) {\n if (typeof params.template === 'string') vl.template = t7.compile(params.template);\n else if (typeof params.template === 'function') vl.template = params.template;\n }\n vl.pageContent = vl.listBlock.parents('.page-content');\n \n // Bad scroll\n var updatableScroll;\n if (typeof vl.params.updatableScroll !== 'undefined') {\n updatableScroll = vl.params.updatableScroll;\n }\n else {\n updatableScroll = true;\n if (app.device.ios && app.device.osVersion.split('.')[0] < 8) {\n updatableScroll = false;\n }\n }\n \n // Append <ul>\n vl.ul = vl.params.ul ? $(vl.params.ul) : vl.listBlock.children('ul');\n if (vl.ul.length === 0) {\n vl.listBlock.append('<ul></ul>');\n vl.ul = vl.listBlock.children('ul');\n }\n \n // DOM cached items\n vl.domCache = {};\n vl.displayDomCache = {};\n \n // Temporary DOM Element\n vl.tempDomElement = document.createElement('ul');\n \n // Last repain position\n vl.lastRepaintY = null;\n \n // Fragment\n vl.fragment = document.createDocumentFragment();\n \n // Filter\n vl.filterItems = function (indexes, resetScrollTop) {\n vl.filteredItems = [];\n var firstIndex = indexes[0];\n var lastIndex = indexes[indexes.length - 1];\n for (var i = 0; i < indexes.length; i++) {\n vl.filteredItems.push(vl.items[indexes[i]]);\n }\n if (typeof resetScrollTop === 'undefined') resetScrollTop = true;\n if (resetScrollTop) {\n vl.pageContent[0].scrollTop = 0;\n }\n vl.update();\n };\n vl.resetFilter = function () {\n vl.filteredItems = null;\n delete vl.filteredItems;\n vl.update();\n };\n \n var pageHeight, rowsPerScreen, rowsBefore, rowsAfter, rowsToRender, maxBufferHeight = 0, listHeight;\n var dynamicHeight = typeof vl.params.height === 'function';\n \n // Set list size\n vl.setListSize = function () {\n var items = vl.filteredItems || vl.items;\n pageHeight = vl.pageContent[0].offsetHeight;\n if (dynamicHeight) {\n listHeight = 0;\n vl.heights = [];\n for (var i = 0; i < items.length; i++) {\n var itemHeight = vl.params.height(items[i]);\n listHeight += itemHeight;\n vl.heights.push(itemHeight);\n }\n }\n else {\n listHeight = items.length * vl.params.height / vl.params.cols;\n rowsPerScreen = Math.ceil(pageHeight / vl.params.height);\n rowsBefore = vl.params.rowsBefore || rowsPerScreen * 2;\n rowsAfter = vl.params.rowsAfter || rowsPerScreen;\n rowsToRender = (rowsPerScreen + rowsBefore + rowsAfter);\n maxBufferHeight = rowsBefore / 2 * vl.params.height;\n }\n \n if (updatableScroll) {\n vl.ul.css({height: listHeight + 'px'});\n }\n };\n \n // Render items\n vl.render = function (force, forceScrollTop) {\n if (force) vl.lastRepaintY = null;\n \n var scrollTop = -(vl.listBlock[0].getBoundingClientRect().top + vl.pageContent[0].getBoundingClientRect().top);\n if (typeof forceScrollTop !== 'undefined') scrollTop = forceScrollTop;\n \n if (vl.lastRepaintY === null || Math.abs(scrollTop - vl.lastRepaintY) > maxBufferHeight || (!updatableScroll && (vl.pageContent[0].scrollTop + pageHeight >= vl.pageContent[0].scrollHeight))) {\n vl.lastRepaintY = scrollTop;\n }\n else {\n return;\n }\n \n var items = vl.filteredItems || vl.items, \n fromIndex, toIndex, heightBeforeFirstItem = 0, heightBeforeLastItem = 0;\n if (dynamicHeight) {\n var itemTop = 0, j, itemHeight; \n maxBufferHeight = pageHeight;\n \n for (j = 0; j < vl.heights.length; j++) {\n itemHeight = vl.heights[j];\n if (typeof fromIndex === 'undefined') {\n if (itemTop + itemHeight >= scrollTop - pageHeight * 2 * vl.params.dynamicHeightBufferSize) fromIndex = j;\n else heightBeforeFirstItem += itemHeight;\n }\n \n if (typeof toIndex === 'undefined') {\n if (itemTop + itemHeight >= scrollTop + pageHeight * 2 * vl.params.dynamicHeightBufferSize || j === vl.heights.length - 1) toIndex = j + 1;\n heightBeforeLastItem += itemHeight;\n }\n itemTop += itemHeight;\n }\n toIndex = Math.min(toIndex, items.length);\n }\n else {\n fromIndex = (parseInt(scrollTop / vl.params.height) - rowsBefore) * vl.params.cols;\n if (fromIndex < 0) {\n fromIndex = 0;\n }\n toIndex = Math.min(fromIndex + rowsToRender * vl.params.cols, items.length);\n }\n \n var topPosition;\n vl.reachEnd = false;\n for (var i = fromIndex; i < toIndex; i++) {\n var item, index;\n // Define real item index\n index = vl.items.indexOf(items[i]);\n \n if (i === fromIndex) vl.currentFromIndex = index;\n if (i === toIndex - 1) vl.currentToIndex = index;\n if (index === vl.items.length - 1) vl.reachEnd = true;\n \n // Find items\n if (vl.domCache[index]) {\n item = vl.domCache[index];\n }\n else {\n if (vl.template) {\n vl.tempDomElement.innerHTML = vl.template(items[i], {index: index});\n }\n else if (vl.params.renderItem) {\n vl.tempDomElement.innerHTML = vl.params.renderItem(index, items[i]); \n }\n else {\n vl.tempDomElement.innerHTML = items[i];\n }\n item = vl.tempDomElement.childNodes[0];\n if (vl.params.cache) vl.domCache[index] = item;\n }\n item.f7VirtualListIndex = index;\n \n // Set item top position\n if (i === fromIndex) {\n if (dynamicHeight) {\n topPosition = heightBeforeFirstItem;\n }\n else {\n topPosition = (i * vl.params.height / vl.params.cols);\n }\n }\n item.style.top = topPosition + 'px';\n \n // Before item insert\n if (vl.params.onItemBeforeInsert) vl.params.onItemBeforeInsert(vl, item);\n \n // Append item to fragment\n vl.fragment.appendChild(item);\n \n \n }\n \n // Update list height with not updatable scroll\n if (!updatableScroll) {\n if (dynamicHeight) {\n vl.ul[0].style.height = heightBeforeLastItem + 'px';\n }\n else {\n vl.ul[0].style.height = i * vl.params.height / vl.params.cols + 'px';\n }\n }\n \n \n // Update list html\n if (vl.params.onBeforeClear) vl.params.onBeforeClear(vl, vl.fragment);\n vl.ul[0].innerHTML = '';\n \n if (vl.params.onItemsBeforeInsert) vl.params.onItemsBeforeInsert(vl, vl.fragment);\n vl.ul[0].appendChild(vl.fragment);\n if (vl.params.onItemsAfterInsert) vl.params.onFragmentAfterInsert(vl, vl.fragment);\n \n if (typeof forceScrollTop !== 'undefined' && force) {\n vl.pageContent.scrollTop(forceScrollTop, 0);\n }\n };\n \n vl.scrollToItem = function (index) {\n if (index > vl.items.length) return false;\n \n var itemTop = 0, listTop;\n if (dynamicHeight) {\n for (var i = 0; i < index; i++) {\n itemTop += vl.heights[i];\n }\n }\n else {\n itemTop = index * vl.params.height;\n }\n listTop = vl.listBlock[0].offsetTop;\n vl.render(true, listTop + itemTop - parseInt(vl.pageContent.css('padding-top'), 10));\n return true;\n };\n \n // Handle scroll event\n vl.handleScroll = function (e) {\n vl.render();\n };\n // Handle resize event\n vl.handleResize = function (e) {\n vl.setListSize();\n vl.render(true);\n };\n \n vl.attachEvents = function (detach) {\n var action = detach ? 'off' : 'on';\n vl.pageContent[action]('scroll', vl.handleScroll);\n $(window)[action]('resize', vl.handleResize);\n };\n \n // Init Virtual List\n vl.init = function () {\n vl.attachEvents();\n vl.setListSize();\n vl.render();\n };\n \n // Append\n vl.appendItems = function (items) {\n for (var i = 0; i < items.length; i++) {\n vl.items.push(items[i]);\n }\n vl.update();\n };\n vl.appendItem = function (item) {\n vl.appendItems([item]);\n };\n // Replace\n vl.replaceAllItems = function (items) {\n vl.items = items;\n delete vl.filteredItems;\n vl.domCache = {};\n vl.update();\n };\n vl.replaceItem = function (index, item) {\n vl.items[index] = item;\n if (vl.params.cache) delete vl.domCache[index];\n vl.update();\n };\n // Prepend\n vl.prependItems = function (items) {\n for (var i = items.length - 1; i >= 0; i--) {\n vl.items.unshift(items[i]);\n }\n if (vl.params.cache) {\n var newCache = {};\n for (var cached in vl.domCache) {\n newCache[parseInt(cached, 10) + items.length] = vl.domCache[cached];\n }\n vl.domCache = newCache;\n }\n vl.update();\n };\n vl.prependItem = function (item) {\n vl.prependItems([item]);\n };\n \n // Move\n vl.moveItem = function (oldIndex, newIndex) {\n if (oldIndex === newIndex) return;\n // remove item from array\n var item = vl.items.splice(oldIndex, 1)[0];\n if (newIndex >= vl.items.length) {\n // Add item to the end\n vl.items.push(item);\n newIndex = vl.items.length - 1;\n }\n else {\n // Add item to new index\n vl.items.splice(newIndex, 0, item);\n }\n // Update cache\n if (vl.params.cache) {\n var newCache = {};\n for (var cached in vl.domCache) {\n var cachedIndex = parseInt(cached, 10);\n var leftIndex = oldIndex < newIndex ? oldIndex : newIndex;\n var rightIndex = oldIndex < newIndex ? newIndex : oldIndex;\n var indexShift = oldIndex < newIndex ? -1 : 1;\n if (cachedIndex < leftIndex || cachedIndex > rightIndex) newCache[cachedIndex] = vl.domCache[cachedIndex];\n if (cachedIndex === leftIndex) newCache[rightIndex] = vl.domCache[cachedIndex];\n if (cachedIndex > leftIndex && cachedIndex <= rightIndex) newCache[cachedIndex + indexShift] = vl.domCache[cachedIndex];\n }\n vl.domCache = newCache;\n }\n vl.update();\n };\n // Insert before\n vl.insertItemBefore = function (index, item) {\n if (index === 0) {\n vl.prependItem(item);\n return;\n }\n if (index >= vl.items.length) {\n vl.appendItem(item);\n return;\n }\n vl.items.splice(index, 0, item);\n // Update cache\n if (vl.params.cache) {\n var newCache = {};\n for (var cached in vl.domCache) {\n var cachedIndex = parseInt(cached, 10);\n if (cachedIndex >= index) {\n newCache[cachedIndex + 1] = vl.domCache[cachedIndex];\n }\n }\n vl.domCache = newCache;\n }\n vl.update();\n };\n // Delete\n vl.deleteItems = function (indexes) {\n var prevIndex, indexShift = 0;\n for (var i = 0; i < indexes.length; i++) {\n var index = indexes[i];\n if (typeof prevIndex !== 'undefined') {\n if (index > prevIndex) {\n indexShift = -i;\n }\n }\n index = index + indexShift;\n prevIndex = indexes[i];\n // Delete item\n var deletedItem = vl.items.splice(index, 1)[0];\n \n // Delete from filtered\n if (vl.filteredItems && vl.filteredItems.indexOf(deletedItem) >= 0) {\n vl.filteredItems.splice(vl.filteredItems.indexOf(deletedItem), 1);\n }\n // Update cache\n if (vl.params.cache) {\n var newCache = {};\n for (var cached in vl.domCache) {\n var cachedIndex = parseInt(cached, 10);\n if (cachedIndex === index) {\n delete vl.domCache[index];\n }\n else if (parseInt(cached, 10) > index) {\n newCache[cachedIndex - 1] = vl.domCache[cached];\n }\n else {\n newCache[cachedIndex] = vl.domCache[cached]; \n }\n }\n vl.domCache = newCache;\n }\n }\n vl.update();\n };\n vl.deleteAllItems = function () {\n vl.items = [];\n delete vl.filteredItems;\n if (vl.params.cache) vl.domCache = {};\n vl.update();\n };\n vl.deleteItem = function (index) {\n vl.deleteItems([index]);\n };\n \n // Clear cache\n vl.clearCache = function () {\n vl.domCache = {};\n };\n \n // Update Virtual List\n vl.update = function () {\n vl.setListSize();\n vl.render(true);\n };\n \n // Destroy\n vl.destroy = function () {\n vl.attachEvents(true);\n delete vl.items;\n delete vl.domCache;\n };\n \n // Init Virtual List\n vl.init();\n \n // Store vl in container\n vl.listBlock[0].f7VirtualList = vl;\n return vl;\n };\n \n // App Method\n app.virtualList = function (listBlock, params) {\n return new VirtualList(listBlock, params);\n };\n \n app.reinitVirtualList = function (pageContainer) {\n var page = $(pageContainer);\n var vlists = page.find('.virtual-list');\n if (vlists.length === 0) return;\n for (var i = 0; i < vlists.length; i++) {\n var vlistInstance = vlistInstance[0].f7VirtualList;\n if (vlistInstance) {\n vlistInstance.update();\n }\n }\n };\n"," /*======================================================\n ************ Pull To Refresh ************\n ======================================================*/\n app.initPullToRefresh = function (pageContainer) {\n var eventsTarget = $(pageContainer);\n if (!eventsTarget.hasClass('pull-to-refresh-content')) {\n eventsTarget = eventsTarget.find('.pull-to-refresh-content');\n }\n if (!eventsTarget || eventsTarget.length === 0) return;\n \n var isTouched, isMoved, touchesStart = {}, isScrolling, touchesDiff, touchStartTime, container, refresh = false, useTranslate = false, startTranslate = 0, translate, scrollTop, wasScrolled, layer, triggerDistance, dynamicTriggerDistance;\n var page = eventsTarget.hasClass('page') ? eventsTarget : eventsTarget.parents('.page');\n var hasNavbar = false;\n if (page.find('.navbar').length > 0 || page.parents('.navbar-fixed, .navbar-through').length > 0 || page.hasClass('navbar-fixed') || page.hasClass('navbar-through')) hasNavbar = true;\n if (page.hasClass('no-navbar')) hasNavbar = false;\n if (!hasNavbar) eventsTarget.addClass('pull-to-refresh-no-navbar');\n \n container = eventsTarget;\n \n // Define trigger distance\n if (container.attr('data-ptr-distance')) {\n dynamicTriggerDistance = true;\n }\n else {\n triggerDistance = 44; \n }\n \n function handleTouchStart(e) {\n if (isTouched) {\n if (app.device.os === 'android') {\n if ('targetTouches' in e && e.targetTouches.length > 1) return;\n }\n else return;\n }\n isMoved = false;\n isTouched = true;\n isScrolling = undefined;\n wasScrolled = undefined;\n touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n /*jshint validthis:true */\n container = $(this);\n }\n \n function handleTouchMove(e) {\n if (!isTouched) return;\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));\n }\n if (!isScrolling) {\n isTouched = false;\n return;\n }\n \n scrollTop = container[0].scrollTop;\n if (typeof wasScrolled === 'undefined' && scrollTop !== 0) wasScrolled = true; \n \n if (!isMoved) {\n /*jshint validthis:true */\n container.removeClass('transitioning');\n if (scrollTop > container[0].offsetHeight) {\n isTouched = false;\n return;\n }\n if (dynamicTriggerDistance) {\n triggerDistance = container.attr('data-ptr-distance');\n if (triggerDistance.indexOf('%') >= 0) triggerDistance = container[0].offsetHeight * parseInt(triggerDistance, 10) / 100;\n }\n startTranslate = container.hasClass('refreshing') ? triggerDistance : 0;\n if (container[0].scrollHeight === container[0].offsetHeight || app.device.os !== 'ios') {\n useTranslate = true;\n }\n else {\n useTranslate = false;\n }\n }\n isMoved = true;\n touchesDiff = pageY - touchesStart.y;\n \n if (touchesDiff > 0 && scrollTop <= 0 || scrollTop < 0) {\n // iOS 8 fix\n if (app.device.os === 'ios' && parseInt(app.device.osVersion.split('.')[0], 10) > 7 && scrollTop === 0 && !wasScrolled) useTranslate = true;\n \n if (useTranslate) {\n e.preventDefault();\n translate = (Math.pow(touchesDiff, 0.85) + startTranslate);\n container.transform('translate3d(0,' + translate + 'px,0)');\n }\n else {\n }\n if ((useTranslate && Math.pow(touchesDiff, 0.85) > triggerDistance) || (!useTranslate && touchesDiff >= triggerDistance * 2)) {\n refresh = true;\n container.addClass('pull-up').removeClass('pull-down');\n }\n else {\n refresh = false;\n container.removeClass('pull-up').addClass('pull-down');\n }\n }\n else {\n \n container.removeClass('pull-up pull-down');\n refresh = false;\n return;\n }\n }\n function handleTouchEnd(e) {\n if (!isTouched || !isMoved) {\n isTouched = false;\n isMoved = false;\n return;\n }\n if (translate) {\n container.addClass('transitioning');\n translate = 0;\n }\n container.transform('');\n if (refresh) {\n container.addClass('refreshing');\n container.trigger('refresh', {\n done: function () {\n app.pullToRefreshDone(container);\n }\n });\n }\n else {\n container.removeClass('pull-down');\n }\n isTouched = false;\n isMoved = false;\n }\n \n // Attach Events\n eventsTarget.on(app.touchEvents.start, handleTouchStart);\n eventsTarget.on(app.touchEvents.move, handleTouchMove);\n eventsTarget.on(app.touchEvents.end, handleTouchEnd);\n \n // Detach Events on page remove\n if (page.length === 0) return;\n function destroyPullToRefresh() {\n eventsTarget.off(app.touchEvents.start, handleTouchStart);\n eventsTarget.off(app.touchEvents.move, handleTouchMove);\n eventsTarget.off(app.touchEvents.end, handleTouchEnd);\n }\n eventsTarget[0].f7DestroyPullToRefresh = destroyPullToRefresh;\n function detachEvents() {\n destroyPullToRefresh();\n page.off('pageBeforeRemove', detachEvents);\n }\n page.on('pageBeforeRemove', detachEvents);\n \n };\n \n app.pullToRefreshDone = function (container) {\n container = $(container);\n if (container.length === 0) container = $('.pull-to-refresh-content.refreshing');\n container.removeClass('refreshing').addClass('transitioning');\n container.transitionEnd(function () {\n container.removeClass('transitioning pull-up pull-down');\n });\n };\n app.pullToRefreshTrigger = function (container) {\n container = $(container);\n if (container.length === 0) container = $('.pull-to-refresh-content');\n if (container.hasClass('refreshing')) return;\n container.addClass('transitioning refreshing');\n container.trigger('refresh', {\n done: function () {\n app.pullToRefreshDone(container);\n }\n });\n };\n \n app.destroyPullToRefresh = function (pageContainer) {\n pageContainer = $(pageContainer);\n var pullToRefreshContent = pageContainer.hasClass('pull-to-refresh-content') ? pageContainer : pageContainer.find('.pull-to-refresh-content');\n if (pullToRefreshContent.length === 0) return;\n if (pullToRefreshContent[0].f7DestroyPullToRefresh) pullToRefreshContent[0].f7DestroyPullToRefresh();\n };\n \n"," /* ===============================================================================\n ************ Infinite Scroll ************\n =============================================================================== */\n function handleInfiniteScroll() {\n /*jshint validthis:true */\n var inf = $(this);\n var scrollTop = inf[0].scrollTop;\n var scrollHeight = inf[0].scrollHeight;\n var height = inf[0].offsetHeight;\n var distance = inf[0].getAttribute('data-distance');\n var virtualListContainer = inf.find('.virtual-list');\n var virtualList;\n var onTop = inf.hasClass('infinite-scroll-top');\n if (!distance) distance = 50;\n if (typeof distance === 'string' && distance.indexOf('%') >= 0) {\n distance = parseInt(distance, 10) / 100 * height;\n }\n if (distance > height) distance = height;\n if (onTop) {\n if (scrollTop < distance) {\n inf.trigger('infinite');\n }\n }\n else {\n if (scrollTop + height >= scrollHeight - distance) {\n if (virtualListContainer.length > 0) {\n virtualList = virtualListContainer[0].f7VirtualList;\n if (virtualList && !virtualList.reachEnd) return;\n }\n inf.trigger('infinite');\n }\n }\n \n }\n app.attachInfiniteScroll = function (infiniteContent) {\n $(infiniteContent).on('scroll', handleInfiniteScroll);\n };\n app.detachInfiniteScroll = function (infiniteContent) {\n $(infiniteContent).off('scroll', handleInfiniteScroll);\n };\n \n app.initInfiniteScroll = function (pageContainer) {\n pageContainer = $(pageContainer);\n var infiniteContent = pageContainer.find('.infinite-scroll');\n if (infiniteContent.length === 0) return;\n app.attachInfiniteScroll(infiniteContent);\n function detachEvents() {\n app.detachInfiniteScroll(infiniteContent);\n pageContainer.off('pageBeforeRemove', detachEvents);\n }\n pageContainer.on('pageBeforeRemove', detachEvents);\n };\n"," /*=============================================================\n ************ Hide/show Toolbar/Navbar on scroll ************\n =============================================================*/\n app.initScrollToolbars = function (pageContainer) {\n pageContainer = $(pageContainer);\n var scrollContent = pageContainer.find('.page-content');\n if (scrollContent.length === 0) return;\n var hideNavbar = (app.params.hideNavbarOnPageScroll || scrollContent.hasClass('hide-navbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll')) && !(scrollContent.hasClass('keep-navbar-on-scroll') || scrollContent.hasClass('keep-bars-on-scroll'));\n var hideToolbar = (app.params.hideToolbarOnPageScroll || scrollContent.hasClass('hide-toolbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll')) && !(scrollContent.hasClass('keep-toolbar-on-scroll') || scrollContent.hasClass('keep-bars-on-scroll'));\n var hideTabbar = (app.params.hideTabbarOnPageScroll || scrollContent.hasClass('hide-tabbar-on-scroll')) && !(scrollContent.hasClass('keep-tabbar-on-scroll'));\n \n if (!(hideNavbar || hideToolbar || hideTabbar)) return;\n \n var viewContainer = scrollContent.parents('.' + app.params.viewClass);\n if (viewContainer.length === 0) return;\n \n var navbar = viewContainer.find('.navbar'), \n toolbar = viewContainer.find('.toolbar'), \n tabbar;\n if (hideTabbar) {\n tabbar = viewContainer.find('.tabbar');\n if (tabbar.length === 0) tabbar = viewContainer.parents('.' + app.params.viewsClass).find('.tabbar');\n }\n \n var hasNavbar = navbar.length > 0,\n hasToolbar = toolbar.length > 0,\n hasTabbar = tabbar && tabbar.length > 0;\n \n var previousScroll, currentScroll;\n previousScroll = currentScroll = scrollContent[0].scrollTop;\n \n var scrollHeight, offsetHeight, reachEnd, action, navbarHidden, toolbarHidden, tabbarHidden;\n \n var toolbarHeight = (hasToolbar && hideToolbar) ? toolbar[0].offsetHeight : 0;\n var tabbarHeight = (hasTabbar && hideTabbar) ? tabbar[0].offsetHeight : 0;\n var bottomBarHeight = tabbarHeight || toolbarHeight;\n \n function handleScroll(e) {\n if (pageContainer.hasClass('page-on-left')) return;\n currentScroll = scrollContent[0].scrollTop;\n scrollHeight = scrollContent[0].scrollHeight;\n offsetHeight = scrollContent[0].offsetHeight;\n reachEnd = app.params.showBarsOnPageScrollEnd && (currentScroll + offsetHeight >= scrollHeight - bottomBarHeight);\n navbarHidden = navbar.hasClass('navbar-hidden');\n toolbarHidden = toolbar.hasClass('toolbar-hidden');\n tabbarHidden = tabbar && tabbar.hasClass('toolbar-hidden');\n \n \n if (previousScroll > currentScroll || reachEnd) {\n action = 'show';\n }\n else {\n if (currentScroll > 44) {\n action = 'hide';\n }\n else {\n action = 'show';\n }\n }\n \n if (action === 'show') {\n if (hasNavbar && hideNavbar && navbarHidden) {\n app.showNavbar(navbar);\n pageContainer.removeClass('no-navbar-by-scroll'); \n navbarHidden = false;\n }\n if (hasToolbar && hideToolbar && toolbarHidden) {\n app.showToolbar(toolbar);\n pageContainer.removeClass('no-toolbar-by-scroll'); \n toolbarHidden = false;\n }\n if (hasTabbar && hideTabbar && tabbarHidden) {\n app.showToolbar(tabbar);\n pageContainer.removeClass('no-tabbar-by-scroll'); \n tabbarHidden = false;\n }\n }\n else {\n if (hasNavbar && hideNavbar && !navbarHidden) {\n app.hideNavbar(navbar);\n pageContainer.addClass('no-navbar-by-scroll'); \n navbarHidden = true;\n }\n if (hasToolbar && hideToolbar && !toolbarHidden) {\n app.hideToolbar(toolbar);\n pageContainer.addClass('no-toolbar-by-scroll'); \n toolbarHidden = true;\n }\n if (hasTabbar && hideTabbar && !tabbarHidden) {\n app.hideToolbar(tabbar);\n pageContainer.addClass('no-tabbar-by-scroll'); \n tabbarHidden = true;\n }\n }\n \n previousScroll = currentScroll;\n }\n scrollContent.on('scroll', handleScroll);\n scrollContent[0].f7ScrollToolbarsHandler = handleScroll;\n };\n app.destroyScrollToolbars = function (pageContainer) {\n pageContainer = $(pageContainer);\n var scrollContent = pageContainer.find('.page-content');\n if (scrollContent.length === 0) return;\n var handler = scrollContent[0].f7ScrollToolbarsHandler;\n if (!handler) return;\n scrollContent.off('scroll', scrollContent[0].f7ScrollToolbarsHandler);\n };\n"," /* ===============================================================================\n ************ Tabs ************\n =============================================================================== */\n app.showTab = function (tab, tabLink, force) {\n var newTab = $(tab);\n if (arguments.length === 2) {\n if (typeof tabLink === 'boolean') {\n force = tabLink;\n }\n }\n if (newTab.length === 0) return false;\n if (newTab.hasClass('active')) {\n if (force) newTab.trigger('show');\n return false;\n }\n var tabs = newTab.parent('.tabs');\n if (tabs.length === 0) return false;\n \n // Return swipeouts in hidden tabs\n app.allowSwipeout = true;\n \n // Animated tabs\n var isAnimatedTabs = tabs.parent().hasClass('tabs-animated-wrap');\n if (isAnimatedTabs) {\n tabs.transform('translate3d(' + -newTab.index() * 100 + '%,0,0)');\n }\n \n // Remove active class from old tabs\n var oldTab = tabs.children('.tab.active').removeClass('active');\n // Add active class to new tab\n newTab.addClass('active');\n // Trigger 'show' event on new tab\n newTab.trigger('show');\n \n // Update navbars in new tab\n if (!isAnimatedTabs && newTab.find('.navbar').length > 0) {\n // Find tab's view\n var viewContainer;\n if (newTab.hasClass(app.params.viewClass)) viewContainer = newTab[0];\n else viewContainer = newTab.parents('.' + app.params.viewClass)[0];\n app.sizeNavbars(viewContainer);\n }\n \n // Find related link for new tab\n if (tabLink) tabLink = $(tabLink);\n else {\n // Search by id\n if (typeof tab === 'string') tabLink = $('.tab-link[href=\"' + tab + '\"]');\n else tabLink = $('.tab-link[href=\"#' + newTab.attr('id') + '\"]');\n // Search by data-tab\n if (!tabLink || tabLink && tabLink.length === 0) {\n $('[data-tab]').each(function () {\n if (newTab.is($(this).attr('data-tab'))) tabLink = $(this);\n });\n }\n }\n if (tabLink.length === 0) return;\n \n // Find related link for old tab\n var oldTabLink;\n if (oldTab && oldTab.length > 0) {\n // Search by id\n var oldTabId = oldTab.attr('id');\n if (oldTabId) oldTabLink = $('.tab-link[href=\"#' + oldTabId + '\"]');\n // Search by data-tab\n if (!oldTabLink || oldTabLink && oldTabLink.length === 0) {\n $('[data-tab]').each(function () {\n if (oldTab.is($(this).attr('data-tab'))) oldTabLink = $(this);\n });\n }\n }\n \n // Update links' classes\n if (tabLink && tabLink.length > 0) tabLink.addClass('active');\n if (oldTabLink && oldTabLink.length > 0) oldTabLink.removeClass('active');\n \n return true;\n };\n"," /*===============================================================================\n ************ Accordion ************\n ===============================================================================*/\n app.accordionToggle = function (item) {\n item = $(item);\n if (item.length === 0) return;\n if (item.hasClass('accordion-item-expanded')) app.accordionClose(item);\n else app.accordionOpen(item);\n };\n app.accordionOpen = function (item) {\n item = $(item);\n var list = item.parents('.accordion-list').eq(0);\n var content = item.children('.accordion-item-content');\n if (content.length === 0) content = item.find('.accordion-item-content');\n var expandedItem = list.length > 0 && item.parent().children('.accordion-item-expanded');\n if (expandedItem.length > 0) {\n app.accordionClose(expandedItem);\n }\n content.css('height', content[0].scrollHeight + 'px').transitionEnd(function () {\n if (item.hasClass('accordion-item-expanded')) {\n content.transition(0);\n content.css('height', 'auto');\n var clientLeft = content[0].clientLeft;\n content.transition('');\n item.trigger('opened');\n }\n else {\n content.css('height', '');\n item.trigger('closed');\n }\n });\n item.trigger('open');\n item.addClass('accordion-item-expanded');\n };\n app.accordionClose = function (item) {\n item = $(item);\n var content = item.children('.accordion-item-content');\n if (content.length === 0) content = item.find('.accordion-item-content');\n item.removeClass('accordion-item-expanded');\n content.transition(0);\n content.css('height', content[0].scrollHeight + 'px');\n // Relayout\n var clientLeft = content[0].clientLeft;\n // Close\n content.transition('');\n content.css('height', '').transitionEnd(function () {\n if (item.hasClass('accordion-item-expanded')) {\n content.transition(0);\n content.css('height', 'auto');\n var clientLeft = content[0].clientLeft;\n content.transition('');\n item.trigger('opened');\n }\n else {\n content.css('height', '');\n item.trigger('closed');\n }\n });\n item.trigger('close');\n };\n"," /*===============================================================================\n ************ Fast Clicks ************\n ************ Inspired by https://github.com/ftlabs/fastclick ************\n ===============================================================================*/\n app.initFastClicks = function () {\n if (app.params.activeState) {\n $('html').addClass('watch-active-state');\n }\n \n var touchStartX, touchStartY, touchStartTime, targetElement, trackClick, activeSelection, scrollParent, lastClickTime, isMoved;\n var activableElement, activeTimeout, needsFastClick;\n \n function findActivableElement(e) {\n var target = $(e.target);\n var parents = target.parents(app.params.activeStateElements);\n var activable;\n if (target.is(app.params.activeStateElements)) {\n activable = target;\n }\n if (parents.length > 0) {\n activable = activable ? activable.add(parents) : parents;\n }\n return activable ? activable : target;\n }\n function isInsideScrollableView() {\n var pageContent = activableElement.parents('.page-content, .panel');\n \n if (pageContent.length === 0) {\n return false;\n }\n \n // This event handler covers the \"tap to stop scrolling\".\n if (pageContent.prop('scrollHandlerSet') !== 'yes') {\n pageContent.on('scroll', function() {\n clearTimeout(activeTimeout);\n });\n pageContent.prop('scrollHandlerSet', 'yes');\n }\n \n return true;\n }\n function addActive() {\n activableElement.addClass('active-state');\n }\n function removeActive(el) {\n activableElement.removeClass('active-state');\n }\n \n function androidNeedsBlur(el) {\n var noBlur = ('button checkbox file image radio submit input textarea').split(' ');\n if (document.activeElement && el !== document.activeElement && document.activeElement !== document.body) {\n if (noBlur.indexOf(el.nodeName.toLowerCase()) >= 0) {\n return false;\n }\n else {\n return true;\n }\n }\n else {\n return false;\n }\n }\n function targetNeedsFastClick(el) {\n var $el = $(el);\n if (el.nodeName.toLowerCase() === 'input' && el.type === 'file') return false;\n if ($el.hasClass('no-fastclick') || $el.parents('.no-fastclick').length > 0) return false;\n return true;\n }\n function targetNeedsFocus(el) {\n if (document.activeElement === el) {\n return false;\n }\n var tag = el.nodeName.toLowerCase();\n var skipInputs = ('button checkbox file image radio submit').split(' ');\n if (el.disabled || el.readOnly) return false;\n if (tag === 'textarea') return true;\n if (tag === 'select') {\n if (app.device.android) return false;\n else return true;\n }\n if (tag === 'input' && skipInputs.indexOf(el.type) < 0) return true;\n }\n function targetNeedsPrevent(el) {\n el = $(el);\n var prevent = true;\n if (el.is('label') || el.parents('label').length > 0) {\n if (app.device.android) {\n prevent = false;\n }\n else if (app.device.ios && el.is('input')) {\n prevent = true;\n }\n else prevent = false;\n }\n return prevent;\n }\n \n // Mouse Handlers\n function handleMouseDown (e) {\n findActivableElement(e).addClass('active-state');\n if ('which' in e && e.which === 3) {\n setTimeout(function () {\n $('.active-state').removeClass('active-state');\n }, 0);\n }\n }\n function handleMouseMove (e) {\n $('.active-state').removeClass('active-state');\n }\n function handleMouseUp (e) {\n $('.active-state').removeClass('active-state');\n }\n \n // Touch Handlers\n function handleTouchStart(e) {\n isMoved = false;\n if (e.targetTouches.length > 1) {\n return true;\n }\n needsFastClick = targetNeedsFastClick(e.target);\n \n if (!needsFastClick) {\n trackClick = false;\n return true;\n }\n if (app.device.ios) {\n var selection = window.getSelection();\n if (selection.rangeCount && selection.focusNode !== document.body && (!selection.isCollapsed || document.activeElement === selection.focusNode)) {\n activeSelection = true;\n return true;\n }\n else {\n activeSelection = false;\n }\n }\n if (app.device.android) {\n if (androidNeedsBlur(e.target)) {\n document.activeElement.blur();\n }\n }\n \n trackClick = true;\n targetElement = e.target;\n touchStartTime = (new Date()).getTime();\n touchStartX = e.targetTouches[0].pageX;\n touchStartY = e.targetTouches[0].pageY;\n \n // Detect scroll parent\n if (app.device.ios) {\n scrollParent = undefined;\n $(targetElement).parents().each(function () {\n var parent = this;\n if (parent.scrollHeight > parent.offsetHeight && !scrollParent) {\n scrollParent = parent;\n scrollParent.f7ScrollTop = scrollParent.scrollTop;\n }\n });\n }\n if ((e.timeStamp - lastClickTime) < app.params.fastClicksDelayBetweenClicks) {\n e.preventDefault();\n }\n if (app.params.activeState) {\n activableElement = findActivableElement(e);\n // If it's inside a scrollable view, we don't trigger active-state yet,\n // because it can be a scroll instead. Based on the link:\n // http://labnote.beedesk.com/click-scroll-and-pseudo-active-on-mobile-webk\n if (!isInsideScrollableView(e)) {\n addActive();\n } else {\n activeTimeout = setTimeout(addActive, 80);\n }\n }\n }\n function handleTouchMove(e) {\n if (!trackClick) return;\n var _isMoved = false;\n var distance = app.params.fastClicksDistanceThreshold;\n if (distance) {\n var pageX = e.targetTouches[0].pageX;\n var pageY = e.targetTouches[0].pageY;\n if (Math.abs(pageX - touchStartX) > distance || Math.abs(pageY - touchStartY) > distance) {\n _isMoved = true;\n }\n }\n else {\n _isMoved = true;\n }\n if (_isMoved) {\n trackClick = false;\n targetElement = null;\n isMoved = true;\n }\n \n if (app.params.activeState) {\n clearTimeout(activeTimeout);\n removeActive();\n }\n }\n function handleTouchEnd(e) {\n clearTimeout(activeTimeout);\n \n if (!trackClick) {\n if (!activeSelection && needsFastClick) {\n if (!(app.device.android && !e.cancelable)) {\n e.preventDefault();\n }\n }\n return true;\n }\n \n if (document.activeElement === e.target) {\n return true;\n }\n \n if (!activeSelection) {\n e.preventDefault();\n }\n \n if ((e.timeStamp - lastClickTime) < app.params.fastClicksDelayBetweenClicks) {\n setTimeout(removeActive, 0);\n return true;\n }\n \n lastClickTime = e.timeStamp;\n \n trackClick = false;\n \n if (app.device.ios && scrollParent) {\n if (scrollParent.scrollTop !== scrollParent.f7ScrollTop) {\n return false;\n }\n }\n \n // Add active-state here because, in a very fast tap, the timeout didn't\n // have the chance to execute. Removing active-state in a timeout gives \n // the chance to the animation execute.\n if (app.params.activeState) {\n addActive();\n setTimeout(removeActive, 0);\n }\n \n // Trigger focus when required\n if (targetNeedsFocus(targetElement)) {\n targetElement.focus();\n }\n \n // Blur active elements\n if (document.activeElement && targetElement !== document.activeElement && document.activeElement !== document.body && targetElement.nodeName.toLowerCase() !== 'label') {\n document.activeElement.blur();\n }\n \n // Send click\n e.preventDefault();\n var touch = e.changedTouches[0];\n var evt = document.createEvent('MouseEvents');\n var eventType = 'click';\n if (app.device.android && targetElement.nodeName.toLowerCase() === 'select') {\n eventType = 'mousedown';\n }\n evt.initMouseEvent(eventType, true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);\n evt.forwardedTouchEvent = true;\n targetElement.dispatchEvent(evt);\n return false;\n }\n function handleTouchCancel(e) {\n trackClick = false;\n targetElement = null;\n }\n \n function handleClick(e) {\n var allowClick = false;\n if (trackClick) {\n targetElement = null;\n trackClick = false;\n return true;\n }\n \n if (e.target.type === 'submit' && e.detail === 0) {\n return true;\n }\n // if (!targetElement) {\n // allowClick = true;\n // }\n if (!needsFastClick) {\n allowClick = true;\n }\n if (document.activeElement === targetElement) {\n allowClick = true;\n }\n if (e.forwardedTouchEvent) {\n allowClick = true;\n }\n if (!e.cancelable) {\n allowClick = true;\n }\n if (!allowClick) {\n e.stopImmediatePropagation();\n e.stopPropagation();\n if (targetElement) {\n if (targetNeedsPrevent(targetElement) || isMoved) {\n e.preventDefault();\n }\n }\n else {\n e.preventDefault();\n }\n targetElement = null;\n }\n return allowClick;\n }\n if (app.support.touch) {\n document.addEventListener('click', handleClick, true);\n \n document.addEventListener('touchstart', handleTouchStart);\n document.addEventListener('touchmove', handleTouchMove);\n document.addEventListener('touchend', handleTouchEnd);\n document.addEventListener('touchcancel', handleTouchCancel);\n }\n else {\n if (app.params.activeState) {\n document.addEventListener('mousedown', handleMouseDown);\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n }\n }\n \n };\n \n"," /*===============================================================================\n ************ Handle clicks and make them fast (on tap); ************\n ===============================================================================*/\n app.initClickEvents = function () {\n function handleScrollTop(e) {\n /*jshint validthis:true */\n var clicked = $(this);\n var target = $(e.target);\n var isLink = clicked[0].nodeName.toLowerCase() === 'a' ||\n clicked.parents('a').length > 0 ||\n target[0].nodeName.toLowerCase() === 'a' ||\n target.parents('a').length > 0;\n \n if (isLink) return;\n var pageContent, page;\n if (app.params.scrollTopOnNavbarClick && clicked.is('.navbar .center')) {\n // Find active page\n var navbar = clicked.parents('.navbar');\n \n // Static Layout\n pageContent = navbar.parents('.page-content');\n \n if (pageContent.length === 0) {\n // Fixed Layout\n if (navbar.parents('.page').length > 0) {\n pageContent = navbar.parents('.page').find('.page-content');\n }\n // Through Layout\n if (pageContent.length === 0) {\n if (navbar.nextAll('.pages').length > 0) {\n pageContent = navbar.nextAll('.pages').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');\n }\n }\n }\n }\n if (app.params.scrollTopOnStatusbarClick && clicked.is('.statusbar-overlay')) {\n if ($('.popup.modal-in').length > 0) {\n // Check for opened popup\n pageContent = $('.popup.modal-in').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');\n }\n else if ($('.panel.active').length > 0) {\n // Check for opened panel\n pageContent = $('.panel.active').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');\n }\n else if ($('.views > .view.active').length > 0) {\n // View in tab bar app layout\n pageContent = $('.views > .view.active').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');\n }\n else {\n // Usual case\n pageContent = $('.views').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content'); \n }\n }\n \n if (pageContent && pageContent.length > 0) {\n // Check for tab\n if (pageContent.hasClass('tab')) {\n pageContent = pageContent.parent('.tabs').children('.page-content.active');\n }\n if (pageContent.length > 0) pageContent.scrollTop(0, 300);\n }\n }\n function handleClicks(e) {\n /*jshint validthis:true */\n var clicked = $(this);\n var url = clicked.attr('href');\n var isLink = clicked[0].nodeName.toLowerCase() === 'a';\n \n // Str to boolean for data attributes\n function toBoolean(str) {\n if (str === 'false') return false;\n if (str === 'true') return true;\n return undefined;\n }\n // Check if link is external \n if (isLink) {\n if (clicked.is(app.params.externalLinks)) {\n if(clicked.attr('target') === '_system') {\n e.preventDefault();\n window.open(url, '_system');\n }\n return;\n }\n }\n \n // Smart Select\n if (clicked.hasClass('smart-select')) {\n if (app.smartSelectOpen) app.smartSelectOpen(clicked);\n }\n \n // Open Panel\n if (clicked.hasClass('open-panel')) {\n if ($('.panel').length === 1) {\n if ($('.panel').hasClass('panel-left')) app.openPanel('left');\n else app.openPanel('right');\n }\n else {\n if (clicked.attr('data-panel') === 'right') app.openPanel('right');\n else app.openPanel('left');\n }\n }\n // Close Panel\n if (clicked.hasClass('close-panel')) {\n app.closePanel();\n }\n \n if (clicked.hasClass('panel-overlay') && app.params.panelsCloseByOutside) {\n app.closePanel();\n }\n // Popover\n if (clicked.hasClass('open-popover')) {\n var popover;\n if (clicked.attr('data-popover')) {\n popover = clicked.attr('data-popover');\n }\n else popover = '.popover';\n app.popover(popover, clicked);\n }\n if (clicked.hasClass('close-popover')) {\n app.closeModal('.popover.modal-in');\n }\n // Popup\n var popup;\n if (clicked.hasClass('open-popup')) {\n if (clicked.attr('data-popup')) {\n popup = clicked.attr('data-popup');\n }\n else popup = '.popup';\n app.popup(popup);\n }\n if (clicked.hasClass('close-popup')) {\n if (clicked.attr('data-popup')) {\n popup = clicked.attr('data-popup');\n }\n else popup = '.popup.modal-in';\n app.closeModal(popup);\n }\n // Login Screen\n var loginScreen;\n if (clicked.hasClass('open-login-screen')) {\n if (clicked.attr('data-login-screen')) {\n loginScreen = clicked.attr('data-login-screen');\n }\n else loginScreen = '.login-screen';\n app.loginScreen(loginScreen);\n }\n if (clicked.hasClass('close-login-screen')) {\n app.closeModal('.login-screen.modal-in');\n }\n // Close Modal\n if (clicked.hasClass('modal-overlay')) {\n if ($('.modal.modal-in').length > 0 && app.params.modalCloseByOutside)\n app.closeModal('.modal.modal-in');\n if ($('.actions-modal.modal-in').length > 0 && app.params.actionsCloseByOutside)\n app.closeModal('.actions-modal.modal-in');\n \n if ($('.popover.modal-in').length > 0) app.closeModal('.popover.modal-in');\n }\n if (clicked.hasClass('popup-overlay')) {\n if ($('.popup.modal-in').length > 0 && app.params.popupCloseByOutside)\n app.closeModal('.popup.modal-in');\n }\n \n // Picker\n if (clicked.hasClass('close-picker')) {\n var pickerToClose = $('.picker-modal.modal-in');\n if (pickerToClose.length > 0) {\n app.closeModal(pickerToClose);\n }\n else {\n pickerToClose = $('.popover.modal-in .picker-modal');\n if (pickerToClose.length > 0) {\n app.closeModal(pickerToClose.parents('.popover'));\n }\n }\n }\n if (clicked.hasClass('open-picker')) {\n var pickerToOpen;\n if (clicked.attr('data-picker')) {\n pickerToOpen = clicked.attr('data-picker');\n }\n else pickerToOpen = '.picker-modal';\n app.pickerModal(pickerToOpen, clicked);\n }\n \n // Tabs\n var isTabLink;\n if (clicked.hasClass('tab-link')) {\n isTabLink = true;\n app.showTab(clicked.attr('data-tab') || clicked.attr('href'), clicked);\n }\n // Swipeout Close\n if (clicked.hasClass('swipeout-close')) {\n app.swipeoutClose(clicked.parents('.swipeout-opened'));\n }\n // Swipeout Delete\n if (clicked.hasClass('swipeout-delete')) {\n if (clicked.attr('data-confirm')) {\n var text = clicked.attr('data-confirm');\n var title = clicked.attr('data-confirm-title');\n if (title) {\n app.confirm(text, title, function () {\n app.swipeoutDelete(clicked.parents('.swipeout'));\n });\n }\n else {\n app.confirm(text, function () {\n app.swipeoutDelete(clicked.parents('.swipeout'));\n });\n }\n }\n else {\n app.swipeoutDelete(clicked.parents('.swipeout'));\n }\n \n }\n // Sortable\n if (clicked.hasClass('toggle-sortable')) {\n app.sortableToggle(clicked.data('sortable'));\n }\n if (clicked.hasClass('open-sortable')) {\n app.sortableOpen(clicked.data('sortable'));\n }\n if (clicked.hasClass('close-sortable')) {\n app.sortableClose(clicked.data('sortable'));\n }\n // Accordion\n if (clicked.hasClass('accordion-item-toggle') || (clicked.hasClass('item-link') && clicked.parent().hasClass('accordion-item'))) {\n var accordionItem = clicked.parent('.accordion-item');\n if (accordionItem.length === 0) accordionItem = clicked.parents('.accordion-item');\n if (accordionItem.length === 0) accordionItem = clicked.parents('li');\n app.accordionToggle(accordionItem);\n }\n \n // Load Page\n if (app.params.ajaxLinks && !clicked.is(app.params.ajaxLinks) || !isLink || !app.params.router) {\n return;\n }\n if (isLink) {\n e.preventDefault();\n }\n \n var validUrl = url && url.length > 0 && url !== '#' && !isTabLink;\n var template = clicked.attr('data-template');\n if (validUrl || clicked.hasClass('back') || template) {\n var view;\n if (clicked.attr('data-view')) {\n view = $(clicked.attr('data-view'))[0].f7View;\n }\n else {\n view = clicked.parents('.' + app.params.viewClass)[0] && clicked.parents('.' + app.params.viewClass)[0].f7View;\n if (view && view.params.linksView) {\n if (typeof view.params.linksView === 'string') view = $(view.params.linksView)[0].f7View;\n else if (view.params.linksView instanceof View) view = view.params.linksView;\n }\n }\n if (!view) {\n if (app.mainView) view = app.mainView;\n }\n if (!view) return;\n \n var pageName;\n if (!template) {\n if (url.indexOf('#') === 0 && url !== '#') {\n if (view.params.domCache) {\n pageName = url.split('#')[1];\n url = undefined;\n }\n else return;\n }\n if (url === '#' && !clicked.hasClass('back')) return;\n }\n else {\n url = undefined;\n }\n \n var animatePages;\n if (clicked.attr('data-animatePages')) {\n animatePages = toBoolean(clicked.attr('data-animatePages'));\n }\n else {\n if (clicked.hasClass('with-animation')) animatePages = true;\n if (clicked.hasClass('no-animation')) animatePages = false;\n }\n \n var options = {\n animatePages: animatePages,\n ignoreCache: toBoolean(clicked.attr('data-ignoreCache')),\n force: toBoolean(clicked.attr('data-force')),\n reload: toBoolean(clicked.attr('data-reload')),\n reloadPrevious: toBoolean(clicked.attr('data-reloadPrevious')),\n pageName: pageName,\n url: url\n };\n \n if (app.params.template7Pages) {\n options.contextName = clicked.attr('data-contextName');\n var context = clicked.attr('data-context');\n if (context) {\n options.context = JSON.parse(context);\n }\n }\n if (template && template in t7.templates) {\n options.template = t7.templates[template];\n }\n \n if (clicked.hasClass('back')) view.router.back(options);\n else view.router.load(options);\n }\n }\n $(document).on('click', 'a, .open-panel, .close-panel, .panel-overlay, .modal-overlay, .popup-overlay, .swipeout-delete, .swipeout-close, .close-popup, .open-popup, .open-popover, .open-login-screen, .close-login-screen .smart-select, .toggle-sortable, .open-sortable, .close-sortable, .accordion-item-toggle, .close-picker', handleClicks);\n if (app.params.scrollTopOnNavbarClick || app.params.scrollTopOnStatusbarClick) {\n $(document).on('click', '.statusbar-overlay, .navbar .center', handleScrollTop);\n }\n \n // Prevent scrolling on overlays\n function preventScrolling(e) {\n e.preventDefault();\n }\n if (app.support.touch) {\n $(document).on('touchstart', '.panel-overlay, .modal-overlay, .preloader-indicator-overlay, .popup-overlay, .searchbar-overlay', preventScrolling);\n }\n };\n \n"," /*======================================================\n ************ App Resize Actions ************\n ======================================================*/\n // Prevent iPad horizontal body scrolling when soft keyboard is opened\n function _fixIpadBodyScrolLeft() {\n if (app.device.ipad) {\n document.body.scrollLeft = 0;\n setTimeout(function () {\n document.body.scrollLeft = 0;\n }, 0);\n }\n }\n app.initResize = function () {\n $(window).on('resize', app.resize);\n $(window).on('orientationchange', app.orientationchange);\n };\n app.resize = function () {\n if (app.sizeNavbars) app.sizeNavbars();\n _fixIpadBodyScrolLeft();\n \n };\n app.orientationchange = function () {\n if (app.device && app.device.minimalUi) {\n if (window.orientation === 90 || window.orientation === -90) document.body.scrollTop = 0;\n }\n _fixIpadBodyScrolLeft();\n };\n \n"," /*===============================================================================\n ************ Store and parse forms data ************\n ===============================================================================*/\n app.formsData = {};\n app.formStoreData = function (formId, formJSON) {\n // Store form data in app.formsData\n app.formsData[formId] = formJSON;\n \n // Store form data in local storage also\n app.ls['f7form-' + formId] = JSON.stringify(formJSON);\n };\n app.formDeleteData = function (formId) {\n // Delete form data from app.formsData\n if (app.formsData[formId]) {\n app.formsData[formId] = '';\n delete app.formsData[formId];\n }\n \n // Delete form data from local storage also\n if (app.ls['f7form-' + formId]) {\n app.ls['f7form-' + formId] = '';\n app.ls.removeItem('f7form-' + formId);\n }\n };\n app.formGetData = function (formId) {\n // First of all check in local storage\n if (app.ls['f7form-' + formId]) {\n return JSON.parse(app.ls['f7form-' + formId]);\n }\n // Try to get it from formsData obj\n else if (app.formsData[formId]) return app.formsData[formId];\n };\n app.formToJSON = function (form) {\n form = $(form);\n if (form.length !== 1) return false;\n \n // Form data\n var formData = {};\n \n // Skip input types\n var skipTypes = ['submit', 'image', 'button', 'file'];\n var skipNames = [];\n form.find('input, select, textarea').each(function () {\n var input = $(this);\n var name = input.attr('name');\n var type = input.attr('type');\n var tag = this.nodeName.toLowerCase();\n if (skipTypes.indexOf(type) >= 0) return;\n if (skipNames.indexOf(name) >= 0 || !name) return;\n if (tag === 'select' && input.attr('multiple')) {\n skipNames.push(name);\n formData[name] = [];\n form.find('select[name=\"' + name + '\"] option').each(function () {\n if (this.selected) formData[name].push(this.value);\n });\n }\n else {\n switch (type) {\n case 'checkbox' :\n skipNames.push(name);\n formData[name] = [];\n form.find('input[name=\"' + name + '\"]').each(function () {\n if (this.checked) formData[name].push(this.value);\n });\n break;\n case 'radio' :\n skipNames.push(name);\n form.find('input[name=\"' + name + '\"]').each(function () {\n if (this.checked) formData[name] = this.value;\n });\n break;\n default :\n formData[name] = input.val();\n break;\n }\n }\n \n });\n form.trigger('formToJSON', {formData: formData});\n \n return formData;\n };\n app.formFromJSON = function (form, formData) {\n form = $(form);\n if (form.length !== 1) return false;\n \n // Skip input types\n var skipTypes = ['submit', 'image', 'button', 'file'];\n var skipNames = [];\n \n form.find('input, select, textarea').each(function () {\n var input = $(this);\n var name = input.attr('name');\n var type = input.attr('type');\n var tag = this.nodeName.toLowerCase();\n if (!formData[name]) return;\n if (skipTypes.indexOf(type) >= 0) return;\n if (skipNames.indexOf(name) >= 0 || !name) return;\n if (tag === 'select' && input.attr('multiple')) {\n skipNames.push(name);\n form.find('select[name=\"' + name + '\"] option').each(function () {\n if (formData[name].indexOf(this.value) >= 0) this.selected = true;\n else this.selected = false;\n });\n }\n else {\n switch (type) {\n case 'checkbox' :\n skipNames.push(name);\n form.find('input[name=\"' + name + '\"]').each(function () {\n if (formData[name].indexOf(this.value) >= 0) this.checked = true;\n else this.checked = false;\n });\n break;\n case 'radio' :\n skipNames.push(name);\n form.find('input[name=\"' + name + '\"]').each(function () {\n if (formData[name] === this.value) this.checked = true;\n else this.checked = false;\n });\n break;\n default :\n input.val(formData[name]);\n break;\n }\n }\n \n });\n form.trigger('formFromJSON', {formData: formData});\n };\n app.initFormsStorage = function (pageContainer) {\n pageContainer = $(pageContainer);\n if (pageContainer.length === 0) return;\n \n var forms = pageContainer.find('form.store-data');\n if (forms.length === 0) return;\n \n // Parse forms data and fill form if there is such data\n forms.each(function () {\n var id = this.getAttribute('id');\n if (!id) return;\n var formData = app.formGetData(id);\n if (formData) app.formFromJSON(this, formData);\n });\n // Update forms data on inputs change\n function storeForm() {\n /*jshint validthis:true */\n var form = $(this);\n var formId = form[0].id;\n if (!formId) return;\n var formJSON = app.formToJSON(form);\n if (!formJSON) return;\n app.formStoreData(formId, formJSON);\n form.trigger('store', {data: formJSON});\n }\n forms.on('change submit', storeForm);\n \n // Detach Listeners\n function pageBeforeRemove() {\n forms.off('change submit', storeForm);\n pageContainer.off('pageBeforeRemove', pageBeforeRemove);\n }\n pageContainer.on('pageBeforeRemove', pageBeforeRemove);\n };\n \n // Ajax submit on forms\n $(document).on('submit change', 'form.ajax-submit, form.ajax-submit-onchange', function (e) {\n var form = $(this);\n if (e.type === 'change' && !form.hasClass('ajax-submit-onchange')) return;\n if (e.type === 'submit') e.preventDefault();\n \n var method = form.attr('method') || 'GET';\n var contentType = form.attr('enctype');\n \n var url = form.attr('action');\n if (!url) return;\n \n var data;\n if (method === 'POST') data = new FormData(form[0]);\n else data = $.serializeObject(app.formToJSON(form[0]));\n \n var xhr = $.ajax({\n method: method,\n url: url,\n contentType: contentType,\n data: data,\n beforeSend: function (xhr) {\n form.trigger('beforeSubmit', {data:data, xhr: xhr});\n },\n error: function (xhr) {\n form.trigger('submitError', {data:data, xhr: xhr}); \n },\n success: function (data) {\n form.trigger('submitted', {data: data, xhr: xhr});\n }\n });\n });\n \n \n"," /*======================================================\n ************ Handle Browser's History ************\n ======================================================*/\n app.pushStateQueue = [];\n app.pushStateClearQueue = function () {\n if (app.pushStateQueue.length === 0) return;\n var queue = app.pushStateQueue.pop();\n var animatePages;\n if (app.params.pushStateNoAnimation === true) animatePages = false;\n if (queue.action === 'back') {\n app.router.back(queue.view, {animatePages: animatePages});\n }\n if (queue.action === 'loadPage') {\n app.router.load(queue.view, {url: queue.stateUrl, animatePages: animatePages, pushState: false});\n }\n if (queue.action === 'loadContent') {\n app.router.load(queue.view, {content: queue.stateContent, animatePages: animatePages, pushState: false});\n }\n if (queue.action === 'loadPageName') {\n app.router.load(queue.view, {pageName: queue.statePageName, animatePages: animatePages, pushState: false});\n }\n };\n \n app.initPushState = function () {\n var blockPopstate = true;\n $(window).on('load', function () {\n setTimeout(function () {\n blockPopstate = false;\n }, 0);\n });\n function handlePopState(e) {\n if (blockPopstate) return;\n var mainView = app.mainView;\n if (!mainView) return;\n var state = e.state;\n if (!state) {\n state = {\n viewIndex: app.views.indexOf(mainView),\n url : mainView.history[0]\n };\n }\n if (state.viewIndex < 0) return;\n var view = app.views[state.viewIndex];\n var stateUrl = state && state.url || undefined;\n var stateContent = state && state.content || undefined;\n var statePageName = state && state.pageName || undefined;\n var animatePages;\n \n if (app.params.pushStateNoAnimation === true) animatePages = false;\n \n if (stateUrl !== view.url) {\n if (view.history.indexOf(stateUrl) >= 0) {\n // Go Back\n if (view.allowPageChange) {\n app.router.back(view, {url:undefined, animatePages: animatePages, pushState: false, preloadOnly:false});\n }\n else {\n app.pushStateQueue.push({\n action: 'back',\n view: view\n });\n }\n }\n else if (stateContent) {\n // Load Page\n if (view.allowPageChange) {\n app.router.load(view, {content:stateContent, animatePages: animatePages, pushState: false});\n }\n else {\n app.pushStateQueue.unshift({\n action: 'loadContent',\n stateContent: stateContent,\n view: view\n });\n }\n \n }\n else if (statePageName) {\n // Load Page by page name with Dom Cache\n if (view.allowPageChange) {\n app.router.load(view, {pageName:statePageName, animatePages: animatePages, pushState: false});\n }\n else {\n app.pushStateQueue.unshift({\n action: 'loadPageName',\n statePageName: statePageName,\n view: view\n });\n }\n }\n else {\n // Load Page\n if (view.allowPageChange) {\n app.router.load(view, {url:stateUrl, animatePages: animatePages, pushState: false});\n }\n else {\n app.pushStateQueue.unshift({\n action: 'loadPage',\n stateUrl: stateUrl,\n view: view\n });\n }\n }\n }\n }\n $(window).on('popstate', handlePopState);\n };\n \n"," /*===========================\n Framework7 Swiper Additions\n ===========================*/\n app.swiper = function (container, params) {\n return new Swiper(container, params);\n };\n app.initSwiper = function (pageContainer) {\n var page = $(pageContainer);\n var swipers = page.find('.swiper-init');\n if (swipers.length === 0) return;\n function destroySwiperOnRemove(slider) {\n function destroySwiper() {\n slider.destroy();\n page.off('pageBeforeRemove', destroySwiper);\n }\n page.on('pageBeforeRemove', destroySwiper);\n }\n for (var i = 0; i < swipers.length; i++) {\n var swiper = swipers.eq(i);\n var params;\n if (swiper.data('swiper')) {\n params = JSON.parse(swiper.data('swiper'));\n }\n else {\n params = {\n initialSlide: parseInt(swiper.data('initialSlide'), 10) || undefined,\n spaceBetween: parseInt(swiper.data('spaceBetween'), 10) || undefined,\n speed: parseInt(swiper.data('speed'), 10) || undefined,\n slidesPerView: swiper.data('slidesPerView') || undefined,\n slidesPerColumn: parseInt(swiper.data('slidesPerColumn'), 10) || undefined,\n centeredSlides: swiper.data('centeredSlides') && (swiper.data('centeredSlides') === 'true' ? true : false),\n direction: swiper.data('direction'),\n pagination: swiper.data('pagination'),\n paginationHide: swiper.data('paginationHide') && (swiper.data('paginationHide') === 'true' ? true : false),\n paginationClickable: swiper.data('paginationClickable') && (swiper.data('paginationClickable') === 'true' ? true : false),\n scrollbar: swiper.data('scrollbar'),\n scrollbarHide: swiper.data('scrollbarHide') && (swiper.data('scrollbarHide') === 'true' ? true : false),\n loop: swiper.data('loop') && (swiper.data('loop') === 'true' ? true : false),\n effect: swiper.data('effect') || 'slide',\n freeMode: swiper.data('freeMode') && (swiper.data('freeMode') === 'true' ? true : false),\n onlyExternal: swiper.data('onlyExternal') && (swiper.data('onlyExternal') === 'true' ? true : false),\n nextButton: swiper.data('nextButton'),\n prevButton: swiper.data('prevButton'),\n autoplay: swiper.data('autoplay')\n };\n }\n var _slider = app.swiper(swiper[0], params);\n destroySwiperOnRemove(_slider);\n }\n };\n app.reinitSwiper = function (pageContainer) {\n var page = $(pageContainer);\n var sliders = page.find('.swiper-init');\n if (sliders.length === 0) return;\n for (var i = 0; i < sliders.length; i++) {\n var sliderInstance = sliders[0].swiper;\n if (sliderInstance) {\n sliderInstance.onResize();\n }\n }\n };\n \n"," /*======================================================\n ************ Photo Browser ************\n ======================================================*/\n var PhotoBrowser = function (params) {\n var pb = this, i;\n \n var defaults = {\n photos : [],\n initialSlide: 0,\n spaceBetween: 20,\n speed: 300,\n zoom: true,\n maxZoom: 3,\n minZoom: 1,\n exposition: true,\n expositionHideCaptions: false,\n type: 'standalone',\n navbar: true,\n toolbar: true,\n theme: 'light',\n swipeToClose: true,\n backLinkText: 'Close',\n ofText: 'of',\n loop: false,\n lazyLoading: false,\n lazyLoadingInPrevNext: false,\n lazyLoadingOnTransitionStart: false\n };\n \n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n \n pb.params = params;\n \n var iconColor = pb.params.theme === 'dark' ? 'color-white' : '';\n \n var navbarTemplate = pb.params.navbarTemplate ||\n '<div class=\"navbar\">' +\n '<div class=\"navbar-inner\">' +\n '<div class=\"left sliding\"><a href=\"#\" class=\"link ' + (pb.params.type === 'page' && 'back') + ' close-popup photo-browser-close-link\" data-popup=\".photo-browser-popup\"><i class=\"icon icon-back ' + iconColor + '\"></i><span>' + pb.params.backLinkText + '</span></a></div>' +\n '<div class=\"center sliding\"><span class=\"photo-browser-current\"></span> <span class=\"photo-browser-of\">' + pb.params.ofText + '</span> <span class=\"photo-browser-total\"></span></div>' +\n '<div class=\"right\"></div>' +\n '</div>' +\n '</div>';\n var toolbarTemplate = pb.params.toolbarTemplate ||\n '<div class=\"toolbar tabbar\">' +\n '<div class=\"toolbar-inner\">' +\n '<a href=\"#\" class=\"link photo-browser-prev\"><i class=\"icon icon-prev ' + iconColor + '\"></i></a>' +\n '<a href=\"#\" class=\"link photo-browser-next\"><i class=\"icon icon-next ' + iconColor + '\"></i></a>' +\n '</div>' +\n '</div>';\n \n var template = pb.params.template ||\n '<div class=\"photo-browser photo-browser-' + pb.params.theme + '\">' +\n '<div class=\"view navbar-fixed toolbar-fixed\">' +\n '{{navbar}}' +\n '<div data-page=\"photo-browser-slides\" class=\"page no-toolbar {{noNavbar}} toolbar-fixed navbar-fixed\">' +\n '{{toolbar}}' +\n '{{captions}}' +\n '<div class=\"photo-browser-swiper-container swiper-container\">' +\n '<div class=\"photo-browser-swiper-wrapper swiper-wrapper\">' +\n '{{photos}}' +\n '</div>' +\n '</div>' +\n '</div>' +\n '</div>' +\n '</div>';\n \n var photoTemplate = !pb.params.lazyLoading ? \n (pb.params.photoTemplate || '<div class=\"photo-browser-slide swiper-slide\"><span class=\"photo-browser-zoom-container\"><img src=\"{{url}}\"></span></div>') : \n (pb.params.photoLazyTemplate || '<div class=\"photo-browser-slide photo-browser-slide-lazy swiper-slide\"><div class=\"preloader' + (pb.params.theme === 'dark' ? ' preloader-white' : '') + '\"></div><span class=\"photo-browser-zoom-container\"><img data-src=\"{{url}}\"></span></div>');\n \n var captionsTheme = pb.params.captionsTheme || pb.params.theme;\n var captionsTemplate = pb.params.captionsTemplate || '<div class=\"photo-browser-captions photo-browser-captions-' + captionsTheme + '\">{{captions}}</div>';\n var captionTemplate = pb.params.captionTemplate || '<div class=\"photo-browser-caption\" data-caption-index=\"{{captionIndex}}\">{{caption}}</div>';\n \n var objectTemplate = pb.params.objectTemplate || '<div class=\"photo-browser-slide photo-browser-object-slide swiper-slide\">{{html}}</div>';\n var photosHtml = '';\n var captionsHtml = '';\n for (i = 0; i < pb.params.photos.length; i ++) {\n var photo = pb.params.photos[i];\n var thisTemplate = '';\n \n //check if photo is a string or string-like object, for backwards compatibility \n if (typeof(photo) === 'string' || photo instanceof String) {\n \n //check if \"photo\" is html object\n if (photo.indexOf('<') >= 0 || photo.indexOf('>') >= 0) {\n thisTemplate = objectTemplate.replace(/{{html}}/g, photo);\n } else {\n thisTemplate = photoTemplate.replace(/{{url}}/g, photo);\n }\n \n //photo is a string, thus has no caption, so remove the caption template placeholder\n //otherwise check if photo is an object with a url property\n } else if (typeof(photo) === 'object') {\n \n //check if \"photo\" is html object\n if (photo.hasOwnProperty('html') && photo.html.length > 0) {\n thisTemplate = objectTemplate.replace(/{{html}}/g, photo.html);\n } else if (photo.hasOwnProperty('url') && photo.url.length > 0) {\n thisTemplate = photoTemplate.replace(/{{url}}/g, photo.url);\n }\n \n //check if photo has a caption\n if (photo.hasOwnProperty('caption') && photo.caption.length > 0) {\n captionsHtml += captionTemplate.replace(/{{caption}}/g, photo.caption).replace(/{{captionIndex}}/g, i);\n } else {\n thisTemplate = thisTemplate.replace(/{{caption}}/g, '');\n }\n }\n \n photosHtml += thisTemplate;\n \n }\n \n var htmlTemplate = template\n .replace('{{navbar}}', (pb.params.navbar ? navbarTemplate : ''))\n .replace('{{noNavbar}}', (pb.params.navbar ? '' : 'no-navbar'))\n .replace('{{photos}}', photosHtml)\n .replace('{{captions}}', captionsTemplate.replace(/{{captions}}/g, captionsHtml))\n .replace('{{toolbar}}', (pb.params.toolbar ? toolbarTemplate : ''));\n \n pb.activeIndex = pb.params.initialSlide;\n pb.openIndex = pb.activeIndex;\n pb.opened = false;\n \n pb.open = function (index) {\n if (typeof index === 'undefined') index = pb.activeIndex;\n index = parseInt(index, 10);\n if (pb.opened && pb.swiper) {\n pb.swiper.slideTo(index);\n return;\n }\n pb.opened = true;\n pb.openIndex = index;\n pb.initialLazyLoaded = false;\n if (pb.params.type === 'standalone') {\n $('body').append(htmlTemplate);\n }\n if (pb.params.type === 'popup') {\n pb.popup = app.popup('<div class=\"popup photo-browser-popup\">' + htmlTemplate + '</div>');\n $(pb.popup).on('closed', pb.onPopupClose);\n }\n if (pb.params.type === 'page') {\n $(document).on('pageBeforeInit', pb.onPageBeforeInit);\n $(document).on('pageBeforeRemove', pb.onPageBeforeRemove);\n if (!pb.params.view) pb.params.view = app.mainView;\n pb.params.view.loadContent(htmlTemplate);\n return;\n }\n pb.layout(pb.openIndex);\n if (pb.params.onOpen) {\n pb.params.onOpen(pb);\n }\n \n };\n pb.close = function () {\n pb.opened = false;\n if (!pb.swiperContainer || pb.swiperContainer.length === 0) {\n return;\n }\n if (pb.params.onClose) {\n pb.params.onClose(pb);\n }\n // Detach events\n pb.attachEvents(true);\n // Delete from DOM\n if (pb.params.type === 'standalone') {\n pb.container.removeClass('photo-browser-in').addClass('photo-browser-out').animationEnd(function () {\n pb.container.remove();\n });\n }\n // Destroy slider\n pb.swiper.destroy();\n // Delete references\n pb.swiper = pb.swiperContainer = pb.swiperWrapper = pb.slides = gestureSlide = gestureImg = gestureImgWrap = undefined;\n };\n \n pb.onPopupClose = function (e) {\n pb.close();\n $(pb.popup).off('pageBeforeInit', pb.onPopupClose);\n };\n pb.onPageBeforeInit = function (e) {\n if (e.detail.page.name === 'photo-browser-slides') {\n pb.layout(pb.openIndex);\n }\n $(document).off('pageBeforeInit', pb.onPageBeforeInit);\n };\n pb.onPageBeforeRemove = function (e) {\n if (e.detail.page.name === 'photo-browser-slides') {\n pb.close();\n }\n $(document).off('pageBeforeRemove', pb.onPageBeforeRemove);\n };\n \n pb.loadImageInSlide = function (swiper, index) {\n if (!swiper || typeof index === 'undefined') return;\n if (swiper.slides.length === 0) return;\n \n var slide = swiper.slides.eq(index);\n if (!slide.hasClass('photo-browser-slide-lazy')) return;\n \n var img = slide.find('img');\n if (img.length === 0) return;\n \n var image = new Image();\n var src = img.attr('data-src');\n \n image.onload = function () {\n img.attr('src', src);\n img.removeAttr('data-src');\n slide.removeClass('photo-browser-slide-lazy').find('.preloader').remove();\n if (pb.params.onImageLoaded) {\n pb.params.onImageLoaded(pb, slide[0], img[0]);\n }\n };\n image.src = src;\n \n if (pb.params.onImageLoad) {\n pb.params.onImageLoad(pb, slide[0], img[0]);\n }\n };\n \n pb.lazyLoading = function (swiper, activeIndex) {\n pb.loadImageInSlide(swiper, activeIndex);\n if (pb.params.lazyLoadingInPrevNext) {\n var nextSlide = swiper.wrapper.find('.swiper-slide-next.photo-browser-slide-lazy');\n if (nextSlide.length > 0) pb.loadImageInSlide(swiper, nextSlide.index());\n \n var prevSlide = swiper.wrapper.find('.swiper-slide-prev.photo-browser-slide-lazy');\n if (prevSlide.length > 0) pb.loadImageInSlide(swiper, prevSlide.index());\n }\n };\n \n pb.onSliderTransitionStart = function (swiper) {\n pb.activeIndex = swiper.activeIndex;\n \n var current = swiper.activeIndex + 1;\n var total = swiper.slides.length;\n if (pb.params.loop) {\n total = total - 2;\n current = current - swiper.loopedSlides;\n if (current < 1) current = total + current;\n if (current > total) current = current - total;\n }\n pb.container.find('.photo-browser-current').text(current);\n pb.container.find('.photo-browser-total').text(total);\n \n $('.photo-browser-prev, .photo-browser-next').removeClass('photo-browser-link-inactive');\n \n if (swiper.isBeginning && !pb.params.loop) {\n $('.photo-browser-prev').addClass('photo-browser-link-inactive');\n }\n if (swiper.isEnd && !pb.params.loop) {\n $('.photo-browser-next').addClass('photo-browser-link-inactive');\n }\n \n // Update captions\n if (pb.captions.length > 0) {\n pb.captionsContainer.find('.photo-browser-caption-active').removeClass('photo-browser-caption-active');\n var captionIndex = pb.params.loop ? swiper.slides.eq(swiper.activeIndex).attr('data-swiper-slide-index') : pb.activeIndex;\n pb.captionsContainer.find('[data-caption-index=\"' + captionIndex + '\"]').addClass('photo-browser-caption-active');\n }\n \n // Lazy loading\n if (pb.params.lazyLoading){\n if (pb.params.lazyLoadingOnTransitionStart || (!pb.params.lazyLoadingOnTransitionStart && !pb.initialLazyLoaded)) {\n pb.initialLazyLoaded = true;\n pb.lazyLoading(swiper, pb.activeIndex);\n }\n }\n \n // Stop Video\n var previousSlideVideo = swiper.slides.eq(swiper.previousIndex).find('video');\n if (previousSlideVideo.length > 0) {\n if ('pause' in previousSlideVideo[0]) previousSlideVideo[0].pause();\n }\n // Callback\n if (pb.params.onSlideChangeStart) pb.params.onSlideChangeStart(swiper);\n };\n pb.onSliderTransitionEnd = function (swiper) {\n if (pb.params.lazyLoading && !pb.params.lazyLoadingOnTransitionStart) {\n pb.lazyLoading(swiper, pb.activeIndex);\n }\n // Reset zoom\n if (pb.params.zoom && gestureSlide && swiper.previousIndex !== swiper.activeIndex) {\n gestureImg.transform('translate3d(0,0,0) scale(1)');\n gestureImgWrap.transform('translate3d(0,0,0)');\n gestureSlide = gestureImg = gestureImgWrap = undefined;\n scale = currentScale = 1;\n }\n if (pb.params.onSlideChangeEnd) pb.params.onSlideChangeEnd(swiper);\n };\n \n pb.layout = function (index) {\n if (pb.params.type === 'page') {\n pb.container = $('.photo-browser-swiper-container').parents('.view');\n }\n else {\n pb.container = $('.photo-browser');\n }\n if (pb.params.type === 'standalone') {\n pb.container.addClass('photo-browser-in');\n app.sizeNavbars(pb.container);\n }\n pb.swiperContainer = pb.container.find('.photo-browser-swiper-container');\n pb.swiperWrapper = pb.container.find('.photo-browser-swiper-wrapper');\n pb.slides = pb.container.find('.photo-browser-slide');\n pb.captionsContainer = pb.container.find('.photo-browser-captions');\n pb.captions = pb.container.find('.photo-browser-caption');\n \n var sliderSettings = {\n nextButton: pb.params.nextButton || '.photo-browser-next',\n prevButton: pb.params.prevButton || '.photo-browser-prev',\n indexButton: pb.params.indexButton,\n initialSlide: index,\n spaceBetween: pb.params.spaceBetween,\n speed: pb.params.speed,\n loop: pb.params.loop,\n onTap: function (swiper, e) {\n if (pb.params.onTap) pb.params.onTap(swiper, e);\n },\n onClick: function (swiper, e) {\n if (pb.params.exposition) pb.toggleExposition();\n if (pb.params.onClick) pb.params.onClick(swiper, e);\n },\n onDoubleTap: function (swiper, e) {\n pb.toggleZoom($(e.target).parents('.photo-browser-slide'));\n if (pb.params.onDoubleTap) pb.params.onDoubleTap(swiper, e);\n },\n onTransitionStart: function (swiper) {\n pb.onSliderTransitionStart(swiper);\n },\n onTransitionEnd: function (swiper) {\n pb.onSliderTransitionEnd(swiper); \n }\n };\n \n if (pb.params.swipeToClose && pb.params.type !== 'page') {\n sliderSettings.onTouchStart = pb.swipeCloseTouchStart;\n sliderSettings.onTouchMoveOpposite = pb.swipeCloseTouchMove;\n sliderSettings.onTouchEnd = pb.swipeCloseTouchEnd;\n }\n \n pb.swiper = app.swiper(pb.swiperContainer, sliderSettings);\n if (index === 0) {\n pb.onSliderTransitionStart(pb.swiper);\n }\n pb.attachEvents();\n };\n pb.attachEvents = function (detach) {\n var action = detach ? 'off' : 'on';\n // Slide between photos\n \n if (pb.params.zoom) {\n var target = pb.params.loop ? pb.swiper.slides : pb.slides;\n // Scale image\n target[action]('gesturestart', pb.onSlideGestureStart);\n target[action]('gesturechange', pb.onSlideGestureChange);\n target[action]('gestureend', pb.onSlideGestureEnd);\n \n // Move image\n target[action](app.touchEvents.start, pb.onSlideTouchStart);\n target[action](app.touchEvents.move, pb.onSlideTouchMove);\n target[action](app.touchEvents.end, pb.onSlideTouchEnd);\n }\n pb.container.find('.photo-browser-close-link')[action]('click', pb.close);\n };\n \n var isTouched, isMoved, touchesStart = {}, touchesCurrent = {}, touchStartTime, isScrolling, animating = false, currentTranslate;\n var allowClick = true;\n \n // Expose\n pb.exposed = false;\n pb.toggleExposition = function () {\n if (pb.container) pb.container.toggleClass('photo-browser-exposed');\n if (pb.params.expositionHideCaptions) pb.captionsContainer.toggleClass('photo-browser-captions-exposed');\n pb.exposed = !pb.exposed;\n };\n pb.enableExposition = function () {\n if (pb.container) pb.container.addClass('photo-browser-exposed');\n if (pb.params.expositionHideCaptions) pb.captionsContainer.addClass('photo-browser-captions-exposed');\n pb.exposed = true;\n };\n pb.disableExposition = function () {\n if (pb.container) pb.container.removeClass('photo-browser-exposed');\n if (pb.params.expositionHideCaptions) pb.captionsContainer.removeClass('photo-browser-captions-exposed');\n pb.exposed = false;\n };\n \n // Gestures\n var gestureSlide, gestureImg, gestureImgWrap, scale = 1, currentScale = 1, isScaling = false;\n pb.onSlideGestureStart = function (e) {\n if (!gestureSlide) {\n gestureSlide = $(this);\n gestureImg = gestureSlide.find('img, svg, canvas');\n gestureImgWrap = gestureImg.parent('.photo-browser-zoom-container');\n if (gestureImgWrap.length === 0) {\n gestureImg = undefined;\n return;\n }\n }\n gestureImg.transition(0);\n isScaling = true;\n };\n pb.onSlideGestureChange = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n scale = e.scale * currentScale;\n if (scale > pb.params.maxZoom) {\n scale = pb.params.maxZoom - 1 + Math.pow((scale - pb.params.maxZoom + 1), 0.5);\n }\n if (scale < pb.params.minZoom) {\n scale = pb.params.minZoom + 1 - Math.pow((pb.params.minZoom - scale + 1), 0.5);\n }\n gestureImg.transform('translate3d(0,0,0) scale(' + scale + ')');\n };\n pb.onSlideGestureEnd = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n scale = Math.max(Math.min(scale, pb.params.maxZoom), pb.params.minZoom);\n gestureImg.transition(pb.params.speed).transform('translate3d(0,0,0) scale(' + scale + ')');\n currentScale = scale;\n isScaling = false;\n if (scale === 1) gestureSlide = undefined;\n };\n pb.toggleZoom = function () {\n if (!gestureSlide) {\n gestureSlide = pb.swiper.slides.eq(pb.swiper.activeIndex);\n gestureImg = gestureSlide.find('img, svg, canvas');\n gestureImgWrap = gestureImg.parent('.photo-browser-zoom-container');\n }\n if (!gestureImg || gestureImg.length === 0) return;\n gestureImgWrap.transition(300).transform('translate3d(0,0,0)');\n if (scale && scale !== 1) {\n scale = currentScale = 1;\n gestureImg.transition(300).transform('translate3d(0,0,0) scale(1)');\n gestureSlide = undefined;\n }\n else {\n scale = currentScale = pb.params.maxZoom;\n gestureImg.transition(300).transform('translate3d(0,0,0) scale(' + scale + ')');\n }\n };\n \n var imageIsTouched, imageIsMoved, imageCurrentX, imageCurrentY, imageMinX, imageMinY, imageMaxX, imageMaxY, imageWidth, imageHeight, imageTouchesStart = {}, imageTouchesCurrent = {}, imageStartX, imageStartY, velocityPrevPositionX, velocityPrevTime, velocityX, velocityPrevPositionY, velocityY;\n \n pb.onSlideTouchStart = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n if (imageIsTouched) return;\n if (app.device.os === 'android') e.preventDefault();\n imageIsTouched = true;\n imageTouchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n imageTouchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n };\n pb.onSlideTouchMove = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n pb.swiper.allowClick = false;\n if (!imageIsTouched || !gestureSlide) return;\n \n if (!imageIsMoved) {\n imageWidth = gestureImg[0].offsetWidth;\n imageHeight = gestureImg[0].offsetHeight;\n imageStartX = $.getTranslate(gestureImgWrap[0], 'x') || 0;\n imageStartY = $.getTranslate(gestureImgWrap[0], 'y') || 0;\n gestureImgWrap.transition(0);\n }\n // Define if we need image drag\n var scaledWidth = imageWidth * scale;\n var scaledHeight = imageHeight * scale;\n \n if (scaledWidth < pb.swiper.width && scaledHeight < pb.swiper.height) return;\n \n imageMinX = Math.min((pb.swiper.width / 2 - scaledWidth / 2), 0);\n imageMaxX = -imageMinX;\n imageMinY = Math.min((pb.swiper.height / 2 - scaledHeight / 2), 0);\n imageMaxY = -imageMinY;\n \n imageTouchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n imageTouchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n \n if (!imageIsMoved && !isScaling) {\n if (\n (Math.floor(imageMinX) === Math.floor(imageStartX) && imageTouchesCurrent.x < imageTouchesStart.x) ||\n (Math.floor(imageMaxX) === Math.floor(imageStartX) && imageTouchesCurrent.x > imageTouchesStart.x)\n ) {\n imageIsTouched = false;\n return;\n }\n }\n e.preventDefault();\n e.stopPropagation();\n imageIsMoved = true;\n imageCurrentX = imageTouchesCurrent.x - imageTouchesStart.x + imageStartX;\n imageCurrentY = imageTouchesCurrent.y - imageTouchesStart.y + imageStartY;\n \n if (imageCurrentX < imageMinX) {\n imageCurrentX = imageMinX + 1 - Math.pow((imageMinX - imageCurrentX + 1), 0.8);\n }\n if (imageCurrentX > imageMaxX) {\n imageCurrentX = imageMaxX - 1 + Math.pow((imageCurrentX - imageMaxX + 1), 0.8);\n }\n \n if (imageCurrentY < imageMinY) {\n imageCurrentY = imageMinY + 1 - Math.pow((imageMinY - imageCurrentY + 1), 0.8);\n }\n if (imageCurrentY > imageMaxY) {\n imageCurrentY = imageMaxY - 1 + Math.pow((imageCurrentY - imageMaxY + 1), 0.8);\n }\n \n //Velocity\n if (!velocityPrevPositionX) velocityPrevPositionX = imageTouchesCurrent.x;\n if (!velocityPrevPositionY) velocityPrevPositionY = imageTouchesCurrent.y;\n if (!velocityPrevTime) velocityPrevTime = Date.now();\n velocityX = (imageTouchesCurrent.x - velocityPrevPositionX) / (Date.now() - velocityPrevTime) / 2;\n velocityY = (imageTouchesCurrent.y - velocityPrevPositionY) / (Date.now() - velocityPrevTime) / 2;\n if (Math.abs(imageTouchesCurrent.x - velocityPrevPositionX) < 2) velocityX = 0;\n if (Math.abs(imageTouchesCurrent.y - velocityPrevPositionY) < 2) velocityY = 0;\n velocityPrevPositionX = imageTouchesCurrent.x;\n velocityPrevPositionY = imageTouchesCurrent.y;\n velocityPrevTime = Date.now();\n \n gestureImgWrap.transform('translate3d(' + imageCurrentX + 'px, ' + imageCurrentY + 'px,0)');\n };\n pb.onSlideTouchEnd = function (e) {\n if (!gestureImg || gestureImg.length === 0) return;\n if (!imageIsTouched || !imageIsMoved) {\n imageIsTouched = false;\n imageIsMoved = false;\n return;\n }\n imageIsTouched = false;\n imageIsMoved = false;\n var momentumDurationX = 300;\n var momentumDurationY = 300;\n var momentumDistanceX = velocityX * momentumDurationX;\n var newPositionX = imageCurrentX + momentumDistanceX;\n var momentumDistanceY = velocityY * momentumDurationY;\n var newPositionY = imageCurrentY + momentumDistanceY;\n \n //Fix duration\n if (velocityX !== 0) momentumDurationX = Math.abs((newPositionX - imageCurrentX) / velocityX);\n if (velocityY !== 0) momentumDurationY = Math.abs((newPositionY - imageCurrentY) / velocityY);\n var momentumDuration = Math.max(momentumDurationX, momentumDurationY);\n \n imageCurrentX = newPositionX;\n imageCurrentY = newPositionY;\n \n // Define if we need image drag\n var scaledWidth = imageWidth * scale;\n var scaledHeight = imageHeight * scale;\n imageMinX = Math.min((pb.swiper.width / 2 - scaledWidth / 2), 0);\n imageMaxX = -imageMinX;\n imageMinY = Math.min((pb.swiper.height / 2 - scaledHeight / 2), 0);\n imageMaxY = -imageMinY;\n imageCurrentX = Math.max(Math.min(imageCurrentX, imageMaxX), imageMinX);\n imageCurrentY = Math.max(Math.min(imageCurrentY, imageMaxY), imageMinY);\n \n gestureImgWrap.transition(momentumDuration).transform('translate3d(' + imageCurrentX + 'px, ' + imageCurrentY + 'px,0)');\n };\n \n // Swipe Up To Close\n var swipeToCloseIsTouched = false;\n var allowSwipeToClose = true;\n var swipeToCloseDiff, swipeToCloseStart, swipeToCloseCurrent, swipeToCloseStarted = false, swipeToCloseActiveSlide, swipeToCloseTimeStart;\n pb.swipeCloseTouchStart = function (swiper, e) {\n if (!allowSwipeToClose) return;\n swipeToCloseIsTouched = true;\n };\n pb.swipeCloseTouchMove = function (swiper, e) {\n if (!swipeToCloseIsTouched) return;\n if (!swipeToCloseStarted) {\n swipeToCloseStarted = true;\n swipeToCloseStart = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n swipeToCloseActiveSlide = pb.swiper.slides.eq(pb.swiper.activeIndex);\n swipeToCloseTimeStart = (new Date()).getTime();\n }\n e.preventDefault();\n swipeToCloseCurrent = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n swipeToCloseDiff = swipeToCloseStart - swipeToCloseCurrent;\n var opacity = 1 - Math.abs(swipeToCloseDiff) / 300;\n swipeToCloseActiveSlide.transform('translate3d(0,' + (-swipeToCloseDiff) + 'px,0)');\n pb.swiper.container.css('opacity', opacity).transition(0);\n };\n pb.swipeCloseTouchEnd = function (swiper, e) {\n swipeToCloseIsTouched = false;\n if (!swipeToCloseStarted) {\n swipeToCloseStarted = false;\n return;\n }\n swipeToCloseStarted = false;\n allowSwipeToClose = false;\n var diff = Math.abs(swipeToCloseDiff);\n var timeDiff = (new Date()).getTime() - swipeToCloseTimeStart;\n if ((timeDiff < 300 && diff > 20) || (timeDiff >= 300 && diff > 100)) {\n setTimeout(function () {\n if (pb.params.type === 'standalone') {\n pb.close();\n }\n if (pb.params.type === 'popup') {\n app.closeModal(pb.popup);\n }\n if (pb.params.onSwipeToClose) {\n pb.params.onSwipeToClose(pb);\n }\n allowSwipeToClose = true;\n }, 0);\n return;\n }\n if (diff !== 0) {\n swipeToCloseActiveSlide.addClass('transitioning').transitionEnd(function () {\n allowSwipeToClose = true;\n swipeToCloseActiveSlide.removeClass('transitioning');\n });\n }\n else {\n allowSwipeToClose = true;\n }\n pb.swiper.container.css('opacity', '').transition('');\n swipeToCloseActiveSlide.transform('');\n };\n \n return pb;\n };\n \n app.photoBrowser = function (params) {\n return new PhotoBrowser(params);\n };\n \n"," /*======================================================\n ************ Picker ************\n ======================================================*/\n var Picker = function (params) {\n var p = this;\n var defaults = {\n updateValuesOnMomentum: false,\n updateValuesOnTouchmove: true,\n rotateEffect: false,\n momentumRatio: 7,\n freeMode: false,\n // Common settings\n scrollToInput: true,\n inputReadOnly: true,\n convertToPopover: true,\n toolbar: true,\n toolbarCloseText: 'Done',\n toolbarTemplate: \n '<div class=\"toolbar\">' +\n '<div class=\"toolbar-inner\">' +\n '<div class=\"left\"></div>' +\n '<div class=\"right\">' +\n '<a href=\"#\" class=\"link close-picker\">{{closeText}}</a>' +\n '</div>' +\n '</div>' +\n '</div>'\n };\n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n p.params = params;\n p.cols = [];\n p.initialized = false;\n \n // Inline flag\n p.inline = p.params.container ? true : false;\n \n // 3D Transforms origin bug, only on safari\n var originBug = app.device.ios || (navigator.userAgent.toLowerCase().indexOf('safari') >= 0 && navigator.userAgent.toLowerCase().indexOf('chrome') < 0) && !app.device.android;\n \n // Should be converted to popover\n function isPopover() {\n var toPopover = false;\n if (!p.params.convertToPopover) return toPopover;\n if (!p.inline && p.params.input) {\n if (app.device.ios) {\n toPopover = app.device.ipad ? true : false;\n }\n else {\n if ($(window).width() >= 768) toPopover = true;\n }\n } \n return toPopover; \n }\n function inPopover() {\n if (p.opened && p.container && p.container.length > 0 && p.container.parents('.popover').length > 0) return true;\n else return false;\n }\n \n // Value\n p.setValue = function (arrValues, transition) {\n var valueIndex = 0;\n for (var i = 0; i < p.cols.length; i++) {\n if (p.cols[i] && !p.cols[i].divider) {\n p.cols[i].setValue(arrValues[valueIndex], transition);\n valueIndex++;\n }\n }\n };\n p.updateValue = function () {\n var newValue = [];\n var newDisplayValue = [];\n for (var i = 0; i < p.cols.length; i++) {\n if (!p.cols[i].divider) {\n newValue.push(p.cols[i].value);\n newDisplayValue.push(p.cols[i].displayValue);\n }\n }\n if (newValue.indexOf(undefined) >= 0) {\n return;\n }\n p.value = newValue;\n p.displayValue = newDisplayValue;\n if (p.params.onChange) {\n p.params.onChange(p, p.value, p.displayValue);\n }\n if (p.input && p.input.length > 0) {\n $(p.input).val(p.params.formatValue ? p.params.formatValue(p, p.value, p.displayValue) : p.value.join(' '));\n $(p.input).trigger('change');\n }\n };\n \n // Columns Handlers\n p.initPickerCol = function (colElement, updateItems) {\n var colContainer = $(colElement);\n var colIndex = colContainer.index();\n var col = p.cols[colIndex];\n if (col.divider) return;\n col.container = colContainer;\n col.wrapper = col.container.find('.picker-items-col-wrapper');\n col.items = col.wrapper.find('.picker-item');\n \n var i, j;\n var wrapperHeight, itemHeight, itemsHeight, minTranslate, maxTranslate;\n col.replaceValues = function (values, displayValues) {\n col.values = values;\n col.displayValues = displayValues;\n var newItemsHTML = p.columnHTML(col, true);\n col.wrapper.html(newItemsHTML);\n col.items = col.wrapper.find('.picker-item');\n col.calcSize();\n col.setValue(col.values[0], 0, true);\n };\n col.calcSize = function () {\n if (p.params.rotateEffect) {\n col.container.removeClass('picker-items-col-absolute');\n if (!col.width) col.container.css({width:''});\n }\n var colWidth, colHeight;\n colWidth = 0;\n colHeight = col.container[0].offsetHeight;\n wrapperHeight = col.wrapper[0].offsetHeight;\n itemHeight = col.items[0].offsetHeight;\n itemsHeight = itemHeight * col.items.length;\n minTranslate = colHeight / 2 - itemsHeight + itemHeight / 2;\n maxTranslate = colHeight / 2 - itemHeight / 2; \n if (col.width) {\n colWidth = col.width;\n if (parseInt(colWidth, 10) === colWidth) colWidth = colWidth + 'px';\n col.container.css({width: colWidth});\n }\n if (p.params.rotateEffect) {\n if (!col.width) {\n col.items.each(function () {\n var item = $(this);\n item.css({width:'auto'});\n colWidth = Math.max(colWidth, item[0].offsetWidth);\n item.css({width:''});\n });\n col.container.css({width: (colWidth + 2) + 'px'});\n }\n col.container.addClass('picker-items-col-absolute');\n }\n };\n col.calcSize();\n \n col.wrapper.transform('translate3d(0,' + maxTranslate + 'px,0)').transition(0);\n \n \n var activeIndex = 0;\n var animationFrameId;\n \n // Set Value Function\n col.setValue = function (newValue, transition, valueCallbacks) {\n if (typeof transition === 'undefined') transition = '';\n var newActiveIndex = col.wrapper.find('.picker-item[data-picker-value=\"' + newValue + '\"]').index();\n if(typeof newActiveIndex === 'undefined' || newActiveIndex === -1) {\n return;\n }\n var newTranslate = -newActiveIndex * itemHeight + maxTranslate;\n // Update wrapper\n col.wrapper.transition(transition);\n col.wrapper.transform('translate3d(0,' + (newTranslate) + 'px,0)');\n \n // Watch items\n if (p.params.updateValuesOnMomentum && col.activeIndex && col.activeIndex !== newActiveIndex ) {\n $.cancelAnimationFrame(animationFrameId);\n col.wrapper.transitionEnd(function(){\n $.cancelAnimationFrame(animationFrameId);\n });\n updateDuringScroll();\n }\n \n // Update items\n col.updateItems(newActiveIndex, newTranslate, transition, valueCallbacks);\n };\n \n col.updateItems = function (activeIndex, translate, transition, valueCallbacks) {\n if (typeof translate === 'undefined') {\n translate = $.getTranslate(col.wrapper[0], 'y');\n }\n if(typeof activeIndex === 'undefined') activeIndex = -Math.round((translate - maxTranslate)/itemHeight);\n if (activeIndex < 0) activeIndex = 0;\n if (activeIndex >= col.items.length) activeIndex = col.items.length - 1;\n var previousActiveIndex = col.activeIndex;\n col.activeIndex = activeIndex;\n col.wrapper.find('.picker-selected, .picker-after-selected, .picker-before-selected').removeClass('picker-selected picker-after-selected picker-before-selected');\n \n col.items.transition(transition);\n var selectedItem = col.items.eq(activeIndex).addClass('picker-selected').transform('');\n var prevItems = selectedItem.prevAll().addClass('picker-before-selected');\n var nextItems = selectedItem.nextAll().addClass('picker-after-selected');\n \n if (valueCallbacks || typeof valueCallbacks === 'undefined') {\n // Update values\n col.value = selectedItem.attr('data-picker-value');\n col.displayValue = col.displayValues ? col.displayValues[activeIndex] : col.value;\n // On change callback\n if (previousActiveIndex !== activeIndex) {\n if (col.onChange) {\n col.onChange(p, col.value, col.displayValue);\n }\n p.updateValue();\n }\n }\n \n // Set 3D rotate effect\n if (!p.params.rotateEffect) {\n return;\n }\n var percentage = (translate - (Math.floor((translate - maxTranslate)/itemHeight) * itemHeight + maxTranslate)) / itemHeight;\n \n col.items.each(function () {\n var item = $(this);\n var itemOffsetTop = item.index() * itemHeight;\n var translateOffset = maxTranslate - translate;\n var itemOffset = itemOffsetTop - translateOffset;\n var percentage = itemOffset / itemHeight;\n \n var itemsFit = Math.ceil(col.height / itemHeight / 2) + 1;\n \n var angle = (-18*percentage);\n if (angle > 180) angle = 180;\n if (angle < -180) angle = -180;\n // Far class\n if (Math.abs(percentage) > itemsFit) item.addClass('picker-item-far');\n else item.removeClass('picker-item-far');\n // Set transform\n item.transform('translate3d(0, ' + (-translate + maxTranslate) + 'px, ' + (originBug ? -110 : 0) + 'px) rotateX(' + angle + 'deg)');\n });\n };\n \n function updateDuringScroll() {\n animationFrameId = $.requestAnimationFrame(function () {\n col.updateItems(undefined, undefined, 0);\n updateDuringScroll();\n });\n }\n \n // Update items on init\n if (updateItems) col.updateItems(0, maxTranslate, 0);\n \n var allowItemClick = true;\n var isTouched, isMoved, touchStartY, touchCurrentY, touchStartTime, touchEndTime, startTranslate, returnTo, currentTranslate, prevTranslate, velocityTranslate, velocityTime;\n function handleTouchStart (e) {\n if (isMoved || isTouched) return;\n e.preventDefault();\n isTouched = true;\n touchStartY = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n \n allowItemClick = true;\n startTranslate = currentTranslate = $.getTranslate(col.wrapper[0], 'y');\n }\n function handleTouchMove (e) {\n if (!isTouched) return;\n e.preventDefault();\n allowItemClick = false;\n touchCurrentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (!isMoved) {\n // First move\n $.cancelAnimationFrame(animationFrameId);\n isMoved = true;\n startTranslate = currentTranslate = $.getTranslate(col.wrapper[0], 'y');\n col.wrapper.transition(0);\n }\n e.preventDefault();\n \n var diff = touchCurrentY - touchStartY;\n currentTranslate = startTranslate + diff;\n returnTo = undefined;\n \n // Normalize translate\n if (currentTranslate < minTranslate) {\n currentTranslate = minTranslate - Math.pow(minTranslate - currentTranslate, 0.8);\n returnTo = 'min';\n }\n if (currentTranslate > maxTranslate) {\n currentTranslate = maxTranslate + Math.pow(currentTranslate - maxTranslate, 0.8);\n returnTo = 'max';\n }\n // Transform wrapper\n col.wrapper.transform('translate3d(0,' + currentTranslate + 'px,0)');\n \n // Update items\n col.updateItems(undefined, currentTranslate, 0, p.params.updateValuesOnTouchmove);\n \n // Calc velocity\n velocityTranslate = currentTranslate - prevTranslate || currentTranslate;\n velocityTime = (new Date()).getTime();\n prevTranslate = currentTranslate;\n }\n function handleTouchEnd (e) {\n if (!isTouched || !isMoved) {\n isTouched = isMoved = false;\n return;\n }\n isTouched = isMoved = false;\n col.wrapper.transition('');\n if (returnTo) {\n if (returnTo === 'min') {\n col.wrapper.transform('translate3d(0,' + minTranslate + 'px,0)');\n }\n else col.wrapper.transform('translate3d(0,' + maxTranslate + 'px,0)');\n }\n touchEndTime = new Date().getTime();\n var velocity, newTranslate;\n if (touchEndTime - touchStartTime > 300) {\n newTranslate = currentTranslate;\n }\n else {\n velocity = Math.abs(velocityTranslate / (touchEndTime - velocityTime));\n newTranslate = currentTranslate + velocityTranslate * p.params.momentumRatio;\n }\n \n newTranslate = Math.max(Math.min(newTranslate, maxTranslate), minTranslate);\n \n // Active Index\n var activeIndex = -Math.floor((newTranslate - maxTranslate)/itemHeight);\n \n // Normalize translate\n if (!p.params.freeMode) newTranslate = -activeIndex * itemHeight + maxTranslate;\n \n // Transform wrapper\n col.wrapper.transform('translate3d(0,' + (parseInt(newTranslate,10)) + 'px,0)');\n \n // Update items\n col.updateItems(activeIndex, newTranslate, '', true);\n \n // Watch items\n if (p.params.updateValuesOnMomentum) {\n updateDuringScroll();\n col.wrapper.transitionEnd(function(){\n $.cancelAnimationFrame(animationFrameId);\n });\n }\n \n // Allow click\n setTimeout(function () {\n allowItemClick = true;\n }, 100);\n }\n \n function handleClick(e) {\n if (!allowItemClick) return;\n $.cancelAnimationFrame(animationFrameId);\n /*jshint validthis:true */\n var value = $(this).attr('data-picker-value');\n col.setValue(value);\n }\n \n col.container.on(app.touchEvents.start, handleTouchStart);\n col.container.on(app.touchEvents.move, handleTouchMove);\n col.container.on(app.touchEvents.end, handleTouchEnd);\n col.items.on('click', handleClick);\n \n col.container[0].f7DestroyPickerCol = function () {\n col.container.off(app.touchEvents.start, handleTouchStart);\n col.container.off(app.touchEvents.move, handleTouchMove);\n col.container.off(app.touchEvents.end, handleTouchEnd);\n col.items.off('click', handleClick);\n };\n \n };\n p.destroyPickerCol = function (colContainer) {\n colContainer = $(colContainer);\n if ('f7DestroyPickerCol' in colContainer[0]) colContainer[0].f7DestroyPickerCol();\n };\n // Resize cols\n function resizeCols() {\n if (!p.opened) return;\n for (var i = 0; i < p.cols.length; i++) {\n if (!p.cols[i].divider) {\n p.cols[i].calcSize();\n p.cols[i].setValue(p.cols[i].value, 0, false);\n }\n }\n }\n $(window).on('resize', resizeCols);\n \n // HTML Layout\n p.columnHTML = function (col, onlyItems) {\n var columnItemsHTML = '';\n var columnHTML = '';\n if (col.divider) {\n columnHTML += '<div class=\"picker-items-col picker-items-col-divider ' + (col.textAlign ? 'picker-items-col-' + col.textAlign : '') + ' ' + (col.cssClass || '') + '\">' + col.content + '</div>';\n }\n else {\n for (var j = 0; j < col.values.length; j++) {\n columnItemsHTML += '<div class=\"picker-item\" data-picker-value=\"' + col.values[j] + '\">' + (col.displayValues ? col.displayValues[j] : col.values[j]) + '</div>';\n }\n columnHTML += '<div class=\"picker-items-col ' + (col.textAlign ? 'picker-items-col-' + col.textAlign : '') + ' ' + (col.cssClass || '') + '\"><div class=\"picker-items-col-wrapper\">' + columnItemsHTML + '</div></div>';\n }\n return onlyItems ? columnItemsHTML : columnHTML;\n };\n p.layout = function () {\n var pickerHTML = '';\n var pickerClass = '';\n var i;\n p.cols = [];\n var colsHTML = '';\n for (i = 0; i < p.params.cols.length; i++) {\n var col = p.params.cols[i];\n colsHTML += p.columnHTML(p.params.cols[i]);\n p.cols.push(col);\n }\n pickerClass = 'picker-modal picker-columns ' + (p.params.cssClass || '') + (p.params.rotateEffect ? ' picker-3d' : '');\n pickerHTML =\n '<div class=\"' + (pickerClass) + '\">' +\n (p.params.toolbar ? p.params.toolbarTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText) : '') +\n '<div class=\"picker-modal-inner picker-items\">' +\n colsHTML +\n '<div class=\"picker-center-highlight\"></div>' +\n '</div>' +\n '</div>';\n \n p.pickerHTML = pickerHTML; \n };\n \n // Input Events\n function openOnInput(e) {\n e.preventDefault();\n if (p.opened) return;\n p.open();\n if (p.params.scrollToInput && !isPopover()) {\n var pageContent = p.input.parents('.page-content');\n if (pageContent.length === 0) return;\n \n var paddingTop = parseInt(pageContent.css('padding-top'), 10),\n paddingBottom = parseInt(pageContent.css('padding-bottom'), 10),\n pageHeight = pageContent[0].offsetHeight - paddingTop - p.container.height(),\n pageScrollHeight = pageContent[0].scrollHeight - paddingTop - p.container.height(),\n newPaddingBottom;\n var inputTop = p.input.offset().top - paddingTop + p.input[0].offsetHeight;\n if (inputTop > pageHeight) {\n var scrollTop = pageContent.scrollTop() + inputTop - pageHeight;\n if (scrollTop + pageHeight > pageScrollHeight) {\n newPaddingBottom = scrollTop + pageHeight - pageScrollHeight + paddingBottom;\n if (pageHeight === pageScrollHeight) {\n newPaddingBottom = p.container.height();\n }\n pageContent.css({'padding-bottom': (newPaddingBottom) + 'px'});\n }\n pageContent.scrollTop(scrollTop, 300);\n }\n }\n }\n function closeOnHTMLClick(e) {\n if (inPopover()) return;\n if (p.input && p.input.length > 0) {\n if (e.target !== p.input[0] && $(e.target).parents('.picker-modal').length === 0) p.close();\n }\n else {\n if ($(e.target).parents('.picker-modal').length === 0) p.close(); \n }\n }\n \n if (p.params.input) {\n p.input = $(p.params.input);\n if (p.params.inputReadOnly) p.input.prop('readOnly', true);\n if (!p.inline) {\n p.input.on('click', openOnInput); \n }\n if (p.params.inputReadOnly) {\n p.input.on('focus mousedown', function (e) {\n e.preventDefault();\n });\n }\n }\n \n if (!p.inline) $('html').on('click', closeOnHTMLClick);\n \n // Open\n function onPickerClose() {\n p.opened = false;\n p.input.parents('.page-content').css({'padding-bottom': ''});\n if (p.params.onClose) p.params.onClose(p);\n \n // Destroy events\n p.container.find('.picker-items-col').each(function () {\n p.destroyPickerCol(this);\n });\n }\n \n p.opened = false;\n p.open = function () {\n var toPopover = isPopover();\n \n if (!p.opened) {\n \n // Layout\n p.layout();\n \n // Append\n if (toPopover) {\n p.pickerHTML = '<div class=\"popover popover-picker-columns\"><div class=\"popover-inner\">' + p.pickerHTML + '</div></div>';\n p.popover = app.popover(p.pickerHTML, p.params.input, true);\n p.container = $(p.popover).find('.picker-modal');\n $(p.popover).on('close', function () {\n onPickerClose();\n });\n }\n else if (p.inline) {\n p.container = $(p.pickerHTML);\n p.container.addClass('picker-modal-inline');\n $(p.params.container).append(p.container);\n }\n else {\n p.container = $(app.pickerModal(p.pickerHTML));\n $(p.container)\n .on('close', function () {\n onPickerClose();\n });\n }\n \n // Store picker instance\n p.container[0].f7Picker = p;\n \n // Init Events\n p.container.find('.picker-items-col').each(function () {\n var updateItems = true;\n if ((!p.initialized && p.params.value) || (p.initialized && p.value)) updateItems = false;\n p.initPickerCol(this, updateItems);\n });\n \n // Set value\n if (!p.initialized) {\n if (p.params.value) {\n p.setValue(p.params.value, 0);\n }\n }\n else {\n if (p.value) p.setValue(p.value, 0);\n }\n }\n \n // Set flag\n p.opened = true;\n p.initialized = true;\n \n if (p.params.onOpen) p.params.onOpen(p);\n };\n \n // Close\n p.close = function () {\n if (!p.opened || p.inline) return;\n if (inPopover()) {\n app.closeModal(p.popover);\n return;\n }\n else {\n app.closeModal(p.container);\n return;\n }\n };\n \n // Destroy\n p.destroy = function () {\n p.close();\n if (p.params.input) {\n p.input.off('click focus', openOnInput);\n }\n $('html').off('click', closeOnHTMLClick);\n $(window).off('resize', resizeCols);\n };\n \n if (p.inline) {\n p.open();\n }\n \n return p;\n };\n app.picker = function (params) {\n return new Picker(params);\n };\n"," /*======================================================\n ************ Calendar ************\n ======================================================*/\n var Calendar = function (params) {\n var p = this;\n var defaults = {\n monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August' , 'September' , 'October', 'November', 'December'],\n monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n firstDay: 1, // First day of the week, Monday\n weekendDays: [0, 6], // Sunday and Saturday\n multiple: false,\n dateFormat: 'yyyy-mm-dd',\n direction: 'horizontal', // or 'vertical'\n minDate: null,\n maxDate: null,\n touchMove: true,\n animate: true,\n closeOnSelect: false,\n monthPicker: true,\n monthPickerTemplate: \n '<div class=\"picker-calendar-month-picker\">' +\n '<a href=\"#\" class=\"link icon-only picker-calendar-prev-month\"><i class=\"icon icon-prev\"></i></a>' +\n '<span class=\"current-month-value\"></span>' +\n '<a href=\"#\" class=\"link icon-only picker-calendar-next-month\"><i class=\"icon icon-next\"></i></a>' +\n '</div>',\n yearPicker: true,\n yearPickerTemplate: \n '<div class=\"picker-calendar-year-picker\">' +\n '<a href=\"#\" class=\"link icon-only picker-calendar-prev-year\"><i class=\"icon icon-prev\"></i></a>' +\n '<span class=\"current-year-value\"></span>' +\n '<a href=\"#\" class=\"link icon-only picker-calendar-next-year\"><i class=\"icon icon-next\"></i></a>' +\n '</div>',\n weekHeader: true,\n // Common settings\n scrollToInput: true,\n inputReadOnly: true,\n convertToPopover: true,\n toolbar: true,\n toolbarCloseText: 'Done',\n toolbarTemplate: \n '<div class=\"toolbar\">' +\n '<div class=\"toolbar-inner\">' +\n '{{monthPicker}}' +\n '{{yearPicker}}' +\n // '<a href=\"#\" class=\"link close-picker\">{{closeText}}</a>' +\n '</div>' +\n '</div>',\n /* Callbacks\n onMonthAdd\n onChange\n onOpen\n onClose\n onDayClick\n onMonthYearChangeStart\n onMonthYearChangeEnd\n */\n };\n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n }\n p.params = params;\n p.initialized = false;\n \n // Inline flag\n p.inline = p.params.container ? true : false;\n \n // Is horizontal\n p.isH = p.params.direction === 'horizontal';\n \n // RTL inverter\n var inverter = p.isH ? (app.rtl ? -1 : 1) : 1;\n \n // Animating flag\n p.animating = false;\n \n // Should be converted to popover\n function isPopover() {\n var toPopover = false;\n if (!p.params.convertToPopover) return toPopover;\n if (!p.inline && p.params.input) {\n if (app.device.ios) {\n toPopover = app.device.ipad ? true : false;\n }\n else {\n if ($(window).width() >= 768) toPopover = true;\n }\n } \n return toPopover; \n }\n function inPopover() {\n if (p.opened && p.container && p.container.length > 0 && p.container.parents('.popover').length > 0) return true;\n else return false;\n }\n \n // Format date\n function formatDate(date) {\n date = new Date(date);\n var year = date.getFullYear();\n var month = date.getMonth();\n var month1 = month + 1;\n var day = date.getDate();\n var weekDay = date.getDay();\n return p.params.dateFormat\n .replace(/yyyy/g, year)\n .replace(/yy/g, (year + '').substring(2))\n .replace(/mm/g, month1 < 10 ? '0' + month1 : month1)\n .replace(/m/g, month1)\n .replace(/MM/g, p.params.monthNames[month])\n .replace(/M/g, p.params.monthNamesShort[month])\n .replace(/dd/g, day < 10 ? '0' + day : day)\n .replace(/d/g, day)\n .replace(/DD/g, p.params.dayNames[weekDay])\n .replace(/D/g, p.params.dayNamesShort[weekDay]);\n }\n \n \n // Value\n p.addValue = function (value) {\n if (p.params.multiple) {\n if (!p.value) p.value = [];\n var inValuesIndex;\n for (var i = 0; i < p.value.length; i++) {\n if (new Date(value).getTime() === new Date(p.value[i]).getTime()) {\n inValuesIndex = i;\n }\n }\n if (typeof inValuesIndex === 'undefined') {\n p.value.push(value);\n }\n else {\n p.value.splice(inValuesIndex, 1);\n }\n p.updateValue();\n }\n else {\n p.value = [value];\n p.updateValue();\n }\n };\n p.setValue = function (arrValues) {\n p.value = arrValues;\n p.updateValue(); \n };\n p.updateValue = function () {\n p.wrapper.find('.picker-calendar-day-selected').removeClass('picker-calendar-day-selected');\n var i, inputValue;\n for (i = 0; i < p.value.length; i++) {\n var valueDate = new Date(p.value[i]);\n p.wrapper.find('.picker-calendar-day[data-date=\"' + valueDate.getFullYear() + '-' + valueDate.getMonth() + '-' + valueDate.getDate() + '\"]').addClass('picker-calendar-day-selected');\n }\n if (p.params.onChange) {\n p.params.onChange(p, p.value);\n }\n if (p.input && p.input.length > 0) {\n if (p.params.formatValue) inputValue = p.params.formatValue(p, p.value);\n else {\n inputValue = [];\n for (i = 0; i < p.value.length; i++) {\n inputValue.push(formatDate(p.value[i]));\n }\n inputValue = inputValue.join(', ');\n } \n $(p.input).val(inputValue);\n $(p.input).trigger('change');\n }\n };\n \n // Columns Handlers\n p.initCalendarEvents = function () {\n var col;\n var allowItemClick = true;\n var isTouched, isMoved, touchStartX, touchStartY, touchCurrentX, touchCurrentY, touchStartTime, touchEndTime, startTranslate, currentTranslate, wrapperWidth, wrapperHeight, percentage, touchesDiff, isScrolling;\n function handleTouchStart (e) {\n if (isMoved || isTouched) return;\n // e.preventDefault();\n isTouched = true;\n touchStartX = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touchStartY = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = (new Date()).getTime();\n percentage = 0;\n allowItemClick = true;\n isScrolling = undefined;\n startTranslate = currentTranslate = p.monthsTranslate;\n }\n function handleTouchMove (e) {\n if (!isTouched) return;\n \n touchCurrentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n touchCurrentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (typeof isScrolling === 'undefined') {\n isScrolling = !!(isScrolling || Math.abs(touchCurrentY - touchStartY) > Math.abs(touchCurrentX - touchStartX));\n }\n if (p.isH && isScrolling) {\n isTouched = false;\n return;\n }\n e.preventDefault();\n if (p.animating) {\n isTouched = false;\n return; \n }\n allowItemClick = false;\n if (!isMoved) {\n // First move\n isMoved = true;\n wrapperWidth = p.wrapper[0].offsetWidth;\n wrapperHeight = p.wrapper[0].offsetHeight;\n p.wrapper.transition(0);\n }\n e.preventDefault();\n \n touchesDiff = p.isH ? touchCurrentX - touchStartX : touchCurrentY - touchStartY;\n percentage = touchesDiff/(p.isH ? wrapperWidth : wrapperHeight);\n currentTranslate = (p.monthsTranslate * inverter + percentage) * 100;\n \n // Transform wrapper\n p.wrapper.transform('translate3d(' + (p.isH ? currentTranslate : 0) + '%, ' + (p.isH ? 0 : currentTranslate) + '%, 0)');\n \n }\n function handleTouchEnd (e) {\n if (!isTouched || !isMoved) {\n isTouched = isMoved = false;\n return;\n }\n isTouched = isMoved = false;\n \n touchEndTime = new Date().getTime();\n if (touchEndTime - touchStartTime < 300) {\n if (Math.abs(touchesDiff) < 10) {\n p.resetMonth();\n }\n else if (touchesDiff >= 10) {\n if (app.rtl) p.nextMonth();\n else p.prevMonth();\n }\n else {\n if (app.rtl) p.prevMonth();\n else p.nextMonth(); \n }\n }\n else {\n if (percentage <= -0.5) {\n if (app.rtl) p.prevMonth();\n else p.nextMonth();\n }\n else if (percentage >= 0.5) {\n if (app.rtl) p.nextMonth();\n else p.prevMonth();\n }\n else {\n p.resetMonth();\n }\n }\n \n // Allow click\n setTimeout(function () {\n allowItemClick = true;\n }, 100);\n }\n \n function handleDayClick(e) {\n if (!allowItemClick) return;\n var day = $(e.target).parents('.picker-calendar-day');\n if (day.length === 0 && $(e.target).hasClass('picker-calendar-day')) {\n day = $(e.target);\n }\n if (day.length === 0) return;\n if (day.hasClass('picker-calendar-day-selected') && !p.params.multiple) return;\n if (day.hasClass('picker-calendar-day-disabled')) return;\n if (day.hasClass('picker-calendar-day-next')) p.nextMonth();\n if (day.hasClass('picker-calendar-day-prev')) p.prevMonth();\n var dateYear = day.attr('data-year');\n var dateMonth = day.attr('data-month');\n var dateDay = day.attr('data-day');\n if (p.params.onDayClick) {\n p.params.onDayClick(p, day[0], dateYear, dateMonth, dateDay);\n }\n p.addValue(new Date(dateYear, dateMonth, dateDay).getTime());\n if (p.params.closeOnSelect) p.close();\n }\n \n p.container.find('.picker-calendar-prev-month').on('click', p.prevMonth);\n p.container.find('.picker-calendar-next-month').on('click', p.nextMonth);\n p.container.find('.picker-calendar-prev-year').on('click', p.prevYear);\n p.container.find('.picker-calendar-next-year').on('click', p.nextYear);\n p.wrapper.on('click', handleDayClick);\n if (p.params.touchMove) {\n p.wrapper.on(app.touchEvents.start, handleTouchStart);\n p.wrapper.on(app.touchEvents.move, handleTouchMove);\n p.wrapper.on(app.touchEvents.end, handleTouchEnd);\n }\n \n p.container[0].f7DestroyCalendarEvents = function () {\n p.container.find('.picker-calendar-prev-month').off('click', p.prevMonth);\n p.container.find('.picker-calendar-next-month').off('click', p.nextMonth);\n p.container.find('.picker-calendar-prev-year').off('click', p.prevYear);\n p.container.find('.picker-calendar-next-year').off('click', p.nextYear);\n p.wrapper.off('click', handleDayClick);\n if (p.params.touchMove) {\n p.wrapper.off(app.touchEvents.start, handleTouchStart);\n p.wrapper.off(app.touchEvents.move, handleTouchMove);\n p.wrapper.off(app.touchEvents.end, handleTouchEnd);\n }\n };\n \n \n };\n p.destroyCalendarEvents = function (colContainer) {\n if ('f7DestroyCalendarEvents' in p.container[0]) p.container[0].f7DestroyCalendarEvents();\n };\n \n // Calendar Methods\n p.daysInMonth = function (date) {\n var d = new Date(date);\n return new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();\n };\n p.monthHTML = function (date, offset) {\n date = new Date(date);\n var year = date.getFullYear(),\n month = date.getMonth(),\n day = date.getDate();\n if (offset === 'next') {\n if (month === 11) date = new Date(year + 1, 0);\n else date = new Date(year, month + 1, 1);\n }\n if (offset === 'prev') {\n if (month === 0) date = new Date(year - 1, 11);\n else date = new Date(year, month - 1, 1);\n }\n if (offset === 'next' || offset === 'prev') {\n month = date.getMonth();\n year = date.getFullYear();\n }\n var daysInPrevMonth = p.daysInMonth(new Date(date.getFullYear(), date.getMonth()).getTime() - 10 * 24 * 60 * 60 * 1000),\n daysInMonth = p.daysInMonth(date),\n firstDayOfMonthIndex = new Date(date.getFullYear(), date.getMonth()).getDay();\n if (firstDayOfMonthIndex === 0) firstDayOfMonthIndex = 7;\n \n var dayDate, currentValues = [], i, j,\n rows = 6, cols = 7,\n monthHTML = '',\n dayIndex = 0 + (p.params.firstDay - 1), \n today = new Date().setHours(0,0,0,0),\n minDate = p.params.minDate ? new Date(p.params.minDate).getTime() : null,\n maxDate = p.params.maxDate ? new Date(p.params.maxDate).getTime() : null;\n \n if (p.value && p.value.length) {\n for (i = 0; i < p.value.length; i++) {\n currentValues.push(new Date(p.value[i]).setHours(0,0,0,0));\n }\n }\n \n for (i = 1; i <= rows; i++) {\n var rowHTML = '';\n var row = i;\n for (j = 1; j <= cols; j++) {\n var col = j;\n dayIndex ++;\n var dayNumber = dayIndex - firstDayOfMonthIndex;\n var addClass = '';\n if (dayNumber < 0) {\n dayNumber = daysInPrevMonth + dayNumber + 1;\n addClass += ' picker-calendar-day-prev';\n dayDate = new Date(month - 1 < 0 ? year - 1 : year, month - 1 < 0 ? 11 : month - 1, dayNumber).getTime();\n }\n else {\n dayNumber = dayNumber + 1;\n if (dayNumber > daysInMonth) {\n dayNumber = dayNumber - daysInMonth;\n addClass += ' picker-calendar-day-next';\n dayDate = new Date(month + 1 > 11 ? year + 1 : year, month + 1 > 11 ? 0 : month + 1, dayNumber).getTime();\n }\n else {\n dayDate = new Date(year, month, dayNumber).getTime(); \n }\n }\n // Today\n if (dayDate === today) addClass += ' picker-calendar-day-today';\n // Selected\n if (currentValues.indexOf(dayDate) >= 0) addClass += ' picker-calendar-day-selected';\n // Weekend\n if (p.params.weekendDays.indexOf(col - 1) >= 0) {\n addClass += ' picker-calendar-day-weekend';\n }\n // Disabled\n if ((minDate && dayDate < minDate) || (maxDate && dayDate > maxDate)) {\n addClass += ' picker-calendar-day-disabled'; \n }\n \n dayDate = new Date(dayDate);\n var dayYear = dayDate.getFullYear();\n var dayMonth = dayDate.getMonth();\n rowHTML += '<div data-year=\"' + dayYear + '\" data-month=\"' + dayMonth + '\" data-day=\"' + dayNumber + '\" class=\"picker-calendar-day' + (addClass) + '\" data-date=\"' + (dayYear + '-' + dayMonth + '-' + dayNumber) + '\"><span>'+dayNumber+'</span></div>';\n }\n monthHTML += '<div class=\"picker-calendar-row\">' + rowHTML + '</div>';\n }\n monthHTML = '<div class=\"picker-calendar-month\" data-year=\"' + year + '\" data-month=\"' + month + '\">' + monthHTML + '</div>';\n return monthHTML;\n };\n p.animating = false;\n p.updateCurrentMonthYear = function (dir) {\n if (typeof dir === 'undefined') {\n p.currentMonth = parseInt(p.months.eq(1).attr('data-month'), 10);\n p.currentYear = parseInt(p.months.eq(1).attr('data-year'), 10); \n }\n else {\n p.currentMonth = parseInt(p.months.eq(dir === 'next' ? (p.months.length - 1) : 0).attr('data-month'), 10);\n p.currentYear = parseInt(p.months.eq(dir === 'next' ? (p.months.length - 1) : 0).attr('data-year'), 10);\n }\n p.container.find('.current-month-value').text(p.params.monthNames[p.currentMonth]);\n p.container.find('.current-year-value').text(p.currentYear);\n \n };\n p.onMonthChangeStart = function (dir) {\n p.updateCurrentMonthYear(dir);\n p.months.removeClass('picker-calendar-month-current picker-calendar-month-prev picker-calendar-month-next');\n var currentIndex = dir === 'next' ? p.months.length - 1 : 0;\n \n p.months.eq(currentIndex).addClass('picker-calendar-month-current');\n p.months.eq(dir === 'next' ? currentIndex - 1 : currentIndex + 1).addClass(dir === 'next' ? 'picker-calendar-month-prev' : 'picker-calendar-month-next');\n \n if (p.params.onMonthYearChangeStart) {\n p.params.onMonthYearChangeStart(p, p.currentYear, p.currentMonth);\n }\n };\n p.onMonthChangeEnd = function (dir, rebuildBoth) {\n p.animating = false;\n var nextMonthHTML, prevMonthHTML, newMonthHTML;\n p.wrapper.find('.picker-calendar-month:not(.picker-calendar-month-prev):not(.picker-calendar-month-current):not(.picker-calendar-month-next)').remove();\n \n if (typeof dir === 'undefined') {\n dir = 'next';\n rebuildBoth = true;\n }\n if (!rebuildBoth) {\n newMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), dir);\n }\n else {\n p.wrapper.find('.picker-calendar-month-next, .picker-calendar-month-prev').remove();\n prevMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), 'prev');\n nextMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), 'next');\n }\n if (dir === 'next' || rebuildBoth) {\n p.wrapper.append(newMonthHTML || nextMonthHTML);\n }\n if (dir === 'prev' || rebuildBoth) {\n p.wrapper.prepend(newMonthHTML || prevMonthHTML);\n }\n p.months = p.wrapper.find('.picker-calendar-month');\n p.setMonthsTranslate(p.monthsTranslate);\n if (p.params.onMonthAdd) {\n p.params.onMonthAdd(p, dir === 'next' ? p.months.eq(p.months.length - 1)[0] : p.months.eq(0)[0]);\n }\n if (p.params.onMonthYearChangeEnd) {\n p.params.onMonthYearChangeEnd(p, p.currentYear, p.currentMonth);\n }\n };\n p.setMonthsTranslate = function (translate) {\n translate = translate || p.monthsTranslate || 0;\n if (typeof p.monthsTranslate === 'undefined') p.monthsTranslate = translate;\n p.months.removeClass('picker-calendar-month-current picker-calendar-month-prev picker-calendar-month-next');\n var prevMonthTranslate = -(translate + 1) * 100 * inverter;\n var currentMonthTranslate = -translate * 100 * inverter;\n var nextMonthTranslate = -(translate - 1) * 100 * inverter;\n p.months.eq(0).transform('translate3d(' + (p.isH ? prevMonthTranslate : 0) + '%, ' + (p.isH ? 0 : prevMonthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');\n p.months.eq(1).transform('translate3d(' + (p.isH ? currentMonthTranslate : 0) + '%, ' + (p.isH ? 0 : currentMonthTranslate) + '%, 0)').addClass('picker-calendar-month-current');\n p.months.eq(2).transform('translate3d(' + (p.isH ? nextMonthTranslate : 0) + '%, ' + (p.isH ? 0 : nextMonthTranslate) + '%, 0)').addClass('picker-calendar-month-next');\n };\n p.nextMonth = function (transition) {\n if (typeof transition === 'undefined' || typeof transition === 'object') {\n transition = '';\n if (!p.params.animate) transition = 0;\n }\n var nextMonth = parseInt(p.months.eq(p.months.length - 1).attr('data-month'), 10);\n var nextYear = parseInt(p.months.eq(p.months.length - 1).attr('data-year'), 10);\n var nextDate = new Date(nextYear, nextMonth);\n var nextDateTime = nextDate.getTime();\n var transitionEndCallback = p.animating ? false : true;\n if (p.params.maxDate) {\n if (nextDateTime > new Date(p.params.maxDate).getTime()) {\n return p.resetMonth();\n }\n }\n p.monthsTranslate --;\n if (nextMonth === p.currentMonth) {\n var nextMonthTranslate = -(p.monthsTranslate) * 100 * inverter;\n var nextMonthHTML = $(p.monthHTML(nextDateTime, 'next')).transform('translate3d(' + (p.isH ? nextMonthTranslate : 0) + '%, ' + (p.isH ? 0 : nextMonthTranslate) + '%, 0)').addClass('picker-calendar-month-next');\n p.wrapper.append(nextMonthHTML[0]);\n p.months = p.wrapper.find('.picker-calendar-month');\n if (p.params.onMonthAdd) {\n p.params.onMonthAdd(p, p.months.eq(p.months.length - 1)[0]);\n }\n }\n p.animating = true;\n p.onMonthChangeStart('next');\n var translate = (p.monthsTranslate * 100) * inverter;\n \n p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');\n if (transitionEndCallback) {\n p.wrapper.transitionEnd(function () {\n p.onMonthChangeEnd('next');\n });\n }\n if (!p.params.animate) {\n p.onMonthChangeEnd('next');\n }\n };\n p.prevMonth = function (transition) {\n if (typeof transition === 'undefined' || typeof transition === 'object') {\n transition = '';\n if (!p.params.animate) transition = 0;\n }\n var prevMonth = parseInt(p.months.eq(0).attr('data-month'), 10);\n var prevYear = parseInt(p.months.eq(0).attr('data-year'), 10);\n var prevDate = new Date(prevYear, prevMonth + 1, -1);\n var prevDateTime = prevDate.getTime();\n var transitionEndCallback = p.animating ? false : true;\n if (p.params.minDate) {\n if (prevDateTime < new Date(p.params.minDate).getTime()) {\n return p.resetMonth();\n }\n }\n p.monthsTranslate ++;\n if (prevMonth === p.currentMonth) {\n var prevMonthTranslate = -(p.monthsTranslate) * 100 * inverter;\n var prevMonthHTML = $(p.monthHTML(prevDateTime, 'prev')).transform('translate3d(' + (p.isH ? prevMonthTranslate : 0) + '%, ' + (p.isH ? 0 : prevMonthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');\n p.wrapper.prepend(prevMonthHTML[0]);\n p.months = p.wrapper.find('.picker-calendar-month');\n if (p.params.onMonthAdd) {\n p.params.onMonthAdd(p, p.months.eq(0)[0]);\n }\n }\n p.animating = true;\n p.onMonthChangeStart('prev');\n var translate = (p.monthsTranslate * 100) * inverter;\n p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');\n if (transitionEndCallback) {\n p.wrapper.transitionEnd(function () {\n p.onMonthChangeEnd('prev');\n });\n }\n if (!p.params.animate) {\n p.onMonthChangeEnd('prev');\n }\n };\n p.resetMonth = function (transition) {\n if (typeof transition === 'undefined') transition = '';\n var translate = (p.monthsTranslate * 100) * inverter;\n p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');\n };\n p.setYearMonth = function (year, month, transition) {\n if (typeof year === 'undefined') year = p.currentYear;\n if (typeof month === 'undefined') month = p.currentMonth;\n if (typeof transition === 'undefined' || typeof transition === 'object') {\n transition = '';\n if (!p.params.animate) transition = 0;\n }\n var targetDate = new Date(year, month).getTime();\n if (p.params.maxDate && targetDate > new Date(p.params.maxDate).getTime()) {\n return false;\n }\n if (p.params.minDate && targetDate < new Date(p.params.minDate).getTime()) {\n return false;\n }\n var currentDate = new Date(p.currentYear, p.currentMonth).getTime();\n var dir;\n var newMonthHTML = p.monthHTML(new Date(year, month));\n p.monthsTranslate = p.monthsTranslate || 0;\n var prevTranslate = p.monthsTranslate;\n var monthTranslate, wrapperTranslate;\n var transitionEndCallback = p.animating ? false : true;\n if (targetDate > currentDate) {\n // To next\n p.monthsTranslate --;\n dir = 'next';\n if (!p.animating) p.months.eq(p.months.length - 1).remove();\n p.wrapper.append(newMonthHTML);\n p.months = p.wrapper.find('.picker-calendar-month');\n monthTranslate = -(prevTranslate - 1) * 100 * inverter;\n p.months.eq(p.months.length - 1).transform('translate3d(' + (p.isH ? monthTranslate : 0) + '%, ' + (p.isH ? 0 : monthTranslate) + '%, 0)').addClass('picker-calendar-month-next');\n }\n else {\n // To prev\n p.monthsTranslate ++;\n dir = 'prev';\n if (!p.animating) p.months.eq(0).remove();\n p.wrapper.prepend(newMonthHTML);\n p.months = p.wrapper.find('.picker-calendar-month');\n monthTranslate = -(prevTranslate + 1) * 100 * inverter;\n p.months.eq(0).transform('translate3d(' + (p.isH ? monthTranslate : 0) + '%, ' + (p.isH ? 0 : monthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');\n }\n if (p.params.onMonthAdd) {\n p.params.onMonthAdd(p, dir === 'next' ? p.months.eq(p.months.length - 1)[0] : p.months.eq(0)[0]);\n }\n p.animating = true;\n p.onMonthChangeStart(dir);\n wrapperTranslate = (p.monthsTranslate * 100) * inverter;\n p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? wrapperTranslate : 0) + '%, ' + (p.isH ? 0 : wrapperTranslate) + '%, 0)');\n if (transitionEndCallback) {\n p.wrapper.transitionEnd(function () {\n p.onMonthChangeEnd(dir, true);\n }); \n }\n if (!p.params.animate) {\n p.onMonthChangeEnd(dir);\n }\n };\n p.nextYear = function () {\n p.setYearMonth(p.currentYear + 1);\n };\n p.prevYear = function () {\n p.setYearMonth(p.currentYear - 1);\n };\n \n \n // HTML Layout\n p.layout = function () {\n var pickerHTML = '';\n var pickerClass = '';\n var i;\n \n var layoutDate = p.value && p.value.length ? p.value[0] : new Date().setHours(0,0,0,0);\n var prevMonthHTML = p.monthHTML(layoutDate, 'prev');\n var currentMonthHTML = p.monthHTML(layoutDate);\n var nextMonthHTML = p.monthHTML(layoutDate, 'next');\n var monthsHTML = '<div class=\"picker-calendar-months\"><div class=\"picker-calendar-months-wrapper\">' + (prevMonthHTML + currentMonthHTML + nextMonthHTML) + '</div></div>';\n // Week days header\n var weekHeaderHTML = '';\n if (p.params.weekHeader) {\n for (i = 0; i < 7; i++) {\n var weekDayIndex = (i + p.params.firstDay > 6) ? (i - 7 + p.params.firstDay) : (i + p.params.firstDay);\n var dayName = p.params.dayNamesShort[weekDayIndex];\n weekHeaderHTML += '<div class=\"picker-calendar-week-day ' + ((p.params.weekendDays.indexOf(weekDayIndex) >= 0) ? 'picker-calendar-week-day-weekend' : '') + '\"> ' + dayName + '</div>';\n \n }\n weekHeaderHTML = '<div class=\"picker-calendar-week-days\">' + weekHeaderHTML + '</div>';\n }\n pickerClass = 'picker-modal picker-calendar ' + (p.params.cssClass || '');\n var toolbarHTML = p.params.toolbar ? p.params.toolbarTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText) : '';\n if (p.params.toolbar) {\n toolbarHTML = p.params.toolbarTemplate\n .replace(/{{closeText}}/g, p.params.toolbarCloseText)\n .replace(/{{monthPicker}}/g, (p.params.monthPicker ? p.params.monthPickerTemplate : ''))\n .replace(/{{yearPicker}}/g, (p.params.yearPicker ? p.params.yearPickerTemplate : ''));\n }\n \n pickerHTML =\n '<div class=\"' + (pickerClass) + '\">' +\n toolbarHTML +\n '<div class=\"picker-modal-inner\">' +\n weekHeaderHTML +\n monthsHTML +\n '</div>' +\n '</div>';\n \n \n p.pickerHTML = pickerHTML; \n };\n \n // Input Events\n function openOnInput(e) {\n e.preventDefault();\n if (p.opened) return;\n p.open();\n if (p.params.scrollToInput && !isPopover()) {\n var pageContent = p.input.parents('.page-content');\n if (pageContent.length === 0) return;\n \n var paddingTop = parseInt(pageContent.css('padding-top'), 10),\n paddingBottom = parseInt(pageContent.css('padding-bottom'), 10),\n pageHeight = pageContent[0].offsetHeight - paddingTop - p.container.height(),\n pageScrollHeight = pageContent[0].scrollHeight - paddingTop - p.container.height(),\n newPaddingBottom;\n \n var inputTop = p.input.offset().top - paddingTop + p.input[0].offsetHeight;\n if (inputTop > pageHeight) {\n var scrollTop = pageContent.scrollTop() + inputTop - pageHeight;\n if (scrollTop + pageHeight > pageScrollHeight) {\n newPaddingBottom = scrollTop + pageHeight - pageScrollHeight + paddingBottom;\n if (pageHeight === pageScrollHeight) {\n newPaddingBottom = p.container.height();\n }\n pageContent.css({'padding-bottom': (newPaddingBottom) + 'px'});\n }\n pageContent.scrollTop(scrollTop, 300);\n }\n }\n }\n function closeOnHTMLClick(e) {\n if (inPopover()) return;\n if (p.input && p.input.length > 0) {\n if (e.target !== p.input[0] && $(e.target).parents('.picker-modal').length === 0) p.close();\n }\n else {\n if ($(e.target).parents('.picker-modal').length === 0) p.close(); \n }\n }\n \n if (p.params.input) {\n p.input = $(p.params.input);\n if (p.params.inputReadOnly) p.input.prop('readOnly', true);\n if (!p.inline) {\n p.input.on('click', openOnInput); \n }\n if (p.params.inputReadOnly) {\n p.input.on('focus mousedown', function (e) {\n e.preventDefault();\n });\n }\n }\n \n if (!p.inline) $('html').on('click', closeOnHTMLClick);\n \n // Open\n function onPickerClose() {\n p.opened = false;\n p.input.parents('.page-content').css({'padding-bottom': ''});\n if (p.params.onClose) p.params.onClose(p);\n \n // Destroy events\n p.destroyCalendarEvents();\n }\n \n p.opened = false;\n p.open = function () {\n var toPopover = isPopover();\n var updateValue = false;\n if (!p.opened) {\n // Set date value\n if (!p.value) {\n if (p.params.value) {\n p.value = p.params.value;\n updateValue = true;\n }\n }\n \n // Layout\n p.layout();\n \n // Append\n if (toPopover) {\n p.pickerHTML = '<div class=\"popover popover-picker-calendar\"><div class=\"popover-inner\">' + p.pickerHTML + '</div></div>';\n p.popover = app.popover(p.pickerHTML, p.params.input, true);\n p.container = $(p.popover).find('.picker-modal');\n $(p.popover).on('close', function () {\n onPickerClose();\n });\n }\n else if (p.inline) {\n p.container = $(p.pickerHTML);\n p.container.addClass('picker-modal-inline');\n $(p.params.container).append(p.container);\n }\n else {\n p.container = $(app.pickerModal(p.pickerHTML));\n $(p.container)\n .on('close', function () {\n onPickerClose();\n });\n }\n \n // Store calendar instance\n p.container[0].f7Calendar = p;\n p.wrapper = p.container.find('.picker-calendar-months-wrapper');\n \n // Months\n p.months = p.wrapper.find('.picker-calendar-month');\n \n // Update current month and year\n p.updateCurrentMonthYear();\n \n // Set initial translate\n p.monthsTranslate = 0;\n p.setMonthsTranslate();\n \n // Init events\n p.initCalendarEvents();\n \n // Update input value\n if (updateValue) p.updateValue();\n \n }\n \n // Set flag\n p.opened = true;\n p.initialized = true;\n if (p.params.onMonthAdd) {\n p.months.each(function () {\n p.params.onMonthAdd(p, this);\n });\n }\n if (p.params.onOpen) p.params.onOpen(p);\n };\n \n // Close\n p.close = function () {\n if (!p.opened || p.inline) return;\n if (inPopover()) {\n app.closeModal(p.popover);\n return;\n }\n else {\n app.closeModal(p.container);\n return;\n }\n };\n \n // Destroy\n p.destroy = function () {\n p.close();\n if (p.params.input) {\n p.input.off('click focus', openOnInput);\n }\n $('html').off('click', closeOnHTMLClick);\n };\n \n if (p.inline) {\n p.open();\n }\n \n return p;\n };\n app.calendar = function (params) {\n return new Calendar(params);\n };\n"," /*======================================================\n ************ Notifications ************\n ======================================================*/\n var _tempNotificationElement;\n app.addNotification = function (params) {\n if (!params) return;\n \n if (typeof params.media === 'undefined') params.media = app.params.notificationMedia;\n if (typeof params.title === 'undefined') params.title = app.params.notificationTitle;\n if (typeof params.subtitle === 'undefined') params.subtitle = app.params.notificationSubtitle;\n if (typeof params.closeIcon === 'undefined') params.closeIcon = app.params.notificationCloseIcon;\n if (typeof params.hold === 'undefined') params.hold = app.params.notificationHold;\n if (typeof params.closeOnClick === 'undefined') params.closeOnClick = app.params.notificationCloseOnClick;\n \n if (!_tempNotificationElement) _tempNotificationElement = document.createElement('div');\n \n var container = $('.notifications');\n if (container.length === 0) {\n $('body').append('<div class=\"notifications list-block media-list\"><ul></ul></div>');\n container = $('.notifications');\n }\n var list = container.children('ul');\n \n var itemHTML;\n if (params.custom) {\n itemHTML = '<li>' + params.custom + '</li>';\n }\n else {\n itemHTML = '<li class=\"notification-item notification-hidden\"><div class=\"item-content\">' +\n (params.media ?\n '<div class=\"item-media\">' +\n params.media +\n '</div>' : '') +\n '<div class=\"item-inner\">' +\n '<div class=\"item-title-row\">' +\n (params.title ? '<div class=\"item-title\">' + params.title + '</div>' : '') +\n (params.closeIcon ? '<div class=\"item-after\"><a href=\"#\" class=\"close-notification\"><span></span></a></div>' : '') +\n '</div>' +\n (params.subtitle ? '<div class=\"item-subtitle\">' + params.subtitle + '</div>' : '') +\n (params.message ? '<div class=\"item-text\">' + params.message + '</div>' : '') +\n '</div>' +\n '</div></li>';\n }\n _tempNotificationElement.innerHTML = itemHTML;\n \n var item = $(_tempNotificationElement).children();\n \n item.on('click', function (e) {\n var close = false;\n if ($(e.target).is('.close-notification') || $(e.target).parents('.close-notification').length > 0) {\n close = true;\n }\n else {\n if (params.onClick) params.onClick(e, item[0]);\n if (params.closeOnClick) close = true;\n }\n if (close) app.closeNotification(item[0]);\n });\n if (params.onClose) {\n item.data('f7NotificationOnClose', function () {\n params.onClose(item[0]);\n });\n }\n if (params.additionalClass) {\n item.addClass(params.additionalClass);\n }\n if (params.hold) {\n setTimeout(function () {\n if (item.length > 0) app.closeNotification(item[0]);\n }, params.hold);\n }\n \n list.prepend(item[0]);\n container.show();\n \n var itemHeight = item.outerHeight();\n item.css('marginTop', -itemHeight + 'px');\n item.transition(0);\n \n var clientLeft = item[0].clientLeft;\n item.transition('');\n item.css('marginTop', '0px');\n \n container.transform('translate3d(0, 0,0)');\n item.removeClass('notification-hidden');\n \n return item[0];\n };\n app.closeNotification = function (item) {\n item = $(item);\n if (item.length === 0) return;\n if (item.hasClass('notification-item-removing')) return;\n var container = $('.notifications');\n \n var itemHeight = item.outerHeight();\n item.css('height', itemHeight + 'px').transition(0);\n var clientLeft = item[0].clientLeft;\n \n item.css('height', '0px').transition('').addClass('notification-item-removing');\n if (item.data('f7NotificationOnClose')) item.data('f7NotificationOnClose')();\n \n if (container.find('.notification-item:not(.notification-item-removing)').length === 0) {\n container.transform('');\n }\n \n item.addClass('notification-hidden').transitionEnd(function () {\n item.remove();\n if (container.find('.notification-item').length === 0) {\n container.hide();\n }\n });\n };\n"," /*===========================\n Compile Template7 Templates On App Init\n ===========================*/\n app.initTemplate7Templates = function () {\n if (!window.Template7) return;\n Template7.templates = Template7.templates || app.params.templates || {};\n Template7.data = Template7.data || app.params.template7Data || {};\n Template7.cache = Template7.cache || {};\n \n app.templates = Template7.templates;\n app.template7Data = Template7.data;\n app.template7Cache = Template7.cache;\n \n // Precompile templates on app init\n if (!app.params.precompileTemplates) return;\n $('script[type=\"text/template7\"]').each(function () {\n var id = $(this).attr('id');\n if (!id) return;\n Template7.templates[id] = Template7.compile($(this).html());\n });\n };\n \n"," /*=======================================\n ************ Plugins API ************\n =======================================*/\n var _plugins = [];\n app.initPlugins = function () {\n // Initialize plugins\n for (var plugin in app.plugins) {\n var p = app.plugins[plugin](app, app.params[plugin]);\n if (p) _plugins.push(p);\n }\n };\n // Plugin Hooks\n app.pluginHook = function (hook) {\n for (var i = 0; i < _plugins.length; i++) {\n if (_plugins[i].hooks && hook in _plugins[i].hooks) {\n _plugins[i].hooks[hook](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n }\n }\n };\n // Prevented by plugin\n app.pluginPrevent = function (action) {\n var prevent = false;\n for (var i = 0; i < _plugins.length; i++) {\n if (_plugins[i].prevents && action in _plugins[i].prevents) {\n if (_plugins[i].prevents[action](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5])) prevent = true;\n }\n }\n return prevent;\n };\n // Preprocess content by plugin\n app.pluginProcess = function (action, data) {\n var processed = data;\n for (var i = 0; i < _plugins.length; i++) {\n if (_plugins[i].preprocess && process in _plugins[i].preprocess) {\n processed = _plugins[i].preprocess[process](data, arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);\n }\n }\n return processed;\n };\n \n \n"," /*======================================================\n ************ App Init ************\n ======================================================*/\n app.init = function () {\n // Compile Template7 templates on app load\n if (app.initTemplate7Templates) app.initTemplate7Templates();\n \n // Init Plugins\n if (app.initPlugins) app.initPlugins();\n \n // Init Device\n if (app.getDeviceInfo) app.getDeviceInfo();\n \n // Init Click events\n if (app.initFastClicks && app.params.fastClicks) app.initFastClicks();\n if (app.initClickEvents) app.initClickEvents();\n \n // Init each page callbacks\n $('.page:not(.cached)').each(function () {\n app.initPageWithCallback(this);\n });\n \n // Init resize events\n if (app.initResize) app.initResize();\n \n // Init push state\n if (app.initPushState && app.params.pushState) app.initPushState();\n \n // Init Live Swipeouts events\n if (app.initSwipeout && app.params.swipeout) app.initSwipeout();\n \n // Init Live Sortable events\n if (app.initSortable && app.params.sortable) app.initSortable();\n \n // Init Live Swipe Panels\n if (app.initSwipePanels && (app.params.swipePanel || app.params.swipePanelOnlyClose)) app.initSwipePanels();\n \n // App Init callback\n if (app.params.onAppInit) app.params.onAppInit();\n \n // Plugin app init hook\n app.pluginHook('appInit');\n };\n if (app.params.init) app.init();\n \n"," //Return instance \n return app;\n };\n \n"," /*===========================\n Dom7 Library\n ===========================*/\n var Dom7 = (function () {\n var Dom7 = function (arr) {\n var _this = this, i = 0;\n // Create array-like object\n for (i = 0; i < arr.length; i++) {\n _this[i] = arr[i];\n }\n _this.length = arr.length;\n // Return collection with methods\n return this;\n };\n var $ = function (selector, context) {\n var arr = [], i = 0;\n if (selector && !context) {\n if (selector instanceof Dom7) {\n return selector;\n }\n }\n if (selector) {\n // String\n if (typeof selector === 'string') {\n var els, tempParent, html = selector.trim();\n if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n var toCreate = 'div';\n if (html.indexOf('<li') === 0) toCreate = 'ul';\n if (html.indexOf('<tr') === 0) toCreate = 'tbody';\n if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';\n if (html.indexOf('<tbody') === 0) toCreate = 'table';\n if (html.indexOf('<option') === 0) toCreate = 'select';\n tempParent = document.createElement(toCreate);\n tempParent.innerHTML = selector;\n for (i = 0; i < tempParent.childNodes.length; i++) {\n arr.push(tempParent.childNodes[i]);\n }\n }\n else {\n if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {\n // Pure ID selector\n els = [document.getElementById(selector.split('#')[1])];\n }\n else {\n // Other selectors\n els = (context || document).querySelectorAll(selector);\n }\n for (i = 0; i < els.length; i++) {\n if (els[i]) arr.push(els[i]);\n }\n }\n }\n // Node/element\n else if (selector.nodeType || selector === window || selector === document) {\n arr.push(selector);\n }\n //Array of elements or instance of Dom\n else if (selector.length > 0 && selector[0].nodeType) {\n for (i = 0; i < selector.length; i++) {\n arr.push(selector[i]);\n }\n }\n }\n return new Dom7(arr);\n };\n"," Dom7.prototype = {\n // Classes and attriutes\n addClass: function (className) {\n if (typeof className === 'undefined') {\n return this;\n }\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i++) {\n for (var j = 0; j < this.length; j++) {\n if (typeof this[j].classList !== 'undefined') this[j].classList.add(classes[i]);\n }\n }\n return this;\n },\n removeClass: function (className) {\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i++) {\n for (var j = 0; j < this.length; j++) {\n if (typeof this[j].classList !== 'undefined') this[j].classList.remove(classes[i]);\n }\n }\n return this;\n },\n hasClass: function (className) {\n if (!this[0]) return false;\n else return this[0].classList.contains(className);\n },\n toggleClass: function (className) {\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i++) {\n for (var j = 0; j < this.length; j++) {\n if (typeof this[j].classList !== 'undefined') this[j].classList.toggle(classes[i]);\n }\n }\n return this;\n },\n attr: function (attrs, value) {\n if (arguments.length === 1 && typeof attrs === 'string') {\n // Get attr\n if (this[0]) return this[0].getAttribute(attrs);\n else return undefined;\n }\n else {\n // Set attrs\n for (var i = 0; i < this.length; i++) {\n if (arguments.length === 2) {\n // String\n this[i].setAttribute(attrs, value);\n }\n else {\n // Object\n for (var attrName in attrs) {\n this[i][attrName] = attrs[attrName];\n this[i].setAttribute(attrName, attrs[attrName]);\n }\n }\n }\n return this;\n }\n },\n removeAttr: function (attr) {\n for (var i = 0; i < this.length; i++) {\n this[i].removeAttribute(attr);\n }\n },\n prop: function (props, value) {\n if (arguments.length === 1 && typeof props === 'string') {\n // Get prop\n if (this[0]) return this[0][props];\n else return undefined;\n }\n else {\n // Set props\n for (var i = 0; i < this.length; i++) {\n if (arguments.length === 2) {\n // String\n this[i][props] = value;\n }\n else {\n // Object\n for (var propName in props) {\n this[i][propName] = props[propName];\n }\n }\n }\n return this;\n }\n },\n data: function (key, value) {\n if (typeof value === 'undefined') {\n // Get value\n if (this[0]) {\n var dataKey = this[0].getAttribute('data-' + key);\n if (dataKey) return dataKey;\n else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];\n else return undefined;\n }\n else return undefined;\n }\n else {\n // Set value\n for (var i = 0; i < this.length; i++) {\n var el = this[i];\n if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};\n el.dom7ElementDataStorage[key] = value;\n }\n return this;\n }\n },\n val: function (value) {\n if (typeof value === 'undefined') {\n if (this[0]) return this[0].value;\n else return undefined;\n }\n else {\n for (var i = 0; i < this.length; i++) {\n this[i].value = value;\n }\n return this;\n }\n },\n // Transforms\n transform : function (transform) {\n for (var i = 0; i < this.length; i++) {\n var elStyle = this[i].style;\n elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n }\n return this;\n },\n transition: function (duration) {\n if (typeof duration !== 'string') {\n duration = duration + 'ms';\n }\n for (var i = 0; i < this.length; i++) {\n var elStyle = this[i].style;\n elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n }\n return this;\n },\n //Events\n on: function (eventName, targetSelector, listener, capture) {\n function handleLiveEvent(e) {\n var target = e.target;\n if ($(target).is(targetSelector)) listener.call(target, e);\n else {\n var parents = $(target).parents();\n for (var k = 0; k < parents.length; k++) {\n if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);\n }\n }\n }\n var events = eventName.split(' ');\n var i, j;\n for (i = 0; i < this.length; i++) {\n if (typeof targetSelector === 'function' || targetSelector === false) {\n // Usual events\n if (typeof targetSelector === 'function') {\n listener = arguments[1];\n capture = arguments[2] || false;\n }\n for (j = 0; j < events.length; j++) {\n this[i].addEventListener(events[j], listener, capture);\n }\n }\n else {\n //Live events\n for (j = 0; j < events.length; j++) {\n if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];\n this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});\n this[i].addEventListener(events[j], handleLiveEvent, capture);\n }\n }\n }\n \n return this;\n },\n off: function (eventName, targetSelector, listener, capture) {\n var events = eventName.split(' ');\n for (var i = 0; i < events.length; i++) {\n for (var j = 0; j < this.length; j++) {\n if (typeof targetSelector === 'function' || targetSelector === false) {\n // Usual events\n if (typeof targetSelector === 'function') {\n listener = arguments[1];\n capture = arguments[2] || false;\n }\n this[j].removeEventListener(events[i], listener, capture);\n }\n else {\n // Live event\n if (this[j].dom7LiveListeners) {\n for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {\n if (this[j].dom7LiveListeners[k].listener === listener) {\n this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);\n }\n }\n }\n }\n }\n }\n return this;\n },\n once: function (eventName, targetSelector, listener, capture) {\n var dom = this;\n if (typeof targetSelector === 'function') {\n targetSelector = false;\n listener = arguments[1];\n capture = arguments[2];\n }\n function proxy(e) {\n listener(e);\n dom.off(eventName, targetSelector, proxy, capture);\n }\n dom.on(eventName, targetSelector, proxy, capture);\n },\n trigger: function (eventName, eventData) {\n for (var i = 0; i < this.length; i++) {\n var evt;\n try {\n evt = new CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});\n }\n catch (e) {\n evt = document.createEvent('Event');\n evt.initEvent(eventName, true, true);\n evt.detail = eventData;\n }\n this[i].dispatchEvent(evt);\n }\n return this;\n },\n transitionEnd: function (callback) {\n var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n i, j, dom = this;\n function fireCallBack(e) {\n /*jshint validthis:true */\n if (e.target !== this) return;\n callback.call(this, e);\n for (i = 0; i < events.length; i++) {\n dom.off(events[i], fireCallBack);\n }\n }\n if (callback) {\n for (i = 0; i < events.length; i++) {\n dom.on(events[i], fireCallBack);\n }\n }\n return this;\n },\n animationEnd: function (callback) {\n var events = ['webkitAnimationEnd', 'OAnimationEnd', 'MSAnimationEnd', 'animationend'],\n i, j, dom = this;\n function fireCallBack(e) {\n callback(e);\n for (i = 0; i < events.length; i++) {\n dom.off(events[i], fireCallBack);\n }\n }\n if (callback) {\n for (i = 0; i < events.length; i++) {\n dom.on(events[i], fireCallBack);\n }\n }\n return this;\n },\n // Sizing/Styles\n width: function () {\n if (this[0] === window) {\n return window.innerWidth;\n }\n else {\n if (this.length > 0) {\n return parseFloat(this.css('width'));\n }\n else {\n return null;\n }\n }\n },\n outerWidth: function (includeMargins) {\n if (this.length > 0) {\n if (includeMargins)\n return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));\n else\n return this[0].offsetWidth;\n }\n else return null;\n },\n height: function () {\n if (this[0] === window) {\n return window.innerHeight;\n }\n else {\n if (this.length > 0) {\n return parseFloat(this.css('height'));\n }\n else {\n return null;\n }\n }\n },\n outerHeight: function (includeMargins) {\n if (this.length > 0) {\n if (includeMargins)\n return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));\n else\n return this[0].offsetHeight;\n }\n else return null;\n },\n offset: function () {\n if (this.length > 0) {\n var el = this[0];\n var box = el.getBoundingClientRect();\n var body = document.body;\n var clientTop = el.clientTop || body.clientTop || 0;\n var clientLeft = el.clientLeft || body.clientLeft || 0;\n var scrollTop = window.pageYOffset || el.scrollTop;\n var scrollLeft = window.pageXOffset || el.scrollLeft;\n return {\n top: box.top + scrollTop - clientTop,\n left: box.left + scrollLeft - clientLeft\n };\n }\n else {\n return null;\n }\n },\n hide: function () {\n for (var i = 0; i < this.length; i++) {\n this[i].style.display = 'none';\n }\n return this;\n },\n show: function () {\n for (var i = 0; i < this.length; i++) {\n this[i].style.display = 'block';\n }\n return this;\n },\n css: function (props, value) {\n var i;\n if (arguments.length === 1) {\n if (typeof props === 'string') {\n if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);\n }\n else {\n for (i = 0; i < this.length; i++) {\n for (var prop in props) {\n this[i].style[prop] = props[prop];\n }\n }\n return this;\n }\n }\n if (arguments.length === 2 && typeof props === 'string') {\n for (i = 0; i < this.length; i++) {\n this[i].style[props] = value;\n }\n return this;\n }\n return this;\n },\n \n //Dom manipulation\n each: function (callback) {\n for (var i = 0; i < this.length; i++) {\n callback.call(this[i], i, this[i]);\n }\n return this;\n },\n html: function (html) {\n if (typeof html === 'undefined') {\n return this[0] ? this[0].innerHTML : undefined;\n }\n else {\n for (var i = 0; i < this.length; i++) {\n this[i].innerHTML = html;\n }\n return this;\n }\n },\n text: function (text) {\n if (typeof text === 'undefined') {\n if (this[0]) {\n return this[0].textContent.trim();\n }\n else return null;\n }\n else {\n for (var i = 0; i < this.length; i++) {\n this[i].textContent = text;\n }\n }\n },\n is: function (selector) {\n if (!this[0]) return false;\n var compareWith, i;\n if (typeof selector === 'string') {\n var el = this[0];\n if (el === document) return selector === document;\n if (el === window) return selector === window;\n \n if (el.matches) return el.matches(selector);\n else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);\n else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);\n else if (el.msMatchesSelector) return el.msMatchesSelector(selector);\n else {\n compareWith = $(selector);\n for (i = 0; i < compareWith.length; i++) {\n if (compareWith[i] === this[0]) return true;\n }\n return false;\n }\n }\n else if (selector === document) return this[0] === document;\n else if (selector === window) return this[0] === window;\n else {\n if (selector.nodeType || selector instanceof Dom7) {\n compareWith = selector.nodeType ? [selector] : selector;\n for (i = 0; i < compareWith.length; i++) {\n if (compareWith[i] === this[0]) return true;\n }\n return false;\n }\n return false;\n }\n \n },\n indexOf: function (el) {\n for (var i = 0; i < this.length; i++) {\n if (this[i] === el) return i;\n }\n },\n index: function () {\n if (this[0]) {\n var child = this[0];\n var i = 0;\n while ((child = child.previousSibling) !== null) {\n if (child.nodeType === 1) i++;\n }\n return i;\n }\n else return undefined;\n },\n eq: function (index) {\n if (typeof index === 'undefined') return this;\n var length = this.length;\n var returnIndex;\n if (index > length - 1) {\n return new Dom7([]);\n }\n if (index < 0) {\n returnIndex = length + index;\n if (returnIndex < 0) return new Dom7([]);\n else return new Dom7([this[returnIndex]]);\n }\n return new Dom7([this[index]]);\n },\n append: function (newChild) {\n var i, j;\n for (i = 0; i < this.length; i++) {\n if (typeof newChild === 'string') {\n var tempDiv = document.createElement('div');\n tempDiv.innerHTML = newChild;\n while (tempDiv.firstChild) {\n this[i].appendChild(tempDiv.firstChild);\n }\n }\n else if (newChild instanceof Dom7) {\n for (j = 0; j < newChild.length; j++) {\n this[i].appendChild(newChild[j]);\n }\n }\n else {\n this[i].appendChild(newChild);\n }\n }\n return this;\n },\n prepend: function (newChild) {\n var i, j;\n for (i = 0; i < this.length; i++) {\n if (typeof newChild === 'string') {\n var tempDiv = document.createElement('div');\n tempDiv.innerHTML = newChild;\n for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {\n this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n }\n // this[i].insertAdjacentHTML('afterbegin', newChild);\n }\n else if (newChild instanceof Dom7) {\n for (j = 0; j < newChild.length; j++) {\n this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n }\n }\n else {\n this[i].insertBefore(newChild, this[i].childNodes[0]);\n }\n }\n return this;\n },\n insertBefore: function (selector) {\n var before = $(selector);\n for (var i = 0; i < this.length; i++) {\n if (before.length === 1) {\n before[0].parentNode.insertBefore(this[i], before[0]);\n }\n else if (before.length > 1) {\n for (var j = 0; j < before.length; j++) {\n before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);\n }\n }\n }\n },\n insertAfter: function (selector) {\n var after = $(selector);\n for (var i = 0; i < this.length; i++) {\n if (after.length === 1) {\n after[0].parentNode.insertBefore(this[i], after[0].nextSibling);\n }\n else if (after.length > 1) {\n for (var j = 0; j < after.length; j++) {\n after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);\n }\n }\n }\n },\n next: function (selector) {\n if (this.length > 0) {\n if (selector) {\n if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);\n else return new Dom7([]);\n }\n else {\n if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);\n else return new Dom7([]);\n }\n }\n else return new Dom7([]);\n },\n nextAll: function (selector) {\n var nextEls = [];\n var el = this[0];\n if (!el) return new Dom7([]);\n while (el.nextElementSibling) {\n var next = el.nextElementSibling;\n if (selector) {\n if($(next).is(selector)) nextEls.push(next);\n }\n else nextEls.push(next);\n el = next;\n }\n return new Dom7(nextEls);\n },\n prev: function (selector) {\n if (this.length > 0) {\n if (selector) {\n if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);\n else return new Dom7([]);\n }\n else {\n if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);\n else return new Dom7([]);\n }\n }\n else return new Dom7([]);\n },\n prevAll: function (selector) {\n var prevEls = [];\n var el = this[0];\n if (!el) return new Dom7([]);\n while (el.previousElementSibling) {\n var prev = el.previousElementSibling;\n if (selector) {\n if($(prev).is(selector)) prevEls.push(prev);\n }\n else prevEls.push(prev);\n el = prev;\n }\n return new Dom7(prevEls);\n },\n parent: function (selector) {\n var parents = [];\n for (var i = 0; i < this.length; i++) {\n if (selector) {\n if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);\n }\n else {\n parents.push(this[i].parentNode);\n }\n }\n return $($.unique(parents));\n },\n parents: function (selector) {\n var parents = [];\n for (var i = 0; i < this.length; i++) {\n var parent = this[i].parentNode;\n while (parent) {\n if (selector) {\n if ($(parent).is(selector)) parents.push(parent);\n }\n else {\n parents.push(parent);\n }\n parent = parent.parentNode;\n }\n }\n return $($.unique(parents));\n },\n find : function (selector) {\n var foundElements = [];\n for (var i = 0; i < this.length; i++) {\n var found = this[i].querySelectorAll(selector);\n for (var j = 0; j < found.length; j++) {\n foundElements.push(found[j]);\n }\n }\n return new Dom7(foundElements);\n },\n children: function (selector) {\n var children = [];\n for (var i = 0; i < this.length; i++) {\n var childNodes = this[i].childNodes;\n \n for (var j = 0; j < childNodes.length; j++) {\n if (!selector) {\n if (childNodes[j].nodeType === 1) children.push(childNodes[j]);\n }\n else {\n if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);\n }\n }\n }\n return new Dom7($.unique(children));\n },\n remove: function () {\n for (var i = 0; i < this.length; i++) {\n if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);\n }\n return this;\n },\n detach: function () {\n return this.remove();\n },\n add: function () {\n var dom = this;\n var i, j;\n for (i = 0; i < arguments.length; i++) {\n var toAdd = $(arguments[i]);\n for (j = 0; j < toAdd.length; j++) {\n dom[dom.length] = toAdd[j];\n dom.length++;\n }\n }\n return dom;\n }\n };\n \n // Shortcuts\n (function () {\n var shortcuts = ('click blur focus focusin focusout keyup keydown keypress submit change mousedown mousemove mouseup mouseenter mouseleave mouseout mouseover touchstart touchend touchmove resize scroll').split(' ');\n var notTrigger = ('resize scroll').split(' ');\n function createMethod(name) {\n Dom7.prototype[name] = function (handler) {\n var i;\n if (typeof handler === 'undefined') {\n for (i = 0; i < this.length; i++) {\n if (notTrigger.indexOf(name) < 0) {\n if (name in this[i]) this[i][name]();\n else {\n $(this[i]).trigger(name);\n }\n }\n }\n return this;\n }\n else {\n return this.on(name, handler);\n }\n };\n }\n for (var i = 0; i < shortcuts.length; i++) {\n createMethod(shortcuts[i]);\n }\n })();\n \n"," // Global Ajax Setup\n var globalAjaxOptions = {};\n $.ajaxSetup = function (options) {\n if (options.type) options.method = options.type;\n for (var option in options) {\n globalAjaxOptions[option] = options[option];\n }\n };\n \n // Ajax\n var _jsonpRequests = 0;\n $.ajax = function (options) {\n var defaults = {\n method: 'GET',\n data: false,\n async: true,\n cache: true,\n user: '',\n password: '',\n headers: {},\n xhrFields: {},\n statusCode: {},\n processData: true,\n dataType: 'text',\n contentType: 'application/x-www-form-urlencoded',\n timeout: 0\n };\n var callbacks = ['beforeSend', 'error', 'complete', 'success', 'statusCode'];\n \n //For jQuery guys\n if (options.type) options.method = options.type;\n \n // Merge global and defaults\n for (var globalOption in globalAjaxOptions) {\n if (callbacks.indexOf(globalOption) < 0) defaults[globalOption] = globalAjaxOptions[globalOption];\n }\n // Function to run XHR callbacks and events\n function fireAjaxCallback (eventName, eventData, callbackName) {\n var a = arguments;\n if (eventName) $(document).trigger(eventName, eventData);\n if (callbackName) {\n // Global callback\n if (callbackName in globalAjaxOptions) globalAjaxOptions[callbackName](a[3], a[4], a[5], a[6]);\n // Options callback\n if (options[callbackName]) options[callbackName](a[3], a[4], a[5], a[6]);\n }\n }\n \n // Merge options and defaults\n for (var prop in defaults) {\n if (!(prop in options)) options[prop] = defaults[prop];\n }\n \n // Default URL\n if (!options.url) {\n options.url = window.location.toString();\n }\n // UC method\n var _method = options.method.toUpperCase();\n // Data to modify GET URL\n if ((_method === 'GET' || _method === 'HEAD') && options.data) {\n var stringData;\n if (typeof options.data === 'string') {\n // Should be key=value string\n if (options.data.indexOf('?') >= 0) stringData = options.data.split('?')[1];\n else stringData = options.data;\n }\n else {\n // Should be key=value object\n stringData = $.serializeObject(options.data);\n }\n if (options.url.indexOf('?') >= 0) options.url += '&' + stringData;\n else options.url += '?' + stringData;\n }\n // JSONP\n if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {\n \n var callbackName = 'f7jsonp_' + Date.now() + (_jsonpRequests++);\n var requestUrl, abortTimeout;\n var callbackSplit = options.url.split('callback=');\n if (callbackSplit[1].indexOf('&') >= 0) {\n var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');\n requestUrl = callbackSplit[0] + 'callback=' + callbackName + (addVars.length > 0 ? '&' + addVars : '');\n }\n else {\n requestUrl = callbackSplit[0] + 'callback=' + callbackName;\n }\n \n // Create script\n var script = document.createElement('script');\n script.type = 'text/javascript';\n script.onerror = function() {\n clearTimeout(abortTimeout);\n fireAjaxCallback(undefined, undefined, 'error', null, 'scripterror');\n };\n script.src = requestUrl;\n \n // Handler\n window[callbackName] = function (data) {\n clearTimeout(abortTimeout);\n fireAjaxCallback(undefined, undefined, 'success', data);\n script.parentNode.removeChild(script);\n script = null;\n delete window[callbackName];\n };\n document.querySelector('head').appendChild(script);\n \n if (options.timeout > 0) {\n abortTimeout = setTimeout(function () {\n script.parentNode.removeChild(script);\n script = null;\n fireAjaxCallback(undefined, undefined, 'error', null, 'timeout');\n }, options.timeout);\n }\n \n return;\n }\n \n // Cache for GET/HEAD requests\n if (_method === 'GET' || _method === 'HEAD') {\n if (options.cache === false) {\n if (options.url.indexOf('?') >= 0) {\n options.url += ('&_nocache=' + Date.now());\n }\n else {\n options.url += ('?_nocache=' + Date.now());\n }\n }\n }\n \n // Create XHR\n var xhr = new XMLHttpRequest();\n \n // Save Request URL\n xhr.requestUrl = options.url;\n \n // Open XHR\n xhr.open(_method, options.url, options.async, options.user, options.password);\n \n // Create POST Data\n var postData = null;\n \n if ((_method === 'POST' || _method === 'PUT') && options.data) {\n if (options.processData) {\n var postDataInstances = [ArrayBuffer, Blob, Document, FormData];\n // Post Data\n if (postDataInstances.indexOf(options.data.constructor) >= 0) {\n postData = options.data;\n }\n else {\n // POST Headers\n var boundary = '---------------------------' + Date.now().toString(16);\n \n if (options.contentType === 'multipart\\/form-data') {\n xhr.setRequestHeader('Content-Type', 'multipart\\/form-data; boundary=' + boundary);\n }\n else {\n xhr.setRequestHeader('Content-Type', options.contentType);\n }\n postData = '';\n var _data = $.serializeObject(options.data);\n if (options.contentType === 'multipart\\/form-data') {\n boundary = '---------------------------' + Date.now().toString(16);\n _data = _data.split('&');\n var _newData = [];\n for (var i = 0; i < _data.length; i++) {\n _newData.push('Content-Disposition: form-data; name=\"' + _data[i].split('=')[0] + '\"\\r\\n\\r\\n' + _data[i].split('=')[1] + '\\r\\n');\n }\n postData = '--' + boundary + '\\r\\n' + _newData.join('--' + boundary + '\\r\\n') + '--' + boundary + '--\\r\\n';\n }\n else {\n postData = options.contentType === 'application/x-www-form-urlencoded' ? _data : _data.replace(/&/g, '\\r\\n');\n }\n }\n }\n else {\n postData = options.data;\n }\n \n }\n \n // Additional headers\n if (options.headers) {\n for (var header in options.headers) {\n xhr.setRequestHeader(header, options.headers[header]);\n }\n }\n \n // Check for crossDomain\n if (typeof options.crossDomain === 'undefined') {\n options.crossDomain = /^([\\w-]+:)?\\/\\/([^\\/]+)/.test(options.url) && RegExp.$2 !== window.location.host;\n }\n \n if (!options.crossDomain) {\n xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n }\n \n if (options.xhrFields) {\n for (var field in options.xhrFields) {\n xhr[field] = options.xhrFields[field];\n }\n }\n \n var xhrTimeout;\n // Handle XHR\n xhr.onload = function (e) {\n if (xhrTimeout) clearTimeout(xhrTimeout);\n if (xhr.status === 200 || xhr.status === 0) {\n var isSuccess, responseData;\n if (options.dataType === 'json') {\n try {\n responseData = JSON.parse(xhr.responseText);\n fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', responseData, xhr.status, xhr);\n }\n catch (e) {\n fireAjaxCallback('ajaxError', {xhr: xhr, parseerror: true}, 'error', xhr, 'parseerror');\n }\n }\n else {\n fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', xhr.responseText, xhr.status, xhr);\n }\n }\n else {\n fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);\n }\n if (options.statusCode) {\n if (globalAjaxOptions.statusCode && globalAjaxOptions.statusCode[xhr.status]) globalAjaxOptions.statusCode[xhr.status](xhr);\n if (options.statusCode[xhr.status]) options.statusCode[xhr.status](xhr);\n }\n fireAjaxCallback('ajaxComplete', {xhr: xhr}, 'complete', xhr, xhr.status);\n };\n \n xhr.onerror = function (e) {\n if (xhrTimeout) clearTimeout(xhrTimeout);\n fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);\n };\n \n // Ajax start callback\n fireAjaxCallback('ajaxStart', {xhr: xhr}, 'start', xhr);\n fireAjaxCallback(undefined, undefined, 'beforeSend', xhr);\n \n \n // Send XHR\n xhr.send(postData);\n \n // Timeout\n if (options.timeout > 0) {\n xhrTimeout = setTimeout(function () {\n xhr.abort();\n fireAjaxCallback('ajaxError', {xhr: xhr, timeout: true}, 'error', xhr, 'timeout');\n fireAjaxCallback('ajaxComplete', {xhr: xhr, timeout: true}, 'complete', xhr, 'timeout');\n }, options.timeout);\n }\n \n // Return XHR object\n return xhr;\n };\n // Shrotcuts\n (function () {\n var methods = ('get post getJSON').split(' ');\n function createMethod(method) {\n $[method] = function (url, data, success) {\n return $.ajax({\n url: url,\n method: method === 'post' ? 'POST' : 'GET',\n data: typeof data === 'function' ? undefined : data,\n success: typeof data === 'function' ? data : success,\n dataType: method === 'getJSON' ? 'json' : undefined\n });\n };\n }\n for (var i = 0; i < methods.length; i++) {\n createMethod(methods[i]);\n }\n })();\n"," // DOM Library Utilites\n $.parseUrlQuery = function (url) {\n var query = {}, i, params, param;\n if (url.indexOf('?') >= 0) url = url.split('?')[1];\n else return query;\n params = url.split('&');\n for (i = 0; i < params.length; i++) {\n param = params[i].split('=');\n query[param[0]] = param[1];\n }\n return query;\n };\n $.isArray = function (arr) {\n if (Object.prototype.toString.apply(arr) === '[object Array]') return true;\n else return false;\n };\n $.unique = function (arr) {\n var unique = [];\n for (var i = 0; i < arr.length; i++) {\n if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);\n }\n return unique;\n };\n $.trim = function (str) {\n return str.trim();\n };\n $.serializeObject = function (obj) {\n if (typeof obj === 'string') return obj;\n var resultArray = [];\n var separator = '&';\n for (var prop in obj) {\n if ($.isArray(obj[prop])) {\n var toPush = [];\n for (var i = 0; i < obj[prop].length; i ++) {\n toPush.push(prop + '=' + obj[prop][i]);\n }\n resultArray.push(toPush.join(separator));\n }\n else {\n // Should be string\n resultArray.push(prop + '=' + obj[prop]);\n }\n }\n \n return resultArray.join(separator);\n };\n \n $.getTranslate = function (el, axis) {\n var matrix, curTransform, curStyle, transformMatrix;\n \n // automatic axis detection\n if (typeof axis === 'undefined') {\n axis = 'x';\n }\n \n curStyle = window.getComputedStyle(el, null);\n if (window.WebKitCSSMatrix) {\n // Some old versions of Webkit choke when 'none' is passed; pass\n // empty string instead in this case\n transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);\n }\n else {\n transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n matrix = transformMatrix.toString().split(',');\n }\n \n if (axis === 'x') {\n //Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix)\n curTransform = transformMatrix.m41;\n //Crazy IE10 Matrix\n else if (matrix.length === 16)\n curTransform = parseFloat(matrix[12]);\n //Normal Browsers\n else\n curTransform = parseFloat(matrix[4]);\n }\n if (axis === 'y') {\n //Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix)\n curTransform = transformMatrix.m42;\n //Crazy IE10 Matrix\n else if (matrix.length === 16)\n curTransform = parseFloat(matrix[13]);\n //Normal Browsers\n else\n curTransform = parseFloat(matrix[5]);\n }\n \n return curTransform || 0;\n };\n \n $.requestAnimationFrame = function (callback) {\n if (window.requestAnimationFrame) return window.requestAnimationFrame(callback);\n else if (window.webkitRequestAnimationFrame) return window.webkitRequestAnimationFrame(callback);\n else if (window.mozRequestAnimationFrame) return window.mozRequestAnimationFrame(callback);\n else {\n return window.setTimeout(callback, 1000 / 60);\n }\n };\n $.cancelAnimationFrame = function (id) {\n if (window.cancelAnimationFrame) return window.cancelAnimationFrame(id);\n else if (window.webkitCancelAnimationFrame) return window.webkitCancelAnimationFrame(id);\n else if (window.mozCancelAnimationFrame) return window.mozCancelAnimationFrame(id);\n else {\n return window.clearTimeout(id);\n } \n };\n $.supportTouch = !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n \n // Link to prototype\n $.fn = Dom7.prototype;\n \n // Plugins\n $.fn.scrollTo = function (left, top, duration, easing) {\n return this.each(function () {\n var el = this;\n var currentTop, currentLeft, maxTop, maxLeft, newTop, newLeft, scrollTop, scrollLeft;\n var animateTop = top > 0 || top === 0;\n var animateLeft = left > 0 || left === 0;\n if (typeof easing === 'undefined') {\n easing = 'swing';\n }\n if (animateTop) {\n currentTop = el.scrollTop;\n if (!duration) {\n el.scrollTop = top;\n }\n }\n if (animateLeft) {\n currentLeft = el.scrollLeft;\n if (!duration) {\n el.scrollLeft = left;\n }\n }\n if (!duration) return;\n if (animateTop) {\n maxTop = el.scrollHeight - el.offsetHeight;\n newTop = Math.max(Math.min(top, maxTop), 0);\n }\n if (animateLeft) {\n maxLeft = el.scrollWidth - el.offsetWidth;\n newLeft = Math.max(Math.min(left, maxLeft), 0);\n }\n var startTime = null;\n if (animateTop && newTop === currentTop) animateTop = false;\n if (animateLeft && newLeft === currentLeft) animateLeft = false;\n function render(time) {\n if (time === undefined) {\n time = new Date().getTime();\n }\n if (startTime === null) {\n startTime = time;\n }\n var doneLeft, doneTop, done;\n var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);\n var easeProgress = easing === 'linear' ? progress : (0.5 - Math.cos( progress * Math.PI ) / 2);\n if (animateTop) scrollTop = currentTop + (easeProgress * (newTop - currentTop));\n if (animateLeft) scrollLeft = currentLeft + (easeProgress * (newLeft - currentLeft));\n if (animateTop && newTop > currentTop && scrollTop >= newTop) {\n el.scrollTop = newTop;\n done = true;\n }\n if (animateTop && newTop < currentTop && scrollTop <= newTop) {\n el.scrollTop = newTop;\n done = true;\n }\n \n if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {\n el.scrollLeft = newLeft;\n done = true;\n }\n if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {\n el.scrollLeft = newLeft;\n done = true;\n }\n \n if (done) return;\n if (animateTop) el.scrollTop = scrollTop;\n if (animateLeft) el.scrollLeft = scrollLeft;\n $.requestAnimationFrame(render);\n }\n $.requestAnimationFrame(render);\n });\n };\n $.fn.scrollTop = function (top, duration, easing) {\n var dom = this;\n if (typeof top === 'undefined') {\n if (dom.length > 0) return dom[0].scrollTop;\n else return null;\n }\n return dom.scrollTo(undefined, top, duration, easing);\n };\n $.fn.scrollLeft = function (left, duration, easing) {\n var dom = this;\n if (typeof left === 'undefined') {\n if (dom.length > 0) return dom[0].scrollLeft;\n else return null;\n }\n return dom.scrollTo(left, undefined, duration, easing);\n };\n"," return $;\n })();\n \n // Export Dom7 to Framework7\n Framework7.$ = Dom7;\n \n // Export to local scope\n var $ = Dom7;\n \n // Export to Window\n window.Dom7 = Dom7;\n \n"," /*===========================\n Features Support Detection\n ===========================*/\n Framework7.prototype.support = (function () {\n var support = {\n touch: !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch)\n };\n \n // Export object\n return support;\n })();\n \n"," /*===========================\n Device/OS Detection\n ===========================*/\n Framework7.prototype.device = (function () {\n var device = {};\n var ua = navigator.userAgent;\n var $ = Dom7;\n \n var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n \n device.ios = device.android = device.iphone = device.ipad = device.androidChrome = false;\n \n // Android\n if (android) {\n device.os = 'android';\n device.osVersion = android[2];\n device.android = true;\n device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;\n }\n if (ipad || iphone || ipod) {\n device.os = 'ios';\n device.ios = true;\n }\n // iOS\n if (iphone && !ipod) {\n device.osVersion = iphone[2].replace(/_/g, '.');\n device.iphone = true;\n }\n if (ipad) {\n device.osVersion = ipad[2].replace(/_/g, '.');\n device.ipad = true;\n }\n if (ipod) {\n device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;\n device.iphone = true;\n }\n // iOS 8+ changed UA\n if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {\n if (device.osVersion.split('.')[0] === '10') {\n device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];\n }\n }\n \n // Webview\n device.webView = (iphone || ipad || ipod) && ua.match(/.*AppleWebKit(?!.*Safari)/i);\n \n // Minimal UI\n if (device.os && device.os === 'ios') {\n var osVersionArr = device.osVersion.split('.');\n device.minimalUi = !device.webView &&\n (ipod || iphone) &&\n (osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7) &&\n $('meta[name=\"viewport\"]').length > 0 && $('meta[name=\"viewport\"]').attr('content').indexOf('minimal-ui') >= 0;\n }\n \n // Check for status bar and fullscreen app mode\n var windowWidth = $(window).width();\n var windowHeight = $(window).height();\n device.statusBar = false;\n if (device.webView && (windowWidth * windowHeight === screen.width * screen.height)) {\n device.statusBar = true;\n }\n else {\n device.statusBar = false;\n }\n \n // Classes\n var classNames = [];\n \n // Pixel Ratio\n device.pixelRatio = window.devicePixelRatio || 1;\n classNames.push('pixel-ratio-' + Math.floor(device.pixelRatio));\n if (device.pixelRatio >= 2) {\n classNames.push('retina');\n }\n \n // OS classes\n if (device.os) {\n classNames.push(device.os, device.os + '-' + device.osVersion.split('.')[0], device.os + '-' + device.osVersion.replace(/\\./g, '-'));\n if (device.os === 'ios') {\n var major = parseInt(device.osVersion.split('.')[0], 10);\n for (var i = major - 1; i >= 6; i--) {\n classNames.push('ios-gt-' + i);\n }\n }\n \n }\n // Status bar classes\n if (device.statusBar) {\n classNames.push('with-statusbar-overlay');\n }\n else {\n $('html').removeClass('with-statusbar-overlay');\n }\n \n // Add html classes\n if (classNames.length > 0) $('html').addClass(classNames.join(' '));\n \n // Export object\n return device;\n })();\n \n"," /*===========================\n Plugins prototype\n ===========================*/\n Framework7.prototype.plugins = {};\n \n"," /*===========================\n Template7 Template engine\n ===========================*/\n window.Template7 = (function () {\n function isArray(arr) {\n return Object.prototype.toString.apply(arr) === '[object Array]';\n }\n function isObject(obj) {\n return obj instanceof Object;\n }\n function isFunction(func) {\n return typeof func === 'function';\n }\n var cache = {};\n function helperToSlices(string) {\n var helperParts = string.replace(/[{}#}]/g, '').split(' ');\n var slices = [];\n var shiftIndex, i, j;\n for (i = 0; i < helperParts.length; i++) {\n var part = helperParts[i];\n if (i === 0) slices.push(part);\n else {\n if (part.indexOf('\"') === 0) {\n // Plain String\n if (part.match(/\"/g).length === 2) {\n // One word string\n slices.push(part);\n }\n else {\n // Find closed Index\n shiftIndex = 0;\n for (j = i + 1; j < helperParts.length; j++) {\n part += ' ' + helperParts[j];\n if (helperParts[j].indexOf('\"') >= 0) {\n shiftIndex = j;\n slices.push(part);\n break;\n }\n }\n if (shiftIndex) i = shiftIndex;\n }\n }\n else {\n if (part.indexOf('=') > 0) {\n // Hash\n var hashParts = part.split('=');\n var hashName = hashParts[0];\n var hashContent = hashParts[1];\n if (hashContent.match(/\"/g).length !== 2) {\n shiftIndex = 0;\n for (j = i + 1; j < helperParts.length; j++) {\n hashContent += ' ' + helperParts[j];\n if (helperParts[j].indexOf('\"') >= 0) {\n shiftIndex = j;\n break;\n }\n }\n if (shiftIndex) i = shiftIndex;\n }\n var hash = [hashName, hashContent.replace(/\"/g,'')];\n slices.push(hash);\n }\n else {\n // Plain variable\n slices.push(part);\n }\n }\n }\n }\n return slices;\n }\n function stringToBlocks(string) {\n var blocks = [], i, j, k;\n if (!string) return [];\n var _blocks = string.split(/({{[^{^}]*}})/);\n for (i = 0; i < _blocks.length; i++) {\n var block = _blocks[i];\n if (block === '') continue;\n if (block.indexOf('{{') < 0) {\n blocks.push({\n type: 'plain',\n content: block\n });\n }\n else {\n if (block.indexOf('{/') >= 0) {\n continue;\n }\n if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) {\n // Simple variable\n blocks.push({\n type: 'variable',\n contextName: block.replace(/[{}]/g, '')\n });\n continue;\n }\n // Helpers\n var helperSlices = helperToSlices(block);\n var helperName = helperSlices[0];\n var helperContext = [];\n var helperHash = {};\n for (j = 1; j < helperSlices.length; j++) {\n var slice = helperSlices[j];\n if (isArray(slice)) {\n // Hash\n helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1];\n }\n else {\n helperContext.push(slice);\n }\n }\n \n if (block.indexOf('{#') >= 0) {\n // Condition/Helper\n var helperStartIndex = i;\n var helperContent = '';\n var elseContent = '';\n var toSkip = 0;\n var shiftIndex;\n var foundClosed = false, foundElse = false, foundClosedElse = false, depth = 0;\n for (j = i + 1; j < _blocks.length; j++) {\n if (_blocks[j].indexOf('{{#') >= 0) {\n depth ++;\n }\n if (_blocks[j].indexOf('{{/') >= 0) {\n depth --;\n }\n if (_blocks[j].indexOf('{{#' + helperName) >= 0) {\n helperContent += _blocks[j];\n if (foundElse) elseContent += _blocks[j];\n toSkip ++;\n }\n else if (_blocks[j].indexOf('{{/' + helperName) >= 0) {\n if (toSkip > 0) {\n toSkip--;\n helperContent += _blocks[j];\n if (foundElse) elseContent += _blocks[j];\n }\n else {\n shiftIndex = j;\n foundClosed = true;\n break;\n }\n }\n else if (_blocks[j].indexOf('else') >= 0 && depth === 0) {\n foundElse = true;\n }\n else {\n if (!foundElse) helperContent += _blocks[j];\n if (foundElse) elseContent += _blocks[j];\n }\n \n }\n if (foundClosed) {\n if (shiftIndex) i = shiftIndex;\n blocks.push({\n type: 'helper',\n helperName: helperName,\n contextName: helperContext,\n content: helperContent,\n inverseContent: elseContent,\n hash: helperHash\n });\n }\n }\n else if (block.indexOf(' ') > 0) {\n blocks.push({\n type: 'helper',\n helperName: helperName,\n contextName: helperContext,\n hash: helperHash\n });\n }\n }\n }\n return blocks;\n }\n var Template7 = function (template) {\n var t = this;\n t.template = template;\n \n function getCompileFn(block, depth) {\n if (block.content) return compile(block.content, depth);\n else return function () {return ''; };\n }\n function getCompileInverse(block, depth) {\n if (block.inverseContent) return compile(block.inverseContent, depth);\n else return function () {return ''; };\n }\n function getCompileVar(name, ctx) {\n var parents, variable, context;\n if (name.indexOf('@global') >= 0) {\n variable = '(Template7.global && Template7.global.' + (name.split('@global.')[1]) + ')';\n }\n else if (name.indexOf('@') >= 0) {\n variable = '(data && data.' + name.replace('@', '') + ')';\n }\n else {\n if (name.indexOf('.') > 0) {\n if (name.indexOf('this') === 0) variable = name.replace('this', ctx);\n else variable = ctx + '.' + name;\n }\n else if (name.indexOf('../') === 0) {\n var levelUp = name.split('../').length - 1;\n var newName = name.split('../')[name.split('../').length - 1];\n var newDepth = ctx.split('_')[1] - levelUp;\n variable = 'ctx_' + (newDepth >= 1 ? newDepth : 1) + '.' + newName;\n }\n else {\n variable = name === 'this' ? ctx : ctx + '.' + name;\n }\n }\n return variable;\n }\n function getCompiledArguments(contextArray, ctx) {\n var arr = [];\n for (var i = 0; i < contextArray.length; i++) {\n if (contextArray[i].indexOf('\"') === 0) arr.push(contextArray[i]);\n else {\n arr.push(getCompileVar(contextArray[i], ctx));\n }\n }\n return arr.join(', ');\n }\n function compile(template, depth) {\n depth = depth || 1;\n template = template || t.template;\n if (typeof template !== 'string') {\n throw new Error('Template7: Template must be a string');\n }\n var blocks = stringToBlocks(template);\n \n if (blocks.length === 0) {\n return function () { return ''; };\n }\n var ctx = 'ctx_' + depth;\n var resultString = '(function (' + ctx + ', data) {\\n';\n if (depth === 1) {\n resultString += 'function isArray(arr){return Object.prototype.toString.apply(arr) === \\'[object Array]\\';}\\n';\n resultString += 'function isFunction(func){return (typeof func === \\'function\\');}\\n';\n resultString += 'function c(val, ctx) {if (typeof val !== \"undefined\") {if (isFunction(val)) {return val.call(ctx);} else return val;} else return \"\";}\\n';\n }\n resultString += 'var r = \\'\\';\\n';\n var i, j, context;\n for (i = 0; i < blocks.length; i++) {\n var block = blocks[i];\n // Plain block\n if (block.type === 'plain') {\n resultString += 'r +=\\'' + (block.content).replace(/\\r/g, '\\\\r').replace(/\\n/g, '\\\\n').replace(/'/g, '\\\\' + '\\'') + '\\';';\n continue;\n }\n var variable, compiledArguments;\n // Variable block\n if (block.type === 'variable') {\n variable = getCompileVar(block.contextName, ctx);\n resultString += 'r += c(' + variable + ', ' + ctx + ');';\n }\n // Helpers block\n if (block.type === 'helper') {\n if (block.helperName in t.helpers) {\n compiledArguments = getCompiledArguments(block.contextName, ctx);\n resultString += 'r += (Template7.helpers.' + block.helperName + ').call(' + ctx + ', ' + (compiledArguments && (compiledArguments + ',')) +'{hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';\n }\n else {\n if (block.contextName.length > 0) {\n throw new Error('Template7: Missing helper: \"' + block.helperName + '\"');\n }\n else {\n variable = getCompileVar(block.helperName, ctx);\n resultString += 'if (' + variable + ') {';\n resultString += 'if (isArray(' + variable + ')) {';\n resultString += 'r += (Template7.helpers.each).call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';\n resultString += '}else {';\n resultString += 'r += (Template7.helpers.with).call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';\n resultString += '}}';\n }\n }\n }\n }\n resultString += '\\nreturn r;})';\n return eval.call(window, resultString);\n }\n t.compile = function (template) {\n if (!t.compiled) {\n t.compiled = compile(template);\n }\n return t.compiled;\n };\n };\n Template7.prototype = {\n options: {},\n helpers: {\n 'if': function (context, options) {\n if (isFunction(context)) { context = context.call(this); }\n if (context) {\n return options.fn(this, options.data);\n }\n else {\n return options.inverse(this, options.data);\n }\n },\n 'unless': function (context, options) {\n if (isFunction(context)) { context = context.call(this); }\n if (!context) {\n return options.fn(this, options.data);\n }\n else {\n return options.inverse(this, options.data);\n }\n },\n 'each': function (context, options) {\n var ret = '', i = 0;\n if (isFunction(context)) { context = context.call(this); }\n if (isArray(context)) {\n if (options.hash.reverse) {\n context = context.reverse();\n }\n for (i = 0; i < context.length; i++) {\n ret += options.fn(context[i], {first: i === 0, last: i === context.length - 1, index: i});\n }\n if (options.hash.reverse) {\n context = context.reverse();\n }\n }\n else {\n for (var key in context) {\n i++;\n ret += options.fn(context[key], {key: key});\n }\n }\n if (i > 0) return ret;\n else return options.inverse(this);\n },\n 'with': function (context, options) {\n if (isFunction(context)) { context = context.call(this); }\n return options.fn(context);\n },\n 'join': function (context, options) {\n if (isFunction(context)) { context = context.call(this); }\n return context.join(options.hash.delimiter || options.hash.delimeter);\n }\n }\n };\n var t7 = function (template, data) {\n if (arguments.length === 2) {\n var instance = new Template7(template);\n var rendered = instance.compile()(data);\n instance = null;\n return (rendered);\n }\n else return new Template7(template);\n };\n t7.registerHelper = function (name, fn) {\n Template7.prototype.helpers[name] = fn;\n };\n t7.unregisterHelper = function (name) {\n Template7.prototype.helpers[name] = undefined; \n delete Template7.prototype.helpers[name];\n };\n \n t7.compile = function (template, options) {\n var instance = new Template7(template, options);\n return instance.compile();\n };\n \n t7.options = Template7.prototype.options;\n t7.helpers = Template7.prototype.helpers;\n return t7;\n })();\n"," /*===========================\n Swiper\n ===========================*/\n window.Swiper = function (container, params) {\n var defaults = {\n direction: 'horizontal',\n touchEventsTarget: 'container',\n initialSlide: 0,\n speed: 300,\n // autoplay\n autoplay: false,\n autoplayDisableOnInteraction: true,\n // Free mode\n freeMode: false,\n freeModeMomentum: true,\n freeModeMomentumRatio: 1,\n freeModeMomentumBounce: true,\n freeModeMomentumBounceRatio: 1,\n // Effects\n effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow'\n coverflow: {\n rotate: 50,\n stretch: 0,\n depth: 100,\n modifier: 1,\n slideShadows : true\n },\n cube: {\n slideShadows: true,\n shadow: true,\n shadowOffset: 20,\n shadowScale: 0.94\n },\n // Scrollbar\n scrollbar: null,\n scrollbarHide: true,\n // Keyboard Mousewheel\n keyboardControl: false,\n mousewheelControl: false,\n mousewheelForceToAxis: false,\n // Hash Navigation\n hashnav: false,\n // Slides grid\n spaceBetween: 0,\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerColumnFill: 'column',\n slidesPerGroup: 1,\n centeredSlides: false,\n // Touches\n touchRatio: 1,\n touchAngle: 45,\n simulateTouch: true,\n shortSwipes: true,\n longSwipes: true,\n longSwipesRatio: 0.5,\n longSwipesMs: 300,\n followFinger: true,\n onlyExternal: false,\n threshold: 0,\n touchMoveStopPropagation: true,\n // Pagination\n pagination: null,\n paginationClickable: false,\n paginationHide: false,\n // Resistance\n resistance: true,\n resistanceRatio: 0.85,\n // Next/prev buttons\n nextButton: null,\n prevButton: null,\n // Progress\n watchSlidesProgress: false,\n watchVisibility: false,\n // Cursor\n grabCursor: false,\n // Clicks\n preventClicks: true,\n preventClicksPropagation: true,\n releaseFormElements: true,\n slideToClickedSlide: false,\n // Images\n updateOnImagesReady: true,\n // loop\n loop: false,\n loopAdditionalSlides: 0,\n loopedSlides: null,\n // Control\n control: undefined,\n controlInverse: false,\n // Swiping/no swiping\n allowSwipeToPrev: true,\n allowSwipeToNext: true,\n swipeHandler: null, //'.swipe-handler',\n noSwiping: true,\n noSwipingClass: 'swiper-no-swiping',\n // NS\n slideClass: 'swiper-slide',\n slideActiveClass: 'swiper-slide-active',\n slideVisibleClass: 'swiper-slide-visible',\n slideDuplicateClass: 'swiper-slide-duplicate',\n slideNextClass: 'swiper-slide-next',\n slidePrevClass: 'swiper-slide-prev',\n wrapperClass: 'swiper-wrapper',\n bulletClass: 'swiper-pagination-bullet',\n bulletActiveClass: 'swiper-pagination-bullet-active',\n buttonDisabledClass: 'swiper-button-disabled',\n paginationHiddenClass: 'swiper-pagination-hidden',\n // Observer\n observer: false,\n observeParents: false,\n // Callbacks\n runCallbacksOnInit: true\n /*\n Callbacks:\n onInit: function (swiper)\n onDestroy: function (swiper)\n onClick: function (swiper, e) \n onTap: function (swiper, e) \n onDoubleTap: function (swiper, e) \n onSliderMove: function (swiper, e) \n onSlideChangeStart: function (swiper) \n onSlideChangeEnd: function (swiper) \n onTransitionStart: function (swiper) \n onTransitionEnd: function (swiper) \n onImagesReady: function (swiper) \n onProgress: function (swiper, progress) \n onTouchStart: function (swiper, e) \n onTouchMove: function (swiper, e) \n onTouchMoveOpposite: function (swiper, e) \n onTouchEnd: function (swiper, e) \n onReachBeginning: function (swiper) \n onReachEnd: function (swiper) \n onSetTransition: function (swiper, duration) \n onSetTranslate: function (swiper, translate) \n */\n };\n params = params || {};\n for (var def in defaults) {\n if (typeof params[def] === 'undefined') {\n params[def] = defaults[def];\n }\n else if (typeof params[def] === 'object') {\n for (var deepDef in defaults[def]) {\n if (typeof params[def][deepDef] === 'undefined') {\n params[def][deepDef] = defaults[def][deepDef];\n }\n }\n }\n }\n \n // Swiper\n var s = this;\n \n // Params\n s.params = params;\n /*=========================\n Dom Library and plugins\n ===========================*/\n var $;\n if (typeof Dom7 === 'undefined') {\n $ = window.Dom7 || window.Zepto || window.jQuery;\n }\n else {\n $ = Dom7;\n }\n if (!$) return;\n \n /*=========================\n Preparation - Define Container, Wrapper and Pagination\n ===========================*/\n s.container = $(container);\n if (s.container.length === 0) return;\n if (s.container.length > 1) {\n s.container.each(function () {\n new Swiper(this, params);\n });\n return;\n }\n \n // Save instance in container HTML Element and in data\n s.container[0].swiper = s;\n s.container.data('swiper', s);\n \n s.container.addClass('swiper-container-' + s.params.direction);\n \n if (s.params.freeMode) {\n s.container.addClass('swiper-container-free-mode');\n }\n \n // Coverflow / 3D\n if (['cube', 'coverflow'].indexOf(s.params.effect) >= 0) {\n if (s.support.transforms3d) {\n s.params.watchSlidesProgress = true;\n s.container.addClass('swiper-container-3d');\n }\n else {\n s.params.effect = 'slide';\n }\n }\n if (s.params.effect !== 'slide') {\n s.container.addClass('swiper-container-' + s.params.effect);\n }\n if (s.params.effect === 'cube') {\n s.params.resistanceRatio = 0;\n s.params.slidesPerView = 1;\n s.params.slidesPerColumn = 1;\n s.params.slidesPerGroup = 1;\n s.params.centeredSlides = false;\n s.params.spaceBetween = 0;\n }\n if (s.params.effect === 'fade') {\n s.params.watchSlidesProgress = true;\n s.params.spaceBetween = 0;\n }\n \n // Grab Cursor\n if (s.params.grabCursor && s.support.touch) {\n s.params.grabCursor = false;\n }\n \n // Wrapper\n s.wrapper = s.container.children('.' + s.params.wrapperClass);\n \n // Pagination\n if (s.params.pagination) {\n s.paginationContainer = $(s.params.pagination);\n if (s.params.paginationClickable) {\n s.paginationContainer.addClass('swiper-pagination-clickable');\n }\n }\n \n // Is Horizontal\n function isH() {\n return s.params.direction === 'horizontal';\n }\n \n // RTL\n s.rtl = isH() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n if (s.rtl) s.container.addClass('swiper-container-rtl');\n // Wrong RTL support\n if (s.rtl) {\n s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n }\n \n // Translate\n s.translate = 0;\n \n // Progress\n s.progress = 0;\n \n // Velocity\n s.velocity = 0;\n \n // Locks, unlocks\n s.lockSwipeToNext = function () {\n s.params.allowSwipeToNext = false;\n };\n s.lockSwipeToPrev = function () {\n s.params.allowSwipeToPrev = false;\n };\n s.lockSwipes = function () {\n s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n };\n s.unlockSwipeToNext = function () {\n s.params.allowSwipeToNext = true;\n };\n s.unlockSwipeToPrev = function () {\n s.params.allowSwipeToPrev = true;\n };\n s.unlockSwipes = function () {\n s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n };\n \n // Columns\n if (s.params.slidesPerColumn > 1) {\n s.container.addClass('swiper-container-multirow');\n }\n \n \n /*=========================\n Set grab cursor\n ===========================*/\n if (s.params.grabCursor) {\n s.container[0].style.cursor = 'move';\n s.container[0].style.cursor = '-webkit-grab';\n s.container[0].style.cursor = '-moz-grab';\n s.container[0].style.cursor = 'grab';\n }\n /*=========================\n Update on Images Ready\n ===========================*/\n s.imagesToLoad = [];\n s.imagesLoaded = 0;\n \n function loadImage(img) {\n var image, src;\n var onReady = function () {\n if (typeof s === 'undefined' || s === null) return;\n if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n if (s.imagesLoaded === s.imagesToLoad.length) {\n s.update();\n if (s.params.onImagesReady) s.params.onImagesReady(s);\n }\n };\n \n if (!img.complete) {\n src = (img.currentSrc || img.getAttribute('src'));\n if (src) {\n image = new Image();\n image.onload = onReady;\n image.onerror = onReady;\n image.src = src;\n } else {\n onReady();\n }\n \n } else {//image already loaded...\n onReady();\n }\n }\n s.preloadImages = function () {\n s.imagesToLoad = s.container.find('img');\n \n for (var i = 0; i < s.imagesToLoad.length; i++) {\n loadImage(s.imagesToLoad[i]);\n }\n };\n \n /*=========================\n Autoplay\n ===========================*/\n s.autoplayTimeoutId = undefined;\n s.autoplaying = false;\n s.autoplayPaused = false;\n function autoplay() {\n s.autoplayTimeoutId = setTimeout(function () {\n if (s.params.loop) {\n s.fixLoop();\n s._slideNext();\n }\n else {\n if (!s.isEnd) {\n s._slideNext();\n }\n else {\n if (!params.autoplayStopOnLast) {\n s._slideTo(0);\n }\n else {\n s.stopAutoplay();\n }\n }\n }\n }, s.params.autoplay);\n }\n s.startAutoplay = function () {\n if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n if (!s.params.autoplay) return;\n if (s.autoplaying) return;\n s.autoplaying = true;\n if (s.params.onAutoplayStart) s.params.onAutoplayStart(s);\n autoplay();\n };\n s.stopAutoplay = function (internal) {\n if (!s.autoplayTimeoutId) return;\n if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n s.autoplaying = false;\n s.autoplayTimeoutId = undefined;\n if (s.params.onAutoplayStop) s.params.onAutoplayStop(s);\n };\n s.pauseAutoplay = function (speed) {\n if (s.autoplayPaused) return;\n if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n s.autoplayPaused = true;\n if (speed === 0) {\n s.autoplayPaused = false;\n autoplay();\n }\n else {\n s.wrapper.transitionEnd(function () {\n s.autoplayPaused = false;\n autoplay();\n });\n }\n };\n /*=========================\n Min/Max Translate\n ===========================*/\n s.minTranslate = function () {\n return (-s.snapGrid[0]);\n };\n s.maxTranslate = function () {\n return (-s.snapGrid[s.snapGrid.length - 1]);\n };\n /*=========================\n Slider/slides sizes\n ===========================*/\n s.updateContainerSize = function () {\n s.width = s.container[0].clientWidth;\n s.height = s.container[0].clientHeight;\n s.size = isH() ? s.width : s.height;\n };\n \n s.updateSlidesSize = function () {\n s.slides = s.wrapper.children('.' + s.params.slideClass);\n s.snapGrid = [];\n s.slidesGrid = [];\n s.slidesSizesGrid = [];\n \n var spaceBetween = s.params.spaceBetween,\n slidePosition = 0,\n i,\n prevSlideSize = 0,\n index = 0;\n if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n }\n \n s.virtualWidth = -spaceBetween;\n // reset margins\n if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n else s.slides.css({marginRight: '', marginBottom: ''});\n \n var slidesNumberEvenToRows;\n if (s.params.slidesPerColumn > 1) {\n if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n slidesNumberEvenToRows = s.slides.length;\n }\n else {\n slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n }\n }\n \n // Calc slides\n var slideSize;\n for (i = 0; i < s.slides.length; i++) {\n slideSize = 0;\n var slide = s.slides.eq(i);\n if (s.params.slidesPerColumn > 1) {\n // Set slides order\n var newSlideOrderIndex;\n var column, row;\n var slidesPerColumn = s.params.slidesPerColumn;\n var slidesPerRow;\n if (s.params.slidesPerColumnFill === 'column') {\n column = Math.floor(i / slidesPerColumn);\n row = i - column * slidesPerColumn;\n newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n slide\n .css({\n '-webkit-box-ordinal-group': newSlideOrderIndex,\n '-moz-box-ordinal-group': newSlideOrderIndex,\n '-ms-flex-order': newSlideOrderIndex,\n '-webkit-order': newSlideOrderIndex,\n 'order': newSlideOrderIndex\n });\n }\n else {\n slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n row = Math.floor(i / slidesPerRow);\n column = i - row * slidesPerRow;\n \n }\n slide\n .css({\n 'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n })\n .attr('data-swiper-column', column)\n .attr('data-swiper-row', row);\n \n }\n if (slide.css('display') === 'none') continue;\n if (s.params.slidesPerView === 'auto') {\n slideSize = isH() ? slide.outerWidth(true) : slide.outerHeight(true);\n }\n else {\n slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n if (isH()) {\n s.slides[i].style.width = slideSize + 'px';\n }\n else {\n s.slides[i].style.height = slideSize + 'px';\n }\n }\n s.slides[i].swiperSlideSize = slideSize;\n s.slidesSizesGrid.push(slideSize);\n \n \n if (s.params.centeredSlides) {\n slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n s.slidesGrid.push(slidePosition);\n }\n else {\n if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n s.slidesGrid.push(slidePosition);\n slidePosition = slidePosition + slideSize + spaceBetween;\n }\n \n s.virtualWidth += slideSize + spaceBetween;\n \n prevSlideSize = slideSize;\n \n index ++;\n }\n s.virtualWidth = Math.max(s.virtualWidth, s.size);\n \n var newSlidesGrid;\n \n if (s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n s.wrapper.css({width: s.virtualWidth + s.params.spaceBetween + 'px'});\n }\n \n if (s.params.slidesPerColumn > 1) {\n s.virtualWidth = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n s.virtualWidth = Math.ceil(s.virtualWidth / s.params.slidesPerColumn) - s.params.spaceBetween;\n s.wrapper.css({width: s.virtualWidth + s.params.spaceBetween + 'px'});\n if (s.params.centeredSlides) {\n newSlidesGrid = [];\n for (i = 0; i < s.snapGrid.length; i++) {\n if (s.snapGrid[i] < s.virtualWidth + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n }\n s.snapGrid = newSlidesGrid;\n }\n }\n \n // Remove last grid elements depending on width\n if (!s.params.centeredSlides) {\n newSlidesGrid = [];\n for (i = 0; i < s.snapGrid.length; i++) {\n if (s.snapGrid[i] <= s.virtualWidth - s.size) {\n newSlidesGrid.push(s.snapGrid[i]);\n }\n }\n s.snapGrid = newSlidesGrid;\n if (Math.floor(s.virtualWidth - s.size) > Math.floor(s.snapGrid[s.snapGrid.length - 1])) {\n s.snapGrid.push(s.virtualWidth - s.size);\n }\n }\n if (s.snapGrid.length === 0) s.snapGrid = [0];\n \n if (s.params.spaceBetween !== 0) {\n if (isH()) {\n if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n else s.slides.css({marginRight: spaceBetween + 'px'});\n }\n else s.slides.css({marginBottom: spaceBetween + 'px'});\n }\n if (s.params.watchSlidesProgress) {\n s.updateSlidesOffset();\n }\n };\n s.updateSlidesOffset = function () {\n for (var i = 0; i < s.slides.length; i++) {\n s.slides[i].swiperSlideOffset = isH() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n }\n };\n \n /*=========================\n Slider/slides progress\n ===========================*/\n s.updateSlidesProgress = function (translate) {\n if (typeof translate === 'undefined') {\n translate = s.translate || 0;\n }\n if (s.slides.length === 0) return;\n if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n \n var offsetCenter = s.params.centeredSlides ? -translate + s.size / 2 : -translate;\n if (s.rtl) offsetCenter = s.params.centeredSlides ? translate - s.size / 2 : translate;\n \n // Visible Slides\n var containerBox = s.container[0].getBoundingClientRect();\n var sideBefore = isH() ? 'left' : 'top';\n var sideAfter = isH() ? 'right' : 'bottom';\n s.slides.removeClass(s.params.slideVisibleClass);\n for (var i = 0; i < s.slides.length; i++) {\n var slide = s.slides[i];\n var slideCenterOffset = (s.params.centeredSlides === true) ? slide.swiperSlideSize / 2 : 0;\n var slideProgress = (offsetCenter - slide.swiperSlideOffset - slideCenterOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n if (s.params.watchVisibility) {\n var slideBefore = -(offsetCenter - slide.swiperSlideOffset - slideCenterOffset);\n var slideAfter = slideBefore + s.slidesSizesGrid[i];\n var isVisible =\n (slideBefore >= 0 && slideBefore < s.size) ||\n (slideAfter > 0 && slideAfter <= s.size) ||\n (slideBefore <= 0 && slideAfter >= s.size);\n if (isVisible) {\n s.slides.eq(i).addClass(s.params.slideVisibleClass);\n }\n }\n slide.progress = s.rtl ? -slideProgress : slideProgress;\n }\n };\n s.updateProgress = function (translate) {\n if (typeof translate === 'undefined') {\n translate = s.translate || 0;\n }\n s.progress = (translate - s.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n s.isBeginning = s.isEnd = false;\n \n if (s.progress <= 0) {\n s.isBeginning = true;\n if (s.params.onReachBeginning) s.params.onReachBeginning(s);\n }\n if (s.progress >= 1) {\n s.isEnd = true;\n if (s.params.onReachEnd) s.params.onReachEnd(s);\n }\n if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n if (s.params.onProgress) s.params.onProgress(s, s.progress);\n };\n s.updateActiveIndex = function () {\n var translate = s.rtl ? s.translate : -s.translate;\n var newActiveIndex, i, snapIndex;\n for (i = 0; i < s.slidesGrid.length; i ++) {\n if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n newActiveIndex = i;\n }\n else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n newActiveIndex = i + 1;\n }\n }\n else {\n if (translate >= s.slidesGrid[i]) {\n newActiveIndex = i;\n }\n }\n }\n // Normalize slideIndex\n if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n // for (i = 0; i < s.slidesGrid.length; i++) {\n // if (- translate >= s.slidesGrid[i]) {\n // newActiveIndex = i;\n // }\n // }\n snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n \n if (newActiveIndex === s.activeIndex) {\n return;\n }\n s.snapIndex = snapIndex;\n s.previousIndex = s.activeIndex;\n s.activeIndex = newActiveIndex;\n s.updateClasses();\n };\n \n /*=========================\n Classes\n ===========================*/\n s.updateClasses = function () {\n s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n var activeSlide = s.slides.eq(s.activeIndex);\n // Active classes\n activeSlide.addClass(s.params.slideActiveClass);\n activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n \n // Pagination\n if (s.bullets && s.bullets.length > 0) {\n s.bullets.removeClass(s.params.bulletActiveClass);\n var bulletIndex;\n if (s.params.loop) {\n bulletIndex = s.activeIndex - s.loopedSlides;\n if (bulletIndex > s.slides.length - 1 - s.loopedSlides * 2) {\n bulletIndex = bulletIndex - (s.slides.length - s.loopedSlides * 2);\n }\n }\n else {\n if (typeof s.snapIndex !== 'undefined') {\n bulletIndex = s.snapIndex;\n }\n else {\n bulletIndex = s.activeIndex || 0;\n }\n }\n s.bullets.eq(bulletIndex).addClass(s.params.bulletActiveClass);\n }\n \n // Next/active buttons\n if (!s.params.loop) {\n if (s.params.prevButton) {\n if (s.isBeginning) $(s.params.prevButton).addClass(s.params.buttonDisabledClass);\n else $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n }\n if (s.params.nextButton) {\n if (s.isEnd) $(s.params.nextButton).addClass(s.params.buttonDisabledClass);\n else $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n }\n }\n };\n \n /*=========================\n Pagination\n ===========================*/\n s.updatePagination = function () {\n if (!s.params.pagination) return;\n if (s.paginationContainer && s.paginationContainer.length > 0) {\n var bulletsHTML = '';\n var numberOfBullets = s.params.loop ? s.slides.length - s.loopedSlides * 2 : s.snapGrid.length;\n for (var i = 0; i < numberOfBullets; i++) {\n bulletsHTML += '<span class=\"' + s.params.bulletClass + '\"></span>';\n }\n s.paginationContainer.html(bulletsHTML);\n s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n }\n };\n /*=========================\n Common update method\n ===========================*/\n s.update = function (updateTranslate) {\n s.updateContainerSize();\n s.updateSlidesSize();\n s.updateProgress();\n s.updatePagination();\n s.updateClasses();\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.set();\n }\n if (updateTranslate) {\n var translated, newTranslate;\n if (s.isEnd) {\n translated = s.slideTo(s.slides.length - 1, 0, false, true);\n }\n else {\n translated = s.slideTo(s.activeIndex, 0, false, true);\n }\n if (!translated) {\n newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n s.setWrapperTranslate(newTranslate);\n }\n \n }\n };\n \n /*=========================\n Resize Handler\n ===========================*/\n s.onResize = function () {\n s.updateContainerSize();\n s.updateSlidesSize();\n s.updateProgress();\n s.updateClasses();\n if (s.params.slidesPerView === 'auto') s.updatePagination();\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.set();\n }\n if (s.isEnd) {\n s.slideTo(s.slides.length - 1, 0, false, true);\n }\n else {\n s.slideTo(s.activeIndex, 0, false, true);\n }\n };\n \n /*=========================\n Events\n ===========================*/\n \n //Define Touch Events\n var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\n if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\n else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n \n s.touchEvents = {\n start : s.support.touch || !s.params.simulateTouch ? 'touchstart' : desktopEvents[0],\n move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n };\n \n // WP8 Touch Events Fix\n if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n }\n \n // Attach/detach events\n s.events = function (detach) {\n var actionDom = detach ? 'off' : 'on';\n var actionVanilla = detach ? 'removeEventListener' : 'addEventListener';\n var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container : s.wrapper;\n var target = s.support.touch ? touchEventsTarget : $(document);\n \n var moveCapture = s.params.nested ? true : false;\n \n // Touch events\n touchEventsTarget[0][actionVanilla](s.touchEvents.start, s.onTouchStart, false);\n target[0][actionVanilla](s.touchEvents.move, s.onTouchMove, moveCapture);\n target[0][actionVanilla](s.touchEvents.end, s.onTouchEnd, false);\n window[actionVanilla]('resize', s.onResize);\n \n // Next, Prev, Index\n if (s.params.nextButton) $(s.params.nextButton)[actionDom]('click', s.onClickNext);\n if (s.params.prevButton) $(s.params.prevButton)[actionDom]('click', s.onClickPrev);\n if (s.params.pagination && s.params.paginationClickable) {\n $(s.paginationContainer)[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n }\n \n // Prevent Links Clicks\n if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[0][actionVanilla]('click', s.preventClicks, true);\n };\n s.attachEvents = function (detach) {\n s.events();\n };\n s.detachEvents = function () {\n s.events(true);\n };\n \n /*=========================\n Handle Clicks\n ===========================*/\n // Prevent Clicks\n s.allowClick = true;\n s.preventClicks = function (e) {\n if (!s.allowClick) {\n if (s.params.preventClicks) e.preventDefault();\n if (s.params.preventClicksPropagation) {\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n };\n // Clicks\n s.onClickNext = function (e) {\n e.preventDefault();\n s.slideNext();\n };\n s.onClickPrev = function (e) {\n e.preventDefault();\n s.slidePrev();\n };\n s.onClickIndex = function (e) {\n e.preventDefault();\n var index = $(this).index() * s.params.slidesPerGroup;\n if (s.params.loop) index = index + s.loopedSlides;\n s.slideTo(index);\n };\n \n /*=========================\n Handle Touches\n ===========================*/\n function findElementInEvent(e, selector) {\n var el = $(e.target);\n if (!el.is(selector)) {\n if (typeof selector === 'string') {\n el = el.parents(selector);\n }\n else if (selector.nodeType) {\n var found;\n el.parents().each(function (index, _el) {\n if (_el === selector) found = selector;\n });\n if (!found) return undefined;\n else return selector;\n }\n }\n if (el.length === 0) {\n return undefined;\n }\n return el[0];\n }\n s.updateClickedSlide = function (e) {\n var slide = findElementInEvent(e, '.' + s.params.slideClass);\n if (slide) {\n s.clickedSlide = slide;\n s.clickedIndex = $(slide).index();\n }\n else {\n s.clickedSlide = undefined;\n s.clickedIndex = undefined;\n return;\n }\n if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n var slideToIndex = s.clickedIndex,\n realIndex;\n if (s.params.loop) {\n realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n s.fixLoop();\n slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]').eq(0).index();\n setTimeout(function () {\n s.slideTo(slideToIndex);\n }, 0);\n }\n else if (slideToIndex < s.params.slidesPerView - 1) {\n s.fixLoop();\n var duplicatedSlides = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]');\n slideToIndex = duplicatedSlides.eq(duplicatedSlides.length - 1).index();\n setTimeout(function () {\n s.slideTo(slideToIndex);\n }, 0);\n }\n else {\n s.slideTo(slideToIndex);\n }\n }\n else {\n s.slideTo(slideToIndex);\n }\n }\n };\n \n var isTouched, \n isMoved, \n touchStartTime, \n isScrolling, \n currentTranslate, \n startTranslate, \n allowThresholdMove,\n // Form elements to match\n formElements = 'input, select, textarea, button',\n // Last click time\n lastClickTime = Date.now(), clickTimeout,\n //Velocities\n velocities = [], \n allowMomentumBounce;\n \n // Animating Flag\n s.animating = false;\n \n // Touches information\n s.touches = {\n startX: 0,\n startY: 0,\n currentX: 0,\n currentY: 0,\n diff: 0\n };\n \n // Touch handlers\n s.onTouchStart = function (e) {\n if (e.originalEvent) e = e.originalEvent;\n if (e.type === 'mousedown' && 'which' in e && e.which === 3) return;\n if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) return;\n if (s.params.swipeHandler) {\n if (!findElementInEvent(e, s.params.swipeHandler)) return;\n }\n isTouched = true;\n isMoved = false;\n isScrolling = undefined;\n s.touches.startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n s.touches.startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n touchStartTime = Date.now();\n s.allowClick = true;\n s.updateContainerSize();\n s.swipeDirection = undefined;\n if (s.params.threshold > 0) allowThresholdMove = false;\n if (e.type !== 'touchstart') {\n var preventDefault = true;\n if ($(e.target).is(formElements)) preventDefault = false;\n if (document.activeElement && $(document.activeElement).is(formElements)) document.activeElement.blur();\n if (preventDefault) {\n e.preventDefault();\n }\n }\n if (s.params.onTouchStart) s.params.onTouchStart(s, e);\n };\n \n s.onTouchMove = function (e) {\n if (e.originalEvent) e = e.originalEvent;\n if (e.preventedByNestedSwiper) return;\n if (s.params.onlyExternal) {\n isMoved = true;\n s.allowClick = false;\n return;\n }\n if (s.params.onTouchMove) s.params.onTouchMove(s, e);\n s.allowClick = false;\n if (e.targetTouches && e.targetTouches.length > 1) return;\n \n s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n \n if (typeof isScrolling === 'undefined') {\n var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n isScrolling = isH() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n // isScrolling = !!(isScrolling || Math.abs(touchesCurrent.y - touchesStart.y) > Math.abs(touchesCurrent.x - touchesStart.x));\n }\n if (isScrolling && s.params.onTouchMoveOpposite) {\n s.params.onTouchMoveOpposite(s, e);\n }\n if (!isTouched) return;\n if (isScrolling) {\n isTouched = false;\n return;\n }\n if (s.params.onSliderMove) s.params.onSliderMove(s, e);\n \n e.preventDefault();\n if (s.params.touchMoveStopPropagation && !s.params.nested) {\n e.stopPropagation();\n }\n \n if (!isMoved) {\n if (params.loop) {\n s.fixLoop();\n }\n startTranslate = s.params.effect === 'cube' ? ((s.rtl ? -s.translate: s.translate) || 0) : s.getWrapperTranslate();\n s.setWrapperTransition(0);\n if (s.animating) {\n s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n }\n if (s.params.autoplay && s.autoplaying) {\n if (s.params.autoplayDisableOnInteraction) {\n s.stopAutoplay();\n }\n else {\n s.pauseAutoplay();\n }\n }\n allowMomentumBounce = false;\n //Grab Cursor\n if (s.params.grabCursor) {\n s.container[0].style.cursor = 'move';\n s.container[0].style.cursor = '-webkit-grabbing';\n s.container[0].style.cursor = '-moz-grabbin';\n s.container[0].style.cursor = 'grabbing';\n }\n }\n isMoved = true;\n \n var diff = s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n \n diff = diff * s.params.touchRatio;\n if (s.rtl) diff = -diff;\n \n s.swipeDirection = diff > 0 ? 'prev' : 'next';\n currentTranslate = diff + startTranslate;\n \n var disableParentSwiper = true;\n if ((diff > 0 && currentTranslate > s.minTranslate())) {\n disableParentSwiper = false;\n if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n }\n else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n disableParentSwiper = false;\n if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n }\n \n if (disableParentSwiper) {\n e.preventedByNestedSwiper = true;\n }\n \n // Directions locks\n if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n currentTranslate = startTranslate;\n }\n if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n currentTranslate = startTranslate;\n }\n \n if (!s.params.followFinger) return;\n \n // Threshold\n if (s.params.threshold > 0) {\n if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n if (!allowThresholdMove) {\n allowThresholdMove = true;\n s.touches.startX = s.touches.currentX;\n s.touches.startY = s.touches.currentY;\n currentTranslate = startTranslate;\n s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n return;\n }\n }\n else {\n currentTranslate = startTranslate;\n return;\n }\n }\n // Update active index in free mode\n if (s.params.freeMode || s.params.watchSlidesProgress) {\n s.updateActiveIndex();\n }\n if (s.params.freeMode) {\n //Velocity\n if (velocities.length === 0) {\n velocities.push({\n position: s.touches[isH() ? 'startX' : 'startY'],\n time: touchStartTime\n });\n }\n velocities.push({\n position: s.touches[isH() ? 'currentX' : 'currentY'],\n time: (new Date()).getTime()\n });\n }\n // Update progress\n s.updateProgress(currentTranslate);\n // Update translate\n s.setWrapperTranslate(currentTranslate);\n };\n s.onTouchEnd = function (e) {\n if (e.originalEvent) e = e.originalEvent;\n if (s.params.onTouchEnd) s.params.onTouchEnd(s, e);\n if (!isTouched) return;\n \n //Return Grab Cursor\n if (s.params.grabCursor && isMoved && isTouched) {\n s.container[0].style.cursor = 'move';\n s.container[0].style.cursor = '-webkit-grab';\n s.container[0].style.cursor = '-moz-grab';\n s.container[0].style.cursor = 'grab';\n }\n \n // Time diff\n var touchEndTime = Date.now();\n var timeDiff = touchEndTime - touchStartTime;\n \n // Tap, doubleTap, Click\n if (s.allowClick) {\n s.updateClickedSlide(e);\n if (s.params.onTap) s.params.onTap(s, e);\n if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n if (clickTimeout) clearTimeout(clickTimeout);\n clickTimeout = setTimeout(function () {\n if (!s) return;\n if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n }\n if (s.params.onClick) s.params.onClick(s, e);\n }, 300);\n \n }\n if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n if (clickTimeout) clearTimeout(clickTimeout);\n if (s.params.onDoubleTap) {\n s.params.onDoubleTap(s, e);\n }\n }\n }\n \n lastClickTime = Date.now();\n setTimeout(function () {\n if (s && s.allowClick) s.allowClick = true;\n }, 0);\n \n if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n isTouched = isMoved = false;\n return;\n }\n isTouched = isMoved = false;\n \n var currentPos;\n if (s.params.followFinger) {\n currentPos = s.rtl ? s.translate : -s.translate;\n }\n else {\n currentPos = -currentTranslate;\n }\n if (s.params.freeMode) {\n if (currentPos < -s.minTranslate()) {\n s.slideTo(s.activeIndex);\n return;\n }\n else if (currentPos > -s.maxTranslate()) {\n s.slideTo(s.slides.length - 1);\n return;\n }\n \n if (s.params.freeModeMomentum) {\n if (velocities.length > 1) {\n var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n \n var distance = lastMoveEvent.position - velocityEvent.position;\n var time = lastMoveEvent.time - velocityEvent.time;\n s.velocity = distance / time;\n s.velocity = s.velocity / 2;\n if (Math.abs(s.velocity) < 0.02) {\n s.velocity = 0;\n }\n // this implies that the user stopped moving a finger then released.\n // There would be no events with distance zero, so the last event is stale.\n if (time > 150 || (new Date().getTime() - lastMoveEvent.time) > 300) {\n s.velocity = 0;\n }\n } else {\n s.velocity = 0;\n }\n \n velocities.length = 0;\n var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n var momentumDistance = s.velocity * momentumDuration;\n \n var newPosition = s.translate + momentumDistance;\n if (s.rtl) newPosition = - newPosition;\n var doBounce = false;\n var afterBouncePosition;\n var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n if (newPosition < s.maxTranslate()) {\n if (s.params.freeModeMomentumBounce) {\n if (newPosition + s.maxTranslate() < -bounceAmount) {\n newPosition = s.maxTranslate() - bounceAmount;\n }\n afterBouncePosition = s.maxTranslate();\n doBounce = true;\n allowMomentumBounce = true;\n }\n else {\n newPosition = s.maxTranslate();\n }\n }\n if (newPosition > s.minTranslate()) {\n if (s.params.freeModeMomentumBounce) {\n if (newPosition - s.minTranslate() > bounceAmount) {\n newPosition = s.minTranslate() + bounceAmount;\n }\n afterBouncePosition = s.minTranslate();\n doBounce = true;\n allowMomentumBounce = true;\n }\n else {\n newPosition = s.minTranslate();\n }\n }\n //Fix duration\n if (s.velocity !== 0) {\n if (s.rtl) {\n momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n }\n else {\n momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n }\n }\n \n if (s.params.freeModeMomentumBounce && doBounce) {\n s.updateProgress(afterBouncePosition);\n s.setWrapperTranslate(newPosition);\n s.setWrapperTransition(momentumDuration);\n s.onTransitionStart();\n s.animating = true;\n s.wrapper.transitionEnd(function () {\n if (!allowMomentumBounce) return;\n if (s.params.onMomentumBounce) s.params.onMomentumBounce(s);\n \n s.setWrapperTranslate(afterBouncePosition);\n s.setWrapperTransition(s.params.speed);\n s.wrapper.transitionEnd(function () {\n s.onTransitionEnd();\n });\n });\n } else if (s.velocity) {\n s.updateProgress(newPosition);\n s.setWrapperTranslate(newPosition);\n s.setWrapperTransition(momentumDuration);\n s.onTransitionStart();\n if (!s.animating) {\n s.animating = true;\n s.wrapper.transitionEnd(function () {\n s.onTransitionEnd();\n });\n }\n \n } else {\n s.updateProgress(newPosition);\n }\n \n s.updateActiveIndex();\n }\n if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n s.updateProgress();\n s.updateActiveIndex();\n }\n return;\n }\n \n // Find current slide\n var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n stopIndex = i;\n groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n }\n }\n else {\n if (currentPos >= s.slidesGrid[i]) {\n stopIndex = i;\n groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n }\n }\n }\n \n // Find current slide size\n var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n \n if (timeDiff > s.params.longSwipesMs) {\n // Long touches\n if (!s.params.longSwipes) {\n s.slideTo(s.activeIndex);\n return;\n }\n if (s.swipeDirection === 'next') {\n if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n else s.slideTo(stopIndex);\n \n }\n if (s.swipeDirection === 'prev') {\n if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n else s.slideTo(stopIndex);\n }\n }\n else {\n // Short swipes\n if (!s.params.shortSwipes) {\n s.slideTo(s.activeIndex);\n return;\n }\n if (s.swipeDirection === 'next') {\n s.slideTo(stopIndex + s.params.slidesPerGroup);\n \n }\n if (s.swipeDirection === 'prev') {\n s.slideTo(stopIndex);\n }\n }\n };\n /*=========================\n Transitions\n ===========================*/\n s._slideTo = function (slideIndex, speed) {\n return s.slideTo(slideIndex, speed, true, true);\n };\n s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n if (typeof runCallbacks === 'undefined') runCallbacks = true;\n if (typeof slideIndex === 'undefined') slideIndex = 0;\n if (slideIndex < 0) slideIndex = 0;\n s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n \n var translate = - s.snapGrid[s.snapIndex];\n \n // Stop autoplay\n \n if (s.params.autoplay && s.autoplaying) {\n if (internal || !s.params.autoplayDisableOnInteraction) {\n s.pauseAutoplay(speed);\n }\n else {\n s.stopAutoplay();\n }\n }\n // Update progress\n s.updateProgress(translate);\n \n // Normalize slideIndex\n for (var i = 0; i < s.slidesGrid.length; i++) {\n if (- translate >= s.slidesGrid[i]) {\n slideIndex = i;\n }\n }\n \n if (typeof speed === 'undefined') speed = s.params.speed;\n s.previousIndex = s.activeIndex || 0;\n s.activeIndex = slideIndex;\n \n if (translate === s.translate) {\n s.updateClasses();\n return false;\n }\n if (runCallbacks) s.onTransitionStart();\n var translateX = isH() ? translate : 0, translateY = isH() ? 0 : translate;\n if (speed === 0) {\n s.setWrapperTransition(0);\n s.setWrapperTranslate(translate);\n if (runCallbacks) s.onTransitionEnd();\n }\n else {\n s.setWrapperTransition(speed);\n s.setWrapperTranslate(translate);\n if (!s.animating) {\n s.animating = true;\n s.wrapper.transitionEnd(function () {\n if (runCallbacks) s.onTransitionEnd();\n });\n }\n \n }\n s.updateClasses();\n return true;\n };\n \n s.onTransitionStart = function () {\n if (s.params.onTransitionStart) s.params.onTransitionStart(s);\n if (s.params.onSlideChangeStart && s.activeIndex !== s.previousIndex) s.params.onSlideChangeStart(s);\n };\n s.onTransitionEnd = function () {\n s.animating = false;\n s.setWrapperTransition(0);\n if (s.params.onTransitionEnd) s.params.onTransitionEnd(s);\n if (s.params.onSlideChangeEnd && s.activeIndex !== s.previousIndex) s.params.onSlideChangeEnd(s);\n };\n s.slideNext = function (runCallbacks, speed, internal) {\n if (s.params.loop) {\n if (s.animating) return false;\n s.fixLoop();\n var clientLeft = s.container[0].clientLeft;\n return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n }\n else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n };\n s._slideNext = function (speed) {\n return s.slideNext(true, speed, true);\n };\n s.slidePrev = function (runCallbacks, speed, internal) {\n if (s.params.loop) {\n if (s.animating) return false;\n s.fixLoop();\n var clientLeft = s.container[0].clientLeft;\n return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n }\n else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n };\n s._slidePrev = function (speed) {\n return s.slidePrev(true, speed, true);\n };\n s.slideReset = function (runCallbacks, speed, internal) {\n return s.slideTo(s.activeIndex, speed, runCallbacks);\n };\n \n /*=========================\n Translate/transition helpers\n ===========================*/\n s.setWrapperTransition = function (duration, byController) {\n s.wrapper.transition(duration);\n if (s.params.onSetTransition) s.params.onSetTransition(s, duration);\n if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n s.effects[s.params.effect].setTransition(duration);\n }\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.setTransition(duration);\n }\n if (s.params.control && s.controller) {\n s.controller.setTransition(duration, byController);\n }\n };\n s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n var x = 0, y = 0, z = 0;\n if (isH()) {\n x = s.rtl ? -translate : translate;\n }\n else {\n y = translate;\n }\n \n if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n s.translate = isH() ? x : y;\n if (updateActiveIndex) s.updateActiveIndex();\n if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n s.effects[s.params.effect].setTranslate(s.translate);\n }\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.setTranslate(s.translate);\n }\n if (s.params.control && s.controller) {\n s.controller.setTranslate(s.translate, byController);\n }\n if (s.params.hashnav && s.hashnav) {\n s.hashnav.setHash();\n }\n if (s.params.onSetTranslate) s.params.onSetTranslate(s, s.translate);\n };\n \n s.getTranslate = function (el, axis) {\n var matrix, curTransform, curStyle, transformMatrix;\n \n // automatic axis detection\n if (typeof axis === 'undefined') {\n axis = 'x';\n }\n \n curStyle = window.getComputedStyle(el, null);\n if (window.WebKitCSSMatrix) {\n // Some old versions of Webkit choke when 'none' is passed; pass\n // empty string instead in this case\n transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);\n }\n else {\n transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n matrix = transformMatrix.toString().split(',');\n }\n \n if (axis === 'x') {\n //Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix)\n curTransform = transformMatrix.m41;\n //Crazy IE10 Matrix\n else if (matrix.length === 16)\n curTransform = parseFloat(matrix[12]);\n //Normal Browsers\n else\n curTransform = parseFloat(matrix[4]);\n }\n if (axis === 'y') {\n //Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix)\n curTransform = transformMatrix.m42;\n //Crazy IE10 Matrix\n else if (matrix.length === 16)\n curTransform = parseFloat(matrix[13]);\n //Normal Browsers\n else\n curTransform = parseFloat(matrix[5]);\n }\n if (s.rtl && curTransform) curTransform = -curTransform;\n return curTransform || 0;\n };\n s.getWrapperTranslate = function (axis) {\n if (typeof axis === 'undefined') {\n axis = isH() ? 'x' : 'y';\n }\n return s.getTranslate(s.wrapper[0], axis);\n };\n \n /*=========================\n Observer\n ===========================*/\n s.observers = [];\n function initObserver(target, options) {\n options = options || {};\n // create an observer instance\n var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n var observer = new ObserverFunc(function (mutations) {\n mutations.forEach(function (mutation) {\n s.onResize();\n });\n });\n \n observer.observe(target, {\n attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n childList: typeof options.childList === 'undefined' ? true : options.childList,\n characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n });\n \n s.observers.push(observer);\n }\n s.initObservers = function () {\n if (s.params.observeParents) {\n var containerParents = s.container.parents();\n for (var i = 0; i < containerParents.length; i++) {\n initObserver(containerParents[i]);\n }\n }\n \n // Observe container\n initObserver(s.container[0], {childList: false});\n \n // Observe wrapper\n initObserver(s.wrapper[0], {attributes: false});\n };\n s.disconnectObservers = function () {\n for (var i = 0; i < s.observers.length; i++) {\n s.observers[i].disconnect();\n }\n s.observers = [];\n };\n /*=========================\n Loop\n ===========================*/\n // Create looped slides\n s.createLoop = function () {\n // Remove duplicated slides\n s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n \n var slides = s.wrapper.children('.' + s.params.slideClass);\n s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n if (s.loopedSlides > slides.length) {\n s.loopedSlides = slides.length;\n }\n \n var prependSlides = [], appendSlides = [], i;\n slides.each(function (index, el) {\n var slide = $(this);\n if (index < s.loopedSlides) appendSlides.push(el);\n if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n slide.attr('data-swiper-slide-index', index);\n });\n for (i = 0; i < appendSlides.length; i++) {\n s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n }\n for (i = prependSlides.length - 1; i >= 0; i--) {\n s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n }\n };\n s.destroyLoop = function () {\n s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n };\n s.fixLoop = function () {\n var newIndex;\n //Fix For Negative Oversliding\n if (s.activeIndex < s.loopedSlides) {\n newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n newIndex = newIndex + s.loopedSlides;\n s.slideTo(newIndex, 0, false, true);\n }\n //Fix For Positive Oversliding\n else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n newIndex = newIndex + s.loopedSlides;\n s.slideTo(newIndex, 0, false, true);\n }\n };\n /*=========================\n Append/Prepend/Remove Slides\n ===========================*/\n s.appendSlide = function (slides) {\n if (s.params.loop) {\n s.destroyLoop();\n }\n if (typeof slides === 'object' && slides.length) {\n for (var i = 0; i < slides.length; i++) {\n if (slides[i]) s.wrapper.append(slides[i]);\n }\n }\n else {\n s.wrapper.append(slides);\n }\n if (s.params.loop) {\n s.createLoop();\n }\n if (!(s.params.observer && s.support.observer)) {\n s.update(true);\n }\n };\n s.prependSlide = function (slides) {\n if (s.params.loop) {\n s.destroyLoop();\n }\n var newActiveIndex = s.activeIndex + 1;\n if (typeof slides === 'object' && slides.length) {\n for (var i = 0; i < slides.length; i++) {\n if (slides[i]) s.wrapper.prepend(slides[i]);\n }\n newActiveIndex = s.activeIndex + slides.length;\n }\n else {\n s.wrapper.prepend(slides);\n }\n if (s.params.loop) {\n s.createLoop();\n }\n if (!(s.params.observer && s.support.observer)) {\n s.update(true);\n }\n s.slideTo(newActiveIndex, 0, false);\n };\n s.removeSlide = function (slidesIndexes) {\n if (s.params.loop) {\n s.destroyLoop();\n }\n var newActiveIndex = s.activeIndex,\n indexToRemove;\n if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n for (var i = 0; i < slidesIndexes.length; i++) {\n indexToRemove = slidesIndexes[i];\n if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n if (indexToRemove < newActiveIndex) newActiveIndex--;\n }\n newActiveIndex = Math.max(newActiveIndex, 0);\n }\n else {\n indexToRemove = slidesIndexes;\n if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n if (indexToRemove < newActiveIndex) newActiveIndex--;\n newActiveIndex = Math.max(newActiveIndex, 0);\n }\n \n if (!(s.params.observer && s.support.observer)) {\n s.update(true);\n }\n s.slideTo(newActiveIndex, 0, false);\n };\n s.removeAllSlides = function () {\n var slidesIndexes = [];\n for (var i = 0; i < s.slides.length; i++) {\n slidesIndexes.push(i);\n }\n s.removeSlide(slidesIndexes);\n };\n \n \n /*=========================\n Effects\n ===========================*/\n s.effects = {\n fade: {\n setTranslate: function () {\n for (var i = 0; i < s.slides.length; i++) {\n var slide = s.slides.eq(i);\n var offset = slide[0].swiperSlideOffset;\n var tx = -offset - s.translate;\n var ty = 0;\n if (!isH()) {\n ty = tx;\n tx = 0;\n }\n slide\n .css({\n opacity: 1 + Math.min(Math.max(slide[0].progress, -1), 0)\n })\n .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n \n }\n },\n setTransition: function (duration) {\n s.slides.transition(duration);\n }\n },\n cube: {\n setTranslate: function () {\n var wrapperRotate = 0, cubeShadow;\n if (s.params.cube.shadow) {\n if (isH()) {\n cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n if (cubeShadow.length === 0) {\n cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n s.wrapper.append(cubeShadow);\n }\n cubeShadow.css({height: s.width + 'px'});\n }\n else {\n cubeShadow = s.container.find('.swiper-cube-shadow');\n if (cubeShadow.length === 0) {\n cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n s.container.append(cubeShadow);\n }\n }\n }\n for (var i = 0; i < s.slides.length; i++) {\n var slide = s.slides.eq(i);\n var slideAngle = i * 90;\n var round = Math.floor(slideAngle / 360);\n if (s.rtl) {\n slideAngle = -slideAngle;\n round = Math.floor(-slideAngle / 360);\n }\n var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n var tx = 0, ty = 0, tz = 0;\n if (i % 4 === 0) {\n tx = - round * 4 * s.size;\n tz = 0;\n }\n else if ((i - 1) % 4 === 0) {\n tx = 0;\n tz = - round * 4 * s.size;\n }\n else if ((i - 2) % 4 === 0) {\n tx = s.size + round * 4 * s.size;\n tz = s.size;\n }\n else if ((i - 3) % 4 === 0) {\n tx = - s.size;\n tz = 3 * s.size + s.size * 4 * round;\n }\n if (s.rtl) {\n tx = -tx;\n }\n \n if (!isH()) {\n ty = tx;\n tx = 0;\n }\n \n var transform = 'rotateX(' + (isH() ? 0 : -slideAngle) + 'deg) rotateY(' + (isH() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n if (progress <= 1 && progress > -1) {\n wrapperRotate = i * 90 + progress * 90;\n if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n }\n slide.transform(transform);\n if (s.params.cube.slideShadows) {\n //Set shadows\n var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n if (shadowBefore.length === 0) {\n shadowBefore = $('<div class=\"swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '\"></div>');\n slide.append(shadowBefore);\n }\n if (shadowAfter.length === 0) {\n shadowAfter = $('<div class=\"swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '\"></div>');\n slide.append(shadowAfter);\n }\n var shadowOpacity = slide[0].progress;\n if (shadowBefore.length) shadowBefore[0].style.opacity = -slide[0].progress;\n if (shadowAfter.length) shadowAfter[0].style.opacity = slide[0].progress;\n }\n }\n s.wrapper.css({\n '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n 'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n });\n \n if (s.params.cube.shadow) {\n if (isH()) {\n cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n }\n else {\n var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n var scale1 = s.params.cube.shadowScale,\n scale2 = s.params.cube.shadowScale / multiplier,\n offset = s.params.cube.shadowOffset;\n cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n }\n }\n var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (isH() ? 0 : wrapperRotate) + 'deg) rotateY(' + (isH() ? -wrapperRotate : 0) + 'deg)');\n },\n setTransition: function (duration) {\n s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n if (s.params.cube.shadow && !isH()) {\n s.container.find('.swiper-cube-shadow').transition(duration);\n }\n }\n },\n coverflow: {\n setTranslate: function () {\n var transform = s.translate;\n var center = isH() ? -transform + s.width / 2 : -transform + s.height / 2;\n var rotate = isH() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n var translate = s.params.coverflow.depth;\n //Each slide offset from center\n for (var i = 0, length = s.slides.length; i < length; i++) {\n var slide = s.slides.eq(i);\n var slideSize = s.slidesSizesGrid[i];\n var slideOffset = slide[0].swiperSlideOffset;\n var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n \n var rotateY = isH() ? rotate * offsetMultiplier : 0;\n var rotateX = isH() ? 0 : rotate * offsetMultiplier;\n // var rotateZ = 0\n var translateZ = -translate * Math.abs(offsetMultiplier);\n \n var translateY = isH() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n var translateX = isH() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n \n //Fix for ultra small values\n if (Math.abs(translateX) < 0.001) translateX = 0;\n if (Math.abs(translateY) < 0.001) translateY = 0;\n if (Math.abs(translateZ) < 0.001) translateZ = 0;\n if (Math.abs(rotateY) < 0.001) rotateY = 0;\n if (Math.abs(rotateX) < 0.001) rotateX = 0;\n \n var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n \n slide.transform(slideTransform);\n slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n if (s.params.coverflow.slideShadows) {\n //Set shadows\n var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n if (shadowBefore.length === 0) {\n shadowBefore = $('<div class=\"swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '\"></div>');\n slide.append(shadowBefore);\n }\n if (shadowAfter.length === 0) {\n shadowAfter = $('<div class=\"swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '\"></div>');\n slide.append(shadowAfter);\n }\n if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n }\n }\n \n //Set correct perspective for IE10\n if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n var ws = s.wrapper.style;\n ws.perspectiveOrigin = center + 'px 50%';\n }\n },\n setTransition: function (duration) {\n s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n }\n }\n };\n \n /*=========================\n Scrollbar\n ===========================*/\n s.scrollbar = {\n set: function () {\n if (!s.params.scrollbar) return;\n var sb = s.scrollbar;\n sb.track = $(s.params.scrollbar);\n sb.drag = sb.track.find('.swiper-scrollbar-drag');\n if (sb.drag.length === 0) {\n sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n sb.track.append(sb.drag);\n }\n sb.drag[0].style.width = '';\n sb.drag[0].style.height = '';\n sb.trackSize = isH() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n \n sb.divider = s.size / s.virtualWidth;\n sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n sb.dragSize = sb.trackSize * sb.divider;\n \n if (isH()) {\n sb.drag[0].style.width = sb.dragSize + 'px';\n }\n else {\n sb.drag[0].style.height = sb.dragSize + 'px';\n }\n \n if (sb.divider >= 1) {\n sb.track[0].style.display = 'none';\n }\n else {\n sb.track[0].style.display = '';\n }\n if (s.params.scrollbarHide) {\n sb.track[0].style.opacity = 0;\n }\n },\n setTranslate: function () {\n if (!s.params.scrollbar) return;\n var diff;\n var sb = s.scrollbar;\n var translate = s.translate || 0;\n var newPos;\n \n var newSize = sb.dragSize;\n newPos = (sb.trackSize - sb.dragSize) * s.progress;\n if (s.rtl && isH()) {\n newPos = -newPos;\n if (newPos > 0) {\n newSize = sb.dragSize - newPos;\n newPos = 0;\n }\n else if (-newPos + sb.dragSize > sb.trackSize) {\n newSize = sb.trackSize + newPos;\n }\n }\n else {\n if (newPos < 0) {\n newSize = sb.dragSize + newPos;\n newPos = 0;\n }\n else if (newPos + sb.dragSize > sb.trackSize) {\n newSize = sb.trackSize - newPos;\n }\n }\n if (isH()) {\n sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n sb.drag[0].style.width = newSize + 'px';\n }\n else {\n sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n sb.drag[0].style.height = newSize + 'px';\n }\n if (s.params.scrollbarHide) {\n clearTimeout(sb.timeout);\n sb.track[0].style.opacity = 1;\n sb.timeout = setTimeout(function () {\n sb.track[0].style.opacity = 0;\n sb.track.transition(400);\n }, 1000);\n }\n },\n setTransition: function (duration) {\n if (!s.params.scrollbar) return;\n s.scrollbar.drag.transition(duration);\n }\n };\n \n /*=========================\n Controller\n ===========================*/\n s.controller = {\n setTranslate: function (translate, byController) {\n var controlled = s.params.control;\n var multiplier, controlledTranslate;\n if (s.isArray(controlled)) {\n for (var i = 0; i < controlled.length; i++) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n translate = controlled[i].rtl && controlled[i].params.direction === 'horizontal' ? -s.translate : s.translate;\n multiplier = (controlled[i].maxTranslate() - controlled[i].minTranslate()) / (s.maxTranslate() - s.minTranslate());\n controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled[i].minTranslate();\n if (s.params.controlInverse) {\n controlledTranslate = controlled[i].maxTranslate() - controlledTranslate;\n }\n controlled[i].updateProgress(controlledTranslate);\n controlled[i].setWrapperTranslate(controlledTranslate, false, s);\n controlled[i].updateActiveIndex();\n }\n }\n }\n else if (controlled instanceof Swiper && byController !== controlled) {\n translate = controlled.rtl && controlled.params.direction === 'horizontal' ? -s.translate : s.translate;\n multiplier = (controlled.maxTranslate() - controlled.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled.minTranslate();\n if (s.params.controlInverse) {\n controlledTranslate = controlled.maxTranslate() - controlledTranslate;\n }\n controlled.updateProgress(controlledTranslate);\n controlled.setWrapperTranslate(controlledTranslate, false, s);\n controlled.updateActiveIndex();\n }\n },\n setTransition: function (duration, byController) {\n var controlled = s.params.control;\n if (s.isArray(controlled)) {\n for (var i = 0; i < controlled.length; i++) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n controlled[i].setWrapperTransition(duration, s);\n }\n }\n }\n else if (controlled instanceof Swiper && byController !== controlled) {\n controlled.setWrapperTransition(duration, s);\n }\n }\n };\n \n /*=========================\n Init/Destroy\n ===========================*/\n s.init = function () {\n if (s.params.loop) s.createLoop();\n s.updateContainerSize();\n s.updateSlidesSize();\n s.updatePagination();\n if (s.params.scrollbar && s.scrollbar) {\n s.scrollbar.set();\n }\n if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n if (!s.params.loop) s.updateProgress();\n s.effects[s.params.effect].setTranslate();\n }\n if (s.params.loop) {\n s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n }\n else {\n s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n }\n s.attachEvents();\n if (s.params.observer && s.support.observer) {\n s.initObservers();\n }\n if (s.params.updateOnImagesReady) {\n s.preloadImages();\n }\n if (s.params.autoplay) {\n s.startAutoplay();\n }\n if (s.params.keyboardControl) {\n if (s.enableKeyboardControl) s.enableKeyboardControl();\n }\n if (s.params.mousewheelControl) {\n if (s.enableMousewheelControl) s.enableMousewheelControl();\n }\n if (s.params.hashnav) {\n if (s.hashnav) s.hashnav.init();\n }\n if (s.params.onInit) s.params.onInit(s);\n };\n \n // Destroy\n s.destroy = function (deleteInstance) {\n s.detachEvents();\n s.disconnectObservers();\n if (s.params.keyboardControl) {\n if (s.disableKeyboardControl) s.disableKeyboardControl();\n }\n if (s.params.mousewheelControl) {\n if (s.disableMousewheelControl) s.disableMousewheelControl();\n }\n if (s.params.onDestroy) s.params.onDestroy();\n if (deleteInstance !== false) s = null;\n };\n \n s.init();\n \n \n \n \n // Return swiper instance\n return s;\n };\n \n /*==================================================\n Prototype\n ====================================================*/\n Swiper.prototype = {\n isSafari: (function () {\n var ua = navigator.userAgent.toLowerCase();\n return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n })(),\n isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n isArray: function (arr) {\n return Object.prototype.toString.apply(arr) === '[object Array]';\n },\n /*==================================================\n Feature Detection\n ====================================================*/\n support: {\n touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n })(),\n \n transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n var div = document.createElement('div').style;\n return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n })(),\n \n flexbox: (function () {\n var div = document.createElement('div').style;\n var styles = ('WebkitBox msFlexbox MsFlexbox WebkitFlex MozBox flex').split(' ');\n for (var i = 0; i < styles.length; i++) {\n if (styles[i] in div) return true;\n }\n })(),\n \n observer: (function () {\n return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n })()\n },\n };\n","})();\n"],"sourceRoot":"/source/"}