{"version":3,"sources":["bootstrap-tabdrop.js","jquery.plugin.js","jquery.datepick.js","jquery.validate.js","galleria-1.4.2.js","flowtype.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1uEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACr3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtwNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"omnivendor-new.js","sourcesContent":["/* =========================================================\r\n * bootstrap-tabdrop.js \r\n * http://www.eyecon.ro/bootstrap-tabdrop\r\n * =========================================================\r\n * Copyright 2012 Stefan Petre\r\n *\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n * \r\n * NOTICE: Changes made 2019 by Nathan Brown, Competitive Computing:\r\n * Added ADA support for HTML being injected into page.\r\n * \r\n * ========================================================= */\r\n\r\n!function ($) {\r\n\r\n var WinReszier = (function () {\r\n var registered = [];\r\n var inited = false;\r\n var timer;\r\n var resize = function (ev) {\r\n clearTimeout(timer);\r\n timer = setTimeout(notify, 100);\r\n };\r\n var notify = function () {\r\n for (var i = 0, cnt = registered.length; i < cnt; i++) {\r\n registered[i].apply();\r\n }\r\n };\r\n return {\r\n register: function (fn) {\r\n registered.push(fn);\r\n if (inited === false) {\r\n $(window).bind('resize', resize);\r\n inited = true;\r\n }\r\n },\r\n unregister: function (fn) {\r\n for (var i = 0, cnt = registered.length; i < cnt; i++) {\r\n if (registered[i] == fn) {\r\n delete registered[i];\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }());\r\n\r\n var TabDrop = function (element, options) {\r\n this.element = $(element);\r\n this.dropdown = $('
  • ' + options.text + '
  • ')\r\n\t\t\t\t\t\t\t.appendTo(this.element);\r\n if (this.element.parent().is('.tabs-below')) {\r\n this.dropdown.addClass('dropup');\r\n }\r\n WinReszier.register($.proxy(this.layout, this));\r\n this.layout();\r\n };\r\n\r\n TabDrop.prototype = {\r\n constructor: TabDrop,\r\n\r\n layout: function () {\r\n var collection = [];\r\n // Task 4676: Need to temporarily set the left padding of the first tab element to the dropdown width so we can correctly calculate which tabs overflow. \r\n // The reason this is needed now is because we are appending (instead of prepending) the dropdown to the tablist to be ADA compliant (elements need to show up in logical order).\r\n this.element.find('>li').not('.tabdrop').first().css({ 'padding-left': this.dropdown.width() + 'px' });\r\n this.element.remove('.tabdrop');\r\n this.dropdown.addClass('hide');\r\n this.dropdown.attr(\"aria-hidden\", \"true\");\r\n this.element\r\n\t\t\t\t.append(this.dropdown.find('li'))\r\n\t\t\t\t.find('>li')\r\n\t\t\t\t.not('.tabdrop')\r\n\t\t\t\t.each(function () {\r\n\t\t\t\t if (this.offsetTop > 0) {\r\n\t\t\t\t collection.push(this);\r\n\t\t\t\t }\r\n\t\t\t\t});\r\n if (collection.length > 0) {\r\n collection = $(collection);\r\n this.dropdown\r\n\t\t\t\t\t.find('ul')\r\n\t\t\t\t\t.empty()\r\n\t\t\t\t\t.append(collection);\r\n if (this.dropdown.find('.active').length == 1) {\r\n this.dropdown.addClass('active');\r\n } else {\r\n this.dropdown.removeClass('active');\r\n }\r\n this.dropdown.removeClass('hide');\r\n this.dropdown.attr(\"aria-hidden\", \"false\");\r\n }\r\n this.dropdown.appendTo(this.element);\r\n this.element.find('>li').not('.tabdrop').first().css({'padding-left': '0px'});\r\n }\r\n }\r\n\r\n $.fn.tabdrop = function (option) {\r\n return this.each(function () {\r\n var $this = $(this),\r\n\t\t\t\tdata = $this.data('tabdrop'),\r\n\t\t\t\toptions = typeof option === 'object' && option;\r\n if (!data) {\r\n $this.data('tabdrop', (data = new TabDrop(this, $.extend({}, $.fn.tabdrop.defaults, options))));\r\n }\r\n if (typeof option == 'string') {\r\n data[option]();\r\n }\r\n })\r\n };\r\n\r\n $.fn.tabdrop.defaults = {\r\n \ttext: ''\r\n };\r\n\r\n $.fn.tabdrop.Constructor = TabDrop;\r\n\r\n}(window.jQuery);","/* Simple JavaScript Inheritance\r\n * By John Resig http://ejohn.org/\r\n * MIT Licensed.\r\n */\r\n// Inspired by base2 and Prototype\r\n(function(){\r\n\tvar initializing = false;\r\n\r\n\t// The base JQClass implementation (does nothing)\r\n\twindow.JQClass = function(){};\r\n\r\n\t// Collection of derived classes\r\n\tJQClass.classes = {};\r\n \r\n\t// Create a new JQClass that inherits from this class\r\n\tJQClass.extend = function extender(prop) {\r\n\t\tvar base = this.prototype;\r\n\r\n\t\t// Instantiate a base class (but only create the instance,\r\n\t\t// don't run the init constructor)\r\n\t\tinitializing = true;\r\n\t\tvar prototype = new this();\r\n\t\tinitializing = false;\r\n\r\n\t\t// Copy the properties over onto the new prototype\r\n\t\tfor (var name in prop) {\r\n\t\t\t// Check if we're overwriting an existing function\r\n\t\t\tprototype[name] = typeof prop[name] == 'function' &&\r\n\t\t\t\ttypeof base[name] == 'function' ?\r\n\t\t\t\t(function(name, fn){\r\n\t\t\t\t\treturn function() {\r\n\t\t\t\t\t\tvar __super = this._super;\r\n\r\n\t\t\t\t\t\t// Add a new ._super() method that is the same method\r\n\t\t\t\t\t\t// but on the super-class\r\n\t\t\t\t\t\tthis._super = function(args) {\r\n\t\t\t\t\t\t\treturn base[name].apply(this, args || []);\r\n\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\tvar ret = fn.apply(this, arguments);\t\t\t\t\r\n\r\n\t\t\t\t\t\t// The method only need to be bound temporarily, so we\r\n\t\t\t\t\t\t// remove it when we're done executing\r\n\t\t\t\t\t\tthis._super = __super;\r\n\r\n\t\t\t\t\t\treturn ret;\r\n\t\t\t\t\t};\r\n\t\t\t\t})(name, prop[name]) :\r\n\t\t\t\tprop[name];\r\n\t\t}\r\n\r\n\t\t// The dummy class constructor\r\n\t\tfunction JQClass() {\r\n\t\t\t// All construction is actually done in the init method\r\n\t\t\tif (!initializing && this._init) {\r\n\t\t\t\tthis._init.apply(this, arguments);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Populate our constructed prototype object\r\n\t\tJQClass.prototype = prototype;\r\n\r\n\t\t// Enforce the constructor to be what we expect\r\n\t\tJQClass.prototype.constructor = JQClass;\r\n\r\n\t\t// And make this class extendable\r\n\t\tJQClass.extend = extender;\r\n\r\n\t\treturn JQClass;\r\n\t};\r\n})();\r\n\r\n(function($) { // Ensure $, encapsulate\r\n\r\n\t/** Abstract base class for collection plugins v1.0.1.\r\n\t\tWritten by Keith Wood (kbwood{at}iinet.com.au) December 2013.\r\n\t\tLicensed under the MIT (http://keith-wood.name/licence.html) license.\r\n\t\t@module $.JQPlugin\r\n\t\t@abstract */\r\n\tJQClass.classes.JQPlugin = JQClass.extend({\r\n\r\n\t\t/** Name to identify this plugin.\r\n\t\t\t@example name: 'tabs' */\r\n\t\tname: 'plugin',\r\n\r\n\t\t/** Default options for instances of this plugin (default: {}).\r\n\t\t\t@example defaultOptions: {\r\n \tselectedClass: 'selected',\r\n \ttriggers: 'click'\r\n } */\r\n\t\tdefaultOptions: {},\r\n\t\t\r\n\t\t/** Options dependent on the locale.\r\n\t\t\tIndexed by language and (optional) country code, with '' denoting the default language (English/US).\r\n\t\t\t@example regionalOptions: {\r\n\t'': {\r\n\t\tgreeting: 'Hi'\r\n\t}\r\n } */\r\n\t\tregionalOptions: {},\r\n\t\t\r\n\t\t/** Names of getter methods - those that can't be chained (default: []).\r\n\t\t\t@example _getters: ['activeTab'] */\r\n\t\t_getters: [],\r\n\r\n\t\t/** Retrieve a marker class for affected elements.\r\n\t\t\t@private\r\n\t\t\t@return {string} The marker class. */\r\n\t\t_getMarker: function() {\r\n\t\t\treturn 'is-' + this.name;\r\n\t\t},\r\n\t\t\r\n\t\t/** Initialise the plugin.\r\n\t\t\tCreate the jQuery bridge - plugin name xyz\r\n\t\t\tproduces $.xyz and $.fn.xyz. */\r\n\t\t_init: function() {\r\n\t\t\t// Apply default localisations\r\n\t\t\t$.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {});\r\n\t\t\t// Camel-case the name\r\n\t\t\tvar jqName = camelCase(this.name);\r\n\t\t\t// Expose jQuery singleton manager\r\n\t\t\t$[jqName] = this;\r\n\t\t\t// Expose jQuery collection plugin\r\n\t\t\t$.fn[jqName] = function(options) {\r\n\t\t\t\tvar otherArgs = Array.prototype.slice.call(arguments, 1);\r\n\t\t\t\tif ($[jqName]._isNotChained(options, otherArgs)) {\r\n\t\t\t\t\treturn $[jqName][options].apply($[jqName], [this[0]].concat(otherArgs));\r\n\t\t\t\t}\r\n\t\t\t\treturn this.each(function() {\r\n\t\t\t\t\tif (typeof options === 'string') {\r\n\t\t\t\t\t\tif (options[0] === '_' || !$[jqName][options]) {\r\n\t\t\t\t\t\t\tthrow 'Unknown method: ' + options;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t$[jqName][options].apply($[jqName], [this].concat(otherArgs));\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\t$[jqName]._attach(this, options);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t};\r\n\t\t},\r\n\r\n\t\t/** Set default values for all subsequent instances.\r\n\t\t\t@param options {object} The new default options.\r\n\t\t\t@example $.plugin.setDefauls({name: value}) */\r\n\t\tsetDefaults: function(options) {\r\n\t\t\t$.extend(this.defaultOptions, options || {});\r\n\t\t},\r\n\t\t\r\n\t\t/** Determine whether a method is a getter and doesn't permit chaining.\r\n\t\t\t@private\r\n\t\t\t@param name {string} The method name.\r\n\t\t\t@param otherArgs {any[]} Any other arguments for the method.\r\n\t\t\t@return {boolean} True if this method is a getter, false otherwise. */\r\n\t\t_isNotChained: function(name, otherArgs) {\r\n\t\t\tif (name === 'option' && (otherArgs.length === 0 ||\r\n\t\t\t\t\t(otherArgs.length === 1 && typeof otherArgs[0] === 'string'))) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\treturn $.inArray(name, this._getters) > -1;\r\n\t\t},\r\n\t\t\r\n\t\t/** Initialise an element. Called internally only.\r\n\t\t\tAdds an instance object as data named for the plugin.\r\n\t\t\t@param elem {Element} The element to enhance.\r\n\t\t\t@param options {object} Overriding settings. */\r\n\t\t_attach: function(elem, options) {\r\n\t\t\telem = $(elem);\r\n\t\t\tif (elem.hasClass(this._getMarker())) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\telem.addClass(this._getMarker());\r\n\t\t\toptions = $.extend({}, this.defaultOptions, this._getMetadata(elem), options || {});\r\n\t\t\tvar inst = $.extend({name: this.name, elem: elem, options: options},\r\n\t\t\t\tthis._instSettings(elem, options));\r\n\t\t\telem.data(this.name, inst); // Save instance against element\r\n\t\t\tthis._postAttach(elem, inst);\r\n\t\t\tthis.option(elem, options);\r\n\t\t},\r\n\r\n\t\t/** Retrieve additional instance settings.\r\n\t\t\tOverride this in a sub-class to provide extra settings.\r\n\t\t\t@param elem {jQuery} The current jQuery element.\r\n\t\t\t@param options {object} The instance options.\r\n\t\t\t@return {object} Any extra instance values.\r\n\t\t\t@example _instSettings: function(elem, options) {\r\n \treturn {nav: elem.find(options.navSelector)};\r\n } */\r\n\t\t_instSettings: function(elem, options) {\r\n\t\t\treturn {};\r\n\t\t},\r\n\r\n\t\t/** Plugin specific post initialisation.\r\n\t\t\tOverride this in a sub-class to perform extra activities.\r\n\t\t\t@param elem {jQuery} The current jQuery element.\r\n\t\t\t@param inst {object} The instance settings.\r\n\t\t\t@example _postAttach: function(elem, inst) {\r\n \telem.on('click.' + this.name, function() {\r\n \t\t...\r\n \t});\r\n } */\r\n\t\t_postAttach: function(elem, inst) {\r\n\t\t},\r\n\r\n\t\t/** Retrieve metadata configuration from the element.\r\n\t\t\tMetadata is specified as an attribute:\r\n\t\t\tdata-<plugin name>=\"<setting name>: '<value>', ...\".\r\n\t\t\tDates should be specified as strings in this format: 'new Date(y, m-1, d)'.\r\n\t\t\t@private\r\n\t\t\t@param elem {jQuery} The source element.\r\n\t\t\t@return {object} The inline configuration or {}. */\r\n\t\t_getMetadata: function(elem) {\r\n\t\t\ttry {\r\n\t\t\t\tvar data = elem.data(this.name.toLowerCase()) || '';\r\n\t\t\t\tdata = data.replace(/'/g, '\"');\r\n\t\t\t\tdata = data.replace(/([a-zA-Z0-9]+):/g, function(match, group, i) { \r\n\t\t\t\t\tvar count = data.substring(0, i).match(/\"/g); // Handle embedded ':'\r\n\t\t\t\t\treturn (!count || count.length % 2 === 0 ? '\"' + group + '\":' : group + ':');\r\n\t\t\t\t});\r\n\t\t\t\tdata = $.parseJSON('{' + data + '}');\r\n\t\t\t\tfor (var name in data) { // Convert dates\r\n\t\t\t\t\tvar value = data[name];\r\n\t\t\t\t\tif (typeof value === 'string' && value.match(/^new Date\\((.*)\\)$/)) {\r\n\t\t\t\t\t\tdata[name] = eval(value);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn data;\r\n\t\t\t}\r\n\t\t\tcatch (e) {\r\n\t\t\t\treturn {};\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Retrieve the instance data for element.\r\n\t\t\t@param elem {Element} The source element.\r\n\t\t\t@return {object} The instance data or {}. */\r\n\t\t_getInst: function(elem) {\r\n\t\t\treturn $(elem).data(this.name) || {};\r\n\t\t},\r\n\t\t\r\n\t\t/** Retrieve or reconfigure the settings for a plugin.\r\n\t\t\t@param elem {Element} The source element.\r\n\t\t\t@param name {object|string} The collection of new option values or the name of a single option.\r\n\t\t\t@param [value] {any} The value for a single named option.\r\n\t\t\t@return {any|object} If retrieving a single value or all options.\r\n\t\t\t@example $(selector).plugin('option', 'name', value)\r\n $(selector).plugin('option', {name: value, ...})\r\n var value = $(selector).plugin('option', 'name')\r\n var options = $(selector).plugin('option') */\r\n\t\toption: function(elem, name, value) {\r\n\t\t\telem = $(elem);\r\n\t\t\tvar inst = elem.data(this.name);\r\n\t\t\tif (!name || (typeof name === 'string' && value == null)) {\r\n\t\t\t\tvar options = (inst || {}).options;\r\n\t\t\t\treturn (options && name ? options[name] : options);\r\n\t\t\t}\r\n\t\t\tif (!elem.hasClass(this._getMarker())) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tvar options = name || {};\r\n\t\t\tif (typeof name === 'string') {\r\n\t\t\t\toptions = {};\r\n\t\t\t\toptions[name] = value;\r\n\t\t\t}\r\n\t\t\tthis._optionsChanged(elem, inst, options);\r\n\t\t\t$.extend(inst.options, options);\r\n\t\t},\r\n\t\t\r\n\t\t/** Plugin specific options processing.\r\n\t\t\tOld value available in inst.options[name], new value in options[name].\r\n\t\t\tOverride this in a sub-class to perform extra activities.\r\n\t\t\t@param elem {jQuery} The current jQuery element.\r\n\t\t\t@param inst {object} The instance settings.\r\n\t\t\t@param options {object} The new options.\r\n\t\t\t@example _optionsChanged: function(elem, inst, options) {\r\n \tif (options.name != inst.options.name) {\r\n \t\telem.removeClass(inst.options.name).addClass(options.name);\r\n \t}\r\n } */\r\n\t\t_optionsChanged: function(elem, inst, options) {\r\n\t\t},\r\n\t\t\r\n\t\t/** Remove all trace of the plugin.\r\n\t\t\tOverride _preDestroy for plugin-specific processing.\r\n\t\t\t@param elem {Element} The source element.\r\n\t\t\t@example $(selector).plugin('destroy') */\r\n\t\tdestroy: function(elem) {\r\n\t\t\telem = $(elem);\r\n\t\t\tif (!elem.hasClass(this._getMarker())) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tthis._preDestroy(elem, this._getInst(elem));\r\n\t\t\telem.removeData(this.name).removeClass(this._getMarker());\r\n\t\t},\r\n\r\n\t\t/** Plugin specific pre destruction.\r\n\t\t\tOverride this in a sub-class to perform extra activities and undo everything that was\r\n\t\t\tdone in the _postAttach or _optionsChanged functions.\r\n\t\t\t@param elem {jQuery} The current jQuery element.\r\n\t\t\t@param inst {object} The instance settings.\r\n\t\t\t@example _preDestroy: function(elem, inst) {\r\n \telem.off('.' + this.name);\r\n } */\r\n\t\t_preDestroy: function(elem, inst) {\r\n\t\t}\r\n\t});\r\n\t\r\n\t/** Convert names from hyphenated to camel-case.\r\n\t\t@private\r\n\t\t@param value {string} The original hyphenated name.\r\n\t\t@return {string} The camel-case version. */\r\n\tfunction camelCase(name) {\r\n\t\treturn name.replace(/-([a-z])/g, function(match, group) {\r\n\t\t\treturn group.toUpperCase();\r\n\t\t});\r\n\t}\r\n\t\r\n\t/** Expose the plugin base.\r\n\t\t@namespace \"$.JQPlugin\" */\r\n\t$.JQPlugin = {\r\n\t\r\n\t\t/** Create a new collection plugin.\r\n\t\t\t@memberof \"$.JQPlugin\"\r\n\t\t\t@param [superClass='JQPlugin'] {string} The name of the parent class to inherit from.\r\n\t\t\t@param overrides {object} The property/function overrides for the new class.\r\n\t\t\t@example $.JQPlugin.createPlugin({\r\n \tname: 'tabs',\r\n \tdefaultOptions: {selectedClass: 'selected'},\r\n \t_initSettings: function(elem, options) { return {...}; },\r\n \t_postAttach: function(elem, inst) { ... }\r\n }); */\r\n\t\tcreatePlugin: function(superClass, overrides) {\r\n\t\t\tif (typeof superClass === 'object') {\r\n\t\t\t\toverrides = superClass;\r\n\t\t\t\tsuperClass = 'JQPlugin';\r\n\t\t\t}\r\n\t\t\tsuperClass = camelCase(superClass);\r\n\t\t\tvar className = camelCase(overrides.name);\r\n\t\t\tJQClass.classes[className] = JQClass.classes[superClass].extend(overrides);\r\n\t\t\tnew JQClass.classes[className]();\r\n\t\t}\r\n\t};\r\n\r\n})(jQuery);","/* http://keith-wood.name/datepick.html\r\n Date picker for jQuery v5.0.1.\r\n Written by Keith Wood (kbwood{at}iinet.com.au) February 2010.\r\n Licensed under the MIT (http://keith-wood.name/licence.html) licence. \r\n Please attribute the author if you use it. */\r\n\r\n(function($) { // Hide scope, no $ conflict\r\n\r\n\tvar pluginName = 'datepick';\r\n\r\n // Multi-language calendar labels from CMS\r\n\tvar cmsMonthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\r\n\tvar cmsMonthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\r\n\tvar cmsDayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\r\n\tvar cmsDayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\r\n\r\n\tvar longMonths = $(\".calendar-container\").data(\"long-months\");\r\n\tif (longMonths) {\r\n\t cmsMonthNames = longMonths.split(\",\");\r\n\t}\r\n\tvar shortMonths = $(\".calendar-container\").data(\"short-months\");\r\n\tif (shortMonths) {\r\n\t cmsMonthNamesShort = shortMonths.split(\",\");\r\n\t}\r\n\r\n\tvar longWeekdays = $(\".calendar-container\").data(\"long-weekdays\");\r\n\tif (longWeekdays) {\r\n\t cmsDayNames = longWeekdays.split(\",\");\r\n\t}\r\n\tvar shortWeekdays = $(\".calendar-container\").data(\"short-weekdays\");\r\n\tif (shortWeekdays) {\r\n\t cmsDayNamesShort = shortWeekdays.split(\",\");\r\n\t}\r\n // End multi-language calendar labels from CMS\r\n\r\n\t/** Create the datepicker plugin.\r\n\t\t

    Sets an input field to popup a calendar for date entry,\r\n\t\t\tor a div or span to show an inline calendar.

    \r\n\t\t

    Expects HTML like:

    \r\n\t\t
    <input type=\"text\"> or <div></div>
    \r\n\t\t

    Provide inline configuration like:

    \r\n\t\t
    <input type=\"text\" data-datepick=\"name: 'value'\"/>
    \r\n\t \t@module Datepick\r\n\t\t@augments JQPlugin\r\n\t\t@example $(selector).datepick()\r\n $(selector).datepick({minDate: 0, maxDate: '+1m +1w'}) */\r\n\t$.JQPlugin.createPlugin({\r\n\t\r\n\t\t/** The name of the plugin. */\r\n\t\tname: pluginName,\r\n\t\t\r\n\t\t/** Default template for generating a datepicker.\r\n\t\t\tInsert anywhere: '{l10n:name}' to insert localised value for name,\r\n\t\t\t'{link:name}' to insert a link trigger for command name,\r\n\t\t\t'{button:name}' to insert a button trigger for command name,\r\n\t\t\t'{popup:start}...{popup:end}' to mark a section for inclusion in a popup datepicker only,\r\n\t\t\t'{inline:start}...{inline:end}' to mark a section for inclusion in an inline datepicker only.\r\n\t\t\t@property picker {string} Overall structure: '{months}' to insert calendar months.\r\n\t\t\t@property monthRow {string} One row of months: '{months}' to insert calendar months.\r\n\t\t\t@property month {string} A single month: '{monthHeader:dateFormat}' to insert the month header -\r\n\t\t\t\t\t\tdateFormat is optional and defaults to 'MM yyyy',\r\n\t\t\t\t\t\t'{weekHeader}' to insert a week header, '{weeks}' to insert the month's weeks.\r\n\t\t\t@property weekHeader {string} A week header: '{days}' to insert individual day names.\r\n\t\t\t@property dayHeader {string} Individual day header: '{day}' to insert day name.\r\n\t\t\t@property week {string} One week of the month: '{days}' to insert the week's days,\r\n\t\t\t\t\t\t'{weekOfYear}' to insert week of year.\r\n\t\t\t@property day {string} An individual day: '{day}' to insert day value.\r\n\t\t\t@property monthSelector {string} jQuery selector, relative to picker, for a single month.\r\n\t\t\t@property daySelector {string} jQuery selector, relative to picker, for individual days.\r\n\t\t\t@property rtlClass {string} Class for right-to-left (RTL) languages.\r\n\t\t\t@property multiClass {string} Class for multi-month datepickers.\r\n\t\t\t@property defaultClass {string} Class for selectable dates.\r\n\t\t\t@property selectedClass {string} Class for currently selected dates.\r\n\t\t\t@property highlightedClass {string} Class for highlighted dates.\r\n\t\t\t@property todayClass {string} Class for today.\r\n\t\t\t@property otherMonthClass {string} Class for days from other months.\r\n\t\t\t@property weekendClass {string} Class for days on weekends.\r\n\t\t\t@property commandClass {string} Class prefix for commands.\r\n\t\t\t@property commandButtonClass {string} Extra class(es) for commands that are buttons.\r\n\t\t\t@property commandLinkClass {string} Extra class(es) for commands that are links.\r\n\t\t\t@property disabledClass {string} Class for disabled commands. */\r\n\t\tdefaultRenderer: {\r\n\t\t\tpicker: '
    ' +\r\n\t\t\t'
    {link:prev}{link:today}{link:next}
    {months}' +\r\n\t\t\t'{popup:start}
    {link:clear}{link:close}
    {popup:end}' +\r\n\t\t\t'
    ',\r\n\t\t\tmonthRow: '
    {months}
    ',\r\n\t\t\tmonth: '
    {monthHeader}
    ' +\r\n\t\t\t'{weekHeader}{weeks}
    ',\r\n\t\t\tweekHeader: '{days}',\r\n\t\t\tdayHeader: '{day}',\r\n\t\t\tweek: '{days}',\r\n\t\t\tday: '{day}',\r\n\t\t\tmonthSelector: '.datepick-month',\r\n\t\t\tdaySelector: 'td',\r\n\t\t\trtlClass: 'datepick-rtl',\r\n\t\t\tmultiClass: 'datepick-multi',\r\n\t\t\tdefaultClass: '',\r\n\t\t\tselectedClass: 'datepick-selected',\r\n\t\t\thighlightedClass: 'datepick-highlight',\r\n\t\t\ttodayClass: 'datepick-today',\r\n\t\t\totherMonthClass: 'datepick-other-month',\r\n\t\t\tweekendClass: 'datepick-weekend',\r\n\t\t\tcommandClass: 'datepick-cmd',\r\n\t\t\tcommandButtonClass: '',\r\n\t\t\tcommandLinkClass: '',\r\n\t\t\tdisabledClass: 'datepick-disabled'\r\n\t\t},\r\n\t\r\n\t\t/** Command actions that may be added to a layout by name.\r\n\t\t\t\r\n\t\t\tThe command name is the key name and is used to add the command to a layout\r\n\t\t\twith '{button:name}' or '{link:name}'. Each has the following attributes.\r\n\t\t\t@property text {string} The field in the regional settings for the displayed text.\r\n\t\t\t@property status {string} The field in the regional settings for the status text.\r\n\t\t\t@property keystroke {object} The keystroke to trigger the action, with attributes:\r\n\t\t\t\tkeyCode {number} the code for the keystroke,\r\n\t\t\t\tctrlKey {boolean} true if Ctrl is required,\r\n\t\t\t\taltKey {boolean} true if Alt is required,\r\n\t\t\t\tshiftKey {boolean} true if Shift is required.\r\n\t\t\t@property enabled {DatepickCommandEnabled} The function that indicates the command is enabled.\r\n\t\t\t@property date {DatepickCommandDate} The function to get the date associated with this action.\r\n\t\t\t@property action {DatepickCommandAction} The function that implements the action. */\r\n\t\tcommands: {\r\n\t\t\tprev: {text: 'prevText', status: 'prevStatus', // Previous month\r\n\t\t\t\tkeystroke: {keyCode: 33}, // Page up\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar minDate = inst.curMinDate();\r\n\t\t\t\t\treturn (!minDate || plugin.add(plugin.day(\r\n\t\t\t\t\t\tplugin._applyMonthsOffset(plugin.add(plugin.newDate(inst.drawDate),\r\n\t\t\t\t\t\t1 - inst.options.monthsToStep, 'm'), inst), 1), -1, 'd').\r\n\t\t\t\t\t\tgetTime() >= minDate.getTime()); },\r\n\t\t\t\tdate: function(inst) {\r\n\t\t\t\t\treturn plugin.day(plugin._applyMonthsOffset(plugin.add(\r\n\t\t\t\t\t\tplugin.newDate(inst.drawDate), -inst.options.monthsToStep, 'm'), inst), 1); },\r\n\t\t\t\taction: function(inst) {\r\n\t\t\t\t\tplugin.changeMonth(this, -inst.options.monthsToStep); }\r\n\t\t\t},\r\n\t\t\tprevJump: {text: 'prevJumpText', status: 'prevJumpStatus', // Previous year\r\n\t\t\t\tkeystroke: {keyCode: 33, ctrlKey: true}, // Ctrl + Page up\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar minDate = inst.curMinDate();\r\n\t\t\t\t\treturn (!minDate || plugin.add(plugin.day(\r\n\t\t\t\t\t\tplugin._applyMonthsOffset(plugin.add(plugin.newDate(inst.drawDate),\r\n\t\t\t\t\t\t1 - inst.options.monthsToJump, 'm'), inst), 1), -1, 'd').\r\n\t\t\t\t\t\tgetTime() >= minDate.getTime()); },\r\n\t\t\t\tdate: function(inst) {\r\n\t\t\t\t\treturn plugin.day(plugin._applyMonthsOffset(plugin.add(\r\n\t\t\t\t\t\tplugin.newDate(inst.drawDate), -inst.options.monthsToJump, 'm'), inst), 1); },\r\n\t\t\t\taction: function(inst) {\r\n\t\t\t\t\tplugin.changeMonth(this, -inst.options.monthsToJump); }\r\n\t\t\t},\r\n\t\t\tnext: {text: 'nextText', status: 'nextStatus', // Next month\r\n\t\t\t\tkeystroke: {keyCode: 34}, // Page down\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\t\t\treturn (!maxDate || plugin.day(plugin._applyMonthsOffset(plugin.add(\r\n\t\t\t\t\t\tplugin.newDate(inst.drawDate), inst.options.monthsToStep, 'm'), inst), 1).\r\n\t\t\t\t\t\tgetTime() <= maxDate.getTime()); },\r\n\t\t\t\tdate: function(inst) {\r\n\t\t\t\t\treturn plugin.day(plugin._applyMonthsOffset(plugin.add(\r\n\t\t\t\t\t\tplugin.newDate(inst.drawDate), inst.options.monthsToStep, 'm'), inst), 1); },\r\n\t\t\t\taction: function(inst) {\r\n\t\t\t\t\tplugin.changeMonth(this, inst.options.monthsToStep); }\r\n\t\t\t},\r\n\t\t\tnextJump: {text: 'nextJumpText', status: 'nextJumpStatus', // Next year\r\n\t\t\t\tkeystroke: {keyCode: 34, ctrlKey: true}, // Ctrl + Page down\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\t\t\treturn (!maxDate || plugin.day(plugin._applyMonthsOffset(plugin.add(\r\n\t\t\t\t\t\tplugin.newDate(inst.drawDate), inst.options.monthsToJump, 'm'), inst), 1).\r\n\t\t\t\t\t\tgetTime() <= maxDate.getTime()); },\r\n\t\t\t\tdate: function(inst) {\r\n\t\t\t\t\treturn plugin.day(plugin._applyMonthsOffset(plugin.add(\r\n\t\t\t\t\t\tplugin.newDate(inst.drawDate), inst.options.monthsToJump, 'm'), inst), 1); },\r\n\t\t\t\taction: function(inst) {\r\n\t\t\t\t\tplugin.changeMonth(this, inst.options.monthsToJump); }\r\n\t\t\t},\r\n\t\t\tcurrent: {text: 'currentText', status: 'currentStatus', // Current month\r\n\t\t\t\tkeystroke: {keyCode: 36, ctrlKey: true}, // Ctrl + Home\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar minDate = inst.curMinDate();\r\n\t\t\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\t\t\tvar curDate = inst.selectedDates[0] || plugin.today();\r\n\t\t\t\t\treturn (!minDate || curDate.getTime() >= minDate.getTime()) &&\r\n\t\t\t\t\t\t(!maxDate || curDate.getTime() <= maxDate.getTime()); },\r\n\t\t\t\tdate: function(inst) {\r\n\t\t\t\t\treturn inst.selectedDates[0] || plugin.today(); },\r\n\t\t\t\taction: function(inst) {\r\n\t\t\t\t\tvar curDate = inst.selectedDates[0] || plugin.today();\r\n\t\t\t\t\tplugin.showMonth(this, curDate.getFullYear(), curDate.getMonth() + 1); }\r\n\t\t\t},\r\n\t\t\ttoday: {text: 'todayText', status: 'todayStatus', // Today's month\r\n\t\t\t\tkeystroke: {keyCode: 36, ctrlKey: true}, // Ctrl + Home\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar minDate = inst.curMinDate();\r\n\t\t\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\t\t\treturn (!minDate || plugin.today().getTime() >= minDate.getTime()) &&\r\n\t\t\t\t\t\t(!maxDate || plugin.today().getTime() <= maxDate.getTime()); },\r\n\t\t\t\tdate: function(inst) { return plugin.today(); },\r\n\t\t\t\taction: function(inst) { plugin.showMonth(this); }\r\n\t\t\t},\r\n\t\t\tclear: {text: 'clearText', status: 'clearStatus', // Clear the datepicker\r\n\t\t\t\tkeystroke: {keyCode: 35, ctrlKey: true}, // Ctrl + End\r\n\t\t\t\tenabled: function(inst) { return true; },\r\n\t\t\t\tdate: function(inst) { return null; },\r\n\t\t\t\taction: function(inst) { plugin.clear(this); }\r\n\t\t\t},\r\n\t\t\tclose: {text: 'closeText', status: 'closeStatus', // Close the datepicker\r\n\t\t\t\tkeystroke: {keyCode: 27}, // Escape\r\n\t\t\t\tenabled: function(inst) { return true; },\r\n\t\t\t\tdate: function(inst) { return null; },\r\n\t\t\t\taction: function(inst) { plugin.hide(this); }\r\n\t\t\t},\r\n\t\t\tprevWeek: {text: 'prevWeekText', status: 'prevWeekStatus', // Previous week\r\n\t\t\t\tkeystroke: {keyCode: 38, ctrlKey: true}, // Ctrl + Up\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar minDate = inst.curMinDate();\r\n\t\t\t\t\treturn (!minDate || plugin.add(plugin.newDate(inst.drawDate), -7, 'd').\r\n\t\t\t\t\t\tgetTime() >= minDate.getTime()); },\r\n\t\t\t\tdate: function(inst) { return plugin.add(plugin.newDate(inst.drawDate), -7, 'd'); },\r\n\t\t\t\taction: function(inst) { plugin.changeDay(this, -7); }\r\n\t\t\t},\r\n\t\t\tprevDay: {text: 'prevDayText', status: 'prevDayStatus', // Previous day\r\n\t\t\t\tkeystroke: {keyCode: 37, ctrlKey: true}, // Ctrl + Left\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar minDate = inst.curMinDate();\r\n\t\t\t\t\treturn (!minDate || plugin.add(plugin.newDate(inst.drawDate), -1, 'd').\r\n\t\t\t\t\t\tgetTime() >= minDate.getTime()); },\r\n\t\t\t\tdate: function(inst) { return plugin.add(plugin.newDate(inst.drawDate), -1, 'd'); },\r\n\t\t\t\taction: function(inst) { plugin.changeDay(this, -1); }\r\n\t\t\t},\r\n\t\t\tnextDay: {text: 'nextDayText', status: 'nextDayStatus', // Next day\r\n\t\t\t\tkeystroke: {keyCode: 39, ctrlKey: true}, // Ctrl + Right\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\t\t\treturn (!maxDate || plugin.add(plugin.newDate(inst.drawDate), 1, 'd').\r\n\t\t\t\t\t\tgetTime() <= maxDate.getTime()); },\r\n\t\t\t\tdate: function(inst) { return plugin.add(plugin.newDate(inst.drawDate), 1, 'd'); },\r\n\t\t\t\taction: function(inst) { plugin.changeDay(this, 1); }\r\n\t\t\t},\r\n\t\t\tnextWeek: {text: 'nextWeekText', status: 'nextWeekStatus', // Next week\r\n\t\t\t\tkeystroke: {keyCode: 40, ctrlKey: true}, // Ctrl + Down\r\n\t\t\t\tenabled: function(inst) {\r\n\t\t\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\t\t\treturn (!maxDate || plugin.add(plugin.newDate(inst.drawDate), 7, 'd').\r\n\t\t\t\t\t\tgetTime() <= maxDate.getTime()); },\r\n\t\t\t\tdate: function(inst) { return plugin.add(plugin.newDate(inst.drawDate), 7, 'd'); },\r\n\t\t\t\taction: function(inst) { plugin.changeDay(this, 7); }\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Determine whether a command is enabled.\r\n\t\t\t@callback DatepickCommandEnabled\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@return {boolean} true if this command is enabled, false if not.\r\n\t\t\t@example enabled: function(inst) {\r\n\treturn !!inst.curMinDate();\r\n } */\r\n\r\n\t\t/** Calculate the representative date for a command.\r\n\t\t\t@callback DatepickCommandDate\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@return {Date} A date appropriate for this command.\r\n\t\t\t@example date: function(inst) {\r\n\treturn inst.curMinDate();\r\n } */\r\n\r\n\t\t/** Perform the action for a command.\r\n\t\t\t@callback DatepickCommandAction\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@example date: function(inst) {\r\n\t$.datepick.setDate(inst.elem, inst.curMinDate());\r\n } */\r\n\r\n\t\t/** Calculate the week of the year for a date.\r\n\t\t\t@callback DatepickCalculateWeek\r\n\t\t\t@param date {Date} The date to evaluate.\r\n\t\t\t@return {number} The week of the year.\r\n\t\t\t@example calculateWeek: function(date) {\r\n\treturn Math.floor(($.datepick.dayOfYear(date) - 1) / 7) + 1;\r\n } */\r\n\r\n\t\t/** Provide information about an individual date shown in the calendar.\r\n\t\t\t@callback DatepickOnDate\r\n\t\t\t@param date {Date} The date to evaluate.\r\n\t\t\t@return {object} Information about that date, with the properties above.\r\n\t\t\t@property selectable {boolean} true if this date can be selected.\r\n\t\t\t@property dateClass {string} Class(es) to be applied to the date.\r\n\t\t\t@property content {string} The date cell content.\r\n\t\t\t@property tooltip {string} A popup tooltip for the date.\r\n\t\t\t@example onDate: function(date) {\r\n\treturn {selectable: date.getDay() > 0 && date.getDay() < 5,\r\n\t\tdateClass: date.getDay() == 4 ? 'last-day' : ''};\r\n } */\r\n\r\n\t\t/** Update the datepicker display.\r\n\t\t\t@callback DatepickOnShow\r\n\t\t\t@param picker {jQuery} The datepicker div to be shown.\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@example onShow: function(picker, inst) {\r\n\tpicker.append('<button type=\"button\">Hi</button>').\r\n\t\tfind('button:last').click(function() {\r\n\t\t\talert('Hi!');\r\n\t\t});\r\n } */\r\n\r\n\t\t/** React to navigating through the months/years.\r\n\t\t\t@callback DatepickOnChangeMonthYear\r\n\t\t\t@param year {number} The new year.\r\n\t\t\t@param month {number} The new month (1 to 12).\r\n\t\t\t@example onChangeMonthYear: function(year, month) {\r\n\talert('Now in ' + month + '/' + year);\r\n } */\r\n\t\t\t\r\n\t\t/** Datepicker on select callback.\r\n\t\t\tTriggered when a date is selected.\r\n\t\t\t@callback DatepickOnSelect\r\n\t\t\t@param dates {Date[]} The selected date(s).\r\n\t\t\t@example onSelect: function(dates) {\r\n \talert('Selected ' + dates);\r\n } */\r\n\t\t\t\r\n\t\t/** Datepicker on close callback.\r\n\t\t\tTriggered when a popup calendar is closed.\r\n\t\t\t@callback DatepickOnClose\r\n\t\t\t@param dates {Date[]} The selected date(s).\r\n\t\t\t@example onClose: function(dates) {\r\n \talert('Selected ' + dates);\r\n } */\r\n\t\t\t\r\n\t\t/** Default settings for the plugin.\r\n\t\t\t@property [pickerClass=''] {string} CSS class to add to this instance of the datepicker.\r\n\t\t\t@property [showOnFocus=true] {boolean} true for popup on focus, false for not.\r\n\t\t\t@property [showTrigger=null] {string|Element|jQuery} Element to be cloned for a trigger, null for none.\r\n\t\t\t@property [showAnim='show'] {string} Name of jQuery animation for popup, '' for no animation.\r\n\t\t\t@property [showOptions=null] {object} Options for enhanced animations.\r\n\t\t\t@property [showSpeed='normal'] {string} Duration of display/closure.\r\n\t\t\t@property [popupContainer=null] {string|Element|jQuery} The element to which a popup calendar is added, null for body.\r\n\t\t\t@property [alignment='bottom'] {string} Alignment of popup - with nominated corner of input:\r\n\t\t\t\t\t\t'top' or 'bottom' aligns depending on language direction,\r\n\t\t\t\t\t\t'topLeft', 'topRight', 'bottomLeft', 'bottomRight'.\r\n\t\t\t@property [fixedWeeks=false] {boolean} true to always show 6 weeks, false to only show as many as are needed.\r\n\t\t\t@property [firstDay=0] {number} First day of the week, 0 = Sunday, 1 = Monday, etc.\r\n\t\t\t@property [calculateWeek=this.iso8601Week] {DatepickCalculateWeek} Calculate week of the year from a date, null for ISO8601.\r\n\t\t\t@property [monthsToShow=1] {number|number[]} How many months to show, cols or [rows, cols].\r\n\t\t\t@property [monthsOffset=0] {number} How many months to offset the primary month by;\r\n\t\t\t\t\t\tmay be a function that takes the date and returns the offset.\r\n\t\t\t@property [monthsToStep=1] {number} How many months to move when prev/next clicked.\r\n\t\t\t@property [monthsToJump=12] {number} How many months to move when large prev/next clicked.\r\n\t\t\t@property [useMouseWheel=true] {boolean} true to use mousewheel if available, false to never use it.\r\n\t\t\t@property [changeMonth=true] {boolean} true to change month/year via drop-down, false for navigation only.\r\n\t\t\t@property [yearRange='c-10:c+10'] {string} Range of years to show in drop-down: 'any' for direct text entry\r\n\t\t\t\t\t\tor 'start:end', where start/end are '+-nn' for relative to today\r\n\t\t\t\t\t\tor 'c+-nn' for relative to the currently selected date\r\n\t\t\t\t\t\tor 'nnnn' for an absolute year.\r\n\t\t\t@property [shortYearCutoff='+10'] {string} Cutoff for two-digit year in the current century.\r\n\t\t\t@property [showOtherMonths=false] {boolean} true to show dates from other months, false to not show them.\r\n\t\t\t@property [selectOtherMonths=false] {boolean} true to allow selection of dates from other months too.\r\n\t\t\t@property [defaultDate=null] {string|number|Date} Date to show if no other selected.\r\n\t\t\t@property [selectDefaultDate=false] {boolean} true to pre-select the default date if no other is chosen.\r\n\t\t\t@property [minDate=null] {string|number|Date} The minimum selectable date.\r\n\t\t\t@property [maxDate=null] {string|number|Date} The maximum selectable date.\r\n\t\t\t@property [dateFormat='mm/dd/yyyy'] {string} Format for dates.\r\n\t\t\t@property [autoSize=false] {boolean} true to size the input field according to the date format.\r\n\t\t\t@property [rangeSelect=false] {boolean} Allows for selecting a date range on one date picker.\r\n\t\t\t@property [rangeSeparator=' - '] {string} Text between two dates in a range.\r\n\t\t\t@property [multiSelect=0] {number} Maximum number of selectable dates, zero for single select.\r\n\t\t\t@property [multiSeparator=','] {string} Text between multiple dates.\r\n\t\t\t@property [onDate=null] {DatepickOnDate} Callback as a date is added to the datepicker.\r\n\t\t\t@property [onShow=null] {DatepickOnShow} Callback just before a datepicker is shown.\r\n\t\t\t@property [onChangeMonthYear=null] {DatepickOnChangeMonthYear} Callback when a new month/year is selected.\r\n\t\t\t@property [onSelect=null] {DatepickOnSelect} Callback when a date is selected.\r\n\t\t\t@property [onClose=null] {DatepickOnClose} Callback when a datepicker is closed.\r\n\t\t\t@property [altField=null] {string|Element|jQuery} Alternate field to update in synch with the datepicker.\r\n\t\t\t@property [altFormat=null] {string} Date format for alternate field, defaults to dateFormat.\r\n\t\t\t@property [constrainInput=true] {boolean} true to constrain typed input to dateFormat allowed characters.\r\n\t\t\t@property [commandsAsDateFormat=false] {boolean} true to apply\r\n\t\t\t\t\t\tformatDate to the command texts.\r\n\t\t\t@property [commands=this.commands] {object} Command actions that may be added to a layout by name. */\r\n\t\tdefaultOptions: {\r\n\t\t\tpickerClass: '',\r\n\t\t\tshowOnFocus: true,\r\n\t\t\tshowTrigger: null,\r\n\t\t\tshowAnim: 'show',\r\n\t\t\tshowOptions: {},\r\n\t\t\tshowSpeed: 'normal',\r\n\t\t\tpopupContainer: null,\r\n\t\t\talignment: 'bottom',\r\n\t\t\tfixedWeeks: false,\r\n\t\t\tfirstDay: 0,\r\n\t\t\tcalculateWeek: null, // this.iso8601Week,\r\n\t\t\tmonthsToShow: 1,\r\n\t\t\tmonthsOffset: 0,\r\n\t\t\tmonthsToStep: 1,\r\n\t\t\tmonthsToJump: 12,\r\n\t\t\tuseMouseWheel: true,\r\n\t\t\tchangeMonth: true,\r\n\t\t\tyearRange: 'c-10:c+10',\r\n\t\t\tshortYearCutoff: '+10',\r\n\t\t\tshowOtherMonths: false,\r\n\t\t\tselectOtherMonths: false,\r\n\t\t\tdefaultDate: null,\r\n\t\t\tselectDefaultDate: false,\r\n\t\t\tminDate: null,\r\n\t\t\tmaxDate: null,\r\n\t\t\tdateFormat: 'mm/dd/yyyy',\r\n\t\t\tautoSize: false,\r\n\t\t\trangeSelect: false,\r\n\t\t\trangeSeparator: ' - ',\r\n\t\t\tmultiSelect: 0,\r\n\t\t\tmultiSeparator: ',',\r\n\t\t\tonDate: null,\r\n\t\t\tonShow: null,\r\n\t\t\tonChangeMonthYear: null,\r\n\t\t\tonSelect: null,\r\n\t\t\tonClose: null,\r\n\t\t\taltField: null,\r\n\t\t\taltFormat: null,\r\n\t\t\tconstrainInput: true,\r\n\t\t\tcommandsAsDateFormat: false,\r\n\t\t\tcommands: {} // this.commands\r\n\t\t},\r\n\r\n\t\t/** Localisations for the plugin.\r\n\t\t\tEntries are objects indexed by the language code ('' being the default US/English).\r\n\t\t\tEach object has the following attributes.\r\n\t\t\t@property [monthNames=['January','February','March','April','May','June','July','August','September','October','November','December']]\r\n\t\t\t\t\t\tThe long names of the months.\r\n\t\t\t@property [monthNamesShort=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']]\r\n\t\t\t\t\t\tThe short names of the months.\r\n\t\t\t@property [dayNames=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']]\r\n\t\t\t\t\t\tThe long names of the days of the week.\r\n\t\t\t@property [dayNamesShort=['Sun','Mon','Tue','Wed','Thu','Fri','Sat']] The short names of the days of the week.\r\n\t\t\t@property [dayNamesMin=['Su','Mo','Tu','We','Th','Fr','Sa']] The minimal names of the days of the week.\r\n\t\t\t@property [dateFormat='mm/dd/yyyy'] {string} See options on formatDate.\r\n\t\t\t@property [firstDay=0] {number} The first day of the week, Sun = 0, Mon = 1, etc.\r\n\t\t\t@property [renderer=this.defaultRenderer] {string} The rendering templates.\r\n\t\t\t@property [prevText='<Prev'] {string} Text for the previous month command.\r\n\t\t\t@property [prevStatus='Show the previous month'] {string} Status text for the previous month command.\r\n\t\t\t@property [prevJumpText='<<'] {string} Text for the previous year command.\r\n\t\t\t@property [prevJumpStatus='Show the previous year'] {string} Status text for the previous year command.\r\n\t\t\t@property [nextText='Next>'] {string} Text for the next month command.\r\n\t\t\t@property [nextStatus='Show the next month'] {string} Status text for the next month command.\r\n\t\t\t@property [nextJumpText='>>'] {string} Text for the next year command.\r\n\t\t\t@property [nextJumpStatus='Show the next year'] {string} Status text for the next year command.\r\n\t\t\t@property [currentText='Current'] {string} Text for the current month command.\r\n\t\t\t@property [currentStatus='Show the current month'] {string} Status text for the current month command.\r\n\t\t\t@property [todayText='Today'] {string} Text for the today's month command.\r\n\t\t\t@property [todayStatus='Show today\\'s month'] {string} Status text for the today's month command.\r\n\t\t\t@property [clearText='Clear'] {string} Text for the clear command.\r\n\t\t\t@property [clearStatus='Clear all the dates'] {string} Status text for the clear command.\r\n\t\t\t@property [closeText='Close'] {string} Text for the close command.\r\n\t\t\t@property [closeStatus='Close the datepicker'] {string} Status text for the close command.\r\n\t\t\t@property [yearStatus='Change the year'] {string} Status text for year selection.\r\n\t\t\t@property [earlierText='  â–²'] {string} Text for earlier years.\r\n\t\t\t@property [laterText='  â–¼'] {string} Text for later years.\r\n\t\t\t@property [monthStatus='Change the month'] {string} Status text for month selection.\r\n\t\t\t@property [weekText='Wk'] {string} Text for week of the year column header.\r\n\t\t\t@property [weekStatus='Week of the year'] {string} Status text for week of the year column header.\r\n\t\t\t@property [dayStatus='Select DD, M d, yyyy'] {string} Status text for selectable days.\r\n\t\t\t@property [defaultStatus='Select a date'] {string} Status text shown by default.\r\n\t\t\t@property [isRTL=false] {boolean} true if language is right-to-left. */\r\n\t\tregionalOptions: { // Available regional settings, indexed by language/country code\r\n\t\t\t'': { // Default regional settings - English/US\r\n\t\t\t monthNames: cmsMonthNames,\r\n\t\t\t monthNamesShort: cmsMonthNamesShort,\r\n\t\t\t dayNames: cmsDayNames,\r\n\t\t\t dayNamesShort: cmsDayNamesShort,\r\n\t\t\t dayNamesMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],\r\n\t\t\t\tdateFormat: 'mm/dd/yyyy',\r\n\t\t\t\tfirstDay: 0,\r\n\t\t\t\trenderer: {}, // this.defaultRenderer\r\n\t\t\t\tprevText: '<Prev',\r\n\t\t\t\tprevStatus: 'Show the previous month',\r\n\t\t\t\tprevJumpText: '<<',\r\n\t\t\t\tprevJumpStatus: 'Show the previous year',\r\n\t\t\t\tnextText: 'Next>',\r\n\t\t\t\tnextStatus: 'Show the next month',\r\n\t\t\t\tnextJumpText: '>>',\r\n\t\t\t\tnextJumpStatus: 'Show the next year',\r\n\t\t\t\tcurrentText: 'Current',\r\n\t\t\t\tcurrentStatus: 'Show the current month',\r\n\t\t\t\ttodayText: 'Today',\r\n\t\t\t\ttodayStatus: 'Show today\\'s month',\r\n\t\t\t\tclearText: 'Clear',\r\n\t\t\t\tclearStatus: 'Clear all the dates',\r\n\t\t\t\tcloseText: 'Close',\r\n\t\t\t\tcloseStatus: 'Close the datepicker',\r\n\t\t\t\tyearStatus: 'Change the year',\r\n\t\t\t\tearlierText: '  â–²',\r\n\t\t\t\tlaterText: '  â–¼',\r\n\t\t\t\tmonthStatus: 'Change the month',\r\n\t\t\t\tweekText: 'Wk',\r\n\t\t\t\tweekStatus: 'Week of the year',\r\n\t\t\t\tdayStatus: 'Select DD, M d, yyyy',\r\n\t\t\t\tdefaultStatus: 'Select a date',\r\n\t\t\t\tisRTL: false\r\n\t\t\t}\r\n\t\t},\r\n\t\t\r\n\t\t/** Names of getter methods - those that can't be chained. */\r\n\t\t_getters: ['getDate', 'isDisabled', 'isSelectable', 'retrieveDate'],\r\n\r\n\t\t_disabled: [],\r\n\t\t\r\n\t\t_popupClass: pluginName + '-popup', // Marker for popup division\r\n\t\t_triggerClass: pluginName + '-trigger', // Marker for trigger element\r\n\t\t_disableClass: pluginName + '-disable', // Marker for disabled element\r\n\t\t_monthYearClass: pluginName + '-month-year', // Marker for month/year inputs\r\n\t\t_curMonthClass: pluginName + '-month-', // Marker for current month/year\r\n\t\t_anyYearClass: pluginName + '-any-year', // Marker for year direct input\r\n\t\t_curDoWClass: pluginName + '-dow-', // Marker for day of week\r\n\r\n\t\t_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +\r\n\t\t\tMath.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),\r\n\t\t_msPerDay: 24 * 60 * 60 * 1000,\r\n\r\n\t\t/** The date format for use with Atom (RFC 3339/ISO 8601). */\r\n\t\tATOM: 'yyyy-mm-dd',\r\n\t\t/** The date format for use with cookies. */\r\n\t\tCOOKIE: 'D, dd M yyyy',\r\n\t\t/** The date format for full display. */\r\n\t\tFULL: 'DD, MM d, yyyy',\r\n\t\t/** The date format for use with ISO 8601. */\r\n\t\tISO_8601: 'yyyy-mm-dd',\r\n\t\t/** The date format for Julian dates. */\r\n\t\tJULIAN: 'J',\r\n\t\t/** The date format for use with RFC 822. */\r\n\t\tRFC_822: 'D, d M yy',\r\n\t\t/** The date format for use with RFC 850. */\r\n\t\tRFC_850: 'DD, dd-M-yy',\r\n\t\t/** The date format for use with RFC 1036. */\r\n\t\tRFC_1036: 'D, d M yy',\r\n\t\t/** The date format for use with RFC 1123. */\r\n\t\tRFC_1123: 'D, d M yyyy',\r\n\t\t/** The date format for use with RFC 2822. */\r\n\t\tRFC_2822: 'D, d M yyyy',\r\n\t\t/** The date format for use with RSS (RFC 822). */\r\n\t\tRSS: 'D, d M yy',\r\n\t\t/** The date format for Windows ticks. */\r\n\t\tTICKS: '!',\r\n\t\t/** The date format for Unix timestamp. */\r\n\t\tTIMESTAMP: '@',\r\n\t\t/** The date format for use with W3C (ISO 8601). */\r\n\t\tW3C: 'yyyy-mm-dd',\r\n\r\n\t\t/** Format a date object into a string value.\r\n\t\t\tThe format can be combinations of the following:\r\n\t\t\t\r\n\t\t\t@param [format=dateFormat] {string} The desired format of the date.\r\n\t\t\t@param date {Date} The date value to format.\r\n\t\t\t@param [settings] {object} With the properties shown below.\r\n\t\t\t@property [dayNamesShort] {string[]} Abbreviated names of the days from Sunday.\r\n\t\t\t@property [dayNames] {string[]} Names of the days from Sunday.\r\n\t\t\t@property [monthNamesShort] {string[]} Abbreviated names of the months.\r\n\t\t\t@property [monthNames] {string[]} Names of the months.\r\n\t\t\t@property [calculateWeek] {DatepickCalculateWeek} Function that determines week of the year.\r\n\t\t\t@return {string} The date in the above format.\r\n\t\t\t@example var display = $.datepick.formatDate('yyyy-mm-dd', new Date(2014, 12-1, 25)) */\r\n\t\tformatDate: function(format, date, settings) {\r\n\t\t\tif (typeof format !== 'string') {\r\n\t\t\t\tsettings = date;\r\n\t\t\t\tdate = format;\r\n\t\t\t\tformat = '';\r\n\t\t\t}\r\n\t\t\tif (!date) {\r\n\t\t\t\treturn '';\r\n\t\t\t}\r\n\t\t\tformat = format || this.defaultOptions.dateFormat;\r\n\t\t\tsettings = settings || {};\r\n\t\t\tvar dayNamesShort = settings.dayNamesShort || this.defaultOptions.dayNamesShort;\r\n\t\t\tvar dayNames = settings.dayNames || this.defaultOptions.dayNames;\r\n\t\t\tvar monthNamesShort = settings.monthNamesShort || this.defaultOptions.monthNamesShort;\r\n\t\t\tvar monthNames = settings.monthNames || this.defaultOptions.monthNames;\r\n\t\t\tvar calculateWeek = settings.calculateWeek || this.defaultOptions.calculateWeek;\r\n\t\t\t// Check whether a format character is doubled\r\n\t\t\tvar doubled = function(match, step) {\r\n\t\t\t\tvar matches = 1;\r\n\t\t\t\twhile (iFormat + matches < format.length && format.charAt(iFormat + matches) === match) {\r\n\t\t\t\t\tmatches++;\r\n\t\t\t\t}\r\n\t\t\t\tiFormat += matches - 1;\r\n\t\t\t\treturn Math.floor(matches / (step || 1)) > 1;\r\n\t\t\t};\r\n\t\t\t// Format a number, with leading zeroes if necessary\r\n\t\t\tvar formatNumber = function(match, value, len, step) {\r\n\t\t\t\tvar num = '' + value;\r\n\t\t\t\tif (doubled(match, step)) {\r\n\t\t\t\t\twhile (num.length < len) {\r\n\t\t\t\t\t\tnum = '0' + num;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn num;\r\n\t\t\t};\r\n\t\t\t// Format a name, short or long as requested\r\n\t\t\tvar formatName = function(match, value, shortNames, longNames) {\r\n\t\t\t\treturn (doubled(match) ? longNames[value] : shortNames[value]);\r\n\t\t\t};\r\n\t\t\tvar output = '';\r\n\t\t\tvar literal = false;\r\n\t\t\tfor (var iFormat = 0; iFormat < format.length; iFormat++) {\r\n\t\t\t\tif (literal) {\r\n\t\t\t\t\tif (format.charAt(iFormat) === \"'\" && !doubled(\"'\")) {\r\n\t\t\t\t\t\tliteral = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\toutput += format.charAt(iFormat);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tswitch (format.charAt(iFormat)) {\r\n\t\t\t\t\t\tcase 'd': output += formatNumber('d', date.getDate(), 2); break;\r\n\t\t\t\t\t\tcase 'D': output += formatName('D', date.getDay(),\r\n\t\t\t\t\t\t\tdayNamesShort, dayNames); break;\r\n\t\t\t\t\t\tcase 'o': output += formatNumber('o', this.dayOfYear(date), 3); break;\r\n\t\t\t\t\t\tcase 'w': output += formatNumber('w', calculateWeek(date), 2); break;\r\n\t\t\t\t\t\tcase 'm': output += formatNumber('m', date.getMonth() + 1, 2); break;\r\n\t\t\t\t\t\tcase 'M': output += formatName('M', date.getMonth(),\r\n\t\t\t\t\t\t\tmonthNamesShort, monthNames); break;\r\n\t\t\t\t\t\tcase 'y':\r\n\t\t\t\t\t\t\toutput += (doubled('y', 2) ? date.getFullYear() :\r\n\t\t\t\t\t\t\t\t(date.getFullYear() % 100 < 10 ? '0' : '') + date.getFullYear() % 100);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase '@': output += Math.floor(date.getTime() / 1000); break;\r\n\t\t\t\t\t\tcase '!': output += date.getTime() * 10000 + this._ticksTo1970; break;\r\n\t\t\t\t\t\tcase \"'\":\r\n\t\t\t\t\t\t\tif (doubled(\"'\")) {\r\n\t\t\t\t\t\t\t\toutput += \"'\";\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t\tliteral = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\toutput += format.charAt(iFormat);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn output;\r\n\t\t},\r\n\r\n\t\t/** Parse a string value into a date object.\r\n\t\t\tSee formatDate for the possible formats, plus:\r\n\t\t\t\r\n\t\t\t@param format {string} The expected format of the date ('' for default datepicker format).\r\n\t\t\t@param value {string} The date in the above format.\r\n\t\t\t@param [settings] {object} With the properties shown above.\r\n\t\t\t@property [shortYearCutoff] {number} the cutoff year for determining the century.\r\n\t\t\t@property [dayNamesShort] {string[]} abbreviated names of the days from Sunday.\r\n\t\t\t@property [dayNames] {string[]} names of the days from Sunday.\r\n\t\t\t@property [monthNamesShort] {string[]} abbreviated names of the months.\r\n\t\t\t@property [monthNames] {string[]} names of the months.\r\n\t\t\t@return {Date} The extracted date value or null if value is blank.\r\n\t\t\t@throws Errors if the format and/or value are missing, if the value doesn't match the format,\r\n\t\t\t\t\tor if the date is invalid.\r\n\t\t\t@example var date = $.datepick.parseDate('dd/mm/yyyy', '25/12/2014') */\r\n\t\tparseDate: function(format, value, settings) {\r\n\t\t\tif (value == null) {\r\n\t\t\t\tthrow 'Invalid arguments';\r\n\t\t\t}\r\n\t\t\tvalue = (typeof value === 'object' ? value.toString() : value + '');\r\n\t\t\tif (value === '') {\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\t\t\tformat = format || this.defaultOptions.dateFormat;\r\n\t\t\tsettings = settings || {};\r\n\t\t\tvar shortYearCutoff = settings.shortYearCutoff || this.defaultOptions.shortYearCutoff;\r\n\t\t\tshortYearCutoff = (typeof shortYearCutoff !== 'string' ? shortYearCutoff :\r\n\t\t\t\tthis.today().getFullYear() % 100 + parseInt(shortYearCutoff, 10));\r\n\t\t\tvar dayNamesShort = settings.dayNamesShort || this.defaultOptions.dayNamesShort;\r\n\t\t\tvar dayNames = settings.dayNames || this.defaultOptions.dayNames;\r\n\t\t\tvar monthNamesShort = settings.monthNamesShort || this.defaultOptions.monthNamesShort;\r\n\t\t\tvar monthNames = settings.monthNames || this.defaultOptions.monthNames;\r\n\t\t\tvar year = -1;\r\n\t\t\tvar month = -1;\r\n\t\t\tvar day = -1;\r\n\t\t\tvar doy = -1;\r\n\t\t\tvar shortYear = false;\r\n\t\t\tvar literal = false;\r\n\t\t\t// Check whether a format character is doubled\r\n\t\t\tvar doubled = function(match, step) {\r\n\t\t\t\tvar matches = 1;\r\n\t\t\t\twhile (iFormat + matches < format.length && format.charAt(iFormat + matches) === match) {\r\n\t\t\t\t\tmatches++;\r\n\t\t\t\t}\r\n\t\t\t\tiFormat += matches - 1;\r\n\t\t\t\treturn Math.floor(matches / (step || 1)) > 1;\r\n\t\t\t};\r\n\t\t\t// Extract a number from the string value\r\n\t\t\tvar getNumber = function(match, step) {\r\n\t\t\t\tvar isDoubled = doubled(match, step);\r\n\t\t\t\tvar size = [2, 3, isDoubled ? 4 : 2, 11, 20]['oy@!'.indexOf(match) + 1];\r\n\t\t\t\tvar digits = new RegExp('^-?\\\\d{1,' + size + '}');\r\n\t\t\t\tvar num = value.substring(iValue).match(digits);\r\n\t\t\t\tif (!num) {\r\n\t\t\t\t\tthrow 'Missing number at position {0}'.replace(/\\{0\\}/, iValue);\r\n\t\t\t\t}\r\n\t\t\t\tiValue += num[0].length;\r\n\t\t\t\treturn parseInt(num[0], 10);\r\n\t\t\t};\r\n\t\t\t// Extract a name from the string value and convert to an index\r\n\t\t\tvar getName = function(match, shortNames, longNames, step) {\r\n\t\t\t\tvar names = (doubled(match, step) ? longNames : shortNames);\r\n\t\t\t\tfor (var i = 0; i < names.length; i++) {\r\n\t\t\t\t\tif (value.substr(iValue, names[i].length).toLowerCase() === names[i].toLowerCase()) {\r\n\t\t\t\t\t\tiValue += names[i].length;\r\n\t\t\t\t\t\treturn i + 1;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tthrow 'Unknown name at position {0}'.replace(/\\{0\\}/, iValue);\r\n\t\t\t};\r\n\t\t\t// Confirm that a literal character matches the string value\r\n\t\t\tvar checkLiteral = function() {\r\n\t\t\t\tif (value.charAt(iValue) !== format.charAt(iFormat)) {\r\n\t\t\t\t\tthrow 'Unexpected literal at position {0}'.replace(/\\{0\\}/, iValue);\r\n\t\t\t\t}\r\n\t\t\t\tiValue++;\r\n\t\t\t};\r\n\t\t\tvar iValue = 0;\r\n\t\t\tfor (var iFormat = 0; iFormat < format.length; iFormat++) {\r\n\t\t\t\tif (literal) {\r\n\t\t\t\t\tif (format.charAt(iFormat) === \"'\" && !doubled(\"'\")) {\r\n\t\t\t\t\t\tliteral = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tcheckLiteral();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tswitch (format.charAt(iFormat)) {\r\n\t\t\t\t\t\tcase 'd': day = getNumber('d'); break;\r\n\t\t\t\t\t\tcase 'D': getName('D', dayNamesShort, dayNames); break;\r\n\t\t\t\t\t\tcase 'o': doy = getNumber('o'); break;\r\n\t\t\t\t\t\tcase 'w': getNumber('w'); break;\r\n\t\t\t\t\t\tcase 'm': month = getNumber('m'); break;\r\n\t\t\t\t\t\tcase 'M': month = getName('M', monthNamesShort, monthNames); break;\r\n\t\t\t\t\t\tcase 'y':\r\n\t\t\t\t\t\t\tvar iSave = iFormat;\r\n\t\t\t\t\t\t\tshortYear = !doubled('y', 2);\r\n\t\t\t\t\t\t\tiFormat = iSave;\r\n\t\t\t\t\t\t\tyear = getNumber('y', 2);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase '@':\r\n\t\t\t\t\t\t\tvar date = this._normaliseDate(new Date(getNumber('@') * 1000));\r\n\t\t\t\t\t\t\tyear = date.getFullYear();\r\n\t\t\t\t\t\t\tmonth = date.getMonth() + 1;\r\n\t\t\t\t\t\t\tday = date.getDate();\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase '!':\r\n\t\t\t\t\t\t\tvar date = this._normaliseDate(\r\n\t\t\t\t\t\t\t\tnew Date((getNumber('!') - this._ticksTo1970) / 10000));\r\n\t\t\t\t\t\t\tyear = date.getFullYear();\r\n\t\t\t\t\t\t\tmonth = date.getMonth() + 1;\r\n\t\t\t\t\t\t\tday = date.getDate();\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase '*': iValue = value.length; break;\r\n\t\t\t\t\t\tcase \"'\":\r\n\t\t\t\t\t\t\tif (doubled(\"'\")) {\r\n\t\t\t\t\t\t\t\tcheckLiteral();\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t\tliteral = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tdefault: checkLiteral();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (iValue < value.length) {\r\n\t\t\t\tthrow 'Additional text found at end';\r\n\t\t\t}\r\n\t\t\tif (year === -1) {\r\n\t\t\t\tyear = this.today().getFullYear();\r\n\t\t\t}\r\n\t\t\telse if (year < 100 && shortYear) {\r\n\t\t\t\tyear += (shortYearCutoff === -1 ? 1900 : this.today().getFullYear() -\r\n\t\t\t\t\tthis.today().getFullYear() % 100 - (year <= shortYearCutoff ? 0 : 100));\r\n\t\t\t}\r\n\t\t\tif (doy > -1) {\r\n\t\t\t\tmonth = 1;\r\n\t\t\t\tday = doy;\r\n\t\t\t\tfor (var dim = this.daysInMonth(year, month); day > dim;\r\n\t\t\t\t\t\tdim = this.daysInMonth(year, month)) {\r\n\t\t\t\t\tmonth++;\r\n\t\t\t\t\tday -= dim;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tvar date = this.newDate(year, month, day);\r\n\t\t\tif (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {\r\n\t\t\t\tthrow 'Invalid date';\r\n\t\t\t}\r\n\t\t\treturn date;\r\n\t\t},\r\n\r\n\t\t/** A date may be specified as an exact value or a relative one.\r\n\t\t\t@param dateSpec {Date|number|string} The date as an object or string\r\n\t\t\t\t\tin the given format or an offset - numeric days from today,\r\n\t\t\t\t\tor string amounts and periods, e.g. '+1m +2w'.\r\n\t\t\t@param defaultDate {Date} The date to use if no other supplied, may be null.\r\n\t\t\t@param [currentDate] {Date} The current date as a possible basis for relative dates,\r\n\t\t\t\t\tif null today is used.\r\n\t\t\t@param dateFormat {string} The expected date format - see formatDate.\r\n\t\t\t@param settings {object} With the properties shown above.\r\n\t\t\t@property [shortYearCutoff] {number} The cutoff year for determining the century.\r\n\t\t\t@property [dayNamesShort] {string[]} Abbreviated names of the days from Sunday.\r\n\t\t\t@property [dayNames] {string[]} Names of the days from Sunday.\r\n\t\t\t@property [monthNamesShort] {string[]} Abbreviated names of the months.\r\n\t\t\t@property [monthNames] {string[]} Names of the months.\r\n\t\t\t@return {Date} The decoded date.\r\n\t\t\t@example $.datepick.determineDate('+1m +2w', new Date()) */\r\n\t\tdetermineDate: function(dateSpec, defaultDate, currentDate, dateFormat, settings) {\r\n\t\t\tif (currentDate && typeof currentDate !== 'object') {\r\n\t\t\t\tsettings = dateFormat;\r\n\t\t\t\tdateFormat = currentDate;\r\n\t\t\t\tcurrentDate = null;\r\n\t\t\t}\r\n\t\t\tif (typeof dateFormat !== 'string') {\r\n\t\t\t\tsettings = dateFormat;\r\n\t\t\t\tdateFormat = '';\r\n\t\t\t}\r\n\t\t\tvar offsetString = function(offset) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\treturn plugin.parseDate(dateFormat, offset, settings);\r\n\t\t\t\t}\r\n\t\t\t\tcatch (e) {\r\n\t\t\t\t\t// Ignore\r\n\t\t\t\t}\r\n\t\t\t\toffset = offset.toLowerCase();\r\n\t\t\t\tvar date = (offset.match(/^c/) && currentDate ? plugin.newDate(currentDate) : null) ||\r\n\t\t\t\t\tplugin.today();\r\n\t\t\t\tvar pattern = /([+-]?[0-9]+)\\s*(d|w|m|y)?/g;\r\n\t\t\t\tvar matches = null;\r\n\t\t\t\twhile (matches = pattern.exec(offset)) {\r\n\t\t\t\t\tdate = plugin.add(date, parseInt(matches[1], 10), matches[2] || 'd');\r\n\t\t\t\t}\r\n\t\t\t\treturn date;\r\n\t\t\t};\r\n\t\t\tdefaultDate = (defaultDate ? plugin.newDate(defaultDate) : null);\r\n\t\t\tdateSpec = (dateSpec == null ? defaultDate :\r\n\t\t\t\t(typeof dateSpec === 'string' ? offsetString(dateSpec) : (typeof dateSpec === 'number' ?\r\n\t\t\t\t(isNaN(dateSpec) || dateSpec === Infinity || dateSpec === -Infinity ? defaultDate :\r\n\t\t\t\tplugin.add(plugin.today(), dateSpec, 'd')) : plugin.newDate(dateSpec))));\r\n\t\t\treturn dateSpec;\r\n\t\t},\r\n\r\n\t\t/** Find the number of days in a given month.\r\n\t\t\t@param year {Date|number} The date to get days for or the full year.\r\n\t\t\t@param month {number} The month (1 to 12).\r\n\t\t\t@return {number} The number of days in this month.\r\n\t\t\t@example var days = $.datepick.daysInMonth(2014, 12) */\r\n\t\tdaysInMonth: function(year, month) {\r\n\t\t\tmonth = (year.getFullYear ? year.getMonth() + 1 : month);\r\n\t\t\tyear = (year.getFullYear ? year.getFullYear() : year);\r\n\t\t\treturn this.newDate(year, month + 1, 0).getDate();\r\n\t\t},\r\n\r\n\t\t/** Calculate the day of the year for a date.\r\n\t\t\t@param year {Date|number} The date to get the day-of-year for or the full year.\r\n\t\t\t@param month {number} The month (1-12).\r\n\t\t\t@param day {number} The day.\r\n\t\t\t@return {number} The day of the year.\r\n\t\t\t@example var doy = $.datepick.dayOfYear(2014, 12, 25) */\r\n\t\tdayOfYear: function(year, month, day) {\r\n\t\t\tvar date = (year.getFullYear ? year : plugin.newDate(year, month, day));\r\n\t\t\tvar newYear = plugin.newDate(date.getFullYear(), 1, 1);\r\n\t\t\treturn Math.floor((date.getTime() - newYear.getTime()) / plugin._msPerDay) + 1;\r\n\t\t},\r\n\r\n\t\t/** Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.\r\n\t\t\t@param year {Date|number} The date to get the week for or the full year.\r\n\t\t\t@param month {number} The month (1-12).\r\n\t\t\t@param day {number} The day.\r\n\t\t\t@return {number} The number of the week within the year that contains this date.\r\n\t\t\t@example var week = $.datepick.iso8601Week(2014, 12, 25) */\r\n\t\tiso8601Week: function(year, month, day) {\r\n\t\t\tvar checkDate = (year.getFullYear ?\r\n\t\t\t\tnew Date(year.getTime()) : plugin.newDate(year, month, day));\r\n\t\t\t// Find Thursday of this week starting on Monday\r\n\t\t\tcheckDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));\r\n\t\t\tvar time = checkDate.getTime();\r\n\t\t\tcheckDate.setMonth(0, 1); // Compare with Jan 1\r\n\t\t\treturn Math.floor(Math.round((time - checkDate) / plugin._msPerDay) / 7) + 1;\r\n\t\t},\r\n\r\n\t\t/** Return today's date.\r\n\t\t\t@return {Date} Today.\r\n\t\t\t@example $.datepick.today() */\r\n\t\ttoday: function() {\r\n\t\t\treturn this._normaliseDate(new Date());\r\n\t\t},\r\n\r\n\t\t/** Return a new date.\r\n\t\t\t@param year {Date|number} The date to clone or the year.\r\n\t\t\t@param month {number} The month (1-12).\r\n\t\t\t@param day {number} The day.\r\n\t\t\t@return {Date} The date.\r\n\t\t\t@example $.datepick.newDate(oldDate)\r\n $.datepick.newDate(2014, 12, 25) */\r\n\t\tnewDate: function(year, month, day) {\r\n\t\t\treturn (!year ? null : (year.getFullYear ? this._normaliseDate(new Date(year.getTime())) :\r\n\t\t\t\tnew Date(year, month - 1, day, 12)));\r\n\t\t},\r\n\r\n\t\t/** Standardise a date into a common format - time portion is 12 noon.\r\n\t\t\t@private\r\n\t\t\t@param date {Date} The date to standardise.\r\n\t\t\t@return {Date} The normalised date. */\r\n\t\t_normaliseDate: function(date) {\r\n\t\t\tif (date) {\r\n\t\t\t\tdate.setHours(12, 0, 0, 0);\r\n\t\t\t}\r\n\t\t\treturn date;\r\n\t\t},\r\n\r\n\t\t/** Set the year for a date.\r\n\t\t\t@param date {Date} The original date.\r\n\t\t\t@param year {number} The new year.\r\n\t\t\t@return {Date} The updated date.\r\n\t\t\t@example $.datepick.year(date, 2014) */\r\n\t\tyear: function(date, year) {\r\n\t\t\tdate.setFullYear(year);\r\n\t\t\treturn this._normaliseDate(date);\r\n\t\t},\r\n\r\n\t\t/** Set the month for a date.\r\n\t\t\t@param date {Date} The original date.\r\n\t\t\t@param month {number} The new month (1-12).\r\n\t\t\t@return {Date} The updated date.\r\n\t\t\t@example $.datepick.month(date, 12) */\r\n\t\tmonth: function(date, month) {\r\n\t\t\tdate.setMonth(month - 1);\r\n\t\t\treturn this._normaliseDate(date);\r\n\t\t},\r\n\r\n\t\t/** Set the day for a date.\r\n\t\t\t@param date {Date} The original date.\r\n\t\t\t@param day {number} The new day of the month.\r\n\t\t\t@return {Date} The updated date.\r\n\t\t\t@example $.datepick.day(date, 25) */\r\n\t\tday: function(date, day) {\r\n\t\t\tdate.setDate(day);\r\n\t\t\treturn this._normaliseDate(date);\r\n\t\t},\r\n\r\n\t\t/** Add a number of periods to a date.\r\n\t\t\t@param date {Date} The original date.\r\n\t\t\t@param amount {number} The number of periods.\r\n\t\t\t@param period {string} The type of period d/w/m/y.\r\n\t\t\t@return {Date} The updated date.\r\n\t\t\t@example $.datepick.add(date, 10, 'd') */\r\n\t\tadd: function(date, amount, period) {\r\n\t\t\tif (period === 'd' || period === 'w') {\r\n\t\t\t\tthis._normaliseDate(date);\r\n\t\t\t\tdate.setDate(date.getDate() + amount * (period === 'w' ? 7 : 1));\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tvar year = date.getFullYear() + (period === 'y' ? amount : 0);\r\n\t\t\t\tvar month = date.getMonth() + (period === 'm' ? amount : 0);\r\n\t\t\t\tdate.setTime(plugin.newDate(year, month + 1,\r\n\t\t\t\t\tMath.min(date.getDate(), this.daysInMonth(year, month + 1))).getTime());\r\n\t\t\t}\r\n\t\t\treturn date;\r\n\t\t},\r\n\r\n\t\t/** Apply the months offset value to a date.\r\n\t\t\t@private\r\n\t\t\t@param date {Date} The original date.\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@return {Date} The updated date. */\r\n\t\t_applyMonthsOffset: function(date, inst) {\r\n\t\t\tvar monthsOffset = inst.options.monthsOffset;\r\n\t\t\tif ($.isFunction(monthsOffset)) {\r\n\t\t\t\tmonthsOffset = monthsOffset.apply(inst.elem[0], [date]);\r\n\t\t\t}\r\n\t\t\treturn plugin.add(date, -monthsOffset, 'm');\r\n\t\t},\r\n\r\n\t\t_init: function() {\r\n\t\t\tthis.defaultOptions.commands = this.commands;\r\n\t\t\tthis.defaultOptions.calculateWeek = this.iso8601Week;\r\n\t\t\tthis.regionalOptions[''].renderer = this.defaultRenderer;\r\n\t\t\tthis._super();\r\n\t\t},\r\n\r\n\t\t_instSettings: function(elem, options) {\r\n\t\t\treturn {selectedDates: [], drawDate: null, pickingRange: false,\r\n\t\t\t\tinline: ($.inArray(elem[0].nodeName.toLowerCase(), ['div', 'span']) > -1),\r\n\t\t\t\tget: function(name) { // Get a setting value, computing if necessary\r\n\t\t\t\t\tif ($.inArray(name, ['defaultDate', 'minDate', 'maxDate']) > -1) { // Decode date settings\r\n\t\t\t\t\t\treturn plugin.determineDate(this.options[name], null,\r\n\t\t\t\t\t\t\tthis.selectedDates[0], this.options.dateFormat, this.getConfig());\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn this.options[name];\r\n\t\t\t\t},\r\n\t\t\t\tcurMinDate: function() {\r\n\t\t\t\t\treturn (this.pickingRange ? this.selectedDates[0] : this.get('minDate'));\r\n\t\t\t\t},\r\n\t\t\t\tgetConfig: function() {\r\n\t\t\t\t\treturn {dayNamesShort: this.options.dayNamesShort, dayNames: this.options.dayNames,\r\n\t\t\t\t\t\tmonthNamesShort: this.options.monthNamesShort, monthNames: this.options.monthNames,\r\n\t\t\t\t\t\tcalculateWeek: this.options.calculateWeek,\r\n\t\t\t\t\t\tshortYearCutoff: this.options.shortYearCutoff};\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t},\r\n\r\n\t\t_postAttach: function(elem, inst) {\r\n\t\t\tif (inst.inline) {\r\n\t\t\t\tinst.drawDate = plugin._checkMinMax(plugin.newDate(inst.selectedDates[0] ||\r\n\t\t\t\t\tinst.get('defaultDate') || plugin.today()), inst);\r\n\t\t\t\tinst.prevDate = plugin.newDate(inst.drawDate);\r\n\t\t\t\tthis._update(elem[0]);\r\n\t\t\t\tif ($.fn.mousewheel) {\r\n\t\t\t\t\telem.mousewheel(this._doMouseWheel);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tthis._attachments(elem, inst);\r\n\t\t\t\telem.on('keydown.' + inst.name, this._keyDown).on('keypress.' + inst.name, this._keyPress).\r\n\t\t\t\t\ton('keyup.' + inst.name, this._keyUp);\r\n\t\t\t\tif (elem.attr('disabled')) {\r\n\t\t\t\t\tthis.disable(elem[0]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t_optionsChanged: function(elem, inst, options) {\r\n\t\t\tif (options.calendar && options.calendar !== inst.options.calendar) {\r\n\t\t\t\tvar discardDate = function(name) {\r\n\t\t\t\t\treturn (typeof inst.options[name] === 'object' ? null : inst.options[name]);\r\n\t\t\t\t};\r\n\t\t\t\toptions = $.extend({defaultDate: discardDate('defaultDate'),\r\n\t\t\t\t\tminDate: discardDate('minDate'), maxDate: discardDate('maxDate')}, options);\r\n\t\t\t\tinst.selectedDates = [];\r\n\t\t\t\tinst.drawDate = null;\r\n\t\t\t}\r\n\t\t\tvar dates = inst.selectedDates;\r\n\t\t\t$.extend(inst.options, options);\r\n\t\t\tthis.setDate(elem[0], dates, null, false, true);\r\n\t\t\tinst.pickingRange = false;\r\n\t\t\tinst.drawDate = plugin.newDate(this._checkMinMax(\r\n\t\t\t\t(inst.options.defaultDate ? inst.get('defaultDate') : inst.drawDate) ||\r\n\t\t\t\tinst.get('defaultDate') || plugin.today(), inst));\r\n\t\t\tif (!inst.inline) {\r\n\t\t\t\tthis._attachments(elem, inst);\r\n\t\t\t}\r\n\t\t\tif (inst.inline || inst.div) {\r\n\t\t\t\tthis._update(elem[0]);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Attach events and trigger, if necessary.\r\n\t\t\t@private\r\n\t\t\t@param elem {jQuery} The control to affect.\r\n\t\t\t@param inst {object} The current instance settings. */\r\n\t\t_attachments: function(elem, inst) {\r\n\t\t\telem.off('focus.' + inst.name);\r\n\t\t\tif (inst.options.showOnFocus) {\r\n\t\t\t\telem.on('focus.' + inst.name, this.show);\r\n\t\t\t}\r\n\t\t\tif (inst.trigger) {\r\n\t\t\t\tinst.trigger.remove();\r\n\t\t\t}\r\n\t\t\tvar trigger = inst.options.showTrigger;\r\n\t\t\tinst.trigger = (!trigger ? $([]) :\r\n\t\t\t\t$(trigger).clone().removeAttr('id').addClass(this._triggerClass)\r\n\t\t\t\t\t[inst.options.isRTL ? 'insertBefore' : 'insertAfter'](elem).\r\n\t\t\t\t\tclick(function() {\r\n\t\t\t\t\t\tif (!plugin.isDisabled(elem[0])) {\r\n\t\t\t\t\t\t\tplugin[plugin.curInst === inst ? 'hide' : 'show'](elem[0]);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}));\r\n\t\t\tthis._autoSize(elem, inst);\r\n\t\t\tvar dates = this._extractDates(inst, elem.val());\r\n\t\t\tif (dates) {\r\n\t\t\t\tthis.setDate(elem[0], dates, null, true);\r\n\t\t\t}\r\n\t\t\tvar defaultDate = inst.get('defaultDate');\r\n\t\t\tif (inst.options.selectDefaultDate && defaultDate && inst.selectedDates.length === 0) {\r\n\t\t\t\tthis.setDate(elem[0], plugin.newDate(defaultDate || plugin.today()));\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Apply the maximum length for the date format.\r\n\t\t\t@private\r\n\t\t\t@param elem {jQuery} The control to affect.\r\n\t\t\t@param inst {object} The current instance settings. */\r\n\t\t_autoSize: function(elem, inst) {\r\n\t\t\tif (inst.options.autoSize && !inst.inline) {\r\n\t\t\t\tvar date = plugin.newDate(2009, 10, 20); // Ensure double digits\r\n\t\t\t\tvar dateFormat = inst.options.dateFormat;\r\n\t\t\t\tif (dateFormat.match(/[DM]/)) {\r\n\t\t\t\t\tvar findMax = function(names) {\r\n\t\t\t\t\t\tvar max = 0;\r\n\t\t\t\t\t\tvar maxI = 0;\r\n\t\t\t\t\t\tfor (var i = 0; i < names.length; i++) {\r\n\t\t\t\t\t\t\tif (names[i].length > max) {\r\n\t\t\t\t\t\t\t\tmax = names[i].length;\r\n\t\t\t\t\t\t\t\tmaxI = i;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn maxI;\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdate.setMonth(findMax(inst.options[dateFormat.match(/MM/) ? // Longest month\r\n\t\t\t\t\t\t'monthNames' : 'monthNamesShort']));\r\n\t\t\t\t\tdate.setDate(findMax(inst.options[dateFormat.match(/DD/) ? // Longest day\r\n\t\t\t\t\t\t'dayNames' : 'dayNamesShort']) + 20 - date.getDay());\r\n\t\t\t\t}\r\n\t\t\t\tinst.elem.attr('size', plugin.formatDate(dateFormat, date, inst.getConfig()).length);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t_preDestroy: function(elem, inst) {\r\n\t\t\tif (inst.trigger) {\r\n\t\t\t\tinst.trigger.remove();\r\n\t\t\t}\r\n\t\t\telem.empty().off('.' + inst.name);\r\n\t\t\tif (inst.inline && $.fn.mousewheel) {\r\n\t\t\t\telem.unmousewheel();\r\n\t\t\t}\r\n\t\t\tif (!inst.inline && inst.options.autoSize) {\r\n\t\t\t\telem.removeAttr('size');\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Apply multiple event functions.\r\n\t\t\t@param fns {function} The functions to apply.\r\n\t\t\t@example onShow: multipleEvents(fn1, fn2, ...) */\r\n\t\tmultipleEvents: function(fns) {\r\n\t\t\tvar funcs = arguments;\r\n\t\t\treturn function(args) {\r\n\t\t\t\tfor (var i = 0; i < funcs.length; i++) {\r\n\t\t\t\t\tfuncs[i].apply(this, arguments);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t},\r\n\r\n\t\t/** Enable the control.\r\n\t\t\t@param elem {Element} The control to affect.\r\n\t\t\t@example $(selector).datepick('enable') */\r\n\t\tenable: function(elem) {\r\n\t\t\telem = $(elem);\r\n\t\t\tif (!elem.hasClass(this._getMarker())) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (inst.inline) {\r\n\t\t\t\telem.children('.' + this._disableClass).remove().end().\r\n\t\t\t\t\tfind('button,select').prop('disabled', false).end().\r\n\t\t\t\t\tfind('a').attr('href', 'javascript:void(0)');\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\telem.prop('disabled', false);\r\n\t\t\t\tinst.trigger.filter('button.' + this._triggerClass).prop('disabled', false).end().\r\n\t\t\t\t\tfilter('img.' + this._triggerClass).css({opacity: '1.0', cursor: ''});\r\n\t\t\t}\r\n\t\t\tthis._disabled = $.map(this._disabled,\r\n\t\t\t\tfunction(value) { return (value === elem[0] ? null : value); }); // Delete entry\r\n\t\t},\r\n\r\n\t\t/** Disable the control.\r\n\t\t\t@param elem {Element} The control to affect.\r\n\t\t\t@example $(selector).datepick('disable') */\r\n\t\tdisable: function(elem) {\r\n\t\t\telem = $(elem);\r\n\t\t\tif (!elem.hasClass(this._getMarker())) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (inst.inline) {\r\n\t\t\t\tvar inline = elem.children(':last');\r\n\t\t\t\tvar offset = inline.offset();\r\n\t\t\t\tvar relOffset = {left: 0, top: 0};\r\n\t\t\t\tinline.parents().each(function() {\r\n\t\t\t\t\tif ($(this).css('position') === 'relative') {\r\n\t\t\t\t\t\trelOffset = $(this).offset();\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\tvar zIndex = elem.css('zIndex');\r\n\t\t\t\tzIndex = (zIndex === 'auto' ? 0 : parseInt(zIndex, 10)) + 1;\r\n\t\t\t\telem.prepend('
    ').\r\n\t\t\t\t\tfind('button,select').prop('disabled', true).end().\r\n\t\t\t\t\tfind('a').removeAttr('href');\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\telem.prop('disabled', true);\r\n\t\t\t\tinst.trigger.filter('button.' + this._triggerClass).prop('disabled', true).end().\r\n\t\t\t\t\tfilter('img.' + this._triggerClass).css({opacity: '0.5', cursor: 'default'});\r\n\t\t\t}\r\n\t\t\tthis._disabled = $.map(this._disabled,\r\n\t\t\t\tfunction(value) { return (value === elem[0] ? null : value); }); // Delete entry\r\n\t\t\tthis._disabled.push(elem[0]);\r\n\t\t},\r\n\r\n\t\t/** Is the first field in a jQuery collection disabled as a datepicker?\r\n\t\t\t@param elem {Element} The control to examine.\r\n\t\t\t@return {boolean} true if disabled, false if enabled.\r\n\t\t\t@example if ($(selector).datepick('isDisabled')) {...} */\r\n\t\tisDisabled: function(elem) {\r\n\t\t\treturn (elem && $.inArray(elem, this._disabled) > -1);\r\n\t\t},\r\n\r\n\t\t/** Show a popup datepicker.\r\n\t\t\t@param elem {Event|Element} a focus event or the control to use.\r\n\t\t\t@example $(selector).datepick('show') */\r\n\t\tshow: function(elem) {\r\n\t\t\telem = $(elem.target || elem);\r\n\t\t\tvar inst = plugin._getInst(elem);\r\n\t\t\tif (plugin.curInst === inst) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (plugin.curInst) {\r\n\t\t\t\tplugin.hide(plugin.curInst, true);\r\n\t\t\t}\r\n\t\t\tif (!$.isEmptyObject(inst)) {\r\n\t\t\t\t// Retrieve existing date(s)\r\n\t\t\t\tinst.lastVal = null;\r\n\t\t\t\tinst.selectedDates = plugin._extractDates(inst, elem.val());\r\n\t\t\t\tinst.pickingRange = false;\r\n\t\t\t\tinst.drawDate = plugin._checkMinMax(plugin.newDate(inst.selectedDates[0] ||\r\n\t\t\t\t\tinst.get('defaultDate') || plugin.today()), inst);\r\n\t\t\t\tinst.prevDate = plugin.newDate(inst.drawDate);\r\n\t\t\t\tplugin.curInst = inst;\r\n\t\t\t\t// Generate content\r\n\t\t\t\tplugin._update(elem[0], true);\r\n\t\t\t\t// Adjust position before showing\r\n\t\t\t\tvar offset = plugin._checkOffset(inst);\r\n\t\t\t\tinst.div.css({left: offset.left, top: offset.top});\r\n\t\t\t\t// And display\r\n\t\t\t\tvar showAnim = inst.options.showAnim;\r\n\t\t\t\tvar showSpeed = inst.options.showSpeed;\r\n\t\t\t\tshowSpeed = (showSpeed === 'normal' && $.ui &&\r\n\t\t\t\t\tparseInt($.ui.version.substring(2)) >= 8 ? '_default' : showSpeed);\r\n\t\t\t\tif ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) {\r\n\t\t\t\t\tvar data = inst.div.data(); // Update old effects data\r\n\t\t\t\t\tfor (var key in data) {\r\n\t\t\t\t\t\tif (key.match(/^ec\\.storage\\./)) {\r\n\t\t\t\t\t\t\tdata[key] = inst._mainDiv.css(key.replace(/ec\\.storage\\./, ''));\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tinst.div.data(data).show(showAnim, inst.options.showOptions, showSpeed);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tinst.div[showAnim || 'show'](showAnim ? showSpeed : 0);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Extract possible dates from a string.\r\n\t\t\t@private\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@param text {string} The text to extract from.\r\n\t\t\t@return {Date[]} The extracted dates. */\r\n\t\t_extractDates: function(inst, datesText) {\r\n\t\t\tif (datesText === inst.lastVal) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tinst.lastVal = datesText;\r\n\t\t\tdatesText = datesText.split(inst.options.multiSelect ? inst.options.multiSeparator :\r\n\t\t\t\t(inst.options.rangeSelect ? inst.options.rangeSeparator : '\\x00'));\r\n\t\t\tvar dates = [];\r\n\t\t\tfor (var i = 0; i < datesText.length; i++) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tvar date = plugin.parseDate(inst.options.dateFormat, datesText[i], inst.getConfig());\r\n\t\t\t\t\tif (date) {\r\n\t\t\t\t\t\tvar found = false;\r\n\t\t\t\t\t\tfor (var j = 0; j < dates.length; j++) {\r\n\t\t\t\t\t\t\tif (dates[j].getTime() === date.getTime()) {\r\n\t\t\t\t\t\t\t\tfound = true;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (!found) {\r\n\t\t\t\t\t\t\tdates.push(date);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tcatch (e) {\r\n\t\t\t\t\t// Ignore\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tdates.splice(inst.options.multiSelect || (inst.options.rangeSelect ? 2 : 1), dates.length);\r\n\t\t\tif (inst.options.rangeSelect && dates.length === 1) {\r\n\t\t\t\tdates[1] = dates[0];\r\n\t\t\t}\r\n\t\t\treturn dates;\r\n\t\t},\r\n\r\n\t\t/** Update the datepicker display.\r\n\t\t\t@private\r\n\t\t\t@param elem {Event|Element} a focus event or the control to use.\r\n\t\t\t@param hidden {boolean} true to initially hide the datepicker. */\r\n\t\t_update: function(elem, hidden) {\r\n\t\t\telem = $(elem.target || elem);\r\n\t\t\tvar inst = plugin._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst)) {\r\n\t\t\t\tif (inst.inline || plugin.curInst === inst) {\r\n\t\t\t\t\tif ($.isFunction(inst.options.onChangeMonthYear) && (!inst.prevDate ||\r\n\t\t\t\t\t\t\tinst.prevDate.getFullYear() !== inst.drawDate.getFullYear() ||\r\n\t\t\t\t\t\t\tinst.prevDate.getMonth() !== inst.drawDate.getMonth())) {\r\n\t\t\t\t\t\tinst.options.onChangeMonthYear.apply(elem[0],\r\n\t\t\t\t\t\t\t[inst.drawDate.getFullYear(), inst.drawDate.getMonth() + 1]);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (inst.inline) {\r\n\t\t\t\t\tvar index = $('a, :input', elem).index($(':focus', elem));\r\n\t\t\t\t\telem.html(this._generateContent(elem[0], inst));\r\n\t\t\t\t\tvar focus = elem.find('a, :input');\r\n\t\t\t\t\tfocus.eq(Math.max(Math.min(index, focus.length - 1), 0)).focus();\r\n\t\t\t\t}\r\n\t\t\t\telse if (plugin.curInst === inst) {\r\n\t\t\t\t\tif (!inst.div) {\r\n\t\t\t\t\t\tinst.div = $('
    ').addClass(this._popupClass).\r\n\t\t\t\t\t\t\tcss({display: (hidden ? 'none' : 'static'), position: 'absolute',\r\n\t\t\t\t\t\t\t\tleft: elem.offset().left, top: elem.offset().top + elem.outerHeight()}).\r\n\t\t\t\t\t\t\tappendTo($(inst.options.popupContainer || 'body'));\r\n\t\t\t\t\t\tif ($.fn.mousewheel) {\r\n\t\t\t\t\t\t\tinst.div.mousewheel(this._doMouseWheel);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tinst.div.html(this._generateContent(elem[0], inst));\r\n\t\t\t\t\telem.focus();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Update the input field and any alternate field with the current dates.\r\n\t\t\t@private\r\n\t\t\t@param elem {Element} The control to use.\r\n\t\t\t@param keyUp {boolean} true if coming from keyUp processing (internal). */\r\n\t\t_updateInput: function(elem, keyUp) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst)) {\r\n\t\t\t\tvar value = '';\r\n\t\t\t\tvar altValue = '';\r\n\t\t\t\tvar sep = (inst.options.multiSelect ? inst.options.multiSeparator :\r\n\t\t\t\t\tinst.options.rangeSeparator);\r\n\t\t\t\tvar altFormat = inst.options.altFormat || inst.options.dateFormat;\r\n\t\t\t\tfor (var i = 0; i < inst.selectedDates.length; i++) {\r\n\t\t\t\t\tvalue += (keyUp ? '' : (i > 0 ? sep : '') + plugin.formatDate(\r\n\t\t\t\t\t\tinst.options.dateFormat, inst.selectedDates[i], inst.getConfig()));\r\n\t\t\t\t\taltValue += (i > 0 ? sep : '') + plugin.formatDate(\r\n\t\t\t\t\t\taltFormat, inst.selectedDates[i], inst.getConfig());\r\n\t\t\t\t}\r\n\t\t\t\tif (!inst.inline && !keyUp) {\r\n\t\t\t\t\t$(elem).val(value);\r\n\t\t\t\t}\r\n\t\t\t\t$(inst.options.altField).val(altValue);\r\n\t\t\t\tif ($.isFunction(inst.options.onSelect) && !keyUp && !inst.inSelect) {\r\n\t\t\t\t\tinst.inSelect = true; // Prevent endless loops\r\n\t\t\t\t\tinst.options.onSelect.apply(elem, [inst.selectedDates]);\r\n\t\t\t\t\tinst.inSelect = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Retrieve the size of left and top borders for an element.\r\n\t\t\t@private\r\n\t\t\t@param elem {jQuery} The element of interest.\r\n\t\t\t@return {number[]} The left and top borders. */\r\n\t\t_getBorders: function(elem) {\r\n\t\t\tvar convert = function(value) {\r\n\t\t\t\treturn {thin: 1, medium: 3, thick: 5}[value] || value;\r\n\t\t\t};\r\n\t\t\treturn [parseFloat(convert(elem.css('border-left-width'))),\r\n\t\t\t\tparseFloat(convert(elem.css('border-top-width')))];\r\n\t\t},\r\n\r\n\t\t/** Check positioning to remain on the screen.\r\n\t\t\t@private\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@return {object} The updated offset for the datepicker. */\r\n\t\t_checkOffset: function(inst) {\r\n\t\t\tvar base = (inst.elem.is(':hidden') && inst.trigger ? inst.trigger : inst.elem);\r\n\t\t\tvar offset = base.offset();\r\n\t\t\tvar browserWidth = $(window).width();\r\n\t\t\tvar browserHeight = $(window).height();\r\n\t\t\tif (browserWidth === 0) {\r\n\t\t\t\treturn offset;\r\n\t\t\t}\r\n\t\t\tvar isFixed = false;\r\n\t\t\t$(inst.elem).parents().each(function() {\r\n\t\t\t\tisFixed |= $(this).css('position') === 'fixed';\r\n\t\t\t\treturn !isFixed;\r\n\t\t\t});\r\n\t\t\tvar scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;\r\n\t\t\tvar scrollY = document.documentElement.scrollTop || document.body.scrollTop;\r\n\t\t\tvar above = offset.top - (isFixed ? scrollY : 0) - inst.div.outerHeight();\r\n\t\t\tvar below = offset.top - (isFixed ? scrollY : 0) + base.outerHeight();\r\n\t\t\tvar alignL = offset.left - (isFixed ? scrollX : 0);\r\n\t\t\tvar alignR = offset.left - (isFixed ? scrollX : 0) + base.outerWidth() - inst.div.outerWidth();\r\n\t\t\tvar tooWide = (offset.left - scrollX + inst.div.outerWidth()) > browserWidth;\r\n\t\t\tvar tooHigh = (offset.top - scrollY + inst.elem.outerHeight() +\r\n\t\t\t\tinst.div.outerHeight()) > browserHeight;\r\n\t\t\tinst.div.css('position', isFixed ? 'fixed' : 'absolute');\r\n\t\t\tvar alignment = inst.options.alignment;\r\n\t\t\tif (alignment === 'topLeft') {\r\n\t\t\t\toffset = {left: alignL, top: above};\r\n\t\t\t}\r\n\t\t\telse if (alignment === 'topRight') {\r\n\t\t\t\toffset = {left: alignR, top: above};\r\n\t\t\t}\r\n\t\t\telse if (alignment === 'bottomLeft') {\r\n\t\t\t\toffset = {left: alignL, top: below};\r\n\t\t\t}\r\n\t\t\telse if (alignment === 'bottomRight') {\r\n\t\t\t\toffset = {left: alignR, top: below};\r\n\t\t\t}\r\n\t\t\telse if (alignment === 'top') {\r\n\t\t\t\toffset = {left: (inst.options.isRTL || tooWide ? alignR : alignL), top: above};\r\n\t\t\t}\r\n\t\t\telse { // bottom\r\n\t\t\t\toffset = {left: (inst.options.isRTL || tooWide ? alignR : alignL),\r\n\t\t\t\t\ttop: (tooHigh ? above : below)};\r\n\t\t\t}\r\n\t\t\toffset.left = Math.max((isFixed ? 0 : scrollX), offset.left);\r\n\t\t\toffset.top = Math.max((isFixed ? 0 : scrollY), offset.top);\r\n\t\t\treturn offset;\r\n\t\t},\r\n\r\n\t\t/** Close date picker if clicked elsewhere.\r\n\t\t\t@private\r\n\t\t\t@param event {MouseEvent} The mouse click to check. */\r\n\t\t_checkExternalClick: function(event) {\r\n\t\t\tif (!plugin.curInst) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tvar elem = $(event.target);\r\n\t\t\tif (elem.closest('.' + plugin._popupClass + ',.' + plugin._triggerClass).length === 0 &&\r\n\t\t\t\t\t!elem.hasClass(plugin._getMarker())) {\r\n\t\t\t\tplugin.hide(plugin.curInst);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Hide a popup datepicker.\r\n\t\t\t@param elem {Element|object} The control to use or the current instance settings.\r\n\t\t\t@param immediate {boolean} true to close immediately without animation (internal).\r\n\t\t\t@example $(selector).datepick('hide') */\r\n\t\thide: function(elem, immediate) {\r\n\t\t\tif (!elem) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif ($.isEmptyObject(inst)) {\r\n\t\t\t\tinst = elem;\r\n\t\t\t}\r\n\t\t\tif (inst && inst === plugin.curInst) {\r\n\t\t\t\tvar showAnim = (immediate ? '' : inst.options.showAnim);\r\n\t\t\t\tvar showSpeed = inst.options.showSpeed;\r\n\t\t\t\tshowSpeed = (showSpeed === 'normal' && $.ui &&\r\n\t\t\t\t\tparseInt($.ui.version.substring(2)) >= 8 ? '_default' : showSpeed);\r\n\t\t\t\tvar postProcess = function() {\r\n\t\t\t\t\tif (!inst.div) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tinst.div.remove();\r\n\t\t\t\t\tinst.div = null;\r\n\t\t\t\t\tplugin.curInst = null;\r\n\t\t\t\t\tif ($.isFunction(inst.options.onClose)) {\r\n\t\t\t\t\t\tinst.options.onClose.apply(elem, [inst.selectedDates]);\r\n\t\t\t\t\t}\r\n\t\t\t\t};\r\n\t\t\t\tinst.div.stop();\r\n\t\t\t\tif ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) {\r\n\t\t\t\t\tinst.div.hide(showAnim, inst.options.showOptions, showSpeed, postProcess);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tvar hideAnim = (showAnim === 'slideDown' ? 'slideUp' :\r\n\t\t\t\t\t\t(showAnim === 'fadeIn' ? 'fadeOut' : 'hide'));\r\n\t\t\t\t\tinst.div[hideAnim]((showAnim ? showSpeed : ''), postProcess);\r\n\t\t\t\t}\r\n\t\t\t\tif (!showAnim) {\r\n\t\t\t\t\tpostProcess();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Handle keystrokes in the datepicker.\r\n\t\t\t@private\r\n\t\t\t@param event {KeyEvent} The keystroke.\r\n\t\t\t@return {boolean} true if not handled, false if handled. */\r\n\t\t_keyDown: function(event) {\r\n\t\t\tvar elem = (event.data && event.data.elem) || event.target;\r\n\t\t\tvar inst = plugin._getInst(elem);\r\n\t\t\tvar handled = false;\r\n\t\t\tif (inst.inline || inst.div) {\r\n\t\t\t\tif (event.keyCode === 9) { // Tab - close\r\n\t\t\t\t\tplugin.hide(elem);\r\n\t\t\t\t}\r\n\t\t\t\telse if (event.keyCode === 13) { // Enter - select\r\n\t\t\t\t\tplugin.selectDate(elem,\r\n\t\t\t\t\t\t$('a.' + inst.options.renderer.highlightedClass, inst.div)[0]);\r\n\t\t\t\t\thandled = true;\r\n\t\t\t\t}\r\n\t\t\t\telse { // Command keystrokes\r\n\t\t\t\t\tvar commands = inst.options.commands;\r\n\t\t\t\t\tfor (var name in commands) {\r\n\t\t\t\t\t\tvar command = commands[name];\r\n\t\t\t\t\t\tif (command.keystroke.keyCode === event.keyCode &&\r\n\t\t\t\t\t\t\t\t!!command.keystroke.ctrlKey === !!(event.ctrlKey || event.metaKey) &&\r\n\t\t\t\t\t\t\t\t!!command.keystroke.altKey === event.altKey &&\r\n\t\t\t\t\t\t\t\t!!command.keystroke.shiftKey === event.shiftKey) {\r\n\t\t\t\t\t\t\tplugin.performAction(elem, name);\r\n\t\t\t\t\t\t\thandled = true;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse { // Show on 'current' keystroke\r\n\t\t\t\tvar command = inst.options.commands.current;\r\n\t\t\t\tif (command.keystroke.keyCode === event.keyCode &&\r\n\t\t\t\t\t\t!!command.keystroke.ctrlKey === !!(event.ctrlKey || event.metaKey) &&\r\n\t\t\t\t\t\t!!command.keystroke.altKey === event.altKey &&\r\n\t\t\t\t\t\t!!command.keystroke.shiftKey === event.shiftKey) {\r\n\t\t\t\t\tplugin.show(elem);\r\n\t\t\t\t\thandled = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tinst.ctrlKey = ((event.keyCode < 48 && event.keyCode !== 32) || event.ctrlKey || event.metaKey);\r\n\t\t\tif (handled) {\r\n\t\t\t\tevent.preventDefault();\r\n\t\t\t\tevent.stopPropagation();\r\n\t\t\t}\r\n\t\t\treturn !handled;\r\n\t\t},\r\n\r\n\t\t/** Filter keystrokes in the datepicker.\r\n\t\t\t@private\r\n\t\t\t@param event {KeyEvent} The keystroke.\r\n\t\t\t@return {boolean} true if allowed, false if not allowed. */\r\n\t\t_keyPress: function(event) {\r\n\t\t\tvar inst = plugin._getInst((event.data && event.data.elem) || event.target);\r\n\t\t\tif (!$.isEmptyObject(inst) && inst.options.constrainInput) {\r\n\t\t\t\tvar ch = String.fromCharCode(event.keyCode || event.charCode);\r\n\t\t\t\tvar allowedChars = plugin._allowedChars(inst);\r\n\t\t\t\treturn (event.metaKey || inst.ctrlKey || ch < ' ' ||\r\n\t\t\t\t\t!allowedChars || allowedChars.indexOf(ch) > -1);\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t},\r\n\r\n\t\t/** Determine the set of characters allowed by the date format.\r\n\t\t\t@private\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@return {string} The set of allowed characters, or null if anything allowed. */\r\n\t\t_allowedChars: function(inst) {\r\n\t\t\tvar allowedChars = (inst.options.multiSelect ? inst.options.multiSeparator :\r\n\t\t\t\t(inst.options.rangeSelect ? inst.options.rangeSeparator : ''));\r\n\t\t\tvar literal = false;\r\n\t\t\tvar hasNum = false;\r\n\t\t\tvar dateFormat = inst.options.dateFormat;\r\n\t\t\tfor (var i = 0; i < dateFormat.length; i++) {\r\n\t\t\t\tvar ch = dateFormat.charAt(i);\r\n\t\t\t\tif (literal) {\r\n\t\t\t\t\tif (ch === \"'\" && dateFormat.charAt(i + 1) !== \"'\") {\r\n\t\t\t\t\t\tliteral = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tallowedChars += ch;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tswitch (ch) {\r\n\t\t\t\t\t\tcase 'd': case 'm': case 'o': case 'w':\r\n\t\t\t\t\t\t\tallowedChars += (hasNum ? '' : '0123456789'); hasNum = true; break;\r\n\t\t\t\t\t\tcase 'y': case '@': case '!':\r\n\t\t\t\t\t\t\tallowedChars += (hasNum ? '' : '0123456789') + '-'; hasNum = true; break;\r\n\t\t\t\t\t\tcase 'J':\r\n\t\t\t\t\t\t\tallowedChars += (hasNum ? '' : '0123456789') + '-.'; hasNum = true; break;\r\n\t\t\t\t\t\tcase 'D': case 'M': case 'Y':\r\n\t\t\t\t\t\t\treturn null; // Accept anything\r\n\t\t\t\t\t\tcase \"'\":\r\n\t\t\t\t\t\t\tif (dateFormat.charAt(i + 1) === \"'\") {\r\n\t\t\t\t\t\t\t\tallowedChars += \"'\";\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t\tliteral = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\tallowedChars += ch;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn allowedChars;\r\n\t\t},\r\n\r\n\t\t/** Synchronise datepicker with the field.\r\n\t\t\t@private\r\n\t\t\t@param event {KeyEvent} The keystroke.\r\n\t\t\t@return {boolean} true if allowed, false if not allowed. */\r\n\t\t_keyUp: function(event) {\r\n\t\t\tvar elem = (event.data && event.data.elem) || event.target;\r\n\t\t\tvar inst = plugin._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst) && !inst.ctrlKey && inst.lastVal !== inst.elem.val()) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tvar dates = plugin._extractDates(inst, inst.elem.val());\r\n\t\t\t\t\tif (dates.length > 0) {\r\n\t\t\t\t\t\tplugin.setDate(elem, dates, null, true);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tcatch (event) {\r\n\t\t\t\t\t// Ignore\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t},\r\n\r\n\t\t/** Increment/decrement month/year on mouse wheel activity.\r\n\t\t\t@private\r\n\t\t\t@param event {event} The mouse wheel event.\r\n\t\t\t@param delta {number} The amount of change. */\r\n\t\t_doMouseWheel: function(event, delta) {\r\n\t\t\tvar elem = (plugin.curInst && plugin.curInst.elem[0]) ||\r\n\t\t\t\t$(event.target).closest('.' + plugin._getMarker())[0];\r\n\t\t\tif (plugin.isDisabled(elem)) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tvar inst = plugin._getInst(elem);\r\n\t\t\tif (inst.options.useMouseWheel) {\r\n\t\t\t\tdelta = (delta < 0 ? -1 : +1);\r\n\t\t\t\tplugin.changeMonth(elem, -inst.options[event.ctrlKey ? 'monthsToJump' : 'monthsToStep'] * delta);\r\n\t\t\t}\r\n\t\t\tevent.preventDefault();\r\n\t\t},\r\n\r\n\t\t/** Clear an input and close a popup datepicker.\r\n\t\t\t@param elem {Element} The control to use.\r\n\t\t\t@example $(selector).datepick('clear') */\r\n\t\tclear: function(elem) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst)) {\r\n\t\t\t\tinst.selectedDates = [];\r\n\t\t\t\tthis.hide(elem);\r\n\t\t\t\tvar defaultDate = inst.get('defaultDate');\r\n\t\t\t\tif (inst.options.selectDefaultDate && defaultDate) {\r\n\t\t\t\t\tthis.setDate(elem, plugin.newDate(defaultDate || plugin.today()));\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tthis._updateInput(elem);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Retrieve the selected date(s) for a datepicker.\r\n\t\t\t@param elem {Element} The control to examine.\r\n\t\t\t@return {Date[]} The selected date(s).\r\n\t\t\t@example var dates = $(selector).datepick('getDate') */\r\n\t\tgetDate: function(elem) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\treturn (!$.isEmptyObject(inst) ? inst.selectedDates : []);\r\n\t\t},\r\n\r\n\t\t/** Set the selected date(s) for a datepicker.\r\n\t\t\t@param elem {Element} the control to examine.\r\n\t\t\t@param dates {Date|number|string|array} the selected date(s).\r\n\t\t\t@param [endDate] {Date|number|string} the ending date for a range.\r\n\t\t\t@param keyUp {boolean} true if coming from keyUp processing (internal).\r\n\t\t\t@param setOpt {boolean} true if coming from option processing (internal).\r\n\t\t\t@example $(selector).datepick('setDate', new Date(2014, 12-1, 25))\r\n $(selector).datepick('setDate', '12/25/2014', '01/01/2015')\r\n $(selector).datepick('setDate', [date1, date2, date3]) */\r\n\t\tsetDate: function(elem, dates, endDate, keyUp, setOpt) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst)) {\r\n\t\t\t\tif (!$.isArray(dates)) {\r\n\t\t\t\t\tdates = [dates];\r\n\t\t\t\t\tif (endDate) {\r\n\t\t\t\t\t\tdates.push(endDate);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tvar minDate = inst.get('minDate');\r\n\t\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\t\tvar curDate = inst.selectedDates[0];\r\n\t\t\t\tinst.selectedDates = [];\r\n\t\t\t\tfor (var i = 0; i < dates.length; i++) {\r\n\t\t\t\t\tvar date = plugin.determineDate(\r\n\t\t\t\t\t\tdates[i], null, curDate, inst.options.dateFormat, inst.getConfig());\r\n\t\t\t\t\tif (date) {\r\n\t\t\t\t\t\tif ((!minDate || date.getTime() >= minDate.getTime()) &&\r\n\t\t\t\t\t\t\t\t(!maxDate || date.getTime() <= maxDate.getTime())) {\r\n\t\t\t\t\t\t\tvar found = false;\r\n\t\t\t\t\t\t\tfor (var j = 0; j < inst.selectedDates.length; j++) {\r\n\t\t\t\t\t\t\t\tif (inst.selectedDates[j].getTime() === date.getTime()) {\r\n\t\t\t\t\t\t\t\t\tfound = true;\r\n\t\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (!found) {\r\n\t\t\t\t\t\t\t\tinst.selectedDates.push(date);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tinst.selectedDates.splice(inst.options.multiSelect ||\r\n\t\t\t\t\t(inst.options.rangeSelect ? 2 : 1), inst.selectedDates.length);\r\n\t\t\t\tif (inst.options.rangeSelect) {\r\n\t\t\t\t\tswitch (inst.selectedDates.length) {\r\n\t\t\t\t\t\tcase 1: inst.selectedDates[1] = inst.selectedDates[0]; break;\r\n\t\t\t\t\t\tcase 2: inst.selectedDates[1] =\r\n\t\t\t\t\t\t\t(inst.selectedDates[0].getTime() > inst.selectedDates[1].getTime() ?\r\n\t\t\t\t\t\t\tinst.selectedDates[0] : inst.selectedDates[1]); break;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tinst.pickingRange = false;\r\n\t\t\t\t}\r\n\t\t\t\tinst.prevDate = (inst.drawDate ? plugin.newDate(inst.drawDate) : null);\r\n\t\t\t\tinst.drawDate = this._checkMinMax(plugin.newDate(inst.selectedDates[0] ||\r\n\t\t\t\t\tinst.get('defaultDate') || plugin.today()), inst);\r\n\t\t\t\tif (!setOpt) {\r\n\t\t\t\t\tthis._update(elem);\r\n\t\t\t\t\tthis._updateInput(elem, keyUp);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Determine whether a date is selectable for this datepicker.\r\n\t\t\t@private\r\n\t\t\t@param elem {Element} The control to check.\r\n\t\t\t@param date {Date|string|number} The date to check.\r\n\t\t\t@return {boolean} true if selectable, false if not.\r\n\t\t\t@example var selectable = $(selector).datepick('isSelectable', date) */\r\n\t\tisSelectable: function(elem, date) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif ($.isEmptyObject(inst)) {\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tdate = plugin.determineDate(date, inst.selectedDates[0] || this.today(), null,\r\n\t\t\t\tinst.options.dateFormat, inst.getConfig());\r\n\t\t\treturn this._isSelectable(elem, date, inst.options.onDate,\r\n\t\t\t\tinst.get('minDate'), inst.get('maxDate'));\r\n\t\t},\r\n\r\n\t\t/** Internally determine whether a date is selectable for this datepicker.\r\n\t\t\t@private\r\n\t\t\t@param elem {Element} the control to check.\r\n\t\t\t@param date {Date} The date to check.\r\n\t\t\t@param onDate {function|boolean} Any onDate callback or callback.selectable.\r\n\t\t\t@param minDate {Date} The minimum allowed date.\r\n\t\t\t@param maxDate {Date} The maximum allowed date.\r\n\t\t\t@return {boolean} true if selectable, false if not. */\r\n\t\t_isSelectable: function(elem, date, onDate, minDate, maxDate) {\r\n\t\t\tvar dateInfo = (typeof onDate === 'boolean' ? {selectable: onDate} :\r\n\t\t\t\t(!$.isFunction(onDate) ? {} : onDate.apply(elem, [date, true])));\r\n\t\t\treturn (dateInfo.selectable !== false) &&\r\n\t\t\t\t(!minDate || date.getTime() >= minDate.getTime()) &&\r\n\t\t\t\t(!maxDate || date.getTime() <= maxDate.getTime());\r\n\t\t},\r\n\r\n\t\t/** Perform a named action for a datepicker.\r\n\t\t\t@param elem {element} The control to affect.\r\n\t\t\t@param action {string} The name of the action. */\r\n\t\tperformAction: function(elem, action) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst) && !this.isDisabled(elem)) {\r\n\t\t\t\tvar commands = inst.options.commands;\r\n\t\t\t\tif (commands[action] && commands[action].enabled.apply(elem, [inst])) {\r\n\t\t\t\t\tcommands[action].action.apply(elem, [inst]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Set the currently shown month, defaulting to today's.\r\n\t\t\t@param elem {Element} The control to affect.\r\n\t\t\t@param [year] {number} The year to show.\r\n\t\t\t@param [month] {number} The month to show (1-12).\r\n\t\t\t@param [day] {number} The day to show.\r\n\t\t\t@example $(selector).datepick('showMonth', 2014, 12, 25) */\r\n\t\tshowMonth: function(elem, year, month, day) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst) && (day != null ||\r\n\t\t\t\t\t(inst.drawDate.getFullYear() !== year || inst.drawDate.getMonth() + 1 !== month))) {\r\n\t\t\t\tinst.prevDate = plugin.newDate(inst.drawDate);\r\n\t\t\t\tvar show = this._checkMinMax((year != null ?\r\n\t\t\t\t\tplugin.newDate(year, month, 1) : plugin.today()), inst);\r\n\t\t\t\tinst.drawDate = plugin.newDate(show.getFullYear(), show.getMonth() + 1, \r\n\t\t\t\t\t(day != null ? day : Math.min(inst.drawDate.getDate(),\r\n\t\t\t\t\tplugin.daysInMonth(show.getFullYear(), show.getMonth() + 1))));\r\n\t\t\t\tthis._update(elem);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Adjust the currently shown month.\r\n\t\t\t@param elem {Element} The control to affect.\r\n\t\t\t@param offset {number} The number of months to change by.\r\n\t\t\t@example $(selector).datepick('changeMonth', 2)*/\r\n\t\tchangeMonth: function(elem, offset) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst)) {\r\n\t\t\t\tvar date = plugin.add(plugin.newDate(inst.drawDate), offset, 'm');\r\n\t\t\t\tthis.showMonth(elem, date.getFullYear(), date.getMonth() + 1);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Adjust the currently shown day.\r\n\t\t\t@param elem {Element} The control to affect.\r\n\t\t\t@param offset {number} The number of days to change by.\r\n\t\t\t@example $(selector).datepick('changeDay', 7)*/\r\n\t\tchangeDay: function(elem, offset) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst)) {\r\n\t\t\t\tvar date = plugin.add(plugin.newDate(inst.drawDate), offset, 'd');\r\n\t\t\t\tthis.showMonth(elem, date.getFullYear(), date.getMonth() + 1, date.getDate());\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Restrict a date to the minimum/maximum specified.\r\n\t\t\t@private\r\n\t\t\t@param date {Date} The date to check.\r\n\t\t\t@param inst {object} The current instance settings. */\r\n\t\t_checkMinMax: function(date, inst) {\r\n\t\t\tvar minDate = inst.get('minDate');\r\n\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\tdate = (minDate && date.getTime() < minDate.getTime() ? plugin.newDate(minDate) : date);\r\n\t\t\tdate = (maxDate && date.getTime() > maxDate.getTime() ? plugin.newDate(maxDate) : date);\r\n\t\t\treturn date;\r\n\t\t},\r\n\r\n\t\t/** Retrieve the date associated with an entry in the datepicker.\r\n\t\t\t@param elem {Element} The control to examine.\r\n\t\t\t@param target {Element} The selected datepicker element.\r\n\t\t\t@return {Date} The corresponding date, or null.\t\t\t\r\n\t\t\t@example var date = $(selector).datepick('retrieveDate', $('div.datepick-popup a:contains(10)')[0]) */\r\n\t\tretrieveDate: function(elem, target) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\treturn ($.isEmptyObject(inst) ? null : this._normaliseDate(\r\n\t\t\t\tnew Date(parseInt(target.className.replace(/^.*dp(-?\\d+).*$/, '$1'), 10))));\r\n\t\t},\r\n\r\n\t\t/** Select a date for this datepicker.\r\n\t\t\t@param elem {Element} The control to examine.\r\n\t\t\t@param target {Element} The selected datepicker element.\r\n\t\t\t@example $(selector).datepick('selectDate', $('div.datepick-popup a:contains(10)')[0]) */\r\n\t\tselectDate: function(elem, target) {\r\n\t\t\tvar inst = this._getInst(elem);\r\n\t\t\tif (!$.isEmptyObject(inst) && !this.isDisabled(elem)) {\r\n\t\t\t\tvar date = this.retrieveDate(elem, target);\r\n\t\t\t\tif (inst.options.multiSelect) {\r\n\t\t\t\t\tvar found = false;\r\n\t\t\t\t\tfor (var i = 0; i < inst.selectedDates.length; i++) {\r\n\t\t\t\t\t\tif (date.getTime() === inst.selectedDates[i].getTime()) {\r\n\t\t\t\t\t\t\tinst.selectedDates.splice(i, 1);\r\n\t\t\t\t\t\t\tfound = true;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (!found && inst.selectedDates.length < inst.options.multiSelect) {\r\n\t\t\t\t\t\tinst.selectedDates.push(date);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse if (inst.options.rangeSelect) {\r\n\t\t\t\t\tif (inst.pickingRange) {\r\n\t\t\t\t\t\tinst.selectedDates[1] = date;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tinst.selectedDates = [date, date];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tinst.pickingRange = !inst.pickingRange;\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tinst.selectedDates = [date];\r\n\t\t\t\t}\r\n\t\t\t\tinst.prevDate = inst.drawDate = plugin.newDate(date);\r\n\t\t\t\tthis._updateInput(elem);\r\n\t\t\t\tif (inst.inline || inst.pickingRange || inst.selectedDates.length <\r\n\t\t\t\t\t\t(inst.options.multiSelect || (inst.options.rangeSelect ? 2 : 1))) {\r\n\t\t\t\t\tthis._update(elem);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tthis.hide(elem);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/** Generate the datepicker content for this control.\r\n\t\t\t@private\r\n\t\t\t@param elem {Element} The control to affect.\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@return {jQuery} The datepicker content */\r\n\t\t_generateContent: function(elem, inst) {\r\n\t\t\tvar monthsToShow = inst.options.monthsToShow;\r\n\t\t\tmonthsToShow = ($.isArray(monthsToShow) ? monthsToShow : [1, monthsToShow]);\r\n\t\t\tinst.drawDate = this._checkMinMax(\r\n\t\t\t\tinst.drawDate || inst.get('defaultDate') || plugin.today(), inst);\r\n\t\t\tvar drawDate = plugin._applyMonthsOffset(plugin.newDate(inst.drawDate), inst);\r\n\t\t\t// Generate months\r\n\t\t\tvar monthRows = '';\r\n\t\t\tfor (var row = 0; row < monthsToShow[0]; row++) {\r\n\t\t\t\tvar months = '';\r\n\t\t\t\tfor (var col = 0; col < monthsToShow[1]; col++) {\r\n\t\t\t\t\tmonths += this._generateMonth(elem, inst, drawDate.getFullYear(),\r\n\t\t\t\t\t\tdrawDate.getMonth() + 1, inst.options.renderer, (row === 0 && col === 0));\r\n\t\t\t\t\tplugin.add(drawDate, 1, 'm');\r\n\t\t\t\t}\r\n\t\t\t\tmonthRows += this._prepare(inst.options.renderer.monthRow, inst).replace(/\\{months\\}/, months);\r\n\t\t\t}\r\n\t\t\tvar picker = this._prepare(inst.options.renderer.picker, inst).replace(/\\{months\\}/, monthRows).\r\n\t\t\t\treplace(/\\{weekHeader\\}/g, this._generateDayHeaders(inst, inst.options.renderer));\r\n\t\t\t// Add commands\r\n\t\t\tvar addCommand = function(type, open, close, name, classes) {\r\n\t\t\t\tif (picker.indexOf('{' + type + ':' + name + '}') === -1) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tvar command = inst.options.commands[name];\r\n\t\t\t\tvar date = (inst.options.commandsAsDateFormat ? command.date.apply(elem, [inst]) : null);\r\n\t\t\t\tpicker = picker.replace(new RegExp('\\\\{' + type + ':' + name + '\\\\}', 'g'),\r\n\t\t\t\t\t'<' + open + (command.status ? ' title=\"' + inst.options[command.status] + '\"' : '') +\r\n\t\t\t\t\t' class=\"' + inst.options.renderer.commandClass + ' ' +\r\n\t\t\t\t\tinst.options.renderer.commandClass + '-' + name + ' ' + classes +\r\n\t\t\t\t\t(command.enabled(inst) ? '' : ' ' + inst.options.renderer.disabledClass) + '\">' +\r\n\t\t\t\t\t(date ? plugin.formatDate(inst.options[command.text], date, inst.getConfig()) :\r\n\t\t\t\t\tinst.options[command.text]) + '');\r\n\t\t\t};\r\n\t\t\tfor (var name in inst.options.commands) {\r\n\t\t\t\taddCommand('button', 'button type=\"button\"', 'button', name,\r\n\t\t\t\t\tinst.options.renderer.commandButtonClass);\r\n\t\t\t\taddCommand('link', 'a href=\"javascript:void(0)\"', 'a', name,\r\n\t\t\t\t\tinst.options.renderer.commandLinkClass);\r\n\t\t\t}\r\n\t\t\tpicker = $(picker);\r\n\t\t\tif (monthsToShow[1] > 1) {\r\n\t\t\t\tvar count = 0;\r\n\t\t\t\t$(inst.options.renderer.monthSelector, picker).each(function() {\r\n\t\t\t\t\tvar nth = ++count % monthsToShow[1];\r\n\t\t\t\t\t$(this).addClass(nth === 1 ? 'first' : (nth === 0 ? 'last' : ''));\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\t// Add datepicker behaviour\r\n\t\t\tvar self = this;\r\n\t\t\tfunction removeHighlight() {\r\n\t\t\t\t(inst.inline ? $(this).closest('.' + self._getMarker()) : inst.div).\r\n\t\t\t\t\tfind(inst.options.renderer.daySelector + ' a').\r\n\t\t\t\t\tremoveClass(inst.options.renderer.highlightedClass);\r\n\t\t\t}\r\n\t\t\tpicker.find(inst.options.renderer.daySelector + ' a').hover(\r\n\t\t\t\t\tfunction() {\r\n\t\t\t\t\t\tremoveHighlight.apply(this);\r\n\t\t\t\t\t\t$(this).addClass(inst.options.renderer.highlightedClass);\r\n\t\t\t\t\t},\r\n\t\t\t\t\tremoveHighlight).\r\n\t\t\t\tclick(function() {\r\n\t\t\t\t\tself.selectDate(elem, this);\r\n\t\t\t\t}).end().\r\n\t\t\t\tfind('select.' + this._monthYearClass + ':not(.' + this._anyYearClass + ')').\r\n\t\t\t\tchange(function() {\r\n\t\t\t\t\tvar monthYear = $(this).val().split('/');\r\n\t\t\t\t\tself.showMonth(elem, parseInt(monthYear[1], 10), parseInt(monthYear[0], 10));\r\n\t\t\t\t}).end().\r\n\t\t\t\tfind('select.' + this._anyYearClass).click(function() {\r\n\t\t\t\t\t$(this).css('visibility', 'hidden').\r\n\t\t\t\t\t\tnext('input').css({left: this.offsetLeft, top: this.offsetTop,\r\n\t\t\t\t\t\twidth: this.offsetWidth, height: this.offsetHeight}).show().focus();\r\n\t\t\t\t}).end().\r\n\t\t\t\tfind('input.' + self._monthYearClass).change(function() {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tvar year = parseInt($(this).val(), 10);\r\n\t\t\t\t\t\tyear = (isNaN(year) ? inst.drawDate.getFullYear() : year);\r\n\t\t\t\t\t\tself.showMonth(elem, year, inst.drawDate.getMonth() + 1, inst.drawDate.getDate());\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcatch (e) {\r\n\t\t\t\t\t\talert(e);\r\n\t\t\t\t\t}\r\n\t\t\t\t}).keydown(function(event) {\r\n\t\t\t\t\tif (event.keyCode === 13) { // Enter\r\n\t\t\t\t\t\t$(event.elem).change();\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse if (event.keyCode === 27) { // Escape\r\n\t\t\t\t\t\t$(event.elem).hide().prev('select').css('visibility', 'visible');\r\n\t\t\t\t\t\tinst.elem.focus();\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t// Add keyboard handling\r\n\t\t\tvar data = {elem: inst.elem[0]};\r\n\t\t\tpicker.keydown(data, this._keyDown).keypress(data, this._keyPress).keyup(data, this._keyUp);\r\n\t\t\t// Add command behaviour\r\n\t\t\tpicker.find('.' + inst.options.renderer.commandClass).click(function() {\r\n\t\t\t\t\tif (!$(this).hasClass(inst.options.renderer.disabledClass)) {\r\n\t\t\t\t\t\tvar action = this.className.replace(\r\n\t\t\t\t\t\t\tnew RegExp('^.*' + inst.options.renderer.commandClass + '-([^ ]+).*$'), '$1');\r\n\t\t\t\t\t\tplugin.performAction(elem, action);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t// Add classes\r\n\t\t\tif (inst.options.isRTL) {\r\n\t\t\t\tpicker.addClass(inst.options.renderer.rtlClass);\r\n\t\t\t}\r\n\t\t\tif (monthsToShow[0] * monthsToShow[1] > 1) {\r\n\t\t\t\tpicker.addClass(inst.options.renderer.multiClass);\r\n\t\t\t}\r\n\t\t\tif (inst.options.pickerClass) {\r\n\t\t\t\tpicker.addClass(inst.options.pickerClass);\r\n\t\t\t}\r\n\t\t\t// Resize\r\n\t\t\t$('body').append(picker);\r\n\t\t\tvar width = 0;\r\n\t\t\tpicker.find(inst.options.renderer.monthSelector).each(function() {\r\n\t\t\t\twidth += $(this).outerWidth();\r\n\t\t\t});\r\n\t\t\tpicker.width(width / monthsToShow[0]);\r\n\t\t\t// Pre-show customisation\r\n\t\t\tif ($.isFunction(inst.options.onShow)) {\r\n\t\t\t\tinst.options.onShow.apply(elem, [picker, inst]);\r\n\t\t\t}\r\n\t\t\treturn picker;\r\n\t\t},\r\n\r\n\t\t/** Generate the content for a single month.\r\n\t\t\t@private\r\n\t\t\t@param elem {Element} The control to affect.\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@param year {number} The year to generate.\r\n\t\t\t@param month {number} The month to generate.\r\n\t\t\t@param renderer {object} The rendering templates.\r\n\t\t\t@param first {boolean} true if first of multiple months.\r\n\t\t\t@return {string} The month content. */\r\n\t\t_generateMonth: function(elem, inst, year, month, renderer, first) {\r\n\t\t\tvar daysInMonth = plugin.daysInMonth(year, month);\r\n\t\t\tvar monthsToShow = inst.options.monthsToShow;\r\n\t\t\tmonthsToShow = ($.isArray(monthsToShow) ? monthsToShow : [1, monthsToShow]);\r\n\t\t\tvar fixedWeeks = inst.options.fixedWeeks || (monthsToShow[0] * monthsToShow[1] > 1);\r\n\t\t\tvar firstDay = inst.options.firstDay;\r\n\t\t\tvar leadDays = (plugin.newDate(year, month, 1).getDay() - firstDay + 7) % 7;\r\n\t\t\tvar numWeeks = (fixedWeeks ? 6 : Math.ceil((leadDays + daysInMonth) / 7));\r\n\t\t\tvar selectOtherMonths = inst.options.selectOtherMonths && inst.options.showOtherMonths;\r\n\t\t\tvar minDate = (inst.pickingRange ? inst.selectedDates[0] : inst.get('minDate'));\r\n\t\t\tvar maxDate = inst.get('maxDate');\r\n\t\t\tvar showWeeks = renderer.week.indexOf('{weekOfYear}') > -1;\r\n\t\t\tvar today = plugin.today();\r\n\t\t\tvar drawDate = plugin.newDate(year, month, 1);\r\n\t\t\tplugin.add(drawDate, -leadDays - (fixedWeeks && (drawDate.getDay() === firstDay) ? 7 : 0), 'd');\r\n\t\t\tvar ts = drawDate.getTime();\r\n\t\t\t// Generate weeks\r\n\t\t\tvar weeks = '';\r\n\t\t\tfor (var week = 0; week < numWeeks; week++) {\r\n\t\t\t\tvar weekOfYear = (!showWeeks ? '' : '' +\r\n\t\t\t\t\t($.isFunction(inst.options.calculateWeek) ? inst.options.calculateWeek(drawDate) : 0) + '');\r\n\t\t\t\tvar days = '';\r\n\t\t\t\tfor (var day = 0; day < 7; day++) {\r\n\t\t\t\t\tvar selected = false;\r\n\t\t\t\t\tif (inst.options.rangeSelect && inst.selectedDates.length > 0) {\r\n\t\t\t\t\t\tselected = (drawDate.getTime() >= inst.selectedDates[0] &&\r\n\t\t\t\t\t\t\tdrawDate.getTime() <= inst.selectedDates[1]);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tfor (var i = 0; i < inst.selectedDates.length; i++) {\r\n\t\t\t\t\t\t\tif (inst.selectedDates[i].getTime() === drawDate.getTime()) {\r\n\t\t\t\t\t\t\t\tselected = true;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvar dateInfo = (!$.isFunction(inst.options.onDate) ? {} :\r\n\t\t\t\t\t\tinst.options.onDate.apply(elem, [drawDate, drawDate.getMonth() + 1 === month]));\r\n\r\n\t\t\t\t\tvar dateToday = new Date();\r\n\t\t\t\t dateToday.setHours(0, 0, 0, 0);\r\n\r\n\t\t\t\t\tvar selectable = (selectOtherMonths || drawDate.getMonth() + 1 === month) &&\r\n\t\t\t\t \tthis._isSelectable(elem, drawDate, dateInfo.selectable, dateToday, maxDate); // minDate replaced with dateToday.\r\n\r\n\t\t\t\t\tdays += this._prepare(renderer.day, inst).replace(/\\{day\\}/g,\r\n\t\t\t\t\t\t(selectable ? '' +\r\n\t\t\t\t\t\t(inst.options.showOtherMonths || (drawDate.getMonth() + 1) === month ?\r\n\t\t\t\t\t\tdateInfo.content || drawDate.getDate() : ' ') +\r\n\t\t\t\t\t\t(selectable ? '' : ''));\r\n\t\t\t\t\tplugin.add(drawDate, 1, 'd');\r\n\t\t\t\t\tts = drawDate.getTime();\r\n\t\t\t\t}\r\n\t\t\t\tweeks += this._prepare(renderer.week, inst).replace(/\\{days\\}/g, days).\r\n\t\t\t\t\treplace(/\\{weekOfYear\\}/g, weekOfYear);\r\n\t\t\t}\r\n\t\t\tvar monthHeader = this._prepare(renderer.month, inst).match(/\\{monthHeader(:[^\\}]+)?\\}/);\r\n\t\t\tmonthHeader = (monthHeader[0].length <= 13 ? 'MM yyyy' :\r\n\t\t\t\tmonthHeader[0].substring(13, monthHeader[0].length - 1));\r\n\t\t\tmonthHeader = (first ? this._generateMonthSelection(\r\n\t\t\t\tinst, year, month, minDate, maxDate, monthHeader, renderer) :\r\n\t\t\t\tplugin.formatDate(monthHeader, plugin.newDate(year, month, 1), inst.getConfig()));\r\n\t\t\tvar weekHeader = this._prepare(renderer.weekHeader, inst).\r\n\t\t\t\treplace(/\\{days\\}/g, this._generateDayHeaders(inst, renderer));\r\n\t\t\treturn this._prepare(renderer.month, inst).replace(/\\{monthHeader(:[^\\}]+)?\\}/g, monthHeader).\r\n\t\t\t\treplace(/\\{weekHeader\\}/g, weekHeader).replace(/\\{weeks\\}/g, weeks);\r\n\t\t},\r\n\r\n\t\t/** Generate the HTML for the day headers.\r\n\t\t\t@private\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@param renderer {object} The rendering templates.\r\n\t\t\t@return {string} A week's worth of day headers. */\r\n\t\t_generateDayHeaders: function(inst, renderer) {\r\n\t\t\tvar header = '';\r\n\t\t\tfor (var day = 0; day < 7; day++) {\r\n\t\t\t\tvar dow = (day + inst.options.firstDay) % 7;\r\n\t\t\t\theader += this._prepare(renderer.dayHeader, inst).replace(/\\{day\\}/g,\r\n\t\t\t\t\t'' + inst.options.dayNamesMin[dow] + '');\r\n\t\t\t}\r\n\t\t\treturn header;\r\n\t\t},\r\n\r\n\t\t/** Generate selection controls for month.\r\n\t\t\t@private\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@param year {number} The year to generate.\r\n\t\t\t@param month {number} The month to generate.\r\n\t\t\t@param minDate {Date} The minimum date allowed.\r\n\t\t\t@param maxDate {Date} The maximum date allowed.\r\n\t\t\t@param monthHeader {string} The month/year format.\r\n\t\t\t@return {string} The month selection content. */\r\n\t\t_generateMonthSelection: function(inst, year, month, minDate, maxDate, monthHeader) {\r\n\t\t\tif (!inst.options.changeMonth) {\r\n\t\t\t\treturn plugin.formatDate(\r\n\t\t\t\t\tmonthHeader, plugin.newDate(year, month, 1), inst.getConfig());\r\n\t\t\t}\r\n\t\t\t// Months\r\n\t\t\tvar monthNames = inst.options['monthNames' + (monthHeader.match(/mm/i) ? '' : 'Short')];\r\n\t\t\tvar html = monthHeader.replace(/m+/i, '\\\\x2E').replace(/y+/i, '\\\\x2F');\r\n\t\t\tvar selector = '';\r\n\t\t\thtml = html.replace(/\\\\x2E/, selector);\r\n\t\t\t// Years\r\n\t\t\tvar yearRange = inst.options.yearRange;\r\n\t\t\tif (yearRange === 'any') {\r\n\t\t\t\tselector = '' +\r\n\t\t\t\t\t'';\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tyearRange = yearRange.split(':');\r\n\t\t\t\tvar todayYear = plugin.today().getFullYear();\r\n\t\t\t\tvar start = (yearRange[0].match('c[+-].*') ? year + parseInt(yearRange[0].substring(1), 10) :\r\n\t\t\t\t\t((yearRange[0].match('[+-].*') ? todayYear : 0) + parseInt(yearRange[0], 10)));\r\n\t\t\t\tvar end = (yearRange[1].match('c[+-].*') ? year + parseInt(yearRange[1].substring(1), 10) :\r\n\t\t\t\t\t((yearRange[1].match('[+-].*') ? todayYear : 0) + parseInt(yearRange[1], 10)));\r\n\t\t\t\tselector = '';\r\n\t\t\t}\r\n\t\t\thtml = html.replace(/\\\\x2F/, selector);\r\n\t\t\treturn html;\r\n\t\t},\r\n\r\n\t\t/** Prepare a render template for use.\r\n\t\t\tExclude popup/inline sections that are not applicable.\r\n\t\t\tLocalise text of the form: {l10n:name}.\r\n\t\t\t@private\r\n\t\t\t@param text {string} The text to localise.\r\n\t\t\t@param inst {object} The current instance settings.\r\n\t\t\t@return {string} The localised text. */\r\n\t\t_prepare: function(text, inst) {\r\n\t\t\tvar replaceSection = function(type, retain) {\r\n\t\t\t\twhile (true) {\r\n\t\t\t\t\tvar start = text.indexOf('{' + type + ':start}');\r\n\t\t\t\t\tif (start === -1) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvar end = text.substring(start).indexOf('{' + type + ':end}');\r\n\t\t\t\t\tif (end > -1) {\r\n\t\t\t\t\t\ttext = text.substring(0, start) +\r\n\t\t\t\t\t\t\t(retain ? text.substr(start + type.length + 8, end - type.length - 8) : '') +\r\n\t\t\t\t\t\t\ttext.substring(start + end + type.length + 6);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t\treplaceSection('inline', inst.inline);\r\n\t\t\treplaceSection('popup', !inst.inline);\r\n\t\t\tvar pattern = /\\{l10n:([^\\}]+)\\}/;\r\n\t\t\tvar matches = null;\r\n\t\t\twhile (matches = pattern.exec(text)) {\r\n\t\t\t\ttext = text.replace(matches[0], inst.options[matches[1]]);\r\n\t\t\t}\r\n\t\t\treturn text;\r\n\t\t}\r\n\t});\r\n\r\n\tvar plugin = $.datepick; // Singleton instance\r\n\r\n\t$(function() {\r\n\t\t$(document).on('mousedown.' + pluginName, plugin._checkExternalClick).\r\n\t\t\ton('resize.' + pluginName, function() { plugin.hide(plugin.curInst); });\r\n\t});\r\n\r\n})(jQuery);\r\n","/*!\r\n * jQuery Validation Plugin v1.14.0\r\n *\r\n * http://jqueryvalidation.org/\r\n *\r\n * Copyright (c) 2015 Jörn Zaefferer\r\n * Released under the MIT license\r\n */\r\n(function( factory ) {\r\n\tif ( typeof define === \"function\" && define.amd ) {\r\n\t\tdefine( [\"jquery\"], factory );\r\n\t} else {\r\n\t\tfactory( jQuery );\r\n\t}\r\n}(function( $ ) {\r\n\r\n$.extend($.fn, {\r\n\t// http://jqueryvalidation.org/validate/\r\n\tvalidate: function( options ) {\r\n\r\n\t\t// if nothing is selected, return nothing; can't chain anyway\r\n\t\tif ( !this.length ) {\r\n\t\t\tif ( options && options.debug && window.console ) {\r\n\t\t\t\tconsole.warn( \"Nothing selected, can't validate, returning nothing.\" );\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// check if a validator for this form was already created\r\n\t\tvar validator = $.data( this[ 0 ], \"validator\" );\r\n\t\tif ( validator ) {\r\n\t\t\treturn validator;\r\n\t\t}\r\n\r\n\t\t// Add novalidate tag if HTML5.\r\n\t\tthis.attr( \"novalidate\", \"novalidate\" );\r\n\r\n\t\tvalidator = new $.validator( options, this[ 0 ] );\r\n\t\t$.data( this[ 0 ], \"validator\", validator );\r\n\r\n\t\tif ( validator.settings.onsubmit ) {\r\n\r\n\t\t\tthis.on( \"click.validate\", \":submit\", function( event ) {\r\n\t\t\t\tif ( validator.settings.submitHandler ) {\r\n\t\t\t\t\tvalidator.submitButton = event.target;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// allow suppressing validation by adding a cancel class to the submit button\r\n\t\t\t\tif ( $( this ).hasClass( \"cancel\" ) ) {\r\n\t\t\t\t\tvalidator.cancelSubmit = true;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button\r\n\t\t\t\tif ( $( this ).attr( \"formnovalidate\" ) !== undefined ) {\r\n\t\t\t\t\tvalidator.cancelSubmit = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// validate the form on submit\r\n\t\t\tthis.on( \"submit.validate\", function( event ) {\r\n\t\t\t\tif ( validator.settings.debug ) {\r\n\t\t\t\t\t// prevent form submit to be able to see console output\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t}\r\n\t\t\t\tfunction handle() {\r\n\t\t\t\t\tvar hidden, result;\r\n\t\t\t\t\tif ( validator.settings.submitHandler ) {\r\n\t\t\t\t\t\tif ( validator.submitButton ) {\r\n\t\t\t\t\t\t\t// insert a hidden input as a replacement for the missing submit button\r\n\t\t\t\t\t\t\thidden = $( \"\" )\r\n\t\t\t\t\t\t\t\t.attr( \"name\", validator.submitButton.name )\r\n\t\t\t\t\t\t\t\t.val( $( validator.submitButton ).val() )\r\n\t\t\t\t\t\t\t\t.appendTo( validator.currentForm );\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tresult = validator.settings.submitHandler.call( validator, validator.currentForm, event );\r\n\t\t\t\t\t\tif ( validator.submitButton ) {\r\n\t\t\t\t\t\t\t// and clean up afterwards; thanks to no-block-scope, hidden can be referenced\r\n\t\t\t\t\t\t\thidden.remove();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif ( result !== undefined ) {\r\n\t\t\t\t\t\t\treturn result;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// prevent submit for invalid forms or custom submit handlers\r\n\t\t\t\tif ( validator.cancelSubmit ) {\r\n\t\t\t\t\tvalidator.cancelSubmit = false;\r\n\t\t\t\t\treturn handle();\r\n\t\t\t\t}\r\n\t\t\t\tif ( validator.form() ) {\r\n\t\t\t\t\tif ( validator.pendingRequest ) {\r\n\t\t\t\t\t\tvalidator.formSubmitted = true;\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn handle();\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalidator.focusInvalid();\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\treturn validator;\r\n\t},\r\n\t// http://jqueryvalidation.org/valid/\r\n\tvalid: function() {\r\n\t\tvar valid, validator, errorList;\r\n\r\n\t\tif ( $( this[ 0 ] ).is( \"form\" ) ) {\r\n\t\t\tvalid = this.validate().form();\r\n\t\t} else {\r\n\t\t\terrorList = [];\r\n\t\t\tvalid = true;\r\n\t\t\tvalidator = $( this[ 0 ].form ).validate();\r\n\t\t\tthis.each( function() {\r\n\t\t\t\tvalid = validator.element( this ) && valid;\r\n\t\t\t\terrorList = errorList.concat( validator.errorList );\r\n\t\t\t});\r\n\t\t\tvalidator.errorList = errorList;\r\n\t\t}\r\n\t\treturn valid;\r\n\t},\r\n\r\n\t// http://jqueryvalidation.org/rules/\r\n\trules: function( command, argument ) {\r\n\t\tvar element = this[ 0 ],\r\n\t\t\tsettings, staticRules, existingRules, data, param, filtered;\r\n\r\n\t\tif ( command ) {\r\n\t\t\tsettings = $.data( element.form, \"validator\" ).settings;\r\n\t\t\tstaticRules = settings.rules;\r\n\t\t\texistingRules = $.validator.staticRules( element );\r\n\t\t\tswitch ( command ) {\r\n\t\t\tcase \"add\":\r\n\t\t\t\t$.extend( existingRules, $.validator.normalizeRule( argument ) );\r\n\t\t\t\t// remove messages from rules, but allow them to be set separately\r\n\t\t\t\tdelete existingRules.messages;\r\n\t\t\t\tstaticRules[ element.name ] = existingRules;\r\n\t\t\t\tif ( argument.messages ) {\r\n\t\t\t\t\tsettings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"remove\":\r\n\t\t\t\tif ( !argument ) {\r\n\t\t\t\t\tdelete staticRules[ element.name ];\r\n\t\t\t\t\treturn existingRules;\r\n\t\t\t\t}\r\n\t\t\t\tfiltered = {};\r\n\t\t\t\t$.each( argument.split( /\\s/ ), function( index, method ) {\r\n\t\t\t\t\tfiltered[ method ] = existingRules[ method ];\r\n\t\t\t\t\tdelete existingRules[ method ];\r\n\t\t\t\t\tif ( method === \"required\" ) {\r\n\t\t\t\t\t\t$( element ).removeAttr( \"aria-required\" );\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\treturn filtered;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tdata = $.validator.normalizeRules(\r\n\t\t$.extend(\r\n\t\t\t{},\r\n\t\t\t$.validator.classRules( element ),\r\n\t\t\t$.validator.attributeRules( element ),\r\n\t\t\t$.validator.dataRules( element ),\r\n\t\t\t$.validator.staticRules( element )\r\n\t\t), element );\r\n\r\n\t\t// make sure required is at front\r\n\t\tif ( data.required ) {\r\n\t\t\tparam = data.required;\r\n\t\t\tdelete data.required;\r\n\t\t\tdata = $.extend( { required: param }, data );\r\n\t\t\t$( element ).attr( \"aria-required\", \"true\" );\r\n\t\t}\r\n\r\n\t\t// make sure remote is at back\r\n\t\tif ( data.remote ) {\r\n\t\t\tparam = data.remote;\r\n\t\t\tdelete data.remote;\r\n\t\t\tdata = $.extend( data, { remote: param });\r\n\t\t}\r\n\r\n\t\treturn data;\r\n\t}\r\n});\r\n\r\n// Custom selectors\r\n$.extend( $.expr[ \":\" ], {\r\n\t// http://jqueryvalidation.org/blank-selector/\r\n\tblank: function( a ) {\r\n\t\treturn !$.trim( \"\" + $( a ).val() );\r\n\t},\r\n\t// http://jqueryvalidation.org/filled-selector/\r\n\tfilled: function( a ) {\r\n\t\treturn !!$.trim( \"\" + $( a ).val() );\r\n\t},\r\n\t// http://jqueryvalidation.org/unchecked-selector/\r\n\tunchecked: function( a ) {\r\n\t\treturn !$( a ).prop( \"checked\" );\r\n\t}\r\n});\r\n\r\n// constructor for validator\r\n$.validator = function( options, form ) {\r\n\tthis.settings = $.extend( true, {}, $.validator.defaults, options );\r\n\tthis.currentForm = form;\r\n\tthis.init();\r\n};\r\n\r\n// http://jqueryvalidation.org/jQuery.validator.format/\r\n$.validator.format = function( source, params ) {\r\n\tif ( arguments.length === 1 ) {\r\n\t\treturn function() {\r\n\t\t\tvar args = $.makeArray( arguments );\r\n\t\t\targs.unshift( source );\r\n\t\t\treturn $.validator.format.apply( this, args );\r\n\t\t};\r\n\t}\r\n\tif ( arguments.length > 2 && params.constructor !== Array ) {\r\n\t\tparams = $.makeArray( arguments ).slice( 1 );\r\n\t}\r\n\tif ( params.constructor !== Array ) {\r\n\t\tparams = [ params ];\r\n\t}\r\n\t$.each( params, function( i, n ) {\r\n\t\tsource = source.replace( new RegExp( \"\\\\{\" + i + \"\\\\}\", \"g\" ), function() {\r\n\t\t\treturn n;\r\n\t\t});\r\n\t});\r\n\treturn source;\r\n};\r\n\r\n$.extend( $.validator, {\r\n\r\n\tdefaults: {\r\n\t\tmessages: {},\r\n\t\tgroups: {},\r\n\t\trules: {},\r\n\t\terrorClass: \"error\",\r\n\t\tvalidClass: \"valid\",\r\n\t\terrorElement: \"label\",\r\n\t\tfocusCleanup: false,\r\n\t\tfocusInvalid: true,\r\n\t\terrorContainer: $( [] ),\r\n\t\terrorLabelContainer: $( [] ),\r\n\t\tonsubmit: true,\r\n\t\tignore: \":hidden\",\r\n\t\tignoreTitle: false,\r\n\t\tonfocusin: function( element ) {\r\n\t\t\tthis.lastActive = element;\r\n\r\n\t\t\t// Hide error label and remove error class on focus if enabled\r\n\t\t\tif ( this.settings.focusCleanup ) {\r\n\t\t\t\tif ( this.settings.unhighlight ) {\r\n\t\t\t\t\tthis.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );\r\n\t\t\t\t}\r\n\t\t\t\tthis.hideThese( this.errorsFor( element ) );\r\n\t\t\t}\r\n\t\t},\r\n\t\tonfocusout: function( element ) {\r\n\t\t\tif ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {\r\n\t\t\t\tthis.element( element );\r\n\t\t\t}\r\n\t\t},\r\n\t\tonkeyup: function( element, event ) {\r\n\t\t\t// Avoid revalidate the field when pressing one of the following keys\r\n\t\t\t// Shift => 16\r\n\t\t\t// Ctrl => 17\r\n\t\t\t// Alt => 18\r\n\t\t\t// Caps lock => 20\r\n\t\t\t// End => 35\r\n\t\t\t// Home => 36\r\n\t\t\t// Left arrow => 37\r\n\t\t\t// Up arrow => 38\r\n\t\t\t// Right arrow => 39\r\n\t\t\t// Down arrow => 40\r\n\t\t\t// Insert => 45\r\n\t\t\t// Num lock => 144\r\n\t\t\t// AltGr key => 225\r\n\t\t\tvar excludedKeys = [\r\n\t\t\t\t16, 17, 18, 20, 35, 36, 37,\r\n\t\t\t\t38, 39, 40, 45, 144, 225\r\n\t\t\t];\r\n\r\n\t\t\tif ( event.which === 9 && this.elementValue( element ) === \"\" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if ( element.name in this.submitted || element === this.lastElement ) {\r\n\t\t\t\tthis.element( element );\r\n\t\t\t}\r\n\t\t},\r\n\t\tonclick: function( element ) {\r\n\t\t\t// click on selects, radiobuttons and checkboxes\r\n\t\t\tif ( element.name in this.submitted ) {\r\n\t\t\t\tthis.element( element );\r\n\r\n\t\t\t// or option elements, check parent select in that case\r\n\t\t\t} else if ( element.parentNode.name in this.submitted ) {\r\n\t\t\t\tthis.element( element.parentNode );\r\n\t\t\t}\r\n\t\t},\r\n\t\thighlight: function( element, errorClass, validClass ) {\r\n\t\t\tif ( element.type === \"radio\" ) {\r\n\t\t\t\tthis.findByName( element.name ).addClass( errorClass ).removeClass( validClass );\r\n\t\t\t} else {\r\n\t\t\t\t$( element ).addClass( errorClass ).removeClass( validClass );\r\n\t\t\t}\r\n\t\t},\r\n\t\tunhighlight: function( element, errorClass, validClass ) {\r\n\t\t\tif ( element.type === \"radio\" ) {\r\n\t\t\t\tthis.findByName( element.name ).removeClass( errorClass ).addClass( validClass );\r\n\t\t\t} else {\r\n\t\t\t\t$( element ).removeClass( errorClass ).addClass( validClass );\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\t// http://jqueryvalidation.org/jQuery.validator.setDefaults/\r\n\tsetDefaults: function( settings ) {\r\n\t\t$.extend( $.validator.defaults, settings );\r\n\t},\r\n\r\n\tmessages: {\r\n\t\trequired: \"This field is required.\",\r\n\t\tremote: \"Please fix this field.\",\r\n\t\temail: \"Please enter a valid email address.\",\r\n\t\turl: \"Please enter a valid URL.\",\r\n\t\tdate: \"Please enter a valid date.\",\r\n\t\tdateISO: \"Please enter a valid date ( ISO ).\",\r\n\t\tnumber: \"Please enter a valid number.\",\r\n\t\tdigits: \"Please enter only digits.\",\r\n\t\tcreditcard: \"Please enter a valid credit card number.\",\r\n\t\tequalTo: \"Please enter the same value again.\",\r\n\t\tmaxlength: $.validator.format( \"Please enter no more than {0} characters.\" ),\r\n\t\tminlength: $.validator.format( \"Please enter at least {0} characters.\" ),\r\n\t\trangelength: $.validator.format( \"Please enter a value between {0} and {1} characters long.\" ),\r\n\t\trange: $.validator.format( \"Please enter a value between {0} and {1}.\" ),\r\n\t\tmax: $.validator.format( \"Please enter a value less than or equal to {0}.\" ),\r\n\t\tmin: $.validator.format( \"Please enter a value greater than or equal to {0}.\" )\r\n\t},\r\n\r\n\tautoCreateRanges: false,\r\n\r\n\tprototype: {\r\n\r\n\t\tinit: function() {\r\n\t\t\tthis.labelContainer = $( this.settings.errorLabelContainer );\r\n\t\t\tthis.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );\r\n\t\t\tthis.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );\r\n\t\t\tthis.submitted = {};\r\n\t\t\tthis.valueCache = {};\r\n\t\t\tthis.pendingRequest = 0;\r\n\t\t\tthis.pending = {};\r\n\t\t\tthis.invalid = {};\r\n\t\t\tthis.reset();\r\n\r\n\t\t\tvar groups = ( this.groups = {} ),\r\n\t\t\t\trules;\r\n\t\t\t$.each( this.settings.groups, function( key, value ) {\r\n\t\t\t\tif ( typeof value === \"string\" ) {\r\n\t\t\t\t\tvalue = value.split( /\\s/ );\r\n\t\t\t\t}\r\n\t\t\t\t$.each( value, function( index, name ) {\r\n\t\t\t\t\tgroups[ name ] = key;\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t\trules = this.settings.rules;\r\n\t\t\t$.each( rules, function( key, value ) {\r\n\t\t\t\trules[ key ] = $.validator.normalizeRule( value );\r\n\t\t\t});\r\n\r\n\t\t\tfunction delegate( event ) {\r\n\t\t\t\tvar validator = $.data( this.form, \"validator\" ),\r\n\t\t\t\t\teventType = \"on\" + event.type.replace( /^validate/, \"\" ),\r\n\t\t\t\t\tsettings = validator.settings;\r\n\t\t\t\tif ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {\r\n\t\t\t\t\tsettings[ eventType ].call( validator, this, event );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t$( this.currentForm )\r\n\t\t\t\t.on( \"focusin.validate focusout.validate keyup.validate\",\r\n\t\t\t\t\t\":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], \" +\r\n\t\t\t\t\t\"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], \" +\r\n\t\t\t\t\t\"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], \" +\r\n\t\t\t\t\t\"[type='radio'], [type='checkbox']\", delegate)\r\n\t\t\t\t// Support: Chrome, oldIE\r\n\t\t\t\t// \"select\" is provided as event.target when clicking a option\r\n\t\t\t\t.on(\"click.validate\", \"select, option, [type='radio'], [type='checkbox']\", delegate);\r\n\r\n\t\t\tif ( this.settings.invalidHandler ) {\r\n\t\t\t\t$( this.currentForm ).on( \"invalid-form.validate\", this.settings.invalidHandler );\r\n\t\t\t}\r\n\r\n\t\t\t// Add aria-required to any Static/Data/Class required fields before first validation\r\n\t\t\t// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html\r\n\t\t\t$( this.currentForm ).find( \"[required], [data-rule-required], .required\" ).attr( \"aria-required\", \"true\" );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/Validator.form/\r\n\t\tform: function() {\r\n\t\t\tthis.checkForm();\r\n\t\t\t$.extend( this.submitted, this.errorMap );\r\n\t\t\tthis.invalid = $.extend({}, this.errorMap );\r\n\t\t\tif ( !this.valid() ) {\r\n\t\t\t\t$( this.currentForm ).triggerHandler( \"invalid-form\", [ this ]);\r\n\t\t\t}\r\n\t\t\tthis.showErrors();\r\n\t\t\treturn this.valid();\r\n\t\t},\r\n\r\n\t\tcheckForm: function() {\r\n\t\t\tthis.prepareForm();\r\n\t\t\tfor ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {\r\n\t\t\t\tthis.check( elements[ i ] );\r\n\t\t\t}\r\n\t\t\treturn this.valid();\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/Validator.element/\r\n\t\telement: function( element ) {\r\n\t\t\tvar cleanElement = this.clean( element ),\r\n\t\t\t\tcheckElement = this.validationTargetFor( cleanElement ),\r\n\t\t\t\tresult = true;\r\n\r\n\t\t\tthis.lastElement = checkElement;\r\n\r\n\t\t\tif ( checkElement === undefined ) {\r\n\t\t\t\tdelete this.invalid[ cleanElement.name ];\r\n\t\t\t} else {\r\n\t\t\t\tthis.prepareElement( checkElement );\r\n\t\t\t\tthis.currentElements = $( checkElement );\r\n\r\n\t\t\t\tresult = this.check( checkElement ) !== false;\r\n\t\t\t\tif ( result ) {\r\n\t\t\t\t\tdelete this.invalid[ checkElement.name ];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.invalid[ checkElement.name ] = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Add aria-invalid status for screen readers\r\n\t\t\t$( element ).attr( \"aria-invalid\", !result );\r\n\r\n\t\t\tif ( !this.numberOfInvalids() ) {\r\n\t\t\t\t// Hide error containers on last error\r\n\t\t\t\tthis.toHide = this.toHide.add( this.containers );\r\n\t\t\t}\r\n\t\t\tthis.showErrors();\r\n\t\t\treturn result;\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/Validator.showErrors/\r\n\t\tshowErrors: function( errors ) {\r\n\t\t\tif ( errors ) {\r\n\t\t\t\t// add items to error list and map\r\n\t\t\t\t$.extend( this.errorMap, errors );\r\n\t\t\t\tthis.errorList = [];\r\n\t\t\t\tfor ( var name in errors ) {\r\n\t\t\t\t\tthis.errorList.push({\r\n\t\t\t\t\t\tmessage: errors[ name ],\r\n\t\t\t\t\t\telement: this.findByName( name )[ 0 ]\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t\t// remove items from success list\r\n\t\t\t\tthis.successList = $.grep( this.successList, function( element ) {\r\n\t\t\t\t\treturn !( element.name in errors );\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif ( this.settings.showErrors ) {\r\n\t\t\t\tthis.settings.showErrors.call( this, this.errorMap, this.errorList );\r\n\t\t\t} else {\r\n\t\t\t\tthis.defaultShowErrors();\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/Validator.resetForm/\r\n\t\tresetForm: function() {\r\n\t\t\tif ( $.fn.resetForm ) {\r\n\t\t\t\t$( this.currentForm ).resetForm();\r\n\t\t\t}\r\n\t\t\tthis.submitted = {};\r\n\t\t\tthis.lastElement = null;\r\n\t\t\tthis.prepareForm();\r\n\t\t\tthis.hideErrors();\r\n\t\t\tvar i, elements = this.elements()\r\n\t\t\t\t.removeData( \"previousValue\" )\r\n\t\t\t\t.removeAttr( \"aria-invalid\" );\r\n\r\n\t\t\tif ( this.settings.unhighlight ) {\r\n\t\t\t\tfor ( i = 0; elements[ i ]; i++ ) {\r\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[ i ],\r\n\t\t\t\t\t\tthis.settings.errorClass, \"\" );\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\telements.removeClass( this.settings.errorClass );\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tnumberOfInvalids: function() {\r\n\t\t\treturn this.objectLength( this.invalid );\r\n\t\t},\r\n\r\n\t\tobjectLength: function( obj ) {\r\n\t\t\t/* jshint unused: false */\r\n\t\t\tvar count = 0,\r\n\t\t\t\ti;\r\n\t\t\tfor ( i in obj ) {\r\n\t\t\t\tcount++;\r\n\t\t\t}\r\n\t\t\treturn count;\r\n\t\t},\r\n\r\n\t\thideErrors: function() {\r\n\t\t\tthis.hideThese( this.toHide );\r\n\t\t},\r\n\r\n\t\thideThese: function( errors ) {\r\n\t\t\terrors.not( this.containers ).text( \"\" );\r\n\t\t\tthis.addWrapper( errors ).hide();\r\n\t\t},\r\n\r\n\t\tvalid: function() {\r\n\t\t\treturn this.size() === 0;\r\n\t\t},\r\n\r\n\t\tsize: function() {\r\n\t\t\treturn this.errorList.length;\r\n\t\t},\r\n\r\n\t\tfocusInvalid: function() {\r\n\t\t\tif ( this.settings.focusInvalid ) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])\r\n\t\t\t\t\t.filter( \":visible\" )\r\n\t\t\t\t\t.focus()\r\n\t\t\t\t\t// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find\r\n\t\t\t\t\t.trigger( \"focusin\" );\r\n\t\t\t\t} catch ( e ) {\r\n\t\t\t\t\t// ignore IE throwing errors when focusing hidden elements\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tfindLastActive: function() {\r\n\t\t\tvar lastActive = this.lastActive;\r\n\t\t\treturn lastActive && $.grep( this.errorList, function( n ) {\r\n\t\t\t\treturn n.element.name === lastActive.name;\r\n\t\t\t}).length === 1 && lastActive;\r\n\t\t},\r\n\r\n\t\telements: function() {\r\n\t\t\tvar validator = this,\r\n\t\t\t\trulesCache = {};\r\n\r\n\t\t\t// select all valid inputs inside the form (no submit or reset buttons)\r\n\t\t\treturn $( this.currentForm )\r\n\t\t\t.find( \"input, select, textarea\" )\r\n\t\t\t.not( \":submit, :reset, :image, :disabled\" )\r\n\t\t\t.not( this.settings.ignore )\r\n\t\t\t.filter( function() {\r\n\t\t\t\tif ( !this.name && validator.settings.debug && window.console ) {\r\n\t\t\t\t\tconsole.error( \"%o has no name assigned\", this );\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// select only the first element for each name, and only those with rules specified\r\n\t\t\t\tif ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\r\n\t\t\t\trulesCache[ this.name ] = true;\r\n\t\t\t\treturn true;\r\n\t\t\t});\r\n\t\t},\r\n\r\n\t\tclean: function( selector ) {\r\n\t\t\treturn $( selector )[ 0 ];\r\n\t\t},\r\n\r\n\t\terrors: function() {\r\n\t\t\tvar errorClass = this.settings.errorClass.split( \" \" ).join( \".\" );\r\n\t\t\treturn $( this.settings.errorElement + \".\" + errorClass, this.errorContext );\r\n\t\t},\r\n\r\n\t\treset: function() {\r\n\t\t\tthis.successList = [];\r\n\t\t\tthis.errorList = [];\r\n\t\t\tthis.errorMap = {};\r\n\t\t\tthis.toShow = $( [] );\r\n\t\t\tthis.toHide = $( [] );\r\n\t\t\tthis.currentElements = $( [] );\r\n\t\t},\r\n\r\n\t\tprepareForm: function() {\r\n\t\t\tthis.reset();\r\n\t\t\tthis.toHide = this.errors().add( this.containers );\r\n\t\t},\r\n\r\n\t\tprepareElement: function( element ) {\r\n\t\t\tthis.reset();\r\n\t\t\tthis.toHide = this.errorsFor( element );\r\n\t\t},\r\n\r\n\t\telementValue: function( element ) {\r\n\t\t\tvar val,\r\n\t\t\t\t$element = $( element ),\r\n\t\t\t\ttype = element.type;\r\n\r\n\t\t\tif ( type === \"radio\" || type === \"checkbox\" ) {\r\n\t\t\t\treturn this.findByName( element.name ).filter(\":checked\").val();\r\n\t\t\t} else if ( type === \"number\" && typeof element.validity !== \"undefined\" ) {\r\n\t\t\t\treturn element.validity.badInput ? false : $element.val();\r\n\t\t\t}\r\n\r\n\t\t\tval = $element.val();\r\n\t\t\tif ( typeof val === \"string\" ) {\r\n\t\t\t\treturn val.replace(/\\r/g, \"\" );\r\n\t\t\t}\r\n\t\t\treturn val;\r\n\t\t},\r\n\r\n\t\tcheck: function( element ) {\r\n\t\t\telement = this.validationTargetFor( this.clean( element ) );\r\n\r\n\t\t\tvar rules = $( element ).rules(),\r\n\t\t\t\trulesCount = $.map( rules, function( n, i ) {\r\n\t\t\t\t\treturn i;\r\n\t\t\t\t}).length,\r\n\t\t\t\tdependencyMismatch = false,\r\n\t\t\t\tval = this.elementValue( element ),\r\n\t\t\t\tresult, method, rule;\r\n\r\n\t\t\tfor ( method in rules ) {\r\n\t\t\t\trule = { method: method, parameters: rules[ method ] };\r\n\t\t\t\ttry {\r\n\r\n\t\t\t\t\tresult = $.validator.methods[ method ].call( this, val, element, rule.parameters );\r\n\r\n\t\t\t\t\t// if a method indicates that the field is optional and therefore valid,\r\n\t\t\t\t\t// don't mark it as valid when there are no other rules\r\n\t\t\t\t\tif ( result === \"dependency-mismatch\" && rulesCount === 1 ) {\r\n\t\t\t\t\t\tdependencyMismatch = true;\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdependencyMismatch = false;\r\n\r\n\t\t\t\t\tif ( result === \"pending\" ) {\r\n\t\t\t\t\t\tthis.toHide = this.toHide.not( this.errorsFor( element ) );\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( !result ) {\r\n\t\t\t\t\t\tthis.formatAndAdd( element, rule );\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch ( e ) {\r\n\t\t\t\t\tif ( this.settings.debug && window.console ) {\r\n\t\t\t\t\t\tconsole.log( \"Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\", e );\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif ( e instanceof TypeError ) {\r\n\t\t\t\t\t\te.message += \". Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tthrow e;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif ( dependencyMismatch ) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif ( this.objectLength( rules ) ) {\r\n\t\t\t\tthis.successList.push( element );\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t},\r\n\r\n\t\t// return the custom message for the given element and validation method\r\n\t\t// specified in the element's HTML5 data attribute\r\n\t\t// return the generic message if present and no method specific message is present\r\n\t\tcustomDataMessage: function( element, method ) {\r\n\t\t\treturn $( element ).data( \"msg\" + method.charAt( 0 ).toUpperCase() +\r\n\t\t\t\tmethod.substring( 1 ).toLowerCase() ) || $( element ).data( \"msg\" );\r\n\t\t},\r\n\r\n\t\t// return the custom message for the given element name and validation method\r\n\t\tcustomMessage: function( name, method ) {\r\n\t\t\tvar m = this.settings.messages[ name ];\r\n\t\t\treturn m && ( m.constructor === String ? m : m[ method ]);\r\n\t\t},\r\n\r\n\t\t// return the first defined argument, allowing empty strings\r\n\t\tfindDefined: function() {\r\n\t\t\tfor ( var i = 0; i < arguments.length; i++) {\r\n\t\t\t\tif ( arguments[ i ] !== undefined ) {\r\n\t\t\t\t\treturn arguments[ i ];\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn undefined;\r\n\t\t},\r\n\r\n\t\tdefaultMessage: function( element, method ) {\r\n\t\t\treturn this.findDefined(\r\n\t\t\t\tthis.customMessage( element.name, method ),\r\n\t\t\t\tthis.customDataMessage( element, method ),\r\n\t\t\t\t// title is never undefined, so handle empty string as undefined\r\n\t\t\t\t!this.settings.ignoreTitle && element.title || undefined,\r\n\t\t\t\t$.validator.messages[ method ],\r\n\t\t\t\t\"Warning: No message defined for \" + element.name + \"\"\r\n\t\t\t);\r\n\t\t},\r\n\r\n\t\tformatAndAdd: function( element, rule ) {\r\n\t\t\tvar message = this.defaultMessage( element, rule.method ),\r\n\t\t\t\ttheregex = /\\$?\\{(\\d+)\\}/g;\r\n\t\t\tif ( typeof message === \"function\" ) {\r\n\t\t\t\tmessage = message.call( this, rule.parameters, element );\r\n\t\t\t} else if ( theregex.test( message ) ) {\r\n\t\t\t\tmessage = $.validator.format( message.replace( theregex, \"{$1}\" ), rule.parameters );\r\n\t\t\t}\r\n\t\t\tthis.errorList.push({\r\n\t\t\t\tmessage: message,\r\n\t\t\t\telement: element,\r\n\t\t\t\tmethod: rule.method\r\n\t\t\t});\r\n\r\n\t\t\tthis.errorMap[ element.name ] = message;\r\n\t\t\tthis.submitted[ element.name ] = message;\r\n\t\t},\r\n\r\n\t\taddWrapper: function( toToggle ) {\r\n\t\t\tif ( this.settings.wrapper ) {\r\n\t\t\t\ttoToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );\r\n\t\t\t}\r\n\t\t\treturn toToggle;\r\n\t\t},\r\n\r\n\t\tdefaultShowErrors: function() {\r\n\t\t\tvar i, elements, error;\r\n\t\t\tfor ( i = 0; this.errorList[ i ]; i++ ) {\r\n\t\t\t\terror = this.errorList[ i ];\r\n\t\t\t\tif ( this.settings.highlight ) {\r\n\t\t\t\t\tthis.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );\r\n\t\t\t\t}\r\n\t\t\t\tthis.showLabel( error.element, error.message );\r\n\t\t\t}\r\n\t\t\tif ( this.errorList.length ) {\r\n\t\t\t\tthis.toShow = this.toShow.add( this.containers );\r\n\t\t\t}\r\n\t\t\tif ( this.settings.success ) {\r\n\t\t\t\tfor ( i = 0; this.successList[ i ]; i++ ) {\r\n\t\t\t\t\tthis.showLabel( this.successList[ i ] );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif ( this.settings.unhighlight ) {\r\n\t\t\t\tfor ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {\r\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthis.toHide = this.toHide.not( this.toShow );\r\n\t\t\tthis.hideErrors();\r\n\t\t\tthis.addWrapper( this.toShow ).show();\r\n\t\t},\r\n\r\n\t\tvalidElements: function() {\r\n\t\t\treturn this.currentElements.not( this.invalidElements() );\r\n\t\t},\r\n\r\n\t\tinvalidElements: function() {\r\n\t\t\treturn $( this.errorList ).map(function() {\r\n\t\t\t\treturn this.element;\r\n\t\t\t});\r\n\t\t},\r\n\r\n\t\tshowLabel: function( element, message ) {\r\n\t\t\tvar place, group, errorID,\r\n\t\t\t\terror = this.errorsFor( element ),\r\n\t\t\t\telementID = this.idOrName( element ),\r\n\t\t\t\tdescribedBy = $( element ).attr( \"aria-describedby\" );\r\n\t\t\tif ( error.length ) {\r\n\t\t\t\t// refresh error/success class\r\n\t\t\t\terror.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );\r\n\t\t\t\t// replace message on existing label\r\n\t\t\t\terror.html( message );\r\n\t\t\t} else {\r\n\t\t\t\t// create error element\r\n\t\t\t\terror = $( \"<\" + this.settings.errorElement + \">\" )\r\n\t\t\t\t\t.attr( \"id\", elementID + \"-error\" )\r\n\t\t\t\t\t.addClass( this.settings.errorClass )\r\n\t\t\t\t\t.html( message || \"\" );\r\n\r\n\t\t\t\t// Maintain reference to the element to be placed into the DOM\r\n\t\t\t\tplace = error;\r\n\t\t\t\tif ( this.settings.wrapper ) {\r\n\t\t\t\t\t// make sure the element is visible, even in IE\r\n\t\t\t\t\t// actually showing the wrapped element is handled elsewhere\r\n\t\t\t\t\tplace = error.hide().show().wrap( \"<\" + this.settings.wrapper + \"/>\" ).parent();\r\n\t\t\t\t}\r\n\t\t\t\tif ( this.labelContainer.length ) {\r\n\t\t\t\t\tthis.labelContainer.append( place );\r\n\t\t\t\t} else if ( this.settings.errorPlacement ) {\r\n\t\t\t\t\tthis.settings.errorPlacement( place, $( element ) );\r\n\t\t\t\t} else {\r\n\t\t\t\t\tplace.insertAfter( element );\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Link error back to the element\r\n\t\t\t\tif ( error.is( \"label\" ) ) {\r\n\t\t\t\t\t// If the error is a label, then associate using 'for'\r\n\t\t\t\t\terror.attr( \"for\", elementID );\r\n\t\t\t\t} else if ( error.parents( \"label[for='\" + elementID + \"']\" ).length === 0 ) {\r\n\t\t\t\t\t// If the element is not a child of an associated label, then it's necessary\r\n\t\t\t\t\t// to explicitly apply aria-describedby\r\n\r\n\t\t\t\t\terrorID = error.attr( \"id\" ).replace( /(:|\\.|\\[|\\]|\\$)/g, \"\\\\$1\");\r\n\t\t\t\t\t// Respect existing non-error aria-describedby\r\n\t\t\t\t\tif ( !describedBy ) {\r\n\t\t\t\t\t\tdescribedBy = errorID;\r\n\t\t\t\t\t} else if ( !describedBy.match( new RegExp( \"\\\\b\" + errorID + \"\\\\b\" ) ) ) {\r\n\t\t\t\t\t\t// Add to end of list if not already present\r\n\t\t\t\t\t\tdescribedBy += \" \" + errorID;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$( element ).attr( \"aria-describedby\", describedBy );\r\n\r\n\t\t\t\t\t// If this element is grouped, then assign to all elements in the same group\r\n\t\t\t\t\tgroup = this.groups[ element.name ];\r\n\t\t\t\t\tif ( group ) {\r\n\t\t\t\t\t\t$.each( this.groups, function( name, testgroup ) {\r\n\t\t\t\t\t\t\tif ( testgroup === group ) {\r\n\t\t\t\t\t\t\t\t$( \"[name='\" + name + \"']\", this.currentForm )\r\n\t\t\t\t\t\t\t\t\t.attr( \"aria-describedby\", error.attr( \"id\" ) );\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif ( !message && this.settings.success ) {\r\n\t\t\t\terror.text( \"\" );\r\n\t\t\t\tif ( typeof this.settings.success === \"string\" ) {\r\n\t\t\t\t\terror.addClass( this.settings.success );\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.settings.success( error, element );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthis.toShow = this.toShow.add( error );\r\n\t\t},\r\n\r\n\t\terrorsFor: function( element ) {\r\n\t\t\tvar name = this.idOrName( element ),\r\n\t\t\t\tdescriber = $( element ).attr( \"aria-describedby\" ),\r\n\t\t\t\tselector = \"label[for='\" + name + \"'], label[for='\" + name + \"'] *\";\r\n\r\n\t\t\t// aria-describedby should directly reference the error element\r\n\t\t\tif ( describer ) {\r\n\t\t\t\tselector = selector + \", #\" + describer.replace( /\\s+/g, \", #\" );\r\n\t\t\t}\r\n\t\t\treturn this\r\n\t\t\t\t.errors()\r\n\t\t\t\t.filter( selector );\r\n\t\t},\r\n\r\n\t\tidOrName: function( element ) {\r\n\t\t\treturn this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );\r\n\t\t},\r\n\r\n\t\tvalidationTargetFor: function( element ) {\r\n\r\n\t\t\t// If radio/checkbox, validate first element in group instead\r\n\t\t\tif ( this.checkable( element ) ) {\r\n\t\t\t\telement = this.findByName( element.name );\r\n\t\t\t}\r\n\r\n\t\t\t// Always apply ignore filter\r\n\t\t\treturn $( element ).not( this.settings.ignore )[ 0 ];\r\n\t\t},\r\n\r\n\t\tcheckable: function( element ) {\r\n\t\t\treturn ( /radio|checkbox/i ).test( element.type );\r\n\t\t},\r\n\r\n\t\tfindByName: function( name ) {\r\n\t\t\treturn $( this.currentForm ).find( \"[name='\" + name + \"']\" );\r\n\t\t},\r\n\r\n\t\tgetLength: function( value, element ) {\r\n\t\t\tswitch ( element.nodeName.toLowerCase() ) {\r\n\t\t\tcase \"select\":\r\n\t\t\t\treturn $( \"option:selected\", element ).length;\r\n\t\t\tcase \"input\":\r\n\t\t\t\tif ( this.checkable( element ) ) {\r\n\t\t\t\t\treturn this.findByName( element.name ).filter( \":checked\" ).length;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn value.length;\r\n\t\t},\r\n\r\n\t\tdepend: function( param, element ) {\r\n\t\t\treturn this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;\r\n\t\t},\r\n\r\n\t\tdependTypes: {\r\n\t\t\t\"boolean\": function( param ) {\r\n\t\t\t\treturn param;\r\n\t\t\t},\r\n\t\t\t\"string\": function( param, element ) {\r\n\t\t\t\treturn !!$( param, element.form ).length;\r\n\t\t\t},\r\n\t\t\t\"function\": function( param, element ) {\r\n\t\t\t\treturn param( element );\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\toptional: function( element ) {\r\n\t\t\tvar val = this.elementValue( element );\r\n\t\t\treturn !$.validator.methods.required.call( this, val, element ) && \"dependency-mismatch\";\r\n\t\t},\r\n\r\n\t\tstartRequest: function( element ) {\r\n\t\t\tif ( !this.pending[ element.name ] ) {\r\n\t\t\t\tthis.pendingRequest++;\r\n\t\t\t\tthis.pending[ element.name ] = true;\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tstopRequest: function( element, valid ) {\r\n\t\t\tthis.pendingRequest--;\r\n\t\t\t// sometimes synchronization fails, make sure pendingRequest is never < 0\r\n\t\t\tif ( this.pendingRequest < 0 ) {\r\n\t\t\t\tthis.pendingRequest = 0;\r\n\t\t\t}\r\n\t\t\tdelete this.pending[ element.name ];\r\n\t\t\tif ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {\r\n\t\t\t\t$( this.currentForm ).submit();\r\n\t\t\t\tthis.formSubmitted = false;\r\n\t\t\t} else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {\r\n\t\t\t\t$( this.currentForm ).triggerHandler( \"invalid-form\", [ this ]);\r\n\t\t\t\tthis.formSubmitted = false;\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tpreviousValue: function( element ) {\r\n\t\t\treturn $.data( element, \"previousValue\" ) || $.data( element, \"previousValue\", {\r\n\t\t\t\told: null,\r\n\t\t\t\tvalid: true,\r\n\t\t\t\tmessage: this.defaultMessage( element, \"remote\" )\r\n\t\t\t});\r\n\t\t},\r\n\r\n\t\t// cleans up all forms and elements, removes validator-specific events\r\n\t\tdestroy: function() {\r\n\t\t\tthis.resetForm();\r\n\r\n\t\t\t$( this.currentForm )\r\n\t\t\t\t.off( \".validate\" )\r\n\t\t\t\t.removeData( \"validator\" );\r\n\t\t}\r\n\r\n\t},\r\n\r\n\tclassRuleSettings: {\r\n\t\trequired: { required: true },\r\n\t\temail: { email: true },\r\n\t\turl: { url: true },\r\n\t\tdate: { date: true },\r\n\t\tdateISO: { dateISO: true },\r\n\t\tnumber: { number: true },\r\n\t\tdigits: { digits: true },\r\n\t\tcreditcard: { creditcard: true }\r\n\t},\r\n\r\n\taddClassRules: function( className, rules ) {\r\n\t\tif ( className.constructor === String ) {\r\n\t\t\tthis.classRuleSettings[ className ] = rules;\r\n\t\t} else {\r\n\t\t\t$.extend( this.classRuleSettings, className );\r\n\t\t}\r\n\t},\r\n\r\n\tclassRules: function( element ) {\r\n\t\tvar rules = {},\r\n\t\t\tclasses = $( element ).attr( \"class\" );\r\n\r\n\t\tif ( classes ) {\r\n\t\t\t$.each( classes.split( \" \" ), function() {\r\n\t\t\t\tif ( this in $.validator.classRuleSettings ) {\r\n\t\t\t\t\t$.extend( rules, $.validator.classRuleSettings[ this ]);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t\treturn rules;\r\n\t},\r\n\r\n\tnormalizeAttributeRule: function( rules, type, method, value ) {\r\n\r\n\t\t// convert the value to a number for number inputs, and for text for backwards compability\r\n\t\t// allows type=\"date\" and others to be compared as strings\r\n\t\tif ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {\r\n\t\t\tvalue = Number( value );\r\n\r\n\t\t\t// Support Opera Mini, which returns NaN for undefined minlength\r\n\t\t\tif ( isNaN( value ) ) {\r\n\t\t\t\tvalue = undefined;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif ( value || value === 0 ) {\r\n\t\t\trules[ method ] = value;\r\n\t\t} else if ( type === method && type !== \"range\" ) {\r\n\r\n\t\t\t// exception: the jquery validate 'range' method\r\n\t\t\t// does not test for the html5 'range' type\r\n\t\t\trules[ method ] = true;\r\n\t\t}\r\n\t},\r\n\r\n\tattributeRules: function( element ) {\r\n\t\tvar rules = {},\r\n\t\t\t$element = $( element ),\r\n\t\t\ttype = element.getAttribute( \"type\" ),\r\n\t\t\tmethod, value;\r\n\r\n\t\tfor ( method in $.validator.methods ) {\r\n\r\n\t\t\t// support for in both html5 and older browsers\r\n\t\t\tif ( method === \"required\" ) {\r\n\t\t\t\tvalue = element.getAttribute( method );\r\n\r\n\t\t\t\t// Some browsers return an empty string for the required attribute\r\n\t\t\t\t// and non-HTML5 browsers might have required=\"\" markup\r\n\t\t\t\tif ( value === \"\" ) {\r\n\t\t\t\t\tvalue = true;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// force non-HTML5 browsers to return bool\r\n\t\t\t\tvalue = !!value;\r\n\t\t\t} else {\r\n\t\t\t\tvalue = $element.attr( method );\r\n\t\t\t}\r\n\r\n\t\t\tthis.normalizeAttributeRule( rules, type, method, value );\r\n\t\t}\r\n\r\n\t\t// maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs\r\n\t\tif ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {\r\n\t\t\tdelete rules.maxlength;\r\n\t\t}\r\n\r\n\t\treturn rules;\r\n\t},\r\n\r\n\tdataRules: function( element ) {\r\n\t\tvar rules = {},\r\n\t\t\t$element = $( element ),\r\n\t\t\ttype = element.getAttribute( \"type\" ),\r\n\t\t\tmethod, value;\r\n\r\n\t\tfor ( method in $.validator.methods ) {\r\n\t\t\tvalue = $element.data( \"rule\" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );\r\n\t\t\tthis.normalizeAttributeRule( rules, type, method, value );\r\n\t\t}\r\n\t\treturn rules;\r\n\t},\r\n\r\n\tstaticRules: function( element ) {\r\n\t\tvar rules = {},\r\n\t\t\tvalidator = $.data( element.form, \"validator\" );\r\n\r\n\t\tif ( validator.settings.rules ) {\r\n\t\t\trules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};\r\n\t\t}\r\n\t\treturn rules;\r\n\t},\r\n\r\n\tnormalizeRules: function( rules, element ) {\r\n\t\t// handle dependency check\r\n\t\t$.each( rules, function( prop, val ) {\r\n\t\t\t// ignore rule when param is explicitly false, eg. required:false\r\n\t\t\tif ( val === false ) {\r\n\t\t\t\tdelete rules[ prop ];\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif ( val.param || val.depends ) {\r\n\t\t\t\tvar keepRule = true;\r\n\t\t\t\tswitch ( typeof val.depends ) {\r\n\t\t\t\tcase \"string\":\r\n\t\t\t\t\tkeepRule = !!$( val.depends, element.form ).length;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase \"function\":\r\n\t\t\t\t\tkeepRule = val.depends.call( element, element );\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tif ( keepRule ) {\r\n\t\t\t\t\trules[ prop ] = val.param !== undefined ? val.param : true;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tdelete rules[ prop ];\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// evaluate parameters\r\n\t\t$.each( rules, function( rule, parameter ) {\r\n\t\t\trules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;\r\n\t\t});\r\n\r\n\t\t// clean number parameters\r\n\t\t$.each([ \"minlength\", \"maxlength\" ], function() {\r\n\t\t\tif ( rules[ this ] ) {\r\n\t\t\t\trules[ this ] = Number( rules[ this ] );\r\n\t\t\t}\r\n\t\t});\r\n\t\t$.each([ \"rangelength\", \"range\" ], function() {\r\n\t\t\tvar parts;\r\n\t\t\tif ( rules[ this ] ) {\r\n\t\t\t\tif ( $.isArray( rules[ this ] ) ) {\r\n\t\t\t\t\trules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];\r\n\t\t\t\t} else if ( typeof rules[ this ] === \"string\" ) {\r\n\t\t\t\t\tparts = rules[ this ].replace(/[\\[\\]]/g, \"\" ).split( /[\\s,]+/ );\r\n\t\t\t\t\trules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif ( $.validator.autoCreateRanges ) {\r\n\t\t\t// auto-create ranges\r\n\t\t\tif ( rules.min != null && rules.max != null ) {\r\n\t\t\t\trules.range = [ rules.min, rules.max ];\r\n\t\t\t\tdelete rules.min;\r\n\t\t\t\tdelete rules.max;\r\n\t\t\t}\r\n\t\t\tif ( rules.minlength != null && rules.maxlength != null ) {\r\n\t\t\t\trules.rangelength = [ rules.minlength, rules.maxlength ];\r\n\t\t\t\tdelete rules.minlength;\r\n\t\t\t\tdelete rules.maxlength;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn rules;\r\n\t},\r\n\r\n\t// Converts a simple string to a {string: true} rule, e.g., \"required\" to {required:true}\r\n\tnormalizeRule: function( data ) {\r\n\t\tif ( typeof data === \"string\" ) {\r\n\t\t\tvar transformed = {};\r\n\t\t\t$.each( data.split( /\\s/ ), function() {\r\n\t\t\t\ttransformed[ this ] = true;\r\n\t\t\t});\r\n\t\t\tdata = transformed;\r\n\t\t}\r\n\t\treturn data;\r\n\t},\r\n\r\n\t// http://jqueryvalidation.org/jQuery.validator.addMethod/\r\n\taddMethod: function( name, method, message ) {\r\n\t\t$.validator.methods[ name ] = method;\r\n\t\t$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];\r\n\t\tif ( method.length < 3 ) {\r\n\t\t\t$.validator.addClassRules( name, $.validator.normalizeRule( name ) );\r\n\t\t}\r\n\t},\r\n\r\n\tmethods: {\r\n\r\n\t\t// http://jqueryvalidation.org/required-method/\r\n\t\trequired: function( value, element, param ) {\r\n\t\t\t// check if dependency is met\r\n\t\t\tif ( !this.depend( param, element ) ) {\r\n\t\t\t\treturn \"dependency-mismatch\";\r\n\t\t\t}\r\n\t\t\tif ( element.nodeName.toLowerCase() === \"select\" ) {\r\n\t\t\t\t// could be an array for select-multiple or a string, both are fine this way\r\n\t\t\t\tvar val = $( element ).val();\r\n\t\t\t\treturn val && val.length > 0;\r\n\t\t\t}\r\n\t\t\tif ( this.checkable( element ) ) {\r\n\t\t\t\treturn this.getLength( value, element ) > 0;\r\n\t\t\t}\r\n\t\t\treturn value.length > 0;\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/email-method/\r\n\t\temail: function( value, element ) {\r\n\t\t\t// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address\r\n\t\t\t// Retrieved 2014-01-14\r\n\t\t\t// If you have a problem with this implementation, report a bug against the above spec\r\n\t\t\t// Or use custom methods to implement your own email validation\r\n\t\t\treturn this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/url-method/\r\n\t\turl: function( value, element ) {\r\n\r\n\t\t\t// Copyright (c) 2010-2013 Diego Perini, MIT licensed\r\n\t\t\t// https://gist.github.com/dperini/729294\r\n\t\t\t// see also https://mathiasbynens.be/demo/url-regex\r\n\t\t\t// modified to allow protocol-relative URLs\r\n\t\t\treturn this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})).?)(?::\\d{2,5})?(?:[/?#]\\S*)?$/i.test( value );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/date-method/\r\n\t\tdate: function( value, element ) {\r\n\t\t\treturn this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/dateISO-method/\r\n\t\tdateISO: function( value, element ) {\r\n\t\t\treturn this.optional( element ) || /^\\d{4}[\\/\\-](0?[1-9]|1[012])[\\/\\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/number-method/\r\n\t\tnumber: function( value, element ) {\r\n\t\t\treturn this.optional( element ) || /^(?:-?\\d+|-?\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$/.test( value );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/digits-method/\r\n\t\tdigits: function( value, element ) {\r\n\t\t\treturn this.optional( element ) || /^\\d+$/.test( value );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/creditcard-method/\r\n\t\t// based on http://en.wikipedia.org/wiki/Luhn_algorithm\r\n\t\tcreditcard: function( value, element ) {\r\n\t\t\tif ( this.optional( element ) ) {\r\n\t\t\t\treturn \"dependency-mismatch\";\r\n\t\t\t}\r\n\t\t\t// accept only spaces, digits and dashes\r\n\t\t\tif ( /[^0-9 \\-]+/.test( value ) ) {\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tvar nCheck = 0,\r\n\t\t\t\tnDigit = 0,\r\n\t\t\t\tbEven = false,\r\n\t\t\t\tn, cDigit;\r\n\r\n\t\t\tvalue = value.replace( /\\D/g, \"\" );\r\n\r\n\t\t\t// Basing min and max length on\r\n\t\t\t// http://developer.ean.com/general_info/Valid_Credit_Card_Types\r\n\t\t\tif ( value.length < 13 || value.length > 19 ) {\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\r\n\t\t\tfor ( n = value.length - 1; n >= 0; n--) {\r\n\t\t\t\tcDigit = value.charAt( n );\r\n\t\t\t\tnDigit = parseInt( cDigit, 10 );\r\n\t\t\t\tif ( bEven ) {\r\n\t\t\t\t\tif ( ( nDigit *= 2 ) > 9 ) {\r\n\t\t\t\t\t\tnDigit -= 9;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tnCheck += nDigit;\r\n\t\t\t\tbEven = !bEven;\r\n\t\t\t}\r\n\r\n\t\t\treturn ( nCheck % 10 ) === 0;\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/minlength-method/\r\n\t\tminlength: function( value, element, param ) {\r\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\r\n\t\t\treturn this.optional( element ) || length >= param;\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/maxlength-method/\r\n\t\tmaxlength: function( value, element, param ) {\r\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\r\n\t\t\treturn this.optional( element ) || length <= param;\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/rangelength-method/\r\n\t\trangelength: function( value, element, param ) {\r\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\r\n\t\t\treturn this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/min-method/\r\n\t\tmin: function( value, element, param ) {\r\n\t\t\treturn this.optional( element ) || value >= param;\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/max-method/\r\n\t\tmax: function( value, element, param ) {\r\n\t\t\treturn this.optional( element ) || value <= param;\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/range-method/\r\n\t\trange: function( value, element, param ) {\r\n\t\t\treturn this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/equalTo-method/\r\n\t\tequalTo: function( value, element, param ) {\r\n\t\t\t// bind to the blur event of the target in order to revalidate whenever the target field is updated\r\n\t\t\t// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead\r\n\t\t\tvar target = $( param );\r\n\t\t\tif ( this.settings.onfocusout ) {\r\n\t\t\t\ttarget.off( \".validate-equalTo\" ).on( \"blur.validate-equalTo\", function() {\r\n\t\t\t\t\t$( element ).valid();\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\treturn value === target.val();\r\n\t\t},\r\n\r\n\t\t// http://jqueryvalidation.org/remote-method/\r\n\t\tremote: function( value, element, param ) {\r\n\t\t\tif ( this.optional( element ) ) {\r\n\t\t\t\treturn \"dependency-mismatch\";\r\n\t\t\t}\r\n\r\n\t\t\tvar previous = this.previousValue( element ),\r\n\t\t\t\tvalidator, data;\r\n\r\n\t\t\tif (!this.settings.messages[ element.name ] ) {\r\n\t\t\t\tthis.settings.messages[ element.name ] = {};\r\n\t\t\t}\r\n\t\t\tprevious.originalMessage = this.settings.messages[ element.name ].remote;\r\n\t\t\tthis.settings.messages[ element.name ].remote = previous.message;\r\n\r\n\t\t\tparam = typeof param === \"string\" && { url: param } || param;\r\n\r\n\t\t\tif ( previous.old === value ) {\r\n\t\t\t\treturn previous.valid;\r\n\t\t\t}\r\n\r\n\t\t\tprevious.old = value;\r\n\t\t\tvalidator = this;\r\n\t\t\tthis.startRequest( element );\r\n\t\t\tdata = {};\r\n\t\t\tdata[ element.name ] = value;\r\n\t\t\t$.ajax( $.extend( true, {\r\n\t\t\t\tmode: \"abort\",\r\n\t\t\t\tport: \"validate\" + element.name,\r\n\t\t\t\tdataType: \"json\",\r\n\t\t\t\tdata: data,\r\n\t\t\t\tcontext: validator.currentForm,\r\n\t\t\t\tsuccess: function( response ) {\r\n\t\t\t\t\tvar valid = response === true || response === \"true\",\r\n\t\t\t\t\t\terrors, message, submitted;\r\n\r\n\t\t\t\t\tvalidator.settings.messages[ element.name ].remote = previous.originalMessage;\r\n\t\t\t\t\tif ( valid ) {\r\n\t\t\t\t\t\tsubmitted = validator.formSubmitted;\r\n\t\t\t\t\t\tvalidator.prepareElement( element );\r\n\t\t\t\t\t\tvalidator.formSubmitted = submitted;\r\n\t\t\t\t\t\tvalidator.successList.push( element );\r\n\t\t\t\t\t\tdelete validator.invalid[ element.name ];\r\n\t\t\t\t\t\tvalidator.showErrors();\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\terrors = {};\r\n\t\t\t\t\t\tmessage = response || validator.defaultMessage( element, \"remote\" );\r\n\t\t\t\t\t\terrors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;\r\n\t\t\t\t\t\tvalidator.invalid[ element.name ] = true;\r\n\t\t\t\t\t\tvalidator.showErrors( errors );\r\n\t\t\t\t\t}\r\n\t\t\t\t\tprevious.valid = valid;\r\n\t\t\t\t\tvalidator.stopRequest( element, valid );\r\n\t\t\t\t}\r\n\t\t\t}, param ) );\r\n\t\t\treturn \"pending\";\r\n\t\t}\r\n\t}\r\n\r\n});\r\n\r\n// ajax mode: abort\r\n// usage: $.ajax({ mode: \"abort\"[, port: \"uniqueport\"]});\r\n// if mode:\"abort\" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()\r\n\r\nvar pendingRequests = {},\r\n\tajax;\r\n// Use a prefilter if available (1.5+)\r\nif ( $.ajaxPrefilter ) {\r\n\t$.ajaxPrefilter(function( settings, _, xhr ) {\r\n\t\tvar port = settings.port;\r\n\t\tif ( settings.mode === \"abort\" ) {\r\n\t\t\tif ( pendingRequests[port] ) {\r\n\t\t\t\tpendingRequests[port].abort();\r\n\t\t\t}\r\n\t\t\tpendingRequests[port] = xhr;\r\n\t\t}\r\n\t});\r\n} else {\r\n\t// Proxy ajax\r\n\tajax = $.ajax;\r\n\t$.ajax = function( settings ) {\r\n\t\tvar mode = ( \"mode\" in settings ? settings : $.ajaxSettings ).mode,\r\n\t\t\tport = ( \"port\" in settings ? settings : $.ajaxSettings ).port;\r\n\t\tif ( mode === \"abort\" ) {\r\n\t\t\tif ( pendingRequests[port] ) {\r\n\t\t\t\tpendingRequests[port].abort();\r\n\t\t\t}\r\n\t\t\tpendingRequests[port] = ajax.apply(this, arguments);\r\n\t\t\treturn pendingRequests[port];\r\n\t\t}\r\n\t\treturn ajax.apply(this, arguments);\r\n\t};\r\n}\r\n\r\n}));","/**\r\n * Galleria v 1.4.2 2014-08-07\r\n * http://galleria.io\r\n *\r\n * Licensed under the MIT license\r\n * https://raw.github.com/aino/galleria/master/LICENSE\r\n *\r\n */\r\n\r\n(function( $, window, Galleria, undef ) {\r\n\r\n/*global jQuery, navigator, Image, module, define */\r\n\r\n// some references\r\nvar doc = window.document,\r\n $doc = $( doc ),\r\n $win = $( window ),\r\n\r\n// native prototypes\r\n protoArray = Array.prototype,\r\n\r\n// internal constants\r\n VERSION = 1.41,\r\n DEBUG = true,\r\n TIMEOUT = 30000,\r\n DUMMY = false,\r\n NAV = navigator.userAgent.toLowerCase(),\r\n HASH = window.location.hash.replace(/#\\//, ''),\r\n PROT = window.location.protocol,\r\n M = Math,\r\n F = function(){},\r\n FALSE = function() { return false; },\r\n IE = (function() {\r\n\r\n var v = 3,\r\n div = doc.createElement( 'div' ),\r\n all = div.getElementsByTagName( 'i' );\r\n\r\n do {\r\n div.innerHTML = '';\r\n } while ( all[0] );\r\n\r\n return v > 4 ? v : doc.documentMode || undef;\r\n\r\n }() ),\r\n DOM = function() {\r\n return {\r\n html: doc.documentElement,\r\n body: doc.body,\r\n head: doc.getElementsByTagName('head')[0],\r\n title: doc.title\r\n };\r\n },\r\n IFRAME = window.parent !== window.self,\r\n\r\n // list of Galleria events\r\n _eventlist = 'data ready thumbnail loadstart loadfinish image play pause progress ' +\r\n 'fullscreen_enter fullscreen_exit idle_enter idle_exit rescale ' +\r\n 'lightbox_open lightbox_close lightbox_image',\r\n\r\n _events = (function() {\r\n\r\n var evs = [];\r\n\r\n $.each( _eventlist.split(' '), function( i, ev ) {\r\n evs.push( ev );\r\n\r\n // legacy events\r\n if ( /_/.test( ev ) ) {\r\n evs.push( ev.replace( /_/g, '' ) );\r\n }\r\n });\r\n\r\n return evs;\r\n\r\n }()),\r\n\r\n // legacy options\r\n // allows the old my_setting syntax and converts it to camel case\r\n\r\n _legacyOptions = function( options ) {\r\n\r\n var n;\r\n\r\n if ( typeof options !== 'object' ) {\r\n\r\n // return whatever it was...\r\n return options;\r\n }\r\n\r\n $.each( options, function( key, value ) {\r\n if ( /^[a-z]+_/.test( key ) ) {\r\n n = '';\r\n $.each( key.split('_'), function( i, k ) {\r\n n += i > 0 ? k.substr( 0, 1 ).toUpperCase() + k.substr( 1 ) : k;\r\n });\r\n options[ n ] = value;\r\n delete options[ key ];\r\n }\r\n });\r\n\r\n return options;\r\n },\r\n\r\n _patchEvent = function( type ) {\r\n\r\n // allow 'image' instead of Galleria.IMAGE\r\n if ( $.inArray( type, _events ) > -1 ) {\r\n return Galleria[ type.toUpperCase() ];\r\n }\r\n\r\n return type;\r\n },\r\n\r\n // video providers\r\n _video = {\r\n youtube: {\r\n reg: /https?:\\/\\/(?:[a-zA_Z]{2,3}.)?(?:youtube\\.com\\/watch\\?)((?:[\\w\\d\\-\\_\\=]+&(?:amp;)?)*v(?:<[A-Z]+>)?=([0-9a-zA-Z\\-\\_]+))/i,\r\n embed: function() {\r\n return 'http://www.youtube.com/embed/' + this.id;\r\n },\r\n getUrl: function() {\r\n return PROT + '//gdata.youtube.com/feeds/api/videos/' + this.id + '?v=2&alt=json-in-script&callback=?';\r\n },\r\n get_thumb: function(data) {\r\n return data.entry.media$group.media$thumbnail[2].url;\r\n },\r\n get_image: function(data) {\r\n if ( data.entry.yt$hd ) {\r\n return PROT + '//img.youtube.com/vi/'+this.id+'/maxresdefault.jpg';\r\n }\r\n return data.entry.media$group.media$thumbnail[3].url;\r\n }\r\n },\r\n vimeo: {\r\n reg: /https?:\\/\\/(?:www\\.)?(vimeo\\.com)\\/(?:hd#)?([0-9]+)/i,\r\n embed: function() {\r\n return 'http://player.vimeo.com/video/' + this.id;\r\n },\r\n getUrl: function() {\r\n return PROT + '//vimeo.com/api/v2/video/' + this.id + '.json?callback=?';\r\n },\r\n get_thumb: function( data ) {\r\n return data[0].thumbnail_medium;\r\n },\r\n get_image: function( data ) {\r\n return data[0].thumbnail_large;\r\n }\r\n },\r\n dailymotion: {\r\n reg: /https?:\\/\\/(?:www\\.)?(dailymotion\\.com)\\/video\\/([^_]+)/,\r\n embed: function() {\r\n return PROT + '//www.dailymotion.com/embed/video/' + this.id;\r\n },\r\n getUrl: function() {\r\n return 'https://api.dailymotion.com/video/' + this.id + '?fields=thumbnail_240_url,thumbnail_720_url&callback=?';\r\n },\r\n get_thumb: function( data ) {\r\n return data.thumbnail_240_url;\r\n },\r\n get_image: function( data ) {\r\n return data.thumbnail_720_url;\r\n }\r\n },\r\n _inst: []\r\n },\r\n Video = function( type, id ) {\r\n\r\n for( var i=0; i<_video._inst.length; i++ ) {\r\n if ( _video._inst[i].id === id && _video._inst[i].type == type ) {\r\n return _video._inst[i];\r\n }\r\n }\r\n\r\n this.type = type;\r\n this.id = id;\r\n this.readys = [];\r\n\r\n _video._inst.push(this);\r\n\r\n var self = this;\r\n\r\n $.extend( this, _video[type] );\r\n\r\n $.getJSON( this.getUrl(), function(data) {\r\n self.data = data;\r\n $.each( self.readys, function( i, fn ) {\r\n fn( self.data );\r\n });\r\n self.readys = [];\r\n });\r\n\r\n this.getMedia = function( type, callback, fail ) {\r\n fail = fail || F;\r\n var self = this;\r\n var success = function( data ) {\r\n callback( self['get_'+type]( data ) );\r\n };\r\n try {\r\n if ( self.data ) {\r\n success( self.data );\r\n } else {\r\n self.readys.push( success );\r\n }\r\n } catch(e) {\r\n fail();\r\n }\r\n };\r\n },\r\n\r\n // utility for testing the video URL and getting the video ID\r\n _videoTest = function( url ) {\r\n var match;\r\n for ( var v in _video ) {\r\n match = url && _video[v].reg && url.match( _video[v].reg );\r\n if( match && match.length ) {\r\n return {\r\n id: match[2],\r\n provider: v\r\n };\r\n }\r\n }\r\n return false;\r\n },\r\n\r\n // native fullscreen handler\r\n _nativeFullscreen = {\r\n\r\n support: (function() {\r\n var html = DOM().html;\r\n return !IFRAME && ( html.requestFullscreen || html.msRequestFullscreen || html.mozRequestFullScreen || html.webkitRequestFullScreen );\r\n }()),\r\n\r\n callback: F,\r\n\r\n enter: function( instance, callback, elem ) {\r\n\r\n this.instance = instance;\r\n\r\n this.callback = callback || F;\r\n\r\n elem = elem || DOM().html;\r\n if ( elem.requestFullscreen ) {\r\n elem.requestFullscreen();\r\n }\r\n else if ( elem.msRequestFullscreen ) {\r\n elem.msRequestFullscreen();\r\n }\r\n else if ( elem.mozRequestFullScreen ) {\r\n elem.mozRequestFullScreen();\r\n }\r\n else if ( elem.webkitRequestFullScreen ) {\r\n elem.webkitRequestFullScreen();\r\n }\r\n },\r\n\r\n exit: function( callback ) {\r\n\r\n this.callback = callback || F;\r\n\r\n if ( doc.exitFullscreen ) {\r\n doc.exitFullscreen();\r\n }\r\n else if ( doc.msExitFullscreen ) {\r\n doc.msExitFullscreen();\r\n }\r\n else if ( doc.mozCancelFullScreen ) {\r\n doc.mozCancelFullScreen();\r\n }\r\n else if ( doc.webkitCancelFullScreen ) {\r\n doc.webkitCancelFullScreen();\r\n }\r\n },\r\n\r\n instance: null,\r\n\r\n listen: function() {\r\n\r\n if ( !this.support ) {\r\n return;\r\n }\r\n\r\n var handler = function() {\r\n\r\n if ( !_nativeFullscreen.instance ) {\r\n return;\r\n }\r\n var fs = _nativeFullscreen.instance._fullscreen;\r\n\r\n if ( doc.fullscreen || doc.mozFullScreen || doc.webkitIsFullScreen || ( doc.msFullscreenElement && doc.msFullscreenElement !== null ) ) {\r\n fs._enter( _nativeFullscreen.callback );\r\n } else {\r\n fs._exit( _nativeFullscreen.callback );\r\n }\r\n };\r\n doc.addEventListener( 'fullscreenchange', handler, false );\r\n doc.addEventListener( 'MSFullscreenChange', handler, false );\r\n doc.addEventListener( 'mozfullscreenchange', handler, false );\r\n doc.addEventListener( 'webkitfullscreenchange', handler, false );\r\n }\r\n },\r\n\r\n // the internal gallery holder\r\n _galleries = [],\r\n\r\n // the internal instance holder\r\n _instances = [],\r\n\r\n // flag for errors\r\n _hasError = false,\r\n\r\n // canvas holder\r\n _canvas = false,\r\n\r\n // instance pool, holds the galleries until themeLoad is triggered\r\n _pool = [],\r\n\r\n // Run galleries from theme trigger\r\n _loadedThemes = [],\r\n _themeLoad = function( theme ) {\r\n\r\n _loadedThemes.push(theme);\r\n\r\n // run the instances we have in the pool\r\n // and apply the last theme if not specified\r\n $.each( _pool, function( i, instance ) {\r\n if ( instance._options.theme == theme.name || (!instance._initialized && !instance._options.theme) ) {\r\n instance.theme = theme;\r\n instance._init.call( instance );\r\n }\r\n });\r\n },\r\n\r\n // the Utils singleton\r\n Utils = (function() {\r\n\r\n return {\r\n\r\n // legacy support for clearTimer\r\n clearTimer: function( id ) {\r\n $.each( Galleria.get(), function() {\r\n this.clearTimer( id );\r\n });\r\n },\r\n\r\n // legacy support for addTimer\r\n addTimer: function( id ) {\r\n $.each( Galleria.get(), function() {\r\n this.addTimer( id );\r\n });\r\n },\r\n\r\n array : function( obj ) {\r\n return protoArray.slice.call(obj, 0);\r\n },\r\n\r\n create : function( className, nodeName ) {\r\n nodeName = nodeName || 'div';\r\n var elem = doc.createElement( nodeName );\r\n elem.className = className;\r\n return elem;\r\n },\r\n\r\n removeFromArray : function( arr, elem ) {\r\n $.each(arr, function(i, el) {\r\n if ( el == elem ) {\r\n arr.splice(i, 1);\r\n return false;\r\n }\r\n });\r\n return arr;\r\n },\r\n\r\n getScriptPath : function( src ) {\r\n\r\n // the currently executing script is always the last\r\n src = src || $('script:last').attr('src');\r\n var slices = src.split('/');\r\n\r\n if (slices.length == 1) {\r\n return '';\r\n }\r\n\r\n slices.pop();\r\n\r\n return slices.join('/') + '/';\r\n },\r\n\r\n // CSS3 transitions, added in 1.2.4\r\n animate : (function() {\r\n\r\n // detect transition\r\n var transition = (function( style ) {\r\n var props = 'transition WebkitTransition MozTransition OTransition'.split(' '),\r\n i;\r\n\r\n // disable css3 animations in opera until stable\r\n if ( window.opera ) {\r\n return false;\r\n }\r\n\r\n for ( i = 0; props[i]; i++ ) {\r\n if ( typeof style[ props[ i ] ] !== 'undefined' ) {\r\n return props[ i ];\r\n }\r\n }\r\n return false;\r\n }(( doc.body || doc.documentElement).style ));\r\n\r\n // map transitionend event\r\n var endEvent = {\r\n MozTransition: 'transitionend',\r\n OTransition: 'oTransitionEnd',\r\n WebkitTransition: 'webkitTransitionEnd',\r\n transition: 'transitionend'\r\n }[ transition ];\r\n\r\n // map bezier easing conversions\r\n var easings = {\r\n _default: [0.25, 0.1, 0.25, 1],\r\n galleria: [0.645, 0.045, 0.355, 1],\r\n galleriaIn: [0.55, 0.085, 0.68, 0.53],\r\n galleriaOut: [0.25, 0.46, 0.45, 0.94],\r\n ease: [0.25, 0, 0.25, 1],\r\n linear: [0.25, 0.25, 0.75, 0.75],\r\n 'ease-in': [0.42, 0, 1, 1],\r\n 'ease-out': [0, 0, 0.58, 1],\r\n 'ease-in-out': [0.42, 0, 0.58, 1]\r\n };\r\n\r\n // function for setting transition css for all browsers\r\n var setStyle = function( elem, value, suffix ) {\r\n var css = {};\r\n suffix = suffix || 'transition';\r\n $.each( 'webkit moz ms o'.split(' '), function() {\r\n css[ '-' + this + '-' + suffix ] = value;\r\n });\r\n elem.css( css );\r\n };\r\n\r\n // clear styles\r\n var clearStyle = function( elem ) {\r\n setStyle( elem, 'none', 'transition' );\r\n if ( Galleria.WEBKIT && Galleria.TOUCH ) {\r\n setStyle( elem, 'translate3d(0,0,0)', 'transform' );\r\n if ( elem.data('revert') ) {\r\n elem.css( elem.data('revert') );\r\n elem.data('revert', null);\r\n }\r\n }\r\n };\r\n\r\n // various variables\r\n var change, strings, easing, syntax, revert, form, css;\r\n\r\n // the actual animation method\r\n return function( elem, to, options ) {\r\n\r\n // extend defaults\r\n options = $.extend({\r\n duration: 400,\r\n complete: F,\r\n stop: false\r\n }, options);\r\n\r\n // cache jQuery instance\r\n elem = $( elem );\r\n\r\n if ( !options.duration ) {\r\n elem.css( to );\r\n options.complete.call( elem[0] );\r\n return;\r\n }\r\n\r\n // fallback to jQuery's animate if transition is not supported\r\n if ( !transition ) {\r\n elem.animate(to, options);\r\n return;\r\n }\r\n\r\n // stop\r\n if ( options.stop ) {\r\n // clear the animation\r\n elem.off( endEvent );\r\n clearStyle( elem );\r\n }\r\n\r\n // see if there is a change\r\n change = false;\r\n $.each( to, function( key, val ) {\r\n css = elem.css( key );\r\n if ( Utils.parseValue( css ) != Utils.parseValue( val ) ) {\r\n change = true;\r\n }\r\n // also add computed styles for FF\r\n elem.css( key, css );\r\n });\r\n if ( !change ) {\r\n window.setTimeout( function() {\r\n options.complete.call( elem[0] );\r\n }, options.duration );\r\n return;\r\n }\r\n\r\n // the css strings to be applied\r\n strings = [];\r\n\r\n // the easing bezier\r\n easing = options.easing in easings ? easings[ options.easing ] : easings._default;\r\n\r\n // the syntax\r\n syntax = ' ' + options.duration + 'ms' + ' cubic-bezier(' + easing.join(',') + ')';\r\n\r\n // add a tiny timeout so that the browsers catches any css changes before animating\r\n window.setTimeout( (function(elem, endEvent, to, syntax) {\r\n return function() {\r\n\r\n // attach the end event\r\n elem.one(endEvent, (function( elem ) {\r\n return function() {\r\n\r\n // clear the animation\r\n clearStyle(elem);\r\n\r\n // run the complete method\r\n options.complete.call(elem[0]);\r\n };\r\n }( elem )));\r\n\r\n // do the webkit translate3d for better performance on iOS\r\n if( Galleria.WEBKIT && Galleria.TOUCH ) {\r\n\r\n revert = {};\r\n form = [0,0,0];\r\n\r\n $.each( ['left', 'top'], function(i, m) {\r\n if ( m in to ) {\r\n form[ i ] = ( Utils.parseValue( to[ m ] ) - Utils.parseValue(elem.css( m )) ) + 'px';\r\n revert[ m ] = to[ m ];\r\n delete to[ m ];\r\n }\r\n });\r\n\r\n if ( form[0] || form[1]) {\r\n\r\n elem.data('revert', revert);\r\n\r\n strings.push('-webkit-transform' + syntax);\r\n\r\n // 3d animate\r\n setStyle( elem, 'translate3d(' + form.join(',') + ')', 'transform');\r\n }\r\n }\r\n\r\n // push the animation props\r\n $.each(to, function( p, val ) {\r\n strings.push(p + syntax);\r\n });\r\n\r\n // set the animation styles\r\n setStyle( elem, strings.join(',') );\r\n\r\n // animate\r\n elem.css( to );\r\n\r\n };\r\n }(elem, endEvent, to, syntax)), 2);\r\n };\r\n }()),\r\n\r\n removeAlpha : function( elem ) {\r\n if ( elem instanceof jQuery ) {\r\n elem = elem[0];\r\n }\r\n if ( IE < 9 && elem ) {\r\n\r\n var style = elem.style,\r\n currentStyle = elem.currentStyle,\r\n filter = currentStyle && currentStyle.filter || style.filter || \"\";\r\n\r\n if ( /alpha/.test( filter ) ) {\r\n style.filter = filter.replace( /alpha\\([^)]*\\)/i, '' );\r\n }\r\n }\r\n },\r\n\r\n forceStyles : function( elem, styles ) {\r\n elem = $(elem);\r\n if ( elem.attr( 'style' ) ) {\r\n elem.data( 'styles', elem.attr( 'style' ) ).removeAttr( 'style' );\r\n }\r\n elem.css( styles );\r\n },\r\n\r\n revertStyles : function() {\r\n $.each( Utils.array( arguments ), function( i, elem ) {\r\n\r\n elem = $( elem );\r\n elem.removeAttr( 'style' );\r\n\r\n elem.attr('style',''); // \"fixes\" webkit bug\r\n\r\n if ( elem.data( 'styles' ) ) {\r\n elem.attr( 'style', elem.data('styles') ).data( 'styles', null );\r\n }\r\n });\r\n },\r\n\r\n moveOut : function( elem ) {\r\n Utils.forceStyles( elem, {\r\n position: 'absolute',\r\n left: -10000\r\n });\r\n },\r\n\r\n moveIn : function() {\r\n Utils.revertStyles.apply( Utils, Utils.array( arguments ) );\r\n },\r\n\r\n hide : function( elem, speed, callback ) {\r\n\r\n callback = callback || F;\r\n\r\n var $elem = $(elem);\r\n elem = $elem[0];\r\n\r\n // save the value if not exist\r\n if (! $elem.data('opacity') ) {\r\n $elem.data('opacity', $elem.css('opacity') );\r\n }\r\n\r\n // always hide\r\n var style = { opacity: 0 };\r\n\r\n if (speed) {\r\n\r\n var complete = IE < 9 && elem ? function() {\r\n Utils.removeAlpha( elem );\r\n elem.style.visibility = 'hidden';\r\n callback.call( elem );\r\n } : callback;\r\n\r\n Utils.animate( elem, style, {\r\n duration: speed,\r\n complete: complete,\r\n stop: true\r\n });\r\n } else {\r\n if ( IE < 9 && elem ) {\r\n Utils.removeAlpha( elem );\r\n elem.style.visibility = 'hidden';\r\n } else {\r\n $elem.css( style );\r\n }\r\n }\r\n },\r\n\r\n show : function( elem, speed, callback ) {\r\n\r\n callback = callback || F;\r\n\r\n var $elem = $(elem);\r\n elem = $elem[0];\r\n\r\n // bring back saved opacity\r\n var saved = parseFloat( $elem.data('opacity') ) || 1,\r\n style = { opacity: saved };\r\n\r\n // animate or toggle\r\n if (speed) {\r\n\r\n if ( IE < 9 ) {\r\n $elem.css('opacity', 0);\r\n elem.style.visibility = 'visible';\r\n }\r\n\r\n var complete = IE < 9 && elem ? function() {\r\n if ( style.opacity == 1 ) {\r\n Utils.removeAlpha( elem );\r\n }\r\n callback.call( elem );\r\n } : callback;\r\n\r\n Utils.animate( elem, style, {\r\n duration: speed,\r\n complete: complete,\r\n stop: true\r\n });\r\n } else {\r\n if ( IE < 9 && style.opacity == 1 && elem ) {\r\n Utils.removeAlpha( elem );\r\n elem.style.visibility = 'visible';\r\n } else {\r\n $elem.css( style );\r\n }\r\n }\r\n },\r\n\r\n wait : function(options) {\r\n\r\n Galleria._waiters = Galleria._waiters || [];\r\n\r\n options = $.extend({\r\n until : FALSE,\r\n success : F,\r\n error : function() { Galleria.raise('Could not complete wait function.'); },\r\n timeout: 3000\r\n }, options);\r\n\r\n var start = Utils.timestamp(),\r\n elapsed,\r\n now,\r\n tid,\r\n fn = function() {\r\n now = Utils.timestamp();\r\n elapsed = now - start;\r\n Utils.removeFromArray( Galleria._waiters, tid );\r\n if ( options.until( elapsed ) ) {\r\n options.success();\r\n return false;\r\n }\r\n if (typeof options.timeout == 'number' && now >= start + options.timeout) {\r\n options.error();\r\n return false;\r\n }\r\n Galleria._waiters.push( tid = window.setTimeout(fn, 10) );\r\n };\r\n Galleria._waiters.push( tid = window.setTimeout(fn, 10) );\r\n },\r\n\r\n toggleQuality : function( img, force ) {\r\n\r\n if ( ( IE !== 7 && IE !== 8 ) || !img || img.nodeName.toUpperCase() != 'IMG' ) {\r\n return;\r\n }\r\n\r\n if ( typeof force === 'undefined' ) {\r\n force = img.style.msInterpolationMode === 'nearest-neighbor';\r\n }\r\n\r\n img.style.msInterpolationMode = force ? 'bicubic' : 'nearest-neighbor';\r\n },\r\n\r\n insertStyleTag : function( styles, id ) {\r\n\r\n if ( id && $( '#'+id ).length ) {\r\n return;\r\n }\r\n\r\n var style = doc.createElement( 'style' );\r\n if ( id ) {\r\n style.id = id;\r\n }\r\n\r\n DOM().head.appendChild( style );\r\n\r\n if ( style.styleSheet ) { // IE\r\n style.styleSheet.cssText = styles;\r\n } else {\r\n var cssText = doc.createTextNode( styles );\r\n style.appendChild( cssText );\r\n }\r\n },\r\n\r\n // a loadscript method that works for local scripts\r\n loadScript: function( url, callback ) {\r\n\r\n var done = false,\r\n script = $('').attr({\r\n src: url,\r\n async: true\r\n }).get(0);\r\n\r\n // Attach handlers for all browsers\r\n script.onload = script.onreadystatechange = function() {\r\n if ( !done && (!this.readyState ||\r\n this.readyState === 'loaded' || this.readyState === 'complete') ) {\r\n\r\n done = true;\r\n\r\n // Handle memory leak in IE\r\n script.onload = script.onreadystatechange = null;\r\n\r\n if (typeof callback === 'function') {\r\n callback.call( this, this );\r\n }\r\n }\r\n };\r\n\r\n DOM().head.appendChild( script );\r\n },\r\n\r\n // parse anything into a number\r\n parseValue: function( val ) {\r\n if (typeof val === 'number') {\r\n return val;\r\n } else if (typeof val === 'string') {\r\n var arr = val.match(/\\-?\\d|\\./g);\r\n return arr && arr.constructor === Array ? arr.join('')*1 : 0;\r\n } else {\r\n return 0;\r\n }\r\n },\r\n\r\n // timestamp abstraction\r\n timestamp: function() {\r\n return new Date().getTime();\r\n },\r\n\r\n loadCSS : function( href, id, callback ) {\r\n\r\n var link,\r\n length;\r\n\r\n // look for manual css\r\n $('link[rel=stylesheet]').each(function() {\r\n if ( new RegExp( href ).test( this.href ) ) {\r\n link = this;\r\n return false;\r\n }\r\n });\r\n\r\n if ( typeof id === 'function' ) {\r\n callback = id;\r\n id = undef;\r\n }\r\n\r\n callback = callback || F; // dirty\r\n\r\n // if already present, return\r\n if ( link ) {\r\n callback.call( link, link );\r\n return link;\r\n }\r\n\r\n // save the length of stylesheets to check against\r\n length = doc.styleSheets.length;\r\n\r\n // check for existing id\r\n if( $( '#' + id ).length ) {\r\n\r\n $( '#' + id ).attr( 'href', href );\r\n length--;\r\n\r\n } else {\r\n link = $( '' ).attr({\r\n rel: 'stylesheet',\r\n href: href,\r\n id: id\r\n }).get(0);\r\n\r\n var styles = $('link[rel=\"stylesheet\"], style');\r\n if ( styles.length ) {\r\n styles.get(0).parentNode.insertBefore( link, styles[0] );\r\n } else {\r\n DOM().head.appendChild( link );\r\n }\r\n\r\n if ( IE && length >= 31 ) {\r\n Galleria.raise( 'You have reached the browser stylesheet limit (31)', true );\r\n return;\r\n }\r\n }\r\n\r\n if ( typeof callback === 'function' ) {\r\n\r\n // First check for dummy element (new in 1.2.8)\r\n var $loader = $('').attr( 'id', 'galleria-loader' ).hide().appendTo( DOM().body );\r\n\r\n Utils.wait({\r\n until: function() {\r\n return $loader.height() == 1;\r\n },\r\n success: function() {\r\n $loader.remove();\r\n callback.call( link, link );\r\n },\r\n error: function() {\r\n $loader.remove();\r\n\r\n // If failed, tell the dev to download the latest theme\r\n Galleria.raise( 'Theme CSS could not load after 20 sec. ' + ( Galleria.QUIRK ?\r\n 'Your browser is in Quirks Mode, please add a correct doctype.' :\r\n 'Please download the latest theme at http://galleria.io/customer/.' ), true );\r\n },\r\n timeout: 5000\r\n });\r\n }\r\n return link;\r\n }\r\n };\r\n }()),\r\n\r\n // play icon\r\n _playIcon = function( container ) {\r\n\r\n var css = '.galleria-videoicon{width:60px;height:60px;position:absolute;top:50%;left:50%;z-index:1;' +\r\n 'margin:-30px 0 0 -30px;cursor:pointer;background:#000;background:rgba(0,0,0,.8);border-radius:3px;-webkit-transition:all 150ms}' +\r\n '.galleria-videoicon i{width:0px;height:0px;border-style:solid;border-width:10px 0 10px 16px;display:block;' +\r\n 'border-color:transparent transparent transparent #ffffff;margin:20px 0 0 22px}.galleria-image:hover .galleria-videoicon{background:#000}';\r\n\r\n Utils.insertStyleTag( css, 'galleria-videoicon' );\r\n\r\n return $( Utils.create( 'galleria-videoicon' ) ).html( '' ).appendTo( container )\r\n .click( function() { $( this ).siblings( 'img' ).mouseup(); });\r\n },\r\n\r\n // the transitions holder\r\n _transitions = (function() {\r\n\r\n var _slide = function(params, complete, fade, door) {\r\n\r\n var easing = this.getOptions('easing'),\r\n distance = this.getStageWidth(),\r\n from = { left: distance * ( params.rewind ? -1 : 1 ) },\r\n to = { left: 0 };\r\n\r\n if ( fade ) {\r\n from.opacity = 0;\r\n to.opacity = 1;\r\n } else {\r\n from.opacity = 1;\r\n }\r\n\r\n $(params.next).css(from);\r\n\r\n Utils.animate(params.next, to, {\r\n duration: params.speed,\r\n complete: (function( elems ) {\r\n return function() {\r\n complete();\r\n elems.css({\r\n left: 0\r\n });\r\n };\r\n }( $( params.next ).add( params.prev ) )),\r\n queue: false,\r\n easing: easing\r\n });\r\n\r\n if (door) {\r\n params.rewind = !params.rewind;\r\n }\r\n\r\n if (params.prev) {\r\n\r\n from = { left: 0 };\r\n to = { left: distance * ( params.rewind ? 1 : -1 ) };\r\n\r\n if ( fade ) {\r\n from.opacity = 1;\r\n to.opacity = 0;\r\n }\r\n\r\n $(params.prev).css(from);\r\n Utils.animate(params.prev, to, {\r\n duration: params.speed,\r\n queue: false,\r\n easing: easing,\r\n complete: function() {\r\n $(this).css('opacity', 0);\r\n }\r\n });\r\n }\r\n };\r\n\r\n return {\r\n\r\n active: false,\r\n\r\n init: function( effect, params, complete ) {\r\n if ( _transitions.effects.hasOwnProperty( effect ) ) {\r\n _transitions.effects[ effect ].call( this, params, complete );\r\n }\r\n },\r\n\r\n effects: {\r\n\r\n fade: function(params, complete) {\r\n $(params.next).css({\r\n opacity: 0,\r\n left: 0\r\n });\r\n Utils.animate(params.next, {\r\n opacity: 1\r\n },{\r\n duration: params.speed,\r\n complete: complete\r\n });\r\n if (params.prev) {\r\n $(params.prev).css('opacity',1).show();\r\n Utils.animate(params.prev, {\r\n opacity: 0\r\n },{\r\n duration: params.speed\r\n });\r\n }\r\n },\r\n\r\n flash: function(params, complete) {\r\n $(params.next).css({\r\n opacity: 0,\r\n left: 0\r\n });\r\n if (params.prev) {\r\n Utils.animate( params.prev, {\r\n opacity: 0\r\n },{\r\n duration: params.speed/2,\r\n complete: function() {\r\n Utils.animate( params.next, {\r\n opacity:1\r\n },{\r\n duration: params.speed,\r\n complete: complete\r\n });\r\n }\r\n });\r\n } else {\r\n Utils.animate( params.next, {\r\n opacity: 1\r\n },{\r\n duration: params.speed,\r\n complete: complete\r\n });\r\n }\r\n },\r\n\r\n pulse: function(params, complete) {\r\n if (params.prev) {\r\n $(params.prev).hide();\r\n }\r\n $(params.next).css({\r\n opacity: 0,\r\n left: 0\r\n }).show();\r\n Utils.animate(params.next, {\r\n opacity:1\r\n },{\r\n duration: params.speed,\r\n complete: complete\r\n });\r\n },\r\n\r\n slide: function(params, complete) {\r\n _slide.apply( this, Utils.array( arguments ) );\r\n },\r\n\r\n fadeslide: function(params, complete) {\r\n _slide.apply( this, Utils.array( arguments ).concat( [true] ) );\r\n },\r\n\r\n doorslide: function(params, complete) {\r\n _slide.apply( this, Utils.array( arguments ).concat( [false, true] ) );\r\n }\r\n }\r\n };\r\n }());\r\n\r\n// listen to fullscreen\r\n_nativeFullscreen.listen();\r\n\r\n// create special click:fast event for fast touch interaction\r\n$.event.special['click:fast'] = {\r\n propagate: true,\r\n add: function(handleObj) {\r\n\r\n var getCoords = function(e) {\r\n if ( e.touches && e.touches.length ) {\r\n var touch = e.touches[0];\r\n return {\r\n x: touch.pageX,\r\n y: touch.pageY\r\n };\r\n }\r\n };\r\n\r\n var def = {\r\n touched: false,\r\n touchdown: false,\r\n coords: { x:0, y:0 },\r\n evObj: {}\r\n };\r\n\r\n $(this).data({\r\n clickstate: def,\r\n timer: 0\r\n }).on('touchstart.fast', function(e) {\r\n window.clearTimeout($(this).data('timer'));\r\n $(this).data('clickstate', {\r\n touched: true, \r\n touchdown: true,\r\n coords: getCoords(e.originalEvent),\r\n evObj: e\r\n });\r\n }).on('touchmove.fast', function(e) {\r\n var coords = getCoords(e.originalEvent),\r\n state = $(this).data('clickstate'),\r\n distance = Math.max( \r\n Math.abs(state.coords.x - coords.x), \r\n Math.abs(state.coords.y - coords.y) \r\n );\r\n if ( distance > 6 ) {\r\n $(this).data('clickstate', $.extend(state, {\r\n touchdown: false\r\n }));\r\n }\r\n }).on('touchend.fast', function(e) {\r\n var $this = $(this),\r\n state = $this.data('clickstate');\r\n if(state.touchdown) {\r\n handleObj.handler.call(this, e);\r\n }\r\n $this.data('timer', window.setTimeout(function() {\r\n $this.data('clickstate', def);\r\n }, 400));\r\n }).on('click.fast', function(e) {\r\n var state = $(this).data('clickstate');\r\n if ( state.touched ) {\r\n return false;\r\n }\r\n $(this).data('clickstate', def);\r\n handleObj.handler.call(this, e);\r\n });\r\n },\r\n remove: function() {\r\n $(this).off('touchstart.fast touchmove.fast touchend.fast click.fast');\r\n }\r\n};\r\n\r\n// trigger resize on orientationchange (IOS7)\r\n$win.on( 'orientationchange', function() {\r\n $(this).resize();\r\n});\r\n\r\n/**\r\n The main Galleria class\r\n\r\n @class\r\n @constructor\r\n\r\n @example var gallery = new Galleria();\r\n\r\n @author http://aino.se\r\n\r\n @requires jQuery\r\n\r\n*/\r\n\r\nGalleria = function() {\r\n\r\n var self = this;\r\n\r\n // internal options\r\n this._options = {};\r\n\r\n // flag for controlling play/pause\r\n this._playing = false;\r\n\r\n // internal interval for slideshow\r\n this._playtime = 5000;\r\n\r\n // internal variable for the currently active image\r\n this._active = null;\r\n\r\n // the internal queue, arrayified\r\n this._queue = { length: 0 };\r\n\r\n // the internal data array\r\n this._data = [];\r\n\r\n // the internal dom collection\r\n this._dom = {};\r\n\r\n // the internal thumbnails array\r\n this._thumbnails = [];\r\n\r\n // the internal layers array\r\n this._layers = [];\r\n\r\n // internal init flag\r\n this._initialized = false;\r\n\r\n // internal firstrun flag\r\n this._firstrun = false;\r\n\r\n // global stagewidth/height\r\n this._stageWidth = 0;\r\n this._stageHeight = 0;\r\n\r\n // target holder\r\n this._target = undef;\r\n\r\n // bind hashes\r\n this._binds = [];\r\n\r\n // instance id\r\n this._id = parseInt(M.random()*10000, 10);\r\n\r\n // add some elements\r\n var divs = 'container stage images image-nav image-nav-left image-nav-right ' +\r\n 'info info-text info-title info-description ' +\r\n 'thumbnails thumbnails-list thumbnails-container thumb-nav-left thumb-nav-right ' +\r\n 'loader counter tooltip',\r\n spans = 'current total';\r\n\r\n $.each( divs.split(' '), function( i, elemId ) {\r\n self._dom[ elemId ] = Utils.create( 'galleria-' + elemId );\r\n });\r\n\r\n $.each( spans.split(' '), function( i, elemId ) {\r\n self._dom[ elemId ] = Utils.create( 'galleria-' + elemId, 'span' );\r\n });\r\n\r\n // the internal keyboard object\r\n // keeps reference of the keybinds and provides helper methods for binding keys\r\n var keyboard = this._keyboard = {\r\n\r\n keys : {\r\n 'UP': 38,\r\n 'DOWN': 40,\r\n 'LEFT': 37,\r\n 'RIGHT': 39,\r\n 'RETURN': 13,\r\n 'ESCAPE': 27,\r\n 'BACKSPACE': 8,\r\n 'SPACE': 32\r\n },\r\n\r\n map : {},\r\n\r\n bound: false,\r\n\r\n press: function(e) {\r\n var key = e.keyCode || e.which;\r\n if ( key in keyboard.map && typeof keyboard.map[key] === 'function' ) {\r\n keyboard.map[key].call(self, e);\r\n }\r\n },\r\n\r\n attach: function(map) {\r\n\r\n var key, up;\r\n\r\n for( key in map ) {\r\n if ( map.hasOwnProperty( key ) ) {\r\n up = key.toUpperCase();\r\n if ( up in keyboard.keys ) {\r\n keyboard.map[ keyboard.keys[up] ] = map[key];\r\n } else {\r\n keyboard.map[ up ] = map[key];\r\n }\r\n }\r\n }\r\n if ( !keyboard.bound ) {\r\n keyboard.bound = true;\r\n $doc.on('keydown', keyboard.press);\r\n }\r\n },\r\n\r\n detach: function() {\r\n keyboard.bound = false;\r\n keyboard.map = {};\r\n $doc.off('keydown', keyboard.press);\r\n }\r\n };\r\n\r\n // internal controls for keeping track of active / inactive images\r\n var controls = this._controls = {\r\n\r\n 0: undef,\r\n\r\n 1: undef,\r\n\r\n active : 0,\r\n\r\n swap : function() {\r\n controls.active = controls.active ? 0 : 1;\r\n },\r\n\r\n getActive : function() {\r\n return self._options.swipe ? controls.slides[ self._active ] : controls[ controls.active ];\r\n },\r\n\r\n getNext : function() {\r\n return self._options.swipe ? controls.slides[ self.getNext( self._active ) ] : controls[ 1 - controls.active ];\r\n },\r\n\r\n slides : [],\r\n\r\n frames: [],\r\n\r\n layers: []\r\n };\r\n\r\n // internal carousel object\r\n var carousel = this._carousel = {\r\n\r\n // shortcuts\r\n next: self.$('thumb-nav-right'),\r\n prev: self.$('thumb-nav-left'),\r\n\r\n // cache the width\r\n width: 0,\r\n\r\n // track the current position\r\n current: 0,\r\n\r\n // cache max value\r\n max: 0,\r\n\r\n // save all hooks for each width in an array\r\n hooks: [],\r\n\r\n // update the carousel\r\n // you can run this method anytime, f.ex on window.resize\r\n update: function() {\r\n var w = 0,\r\n h = 0,\r\n hooks = [0];\r\n\r\n $.each( self._thumbnails, function( i, thumb ) {\r\n if ( thumb.ready ) {\r\n w += thumb.outerWidth || $( thumb.container ).outerWidth( true );\r\n // Due to a bug in jquery, outerwidth() returns the floor of the actual outerwidth,\r\n // if the browser is zoom to a value other than 100%. height() returns the floating point value.\r\n var containerWidth = $( thumb.container).width();\r\n w += containerWidth - M.floor(containerWidth);\r\n\r\n hooks[ i+1 ] = w;\r\n h = M.max( h, thumb.outerHeight || $( thumb.container).outerHeight( true ) );\r\n }\r\n });\r\n\r\n self.$( 'thumbnails' ).css({\r\n width: w,\r\n height: h\r\n });\r\n\r\n carousel.max = w;\r\n carousel.hooks = hooks;\r\n carousel.width = self.$( 'thumbnails-list' ).width();\r\n carousel.setClasses();\r\n\r\n self.$( 'thumbnails-container' ).toggleClass( 'galleria-carousel', w > carousel.width );\r\n\r\n // one extra calculation\r\n carousel.width = self.$( 'thumbnails-list' ).width();\r\n\r\n // todo: fix so the carousel moves to the left\r\n },\r\n\r\n bindControls: function() {\r\n\r\n var i;\r\n\r\n carousel.next.on( 'click:fast', function(e) {\r\n e.preventDefault();\r\n\r\n if ( self._options.carouselSteps === 'auto' ) {\r\n\r\n for ( i = carousel.current; i < carousel.hooks.length; i++ ) {\r\n if ( carousel.hooks[i] - carousel.hooks[ carousel.current ] > carousel.width ) {\r\n carousel.set(i - 2);\r\n break;\r\n }\r\n }\r\n\r\n } else {\r\n carousel.set( carousel.current + self._options.carouselSteps);\r\n }\r\n });\r\n\r\n carousel.prev.on( 'click:fast', function(e) {\r\n e.preventDefault();\r\n\r\n if ( self._options.carouselSteps === 'auto' ) {\r\n\r\n for ( i = carousel.current; i >= 0; i-- ) {\r\n if ( carousel.hooks[ carousel.current ] - carousel.hooks[i] > carousel.width ) {\r\n carousel.set( i + 2 );\r\n break;\r\n } else if ( i === 0 ) {\r\n carousel.set( 0 );\r\n break;\r\n }\r\n }\r\n } else {\r\n carousel.set( carousel.current - self._options.carouselSteps );\r\n }\r\n });\r\n },\r\n\r\n // calculate and set positions\r\n set: function( i ) {\r\n i = M.max( i, 0 );\r\n while ( carousel.hooks[i - 1] + carousel.width >= carousel.max && i >= 0 ) {\r\n i--;\r\n }\r\n carousel.current = i;\r\n carousel.animate();\r\n },\r\n\r\n // get the last position\r\n getLast: function(i) {\r\n return ( i || carousel.current ) - 1;\r\n },\r\n\r\n // follow the active image\r\n follow: function(i) {\r\n\r\n //don't follow if position fits\r\n if ( i === 0 || i === carousel.hooks.length - 2 ) {\r\n carousel.set( i );\r\n return;\r\n }\r\n\r\n // calculate last position\r\n var last = carousel.current;\r\n while( carousel.hooks[last] - carousel.hooks[ carousel.current ] <\r\n carousel.width && last <= carousel.hooks.length ) {\r\n last ++;\r\n }\r\n\r\n // set position\r\n if ( i - 1 < carousel.current ) {\r\n carousel.set( i - 1 );\r\n } else if ( i + 2 > last) {\r\n carousel.set( i - last + carousel.current + 2 );\r\n }\r\n },\r\n\r\n // helper for setting disabled classes\r\n setClasses: function() {\r\n carousel.prev.toggleClass( 'disabled', !carousel.current );\r\n carousel.next.toggleClass( 'disabled', carousel.hooks[ carousel.current ] + carousel.width >= carousel.max );\r\n },\r\n\r\n // the animation method\r\n animate: function(to) {\r\n carousel.setClasses();\r\n var num = carousel.hooks[ carousel.current ] * -1;\r\n\r\n if ( isNaN( num ) ) {\r\n return;\r\n }\r\n\r\n // FF 24 bug\r\n self.$( 'thumbnails' ).css('left', function() {\r\n return $(this).css('left');\r\n });\r\n\r\n Utils.animate(self.get( 'thumbnails' ), {\r\n left: num\r\n },{\r\n duration: self._options.carouselSpeed,\r\n easing: self._options.easing,\r\n queue: false\r\n });\r\n }\r\n };\r\n\r\n // tooltip control\r\n // added in 1.2\r\n var tooltip = this._tooltip = {\r\n\r\n initialized : false,\r\n\r\n open: false,\r\n\r\n timer: 'tooltip' + self._id,\r\n\r\n swapTimer: 'swap' + self._id,\r\n\r\n init: function() {\r\n\r\n tooltip.initialized = true;\r\n\r\n var css = '.galleria-tooltip{padding:3px 8px;max-width:50%;background:#ffe;color:#000;z-index:3;position:absolute;font-size:11px;line-height:1.3;' +\r\n 'opacity:0;box-shadow:0 0 2px rgba(0,0,0,.4);-moz-box-shadow:0 0 2px rgba(0,0,0,.4);-webkit-box-shadow:0 0 2px rgba(0,0,0,.4);}';\r\n\r\n Utils.insertStyleTag( css, 'galleria-tooltip' );\r\n\r\n self.$( 'tooltip' ).css({\r\n opacity: 0.8,\r\n visibility: 'visible',\r\n display: 'none'\r\n });\r\n\r\n },\r\n\r\n // move handler\r\n move: function( e ) {\r\n var mouseX = self.getMousePosition(e).x,\r\n mouseY = self.getMousePosition(e).y,\r\n $elem = self.$( 'tooltip' ),\r\n x = mouseX,\r\n y = mouseY,\r\n height = $elem.outerHeight( true ) + 1,\r\n width = $elem.outerWidth( true ),\r\n limitY = height + 15;\r\n\r\n var maxX = self.$( 'container' ).width() - width - 2,\r\n maxY = self.$( 'container' ).height() - height - 2;\r\n\r\n if ( !isNaN(x) && !isNaN(y) ) {\r\n\r\n x += 10;\r\n y -= ( height+8 );\r\n\r\n x = M.max( 0, M.min( maxX, x ) );\r\n y = M.max( 0, M.min( maxY, y ) );\r\n\r\n if( mouseY < limitY ) {\r\n y = limitY;\r\n }\r\n\r\n $elem.css({ left: x, top: y });\r\n }\r\n },\r\n\r\n // bind elements to the tooltip\r\n // you can bind multiple elementIDs using { elemID : function } or { elemID : string }\r\n // you can also bind single DOM elements using bind(elem, string)\r\n bind: function( elem, value ) {\r\n\r\n // todo: revise if alternative tooltip is needed for mobile devices\r\n if (Galleria.TOUCH) {\r\n return;\r\n }\r\n\r\n if (! tooltip.initialized ) {\r\n tooltip.init();\r\n }\r\n\r\n var mouseout = function() {\r\n self.$( 'container' ).off( 'mousemove', tooltip.move );\r\n self.clearTimer( tooltip.timer );\r\n\r\n self.$( 'tooltip' ).stop().animate({\r\n opacity: 0\r\n }, 200, function() {\r\n\r\n self.$( 'tooltip' ).hide();\r\n\r\n self.addTimer( tooltip.swapTimer, function() {\r\n tooltip.open = false;\r\n }, 1000);\r\n });\r\n };\r\n\r\n var hover = function( elem, value) {\r\n\r\n tooltip.define( elem, value );\r\n\r\n $( elem ).hover(function() {\r\n\r\n self.clearTimer( tooltip.swapTimer );\r\n self.$('container').off( 'mousemove', tooltip.move ).on( 'mousemove', tooltip.move ).trigger( 'mousemove' );\r\n tooltip.show( elem );\r\n\r\n self.addTimer( tooltip.timer, function() {\r\n self.$( 'tooltip' ).stop().show().animate({\r\n opacity: 1\r\n });\r\n tooltip.open = true;\r\n\r\n }, tooltip.open ? 0 : 500);\r\n\r\n }, mouseout).click(mouseout);\r\n };\r\n\r\n if ( typeof value === 'string' ) {\r\n hover( ( elem in self._dom ? self.get( elem ) : elem ), value );\r\n } else {\r\n // asume elemID here\r\n $.each( elem, function( elemID, val ) {\r\n hover( self.get(elemID), val );\r\n });\r\n }\r\n },\r\n\r\n show: function( elem ) {\r\n\r\n elem = $( elem in self._dom ? self.get(elem) : elem );\r\n\r\n var text = elem.data( 'tt' ),\r\n mouseup = function( e ) {\r\n\r\n // attach a tiny settimeout to make sure the new tooltip is filled\r\n window.setTimeout( (function( ev ) {\r\n return function() {\r\n tooltip.move( ev );\r\n };\r\n }( e )), 10);\r\n\r\n elem.off( 'mouseup', mouseup );\r\n\r\n };\r\n\r\n text = typeof text === 'function' ? text() : text;\r\n\r\n if ( ! text ) {\r\n return;\r\n }\r\n\r\n self.$( 'tooltip' ).html( text.replace(/\\s/, ' ') );\r\n\r\n // trigger mousemove on mouseup in case of click\r\n elem.on( 'mouseup', mouseup );\r\n },\r\n\r\n define: function( elem, value ) {\r\n\r\n // we store functions, not strings\r\n if (typeof value !== 'function') {\r\n var s = value;\r\n value = function() {\r\n return s;\r\n };\r\n }\r\n\r\n elem = $( elem in self._dom ? self.get(elem) : elem ).data('tt', value);\r\n\r\n tooltip.show( elem );\r\n\r\n }\r\n };\r\n\r\n // internal fullscreen control\r\n var fullscreen = this._fullscreen = {\r\n\r\n scrolled: 0,\r\n\r\n crop: undef,\r\n\r\n active: false,\r\n\r\n prev: $(),\r\n\r\n beforeEnter: function(fn){ fn(); },\r\n beforeExit: function(fn){ fn(); },\r\n\r\n keymap: self._keyboard.map,\r\n\r\n parseCallback: function( callback, enter ) {\r\n\r\n return _transitions.active ? function() {\r\n if ( typeof callback == 'function' ) {\r\n callback.call(self);\r\n }\r\n var active = self._controls.getActive(),\r\n next = self._controls.getNext();\r\n\r\n self._scaleImage( next );\r\n self._scaleImage( active );\r\n\r\n if ( enter && self._options.trueFullscreen ) {\r\n // Firefox bug, revise later\r\n $( active.container ).add( next.container ).trigger( 'transitionend' );\r\n }\r\n\r\n } : callback;\r\n\r\n },\r\n\r\n enter: function( callback ) {\r\n\r\n fullscreen.beforeEnter(function() {\r\n\r\n callback = fullscreen.parseCallback( callback, true );\r\n\r\n if ( self._options.trueFullscreen && _nativeFullscreen.support ) {\r\n\r\n // do some stuff prior animation for wmoother transitions\r\n\r\n fullscreen.active = true;\r\n\r\n Utils.forceStyles( self.get('container'), {\r\n width: '100%',\r\n height: '100%'\r\n });\r\n\r\n self.rescale();\r\n\r\n if ( Galleria.MAC ) {\r\n if ( !( Galleria.SAFARI && /version\\/[1-5]/.test(NAV)) ) {\r\n self.$('container').css('opacity', 0).addClass('fullscreen');\r\n window.setTimeout(function() {\r\n fullscreen.scale();\r\n self.$('container').css('opacity', 1);\r\n }, 50);\r\n } else {\r\n self.$('stage').css('opacity', 0);\r\n window.setTimeout(function() {\r\n fullscreen.scale();\r\n self.$('stage').css('opacity', 1);\r\n },4);\r\n }\r\n } else {\r\n self.$('container').addClass('fullscreen');\r\n }\r\n\r\n $win.resize( fullscreen.scale );\r\n\r\n _nativeFullscreen.enter( self, callback, self.get('container') );\r\n\r\n } else {\r\n\r\n fullscreen.scrolled = $win.scrollTop();\r\n if( !Galleria.TOUCH ) {\r\n window.scrollTo(0, 0);\r\n }\r\n\r\n fullscreen._enter( callback );\r\n }\r\n });\r\n\r\n },\r\n\r\n _enter: function( callback ) {\r\n\r\n fullscreen.active = true;\r\n\r\n if ( IFRAME ) {\r\n\r\n fullscreen.iframe = (function() {\r\n\r\n var elem,\r\n refer = doc.referrer,\r\n test = doc.createElement('a'),\r\n loc = window.location;\r\n\r\n test.href = refer;\r\n\r\n if( test.protocol != loc.protocol ||\r\n test.hostname != loc.hostname ||\r\n test.port != loc.port ) {\r\n Galleria.raise('Parent fullscreen not available. Iframe protocol, domains and ports must match.');\r\n return false;\r\n }\r\n\r\n fullscreen.pd = window.parent.document;\r\n\r\n $( fullscreen.pd ).find('iframe').each(function() {\r\n var idoc = this.contentDocument || this.contentWindow.document;\r\n if ( idoc === doc ) {\r\n elem = this;\r\n return false;\r\n }\r\n });\r\n\r\n return elem;\r\n }());\r\n\r\n }\r\n\r\n // hide the image until rescale is complete\r\n Utils.hide( self.getActiveImage() );\r\n\r\n if ( IFRAME && fullscreen.iframe ) {\r\n fullscreen.iframe.scrolled = $( window.parent ).scrollTop();\r\n window.parent.scrollTo(0, 0);\r\n }\r\n\r\n var data = self.getData(),\r\n options = self._options,\r\n inBrowser = !self._options.trueFullscreen || !_nativeFullscreen.support,\r\n htmlbody = {\r\n height: '100%',\r\n overflow: 'hidden',\r\n margin:0,\r\n padding:0\r\n };\r\n\r\n if (inBrowser) {\r\n\r\n self.$('container').addClass('fullscreen');\r\n fullscreen.prev = self.$('container').prev();\r\n\r\n if ( !fullscreen.prev.length ) {\r\n fullscreen.parent = self.$( 'container' ).parent();\r\n }\r\n\r\n // move\r\n self.$( 'container' ).appendTo( 'body' );\r\n\r\n // begin styleforce\r\n\r\n Utils.forceStyles(self.get('container'), {\r\n position: Galleria.TOUCH ? 'absolute' : 'fixed',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n zIndex: 10000\r\n });\r\n Utils.forceStyles( DOM().html, htmlbody );\r\n Utils.forceStyles( DOM().body, htmlbody );\r\n }\r\n\r\n if ( IFRAME && fullscreen.iframe ) {\r\n Utils.forceStyles( fullscreen.pd.documentElement, htmlbody );\r\n Utils.forceStyles( fullscreen.pd.body, htmlbody );\r\n Utils.forceStyles( fullscreen.iframe, $.extend( htmlbody, {\r\n width: '100%',\r\n height: '100%',\r\n top: 0,\r\n left: 0,\r\n position: 'fixed',\r\n zIndex: 10000,\r\n border: 'none'\r\n }));\r\n }\r\n\r\n // temporarily attach some keys\r\n // save the old ones first in a cloned object\r\n fullscreen.keymap = $.extend({}, self._keyboard.map);\r\n\r\n self.attachKeyboard({\r\n escape: self.exitFullscreen,\r\n right: self.next,\r\n left: self.prev\r\n });\r\n\r\n // temporarily save the crop\r\n fullscreen.crop = options.imageCrop;\r\n\r\n // set fullscreen options\r\n if ( options.fullscreenCrop != undef ) {\r\n options.imageCrop = options.fullscreenCrop;\r\n }\r\n\r\n // swap to big image if it's different from the display image\r\n if ( data && data.big && data.image !== data.big ) {\r\n var big = new Galleria.Picture(),\r\n cached = big.isCached( data.big ),\r\n index = self.getIndex(),\r\n thumb = self._thumbnails[ index ];\r\n\r\n self.trigger( {\r\n type: Galleria.LOADSTART,\r\n cached: cached,\r\n rewind: false,\r\n index: index,\r\n imageTarget: self.getActiveImage(),\r\n thumbTarget: thumb,\r\n galleriaData: data\r\n });\r\n\r\n big.load( data.big, function( big ) {\r\n self._scaleImage( big, {\r\n complete: function( big ) {\r\n self.trigger({\r\n type: Galleria.LOADFINISH,\r\n cached: cached,\r\n index: index,\r\n rewind: false,\r\n imageTarget: big.image,\r\n thumbTarget: thumb\r\n });\r\n var image = self._controls.getActive().image;\r\n if ( image ) {\r\n $( image ).width( big.image.width ).height( big.image.height )\r\n .attr( 'style', $( big.image ).attr('style') )\r\n .attr( 'src', big.image.src );\r\n }\r\n }\r\n });\r\n });\r\n\r\n var n = self.getNext(index),\r\n p = new Galleria.Picture(),\r\n ndata = self.getData( n );\r\n p.preload( self.isFullscreen() && ndata.big ? ndata.big : ndata.image );\r\n }\r\n\r\n // init the first rescale and attach callbacks\r\n\r\n self.rescale(function() {\r\n\r\n self.addTimer(false, function() {\r\n // show the image after 50 ms\r\n if ( inBrowser ) {\r\n Utils.show( self.getActiveImage() );\r\n }\r\n\r\n if (typeof callback === 'function') {\r\n callback.call( self );\r\n }\r\n self.rescale();\r\n\r\n }, 100);\r\n\r\n self.trigger( Galleria.FULLSCREEN_ENTER );\r\n });\r\n\r\n if ( !inBrowser ) {\r\n Utils.show( self.getActiveImage() );\r\n } else {\r\n $win.resize( fullscreen.scale );\r\n }\r\n\r\n },\r\n\r\n scale : function() {\r\n self.rescale();\r\n },\r\n\r\n exit: function( callback ) {\r\n\r\n fullscreen.beforeExit(function() {\r\n\r\n callback = fullscreen.parseCallback( callback );\r\n\r\n if ( self._options.trueFullscreen && _nativeFullscreen.support ) {\r\n _nativeFullscreen.exit( callback );\r\n } else {\r\n fullscreen._exit( callback );\r\n }\r\n });\r\n },\r\n\r\n _exit: function( callback ) {\r\n\r\n fullscreen.active = false;\r\n\r\n var inBrowser = !self._options.trueFullscreen || !_nativeFullscreen.support,\r\n $container = self.$( 'container' ).removeClass( 'fullscreen' );\r\n\r\n // move back\r\n if ( fullscreen.parent ) {\r\n fullscreen.parent.prepend( $container );\r\n } else {\r\n $container.insertAfter( fullscreen.prev );\r\n }\r\n\r\n if ( inBrowser ) {\r\n Utils.hide( self.getActiveImage() );\r\n\r\n // revert all styles\r\n Utils.revertStyles( self.get('container'), DOM().html, DOM().body );\r\n\r\n // scroll back\r\n if( !Galleria.TOUCH ) {\r\n window.scrollTo(0, fullscreen.scrolled);\r\n }\r\n\r\n // reload iframe src manually\r\n var frame = self._controls.frames[ self._controls.active ];\r\n if ( frame && frame.image ) {\r\n frame.image.src = frame.image.src;\r\n }\r\n }\r\n\r\n if ( IFRAME && fullscreen.iframe ) {\r\n Utils.revertStyles( fullscreen.pd.documentElement, fullscreen.pd.body, fullscreen.iframe );\r\n if ( fullscreen.iframe.scrolled ) {\r\n window.parent.scrollTo(0, fullscreen.iframe.scrolled );\r\n }\r\n }\r\n\r\n // detach all keyboard events and apply the old keymap\r\n self.detachKeyboard();\r\n self.attachKeyboard( fullscreen.keymap );\r\n\r\n // bring back cached options\r\n self._options.imageCrop = fullscreen.crop;\r\n\r\n // return to original image\r\n var big = self.getData().big,\r\n image = self._controls.getActive().image;\r\n\r\n if ( !self.getData().iframe && image && big && big == image.src ) {\r\n\r\n window.setTimeout(function(src) {\r\n return function() {\r\n image.src = src;\r\n };\r\n }( self.getData().image ), 1 );\r\n\r\n }\r\n\r\n self.rescale(function() {\r\n self.addTimer(false, function() {\r\n\r\n // show the image after 50 ms\r\n if ( inBrowser ) {\r\n Utils.show( self.getActiveImage() );\r\n }\r\n\r\n if ( typeof callback === 'function' ) {\r\n callback.call( self );\r\n }\r\n\r\n $win.trigger( 'resize' );\r\n\r\n }, 50);\r\n self.trigger( Galleria.FULLSCREEN_EXIT );\r\n });\r\n\r\n $win.off('resize', fullscreen.scale);\r\n }\r\n };\r\n\r\n // the internal idle object for controlling idle states\r\n var idle = this._idle = {\r\n\r\n trunk: [],\r\n\r\n bound: false,\r\n\r\n active: false,\r\n\r\n add: function(elem, to, from, hide) {\r\n if ( !elem || Galleria.TOUCH ) {\r\n return;\r\n }\r\n if (!idle.bound) {\r\n idle.addEvent();\r\n }\r\n elem = $(elem);\r\n\r\n if ( typeof from == 'boolean' ) {\r\n hide = from;\r\n from = {};\r\n }\r\n\r\n from = from || {};\r\n\r\n var extract = {},\r\n style;\r\n\r\n for ( style in to ) {\r\n if ( to.hasOwnProperty( style ) ) {\r\n extract[ style ] = elem.css( style );\r\n }\r\n }\r\n\r\n elem.data('idle', {\r\n from: $.extend( extract, from ),\r\n to: to,\r\n complete: true,\r\n busy: false\r\n });\r\n\r\n if ( !hide ) {\r\n idle.addTimer();\r\n } else {\r\n elem.css( to );\r\n }\r\n idle.trunk.push(elem);\r\n },\r\n\r\n remove: function(elem) {\r\n\r\n elem = $(elem);\r\n\r\n $.each(idle.trunk, function(i, el) {\r\n if ( el && el.length && !el.not(elem).length ) {\r\n elem.css( elem.data( 'idle' ).from );\r\n idle.trunk.splice(i, 1);\r\n }\r\n });\r\n\r\n if (!idle.trunk.length) {\r\n idle.removeEvent();\r\n self.clearTimer( idle.timer );\r\n }\r\n },\r\n\r\n addEvent : function() {\r\n idle.bound = true;\r\n self.$('container').on( 'mousemove click', idle.showAll );\r\n if ( self._options.idleMode == 'hover' ) {\r\n self.$('container').on( 'mouseleave', idle.hide );\r\n }\r\n },\r\n\r\n removeEvent : function() {\r\n idle.bound = false;\r\n self.$('container').on( 'mousemove click', idle.showAll );\r\n if ( self._options.idleMode == 'hover' ) {\r\n self.$('container').off( 'mouseleave', idle.hide );\r\n }\r\n },\r\n\r\n addTimer : function() {\r\n if( self._options.idleMode == 'hover' ) {\r\n return;\r\n }\r\n self.addTimer( 'idle', function() {\r\n idle.hide();\r\n }, self._options.idleTime );\r\n },\r\n\r\n hide : function() {\r\n\r\n if ( !self._options.idleMode || self.getIndex() === false ) {\r\n return;\r\n }\r\n\r\n self.trigger( Galleria.IDLE_ENTER );\r\n\r\n var len = idle.trunk.length;\r\n\r\n $.each( idle.trunk, function(i, elem) {\r\n\r\n var data = elem.data('idle');\r\n\r\n if (! data) {\r\n return;\r\n }\r\n\r\n elem.data('idle').complete = false;\r\n\r\n Utils.animate( elem, data.to, {\r\n duration: self._options.idleSpeed,\r\n complete: function() {\r\n if ( i == len-1 ) {\r\n idle.active = false;\r\n }\r\n }\r\n });\r\n });\r\n },\r\n\r\n showAll : function() {\r\n\r\n self.clearTimer( 'idle' );\r\n\r\n $.each( idle.trunk, function( i, elem ) {\r\n idle.show( elem );\r\n });\r\n },\r\n\r\n show: function(elem) {\r\n\r\n var data = elem.data('idle');\r\n\r\n if ( !idle.active || ( !data.busy && !data.complete ) ) {\r\n\r\n data.busy = true;\r\n\r\n self.trigger( Galleria.IDLE_EXIT );\r\n\r\n self.clearTimer( 'idle' );\r\n\r\n Utils.animate( elem, data.from, {\r\n duration: self._options.idleSpeed/2,\r\n complete: function() {\r\n idle.active = true;\r\n $(elem).data('idle').busy = false;\r\n $(elem).data('idle').complete = true;\r\n }\r\n });\r\n\r\n }\r\n idle.addTimer();\r\n }\r\n };\r\n\r\n // internal lightbox object\r\n // creates a predesigned lightbox for simple popups of images in galleria\r\n var lightbox = this._lightbox = {\r\n\r\n width : 0,\r\n\r\n height : 0,\r\n\r\n initialized : false,\r\n\r\n active : null,\r\n\r\n image : null,\r\n\r\n elems : {},\r\n\r\n keymap: false,\r\n\r\n init : function() {\r\n\r\n if ( lightbox.initialized ) {\r\n return;\r\n }\r\n lightbox.initialized = true;\r\n\r\n // create some elements to work with\r\n var elems = 'overlay box content shadow title info close prevholder prev nextholder next counter image',\r\n el = {},\r\n op = self._options,\r\n css = '',\r\n abs = 'position:absolute;',\r\n prefix = 'lightbox-',\r\n cssMap = {\r\n overlay: 'position:fixed;display:none;opacity:'+op.overlayOpacity+';filter:alpha(opacity='+(op.overlayOpacity*100)+\r\n ');top:0;left:0;width:100%;height:100%;background:'+op.overlayBackground+';z-index:99990',\r\n box: 'position:fixed;display:none;width:400px;height:400px;top:50%;left:50%;margin-top:-200px;margin-left:-200px;z-index:99991',\r\n shadow: abs+'background:#000;width:100%;height:100%;',\r\n content: abs+'background-color:#fff;top:10px;left:10px;right:10px;bottom:10px;overflow:hidden',\r\n info: abs+'bottom:10px;left:10px;right:10px;color:#444;font:11px/13px arial,sans-serif;height:13px',\r\n close: abs+'top:10px;right:10px;height:20px;width:20px;background:#fff;text-align:center;cursor:pointer;color:#444;font:16px/22px arial,sans-serif;z-index:99999',\r\n image: abs+'top:10px;left:10px;right:10px;bottom:30px;overflow:hidden;display:block;',\r\n prevholder: abs+'width:50%;top:0;bottom:40px;cursor:pointer;',\r\n nextholder: abs+'width:50%;top:0;bottom:40px;right:-1px;cursor:pointer;',\r\n prev: abs+'top:50%;margin-top:-20px;height:40px;width:30px;background:#fff;left:20px;display:none;text-align:center;color:#000;font:bold 16px/36px arial,sans-serif',\r\n next: abs+'top:50%;margin-top:-20px;height:40px;width:30px;background:#fff;right:20px;left:auto;display:none;font:bold 16px/36px arial,sans-serif;text-align:center;color:#000',\r\n title: 'float:left',\r\n counter: 'float:right;margin-left:8px;'\r\n },\r\n hover = function(elem) {\r\n return elem.hover(\r\n function() { $(this).css( 'color', '#bbb' ); },\r\n function() { $(this).css( 'color', '#444' ); }\r\n );\r\n },\r\n appends = {};\r\n\r\n // fix for navigation hovers transparent background event \"feature\"\r\n var exs = '';\r\n if ( IE > 7 ) {\r\n exs = IE < 9 ? 'background:#000;filter:alpha(opacity=0);' : 'background:rgba(0,0,0,0);';\r\n } else {\r\n exs = 'z-index:99999';\r\n }\r\n\r\n cssMap.nextholder += exs;\r\n cssMap.prevholder += exs;\r\n\r\n // create and insert CSS\r\n $.each(cssMap, function( key, value ) {\r\n css += '.galleria-'+prefix+key+'{'+value+'}';\r\n });\r\n\r\n css += '.galleria-'+prefix+'box.iframe .galleria-'+prefix+'prevholder,'+\r\n '.galleria-'+prefix+'box.iframe .galleria-'+prefix+'nextholder{'+\r\n 'width:100px;height:100px;top:50%;margin-top:-70px}';\r\n\r\n Utils.insertStyleTag( css, 'galleria-lightbox' );\r\n\r\n // create the elements\r\n $.each(elems.split(' '), function( i, elemId ) {\r\n self.addElement( 'lightbox-' + elemId );\r\n el[ elemId ] = lightbox.elems[ elemId ] = self.get( 'lightbox-' + elemId );\r\n });\r\n\r\n // initiate the image\r\n lightbox.image = new Galleria.Picture();\r\n\r\n // append the elements\r\n $.each({\r\n box: 'shadow content close prevholder nextholder',\r\n info: 'title counter',\r\n content: 'info image',\r\n prevholder: 'prev',\r\n nextholder: 'next'\r\n }, function( key, val ) {\r\n var arr = [];\r\n $.each( val.split(' '), function( i, prop ) {\r\n arr.push( prefix + prop );\r\n });\r\n appends[ prefix+key ] = arr;\r\n });\r\n\r\n self.append( appends );\r\n\r\n $( el.image ).append( lightbox.image.container );\r\n\r\n $( DOM().body ).append( el.overlay, el.box );\r\n\r\n // add the prev/next nav and bind some controls\r\n\r\n hover( $( el.close ).on( 'click:fast', lightbox.hide ).html('×') );\r\n\r\n $.each( ['Prev','Next'], function(i, dir) {\r\n\r\n var $d = $( el[ dir.toLowerCase() ] ).html( /v/.test( dir ) ? '‹ ' : ' ›' ),\r\n $e = $( el[ dir.toLowerCase()+'holder'] );\r\n\r\n $e.on( 'click:fast', function() {\r\n lightbox[ 'show' + dir ]();\r\n });\r\n\r\n // IE7 and touch devices will simply show the nav\r\n if ( IE < 8 || Galleria.TOUCH ) {\r\n $d.show();\r\n return;\r\n }\r\n\r\n $e.hover( function() {\r\n $d.show();\r\n }, function(e) {\r\n $d.stop().fadeOut( 200 );\r\n });\r\n\r\n });\r\n $( el.overlay ).on( 'click:fast', lightbox.hide );\r\n\r\n // the lightbox animation is slow on ipad\r\n if ( Galleria.IPAD ) {\r\n self._options.lightboxTransitionSpeed = 0;\r\n }\r\n\r\n },\r\n\r\n rescale: function(event) {\r\n\r\n // calculate\r\n var width = M.min( $win.width()-40, lightbox.width ),\r\n height = M.min( $win.height()-60, lightbox.height ),\r\n ratio = M.min( width / lightbox.width, height / lightbox.height ),\r\n destWidth = M.round( lightbox.width * ratio ) + 40,\r\n destHeight = M.round( lightbox.height * ratio ) + 60,\r\n to = {\r\n width: destWidth,\r\n height: destHeight,\r\n 'margin-top': M.ceil( destHeight / 2 ) *- 1,\r\n 'margin-left': M.ceil( destWidth / 2 ) *- 1\r\n };\r\n\r\n // if rescale event, don't animate\r\n if ( event ) {\r\n $( lightbox.elems.box ).css( to );\r\n } else {\r\n $( lightbox.elems.box ).animate( to, {\r\n duration: self._options.lightboxTransitionSpeed,\r\n easing: self._options.easing,\r\n complete: function() {\r\n var image = lightbox.image,\r\n speed = self._options.lightboxFadeSpeed;\r\n\r\n self.trigger({\r\n type: Galleria.LIGHTBOX_IMAGE,\r\n imageTarget: image.image\r\n });\r\n\r\n $( image.container ).show();\r\n\r\n $( image.image ).animate({ opacity: 1 }, speed);\r\n Utils.show( lightbox.elems.info, speed );\r\n }\r\n });\r\n }\r\n },\r\n\r\n hide: function() {\r\n\r\n // remove the image\r\n lightbox.image.image = null;\r\n\r\n $win.off('resize', lightbox.rescale);\r\n\r\n $( lightbox.elems.box ).hide().find( 'iframe' ).remove();\r\n\r\n Utils.hide( lightbox.elems.info );\r\n\r\n self.detachKeyboard();\r\n self.attachKeyboard( lightbox.keymap );\r\n\r\n lightbox.keymap = false;\r\n\r\n Utils.hide( lightbox.elems.overlay, 200, function() {\r\n $( this ).hide().css( 'opacity', self._options.overlayOpacity );\r\n self.trigger( Galleria.LIGHTBOX_CLOSE );\r\n });\r\n },\r\n\r\n showNext: function() {\r\n lightbox.show( self.getNext( lightbox.active ) );\r\n },\r\n\r\n showPrev: function() {\r\n lightbox.show( self.getPrev( lightbox.active ) );\r\n },\r\n\r\n show: function(index) {\r\n\r\n lightbox.active = index = typeof index === 'number' ? index : self.getIndex() || 0;\r\n\r\n if ( !lightbox.initialized ) {\r\n lightbox.init();\r\n }\r\n\r\n // trigger the event\r\n self.trigger( Galleria.LIGHTBOX_OPEN );\r\n\r\n // temporarily attach some keys\r\n // save the old ones first in a cloned object\r\n if ( !lightbox.keymap ) {\r\n\r\n lightbox.keymap = $.extend({}, self._keyboard.map);\r\n\r\n self.attachKeyboard({\r\n escape: lightbox.hide,\r\n right: lightbox.showNext,\r\n left: lightbox.showPrev\r\n });\r\n }\r\n\r\n $win.off('resize', lightbox.rescale );\r\n\r\n var data = self.getData(index),\r\n total = self.getDataLength(),\r\n n = self.getNext( index ),\r\n ndata, p, i;\r\n\r\n Utils.hide( lightbox.elems.info );\r\n\r\n try {\r\n for ( i = self._options.preload; i > 0; i-- ) {\r\n p = new Galleria.Picture();\r\n ndata = self.getData( n );\r\n p.preload( ndata.big ? ndata.big : ndata.image );\r\n n = self.getNext( n );\r\n }\r\n } catch(e) {}\r\n\r\n lightbox.image.isIframe = ( data.iframe && !data.image );\r\n\r\n $( lightbox.elems.box ).toggleClass( 'iframe', lightbox.image.isIframe );\r\n\r\n $( lightbox.image.container ).find( '.galleria-videoicon' ).remove();\r\n\r\n lightbox.image.load( data.big || data.image || data.iframe, function( image ) {\r\n\r\n if ( image.isIframe ) {\r\n\r\n var cw = $(window).width(),\r\n ch = $(window).height();\r\n\r\n if ( image.video && self._options.maxVideoSize ) {\r\n var r = M.min( self._options.maxVideoSize/cw, self._options.maxVideoSize/ch );\r\n if ( r < 1 ) {\r\n cw *= r;\r\n ch *= r;\r\n }\r\n }\r\n lightbox.width = cw;\r\n lightbox.height = ch;\r\n\r\n } else {\r\n lightbox.width = image.original.width;\r\n lightbox.height = image.original.height;\r\n }\r\n\r\n $( image.image ).css({\r\n width: image.isIframe ? '100%' : '100.1%',\r\n height: image.isIframe ? '100%' : '100.1%',\r\n top: 0,\r\n bottom: 0,\r\n zIndex: 99998,\r\n opacity: 0,\r\n visibility: 'visible'\r\n }).parent().height('100%');\r\n\r\n lightbox.elems.title.innerHTML = data.title || '';\r\n lightbox.elems.counter.innerHTML = (index + 1) + ' / ' + total;\r\n $win.resize( lightbox.rescale );\r\n lightbox.rescale();\r\n\r\n if( data.image && data.iframe ) {\r\n\r\n $( lightbox.elems.box ).addClass('iframe');\r\n\r\n if ( data.video ) {\r\n var $icon = _playIcon( image.container ).hide();\r\n window.setTimeout(function() {\r\n $icon.fadeIn(200);\r\n }, 200);\r\n }\r\n\r\n $( image.image ).css( 'cursor', 'pointer' ).mouseup((function(data, image) {\r\n return function(e) {\r\n $( lightbox.image.container ).find( '.galleria-videoicon' ).remove();\r\n e.preventDefault();\r\n image.isIframe = true;\r\n image.load( data.iframe + ( data.video ? '&autoplay=1' : '' ), {\r\n width: '100%',\r\n height: IE < 8 ? $( lightbox.image.container ).height() : '100%'\r\n });\r\n };\r\n }(data, image)));\r\n }\r\n });\r\n\r\n $( lightbox.elems.overlay ).show().css( 'visibility', 'visible' );\r\n $( lightbox.elems.box ).show();\r\n }\r\n };\r\n\r\n // the internal timeouts object\r\n // provides helper methods for controlling timeouts\r\n\r\n var _timer = this._timer = {\r\n\r\n trunk: {},\r\n\r\n add: function( id, fn, delay, loop ) {\r\n id = id || new Date().getTime();\r\n loop = loop || false;\r\n this.clear( id );\r\n if ( loop ) {\r\n var old = fn;\r\n fn = function() {\r\n old();\r\n _timer.add( id, fn, delay );\r\n };\r\n }\r\n this.trunk[ id ] = window.setTimeout( fn, delay );\r\n },\r\n\r\n clear: function( id ) {\r\n\r\n var del = function( i ) {\r\n window.clearTimeout( this.trunk[ i ] );\r\n delete this.trunk[ i ];\r\n }, i;\r\n\r\n if ( !!id && id in this.trunk ) {\r\n del.call( this, id );\r\n\r\n } else if ( typeof id === 'undefined' ) {\r\n for ( i in this.trunk ) {\r\n if ( this.trunk.hasOwnProperty( i ) ) {\r\n del.call( this, i );\r\n }\r\n }\r\n }\r\n }\r\n };\r\n\r\n return this;\r\n};\r\n\r\n// end Galleria constructor\r\n\r\nGalleria.prototype = {\r\n\r\n // bring back the constructor reference\r\n\r\n constructor: Galleria,\r\n\r\n /**\r\n Use this function to initialize the gallery and start loading.\r\n Should only be called once per instance.\r\n\r\n @param {HTMLElement} target The target element\r\n @param {Object} options The gallery options\r\n\r\n @returns Instance\r\n */\r\n\r\n init: function( target, options ) {\r\n\r\n options = _legacyOptions( options );\r\n\r\n // save the original ingredients\r\n this._original = {\r\n target: target,\r\n options: options,\r\n data: null\r\n };\r\n\r\n // save the target here\r\n this._target = this._dom.target = target.nodeName ? target : $( target ).get(0);\r\n\r\n // save the original content for destruction\r\n this._original.html = this._target.innerHTML;\r\n\r\n // push the instance\r\n _instances.push( this );\r\n\r\n // raise error if no target is detected\r\n if ( !this._target ) {\r\n Galleria.raise('Target not found', true);\r\n return;\r\n }\r\n\r\n // apply options\r\n this._options = {\r\n autoplay: false,\r\n carousel: true,\r\n carouselFollow: true, // legacy, deprecate at 1.3\r\n carouselSpeed: 400,\r\n carouselSteps: 'auto',\r\n clicknext: false,\r\n dailymotion: {\r\n foreground: '%23EEEEEE',\r\n highlight: '%235BCEC5',\r\n background: '%23222222',\r\n logo: 0,\r\n hideInfos: 1\r\n },\r\n dataConfig : function( elem ) { return {}; },\r\n dataSelector: 'img',\r\n dataSort: false,\r\n dataSource: this._target,\r\n debug: undef,\r\n dummy: undef, // 1.2.5\r\n easing: 'galleria',\r\n extend: function(options) {},\r\n fullscreenCrop: undef, // 1.2.5\r\n fullscreenDoubleTap: true, // 1.2.4 toggles fullscreen on double-tap for touch devices\r\n fullscreenTransition: undef, // 1.2.6\r\n height: 0,\r\n idleMode: true, // 1.2.4 toggles idleMode\r\n idleTime: 3000,\r\n idleSpeed: 200,\r\n imageCrop: false,\r\n imageMargin: 0,\r\n imagePan: false,\r\n imagePanSmoothness: 12,\r\n imagePosition: '50%',\r\n imageTimeout: undef, // 1.2.5\r\n initialTransition: undef, // 1.2.4, replaces transitionInitial\r\n keepSource: false,\r\n layerFollow: true, // 1.2.5\r\n lightbox: false, // 1.2.3\r\n lightboxFadeSpeed: 200,\r\n lightboxTransitionSpeed: 200,\r\n linkSourceImages: true,\r\n maxScaleRatio: undef,\r\n maxVideoSize: undef, // 1.2.9\r\n minScaleRatio: undef, // deprecated in 1.2.9\r\n overlayOpacity: 0.85,\r\n overlayBackground: '#0b0b0b',\r\n pauseOnInteraction: true,\r\n popupLinks: false,\r\n preload: 2,\r\n queue: true,\r\n responsive: true,\r\n show: 0,\r\n showInfo: true,\r\n showCounter: true,\r\n showImagenav: true,\r\n swipe: 'auto', // 1.2.4 -> revised in 1.3 -> changed type in 1.3.5\r\n theme: null,\r\n thumbCrop: true,\r\n thumbEventType: 'click:fast',\r\n thumbMargin: 0,\r\n thumbQuality: 'auto',\r\n thumbDisplayOrder: true, // 1.2.8\r\n thumbPosition: '50%', // 1.3\r\n thumbnails: true,\r\n touchTransition: undef, // 1.2.6\r\n transition: 'fade',\r\n transitionInitial: undef, // legacy, deprecate in 1.3. Use initialTransition instead.\r\n transitionSpeed: 400,\r\n trueFullscreen: true, // 1.2.7\r\n useCanvas: false, // 1.2.4\r\n variation: '', // 1.3.2\r\n videoPoster: true, // 1.3\r\n vimeo: {\r\n title: 0,\r\n byline: 0,\r\n portrait: 0,\r\n color: 'aaaaaa'\r\n },\r\n wait: 5000, // 1.2.7\r\n width: 'auto',\r\n youtube: {\r\n modestbranding: 1,\r\n autohide: 1,\r\n color: 'white',\r\n hd: 1,\r\n rel: 0,\r\n showinfo: 0\r\n }\r\n };\r\n\r\n // legacy support for transitionInitial\r\n this._options.initialTransition = this._options.initialTransition || this._options.transitionInitial;\r\n\r\n if ( options ) {\r\n\r\n // turn off debug\r\n if ( options.debug === false ) {\r\n DEBUG = false;\r\n }\r\n\r\n // set timeout\r\n if ( typeof options.imageTimeout === 'number' ) {\r\n TIMEOUT = options.imageTimeout;\r\n }\r\n\r\n // set dummy\r\n if ( typeof options.dummy === 'string' ) {\r\n DUMMY = options.dummy;\r\n }\r\n\r\n // set theme\r\n if ( typeof options.theme == 'string' ) {\r\n this._options.theme = options.theme;\r\n }\r\n }\r\n\r\n // hide all content\r\n $( this._target ).children().hide();\r\n\r\n // Warn for quirks mode\r\n if ( Galleria.QUIRK ) {\r\n Galleria.raise('Your page is in Quirks mode, Galleria may not render correctly. Please validate your HTML and add a correct doctype.');\r\n }\r\n\r\n // now we just have to wait for the theme...\r\n // first check if it has already loaded\r\n if ( _loadedThemes.length ) {\r\n if ( this._options.theme ) {\r\n for ( var i=0; i<_loadedThemes.length; i++ ) {\r\n if( this._options.theme === _loadedThemes[i].name ) {\r\n this.theme = _loadedThemes[i];\r\n break;\r\n }\r\n }\r\n } else {\r\n // if no theme sepcified, apply the first loaded theme\r\n this.theme = _loadedThemes[0];\r\n }\r\n }\r\n\r\n if ( typeof this.theme == 'object' ) {\r\n this._init();\r\n } else {\r\n // if no theme is loaded yet, push the instance into a pool and run it when the theme is ready\r\n _pool.push( this );\r\n }\r\n\r\n return this;\r\n },\r\n\r\n // this method should only be called once per instance\r\n // for manipulation of data, use the .load method\r\n\r\n _init: function() {\r\n\r\n var self = this,\r\n options = this._options;\r\n\r\n if ( this._initialized ) {\r\n Galleria.raise( 'Init failed: Gallery instance already initialized.' );\r\n return this;\r\n }\r\n\r\n this._initialized = true;\r\n\r\n if ( !this.theme ) {\r\n Galleria.raise( 'Init failed: No theme found.', true );\r\n return this;\r\n }\r\n\r\n // merge the theme & caller options\r\n $.extend( true, options, this.theme.defaults, this._original.options, Galleria.configure.options );\r\n\r\n // internally we use boolean for swipe\r\n options.swipe = (function(s) {\r\n\r\n if ( s == 'enforced' ) { return true; }\r\n\r\n // legacy patch\r\n if( s === false || s == 'disabled' ) { return false; }\r\n \r\n return !!Galleria.TOUCH;\r\n\r\n }( options.swipe ));\r\n\r\n // disable options that arent compatible with swipe\r\n if ( options.swipe ) {\r\n options.clicknext = false;\r\n options.imagePan = false;\r\n }\r\n\r\n // check for canvas support\r\n (function( can ) {\r\n if ( !( 'getContext' in can ) ) {\r\n can = null;\r\n return;\r\n }\r\n _canvas = _canvas || {\r\n elem: can,\r\n context: can.getContext( '2d' ),\r\n cache: {},\r\n length: 0\r\n };\r\n }( doc.createElement( 'canvas' ) ) );\r\n\r\n // bind the gallery to run when data is ready\r\n this.bind( Galleria.DATA, function() {\r\n\r\n // remove big if total pixels are less than 1024 (most phones)\r\n if ( window.screen && window.screen.width && Array.prototype.forEach ) {\r\n\r\n this._data.forEach(function(data) {\r\n\r\n var density = 'devicePixelRatio' in window ? window.devicePixelRatio : 1,\r\n m = M.max( window.screen.width, window.screen.height );\r\n\r\n if ( m*density < 1024 ) {\r\n data.big = data.image;\r\n }\r\n });\r\n }\r\n\r\n // save the new data\r\n this._original.data = this._data;\r\n\r\n // lets show the counter here\r\n this.get('total').innerHTML = this.getDataLength();\r\n\r\n // cache the container\r\n var $container = this.$( 'container' );\r\n\r\n // set ratio if height is < 2\r\n if ( self._options.height < 2 ) {\r\n self._userRatio = self._ratio = self._options.height;\r\n }\r\n\r\n // the gallery is ready, let's just wait for the css\r\n var num = { width: 0, height: 0 };\r\n var testHeight = function() {\r\n return self.$( 'stage' ).height();\r\n };\r\n\r\n // check container and thumbnail height\r\n Utils.wait({\r\n until: function() {\r\n\r\n // keep trying to get the value\r\n num = self._getWH();\r\n $container.width( num.width ).height( num.height );\r\n return testHeight() && num.width && num.height > 50;\r\n\r\n },\r\n success: function() {\r\n\r\n self._width = num.width;\r\n self._height = num.height;\r\n self._ratio = self._ratio || num.height/num.width;\r\n\r\n // for some strange reason, webkit needs a single setTimeout to play ball\r\n if ( Galleria.WEBKIT ) {\r\n window.setTimeout( function() {\r\n self._run();\r\n }, 1);\r\n } else {\r\n self._run();\r\n }\r\n },\r\n error: function() {\r\n\r\n // Height was probably not set, raise hard errors\r\n\r\n if ( testHeight() ) {\r\n Galleria.raise('Could not extract sufficient width/height of the gallery container. Traced measures: width:' + num.width + 'px, height: ' + num.height + 'px.', true);\r\n } else {\r\n Galleria.raise('Could not extract a stage height from the CSS. Traced height: ' + testHeight() + 'px.', true);\r\n }\r\n },\r\n timeout: typeof this._options.wait == 'number' ? this._options.wait : false\r\n });\r\n });\r\n\r\n // build the gallery frame\r\n this.append({\r\n 'info-text' :\r\n ['info-title', 'info-description'],\r\n 'info' :\r\n ['info-text'],\r\n 'image-nav' :\r\n ['image-nav-right', 'image-nav-left'],\r\n 'stage' :\r\n ['images', 'loader', 'counter', 'image-nav'],\r\n 'thumbnails-list' :\r\n ['thumbnails'],\r\n 'thumbnails-container' :\r\n ['thumb-nav-left', 'thumbnails-list', 'thumb-nav-right'],\r\n 'container' :\r\n ['stage', 'thumbnails-container', 'info', 'tooltip']\r\n });\r\n\r\n Utils.hide( this.$( 'counter' ).append(\r\n this.get( 'current' ),\r\n doc.createTextNode(' / '),\r\n this.get( 'total' )\r\n ) );\r\n\r\n this.setCounter('–');\r\n\r\n Utils.hide( self.get('tooltip') );\r\n\r\n // add a notouch class on the container to prevent unwanted :hovers on touch devices\r\n this.$( 'container' ).addClass([\r\n ( Galleria.TOUCH ? 'touch' : 'notouch' ),\r\n this._options.variation,\r\n 'galleria-theme-'+this.theme.name\r\n ].join(' '));\r\n\r\n // add images to the controls\r\n if ( !this._options.swipe ) {\r\n $.each( new Array(2), function( i ) {\r\n\r\n // create a new Picture instance\r\n var image = new Galleria.Picture();\r\n\r\n // apply some styles, create & prepend overlay\r\n $( image.container ).css({\r\n position: 'absolute',\r\n top: 0,\r\n left: 0\r\n }).prepend( self._layers[i] = $( Utils.create('galleria-layer') ).css({\r\n position: 'absolute',\r\n top:0, left:0, right:0, bottom:0,\r\n zIndex:2\r\n })[0] );\r\n\r\n // append the image\r\n self.$( 'images' ).append( image.container );\r\n\r\n // reload the controls\r\n self._controls[i] = image;\r\n\r\n // build a frame\r\n var frame = new Galleria.Picture();\r\n frame.isIframe = true;\r\n\r\n $( frame.container ).attr('class', 'galleria-frame').css({\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n zIndex: 4,\r\n background: '#000',\r\n display: 'none'\r\n }).appendTo( image.container );\r\n\r\n self._controls.frames[i] = frame;\r\n\r\n });\r\n }\r\n\r\n // some forced generic styling\r\n this.$( 'images' ).css({\r\n position: 'relative',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%'\r\n });\r\n\r\n if ( options.swipe ) {\r\n this.$( 'images' ).css({\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: 0,\r\n height: '100%'\r\n });\r\n this.finger = new Galleria.Finger(this.get('stage'), {\r\n onchange: function(page) {\r\n self.pause().show(page);\r\n },\r\n oncomplete: function(page) {\r\n\r\n var index = M.max( 0, M.min( parseInt( page, 10 ), self.getDataLength() - 1 ) ),\r\n data = self.getData(index);\r\n\r\n $( self._thumbnails[ index ].container )\r\n .addClass( 'active' )\r\n .siblings( '.active' )\r\n .removeClass( 'active' );\r\n\r\n if ( !data ) {\r\n return;\r\n }\r\n\r\n // remove video iframes\r\n self.$( 'images' ).find( '.galleria-frame' ).css('opacity', 0).hide().find( 'iframe' ).remove();\r\n\r\n if ( self._options.carousel && self._options.carouselFollow ) {\r\n self._carousel.follow( index );\r\n }\r\n }\r\n });\r\n this.bind( Galleria.RESCALE, function() {\r\n this.finger.setup();\r\n });\r\n this.$('stage').on('click', function(e) {\r\n var data = self.getData();\r\n if ( !data ) {\r\n return;\r\n }\r\n if ( data.iframe ) {\r\n\r\n if ( self.isPlaying() ) {\r\n self.pause();\r\n }\r\n var frame = self._controls.frames[ self._active ],\r\n w = self._stageWidth,\r\n h = self._stageHeight;\r\n\r\n if ( $( frame.container ).find( 'iframe' ).length ) {\r\n return;\r\n }\r\n\r\n $( frame.container ).css({\r\n width: w,\r\n height: h,\r\n opacity: 0\r\n }).show().animate({\r\n opacity: 1\r\n }, 200);\r\n\r\n window.setTimeout(function() {\r\n frame.load( data.iframe + ( data.video ? '&autoplay=1' : '' ), {\r\n width: w,\r\n height: h\r\n }, function( frame ) {\r\n self.$( 'container' ).addClass( 'videoplay' );\r\n frame.scale({\r\n width: self._stageWidth,\r\n height: self._stageHeight,\r\n iframelimit: data.video ? self._options.maxVideoSize : undef\r\n });\r\n });\r\n }, 100);\r\n\r\n return;\r\n }\r\n\r\n if ( data.link ) {\r\n if ( self._options.popupLinks ) {\r\n var win = window.open( data.link, '_blank' );\r\n } else {\r\n window.location.href = data.link;\r\n }\r\n return;\r\n }\r\n });\r\n this.bind( Galleria.IMAGE, function(e) {\r\n\r\n self.setCounter( e.index );\r\n self.setInfo( e.index );\r\n\r\n var next = this.getNext(),\r\n prev = this.getPrev();\r\n\r\n var preloads = [prev,next];\r\n preloads.push(this.getNext(next), this.getPrev(prev), self._controls.slides.length-1);\r\n\r\n var filtered = [];\r\n\r\n $.each(preloads, function(i, val) {\r\n if ( $.inArray(val, filtered) == -1 ) {\r\n filtered.push(val);\r\n }\r\n });\r\n\r\n $.each(filtered, function(i, loadme) {\r\n var d = self.getData(loadme),\r\n img = self._controls.slides[loadme],\r\n src = self.isFullscreen() && d.big ? d.big : ( d.image || d.iframe );\r\n\r\n if ( d.iframe && !d.image ) {\r\n img.isIframe = true;\r\n }\r\n\r\n if ( !img.ready ) {\r\n self._controls.slides[loadme].load(src, function(img) {\r\n if ( !img.isIframe ) {\r\n $(img.image).css('visibility', 'hidden');\r\n }\r\n self._scaleImage(img, {\r\n complete: function(img) {\r\n if ( !img.isIframe ) {\r\n $(img.image).css({\r\n opacity: 0,\r\n visibility: 'visible'\r\n }).animate({\r\n opacity: 1\r\n }, 200);\r\n }\r\n }\r\n });\r\n });\r\n }\r\n });\r\n });\r\n }\r\n\r\n this.$( 'thumbnails, thumbnails-list' ).css({\r\n overflow: 'hidden',\r\n position: 'relative'\r\n });\r\n\r\n // bind image navigation arrows\r\n this.$( 'image-nav-right, image-nav-left' ).on( 'click:fast', function(e) {\r\n\r\n // pause if options is set\r\n if ( options.pauseOnInteraction ) {\r\n self.pause();\r\n }\r\n\r\n // navigate\r\n var fn = /right/.test( this.className ) ? 'next' : 'prev';\r\n self[ fn ]();\r\n\r\n }).on('click', function(e) {\r\n\r\n e.preventDefault();\r\n\r\n // tune the clicknext option\r\n if ( options.clicknext || options.swipe ) {\r\n e.stopPropagation();\r\n }\r\n });\r\n\r\n // hide controls if chosen to\r\n $.each( ['info','counter','image-nav'], function( i, el ) {\r\n if ( options[ 'show' + el.substr(0,1).toUpperCase() + el.substr(1).replace(/-/,'') ] === false ) {\r\n Utils.moveOut( self.get( el.toLowerCase() ) );\r\n }\r\n });\r\n\r\n // load up target content\r\n this.load();\r\n\r\n // now it's usually safe to remove the content\r\n // IE will never stop loading if we remove it, so let's keep it hidden for IE (it's usually fast enough anyway)\r\n if ( !options.keepSource && !IE ) {\r\n this._target.innerHTML = '';\r\n }\r\n\r\n // re-append the errors, if they happened before clearing\r\n if ( this.get( 'errors' ) ) {\r\n this.appendChild( 'target', 'errors' );\r\n }\r\n\r\n // append the gallery frame\r\n this.appendChild( 'target', 'container' );\r\n\r\n // parse the carousel on each thumb load\r\n if ( options.carousel ) {\r\n var count = 0,\r\n show = options.show;\r\n this.bind( Galleria.THUMBNAIL, function() {\r\n this.updateCarousel();\r\n if ( ++count == this.getDataLength() && typeof show == 'number' && show > 0 ) {\r\n this._carousel.follow( show );\r\n }\r\n });\r\n }\r\n\r\n // bind window resize for responsiveness\r\n if ( options.responsive ) {\r\n $win.on( 'resize', function() {\r\n if ( !self.isFullscreen() ) {\r\n self.resize();\r\n }\r\n });\r\n }\r\n\r\n // double-tap/click fullscreen toggle\r\n\r\n if ( options.fullscreenDoubleTap ) {\r\n\r\n this.$( 'stage' ).on( 'touchstart', (function() {\r\n var last, cx, cy, lx, ly, now,\r\n getData = function(e) {\r\n return e.originalEvent.touches ? e.originalEvent.touches[0] : e;\r\n };\r\n self.$( 'stage' ).on('touchmove', function() {\r\n last = 0;\r\n });\r\n return function(e) {\r\n if( /(-left|-right)/.test(e.target.className) ) {\r\n return;\r\n }\r\n now = Utils.timestamp();\r\n cx = getData(e).pageX;\r\n cy = getData(e).pageY;\r\n if ( e.originalEvent.touches.length < 2 && ( now - last < 300 ) && ( cx - lx < 20) && ( cy - ly < 20) ) {\r\n self.toggleFullscreen();\r\n e.preventDefault();\r\n return;\r\n }\r\n last = now;\r\n lx = cx;\r\n ly = cy;\r\n };\r\n }()));\r\n }\r\n\r\n // bind the ons\r\n $.each( Galleria.on.binds, function(i, bind) {\r\n // check if already bound\r\n if ( $.inArray( bind.hash, self._binds ) == -1 ) {\r\n self.bind( bind.type, bind.callback );\r\n }\r\n });\r\n\r\n return this;\r\n },\r\n\r\n addTimer : function() {\r\n this._timer.add.apply( this._timer, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n clearTimer : function() {\r\n this._timer.clear.apply( this._timer, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n // parse width & height from CSS or options\r\n\r\n _getWH : function() {\r\n\r\n var $container = this.$( 'container' ),\r\n $target = this.$( 'target' ),\r\n self = this,\r\n num = {},\r\n arr;\r\n\r\n $.each(['width', 'height'], function( i, m ) {\r\n\r\n // first check if options is set\r\n if ( self._options[ m ] && typeof self._options[ m ] === 'number') {\r\n num[ m ] = self._options[ m ];\r\n } else {\r\n\r\n arr = [\r\n Utils.parseValue( $container.css( m ) ), // the container css height\r\n Utils.parseValue( $target.css( m ) ), // the target css height\r\n $container[ m ](), // the container jQuery method\r\n $target[ m ]() // the target jQuery method\r\n ];\r\n\r\n // if first time, include the min-width & min-height\r\n if ( !self[ '_'+m ] ) {\r\n arr.splice(arr.length,\r\n Utils.parseValue( $container.css( 'min-'+m ) ),\r\n Utils.parseValue( $target.css( 'min-'+m ) )\r\n );\r\n }\r\n\r\n // else extract the measures from different sources and grab the highest value\r\n num[ m ] = M.max.apply( M, arr );\r\n }\r\n });\r\n\r\n // allow setting a height ratio instead of exact value\r\n // useful when doing responsive galleries\r\n\r\n if ( self._userRatio ) {\r\n num.height = num.width * self._userRatio;\r\n }\r\n\r\n return num;\r\n },\r\n\r\n // Creates the thumbnails and carousel\r\n // can be used at any time, f.ex when the data object is manipulated\r\n // push is an optional argument with pushed images\r\n\r\n _createThumbnails : function( push ) {\r\n\r\n this.get( 'total' ).innerHTML = this.getDataLength();\r\n\r\n var src,\r\n thumb,\r\n data,\r\n\r\n $container,\r\n\r\n self = this,\r\n o = this._options,\r\n\r\n i = push ? this._data.length - push.length : 0,\r\n chunk = i,\r\n\r\n thumbchunk = [],\r\n loadindex = 0,\r\n\r\n gif = IE < 8 ? 'http://upload.wikimedia.org/wikipedia/commons/c/c0/Blank.gif' :\r\n 'data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D',\r\n\r\n // get previously active thumbnail, if exists\r\n active = (function() {\r\n var a = self.$('thumbnails').find('.active');\r\n if ( !a.length ) {\r\n return false;\r\n }\r\n return a.find('img').attr('src');\r\n }()),\r\n\r\n // cache the thumbnail option\r\n optval = typeof o.thumbnails === 'string' ? o.thumbnails.toLowerCase() : null,\r\n\r\n // move some data into the instance\r\n // for some reason, jQuery cant handle css(property) when zooming in FF, breaking the gallery\r\n // so we resort to getComputedStyle for browsers who support it\r\n getStyle = function( prop ) {\r\n return doc.defaultView && doc.defaultView.getComputedStyle ?\r\n doc.defaultView.getComputedStyle( thumb.container, null )[ prop ] :\r\n $container.css( prop );\r\n },\r\n\r\n fake = function(image, index, container) {\r\n return function() {\r\n $( container ).append( image );\r\n self.trigger({\r\n type: Galleria.THUMBNAIL,\r\n thumbTarget: image,\r\n index: index,\r\n galleriaData: self.getData( index )\r\n });\r\n };\r\n },\r\n\r\n onThumbEvent = function( e ) {\r\n\r\n // pause if option is set\r\n if ( o.pauseOnInteraction ) {\r\n self.pause();\r\n }\r\n\r\n // extract the index from the data\r\n var index = $( e.currentTarget ).data( 'index' );\r\n if ( self.getIndex() !== index ) {\r\n self.show( index );\r\n }\r\n\r\n e.preventDefault();\r\n },\r\n\r\n thumbComplete = function( thumb, callback ) {\r\n\r\n $( thumb.container ).css( 'visibility', 'visible' );\r\n self.trigger({\r\n type: Galleria.THUMBNAIL,\r\n thumbTarget: thumb.image,\r\n index: thumb.data.order,\r\n galleriaData: self.getData( thumb.data.order )\r\n });\r\n\r\n if ( typeof callback == 'function' ) {\r\n callback.call( self, thumb );\r\n }\r\n },\r\n\r\n onThumbLoad = function( thumb, callback ) {\r\n\r\n // scale when ready\r\n thumb.scale({\r\n width: thumb.data.width,\r\n height: thumb.data.height,\r\n crop: o.thumbCrop,\r\n margin: o.thumbMargin,\r\n canvas: o.useCanvas,\r\n position: o.thumbPosition,\r\n complete: function( thumb ) {\r\n\r\n // shrink thumbnails to fit\r\n var top = ['left', 'top'],\r\n arr = ['Width', 'Height'],\r\n m,\r\n css,\r\n data = self.getData( thumb.index );\r\n\r\n // calculate shrinked positions\r\n $.each(arr, function( i, measure ) {\r\n m = measure.toLowerCase();\r\n if ( (o.thumbCrop !== true || o.thumbCrop === m ) ) {\r\n css = {};\r\n css[ m ] = thumb[ m ];\r\n $( thumb.container ).css( css );\r\n css = {};\r\n css[ top[ i ] ] = 0;\r\n $( thumb.image ).css( css );\r\n }\r\n\r\n // cache outer measures\r\n thumb[ 'outer' + measure ] = $( thumb.container )[ 'outer' + measure ]( true );\r\n });\r\n\r\n // set high quality if downscale is moderate\r\n Utils.toggleQuality( thumb.image,\r\n o.thumbQuality === true ||\r\n ( o.thumbQuality === 'auto' && thumb.original.width < thumb.width * 3 )\r\n );\r\n\r\n if ( o.thumbDisplayOrder && !thumb.lazy ) {\r\n\r\n $.each( thumbchunk, function( i, th ) {\r\n if ( i === loadindex && th.ready && !th.displayed ) {\r\n\r\n loadindex++;\r\n th.displayed = true;\r\n\r\n thumbComplete( th, callback );\r\n\r\n return;\r\n }\r\n });\r\n } else {\r\n thumbComplete( thumb, callback );\r\n }\r\n }\r\n });\r\n };\r\n\r\n if ( !push ) {\r\n this._thumbnails = [];\r\n this.$( 'thumbnails' ).empty();\r\n }\r\n\r\n // loop through data and create thumbnails\r\n for( ; this._data[ i ]; i++ ) {\r\n\r\n data = this._data[ i ];\r\n\r\n // get source from thumb or image\r\n src = data.thumb || data.image;\r\n\r\n if ( ( o.thumbnails === true || optval == 'lazy' ) && ( data.thumb || data.image ) ) {\r\n\r\n // add a new Picture instance\r\n thumb = new Galleria.Picture(i);\r\n\r\n // save the index\r\n thumb.index = i;\r\n\r\n // flag displayed\r\n thumb.displayed = false;\r\n\r\n // flag lazy\r\n thumb.lazy = false;\r\n\r\n // flag video\r\n thumb.video = false;\r\n\r\n // append the thumbnail\r\n this.$( 'thumbnails' ).append( thumb.container );\r\n\r\n // cache the container\r\n $container = $( thumb.container );\r\n\r\n // hide it\r\n $container.css( 'visibility', 'hidden' );\r\n\r\n thumb.data = {\r\n width : Utils.parseValue( getStyle( 'width' ) ),\r\n height : Utils.parseValue( getStyle( 'height' ) ),\r\n order : i,\r\n src : src\r\n };\r\n\r\n // grab & reset size for smoother thumbnail loads\r\n if ( o.thumbCrop !== true ) {\r\n $container.css( { width: 'auto', height: 'auto' } );\r\n } else {\r\n $container.css( { width: thumb.data.width, height: thumb.data.height } );\r\n }\r\n\r\n // load the thumbnail\r\n if ( optval == 'lazy' ) {\r\n\r\n $container.addClass( 'lazy' );\r\n\r\n thumb.lazy = true;\r\n\r\n thumb.load( gif, {\r\n height: thumb.data.height,\r\n width: thumb.data.width\r\n });\r\n\r\n } else {\r\n thumb.load( src, onThumbLoad );\r\n }\r\n\r\n // preload all images here\r\n if ( o.preload === 'all' ) {\r\n thumb.preload( data.image );\r\n }\r\n\r\n // create empty spans if thumbnails is set to 'empty'\r\n } else if ( ( data.iframe && optval !== null ) || optval === 'empty' || optval === 'numbers' ) {\r\n thumb = {\r\n container: Utils.create( 'galleria-image' ),\r\n image: Utils.create( 'img', 'span' ),\r\n ready: true,\r\n data: {\r\n order: i\r\n }\r\n };\r\n\r\n // create numbered thumbnails\r\n if ( optval === 'numbers' ) {\r\n $( thumb.image ).text( i + 1 );\r\n }\r\n\r\n if ( data.iframe ) {\r\n $( thumb.image ).addClass( 'iframe' );\r\n }\r\n\r\n this.$( 'thumbnails' ).append( thumb.container );\r\n\r\n // we need to \"fake\" a loading delay before we append and trigger\r\n // 50+ should be enough\r\n\r\n window.setTimeout( ( fake )( thumb.image, i, thumb.container ), 50 + ( i*20 ) );\r\n\r\n // create null object to silent errors\r\n } else {\r\n thumb = {\r\n container: null,\r\n image: null\r\n };\r\n }\r\n\r\n // add events for thumbnails\r\n // you can control the event type using thumb_event_type\r\n // we'll add the same event to the source if it's kept\r\n\r\n $( thumb.container ).add( o.keepSource && o.linkSourceImages ? data.original : null )\r\n .data('index', i).on( o.thumbEventType, onThumbEvent )\r\n .data('thumbload', onThumbLoad);\r\n\r\n if (active === src) {\r\n $( thumb.container ).addClass( 'active' );\r\n }\r\n\r\n this._thumbnails.push( thumb );\r\n }\r\n\r\n thumbchunk = this._thumbnails.slice( chunk );\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Lazy-loads thumbnails.\r\n You can call this method to load lazy thumbnails at run time\r\n\r\n @param {Array|Number} index Index or array of indexes of thumbnails to be loaded\r\n @param {Function} complete Callback that is called when all lazy thumbnails have been loaded\r\n\r\n @returns Instance\r\n */\r\n\r\n lazyLoad: function( index, complete ) {\r\n\r\n var arr = index.constructor == Array ? index : [ index ],\r\n self = this,\r\n loaded = 0;\r\n\r\n $.each( arr, function(i, ind) {\r\n\r\n if ( ind > self._thumbnails.length - 1 ) {\r\n return;\r\n }\r\n\r\n var thumb = self._thumbnails[ ind ],\r\n data = thumb.data,\r\n callback = function() {\r\n if ( ++loaded == arr.length && typeof complete == 'function' ) {\r\n complete.call( self );\r\n }\r\n },\r\n thumbload = $( thumb.container ).data( 'thumbload' );\r\n if ( thumb.video ) {\r\n thumbload.call( self, thumb, callback );\r\n } else {\r\n thumb.load( data.src , function( thumb ) {\r\n thumbload.call( self, thumb, callback );\r\n });\r\n }\r\n });\r\n\r\n return this;\r\n\r\n },\r\n\r\n /**\r\n Lazy-loads thumbnails in chunks.\r\n This method automatcally chops up the loading process of many thumbnails into chunks\r\n\r\n @param {Number} size Size of each chunk to be loaded\r\n @param {Number} [delay] Delay between each loads\r\n\r\n @returns Instance\r\n */\r\n\r\n lazyLoadChunks: function( size, delay ) {\r\n\r\n var len = this.getDataLength(),\r\n i = 0,\r\n n = 0,\r\n arr = [],\r\n temp = [],\r\n self = this;\r\n\r\n delay = delay || 0;\r\n\r\n for( ; i 50 ); // what is an acceptable height?\r\n },\r\n\r\n success: function() {\r\n\r\n // save the instance\r\n _galleries.push( self );\r\n\r\n // postrun some stuff after the gallery is ready\r\n\r\n // create the touch slider\r\n if ( self._options.swipe ) {\r\n\r\n var $images = self.$( 'images' ).width( self.getDataLength() * self._stageWidth );\r\n $.each( new Array( self.getDataLength() ), function(i) {\r\n\r\n var image = new Galleria.Picture(),\r\n data = self.getData(i);\r\n\r\n $( image.container ).css({\r\n position: 'absolute',\r\n top: 0,\r\n left: self._stageWidth*i\r\n }).prepend( self._layers[i] = $( Utils.create('galleria-layer') ).css({\r\n position: 'absolute',\r\n top:0, left:0, right:0, bottom:0,\r\n zIndex:2\r\n })[0] ).appendTo( $images );\r\n\r\n if( data.video ) {\r\n _playIcon( image.container );\r\n }\r\n\r\n self._controls.slides.push(image);\r\n\r\n var frame = new Galleria.Picture();\r\n frame.isIframe = true;\r\n\r\n $( frame.container ).attr('class', 'galleria-frame').css({\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n zIndex: 4,\r\n background: '#000',\r\n display: 'none'\r\n }).appendTo( image.container );\r\n\r\n self._controls.frames.push(frame);\r\n });\r\n\r\n self.finger.setup();\r\n }\r\n\r\n // show counter\r\n Utils.show( self.get('counter') );\r\n\r\n // bind carousel nav\r\n if ( self._options.carousel ) {\r\n self._carousel.bindControls();\r\n }\r\n\r\n // start autoplay\r\n if ( self._options.autoplay ) {\r\n\r\n self.pause();\r\n\r\n if ( typeof self._options.autoplay === 'number' ) {\r\n self._playtime = self._options.autoplay;\r\n }\r\n\r\n self._playing = true;\r\n }\r\n // if second load, just do the show and return\r\n if ( self._firstrun ) {\r\n\r\n if ( self._options.autoplay ) {\r\n self.trigger( Galleria.PLAY );\r\n }\r\n\r\n if ( typeof self._options.show === 'number' ) {\r\n self.show( self._options.show );\r\n }\r\n return;\r\n }\r\n\r\n self._firstrun = true;\r\n\r\n // initialize the History plugin\r\n if ( Galleria.History ) {\r\n\r\n // bind the show method\r\n Galleria.History.change(function( value ) {\r\n\r\n // if ID is NaN, the user pressed back from the first image\r\n // return to previous address\r\n if ( isNaN( value ) ) {\r\n window.history.go(-1);\r\n\r\n // else show the image\r\n } else {\r\n self.show( value, undef, true );\r\n }\r\n });\r\n }\r\n\r\n self.trigger( Galleria.READY );\r\n\r\n // call the theme init method\r\n self.theme.init.call( self, self._options );\r\n\r\n // Trigger Galleria.ready\r\n $.each( Galleria.ready.callbacks, function(i ,fn) {\r\n if ( typeof fn == 'function' ) {\r\n fn.call( self, self._options );\r\n }\r\n });\r\n\r\n // call the extend option\r\n self._options.extend.call( self, self._options );\r\n\r\n // show the initial image\r\n // first test for permalinks in history\r\n if ( /^[0-9]{1,4}$/.test( HASH ) && Galleria.History ) {\r\n self.show( HASH, undef, true );\r\n\r\n } else if( self._data[ self._options.show ] ) {\r\n self.show( self._options.show );\r\n }\r\n\r\n // play trigger\r\n if ( self._options.autoplay ) {\r\n self.trigger( Galleria.PLAY );\r\n }\r\n },\r\n\r\n error: function() {\r\n Galleria.raise('Stage width or height is too small to show the gallery. Traced measures: width:' + self._stageWidth + 'px, height: ' + self._stageHeight + 'px.', true);\r\n }\r\n\r\n });\r\n },\r\n\r\n /**\r\n Loads data into the gallery.\r\n You can call this method on an existing gallery to reload the gallery with new data.\r\n\r\n @param {Array|string} [source] Optional JSON array of data or selector of where to find data in the document.\r\n Defaults to the Galleria target or dataSource option.\r\n\r\n @param {string} [selector] Optional element selector of what elements to parse.\r\n Defaults to 'img'.\r\n\r\n @param {Function} [config] Optional function to modify the data extraction proceedure from the selector.\r\n See the dataConfig option for more information.\r\n\r\n @returns Instance\r\n */\r\n\r\n load : function( source, selector, config ) {\r\n\r\n var self = this,\r\n o = this._options;\r\n\r\n // empty the data array\r\n this._data = [];\r\n\r\n // empty the thumbnails\r\n this._thumbnails = [];\r\n this.$('thumbnails').empty();\r\n\r\n // shorten the arguments\r\n if ( typeof selector === 'function' ) {\r\n config = selector;\r\n selector = null;\r\n }\r\n\r\n // use the source set by target\r\n source = source || o.dataSource;\r\n\r\n // use selector set by option\r\n selector = selector || o.dataSelector;\r\n\r\n // use the dataConfig set by option\r\n config = config || o.dataConfig;\r\n\r\n // if source is a true object, make it into an array\r\n if( $.isPlainObject( source ) ) {\r\n source = [source];\r\n }\r\n\r\n // check if the data is an array already\r\n if ( $.isArray( source ) ) {\r\n if ( this.validate( source ) ) {\r\n this._data = source;\r\n } else {\r\n Galleria.raise( 'Load failed: JSON Array not valid.' );\r\n }\r\n } else {\r\n\r\n // add .video and .iframe to the selector (1.2.7)\r\n selector += ',.video,.iframe';\r\n\r\n // loop through images and set data\r\n $( source ).find( selector ).each( function( i, elem ) {\r\n\r\n elem = $( elem );\r\n var data = {},\r\n parent = elem.parent(),\r\n href = parent.attr( 'href' ),\r\n rel = parent.attr( 'rel' );\r\n\r\n if( href && ( elem[0].nodeName == 'IMG' || elem.hasClass('video') ) && _videoTest( href ) ) {\r\n data.video = href;\r\n } else if( href && elem.hasClass('iframe') ) {\r\n data.iframe = href;\r\n } else {\r\n data.image = data.big = href;\r\n }\r\n\r\n if ( rel ) {\r\n data.big = rel;\r\n }\r\n\r\n // alternative extraction from HTML5 data attribute, added in 1.2.7\r\n $.each( 'big title description link layer image'.split(' '), function( i, val ) {\r\n if ( elem.data(val) ) {\r\n data[ val ] = elem.data(val).toString();\r\n }\r\n });\r\n\r\n if ( !data.big ) {\r\n data.big = data.image;\r\n }\r\n\r\n // mix default extractions with the hrefs and config\r\n // and push it into the data array\r\n self._data.push( $.extend({\r\n\r\n title: elem.attr('title') || '',\r\n thumb: elem.attr('src'),\r\n image: elem.attr('src'),\r\n big: elem.attr('src'),\r\n description: elem.attr('alt') || '',\r\n link: elem.attr('longdesc'),\r\n original: elem.get(0) // saved as a reference\r\n\r\n }, data, config( elem ) ) );\r\n\r\n });\r\n }\r\n\r\n if ( typeof o.dataSort == 'function' ) {\r\n protoArray.sort.call( this._data, o.dataSort );\r\n } else if ( o.dataSort == 'random' ) {\r\n this._data.sort( function() {\r\n return M.round(M.random())-0.5;\r\n });\r\n }\r\n\r\n // trigger the DATA event and return\r\n if ( this.getDataLength() ) {\r\n this._parseData( function() {\r\n this.trigger( Galleria.DATA );\r\n } );\r\n }\r\n return this;\r\n\r\n },\r\n\r\n // make sure the data works properly\r\n _parseData : function( callback ) {\r\n\r\n var self = this,\r\n current,\r\n ready = false,\r\n onload = function() {\r\n var complete = true;\r\n $.each( self._data, function( i, data ) {\r\n if ( data.loading ) {\r\n complete = false;\r\n return false;\r\n }\r\n });\r\n if ( complete && !ready ) {\r\n ready = true;\r\n callback.call( self );\r\n }\r\n };\r\n\r\n $.each( this._data, function( i, data ) {\r\n\r\n current = self._data[ i ];\r\n\r\n // copy image as thumb if no thumb exists\r\n if ( 'thumb' in data === false ) {\r\n current.thumb = data.image;\r\n }\r\n // copy image as big image if no biggie exists\r\n if ( !data.big ) {\r\n current.big = data.image;\r\n }\r\n // parse video\r\n if ( 'video' in data ) {\r\n var result = _videoTest( data.video );\r\n\r\n if ( result ) {\r\n current.iframe = new Video(result.provider, result.id ).embed() + (function() {\r\n\r\n // add options\r\n if ( typeof self._options[ result.provider ] == 'object' ) {\r\n var str = '?', arr = [];\r\n $.each( self._options[ result.provider ], function( key, val ) {\r\n arr.push( key + '=' + val );\r\n });\r\n\r\n // small youtube specifics, perhaps move to _video later\r\n if ( result.provider == 'youtube' ) {\r\n arr = ['wmode=opaque'].concat(arr);\r\n }\r\n return str + arr.join('&');\r\n }\r\n return '';\r\n }());\r\n\r\n // pre-fetch video providers media\r\n\r\n if( !current.thumb || !current.image ) {\r\n $.each( ['thumb', 'image'], function( i, type ) {\r\n if ( type == 'image' && !self._options.videoPoster ) {\r\n current.image = undef;\r\n return;\r\n }\r\n var video = new Video( result.provider, result.id );\r\n if ( !current[ type ] ) {\r\n current.loading = true;\r\n video.getMedia( type, (function(current, type) {\r\n return function(src) {\r\n current[ type ] = src;\r\n if ( type == 'image' && !current.big ) {\r\n current.big = current.image;\r\n }\r\n delete current.loading;\r\n onload();\r\n };\r\n }( current, type )));\r\n }\r\n });\r\n }\r\n }\r\n }\r\n });\r\n\r\n onload();\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Destroy the Galleria instance and recover the original content\r\n\r\n @example this.destroy();\r\n\r\n @returns Instance\r\n */\r\n\r\n destroy : function() {\r\n this.$( 'target' ).data( 'galleria', null );\r\n this.$( 'container' ).off( 'galleria' );\r\n this.get( 'target' ).innerHTML = this._original.html;\r\n this.clearTimer();\r\n Utils.removeFromArray( _instances, this );\r\n Utils.removeFromArray( _galleries, this );\r\n if ( Galleria._waiters.length ) {\r\n $.each( Galleria._waiters, function( i, w ) {\r\n if ( w ) window.clearTimeout( w );\r\n });\r\n }\r\n return this;\r\n },\r\n\r\n /**\r\n Adds and/or removes images from the gallery\r\n Works just like Array.splice\r\n https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice\r\n\r\n @example this.splice( 2, 4 ); // removes 4 images after the second image\r\n\r\n @returns Instance\r\n */\r\n\r\n splice : function() {\r\n var self = this,\r\n args = Utils.array( arguments );\r\n window.setTimeout(function() {\r\n protoArray.splice.apply( self._data, args );\r\n self._parseData( function() {\r\n self._createThumbnails();\r\n });\r\n },2);\r\n return self;\r\n },\r\n\r\n /**\r\n Append images to the gallery\r\n Works just like Array.push\r\n https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/push\r\n\r\n @example this.push({ image: 'image1.jpg' }); // appends the image to the gallery\r\n\r\n @returns Instance\r\n */\r\n\r\n push : function() {\r\n var self = this,\r\n args = Utils.array( arguments );\r\n\r\n if ( args.length == 1 && args[0].constructor == Array ) {\r\n args = args[0];\r\n }\r\n\r\n window.setTimeout(function() {\r\n protoArray.push.apply( self._data, args );\r\n self._parseData( function() {\r\n self._createThumbnails( args );\r\n });\r\n }, 2);\r\n return self;\r\n },\r\n\r\n _getActive : function() {\r\n return this._controls.getActive();\r\n },\r\n\r\n validate : function( data ) {\r\n // todo: validate a custom data array\r\n return true;\r\n },\r\n\r\n /**\r\n Bind any event to Galleria\r\n\r\n @param {string} type The Event type to listen for\r\n @param {Function} fn The function to execute when the event is triggered\r\n\r\n @example this.bind( 'image', function() { Galleria.log('image shown') });\r\n\r\n @returns Instance\r\n */\r\n\r\n bind : function(type, fn) {\r\n\r\n // allow 'image' instead of Galleria.IMAGE\r\n type = _patchEvent( type );\r\n\r\n this.$( 'container' ).on( type, this.proxy(fn) );\r\n return this;\r\n },\r\n\r\n /**\r\n Unbind any event to Galleria\r\n\r\n @param {string} type The Event type to forget\r\n\r\n @returns Instance\r\n */\r\n\r\n unbind : function(type) {\r\n\r\n type = _patchEvent( type );\r\n\r\n this.$( 'container' ).off( type );\r\n return this;\r\n },\r\n\r\n /**\r\n Manually trigger a Galleria event\r\n\r\n @param {string} type The Event to trigger\r\n\r\n @returns Instance\r\n */\r\n\r\n trigger : function( type ) {\r\n\r\n type = typeof type === 'object' ?\r\n $.extend( type, { scope: this } ) :\r\n { type: _patchEvent( type ), scope: this };\r\n\r\n this.$( 'container' ).trigger( type );\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Assign an \"idle state\" to any element.\r\n The idle state will be applied after a certain amount of idle time\r\n Useful to hide f.ex navigation when the gallery is inactive\r\n\r\n @param {HTMLElement|string} elem The Dom node or selector to apply the idle state to\r\n @param {Object} styles the CSS styles to apply when in idle mode\r\n @param {Object} [from] the CSS styles to apply when in normal\r\n @param {Boolean} [hide] set to true if you want to hide it first\r\n\r\n @example addIdleState( this.get('image-nav'), { opacity: 0 });\r\n @example addIdleState( '.galleria-image-nav', { top: -200 }, true);\r\n\r\n @returns Instance\r\n */\r\n\r\n addIdleState: function( elem, styles, from, hide ) {\r\n this._idle.add.apply( this._idle, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Removes any idle state previously set using addIdleState()\r\n\r\n @param {HTMLElement|string} elem The Dom node or selector to remove the idle state from.\r\n\r\n @returns Instance\r\n */\r\n\r\n removeIdleState: function( elem ) {\r\n this._idle.remove.apply( this._idle, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Force Galleria to enter idle mode.\r\n\r\n @returns Instance\r\n */\r\n\r\n enterIdleMode: function() {\r\n this._idle.hide();\r\n return this;\r\n },\r\n\r\n /**\r\n Force Galleria to exit idle mode.\r\n\r\n @returns Instance\r\n */\r\n\r\n exitIdleMode: function() {\r\n this._idle.showAll();\r\n return this;\r\n },\r\n\r\n /**\r\n Enter FullScreen mode\r\n\r\n @param {Function} callback the function to be executed when the fullscreen mode is fully applied.\r\n\r\n @returns Instance\r\n */\r\n\r\n enterFullscreen: function( callback ) {\r\n this._fullscreen.enter.apply( this, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Exits FullScreen mode\r\n\r\n @param {Function} callback the function to be executed when the fullscreen mode is fully applied.\r\n\r\n @returns Instance\r\n */\r\n\r\n exitFullscreen: function( callback ) {\r\n this._fullscreen.exit.apply( this, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Toggle FullScreen mode\r\n\r\n @param {Function} callback the function to be executed when the fullscreen mode is fully applied or removed.\r\n\r\n @returns Instance\r\n */\r\n\r\n toggleFullscreen: function( callback ) {\r\n this._fullscreen[ this.isFullscreen() ? 'exit' : 'enter'].apply( this, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Adds a tooltip to any element.\r\n You can also call this method with an object as argument with elemID:value pairs to apply tooltips to (see examples)\r\n\r\n @param {HTMLElement} elem The DOM Node to attach the event to\r\n @param {string|Function} value The tooltip message. Can also be a function that returns a string.\r\n\r\n @example this.bindTooltip( this.get('thumbnails'), 'My thumbnails');\r\n @example this.bindTooltip( this.get('thumbnails'), function() { return 'My thumbs' });\r\n @example this.bindTooltip( { image_nav: 'Navigation' });\r\n\r\n @returns Instance\r\n */\r\n\r\n bindTooltip: function( elem, value ) {\r\n this._tooltip.bind.apply( this._tooltip, Utils.array(arguments) );\r\n return this;\r\n },\r\n\r\n /**\r\n Note: this method is deprecated. Use refreshTooltip() instead.\r\n\r\n Redefine a tooltip.\r\n Use this if you want to re-apply a tooltip value to an already bound tooltip element.\r\n\r\n @param {HTMLElement} elem The DOM Node to attach the event to\r\n @param {string|Function} value The tooltip message. Can also be a function that returns a string.\r\n\r\n @returns Instance\r\n */\r\n\r\n defineTooltip: function( elem, value ) {\r\n this._tooltip.define.apply( this._tooltip, Utils.array(arguments) );\r\n return this;\r\n },\r\n\r\n /**\r\n Refresh a tooltip value.\r\n Use this if you want to change the tooltip value at runtime, f.ex if you have a play/pause toggle.\r\n\r\n @param {HTMLElement} elem The DOM Node that has a tooltip that should be refreshed\r\n\r\n @returns Instance\r\n */\r\n\r\n refreshTooltip: function( elem ) {\r\n this._tooltip.show.apply( this._tooltip, Utils.array(arguments) );\r\n return this;\r\n },\r\n\r\n /**\r\n Open a pre-designed lightbox with the currently active image.\r\n You can control some visuals using gallery options.\r\n\r\n @returns Instance\r\n */\r\n\r\n openLightbox: function() {\r\n this._lightbox.show.apply( this._lightbox, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Close the lightbox.\r\n\r\n @returns Instance\r\n */\r\n\r\n closeLightbox: function() {\r\n this._lightbox.hide.apply( this._lightbox, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Check if a variation exists\r\n\r\n @returns {Boolean} If the variation has been applied\r\n */\r\n\r\n hasVariation: function( variation ) {\r\n return $.inArray( variation, this._options.variation.split(/\\s+/) ) > -1;\r\n },\r\n\r\n /**\r\n Get the currently active image element.\r\n\r\n @returns {HTMLElement} The image element\r\n */\r\n\r\n getActiveImage: function() {\r\n var active = this._getActive();\r\n return active ? active.image : undef;\r\n },\r\n\r\n /**\r\n Get the currently active thumbnail element.\r\n\r\n @returns {HTMLElement} The thumbnail element\r\n */\r\n\r\n getActiveThumb: function() {\r\n return this._thumbnails[ this._active ].image || undef;\r\n },\r\n\r\n /**\r\n Get the mouse position relative to the gallery container\r\n\r\n @param e The mouse event\r\n\r\n @example\r\n\r\nvar gallery = this;\r\n$(document).mousemove(function(e) {\r\n console.log( gallery.getMousePosition(e).x );\r\n});\r\n\r\n @returns {Object} Object with x & y of the relative mouse postion\r\n */\r\n\r\n getMousePosition : function(e) {\r\n return {\r\n x: e.pageX - this.$( 'container' ).offset().left,\r\n y: e.pageY - this.$( 'container' ).offset().top\r\n };\r\n },\r\n\r\n /**\r\n Adds a panning effect to the image\r\n\r\n @param [img] The optional image element. If not specified it takes the currently active image\r\n\r\n @returns Instance\r\n */\r\n\r\n addPan : function( img ) {\r\n\r\n if ( this._options.imageCrop === false ) {\r\n return;\r\n }\r\n\r\n img = $( img || this.getActiveImage() );\r\n\r\n // define some variables and methods\r\n var self = this,\r\n x = img.width() / 2,\r\n y = img.height() / 2,\r\n destX = parseInt( img.css( 'left' ), 10 ),\r\n destY = parseInt( img.css( 'top' ), 10 ),\r\n curX = destX || 0,\r\n curY = destY || 0,\r\n distX = 0,\r\n distY = 0,\r\n active = false,\r\n ts = Utils.timestamp(),\r\n cache = 0,\r\n move = 0,\r\n\r\n // positions the image\r\n position = function( dist, cur, pos ) {\r\n if ( dist > 0 ) {\r\n move = M.round( M.max( dist * -1, M.min( 0, cur ) ) );\r\n if ( cache !== move ) {\r\n\r\n cache = move;\r\n\r\n if ( IE === 8 ) { // scroll is faster for IE\r\n img.parent()[ 'scroll' + pos ]( move * -1 );\r\n } else {\r\n var css = {};\r\n css[ pos.toLowerCase() ] = move;\r\n img.css(css);\r\n }\r\n }\r\n }\r\n },\r\n\r\n // calculates mouse position after 50ms\r\n calculate = function(e) {\r\n if (Utils.timestamp() - ts < 50) {\r\n return;\r\n }\r\n active = true;\r\n x = self.getMousePosition(e).x;\r\n y = self.getMousePosition(e).y;\r\n },\r\n\r\n // the main loop to check\r\n loop = function(e) {\r\n\r\n if (!active) {\r\n return;\r\n }\r\n\r\n distX = img.width() - self._stageWidth;\r\n distY = img.height() - self._stageHeight;\r\n destX = x / self._stageWidth * distX * -1;\r\n destY = y / self._stageHeight * distY * -1;\r\n curX += ( destX - curX ) / self._options.imagePanSmoothness;\r\n curY += ( destY - curY ) / self._options.imagePanSmoothness;\r\n\r\n position( distY, curY, 'Top' );\r\n position( distX, curX, 'Left' );\r\n\r\n };\r\n\r\n // we need to use scroll in IE8 to speed things up\r\n if ( IE === 8 ) {\r\n\r\n img.parent().scrollTop( curY * -1 ).scrollLeft( curX * -1 );\r\n img.css({\r\n top: 0,\r\n left: 0\r\n });\r\n\r\n }\r\n\r\n // unbind and bind event\r\n this.$( 'stage' ).off( 'mousemove', calculate ).on( 'mousemove', calculate );\r\n\r\n // loop the loop\r\n this.addTimer( 'pan' + self._id, loop, 50, true);\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Brings the scope into any callback\r\n\r\n @param fn The callback to bring the scope into\r\n @param [scope] Optional scope to bring\r\n\r\n @example $('#fullscreen').click( this.proxy(function() { this.enterFullscreen(); }) )\r\n\r\n @returns {Function} Return the callback with the gallery scope\r\n */\r\n\r\n proxy : function( fn, scope ) {\r\n if ( typeof fn !== 'function' ) {\r\n return F;\r\n }\r\n scope = scope || this;\r\n return function() {\r\n return fn.apply( scope, Utils.array( arguments ) );\r\n };\r\n },\r\n\r\n /**\r\n Tells you the theme name of the gallery\r\n\r\n @returns {String} theme name\r\n */\r\n\r\n getThemeName : function() {\r\n return this.theme.name;\r\n },\r\n\r\n /**\r\n Removes the panning effect set by addPan()\r\n\r\n @returns Instance\r\n */\r\n\r\n removePan: function() {\r\n\r\n // todo: doublecheck IE8\r\n\r\n this.$( 'stage' ).off( 'mousemove' );\r\n\r\n this.clearTimer( 'pan' + this._id );\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Adds an element to the Galleria DOM array.\r\n When you add an element here, you can access it using element ID in many API calls\r\n\r\n @param {string} id The element ID you wish to use. You can add many elements by adding more arguments.\r\n\r\n @example addElement('mybutton');\r\n @example addElement('mybutton','mylink');\r\n\r\n @returns Instance\r\n */\r\n\r\n addElement : function( id ) {\r\n\r\n var dom = this._dom;\r\n\r\n $.each( Utils.array(arguments), function( i, blueprint ) {\r\n dom[ blueprint ] = Utils.create( 'galleria-' + blueprint );\r\n });\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Attach keyboard events to Galleria\r\n\r\n @param {Object} map The map object of events.\r\n Possible keys are 'UP', 'DOWN', 'LEFT', 'RIGHT', 'RETURN', 'ESCAPE', 'BACKSPACE', and 'SPACE'.\r\n\r\n @example\r\n\r\nthis.attachKeyboard({\r\n right: this.next,\r\n left: this.prev,\r\n up: function() {\r\n console.log( 'up key pressed' )\r\n }\r\n});\r\n\r\n @returns Instance\r\n */\r\n\r\n attachKeyboard : function( map ) {\r\n this._keyboard.attach.apply( this._keyboard, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Detach all keyboard events to Galleria\r\n\r\n @returns Instance\r\n */\r\n\r\n detachKeyboard : function() {\r\n this._keyboard.detach.apply( this._keyboard, Utils.array( arguments ) );\r\n return this;\r\n },\r\n\r\n /**\r\n Fast helper for appending galleria elements that you added using addElement()\r\n\r\n @param {string} parentID The parent element ID where the element will be appended\r\n @param {string} childID the element ID that should be appended\r\n\r\n @example this.addElement('myElement');\r\n this.appendChild( 'info', 'myElement' );\r\n\r\n @returns Instance\r\n */\r\n\r\n appendChild : function( parentID, childID ) {\r\n this.$( parentID ).append( this.get( childID ) || childID );\r\n return this;\r\n },\r\n\r\n /**\r\n Fast helper for prepending galleria elements that you added using addElement()\r\n\r\n @param {string} parentID The parent element ID where the element will be prepended\r\n @param {string} childID the element ID that should be prepended\r\n\r\n @example\r\n\r\nthis.addElement('myElement');\r\nthis.prependChild( 'info', 'myElement' );\r\n\r\n @returns Instance\r\n */\r\n\r\n prependChild : function( parentID, childID ) {\r\n this.$( parentID ).prepend( this.get( childID ) || childID );\r\n return this;\r\n },\r\n\r\n /**\r\n Remove an element by blueprint\r\n\r\n @param {string} elemID The element to be removed.\r\n You can remove multiple elements by adding arguments.\r\n\r\n @returns Instance\r\n */\r\n\r\n remove : function( elemID ) {\r\n this.$( Utils.array( arguments ).join(',') ).remove();\r\n return this;\r\n },\r\n\r\n // a fast helper for building dom structures\r\n // leave this out of the API for now\r\n\r\n append : function( data ) {\r\n var i, j;\r\n for( i in data ) {\r\n if ( data.hasOwnProperty( i ) ) {\r\n if ( data[i].constructor === Array ) {\r\n for( j = 0; data[i][j]; j++ ) {\r\n this.appendChild( i, data[i][j] );\r\n }\r\n } else {\r\n this.appendChild( i, data[i] );\r\n }\r\n }\r\n }\r\n return this;\r\n },\r\n\r\n // an internal helper for scaling according to options\r\n _scaleImage : function( image, options ) {\r\n\r\n image = image || this._controls.getActive();\r\n\r\n // janpub (JH) fix:\r\n // image might be unselected yet\r\n // e.g. when external logics rescales the gallery on window resize events\r\n if( !image ) {\r\n return;\r\n }\r\n\r\n var complete,\r\n\r\n scaleLayer = function( img ) {\r\n $( img.container ).children(':first').css({\r\n top: M.max(0, Utils.parseValue( img.image.style.top )),\r\n left: M.max(0, Utils.parseValue( img.image.style.left )),\r\n width: Utils.parseValue( img.image.width ),\r\n height: Utils.parseValue( img.image.height )\r\n });\r\n };\r\n\r\n options = $.extend({\r\n width: this._stageWidth,\r\n height: this._stageHeight,\r\n crop: this._options.imageCrop,\r\n max: this._options.maxScaleRatio,\r\n min: this._options.minScaleRatio,\r\n margin: this._options.imageMargin,\r\n position: this._options.imagePosition,\r\n iframelimit: this._options.maxVideoSize\r\n }, options );\r\n\r\n if ( this._options.layerFollow && this._options.imageCrop !== true ) {\r\n\r\n if ( typeof options.complete == 'function' ) {\r\n complete = options.complete;\r\n options.complete = function() {\r\n complete.call( image, image );\r\n scaleLayer( image );\r\n };\r\n } else {\r\n options.complete = scaleLayer;\r\n }\r\n\r\n } else {\r\n $( image.container ).children(':first').css({ top: 0, left: 0 });\r\n }\r\n\r\n image.scale( options );\r\n return this;\r\n },\r\n\r\n /**\r\n Updates the carousel,\r\n useful if you resize the gallery and want to re-check if the carousel nav is needed.\r\n\r\n @returns Instance\r\n */\r\n\r\n updateCarousel : function() {\r\n this._carousel.update();\r\n return this;\r\n },\r\n\r\n /**\r\n Resize the entire gallery container\r\n\r\n @param {Object} [measures] Optional object with width/height specified\r\n @param {Function} [complete] The callback to be called when the scaling is complete\r\n\r\n @returns Instance\r\n */\r\n\r\n resize : function( measures, complete ) {\r\n\r\n if ( typeof measures == 'function' ) {\r\n complete = measures;\r\n measures = undef;\r\n }\r\n\r\n measures = $.extend( { width:0, height:0 }, measures );\r\n\r\n var self = this,\r\n $container = this.$( 'container' );\r\n\r\n $.each( measures, function( m, val ) {\r\n if ( !val ) {\r\n $container[ m ]( 'auto' );\r\n measures[ m ] = self._getWH()[ m ];\r\n }\r\n });\r\n\r\n $.each( measures, function( m, val ) {\r\n $container[ m ]( val );\r\n });\r\n\r\n return this.rescale( complete );\r\n\r\n },\r\n\r\n /**\r\n Rescales the gallery\r\n\r\n @param {number} width The target width\r\n @param {number} height The target height\r\n @param {Function} complete The callback to be called when the scaling is complete\r\n\r\n @returns Instance\r\n */\r\n\r\n rescale : function( width, height, complete ) {\r\n\r\n var self = this;\r\n\r\n // allow rescale(fn)\r\n if ( typeof width === 'function' ) {\r\n complete = width;\r\n width = undef;\r\n }\r\n\r\n var scale = function() {\r\n\r\n // set stagewidth\r\n self._stageWidth = width || self.$( 'stage' ).width();\r\n self._stageHeight = height || self.$( 'stage' ).height();\r\n\r\n if ( self._options.swipe ) {\r\n $.each( self._controls.slides, function(i, img) {\r\n self._scaleImage( img );\r\n $( img.container ).css('left', self._stageWidth * i);\r\n });\r\n self.$('images').css('width', self._stageWidth * self.getDataLength());\r\n } else {\r\n // scale the active image\r\n self._scaleImage();\r\n }\r\n\r\n if ( self._options.carousel ) {\r\n self.updateCarousel();\r\n }\r\n\r\n var frame = self._controls.frames[ self._controls.active ];\r\n\r\n if (frame) {\r\n self._controls.frames[ self._controls.active ].scale({\r\n width: self._stageWidth,\r\n height: self._stageHeight,\r\n iframelimit: self._options.maxVideoSize\r\n });\r\n }\r\n\r\n self.trigger( Galleria.RESCALE );\r\n\r\n if ( typeof complete === 'function' ) {\r\n complete.call( self );\r\n }\r\n };\r\n\r\n scale.call( self );\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Refreshes the gallery.\r\n Useful if you change image options at runtime and want to apply the changes to the active image.\r\n\r\n @returns Instance\r\n */\r\n\r\n refreshImage : function() {\r\n this._scaleImage();\r\n if ( this._options.imagePan ) {\r\n this.addPan();\r\n }\r\n return this;\r\n },\r\n\r\n _preload: function() {\r\n if ( this._options.preload ) {\r\n var p, i,\r\n n = this.getNext(),\r\n ndata;\r\n try {\r\n for ( i = this._options.preload; i > 0; i-- ) {\r\n p = new Galleria.Picture();\r\n ndata = this.getData( n );\r\n p.preload( this.isFullscreen() && ndata.big ? ndata.big : ndata.image );\r\n n = this.getNext( n );\r\n }\r\n } catch(e) {}\r\n }\r\n },\r\n\r\n /**\r\n Shows an image by index\r\n\r\n @param {number|boolean} index The index to show\r\n @param {Boolean} rewind A boolean that should be true if you want the transition to go back\r\n\r\n @returns Instance\r\n */\r\n\r\n show : function( index, rewind, _history ) {\r\n\r\n var swipe = this._options.swipe;\r\n\r\n // do nothing queue is long || index is false || queue is false and transition is in progress\r\n if ( !swipe &&\r\n ( this._queue.length > 3 || index === false || ( !this._options.queue && this._queue.stalled ) ) ) {\r\n return;\r\n }\r\n\r\n index = M.max( 0, M.min( parseInt( index, 10 ), this.getDataLength() - 1 ) );\r\n\r\n rewind = typeof rewind !== 'undefined' ? !!rewind : index < this.getIndex();\r\n\r\n _history = _history || false;\r\n\r\n // do the history thing and return\r\n if ( !_history && Galleria.History ) {\r\n Galleria.History.set( index.toString() );\r\n return;\r\n }\r\n\r\n if ( this.finger && index !== this._active ) {\r\n this.finger.to = -( index*this.finger.width );\r\n this.finger.index = index;\r\n }\r\n this._active = index;\r\n\r\n // we do things a bit simpler in swipe:\r\n if ( swipe ) {\r\n\r\n var data = this.getData(index),\r\n self = this;\r\n if ( !data ) {\r\n return;\r\n }\r\n\r\n var src = this.isFullscreen() && data.big ? data.big : ( data.image || data.iframe ),\r\n image = this._controls.slides[index],\r\n cached = image.isCached( src ),\r\n thumb = this._thumbnails[ index ];\r\n\r\n var evObj = {\r\n cached: cached,\r\n index: index,\r\n rewind: rewind,\r\n imageTarget: image.image,\r\n thumbTarget: thumb.image,\r\n galleriaData: data\r\n };\r\n\r\n this.trigger($.extend(evObj, {\r\n type: Galleria.LOADSTART\r\n }));\r\n\r\n self.$('container').removeClass( 'videoplay' );\r\n\r\n var complete = function() {\r\n\r\n self._layers[index].innerHTML = self.getData().layer || '';\r\n\r\n self.trigger($.extend(evObj, {\r\n type: Galleria.LOADFINISH\r\n }));\r\n self._playCheck();\r\n };\r\n\r\n self._preload();\r\n\r\n window.setTimeout(function() {\r\n\r\n // load if not ready\r\n if ( !image.ready || $(image.image).attr('src') != src ) {\r\n if ( data.iframe && !data.image ) {\r\n image.isIframe = true;\r\n }\r\n image.load(src, function(image) {\r\n evObj.imageTarget = image.image;\r\n self._scaleImage(image, complete).trigger($.extend(evObj, {\r\n type: Galleria.IMAGE\r\n }));\r\n complete();\r\n });\r\n } else {\r\n self.trigger($.extend(evObj, {\r\n type: Galleria.IMAGE\r\n }));\r\n complete();\r\n }\r\n }, 100);\r\n\r\n } else {\r\n protoArray.push.call( this._queue, {\r\n index : index,\r\n rewind : rewind\r\n });\r\n if ( !this._queue.stalled ) {\r\n this._show();\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n // the internal _show method does the actual showing\r\n _show : function() {\r\n\r\n // shortcuts\r\n var self = this,\r\n queue = this._queue[ 0 ],\r\n data = this.getData( queue.index );\r\n\r\n if ( !data ) {\r\n return;\r\n }\r\n\r\n var src = this.isFullscreen() && data.big ? data.big : ( data.image || data.iframe ),\r\n active = this._controls.getActive(),\r\n next = this._controls.getNext(),\r\n cached = next.isCached( src ),\r\n thumb = this._thumbnails[ queue.index ],\r\n mousetrigger = function() {\r\n $( next.image ).trigger( 'mouseup' );\r\n };\r\n\r\n self.$('container').toggleClass('iframe', !!data.isIframe).removeClass( 'videoplay' );\r\n\r\n // to be fired when loading & transition is complete:\r\n var complete = (function( data, next, active, queue, thumb ) {\r\n\r\n return function() {\r\n\r\n var win;\r\n\r\n _transitions.active = false;\r\n\r\n // optimize quality\r\n Utils.toggleQuality( next.image, self._options.imageQuality );\r\n\r\n // remove old layer\r\n self._layers[ self._controls.active ].innerHTML = '';\r\n\r\n // swap\r\n $( active.container ).css({\r\n zIndex: 0,\r\n opacity: 0\r\n }).show();\r\n\r\n $( active.container ).find( 'iframe, .galleria-videoicon' ).remove();\r\n $( self._controls.frames[ self._controls.active ].container ).hide();\r\n\r\n $( next.container ).css({\r\n zIndex: 1,\r\n left: 0,\r\n top: 0\r\n }).show();\r\n\r\n self._controls.swap();\r\n\r\n // add pan according to option\r\n if ( self._options.imagePan ) {\r\n self.addPan( next.image );\r\n }\r\n\r\n // make the image clickable\r\n // order of precedence: iframe, link, lightbox, clicknext\r\n if ( ( data.iframe && data.image ) || data.link || self._options.lightbox || self._options.clicknext ) {\r\n\r\n $( next.image ).css({\r\n cursor: 'pointer'\r\n }).on( 'mouseup', function( e ) {\r\n\r\n // non-left click\r\n if ( typeof e.which == 'number' && e.which > 1 ) {\r\n return;\r\n }\r\n\r\n // iframe / video\r\n if ( data.iframe ) {\r\n\r\n if ( self.isPlaying() ) {\r\n self.pause();\r\n }\r\n var frame = self._controls.frames[ self._controls.active ],\r\n w = self._stageWidth,\r\n h = self._stageHeight;\r\n\r\n $( frame.container ).css({\r\n width: w,\r\n height: h,\r\n opacity: 0\r\n }).show().animate({\r\n opacity: 1\r\n }, 200);\r\n\r\n window.setTimeout(function() {\r\n frame.load( data.iframe + ( data.video ? '&autoplay=1' : '' ), {\r\n width: w,\r\n height: h\r\n }, function( frame ) {\r\n self.$( 'container' ).addClass( 'videoplay' );\r\n frame.scale({\r\n width: self._stageWidth,\r\n height: self._stageHeight,\r\n iframelimit: data.video ? self._options.maxVideoSize : undef\r\n });\r\n });\r\n }, 100);\r\n\r\n return;\r\n }\r\n\r\n // clicknext\r\n if ( self._options.clicknext && !Galleria.TOUCH ) {\r\n if ( self._options.pauseOnInteraction ) {\r\n self.pause();\r\n }\r\n self.next();\r\n return;\r\n }\r\n\r\n // popup link\r\n if ( data.link ) {\r\n if ( self._options.popupLinks ) {\r\n win = window.open( data.link, '_blank' );\r\n } else {\r\n window.location.href = data.link;\r\n }\r\n return;\r\n }\r\n\r\n if ( self._options.lightbox ) {\r\n self.openLightbox();\r\n }\r\n\r\n });\r\n }\r\n\r\n // check if we are playing\r\n self._playCheck();\r\n\r\n // trigger IMAGE event\r\n self.trigger({\r\n type: Galleria.IMAGE,\r\n index: queue.index,\r\n imageTarget: next.image,\r\n thumbTarget: thumb.image,\r\n galleriaData: data\r\n });\r\n\r\n // remove the queued image\r\n protoArray.shift.call( self._queue );\r\n\r\n // remove stalled\r\n self._queue.stalled = false;\r\n\r\n // if we still have images in the queue, show it\r\n if ( self._queue.length ) {\r\n self._show();\r\n }\r\n\r\n };\r\n }( data, next, active, queue, thumb ));\r\n\r\n // let the carousel follow\r\n if ( this._options.carousel && this._options.carouselFollow ) {\r\n this._carousel.follow( queue.index );\r\n }\r\n\r\n // preload images\r\n self._preload();\r\n\r\n // show the next image, just in case\r\n Utils.show( next.container );\r\n\r\n next.isIframe = data.iframe && !data.image;\r\n\r\n // add active classes\r\n $( self._thumbnails[ queue.index ].container )\r\n .addClass( 'active' )\r\n .siblings( '.active' )\r\n .removeClass( 'active' );\r\n\r\n // trigger the LOADSTART event\r\n self.trigger( {\r\n type: Galleria.LOADSTART,\r\n cached: cached,\r\n index: queue.index,\r\n rewind: queue.rewind,\r\n imageTarget: next.image,\r\n thumbTarget: thumb.image,\r\n galleriaData: data\r\n });\r\n\r\n // stall the queue\r\n self._queue.stalled = true;\r\n\r\n // begin loading the next image\r\n next.load( src, function( next ) {\r\n\r\n // add layer HTML\r\n var layer = $( self._layers[ 1-self._controls.active ] ).html( data.layer || '' ).hide();\r\n\r\n self._scaleImage( next, {\r\n\r\n complete: function( next ) {\r\n\r\n // toggle low quality for IE\r\n if ( 'image' in active ) {\r\n Utils.toggleQuality( active.image, false );\r\n }\r\n Utils.toggleQuality( next.image, false );\r\n\r\n // remove the image panning, if applied\r\n // TODO: rethink if this is necessary\r\n self.removePan();\r\n\r\n // set the captions and counter\r\n self.setInfo( queue.index );\r\n self.setCounter( queue.index );\r\n\r\n // show the layer now\r\n if ( data.layer ) {\r\n layer.show();\r\n // inherit click events set on image\r\n if ( ( data.iframe && data.image ) || data.link || self._options.lightbox || self._options.clicknext ) {\r\n layer.css( 'cursor', 'pointer' ).off( 'mouseup' ).mouseup( mousetrigger );\r\n }\r\n }\r\n\r\n // add play icon\r\n if( data.video && data.image ) {\r\n _playIcon( next.container );\r\n }\r\n\r\n var transition = self._options.transition;\r\n\r\n // can JavaScript loop through objects in order? yes.\r\n $.each({\r\n initial: active.image === null,\r\n touch: Galleria.TOUCH,\r\n fullscreen: self.isFullscreen()\r\n }, function( type, arg ) {\r\n if ( arg && self._options[ type + 'Transition' ] !== undef ) {\r\n transition = self._options[ type + 'Transition' ];\r\n return false;\r\n }\r\n });\r\n\r\n // validate the transition\r\n if ( transition in _transitions.effects === false ) {\r\n complete();\r\n } else {\r\n var params = {\r\n prev: active.container,\r\n next: next.container,\r\n rewind: queue.rewind,\r\n speed: self._options.transitionSpeed || 400\r\n };\r\n\r\n _transitions.active = true;\r\n\r\n // call the transition function and send some stuff\r\n _transitions.init.call( self, transition, params, complete );\r\n\r\n }\r\n\r\n // trigger the LOADFINISH event\r\n self.trigger({\r\n type: Galleria.LOADFINISH,\r\n cached: cached,\r\n index: queue.index,\r\n rewind: queue.rewind,\r\n imageTarget: next.image,\r\n thumbTarget: self._thumbnails[ queue.index ].image,\r\n galleriaData: self.getData( queue.index )\r\n });\r\n }\r\n });\r\n });\r\n },\r\n\r\n /**\r\n Gets the next index\r\n\r\n @param {number} [base] Optional starting point\r\n\r\n @returns {number} the next index, or the first if you are at the first (looping)\r\n */\r\n\r\n getNext : function( base ) {\r\n base = typeof base === 'number' ? base : this.getIndex();\r\n return base === this.getDataLength() - 1 ? 0 : base + 1;\r\n },\r\n\r\n /**\r\n Gets the previous index\r\n\r\n @param {number} [base] Optional starting point\r\n\r\n @returns {number} the previous index, or the last if you are at the first (looping)\r\n */\r\n\r\n getPrev : function( base ) {\r\n base = typeof base === 'number' ? base : this.getIndex();\r\n return base === 0 ? this.getDataLength() - 1 : base - 1;\r\n },\r\n\r\n /**\r\n Shows the next image in line\r\n\r\n @returns Instance\r\n */\r\n\r\n next : function() {\r\n if ( this.getDataLength() > 1 ) {\r\n this.show( this.getNext(), false );\r\n }\r\n return this;\r\n },\r\n\r\n /**\r\n Shows the previous image in line\r\n\r\n @returns Instance\r\n */\r\n\r\n prev : function() {\r\n if ( this.getDataLength() > 1 ) {\r\n this.show( this.getPrev(), true );\r\n }\r\n return this;\r\n },\r\n\r\n /**\r\n Retrieve a DOM element by element ID\r\n\r\n @param {string} elemId The delement ID to fetch\r\n\r\n @returns {HTMLElement} The elements DOM node or null if not found.\r\n */\r\n\r\n get : function( elemId ) {\r\n return elemId in this._dom ? this._dom[ elemId ] : null;\r\n },\r\n\r\n /**\r\n Retrieve a data object\r\n\r\n @param {number} index The data index to retrieve.\r\n If no index specified it will take the currently active image\r\n\r\n @returns {Object} The data object\r\n */\r\n\r\n getData : function( index ) {\r\n return index in this._data ?\r\n this._data[ index ] : this._data[ this._active ];\r\n },\r\n\r\n /**\r\n Retrieve the number of data items\r\n\r\n @returns {number} The data length\r\n */\r\n getDataLength : function() {\r\n return this._data.length;\r\n },\r\n\r\n /**\r\n Retrieve the currently active index\r\n\r\n @returns {number|boolean} The active index or false if none found\r\n */\r\n\r\n getIndex : function() {\r\n return typeof this._active === 'number' ? this._active : false;\r\n },\r\n\r\n /**\r\n Retrieve the stage height\r\n\r\n @returns {number} The stage height\r\n */\r\n\r\n getStageHeight : function() {\r\n return this._stageHeight;\r\n },\r\n\r\n /**\r\n Retrieve the stage width\r\n\r\n @returns {number} The stage width\r\n */\r\n\r\n getStageWidth : function() {\r\n return this._stageWidth;\r\n },\r\n\r\n /**\r\n Retrieve the option\r\n\r\n @param {string} key The option key to retrieve. If no key specified it will return all options in an object.\r\n\r\n @returns option or options\r\n */\r\n\r\n getOptions : function( key ) {\r\n return typeof key === 'undefined' ? this._options : this._options[ key ];\r\n },\r\n\r\n /**\r\n Set options to the instance.\r\n You can set options using a key & value argument or a single object argument (see examples)\r\n\r\n @param {string} key The option key\r\n @param {string} value the the options value\r\n\r\n @example setOptions( 'autoplay', true )\r\n @example setOptions({ autoplay: true });\r\n\r\n @returns Instance\r\n */\r\n\r\n setOptions : function( key, value ) {\r\n if ( typeof key === 'object' ) {\r\n $.extend( this._options, key );\r\n } else {\r\n this._options[ key ] = value;\r\n }\r\n return this;\r\n },\r\n\r\n /**\r\n Starts playing the slideshow\r\n\r\n @param {number} delay Sets the slideshow interval in milliseconds.\r\n If you set it once, you can just call play() and get the same interval the next time.\r\n\r\n @returns Instance\r\n */\r\n\r\n play : function( delay ) {\r\n\r\n this._playing = true;\r\n\r\n this._playtime = delay || this._playtime;\r\n\r\n this._playCheck();\r\n\r\n this.trigger( Galleria.PLAY );\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Stops the slideshow if currently playing\r\n\r\n @returns Instance\r\n */\r\n\r\n pause : function() {\r\n\r\n this._playing = false;\r\n\r\n this.trigger( Galleria.PAUSE );\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Toggle between play and pause events.\r\n\r\n @param {number} delay Sets the slideshow interval in milliseconds.\r\n\r\n @returns Instance\r\n */\r\n\r\n playToggle : function( delay ) {\r\n return ( this._playing ) ? this.pause() : this.play( delay );\r\n },\r\n\r\n /**\r\n Checks if the gallery is currently playing\r\n\r\n @returns {Boolean}\r\n */\r\n\r\n isPlaying : function() {\r\n return this._playing;\r\n },\r\n\r\n /**\r\n Checks if the gallery is currently in fullscreen mode\r\n\r\n @returns {Boolean}\r\n */\r\n\r\n isFullscreen : function() {\r\n return this._fullscreen.active;\r\n },\r\n\r\n _playCheck : function() {\r\n var self = this,\r\n played = 0,\r\n interval = 20,\r\n now = Utils.timestamp(),\r\n timer_id = 'play' + this._id;\r\n\r\n if ( this._playing ) {\r\n\r\n this.clearTimer( timer_id );\r\n\r\n var fn = function() {\r\n\r\n played = Utils.timestamp() - now;\r\n if ( played >= self._playtime && self._playing ) {\r\n self.clearTimer( timer_id );\r\n self.next();\r\n return;\r\n }\r\n if ( self._playing ) {\r\n\r\n // trigger the PROGRESS event\r\n self.trigger({\r\n type: Galleria.PROGRESS,\r\n percent: M.ceil( played / self._playtime * 100 ),\r\n seconds: M.floor( played / 1000 ),\r\n milliseconds: played\r\n });\r\n\r\n self.addTimer( timer_id, fn, interval );\r\n }\r\n };\r\n self.addTimer( timer_id, fn, interval );\r\n }\r\n },\r\n\r\n /**\r\n Modify the slideshow delay\r\n\r\n @param {number} delay the number of milliseconds between slides,\r\n\r\n @returns Instance\r\n */\r\n\r\n setPlaytime: function( delay ) {\r\n this._playtime = delay;\r\n return this;\r\n },\r\n\r\n setIndex: function( val ) {\r\n this._active = val;\r\n return this;\r\n },\r\n\r\n /**\r\n Manually modify the counter\r\n\r\n @param {number} [index] Optional data index to fectch,\r\n if no index found it assumes the currently active index\r\n\r\n @returns Instance\r\n */\r\n\r\n setCounter: function( index ) {\r\n\r\n if ( typeof index === 'number' ) {\r\n index++;\r\n } else if ( typeof index === 'undefined' ) {\r\n index = this.getIndex()+1;\r\n }\r\n\r\n this.get( 'current' ).innerHTML = index;\r\n\r\n if ( IE ) { // weird IE bug\r\n\r\n var count = this.$( 'counter' ),\r\n opacity = count.css( 'opacity' );\r\n\r\n if ( parseInt( opacity, 10 ) === 1) {\r\n Utils.removeAlpha( count[0] );\r\n } else {\r\n this.$( 'counter' ).css( 'opacity', opacity );\r\n }\r\n\r\n }\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Manually set captions\r\n\r\n @param {number} [index] Optional data index to fectch and apply as caption,\r\n if no index found it assumes the currently active index\r\n\r\n @returns Instance\r\n */\r\n\r\n setInfo : function( index ) {\r\n\r\n var self = this,\r\n data = this.getData( index );\r\n\r\n $.each( ['title','description'], function( i, type ) {\r\n\r\n var elem = self.$( 'info-' + type );\r\n\r\n if ( !!data[type] ) {\r\n elem[ data[ type ].length ? 'show' : 'hide' ]().html( data[ type ] );\r\n } else {\r\n elem.empty().hide();\r\n }\r\n });\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n Checks if the data contains any captions\r\n\r\n @param {number} [index] Optional data index to fectch,\r\n if no index found it assumes the currently active index.\r\n\r\n @returns {boolean}\r\n */\r\n\r\n hasInfo : function( index ) {\r\n\r\n var check = 'title description'.split(' '),\r\n i;\r\n\r\n for ( i = 0; check[i]; i++ ) {\r\n if ( !!this.getData( index )[ check[i] ] ) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n\r\n },\r\n\r\n jQuery : function( str ) {\r\n\r\n var self = this,\r\n ret = [];\r\n\r\n $.each( str.split(','), function( i, elemId ) {\r\n elemId = $.trim( elemId );\r\n\r\n if ( self.get( elemId ) ) {\r\n ret.push( elemId );\r\n }\r\n });\r\n\r\n var jQ = $( self.get( ret.shift() ) );\r\n\r\n $.each( ret, function( i, elemId ) {\r\n jQ = jQ.add( self.get( elemId ) );\r\n });\r\n\r\n return jQ;\r\n\r\n },\r\n\r\n /**\r\n Converts element IDs into a jQuery collection\r\n You can call for multiple IDs separated with commas.\r\n\r\n @param {string} str One or more element IDs (comma-separated)\r\n\r\n @returns jQuery\r\n\r\n @example this.$('info,container').hide();\r\n */\r\n\r\n $ : function( str ) {\r\n return this.jQuery.apply( this, Utils.array( arguments ) );\r\n }\r\n\r\n};\r\n\r\n// End of Galleria prototype\r\n\r\n// Add events as static variables\r\n$.each( _events, function( i, ev ) {\r\n\r\n // legacy events\r\n var type = /_/.test( ev ) ? ev.replace( /_/g, '' ) : ev;\r\n\r\n Galleria[ ev.toUpperCase() ] = 'galleria.'+type;\r\n\r\n} );\r\n\r\n$.extend( Galleria, {\r\n\r\n // Browser helpers\r\n IE9: IE === 9,\r\n IE8: IE === 8,\r\n IE7: IE === 7,\r\n IE6: IE === 6,\r\n IE: IE,\r\n WEBKIT: /webkit/.test( NAV ),\r\n CHROME: /chrome/.test( NAV ),\r\n SAFARI: /safari/.test( NAV ) && !(/chrome/.test( NAV )),\r\n QUIRK: ( IE && doc.compatMode && doc.compatMode === \"BackCompat\" ),\r\n MAC: /mac/.test( navigator.platform.toLowerCase() ),\r\n OPERA: !!window.opera,\r\n IPHONE: /iphone/.test( NAV ),\r\n IPAD: /ipad/.test( NAV ),\r\n ANDROID: /android/.test( NAV ),\r\n TOUCH: ('ontouchstart' in doc)\r\n\r\n});\r\n\r\n// Galleria static methods\r\n\r\n/**\r\n Adds a theme that you can use for your Gallery\r\n\r\n @param {Object} theme Object that should contain all your theme settings.\r\n
      \r\n
    • name - name of the theme
    • \r\n
    • author - name of the author
    • \r\n
    • css - css file name (not path)
    • \r\n
    • defaults - default options to apply, including theme-specific options
    • \r\n
    • init - the init function
    • \r\n
    \r\n\r\n @returns {Object} theme\r\n*/\r\n\r\nGalleria.addTheme = function( theme ) {\r\n\r\n // make sure we have a name\r\n if ( !theme.name ) {\r\n Galleria.raise('No theme name specified');\r\n }\r\n\r\n if ( typeof theme.defaults !== 'object' ) {\r\n theme.defaults = {};\r\n } else {\r\n theme.defaults = _legacyOptions( theme.defaults );\r\n }\r\n\r\n var css = false,\r\n reg;\r\n\r\n if ( typeof theme.css === 'string' ) {\r\n\r\n // look for manually added CSS\r\n $('link').each(function( i, link ) {\r\n reg = new RegExp( theme.css );\r\n if ( reg.test( link.href ) ) {\r\n\r\n // we found the css\r\n css = true;\r\n\r\n // the themeload trigger\r\n _themeLoad( theme );\r\n\r\n return false;\r\n }\r\n });\r\n\r\n // else look for the absolute path and load the CSS dynamic\r\n if ( !css ) {\r\n\r\n\r\n $(function() {\r\n // Try to determine the css-path from the theme script.\r\n // In IE8/9, the script-dom-element seems to be not present\r\n // at once, if galleria itself is inserted into the dom\r\n // dynamically. We therefore try multiple times before raising\r\n // an error.\r\n var retryCount = 0;\r\n var tryLoadCss = function() {\r\n $('script').each(function (i, script) {\r\n // look for the theme script\r\n reg = new RegExp('galleria\\\\.' + theme.name.toLowerCase() + '\\\\.');\r\n if (reg.test(script.src)) {\r\n\r\n // we have a match\r\n css = script.src.replace(/[^\\/]*$/, '') + theme.css;\r\n\r\n window.setTimeout(function () {\r\n Utils.loadCSS(css, 'galleria-theme-'+theme.name, function () {\r\n\r\n // run galleries with this theme\r\n _themeLoad(theme);\r\n\r\n });\r\n }, 1);\r\n }\r\n });\r\n if (!css) {\r\n if (retryCount++ > 5) {\r\n Galleria.raise('No theme CSS loaded');\r\n } else {\r\n window.setTimeout(tryLoadCss, 500);\r\n }\r\n }\r\n };\r\n tryLoadCss();\r\n });\r\n }\r\n\r\n } else {\r\n\r\n // pass\r\n _themeLoad( theme );\r\n }\r\n return theme;\r\n};\r\n\r\n/**\r\n loadTheme loads a theme js file and attaches a load event to Galleria\r\n\r\n @param {string} src The relative path to the theme source file\r\n\r\n @param {Object} [options] Optional options you want to apply\r\n\r\n @returns Galleria\r\n*/\r\n\r\nGalleria.loadTheme = function( src, options ) {\r\n\r\n // Don't load if theme is already loaded\r\n if( $('script').filter(function() { return $(this).attr('src') == src; }).length ) {\r\n return;\r\n }\r\n\r\n var loaded = false,\r\n err;\r\n\r\n // start listening for the timeout onload\r\n $( window ).load( function() {\r\n if ( !loaded ) {\r\n // give it another 20 seconds\r\n err = window.setTimeout(function() {\r\n if ( !loaded ) {\r\n Galleria.raise( \"Galleria had problems loading theme at \" + src + \". Please check theme path or load manually.\", true );\r\n }\r\n }, 20000);\r\n }\r\n });\r\n\r\n // load the theme\r\n Utils.loadScript( src, function() {\r\n loaded = true;\r\n window.clearTimeout( err );\r\n });\r\n\r\n return Galleria;\r\n};\r\n\r\n/**\r\n Retrieves a Galleria instance.\r\n\r\n @param {number} [index] Optional index to retrieve.\r\n If no index is supplied, the method will return all instances in an array.\r\n\r\n @returns Instance or Array of instances\r\n*/\r\n\r\nGalleria.get = function( index ) {\r\n if ( !!_instances[ index ] ) {\r\n return _instances[ index ];\r\n } else if ( typeof index !== 'number' ) {\r\n return _instances;\r\n } else {\r\n Galleria.raise('Gallery index ' + index + ' not found');\r\n }\r\n};\r\n\r\n/**\r\n\r\n Configure Galleria options via a static function.\r\n The options will be applied to all instances\r\n\r\n @param {string|object} key The options to apply or a key\r\n\r\n @param [value] If key is a string, this is the value\r\n\r\n @returns Galleria\r\n\r\n*/\r\n\r\nGalleria.configure = function( key, value ) {\r\n\r\n var opts = {};\r\n\r\n if( typeof key == 'string' && value ) {\r\n opts[key] = value;\r\n key = opts;\r\n } else {\r\n $.extend( opts, key );\r\n }\r\n\r\n Galleria.configure.options = opts;\r\n\r\n $.each( Galleria.get(), function(i, instance) {\r\n instance.setOptions( opts );\r\n });\r\n\r\n return Galleria;\r\n};\r\n\r\nGalleria.configure.options = {};\r\n\r\n/**\r\n\r\n Bind a Galleria event to the gallery\r\n\r\n @param {string} type A string representing the galleria event\r\n\r\n @param {function} callback The function that should run when the event is triggered\r\n\r\n @returns Galleria\r\n\r\n*/\r\n\r\nGalleria.on = function( type, callback ) {\r\n if ( !type ) {\r\n return;\r\n }\r\n\r\n callback = callback || F;\r\n\r\n // hash the bind\r\n var hash = type + callback.toString().replace(/\\s/g,'') + Utils.timestamp();\r\n\r\n // for existing instances\r\n $.each( Galleria.get(), function(i, instance) {\r\n instance._binds.push( hash );\r\n instance.bind( type, callback );\r\n });\r\n\r\n // for future instances\r\n Galleria.on.binds.push({\r\n type: type,\r\n callback: callback,\r\n hash: hash\r\n });\r\n\r\n return Galleria;\r\n};\r\n\r\nGalleria.on.binds = [];\r\n\r\n/**\r\n\r\n Run Galleria\r\n Alias for $(selector).galleria(options)\r\n\r\n @param {string} selector A selector of element(s) to intialize galleria to\r\n\r\n @param {object} options The options to apply\r\n\r\n @returns Galleria\r\n\r\n*/\r\n\r\nGalleria.run = function( selector, options ) {\r\n if ( $.isFunction( options ) ) {\r\n options = { extend: options };\r\n }\r\n $( selector || '#galleria' ).galleria( options );\r\n return Galleria;\r\n};\r\n\r\n/**\r\n Creates a transition to be used in your gallery\r\n\r\n @param {string} name The name of the transition that you will use as an option\r\n\r\n @param {Function} fn The function to be executed in the transition.\r\n The function contains two arguments, params and complete.\r\n Use the params Object to integrate the transition, and then call complete when you are done.\r\n\r\n @returns Galleria\r\n\r\n*/\r\n\r\nGalleria.addTransition = function( name, fn ) {\r\n _transitions.effects[name] = fn;\r\n return Galleria;\r\n};\r\n\r\n/**\r\n The Galleria utilites\r\n*/\r\n\r\nGalleria.utils = Utils;\r\n\r\n/**\r\n A helper metod for cross-browser logging.\r\n It uses the console log if available otherwise it falls back to alert\r\n\r\n @example Galleria.log(\"hello\", document.body, [1,2,3]);\r\n*/\r\n\r\nGalleria.log = function() {\r\n var args = Utils.array( arguments );\r\n if( 'console' in window && 'log' in window.console ) {\r\n try {\r\n return window.console.log.apply( window.console, args );\r\n } catch( e ) {\r\n $.each( args, function() {\r\n window.console.log(this);\r\n });\r\n }\r\n } else {\r\n return window.alert( args.join('
    ') );\r\n }\r\n};\r\n\r\n/**\r\n A ready method for adding callbacks when a gallery is ready\r\n Each method is call before the extend option for every instance\r\n\r\n @param {function} callback The function to call\r\n\r\n @returns Galleria\r\n*/\r\n\r\nGalleria.ready = function( fn ) {\r\n if ( typeof fn != 'function' ) {\r\n return Galleria;\r\n }\r\n $.each( _galleries, function( i, gallery ) {\r\n fn.call( gallery, gallery._options );\r\n });\r\n Galleria.ready.callbacks.push( fn );\r\n return Galleria;\r\n};\r\n\r\nGalleria.ready.callbacks = [];\r\n\r\n/**\r\n Method for raising errors\r\n\r\n @param {string} msg The message to throw\r\n\r\n @param {boolean} [fatal] Set this to true to override debug settings and display a fatal error\r\n*/\r\n\r\nGalleria.raise = function( msg, fatal ) {\r\n\r\n var type = fatal ? 'Fatal error' : 'Error',\r\n\r\n css = {\r\n color: '#fff',\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n zIndex: 100000\r\n },\r\n\r\n echo = function( msg ) {\r\n\r\n var html = '
    ' +\r\n ( fatal ? '' + type + ': ' : '' ) +\r\n msg + '
    ';\r\n\r\n $.each( _instances, function() {\r\n\r\n var cont = this.$( 'errors' ),\r\n target = this.$( 'target' );\r\n\r\n if ( !cont.length ) {\r\n\r\n target.css( 'position', 'relative' );\r\n\r\n cont = this.addElement( 'errors' ).appendChild( 'target', 'errors' ).$( 'errors' ).css(css);\r\n }\r\n cont.append( html );\r\n\r\n });\r\n\r\n if ( !_instances.length ) {\r\n $('
    ').css( $.extend( css, { position: 'fixed' } ) ).append( html ).appendTo( DOM().body );\r\n }\r\n };\r\n\r\n // if debug is on, display errors and throw exception if fatal\r\n if ( DEBUG ) {\r\n echo( msg );\r\n if ( fatal ) {\r\n throw new Error(type + ': ' + msg);\r\n }\r\n\r\n // else just echo a silent generic error if fatal\r\n } else if ( fatal ) {\r\n if ( _hasError ) {\r\n return;\r\n }\r\n _hasError = true;\r\n fatal = false;\r\n echo( 'Gallery could not load.' );\r\n }\r\n};\r\n\r\n// Add the version\r\nGalleria.version = VERSION;\r\n\r\nGalleria.getLoadedThemes = function() {\r\n return $.map(_loadedThemes, function(theme) {\r\n return theme.name;\r\n });\r\n};\r\n\r\n/**\r\n A method for checking what version of Galleria the user has installed and throws a readable error if the user needs to upgrade.\r\n Useful when building plugins that requires a certain version to function.\r\n\r\n @param {number} version The minimum version required\r\n\r\n @param {string} [msg] Optional message to display. If not specified, Galleria will throw a generic error.\r\n\r\n @returns Galleria\r\n*/\r\n\r\nGalleria.requires = function( version, msg ) {\r\n msg = msg || 'You need to upgrade Galleria to version ' + version + ' to use one or more components.';\r\n if ( Galleria.version < version ) {\r\n Galleria.raise(msg, true);\r\n }\r\n return Galleria;\r\n};\r\n\r\n/**\r\n Adds preload, cache, scale and crop functionality\r\n\r\n @constructor\r\n\r\n @requires jQuery\r\n\r\n @param {number} [id] Optional id to keep track of instances\r\n*/\r\n\r\nGalleria.Picture = function( id ) {\r\n\r\n // save the id\r\n this.id = id || null;\r\n\r\n // the image should be null until loaded\r\n this.image = null;\r\n\r\n // Create a new container\r\n this.container = Utils.create('galleria-image');\r\n\r\n // add container styles\r\n $( this.container ).css({\r\n overflow: 'hidden',\r\n position: 'relative' // for IE Standards mode\r\n });\r\n\r\n // saves the original measurements\r\n this.original = {\r\n width: 0,\r\n height: 0\r\n };\r\n\r\n // flag when the image is ready\r\n this.ready = false;\r\n\r\n // flag for iframe Picture\r\n this.isIframe = false;\r\n\r\n};\r\n\r\nGalleria.Picture.prototype = {\r\n\r\n // the inherited cache object\r\n cache: {},\r\n\r\n // show the image on stage\r\n show: function() {\r\n Utils.show( this.image );\r\n },\r\n\r\n // hide the image\r\n hide: function() {\r\n Utils.moveOut( this.image );\r\n },\r\n\r\n clear: function() {\r\n this.image = null;\r\n },\r\n\r\n /**\r\n Checks if an image is in cache\r\n\r\n @param {string} src The image source path, ex '/path/to/img.jpg'\r\n\r\n @returns {boolean}\r\n */\r\n\r\n isCached: function( src ) {\r\n return !!this.cache[src];\r\n },\r\n\r\n /**\r\n Preloads an image into the cache\r\n\r\n @param {string} src The image source path, ex '/path/to/img.jpg'\r\n\r\n @returns Galleria.Picture\r\n */\r\n\r\n preload: function( src ) {\r\n $( new Image() ).load((function(src, cache) {\r\n return function() {\r\n cache[ src ] = src;\r\n };\r\n }( src, this.cache ))).attr( 'src', src );\r\n },\r\n\r\n /**\r\n Loads an image and call the callback when ready.\r\n Will also add the image to cache.\r\n\r\n @param {string} src The image source path, ex '/path/to/img.jpg'\r\n @param {Object} [size] The forced size of the image, defined as an object { width: xx, height:xx }\r\n @param {Function} callback The function to be executed when the image is loaded & scaled\r\n\r\n @returns The image container (jQuery object)\r\n */\r\n\r\n load: function(src, size, callback) {\r\n\r\n if ( typeof size == 'function' ) {\r\n callback = size;\r\n size = null;\r\n }\r\n\r\n if( this.isIframe ) {\r\n var id = 'if'+new Date().getTime();\r\n\r\n var iframe = this.image = $('