{"version":3,"sources":["_layouts/mootools/mootools-core-1.4.5.js","_layouts/mootools/mootools-more-1.4.0.1.js","_layouts/mootools/mootools-plugins.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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC12MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClyTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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":"_layouts/framework.bundle.js","sourcesContent":["/*\r\n---\r\n\r\nname: Core\r\n\r\ndescription: The heart of this framework.\r\n\r\nlicense: MIT-style license.\r\n\r\ncopyright: Copyright (c) 2006-2012 [Valerio Proietti](http://mad4milk.net/).\r\n\r\ninspiration:\r\n - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)\r\n - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)\r\n\r\nprovides: [Core, Type, typeOf, instanceOf, Native]\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\n// typeOf, instanceOf\r\n\r\nvar typeOf = this.typeOf = function(item){\r\n\tif (item == null) return 'null';\r\n\tif (item.$family != null) return item.$family();\r\n\r\n\tif (item.nodeName){\r\n\t\tif (item.nodeType == 1) return 'element';\r\n\t\tif (item.nodeType == 3) return (/\\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';\r\n\t} else if (typeof item.length == 'number'){\r\n\t\tif (item.callee) return 'arguments';\r\n\t\tif ('item' in item) return 'collection';\r\n\t}\r\n\r\n\treturn typeof item;\r\n};\r\n\r\nvar instanceOf = this.instanceOf = function(item, object){\r\n\tif (item == null) return false;\r\n\tvar constructor = item.$constructor || item.constructor;\r\n\twhile (constructor){\r\n\t\tif (constructor === object) return true;\r\n\t\tconstructor = constructor.parent;\r\n\t}\r\n\t/**/\r\n\tif (!item.hasOwnProperty) return false;\r\n\t/**/\r\n\treturn item instanceof object;\r\n};\r\n\r\n// Function overloading\r\n\r\nvar Function = this.Function;\r\n\r\nvar enumerables = true;\r\nfor (var i in {toString: 1}) enumerables = null;\r\nif (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];\r\n\r\nFunction.prototype.overloadSetter = function(usePlural){\r\n\tvar self = this;\r\n\treturn function(a, b){\r\n\t\tif (a == null) return this;\r\n\t\tif (usePlural || typeof a != 'string'){\r\n\t\t\tfor (var k in a) self.call(this, k, a[k]);\r\n\t\t\tif (enumerables) for (var i = enumerables.length; i--;){\r\n\t\t\t\tk = enumerables[i];\r\n\t\t\t\tif (a.hasOwnProperty(k)) self.call(this, k, a[k]);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tself.call(this, a, b);\r\n\t\t}\r\n\t\treturn this;\r\n\t};\r\n};\r\n\r\nFunction.prototype.overloadGetter = function(usePlural){\r\n\tvar self = this;\r\n\treturn function(a){\r\n\t\tvar args, result;\r\n\t\tif (typeof a != 'string') args = a;\r\n\t\telse if (arguments.length > 1) args = arguments;\r\n\t\telse if (usePlural) args = [a];\r\n\t\tif (args){\r\n\t\t\tresult = {};\r\n\t\t\tfor (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);\r\n\t\t} else {\r\n\t\t\tresult = self.call(this, a);\r\n\t\t}\r\n\t\treturn result;\r\n\t};\r\n};\r\n\r\nFunction.prototype.extend = function(key, value){\r\n\tthis[key] = value;\r\n}.overloadSetter();\r\n\r\nFunction.prototype.implement = function(key, value){\r\n\tthis.prototype[key] = value;\r\n}.overloadSetter();\r\n\r\n// From\r\n\r\nvar slice = Array.prototype.slice;\r\n\r\nFunction.from = function(item){\r\n\treturn (typeOf(item) == 'function') ? item : function(){\r\n\t\treturn item;\r\n\t};\r\n};\r\n\r\nArray.from = function(item){\r\n\tif (item == null) return [];\r\n\treturn (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];\r\n};\r\n\r\nNumber.from = function(item){\r\n\tvar number = parseFloat(item);\r\n\treturn isFinite(number) ? number : null;\r\n};\r\n\r\nString.from = function(item){\r\n\treturn item + '';\r\n};\r\n\r\n// hide, protect\r\n\r\nFunction.implement({\r\n\r\n\thide: function(){\r\n\t\tthis.$hidden = true;\r\n\t\treturn this;\r\n\t},\r\n\r\n\tprotect: function(){\r\n\t\tthis.$protected = true;\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n// Type\r\n\r\nvar Type = this.Type = function(name, object){\r\n\tif (name){\r\n\t\tvar lower = name.toLowerCase();\r\n\t\tvar typeCheck = function(item){\r\n\t\t\treturn (typeOf(item) == lower);\r\n\t\t};\r\n\r\n\t\tType['is' + name] = typeCheck;\r\n\t\tif (object != null){\r\n\t\t\tobject.prototype.$family = (function(){\r\n\t\t\t\treturn lower;\r\n\t\t\t}).hide();\r\n\t\t\t//<1.2compat>\r\n\t\t\tobject.type = typeCheck;\r\n\t\t\t//\r\n\t\t}\r\n\t}\r\n\r\n\tif (object == null) return null;\r\n\r\n\tobject.extend(this);\r\n\tobject.$constructor = Type;\r\n\tobject.prototype.$constructor = object;\r\n\r\n\treturn object;\r\n};\r\n\r\nvar toString = Object.prototype.toString;\r\n\r\nType.isEnumerable = function(item){\r\n\treturn (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );\r\n};\r\n\r\nvar hooks = {};\r\n\r\nvar hooksOf = function(object){\r\n\tvar type = typeOf(object.prototype);\r\n\treturn hooks[type] || (hooks[type] = []);\r\n};\r\n\r\nvar implement = function(name, method){\r\n\tif (method && method.$hidden) return;\r\n\r\n\tvar hooks = hooksOf(this);\r\n\r\n\tfor (var i = 0; i < hooks.length; i++){\r\n\t\tvar hook = hooks[i];\r\n\t\tif (typeOf(hook) == 'type') implement.call(hook, name, method);\r\n\t\telse hook.call(this, name, method);\r\n\t}\r\n\r\n\tvar previous = this.prototype[name];\r\n\tif (previous == null || !previous.$protected) this.prototype[name] = method;\r\n\r\n\tif (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){\r\n\t\treturn method.apply(item, slice.call(arguments, 1));\r\n\t});\r\n};\r\n\r\nvar extend = function(name, method){\r\n\tif (method && method.$hidden) return;\r\n\tvar previous = this[name];\r\n\tif (previous == null || !previous.$protected) this[name] = method;\r\n};\r\n\r\nType.implement({\r\n\r\n\timplement: implement.overloadSetter(),\r\n\r\n\textend: extend.overloadSetter(),\r\n\r\n\talias: function(name, existing){\r\n\t\timplement.call(this, name, this.prototype[existing]);\r\n\t}.overloadSetter(),\r\n\r\n\tmirror: function(hook){\r\n\t\thooksOf(this).push(hook);\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\nnew Type('Type', Type);\r\n\r\n// Default Types\r\n\r\nvar force = function(name, object, methods){\r\n\tvar isType = (object != Object),\r\n\t\tprototype = object.prototype;\r\n\r\n\tif (isType) object = new Type(name, object);\r\n\r\n\tfor (var i = 0, l = methods.length; i < l; i++){\r\n\t\tvar key = methods[i],\r\n\t\t\tgeneric = object[key],\r\n\t\t\tproto = prototype[key];\r\n\r\n\t\tif (generic) generic.protect();\r\n\t\tif (isType && proto) object.implement(key, proto.protect());\r\n\t}\r\n\r\n\tif (isType){\r\n\t\tvar methodsEnumerable = prototype.propertyIsEnumerable(methods[0]);\r\n\t\tobject.forEachMethod = function(fn){\r\n\t\t\tif (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++){\r\n\t\t\t\tfn.call(prototype, prototype[methods[i]], methods[i]);\r\n\t\t\t}\r\n\t\t\tfor (var key in prototype) fn.call(prototype, prototype[key], key)\r\n\t\t};\r\n\t}\r\n\r\n\treturn force;\r\n};\r\n\r\nforce('String', String, [\r\n\t'charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',\r\n\t'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase'\r\n])('Array', Array, [\r\n\t'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice',\r\n\t'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight'\r\n])('Number', Number, [\r\n\t'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'\r\n])('Function', Function, [\r\n\t'apply', 'call', 'bind'\r\n])('RegExp', RegExp, [\r\n\t'exec', 'test'\r\n])('Object', Object, [\r\n\t'create', 'defineProperty', 'defineProperties', 'keys',\r\n\t'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',\r\n\t'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'\r\n])('Date', Date, ['now']);\r\n\r\nObject.extend = extend.overloadSetter();\r\n\r\nDate.extend('now', function(){\r\n\treturn +(new Date);\r\n});\r\n\r\nnew Type('Boolean', Boolean);\r\n\r\n// fixes NaN returning as Number\r\n\r\nNumber.prototype.$family = function(){\r\n\treturn isFinite(this) ? 'number' : 'null';\r\n}.hide();\r\n\r\n// Number.random\r\n\r\nNumber.extend('random', function(min, max){\r\n\treturn Math.floor(Math.random() * (max - min + 1) + min);\r\n});\r\n\r\n// forEach, each\r\n\r\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\r\nObject.extend('forEach', function(object, fn, bind){\r\n\tfor (var key in object){\r\n\t\tif (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object);\r\n\t}\r\n});\r\n\r\nObject.each = Object.forEach;\r\n\r\nArray.implement({\r\n\r\n\tforEach: function(fn, bind){\r\n\t\tfor (var i = 0, l = this.length; i < l; i++){\r\n\t\t\tif (i in this) fn.call(bind, this[i], i, this);\r\n\t\t}\r\n\t},\r\n\r\n\teach: function(fn, bind){\r\n\t\tArray.forEach(this, fn, bind);\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n// Array & Object cloning, Object merging and appending\r\n\r\nvar cloneOf = function(item){\r\n\tswitch (typeOf(item)){\r\n\t\tcase 'array': return item.clone();\r\n\t\tcase 'object': return Object.clone(item);\r\n\t\tdefault: return item;\r\n\t}\r\n};\r\n\r\nArray.implement('clone', function(){\r\n\tvar i = this.length, clone = new Array(i);\r\n\twhile (i--) clone[i] = cloneOf(this[i]);\r\n\treturn clone;\r\n});\r\n\r\nvar mergeOne = function(source, key, current) {\r\n if (key == \"__proto__\")\r\n return source;\r\n\r\n\tswitch (typeOf(current)){\r\n\t\tcase 'object':\r\n\t\t\tif (typeOf(source[key]) == 'object') Object.merge(source[key], current);\r\n\t\t\telse source[key] = Object.clone(current);\r\n\t\tbreak;\r\n\t\tcase 'array': source[key] = current.clone(); break;\r\n\t\tdefault: source[key] = current;\r\n\t}\r\n\treturn source;\r\n};\r\n\r\nObject.extend({\r\n\r\n\tmerge: function(source, k, v){\r\n\t\tif (typeOf(k) == 'string') return mergeOne(source, k, v);\r\n\t\tfor (var i = 1, l = arguments.length; i < l; i++){\r\n\t\t\tvar object = arguments[i];\r\n\t\t\tfor (var key in object) mergeOne(source, key, object[key]);\r\n\t\t}\r\n\t\treturn source;\r\n\t},\r\n\r\n\tclone: function(object){\r\n\t\tvar clone = {};\r\n\t\tfor (var key in object) clone[key] = cloneOf(object[key]);\r\n\t\treturn clone;\r\n\t},\r\n\r\n\tappend: function(original){\r\n\t\tfor (var i = 1, l = arguments.length; i < l; i++){\r\n\t\t\tvar extended = arguments[i] || {};\r\n\t\t\tfor (var key in extended) original[key] = extended[key];\r\n\t\t}\r\n\t\treturn original;\r\n\t}\r\n\r\n});\r\n\r\n// Object-less types\r\n\r\n['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){\r\n\tnew Type(name);\r\n});\r\n\r\n// Unique ID\r\n\r\nvar UID = Date.now();\r\n\r\nString.extend('uniqueID', function(){\r\n\treturn (UID++).toString(36);\r\n});\r\n\r\n//<1.2compat>\r\n\r\nvar Hash = this.Hash = new Type('Hash', function(object){\r\n\tif (typeOf(object) == 'hash') object = Object.clone(object.getClean());\r\n\tfor (var key in object) this[key] = object[key];\r\n\treturn this;\r\n});\r\n\r\nHash.implement({\r\n\r\n\tforEach: function(fn, bind){\r\n\t\tObject.forEach(this, fn, bind);\r\n\t},\r\n\r\n\tgetClean: function(){\r\n\t\tvar clean = {};\r\n\t\tfor (var key in this){\r\n\t\t\tif (this.hasOwnProperty(key)) clean[key] = this[key];\r\n\t\t}\r\n\t\treturn clean;\r\n\t},\r\n\r\n\tgetLength: function(){\r\n\t\tvar length = 0;\r\n\t\tfor (var key in this){\r\n\t\t\tif (this.hasOwnProperty(key)) length++;\r\n\t\t}\r\n\t\treturn length;\r\n\t}\r\n\r\n});\r\n\r\nHash.alias('each', 'forEach');\r\n\r\nObject.type = Type.isObject;\r\n\r\nvar Native = this.Native = function(properties){\r\n\treturn new Type(properties.name, properties.initialize);\r\n};\r\n\r\nNative.type = Type.type;\r\n\r\nNative.implement = function(objects, methods){\r\n\tfor (var i = 0; i < objects.length; i++) objects[i].implement(methods);\r\n\treturn Native;\r\n};\r\n\r\nvar arrayType = Array.type;\r\nArray.type = function(item){\r\n\treturn instanceOf(item, Array) || arrayType(item);\r\n};\r\n\r\nthis.$A = function(item){\r\n\treturn Array.from(item).slice();\r\n};\r\n\r\nthis.$arguments = function(i){\r\n\treturn function(){\r\n\t\treturn arguments[i];\r\n\t};\r\n};\r\n\r\nthis.$chk = function(obj){\r\n\treturn !!(obj || obj === 0);\r\n};\r\n\r\nthis.$clear = function(timer){\r\n\tclearTimeout(timer);\r\n\tclearInterval(timer);\r\n\treturn null;\r\n};\r\n\r\nthis.$defined = function(obj){\r\n\treturn (obj != null);\r\n};\r\n\r\nthis.$each = function(iterable, fn, bind){\r\n\tvar type = typeOf(iterable);\r\n\t((type == 'arguments' || type == 'collection' || type == 'array' || type == 'elements') ? Array : Object).each(iterable, fn, bind);\r\n};\r\n\r\nthis.$empty = function(){};\r\n\r\nthis.$extend = function(original, extended){\r\n\treturn Object.append(original, extended);\r\n};\r\n\r\nthis.$H = function(object){\r\n\treturn new Hash(object);\r\n};\r\n\r\nthis.$merge = function(){\r\n\tvar args = Array.slice(arguments);\r\n\targs.unshift({});\r\n\treturn Object.merge.apply(null, args);\r\n};\r\n\r\nthis.$lambda = Function.from;\r\nthis.$mixin = Object.merge;\r\nthis.$random = Number.random;\r\nthis.$splat = Array.from;\r\nthis.$time = Date.now;\r\n\r\nthis.$type = function(object){\r\n\tvar type = typeOf(object);\r\n\tif (type == 'elements') return 'array';\r\n\treturn (type == 'null') ? false : type;\r\n};\r\n\r\nthis.$unlink = function(object){\r\n\tswitch (typeOf(object)){\r\n\t\tcase 'object': return Object.clone(object);\r\n\t\tcase 'array': return Array.clone(object);\r\n\t\tcase 'hash': return new Hash(object);\r\n\t\tdefault: return object;\r\n\t}\r\n};\r\n\r\n//\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Array\r\n\r\ndescription: Contains Array Prototypes like each, contains, and erase.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Type\r\n\r\nprovides: Array\r\n\r\n...\r\n*/\r\n\r\nArray.implement({\r\n\r\n\t/**/\r\n\tevery: function(fn, bind){\r\n\t\tfor (var i = 0, l = this.length >>> 0; i < l; i++){\r\n\t\t\tif ((i in this) && !fn.call(bind, this[i], i, this)) return false;\r\n\t\t}\r\n\t\treturn true;\r\n\t},\r\n\r\n\tfilter: function(fn, bind){\r\n\t\tvar results = [];\r\n\t\tfor (var value, i = 0, l = this.length >>> 0; i < l; i++) if (i in this){\r\n\t\t\tvalue = this[i];\r\n\t\t\tif (fn.call(bind, value, i, this)) results.push(value);\r\n\t\t}\r\n\t\treturn results;\r\n\t},\r\n\r\n\tindexOf: function(item, from){\r\n\t\tvar length = this.length >>> 0;\r\n\t\tfor (var i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++){\r\n\t\t\tif (this[i] === item) return i;\r\n\t\t}\r\n\t\treturn -1;\r\n\t},\r\n\r\n\tmap: function(fn, bind){\r\n\t\tvar length = this.length >>> 0, results = Array(length);\r\n\t\tfor (var i = 0; i < length; i++){\r\n\t\t\tif (i in this) results[i] = fn.call(bind, this[i], i, this);\r\n\t\t}\r\n\t\treturn results;\r\n\t},\r\n\r\n\tsome: function(fn, bind){\r\n\t\tfor (var i = 0, l = this.length >>> 0; i < l; i++){\r\n\t\t\tif ((i in this) && fn.call(bind, this[i], i, this)) return true;\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\t/**/\r\n\r\n\tclean: function(){\r\n\t\treturn this.filter(function(item){\r\n\t\t\treturn item != null;\r\n\t\t});\r\n\t},\r\n\r\n\tinvoke: function(methodName){\r\n\t\tvar args = Array.slice(arguments, 1);\r\n\t\treturn this.map(function(item){\r\n\t\t\treturn item[methodName].apply(item, args);\r\n\t\t});\r\n\t},\r\n\r\n\tassociate: function(keys){\r\n\t\tvar obj = {}, length = Math.min(this.length, keys.length);\r\n\t\tfor (var i = 0; i < length; i++) obj[keys[i]] = this[i];\r\n\t\treturn obj;\r\n\t},\r\n\r\n\tlink: function(object){\r\n\t\tvar result = {};\r\n\t\tfor (var i = 0, l = this.length; i < l; i++){\r\n\t\t\tfor (var key in object){\r\n\t\t\t\tif (object[key](this[i])){\r\n\t\t\t\t\tresult[key] = this[i];\r\n\t\t\t\t\tdelete object[key];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result;\r\n\t},\r\n\r\n\tcontains: function(item, from){\r\n\t\treturn this.indexOf(item, from) != -1;\r\n\t},\r\n\r\n\tappend: function(array){\r\n\t\tthis.push.apply(this, array);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tgetLast: function(){\r\n\t\treturn (this.length) ? this[this.length - 1] : null;\r\n\t},\r\n\r\n\tgetRandom: function(){\r\n\t\treturn (this.length) ? this[Number.random(0, this.length - 1)] : null;\r\n\t},\r\n\r\n\tinclude: function(item){\r\n\t\tif (!this.contains(item)) this.push(item);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tcombine: function(array){\r\n\t\tfor (var i = 0, l = array.length; i < l; i++) this.include(array[i]);\r\n\t\treturn this;\r\n\t},\r\n\r\n\terase: function(item){\r\n\t\tfor (var i = this.length; i--;){\r\n\t\t\tif (this[i] === item) this.splice(i, 1);\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\tempty: function(){\r\n\t\tthis.length = 0;\r\n\t\treturn this;\r\n\t},\r\n\r\n\tflatten: function(){\r\n\t\tvar array = [];\r\n\t\tfor (var i = 0, l = this.length; i < l; i++){\r\n\t\t\tvar type = typeOf(this[i]);\r\n\t\t\tif (type == 'null') continue;\r\n\t\t\tarray = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);\r\n\t\t}\r\n\t\treturn array;\r\n\t},\r\n\r\n\tpick: function(){\r\n\t\tfor (var i = 0, l = this.length; i < l; i++){\r\n\t\t\tif (this[i] != null) return this[i];\r\n\t\t}\r\n\t\treturn null;\r\n\t},\r\n\r\n\thexToRgb: function(array){\r\n\t\tif (this.length != 3) return null;\r\n\t\tvar rgb = this.map(function(value){\r\n\t\t\tif (value.length == 1) value += value;\r\n\t\t\treturn value.toInt(16);\r\n\t\t});\r\n\t\treturn (array) ? rgb : 'rgb(' + rgb + ')';\r\n\t},\r\n\r\n\trgbToHex: function(array){\r\n\t\tif (this.length < 3) return null;\r\n\t\tif (this.length == 4 && this[3] == 0 && !array) return 'transparent';\r\n\t\tvar hex = [];\r\n\t\tfor (var i = 0; i < 3; i++){\r\n\t\t\tvar bit = (this[i] - 0).toString(16);\r\n\t\t\thex.push((bit.length == 1) ? '0' + bit : bit);\r\n\t\t}\r\n\t\treturn (array) ? hex : '#' + hex.join('');\r\n\t}\r\n\r\n});\r\n\r\n//<1.2compat>\r\n\r\nArray.alias('extend', 'append');\r\n\r\nvar $pick = function(){\r\n\treturn Array.from(arguments).pick();\r\n};\r\n\r\n//\r\n\r\n\r\n/*\r\n---\r\n\r\nname: String\r\n\r\ndescription: Contains String Prototypes like camelCase, capitalize, test, and toInt.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Type\r\n\r\nprovides: String\r\n\r\n...\r\n*/\r\n\r\nString.implement({\r\n\r\n\ttest: function(regex, params){\r\n\t\treturn ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this);\r\n\t},\r\n\r\n\tcontains: function(string, separator){\r\n\t\treturn (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : String(this).indexOf(string) > -1;\r\n\t},\r\n\r\n\ttrim: function(){\r\n\t\treturn String(this).replace(/^\\s+|\\s+$/g, '');\r\n\t},\r\n\r\n\tclean: function(){\r\n\t\treturn String(this).replace(/\\s+/g, ' ').trim();\r\n\t},\r\n\r\n\tcamelCase: function(){\r\n\t\treturn String(this).replace(/-\\D/g, function(match){\r\n\t\t\treturn match.charAt(1).toUpperCase();\r\n\t\t});\r\n\t},\r\n\r\n\thyphenate: function(){\r\n\t\treturn String(this).replace(/[A-Z]/g, function(match){\r\n\t\t\treturn ('-' + match.charAt(0).toLowerCase());\r\n\t\t});\r\n\t},\r\n\r\n\tcapitalize: function(){\r\n\t\treturn String(this).replace(/\\b[a-z]/g, function(match){\r\n\t\t\treturn match.toUpperCase();\r\n\t\t});\r\n\t},\r\n\r\n escapeHtml: function() {\r\n return String(this).replace(/[&\"'<>]/g, function(c) {\r\n return {\r\n '&': \"&\",\r\n '\"': \""\",\r\n '\\'': \"'\",\r\n '<': \"<\",\r\n '>': \">\"\r\n }[c];\r\n });\r\n },\r\n\r\n\tescapeRegExp: function(){\r\n\t\treturn String(this).replace(/([-.*+?^${}()|[\\]\\/\\\\])/g, '\\\\$1');\r\n\t},\r\n\r\n\ttoInt: function(base){\r\n\t\treturn parseInt(this, base || 10);\r\n\t},\r\n\r\n\ttoFloat: function(){\r\n\t\treturn parseFloat(this);\r\n\t},\r\n\r\n\thexToRgb: function(array){\r\n\t\tvar hex = String(this).match(/^#?(\\w{1,2})(\\w{1,2})(\\w{1,2})$/);\r\n\t\treturn (hex) ? hex.slice(1).hexToRgb(array) : null;\r\n\t},\r\n\r\n\trgbToHex: function(array){\r\n\t\tvar rgb = String(this).match(/\\d{1,3}/g);\r\n\t\treturn (rgb) ? rgb.rgbToHex(array) : null;\r\n\t},\r\n\r\n\tsubstitute: function(object, regexp){\r\n\t\treturn String(this).replace(regexp || (/\\\\?\\{([^{}]+)\\}/g), function(match, name){\r\n\t\t\tif (match.charAt(0) == '\\\\') return match.slice(1);\r\n\t\t\treturn (object[name] != null) ? object[name] : '';\r\n\t\t});\r\n\t}\r\n\r\n});\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Number\r\n\r\ndescription: Contains Number Prototypes like limit, round, times, and ceil.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Type\r\n\r\nprovides: Number\r\n\r\n...\r\n*/\r\n\r\nNumber.implement({\r\n\r\n\tlimit: function(min, max){\r\n\t\treturn Math.min(max, Math.max(min, this));\r\n\t},\r\n\r\n\tround: function(precision){\r\n\t\tprecision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);\r\n\t\treturn Math.round(this * precision) / precision;\r\n\t},\r\n\r\n\ttimes: function(fn, bind){\r\n\t\tfor (var i = 0; i < this; i++) fn.call(bind, i, this);\r\n\t},\r\n\r\n\ttoFloat: function(){\r\n\t\treturn parseFloat(this);\r\n\t},\r\n\r\n\ttoInt: function(base){\r\n\t\treturn parseInt(this, base || 10);\r\n\t}\r\n\r\n});\r\n\r\nNumber.alias('each', 'times');\r\n\r\n(function(math){\r\n\tvar methods = {};\r\n\tmath.each(function(name){\r\n\t\tif (!Number[name]) methods[name] = function(){\r\n\t\t\treturn Math[name].apply(null, [this].concat(Array.from(arguments)));\r\n\t\t};\r\n\t});\r\n\tNumber.implement(methods);\r\n})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Function\r\n\r\ndescription: Contains Function Prototypes like create, bind, pass, and delay.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Type\r\n\r\nprovides: Function\r\n\r\n...\r\n*/\r\n\r\nFunction.extend({\r\n\r\n\tattempt: function(){\r\n\t\tfor (var i = 0, l = arguments.length; i < l; i++){\r\n\t\t\ttry {\r\n\t\t\t\treturn arguments[i]();\r\n\t\t\t} catch (e){}\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n});\r\n\r\nFunction.implement({\r\n\r\n\tattempt: function(args, bind){\r\n\t\ttry {\r\n\t\t\treturn this.apply(bind, Array.from(args));\r\n\t\t} catch (e){}\r\n\r\n\t\treturn null;\r\n\t},\r\n\r\n\t/**/\r\n\tbind: function(that){\r\n\t\tvar self = this,\r\n\t\t\targs = arguments.length > 1 ? Array.slice(arguments, 1) : null,\r\n\t\t\tF = function(){};\r\n\r\n\t\tvar bound = function(){\r\n\t\t\tvar context = that, length = arguments.length;\r\n\t\t\tif (this instanceof bound){\r\n\t\t\t\tF.prototype = self.prototype;\r\n\t\t\t\tcontext = new F;\r\n\t\t\t}\r\n\t\t\tvar result = (!args && !length)\r\n\t\t\t\t? self.call(context)\r\n\t\t\t\t: self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments);\r\n\t\t\treturn context == that ? result : context;\r\n\t\t};\r\n\t\treturn bound;\r\n\t},\r\n\t/**/\r\n\r\n\tpass: function(args, bind){\r\n\t\tvar self = this;\r\n\t\tif (args != null) args = Array.from(args);\r\n\t\treturn function(){\r\n\t\t\treturn self.apply(bind, args || arguments);\r\n\t\t};\r\n\t},\r\n\r\n\tdelay: function(delay, bind, args){\r\n\t\treturn setTimeout(this.pass((args == null ? [] : args), bind), delay);\r\n\t},\r\n\r\n\tperiodical: function(periodical, bind, args){\r\n\t\treturn setInterval(this.pass((args == null ? [] : args), bind), periodical);\r\n\t}\r\n\r\n});\r\n\r\n//<1.2compat>\r\n\r\n//delete Function.prototype.bind;\r\n\r\nFunction.implement({\r\n\r\n\tcreate: function(options){\r\n\t\tvar self = this;\r\n\t\toptions = options || {};\r\n\t\treturn function(event){\r\n\t\t\tvar args = options.arguments;\r\n\t\t\targs = (args != null) ? Array.from(args) : Array.slice(arguments, (options.event) ? 1 : 0);\r\n\t\t\tif (options.event) args = [event || window.event].extend(args);\r\n\t\t\tvar returns = function(){\r\n\t\t\t\treturn self.apply(options.bind || null, args);\r\n\t\t\t};\r\n\t\t\tif (options.delay) return setTimeout(returns, options.delay);\r\n\t\t\tif (options.periodical) return setInterval(returns, options.periodical);\r\n\t\t\tif (options.attempt) return Function.attempt(returns);\r\n\t\t\treturn returns();\r\n\t\t};\r\n\t},\r\n\r\n\t//bind: function(bind) {\r\n\t//\tvar self = this;\r\n\t//\tvar originalArgs = Array.slice(arguments, 1);\r\n\t//\r\n\t//\treturn function() {\r\n\t//\t\tvar newArgs = Array.slice(arguments);\r\n\t//\t\tvar args = originalArgs.concat(newArgs);\r\n\t//\r\n\t//\t\treturn self.apply(bind, args);\r\n\t//\t};\r\n\t//\r\n\t//\r\n\t//bindWithEvent: function(bind) {\r\n\t//\tvar self = this;\r\n\t//\tvar originalArgs = Array.slice(arguments, 1);\r\n\t//\r\n\t//\treturn function(event) {\r\n\t//\t\tvar newArgs = Array.slice(arguments, 1);\r\n\t//\t\tvar args = [event].concat(originalArgs).concat(newArgs);\r\n\t//\r\n\t//\t\treturn self.apply(bind, args);\r\n\t//\t};\r\n\t//},\r\n\r\n\trun: function(args, bind){\r\n\t\treturn this.apply(bind, Array.from(args));\r\n\t}\r\n\r\n});\r\n\r\nif (Object.create == Function.prototype.create) Object.create = null;\r\n\r\nvar $try = Function.attempt;\r\n\r\n//\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Object\r\n\r\ndescription: Object generic methods\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Type\r\n\r\nprovides: [Object, Hash]\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\r\n\r\nObject.extend({\r\n\r\n\tsubset: function(object, keys){\r\n\t\tvar results = {};\r\n\t\tfor (var i = 0, l = keys.length; i < l; i++){\r\n\t\t\tvar k = keys[i];\r\n\t\t\tif (k in object) results[k] = object[k];\r\n\t\t}\r\n\t\treturn results;\r\n\t},\r\n\r\n\tmap: function(object, fn, bind){\r\n\t\tvar results = {};\r\n\t\tfor (var key in object){\r\n\t\t\tif (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object);\r\n\t\t}\r\n\t\treturn results;\r\n\t},\r\n\r\n\tfilter: function(object, fn, bind){\r\n\t\tvar results = {};\r\n\t\tfor (var key in object){\r\n\t\t\tvar value = object[key];\r\n\t\t\tif (hasOwnProperty.call(object, key) && fn.call(bind, value, key, object)) results[key] = value;\r\n\t\t}\r\n\t\treturn results;\r\n\t},\r\n\r\n\tevery: function(object, fn, bind){\r\n\t\tfor (var key in object){\r\n\t\t\tif (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false;\r\n\t\t}\r\n\t\treturn true;\r\n\t},\r\n\r\n\tsome: function(object, fn, bind){\r\n\t\tfor (var key in object){\r\n\t\t\tif (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true;\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\r\n\tkeys: function(object){\r\n\t\tvar keys = [];\r\n\t\tfor (var key in object){\r\n\t\t\tif (hasOwnProperty.call(object, key)) keys.push(key);\r\n\t\t}\r\n\t\treturn keys;\r\n\t},\r\n\r\n\tvalues: function(object){\r\n\t\tvar values = [];\r\n\t\tfor (var key in object){\r\n\t\t\tif (hasOwnProperty.call(object, key)) values.push(object[key]);\r\n\t\t}\r\n\t\treturn values;\r\n\t},\r\n\r\n\tgetLength: function(object){\r\n\t\treturn Object.keys(object).length;\r\n\t},\r\n\r\n\tkeyOf: function(object, value){\r\n\t\tfor (var key in object){\r\n\t\t\tif (hasOwnProperty.call(object, key) && object[key] === value) return key;\r\n\t\t}\r\n\t\treturn null;\r\n\t},\r\n\r\n\tcontains: function(object, value){\r\n\t\treturn Object.keyOf(object, value) != null;\r\n\t},\r\n\r\n\ttoQueryString: function(object, base){\r\n\t\tvar queryString = [];\r\n\r\n\t\tObject.each(object, function(value, key){\r\n\t\t\tif (base) key = base + '[' + key + ']';\r\n\t\t\tvar result;\r\n\t\t\tswitch (typeOf(value)){\r\n\t\t\t\tcase 'object': result = Object.toQueryString(value, key); break;\r\n\t\t\t\tcase 'array':\r\n\t\t\t\t\tvar qs = {};\r\n\t\t\t\t\tvalue.each(function(val, i){\r\n\t\t\t\t\t\tqs[i] = val;\r\n\t\t\t\t\t});\r\n\t\t\t\t\tresult = Object.toQueryString(qs, key);\r\n\t\t\t\tbreak;\r\n\t\t\t\tdefault: result = key + '=' + encodeURIComponent(value);\r\n\t\t\t}\r\n\t\t\tif (value != null) queryString.push(result);\r\n\t\t});\r\n\r\n\t\treturn queryString.join('&');\r\n\t}\r\n\r\n});\r\n\r\n})();\r\n\r\n//<1.2compat>\r\n\r\nHash.implement({\r\n\r\n\thas: Object.prototype.hasOwnProperty,\r\n\r\n\tkeyOf: function(value){\r\n\t\treturn Object.keyOf(this, value);\r\n\t},\r\n\r\n\thasValue: function(value){\r\n\t\treturn Object.contains(this, value);\r\n\t},\r\n\r\n\textend: function(properties){\r\n\t\tHash.each(properties || {}, function(value, key){\r\n\t\t\tHash.set(this, key, value);\r\n\t\t}, this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tcombine: function(properties){\r\n\t\tHash.each(properties || {}, function(value, key){\r\n\t\t\tHash.include(this, key, value);\r\n\t\t}, this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\terase: function(key){\r\n\t\tif (this.hasOwnProperty(key)) delete this[key];\r\n\t\treturn this;\r\n\t},\r\n\r\n\tget: function(key){\r\n\t\treturn (this.hasOwnProperty(key)) ? this[key] : null;\r\n\t},\r\n\r\n\tset: function(key, value){\r\n\t\tif (!this[key] || this.hasOwnProperty(key)) this[key] = value;\r\n\t\treturn this;\r\n\t},\r\n\r\n\tempty: function(){\r\n\t\tHash.each(this, function(value, key){\r\n\t\t\tdelete this[key];\r\n\t\t}, this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tinclude: function(key, value){\r\n\t\tif (this[key] == null) this[key] = value;\r\n\t\treturn this;\r\n\t},\r\n\r\n\tmap: function(fn, bind){\r\n\t\treturn new Hash(Object.map(this, fn, bind));\r\n\t},\r\n\r\n\tfilter: function(fn, bind){\r\n\t\treturn new Hash(Object.filter(this, fn, bind));\r\n\t},\r\n\r\n\tevery: function(fn, bind){\r\n\t\treturn Object.every(this, fn, bind);\r\n\t},\r\n\r\n\tsome: function(fn, bind){\r\n\t\treturn Object.some(this, fn, bind);\r\n\t},\r\n\r\n\tgetKeys: function(){\r\n\t\treturn Object.keys(this);\r\n\t},\r\n\r\n\tgetValues: function(){\r\n\t\treturn Object.values(this);\r\n\t},\r\n\r\n\ttoQueryString: function(base){\r\n\t\treturn Object.toQueryString(this, base);\r\n\t}\r\n\r\n});\r\n\r\nHash.extend = Object.append;\r\n\r\nHash.alias({indexOf: 'keyOf', contains: 'hasValue'});\r\n\r\n//\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Browser\r\n\r\ndescription: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Array, Function, Number, String]\r\n\r\nprovides: [Browser, Window, Document]\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar document = this.document;\r\nvar window = document.window = this;\r\n\r\nvar ua = navigator.userAgent.toLowerCase(),\r\n\tplatform = navigator.platform.toLowerCase(),\r\n\tUA = ua.match(/(opera|ie|firefox|chrome|version)[\\s\\/:]([\\w\\d\\.]+)?.*?(safari|version[\\s\\/:]([\\w\\d\\.]+)|$)/) || [null, 'unknown', 0],\r\n\tmode = UA[1] == 'ie' && document.documentMode;\r\n\r\nvar Browser = this.Browser = {\r\n\r\n\textend: Function.prototype.extend,\r\n\r\n\tname: (UA[1] == 'version') ? UA[3] : UA[1],\r\n\r\n\tversion: mode || parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),\r\n\r\n\tPlatform: {\r\n\t\tname: ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0]\r\n\t},\r\n\r\n\tFeatures: {\r\n\t\txpath: !!(document.evaluate),\r\n\t\tair: !!(window.runtime),\r\n\t\tquery: !!(document.querySelector),\r\n\t\tjson: !!(window.JSON)\r\n\t},\r\n\r\n\tPlugins: {}\r\n\r\n};\r\n\r\nBrowser[Browser.name] = true;\r\nBrowser[Browser.name + parseInt(Browser.version, 10)] = true;\r\nBrowser.Platform[Browser.Platform.name] = true;\r\n\r\nif (ua.contains(\"trident\")) {\r\n Browser[\"ie\"] = true;\r\n\r\n if (ua.contains(\"trident/7.0\"))\r\n Browser.version = 11;\r\n}\r\n \r\n// Request\r\n\r\nBrowser.Request = (function(){\r\n\r\n\tvar XMLHTTP = function(){\r\n\t\treturn new XMLHttpRequest();\r\n\t};\r\n\r\n\tvar MSXML2 = function(){\r\n\t\treturn new ActiveXObject('MSXML2.XMLHTTP');\r\n\t};\r\n\r\n\tvar MSXML = function(){\r\n\t\treturn new ActiveXObject('Microsoft.XMLHTTP');\r\n\t};\r\n\r\n\treturn Function.attempt(function(){\r\n\t\tXMLHTTP();\r\n\t\treturn XMLHTTP;\r\n\t}, function(){\r\n\t\tMSXML2();\r\n\t\treturn MSXML2;\r\n\t}, function(){\r\n\t\tMSXML();\r\n\t\treturn MSXML;\r\n\t});\r\n\r\n})();\r\n\r\nBrowser.Features.xhr = !!(Browser.Request);\r\n\r\n// Flash detection\r\n\r\nvar version = (Function.attempt(function(){\r\n\treturn navigator.plugins['Shockwave Flash'].description;\r\n}, function(){\r\n\treturn new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');\r\n}) || '0 r0').match(/\\d+/g);\r\n\r\nBrowser.Plugins.Flash = {\r\n\tversion: Number(version[0] || '0.' + version[1]) || 0,\r\n\tbuild: Number(version[2]) || 0\r\n};\r\n\r\n// String scripts\r\n\r\nBrowser.exec = function(text){\r\n\tif (!text) return text;\r\n\tif (window.execScript){\r\n\t\twindow.execScript(text);\r\n\t} else {\r\n\t\tvar script = document.createElement('script');\r\n\t\tscript.setAttribute('type', 'text/javascript');\r\n\t\tscript.text = text;\r\n\t\tdocument.head.appendChild(script);\r\n\t\tdocument.head.removeChild(script);\r\n\t}\r\n\treturn text;\r\n};\r\n\r\nString.implement('stripScripts', function(exec){\r\n\tvar scripts = '';\r\n\tvar text = this.replace(/]*>([\\s\\S]*?)<\\/script>/gi, function(all, code){\r\n\t\tscripts += code + '\\n';\r\n\t\treturn '';\r\n\t});\r\n\tif (exec === true) Browser.exec(scripts);\r\n\telse if (typeOf(exec) == 'function') exec(scripts, text);\r\n\treturn text;\r\n});\r\n\r\n// Window, Document\r\n\r\nBrowser.extend({\r\n\tDocument: this.Document,\r\n\tWindow: this.Window,\r\n\tElement: this.Element,\r\n\tEvent: this.Event\r\n});\r\n\r\nthis.Window = this.$constructor = new Type('Window', function(){});\r\n\r\nthis.$family = Function.from('window').hide();\r\n\r\nWindow.mirror(function(name, method){\r\n\twindow[name] = method;\r\n});\r\n\r\nthis.Document = document.$constructor = new Type('Document', function(){});\r\n\r\ndocument.$family = Function.from('document').hide();\r\n\r\nDocument.mirror(function(name, method){\r\n\tdocument[name] = method;\r\n});\r\n\r\ndocument.html = document.documentElement;\r\nif (!document.head) document.head = document.getElementsByTagName('head')[0];\r\n\r\nif (document.execCommand) try {\r\n\tdocument.execCommand(\"BackgroundImageCache\", false, true);\r\n} catch (e){}\r\n\r\n/**/\r\nif (this.attachEvent && !this.addEventListener){\r\n\tvar unloadEvent = function(){\r\n\t\tthis.detachEvent('onunload', unloadEvent);\r\n\t\tdocument.head = document.html = document.window = null;\r\n\t};\r\n\tthis.attachEvent('onunload', unloadEvent);\r\n}\r\n\r\n// IE fails on collections and )\r\nvar arrayFrom = Array.from;\r\ntry {\r\n\tarrayFrom(document.html.childNodes);\r\n} catch(e){\r\n\tArray.from = function(item){\r\n\t\tif (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){\r\n\t\t\tvar i = item.length, array = new Array(i);\r\n\t\t\twhile (i--) array[i] = item[i];\r\n\t\t\treturn array;\r\n\t\t}\r\n\t\treturn arrayFrom(item);\r\n\t};\r\n\r\n\tvar prototype = Array.prototype,\r\n\t\tslice = prototype.slice;\r\n\t['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){\r\n\t\tvar method = prototype[name];\r\n\t\tArray[name] = function(item){\r\n\t\t\treturn method.apply(Array.from(item), slice.call(arguments, 1));\r\n\t\t};\r\n\t});\r\n}\r\n/**/\r\n\r\n//<1.2compat>\r\n\r\nif (Browser.Platform.ios) Browser.Platform.ipod = true;\r\n\r\nBrowser.Engine = {};\r\n\r\nvar setEngine = function(name, version){\r\n\tBrowser.Engine.name = name;\r\n\tBrowser.Engine[name + version] = true;\r\n\tBrowser.Engine.version = version;\r\n};\r\n\r\nif (Browser.ie){\r\n\tBrowser.Engine.trident = true;\r\n\r\n\tswitch (Browser.version){\r\n\t\tcase 6: setEngine('trident', 4); break;\r\n\t\tcase 7: setEngine('trident', 5); break;\r\n\t\tcase 8: setEngine('trident', 6);\r\n\t}\r\n}\r\n\r\nif (Browser.firefox){\r\n\tBrowser.Engine.gecko = true;\r\n\r\n\tif (Browser.version >= 3) setEngine('gecko', 19);\r\n\telse setEngine('gecko', 18);\r\n}\r\n\r\nif (Browser.safari || Browser.chrome){\r\n\tBrowser.Engine.webkit = true;\r\n\r\n\tswitch (Browser.version){\r\n\t\tcase 2: setEngine('webkit', 419); break;\r\n\t\tcase 3: setEngine('webkit', 420); break;\r\n\t\tcase 4: setEngine('webkit', 525);\r\n\t}\r\n}\r\n\r\nif (Browser.opera){\r\n\tBrowser.Engine.presto = true;\r\n\r\n\tif (Browser.version >= 9.6) setEngine('presto', 960);\r\n\telse if (Browser.version >= 9.5) setEngine('presto', 950);\r\n\telse setEngine('presto', 925);\r\n}\r\n\r\nif (Browser.name == 'unknown'){\r\n\tswitch ((ua.match(/(?:webkit|khtml|gecko)/) || [])[0]){\r\n\t\tcase 'webkit':\r\n\t\tcase 'khtml':\r\n\t\t\tBrowser.Engine.webkit = true;\r\n\t\tbreak;\r\n\t\tcase 'gecko':\r\n\t\t\tBrowser.Engine.gecko = true;\r\n\t}\r\n}\r\n\r\nthis.$exec = Browser.exec;\r\n\r\n//\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Event\r\n\r\ndescription: Contains the Event Type, to make the event object cross-browser.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Window, Document, Array, Function, String, Object]\r\n\r\nprovides: Event\r\n\r\n...\r\n*/\r\n\r\n(function() {\r\n\r\nvar _keys = {};\r\n\r\nvar DOMEvent = this.DOMEvent = new Type('DOMEvent', function(event, win){\r\n\tif (!win) win = window;\r\n\tevent = event || win.event;\r\n\tif (event.$extended) return event;\r\n\tthis.event = event;\r\n\tthis.$extended = true;\r\n\tthis.shift = event.shiftKey;\r\n\tthis.control = event.ctrlKey;\r\n\tthis.alt = event.altKey;\r\n\tthis.meta = event.metaKey;\r\n\tvar type = this.type = event.type;\r\n\tvar target = event.target || event.srcElement;\r\n\twhile (target && target.nodeType == 3) target = target.parentNode;\r\n\tthis.target = document.id(target);\r\n\r\n\tif (type.indexOf('key') == 0){\r\n\t\tvar keyCode = this.keyCode = (event.which || event.keyCode);\r\n\t\tthis.key = _keys[keyCode]/*<1.3compat>*/ || Object.keyOf(Event.Keys, keyCode)/**/;\r\n\t\tif (type == 'keydown'){\r\n\t\t\tif (keyCode > 111 && keyCode < 124) this.key = 'f' + (keyCode - 111);\r\n\t\t\telse if (keyCode > 95 && keyCode < 106) this.key = keyCode - 96;\r\n\t\t}\r\n\t\tif (this.key == null) this.key = String.fromCharCode(keyCode).toLowerCase();\r\n\t} else if (type == 'click' || type == 'dblclick' || type == 'contextmenu' || type == 'DOMMouseScroll' || type.indexOf('mouse') == 0){\r\n\t\tvar doc = win.document;\r\n\t\tdoc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;\r\n\t\tthis.page = {\r\n\t\t\tx: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,\r\n\t\t\ty: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop\r\n\t\t};\r\n\t\tthis.client = {\r\n\t\t\tx: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,\r\n\t\t\ty: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY\r\n\t\t};\r\n\t\tif (type == 'DOMMouseScroll' || type == 'mousewheel')\r\n\t\t\tthis.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;\r\n\r\n\t\tthis.rightClick = (event.which == 3 || event.button == 2);\r\n\t\tif (type == 'mouseover' || type == 'mouseout'){\r\n\t\t\tvar related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'];\r\n\t\t\twhile (related && related.nodeType == 3) related = related.parentNode;\r\n\t\t\tthis.relatedTarget = document.id(related);\r\n\t\t}\r\n\t} else if (type.indexOf('touch') == 0 || type.indexOf('gesture') == 0){\r\n\t\tthis.rotation = event.rotation;\r\n\t\tthis.scale = event.scale;\r\n\t\tthis.targetTouches = event.targetTouches;\r\n\t\tthis.changedTouches = event.changedTouches;\r\n\t\tvar touches = this.touches = event.touches;\r\n\t\tif (touches && touches[0]){\r\n\t\t\tvar touch = touches[0];\r\n\t\t\tthis.page = {x: touch.pageX, y: touch.pageY};\r\n\t\t\tthis.client = {x: touch.clientX, y: touch.clientY};\r\n\t\t}\r\n\t}\r\n\r\n\tif (!this.client) this.client = {};\r\n\tif (!this.page) this.page = {};\r\n});\r\n\r\nDOMEvent.implement({\r\n\r\n\tstop: function(){\r\n\t\treturn this.preventDefault().stopPropagation();\r\n\t},\r\n\r\n\tstopPropagation: function(){\r\n\t\tif (this.event.stopPropagation) this.event.stopPropagation();\r\n\t\telse this.event.cancelBubble = true;\r\n\t\treturn this;\r\n\t},\r\n\r\n\tpreventDefault: function () {\r\n\t\tvar evt = new Event(this.event);\r\n\t\tif (evt && evt.target && evt.target.tagName.match(/video|audio/i))\r\n\t\t\treturn this;\r\n\t\tif (this.event.preventDefault) this.event.preventDefault();\r\n\t\telse this.event.returnValue = false;\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\nDOMEvent.defineKey = function(code, key){\r\n\t_keys[code] = key;\r\n\treturn this;\r\n};\r\n\r\nDOMEvent.defineKeys = DOMEvent.defineKey.overloadSetter(true);\r\n\r\nDOMEvent.defineKeys({\r\n\t'38': 'up', '40': 'down', '37': 'left', '39': 'right',\r\n\t'27': 'esc', '32': 'space', '8': 'backspace', '9': 'tab',\r\n\t'46': 'delete', '13': 'enter'\r\n});\r\n\r\n})();\r\n\r\n/*<1.3compat>*/\r\nvar Event = DOMEvent;\r\nEvent.Keys = {};\r\n/**/\r\n\r\n/*<1.2compat>*/\r\n\r\nEvent.Keys = new Hash(Event.Keys);\r\n\r\n/**/\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Class\r\n\r\ndescription: Contains the Class Function for easily creating, extending, and implementing reusable Classes.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Array, String, Function, Number]\r\n\r\nprovides: Class\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar Class = this.Class = new Type('Class', function(params){\r\n\tif (instanceOf(params, Function)) params = {initialize: params};\r\n\r\n\tvar newClass = function(){\r\n\t\treset(this);\r\n\t\tif (newClass.$prototyping) return this;\r\n\t\tthis.$caller = null;\r\n\t\tvar value = (this.initialize) ? this.initialize.apply(this, arguments) : this;\r\n\t\tthis.$caller = this.caller = null;\r\n\t\treturn value;\r\n\t}.extend(this).implement(params);\r\n\r\n\tnewClass.$constructor = Class;\r\n\tnewClass.prototype.$constructor = newClass;\r\n\tnewClass.prototype.parent = parent;\r\n\r\n\treturn newClass;\r\n});\r\n\r\nvar parent = function(){\r\n\tif (!this.$caller) throw new Error('The method \"parent\" cannot be called.');\r\n\tvar name = this.$caller.$name,\r\n\t\tparent = this.$caller.$owner.parent,\r\n\t\tprevious = (parent) ? parent.prototype[name] : null;\r\n\tif (!previous) throw new Error('The method \"' + name + '\" has no parent.');\r\n\treturn previous.apply(this, arguments);\r\n};\r\n\r\nvar reset = function(object){\r\n\tfor (var key in object) {\r\n\t\ttry {\r\n\t\t\tvar value = object[key];\r\n\r\n\t\t\tswitch (typeOf(value)) {\r\n\t\t\t\tcase 'object':\r\n\t\t\t\t\tvar F = function(){};\r\n\t\t\t\t\tF.prototype = value;\r\n\t\t\t\t\tobject[key] = reset(new F);\r\n\t\t \t\t\tbreak;\r\n\t\t\t\tcase 'array':\r\n\t\t\t\t\tobject[key] = value.clone();\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\tcatch (error) {\r\n\t\t\t// Chrome may throw \"Illegal Invocation\" when accessing properties of native objects\r\n\t\t\t// If so, ignore and skip\r\n\t\t}\r\n\t}\r\n\treturn object;\r\n};\r\n\r\nvar wrap = function(self, key, method){\r\n\tif (method.$origin) method = method.$origin;\r\n\tvar wrapper = function(){\r\n\t\tif (method.$protected && this.$caller == null) throw new Error('The method \"' + key + '\" cannot be called.');\r\n\t\tvar caller = this.caller, current = this.$caller;\r\n\t\tthis.caller = current; this.$caller = wrapper;\r\n\t\tvar result = method.apply(this, arguments);\r\n\t\tthis.$caller = current; this.caller = caller;\r\n\t\treturn result;\r\n\t}.extend({$owner: self, $origin: method, $name: key});\r\n\treturn wrapper;\r\n};\r\n\r\nvar implement = function(key, value, retain){\r\n\tif (Class.Mutators.hasOwnProperty(key)){\r\n\t\tvalue = Class.Mutators[key].call(this, value);\r\n\t\tif (value == null) return this;\r\n\t}\r\n\r\n\tif (typeOf(value) == 'function'){\r\n\t\tif (value.$hidden) return this;\r\n\t\tthis.prototype[key] = (retain) ? value : wrap(this, key, value);\r\n\t} else {\r\n\t\tObject.merge(this.prototype, key, value);\r\n\t}\r\n\r\n\treturn this;\r\n};\r\n\r\nvar getInstance = function(klass){\r\n\tklass.$prototyping = true;\r\n\tvar proto = new klass;\r\n\tdelete klass.$prototyping;\r\n\treturn proto;\r\n};\r\n\r\nClass.implement('implement', implement.overloadSetter());\r\n\r\nClass.Mutators = {\r\n\r\n\tExtends: function(parent){\r\n\t\tthis.parent = parent;\r\n\t\tthis.prototype = getInstance(parent);\r\n\t},\r\n\r\n\tImplements: function(items){\r\n\t\tArray.from(items).each(function(item){\r\n\t\t\tvar instance = new item;\r\n\t\t\tfor (var key in instance) implement.call(this, key, instance[key], true);\r\n\t\t}, this);\r\n\t}\r\n};\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Class.Extras\r\n\r\ndescription: Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Class\r\n\r\nprovides: [Class.Extras, Chain, Events, Options]\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nthis.Chain = new Class({\r\n\r\n\t$chain: [],\r\n\r\n\tchain: function(){\r\n\t\tthis.$chain.append(Array.flatten(arguments));\r\n\t\treturn this;\r\n\t},\r\n\r\n\tcallChain: function(){\r\n\t\treturn (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;\r\n\t},\r\n\r\n\tclearChain: function(){\r\n\t\tthis.$chain.empty();\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\nvar removeOn = function(string){\r\n\treturn string.replace(/^on([A-Z])/, function(full, first){\r\n\t\treturn first.toLowerCase();\r\n\t});\r\n};\r\n\r\nthis.Events = new Class({\r\n\r\n\t$events: {},\r\n\r\n\taddEvent: function(type, fn, internal){\r\n\t\ttype = removeOn(type);\r\n\r\n\t\t/*<1.2compat>*/\r\n\t\tif (fn == $empty) return this;\r\n\t\t/**/\r\n\r\n\t\tthis.$events[type] = (this.$events[type] || []).include(fn);\r\n\t\tif (internal) fn.internal = true;\r\n\t\treturn this;\r\n\t},\r\n\r\n\taddEvents: function(events){\r\n\t\tfor (var type in events) this.addEvent(type, events[type]);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tfireEvent: function(type, args, delay){\r\n\t\ttype = removeOn(type);\r\n\t\tvar events = this.$events[type];\r\n\t\tif (!events) return this;\r\n\t\targs = Array.from(args);\r\n\t\tevents.each(function(fn){\r\n\t\t\tif (delay) fn.delay(delay, this, args);\r\n\t\t\telse fn.apply(this, args);\r\n\t\t}, this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tremoveEvent: function(type, fn){\r\n\t\ttype = removeOn(type);\r\n\t\tvar events = this.$events[type];\r\n\t\tif (events && !fn.internal){\r\n\t\t\tvar index = events.indexOf(fn);\r\n\t\t\tif (index != -1) delete events[index];\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\tremoveEvents: function(events){\r\n\t\tvar type;\r\n\t\tif (typeOf(events) == 'object'){\r\n\t\t\tfor (type in events) this.removeEvent(type, events[type]);\r\n\t\t\treturn this;\r\n\t\t}\r\n\t\tif (events) events = removeOn(events);\r\n\t\tfor (type in this.$events){\r\n\t\t\tif (events && events != type) continue;\r\n\t\t\tvar fns = this.$events[type];\r\n\t\t\tfor (var i = fns.length; i--;) if (i in fns){\r\n\t\t\t\tthis.removeEvent(type, fns[i]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\nthis.Options = new Class({\r\n\r\n\tsetOptions: function(){\r\n\t\tvar options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));\r\n\t\tif (this.addEvent) for (var option in options){\r\n\t\t\tif (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;\r\n\t\t\tthis.addEvent(option, options[option]);\r\n\t\t\t//delete options[option];\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\nname: Slick.Parser\r\ndescription: Standalone CSS3 Selector parser\r\nprovides: Slick.Parser\r\n...\r\n*/\r\n\r\n;(function(){\r\n\r\nvar parsed,\r\n\tseparatorIndex,\r\n\tcombinatorIndex,\r\n\treversed,\r\n\tcache = {},\r\n\treverseCache = {},\r\n\treUnescape = /\\\\/g;\r\n\r\nvar parse = function(expression, isReversed){\r\n\tif (expression == null) return null;\r\n\tif (expression.Slick === true) return expression;\r\n\texpression = ('' + expression).replace(/^\\s+|\\s+$/g, '');\r\n\treversed = !!isReversed;\r\n\tvar currentCache = (reversed) ? reverseCache : cache;\r\n\tif (currentCache[expression]) return currentCache[expression];\r\n\tparsed = {\r\n\t\tSlick: true,\r\n\t\texpressions: [],\r\n\t\traw: expression,\r\n\t\treverse: function(){\r\n\t\t\treturn parse(this.raw, true);\r\n\t\t}\r\n\t};\r\n\tseparatorIndex = -1;\r\n\twhile (expression != (expression = expression.replace(regexp, parser)));\r\n\tparsed.length = parsed.expressions.length;\r\n\treturn currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed;\r\n};\r\n\r\nvar reverseCombinator = function(combinator){\r\n\tif (combinator === '!') return ' ';\r\n\telse if (combinator === ' ') return '!';\r\n\telse if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');\r\n\telse return '!' + combinator;\r\n};\r\n\r\nvar reverse = function(expression){\r\n\tvar expressions = expression.expressions;\r\n\tfor (var i = 0; i < expressions.length; i++){\r\n\t\tvar exp = expressions[i];\r\n\t\tvar last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combinator)};\r\n\r\n\t\tfor (var j = 0; j < exp.length; j++){\r\n\t\t\tvar cexp = exp[j];\r\n\t\t\tif (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';\r\n\t\t\tcexp.combinator = cexp.reverseCombinator;\r\n\t\t\tdelete cexp.reverseCombinator;\r\n\t\t}\r\n\r\n\t\texp.reverse().push(last);\r\n\t}\r\n\treturn expression;\r\n};\r\n\r\nvar escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan MIT License\r\n\treturn string.replace(/[-[\\]{}()*+?.\\\\^$|,#\\s]/g, function(match){\r\n\t\treturn '\\\\' + match;\r\n\t});\r\n};\r\n\r\nvar regexp = new RegExp(\r\n/*\r\n#!/usr/bin/env ruby\r\nputs \"\\t\\t\" + DATA.read.gsub(/\\(\\?x\\)|\\s+#.*$|\\s+|\\\\$|\\\\n/,'')\r\n__END__\r\n\t\"(?x)^(?:\\\r\n\t \\\\s* ( , ) \\\\s* # Separator \\n\\\r\n\t| \\\\s* ( + ) \\\\s* # Combinator \\n\\\r\n\t| ( \\\\s+ ) # CombinatorChildren \\n\\\r\n\t| ( + | \\\\* ) # Tag \\n\\\r\n\t| \\\\# ( + ) # ID \\n\\\r\n\t| \\\\. ( + ) # ClassName \\n\\\r\n\t| # Attribute \\n\\\r\n\t\\\\[ \\\r\n\t\t\\\\s* (+) (?: \\\r\n\t\t\t\\\\s* ([*^$!~|]?=) (?: \\\r\n\t\t\t\t\\\\s* (?:\\\r\n\t\t\t\t\t([\\\"']?)(.*?)\\\\9 \\\r\n\t\t\t\t)\\\r\n\t\t\t) \\\r\n\t\t)? \\\\s* \\\r\n\t\\\\](?!\\\\]) \\n\\\r\n\t| :+ ( + )(?:\\\r\n\t\\\\( (?:\\\r\n\t\t(?:([\\\"'])([^\\\\12]*)\\\\12)|((?:\\\\([^)]+\\\\)|[^()]*)+)\\\r\n\t) \\\\)\\\r\n\t)?\\\r\n\t)\"\r\n*/\r\n\t\"^(?:\\\\s*(,)\\\\s*|\\\\s*(+)\\\\s*|(\\\\s+)|(+|\\\\*)|\\\\#(+)|\\\\.(+)|\\\\[\\\\s*(+)(?:\\\\s*([*^$!~|]?=)(?:\\\\s*(?:([\\\"']?)(.*?)\\\\9)))?\\\\s*\\\\](?!\\\\])|(:+)(+)(?:\\\\((?:(?:([\\\"'])([^\\\\13]*)\\\\13)|((?:\\\\([^)]+\\\\)|[^()]*)+))\\\\))?)\"\r\n\t.replace(//, '[' + escapeRegExp(\">+~`!@$%^&={}\\\\;/g, '(?:[\\\\w\\\\u00a1-\\\\uFFFF-]|\\\\\\\\[^\\\\s0-9a-f])')\r\n\t.replace(//g, '(?:[:\\\\w\\\\u00a1-\\\\uFFFF-]|\\\\\\\\[^\\\\s0-9a-f])')\r\n);\r\n\r\nfunction parser(\r\n\trawMatch,\r\n\r\n\tseparator,\r\n\tcombinator,\r\n\tcombinatorChildren,\r\n\r\n\ttagName,\r\n\tid,\r\n\tclassName,\r\n\r\n\tattributeKey,\r\n\tattributeOperator,\r\n\tattributeQuote,\r\n\tattributeValue,\r\n\r\n\tpseudoMarker,\r\n\tpseudoClass,\r\n\tpseudoQuote,\r\n\tpseudoClassQuotedValue,\r\n\tpseudoClassValue\r\n){\r\n\tif (separator || separatorIndex === -1){\r\n\t\tparsed.expressions[++separatorIndex] = [];\r\n\t\tcombinatorIndex = -1;\r\n\t\tif (separator) return '';\r\n\t}\r\n\r\n\tif (combinator || combinatorChildren || combinatorIndex === -1){\r\n\t\tcombinator = combinator || ' ';\r\n\t\tvar currentSeparator = parsed.expressions[separatorIndex];\r\n\t\tif (reversed && currentSeparator[combinatorIndex])\r\n\t\t\tcurrentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator);\r\n\t\tcurrentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'};\r\n\t}\r\n\r\n\tvar currentParsed = parsed.expressions[separatorIndex][combinatorIndex];\r\n\r\n\tif (tagName){\r\n\t\tcurrentParsed.tag = tagName.replace(reUnescape, '');\r\n\r\n\t} else if (id){\r\n\t\tcurrentParsed.id = id.replace(reUnescape, '');\r\n\r\n\t} else if (className){\r\n\t\tclassName = className.replace(reUnescape, '');\r\n\r\n\t\tif (!currentParsed.classList) currentParsed.classList = [];\r\n\t\tif (!currentParsed.classes) currentParsed.classes = [];\r\n\t\tcurrentParsed.classList.push(className);\r\n\t\tcurrentParsed.classes.push({\r\n\t\t\tvalue: className,\r\n\t\t\tregexp: new RegExp('(^|\\\\s)' + escapeRegExp(className) + '(\\\\s|$)')\r\n\t\t});\r\n\r\n\t} else if (pseudoClass){\r\n\t\tpseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;\r\n\t\tpseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, '') : null;\r\n\r\n\t\tif (!currentParsed.pseudos) currentParsed.pseudos = [];\r\n\t\tcurrentParsed.pseudos.push({\r\n\t\t\tkey: pseudoClass.replace(reUnescape, ''),\r\n\t\t\tvalue: pseudoClassValue,\r\n\t\t\ttype: pseudoMarker.length == 1 ? 'class' : 'element'\r\n\t\t});\r\n\r\n\t} else if (attributeKey){\r\n\t\tattributeKey = attributeKey.replace(reUnescape, '');\r\n\t\tattributeValue = (attributeValue || '').replace(reUnescape, '');\r\n\r\n\t\tvar test, regexp;\r\n\r\n\t\tswitch (attributeOperator){\r\n\t\t\tcase '^=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) ); break;\r\n\t\t\tcase '$=' : regexp = new RegExp( escapeRegExp(attributeValue) +'$' ); break;\r\n\t\t\tcase '~=' : regexp = new RegExp( '(^|\\\\s)'+ escapeRegExp(attributeValue) +'(\\\\s|$)' ); break;\r\n\t\t\tcase '|=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) +'(-|$)' ); break;\r\n\t\t\tcase '=' : test = function(value){\r\n\t\t\t\treturn attributeValue == value;\r\n\t\t\t}; break;\r\n\t\t\tcase '*=' : test = function(value){\r\n\t\t\t\treturn value && value.indexOf(attributeValue) > -1;\r\n\t\t\t}; break;\r\n\t\t\tcase '!=' : test = function(value){\r\n\t\t\t\treturn attributeValue != value;\r\n\t\t\t}; break;\r\n\t\t\tdefault : test = function(value){\r\n\t\t\t\treturn !!value;\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tif (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = function(){\r\n\t\t\treturn false;\r\n\t\t};\r\n\r\n\t\tif (!test) test = function(value){\r\n\t\t\treturn value && regexp.test(value);\r\n\t\t};\r\n\r\n\t\tif (!currentParsed.attributes) currentParsed.attributes = [];\r\n\t\tcurrentParsed.attributes.push({\r\n\t\t\tkey: attributeKey,\r\n\t\t\toperator: attributeOperator,\r\n\t\t\tvalue: attributeValue,\r\n\t\t\ttest: test\r\n\t\t});\r\n\r\n\t}\r\n\r\n\treturn '';\r\n};\r\n\r\n// Slick NS\r\n\r\nvar Slick = (this.Slick || {});\r\n\r\nSlick.parse = function(expression){\r\n\treturn parse(expression);\r\n};\r\n\r\nSlick.escapeRegExp = escapeRegExp;\r\n\r\nif (!this.Slick) this.Slick = Slick;\r\n\r\n}).apply(/**/(typeof exports != 'undefined') ? exports : /**/this);\r\n\r\n\r\n/*\r\n---\r\nname: Slick.Finder\r\ndescription: The new, superfast css selector engine.\r\nprovides: Slick.Finder\r\nrequires: Slick.Parser\r\n...\r\n*/\r\n\r\n;(function(){\r\n\r\nvar local = {},\r\n\tfeaturesCache = {},\r\n\ttoString = Object.prototype.toString;\r\n\r\n// Feature / Bug detection\r\n\r\nlocal.isNativeCode = function(fn){\r\n\treturn (/\\{\\s*\\[native code\\]\\s*\\}/).test('' + fn);\r\n};\r\n\r\nlocal.isXML = function(document){\r\n\treturn (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]') ||\r\n\t(document.nodeType == 9 && document.documentElement.nodeName != 'HTML');\r\n};\r\n\r\nlocal.setDocument = function(document){\r\n\r\n\t// convert elements / window arguments to document. if document cannot be extrapolated, the function returns.\r\n\tvar nodeType = document.nodeType;\r\n\tif (nodeType == 9); // document\r\n\telse if (nodeType) document = document.ownerDocument; // node\r\n\telse if (document.navigator) document = document.document; // window\r\n\telse return;\r\n\r\n\t// check if it's the old document\r\n\r\n\tif (this.document === document) return;\r\n\tthis.document = document;\r\n\r\n\t// check if we have done feature detection on this document before\r\n\r\n\tvar root = document.documentElement,\r\n\t\trootUid = this.getUIDXML(root),\r\n\t\tfeatures = featuresCache[rootUid],\r\n\t\tfeature;\r\n\r\n\tif (features){\r\n\t\tfor (feature in features){\r\n\t\t\tthis[feature] = features[feature];\r\n\t\t}\r\n\t\treturn;\r\n\t}\r\n\r\n\tfeatures = featuresCache[rootUid] = {};\r\n\r\n\tfeatures.root = root;\r\n\tfeatures.isXMLDocument = this.isXML(document);\r\n\r\n\tfeatures.brokenStarGEBTN\r\n\t= features.starSelectsClosedQSA\r\n\t= features.idGetsName\r\n\t= features.brokenMixedCaseQSA\r\n\t= features.brokenGEBCN\r\n\t= features.brokenCheckedQSA\r\n\t= features.brokenEmptyAttributeQSA\r\n\t= features.isHTMLDocument\r\n\t= features.nativeMatchesSelector\r\n\t= false;\r\n\r\n\tvar starSelectsClosed, starSelectsComments,\r\n\t\tbrokenSecondClassNameGEBCN, cachedGetElementsByClassName,\r\n\t\tbrokenFormAttributeGetter;\r\n\r\n\tvar selected, id = 'slick_uniqueid';\r\n\tvar testNode = document.createElement('div');\r\n\r\n\tvar testRoot = document.body || document.getElementsByTagName('body')[0] || root;\r\n\ttestRoot.appendChild(testNode);\r\n\r\n\t// on non-HTML documents innerHTML and getElementsById doesnt work properly\r\n\ttry {\r\n\t\ttestNode.innerHTML = '';\r\n\t\tfeatures.isHTMLDocument = !!document.getElementById(id);\r\n\t} catch(e){};\r\n\r\n\tif (features.isHTMLDocument){\r\n\r\n\t\ttestNode.style.display = 'none';\r\n\r\n\t\t// IE returns comment nodes for getElementsByTagName('*') for some documents\r\n\t\ttestNode.appendChild(document.createComment(''));\r\n\t\tstarSelectsComments = (testNode.getElementsByTagName('*').length > 1);\r\n\r\n\t\t// IE returns closed nodes (EG:\"\") for getElementsByTagName('*') for some documents\r\n\t\ttry {\r\n\t\t\ttestNode.innerHTML = 'foo';\r\n\t\t\tselected = testNode.getElementsByTagName('*');\r\n\t\t\tstarSelectsClosed = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');\r\n\t\t} catch(e){};\r\n\r\n\t\tfeatures.brokenStarGEBTN = starSelectsComments || starSelectsClosed;\r\n\r\n\t\t// IE returns elements with the name instead of just id for getElementsById for some documents\r\n\t\ttry {\r\n\t\t\ttestNode.innerHTML = '';\r\n\t\t\tfeatures.idGetsName = document.getElementById(id) === testNode.firstChild;\r\n\t\t} catch(e){};\r\n\r\n\t\tif (testNode.getElementsByClassName){\r\n\r\n\t\t\t// Safari 3.2 getElementsByClassName caches results\r\n\t\t\ttry {\r\n\t\t\t\ttestNode.innerHTML = '';\r\n\t\t\t\ttestNode.getElementsByClassName('b').length;\r\n\t\t\t\ttestNode.firstChild.className = 'b';\r\n\t\t\t\tcachedGetElementsByClassName = (testNode.getElementsByClassName('b').length != 2);\r\n\t\t\t} catch(e){};\r\n\r\n\t\t\t// Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one\r\n\t\t\ttry {\r\n\t\t\t\ttestNode.innerHTML = '';\r\n\t\t\t\tbrokenSecondClassNameGEBCN = (testNode.getElementsByClassName('a').length != 2);\r\n\t\t\t} catch(e){};\r\n\r\n\t\t\tfeatures.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN;\r\n\t\t}\r\n\r\n\t\tif (testNode.querySelectorAll){\r\n\t\t\t// IE 8 returns closed nodes (EG:\"\") for querySelectorAll('*') for some documents\r\n\t\t\ttry {\r\n\t\t\t\ttestNode.innerHTML = 'foo';\r\n\t\t\t\tselected = testNode.querySelectorAll('*');\r\n\t\t\t\tfeatures.starSelectsClosedQSA = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');\r\n\t\t\t} catch(e){};\r\n\r\n\t\t\t// Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode\r\n\t\t\ttry {\r\n\t\t\t\ttestNode.innerHTML = '';\r\n\t\t\t\tfeatures.brokenMixedCaseQSA = !testNode.querySelectorAll('.MiX').length;\r\n\t\t\t} catch(e){};\r\n\r\n\t\t\t// Webkit and Opera dont return selected options on querySelectorAll\r\n\t\t\ttry {\r\n\t\t\t\ttestNode.innerHTML = '';\r\n\t\t\t\tfeatures.brokenCheckedQSA = (testNode.querySelectorAll(':checked').length == 0);\r\n\t\t\t} catch(e){};\r\n\r\n\t\t\t// IE returns incorrect results for attr[*^$]=\"\" selectors on querySelectorAll\r\n\t\t\ttry {\r\n\t\t\t\ttestNode.innerHTML = '';\r\n\t\t\t\tfeatures.brokenEmptyAttributeQSA = (testNode.querySelectorAll('[class*=\"\"]').length != 0);\r\n\t\t\t} catch(e){};\r\n\r\n\t\t}\r\n\r\n\t\t// IE6-7, if a form has an input of id x, form.getAttribute(x) returns a reference to the input\r\n\t\ttry {\r\n\t\t\ttestNode.innerHTML = '
';\r\n\t\t\tbrokenFormAttributeGetter = (testNode.firstChild.getAttribute('action') != 's');\r\n\t\t} catch(e){};\r\n\r\n\t\t// native matchesSelector function\r\n\r\n\t\tfeatures.nativeMatchesSelector = root.matchesSelector || /*root.msMatchesSelector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector;\r\n\t\tif (features.nativeMatchesSelector) try {\r\n\t\t\t// if matchesSelector trows errors on incorrect sintaxes we can use it\r\n\t\t\tfeatures.nativeMatchesSelector.call(root, ':slick');\r\n\t\t\tfeatures.nativeMatchesSelector = null;\r\n\t\t} catch(e){};\r\n\r\n\t}\r\n\r\n\ttry {\r\n\t\troot.slick_expando = 1;\r\n\t\tdelete root.slick_expando;\r\n\t\tfeatures.getUID = this.getUIDHTML;\r\n\t} catch(e) {\r\n\t\tfeatures.getUID = this.getUIDXML;\r\n\t}\r\n\r\n\ttestRoot.removeChild(testNode);\r\n\ttestNode = selected = testRoot = null;\r\n\r\n\t// getAttribute\r\n\r\n\tfeatures.getAttribute = (features.isHTMLDocument && brokenFormAttributeGetter) ? function(node, name){\r\n\t\tvar method = this.attributeGetters[name];\r\n\t\tif (method) return method.call(node);\r\n\t\tvar attributeNode = node.getAttributeNode(name);\r\n\t\treturn (attributeNode) ? attributeNode.nodeValue : null;\r\n\t} : function(node, name){\r\n\t\tvar method = this.attributeGetters[name];\r\n\t\treturn (method) ? method.call(node) : node.getAttribute(name);\r\n\t};\r\n\r\n\t// hasAttribute\r\n\r\n\tfeatures.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? function(node, attribute) {\r\n\t\treturn node.hasAttribute(attribute);\r\n\t} : function(node, attribute) {\r\n\t\tnode = node.getAttributeNode(attribute);\r\n\t\treturn !!(node && (node.specified || node.nodeValue));\r\n\t};\r\n\r\n\t// contains\r\n\t// FIXME: Add specs: local.contains should be different for xml and html documents?\r\n\tvar nativeRootContains = root && this.isNativeCode(root.contains),\r\n\t\tnativeDocumentContains = document && this.isNativeCode(document.contains);\r\n\r\n\tfeatures.contains = (nativeRootContains && nativeDocumentContains) ? function(context, node){\r\n\t\treturn context.contains(node);\r\n\t} : (nativeRootContains && !nativeDocumentContains) ? function(context, node){\r\n\t\t// IE8 does not have .contains on document.\r\n\t\treturn context === node || ((context === document) ? document.documentElement : context).contains(node);\r\n\t} : (root && root.compareDocumentPosition) ? function(context, node){\r\n\t\treturn context === node || !!(context.compareDocumentPosition(node) & 16);\r\n\t} : function(context, node){\r\n\t\tif (node) do {\r\n\t\t\tif (node === context) return true;\r\n\t\t} while ((node = node.parentNode));\r\n\t\treturn false;\r\n\t};\r\n\r\n\t// document order sorting\r\n\t// credits to Sizzle (http://sizzlejs.com/)\r\n\r\n\tfeatures.documentSorter = (root.compareDocumentPosition) ? function(a, b){\r\n\t\tif (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0;\r\n\t\treturn a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;\r\n\t} : ('sourceIndex' in root) ? function(a, b){\r\n\t\tif (!a.sourceIndex || !b.sourceIndex) return 0;\r\n\t\treturn a.sourceIndex - b.sourceIndex;\r\n\t} : (document.createRange) ? function(a, b){\r\n\t\tif (!a.ownerDocument || !b.ownerDocument) return 0;\r\n\t\tvar aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();\r\n\t\taRange.setStart(a, 0);\r\n\t\taRange.setEnd(a, 0);\r\n\t\tbRange.setStart(b, 0);\r\n\t\tbRange.setEnd(b, 0);\r\n\t\treturn aRange.compareBoundaryPoints(Range.START_TO_END, bRange);\r\n\t} : null ;\r\n\r\n\troot = null;\r\n\r\n\tfor (feature in features){\r\n\t\tthis[feature] = features[feature];\r\n\t}\r\n};\r\n\r\n// Main Method\r\n\r\nvar reSimpleSelector = /^([#.]?)((?:[\\w-]+|\\*))$/,\r\n\treEmptyAttribute = /\\[.+[*$^]=(?:\"\"|'')?\\]/,\r\n\tqsaFailExpCache = {};\r\n\r\nlocal.search = function(context, expression, append, first){\r\n\r\n\tvar found = this.found = (first) ? null : (append || []);\r\n\r\n\tif (!context) return found;\r\n\telse if (context.navigator) context = context.document; // Convert the node from a window to a document\r\n\telse if (!context.nodeType) return found;\r\n\r\n\t// setup\r\n\r\n\tvar parsed, i,\r\n\t\tuniques = this.uniques = {},\r\n\t\thasOthers = !!(append && append.length),\r\n\t\tcontextIsDocument = (context.nodeType == 9);\r\n\r\n\tif (this.document !== (contextIsDocument ? context : context.ownerDocument)) this.setDocument(context);\r\n\r\n\t// avoid duplicating items already in the append array\r\n\tif (hasOthers) for (i = found.length; i--;) uniques[this.getUID(found[i])] = true;\r\n\r\n\t// expression checks\r\n\r\n\tif (typeof expression == 'string'){ // expression is a string\r\n\r\n\t\t/**/\r\n\t\tvar simpleSelector = expression.match(reSimpleSelector);\r\n\t\tsimpleSelectors: if (simpleSelector) {\r\n\r\n\t\t\tvar symbol = simpleSelector[1],\r\n\t\t\t\tname = simpleSelector[2],\r\n\t\t\t\tnode, nodes;\r\n\r\n\t\t\tif (!symbol){\r\n\r\n\t\t\t\tif (name == '*' && this.brokenStarGEBTN) break simpleSelectors;\r\n\t\t\t\tnodes = context.getElementsByTagName(name);\r\n\t\t\t\tif (first) return nodes[0] || null;\r\n\t\t\t\tfor (i = 0; node = nodes[i++];){\r\n\t\t\t\t\tif (!(hasOthers && uniques[this.getUID(node)])) found.push(node);\r\n\t\t\t\t}\r\n\r\n\t\t\t} else if (symbol == '#'){\r\n\r\n\t\t\t\tif (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors;\r\n\t\t\t\tnode = context.getElementById(name);\r\n\t\t\t\tif (!node) return found;\r\n\t\t\t\tif (this.idGetsName && node.getAttributeNode('id').nodeValue != name) break simpleSelectors;\r\n\t\t\t\tif (first) return node || null;\r\n\t\t\t\tif (!(hasOthers && uniques[this.getUID(node)])) found.push(node);\r\n\r\n\t\t\t} else if (symbol == '.'){\r\n\r\n\t\t\t\tif (!this.isHTMLDocument || ((!context.getElementsByClassName || this.brokenGEBCN) && context.querySelectorAll)) break simpleSelectors;\r\n\t\t\t\tif (context.getElementsByClassName && !this.brokenGEBCN){\r\n\t\t\t\t\tnodes = context.getElementsByClassName(name);\r\n\t\t\t\t\tif (first) return nodes[0] || null;\r\n\t\t\t\t\tfor (i = 0; node = nodes[i++];){\r\n\t\t\t\t\t\tif (!(hasOthers && uniques[this.getUID(node)])) found.push(node);\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvar matchClass = new RegExp('(^|\\\\s)'+ Slick.escapeRegExp(name) +'(\\\\s|$)');\r\n\t\t\t\t\tnodes = context.getElementsByTagName('*');\r\n\t\t\t\t\tfor (i = 0; node = nodes[i++];){\r\n\t\t\t\t\t\tclassName = node.className;\r\n\t\t\t\t\t\tif (!(className && matchClass.test(className))) continue;\r\n\t\t\t\t\t\tif (first) return node;\r\n\t\t\t\t\t\tif (!(hasOthers && uniques[this.getUID(node)])) found.push(node);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\r\n\t\t\tif (hasOthers) this.sort(found);\r\n\t\t\treturn (first) ? null : found;\r\n\r\n\t\t}\r\n\t\t/**/\r\n\r\n\t\t/**/\r\n\t\tquerySelector: if (context.querySelectorAll) {\r\n\r\n\t\t\tif (!this.isHTMLDocument\r\n\t\t\t\t|| qsaFailExpCache[expression]\r\n\t\t\t\t//TODO: only skip when expression is actually mixed case\r\n\t\t\t\t|| this.brokenMixedCaseQSA\r\n\t\t\t\t|| (this.brokenCheckedQSA && expression.indexOf(':checked') > -1)\r\n\t\t\t\t|| (this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression))\r\n\t\t\t\t|| (!contextIsDocument //Abort when !contextIsDocument and...\r\n\t\t\t\t\t// there are multiple expressions in the selector\r\n\t\t\t\t\t// since we currently only fix non-document rooted QSA for single expression selectors\r\n\t\t\t\t\t&& expression.indexOf(',') > -1\r\n\t\t\t\t)\r\n\t\t\t\t|| Slick.disableQSA\r\n\t\t\t) break querySelector;\r\n\r\n\t\t\tvar _expression = expression, _context = context;\r\n\t\t\tif (!contextIsDocument){\r\n\t\t\t\t// non-document rooted QSA\r\n\t\t\t\t// credits to Andrew Dupont\r\n\t\t\t\tvar currentId = _context.getAttribute('id'), slickid = 'slickid__';\r\n\t\t\t\t_context.setAttribute('id', slickid);\r\n\t\t\t\t_expression = '#' + slickid + ' ' + _expression;\r\n\t\t\t\tcontext = _context.parentNode;\r\n\t\t\t}\r\n\r\n\t\t\ttry {\r\n\t\t\t\tif (first) return context.querySelector(_expression) || null;\r\n\t\t\t\telse nodes = context.querySelectorAll(_expression);\r\n\t\t\t} catch(e) {\r\n\t\t\t\tqsaFailExpCache[expression] = 1;\r\n\t\t\t\tbreak querySelector;\r\n\t\t\t} finally {\r\n\t\t\t\tif (!contextIsDocument){\r\n\t\t\t\t\tif (currentId) _context.setAttribute('id', currentId);\r\n\t\t\t\t\telse _context.removeAttribute('id');\r\n\t\t\t\t\tcontext = _context;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (this.starSelectsClosedQSA) for (i = 0; node = nodes[i++];){\r\n\t\t\t\tif (node.nodeName > '@' && !(hasOthers && uniques[this.getUID(node)])) found.push(node);\r\n\t\t\t} else for (i = 0; node = nodes[i++];){\r\n\t\t\t\tif (!(hasOthers && uniques[this.getUID(node)])) found.push(node);\r\n\t\t\t}\r\n\r\n\t\t\tif (hasOthers) this.sort(found);\r\n\t\t\treturn found;\r\n\r\n\t\t}\r\n\t\t/**/\r\n\r\n\t\tparsed = this.Slick.parse(expression);\r\n\t\tif (!parsed.length) return found;\r\n\t} else if (expression == null){ // there is no expression\r\n\t\treturn found;\r\n\t} else if (expression.Slick){ // expression is a parsed Slick object\r\n\t\tparsed = expression;\r\n\t} else if (this.contains(context.documentElement || context, expression)){ // expression is a node\r\n\t\t(found) ? found.push(expression) : found = expression;\r\n\t\treturn found;\r\n\t} else { // other junk\r\n\t\treturn found;\r\n\t}\r\n\r\n\t/**//**/\r\n\r\n\t// cache elements for the nth selectors\r\n\r\n\tthis.posNTH = {};\r\n\tthis.posNTHLast = {};\r\n\tthis.posNTHType = {};\r\n\tthis.posNTHTypeLast = {};\r\n\r\n\t/**//**/\r\n\r\n\t// if append is null and there is only a single selector with one expression use pushArray, else use pushUID\r\n\tthis.push = (!hasOthers && (first || (parsed.length == 1 && parsed.expressions[0].length == 1))) ? this.pushArray : this.pushUID;\r\n\r\n\tif (found == null) found = [];\r\n\r\n\t// default engine\r\n\r\n\tvar j, m, n;\r\n\tvar combinator, tag, id, classList, classes, attributes, pseudos;\r\n\tvar currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions;\r\n\r\n\tsearch: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++){\r\n\r\n\t\tcombinator = 'combinator:' + currentBit.combinator;\r\n\t\tif (!this[combinator]) continue search;\r\n\r\n\t\ttag = (this.isXMLDocument) ? currentBit.tag : currentBit.tag.toUpperCase();\r\n\t\tid = currentBit.id;\r\n\t\tclassList = currentBit.classList;\r\n\t\tclasses = currentBit.classes;\r\n\t\tattributes = currentBit.attributes;\r\n\t\tpseudos = currentBit.pseudos;\r\n\t\tlastBit = (j === (currentExpression.length - 1));\r\n\r\n\t\tthis.bitUniques = {};\r\n\r\n\t\tif (lastBit){\r\n\t\t\tthis.uniques = uniques;\r\n\t\t\tthis.found = found;\r\n\t\t} else {\r\n\t\t\tthis.uniques = {};\r\n\t\t\tthis.found = [];\r\n\t\t}\r\n\r\n\t\tif (j === 0){\r\n\t\t\tthis[combinator](context, tag, id, classes, attributes, pseudos, classList);\r\n\t\t\tif (first && lastBit && found.length) break search;\r\n\t\t} else {\r\n\t\t\tif (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++){\r\n\t\t\t\tthis[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);\r\n\t\t\t\tif (found.length) break search;\r\n\t\t\t} else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);\r\n\t\t}\r\n\r\n\t\tcurrentItems = this.found;\r\n\t}\r\n\r\n\t// should sort if there are nodes in append and if you pass multiple expressions.\r\n\tif (hasOthers || (parsed.expressions.length > 1)) this.sort(found);\r\n\r\n\treturn (first) ? (found[0] || null) : found;\r\n};\r\n\r\n// Utils\r\n\r\nlocal.uidx = 1;\r\nlocal.uidk = 'slick-uniqueid';\r\n\r\nlocal.getUIDXML = function(node){\r\n\tvar uid = node.getAttribute(this.uidk);\r\n\tif (!uid){\r\n\t\tuid = this.uidx++;\r\n\t\tnode.setAttribute(this.uidk, uid);\r\n\t}\r\n\treturn uid;\r\n};\r\n\r\nlocal.getUIDHTML = function(node){\r\n\treturn node.uniqueNumber || (node.uniqueNumber = this.uidx++);\r\n};\r\n\r\n// sort based on the setDocument documentSorter method.\r\n\r\nlocal.sort = function(results){\r\n\tif (!this.documentSorter) return results;\r\n\tresults.sort(this.documentSorter);\r\n\treturn results;\r\n};\r\n\r\n/**//**/\r\n\r\nlocal.cacheNTH = {};\r\n\r\nlocal.matchNTH = /^([+-]?\\d*)?([a-z]+)?([+-]\\d+)?$/;\r\n\r\nlocal.parseNTHArgument = function(argument){\r\n\tvar parsed = argument.match(this.matchNTH);\r\n\tif (!parsed) return false;\r\n\tvar special = parsed[2] || false;\r\n\tvar a = parsed[1] || 1;\r\n\tif (a == '-') a = -1;\r\n\tvar b = +parsed[3] || 0;\r\n\tparsed =\r\n\t\t(special == 'n')\t? {a: a, b: b} :\r\n\t\t(special == 'odd')\t? {a: 2, b: 1} :\r\n\t\t(special == 'even')\t? {a: 2, b: 0} : {a: 0, b: a};\r\n\r\n\treturn (this.cacheNTH[argument] = parsed);\r\n};\r\n\r\nlocal.createNTHPseudo = function(child, sibling, positions, ofType){\r\n\treturn function(node, argument){\r\n\t\tvar uid = this.getUID(node);\r\n\t\tif (!this[positions][uid]){\r\n\t\t\tvar parent = node.parentNode;\r\n\t\t\tif (!parent) return false;\r\n\t\t\tvar el = parent[child], count = 1;\r\n\t\t\tif (ofType){\r\n\t\t\t\tvar nodeName = node.nodeName;\r\n\t\t\t\tdo {\r\n\t\t\t\t\tif (el.nodeName != nodeName) continue;\r\n\t\t\t\t\tthis[positions][this.getUID(el)] = count++;\r\n\t\t\t\t} while ((el = el[sibling]));\r\n\t\t\t} else {\r\n\t\t\t\tdo {\r\n\t\t\t\t\tif (el.nodeType != 1) continue;\r\n\t\t\t\t\tthis[positions][this.getUID(el)] = count++;\r\n\t\t\t\t} while ((el = el[sibling]));\r\n\t\t\t}\r\n\t\t}\r\n\t\targument = argument || 'n';\r\n\t\tvar parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument);\r\n\t\tif (!parsed) return false;\r\n\t\tvar a = parsed.a, b = parsed.b, pos = this[positions][uid];\r\n\t\tif (a == 0) return b == pos;\r\n\t\tif (a > 0){\r\n\t\t\tif (pos < b) return false;\r\n\t\t} else {\r\n\t\t\tif (b < pos) return false;\r\n\t\t}\r\n\t\treturn ((pos - b) % a) == 0;\r\n\t};\r\n};\r\n\r\n/**//**/\r\n\r\nlocal.pushArray = function(node, tag, id, classes, attributes, pseudos){\r\n\tif (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.found.push(node);\r\n};\r\n\r\nlocal.pushUID = function(node, tag, id, classes, attributes, pseudos){\r\n\tvar uid = this.getUID(node);\r\n\tif (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, attributes, pseudos)){\r\n\t\tthis.uniques[uid] = true;\r\n\t\tthis.found.push(node);\r\n\t}\r\n};\r\n\r\nlocal.matchNode = function(node, selector){\r\n\tif (this.isHTMLDocument && this.nativeMatchesSelector){\r\n\t\ttry {\r\n\t\t\treturn this.nativeMatchesSelector.call(node, selector.replace(/\\[([^=]+)=\\s*([^'\"\\]]+?)\\s*\\]/g, '[$1=\"$2\"]'));\r\n\t\t} catch(matchError) {}\r\n\t}\r\n\r\n\tvar parsed = this.Slick.parse(selector);\r\n\tif (!parsed) return true;\r\n\r\n\t// simple (single) selectors\r\n\tvar expressions = parsed.expressions, simpleExpCounter = 0, i;\r\n\tfor (i = 0; (currentExpression = expressions[i]); i++){\r\n\t\tif (currentExpression.length == 1){\r\n\t\t\tvar exp = currentExpression[0];\r\n\t\t\tif (this.matchSelector(node, (this.isXMLDocument) ? exp.tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos)) return true;\r\n\t\t\tsimpleExpCounter++;\r\n\t\t}\r\n\t}\r\n\r\n\tif (simpleExpCounter == parsed.length) return false;\r\n\r\n\tvar nodes = this.search(this.document, parsed), item;\r\n\tfor (i = 0; item = nodes[i++];){\r\n\t\tif (item === node) return true;\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nlocal.matchPseudo = function(node, name, argument){\r\n\tvar pseudoName = 'pseudo:' + name;\r\n\tif (this[pseudoName]) return this[pseudoName](node, argument);\r\n\tvar attribute = this.getAttribute(node, name);\r\n\treturn (argument) ? argument == attribute : !!attribute;\r\n};\r\n\r\nlocal.matchSelector = function(node, tag, id, classes, attributes, pseudos){\r\n\tif (tag){\r\n\t\tvar nodeName = (this.isXMLDocument) ? node.nodeName : node.nodeName.toUpperCase();\r\n\t\tif (tag == '*'){\r\n\t\t\tif (nodeName < '@') return false; // Fix for comment nodes and closed nodes\r\n\t\t} else {\r\n\t\t\tif (nodeName != tag) return false;\r\n\t\t}\r\n\t}\r\n\r\n\tif (id && node.getAttribute('id') != id) return false;\r\n\r\n\tvar i, part, cls;\r\n\tif (classes) for (i = classes.length; i--;){\r\n\t\tcls = this.getAttribute(node, 'class');\r\n\t\tif (!(cls && classes[i].regexp.test(cls))) return false;\r\n\t}\r\n\tif (attributes) for (i = attributes.length; i--;){\r\n\t\tpart = attributes[i];\r\n\t\tif (part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.hasAttribute(node, part.key)) return false;\r\n\t}\r\n\tif (pseudos) for (i = pseudos.length; i--;){\r\n\t\tpart = pseudos[i];\r\n\t\tif (!this.matchPseudo(node, part.key, part.value)) return false;\r\n\t}\r\n\treturn true;\r\n};\r\n\r\nvar combinators = {\r\n\r\n\t' ': function(node, tag, id, classes, attributes, pseudos, classList){ // all child nodes, any level\r\n\r\n\t\tvar i, item, children;\r\n\r\n\t\tif (this.isHTMLDocument){\r\n\t\t\tgetById: if (id){\r\n\t\t\t\titem = this.document.getElementById(id);\r\n\t\t\t\tif ((!item && node.all) || (this.idGetsName && item && item.getAttributeNode('id').nodeValue != id)){\r\n\t\t\t\t\t// all[id] returns all the elements with that name or id inside node\r\n\t\t\t\t\t// if theres just one it will return the element, else it will be a collection\r\n\t\t\t\t\tchildren = node.all[id];\r\n\t\t\t\t\tif (!children) return;\r\n\t\t\t\t\tif (!children[0]) children = [children];\r\n\t\t\t\t\tfor (i = 0; item = children[i++];){\r\n\t\t\t\t\t\tvar idNode = item.getAttributeNode('id');\r\n\t\t\t\t\t\tif (idNode && idNode.nodeValue == id){\r\n\t\t\t\t\t\t\tthis.push(item, tag, null, classes, attributes, pseudos);\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\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tif (!item){\r\n\t\t\t\t\t// if the context is in the dom we return, else we will try GEBTN, breaking the getById label\r\n\t\t\t\t\tif (this.contains(this.root, node)) return;\r\n\t\t\t\t\telse break getById;\r\n\t\t\t\t} else if (this.document !== node && !this.contains(node, item)) return;\r\n\t\t\t\tthis.push(item, tag, null, classes, attributes, pseudos);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tgetByClass: if (classes && node.getElementsByClassName && !this.brokenGEBCN){\r\n\t\t\t\tchildren = node.getElementsByClassName(classList.join(' '));\r\n\t\t\t\tif (!(children && children.length)) break getByClass;\r\n\t\t\t\tfor (i = 0; item = children[i++];) this.push(item, tag, id, null, attributes, pseudos);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\t\tgetByTag: {\r\n\t\t\tchildren = node.getElementsByTagName(tag);\r\n\t\t\tif (!(children && children.length)) break getByTag;\r\n\t\t\tif (!this.brokenStarGEBTN) tag = null;\r\n\t\t\tfor (i = 0; item = children[i++];) this.push(item, tag, id, classes, attributes, pseudos);\r\n\t\t}\r\n\t},\r\n\r\n\t'>': function(node, tag, id, classes, attributes, pseudos){ // direct children\r\n\t\tif ((node = node.firstChild)) do {\r\n\t\t\tif (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);\r\n\t\t} while ((node = node.nextSibling));\r\n\t},\r\n\r\n\t'+': function(node, tag, id, classes, attributes, pseudos){ // next sibling\r\n\t\twhile ((node = node.nextSibling)) if (node.nodeType == 1){\r\n\t\t\tthis.push(node, tag, id, classes, attributes, pseudos);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t},\r\n\r\n\t'^': function(node, tag, id, classes, attributes, pseudos){ // first child\r\n\t\tnode = node.firstChild;\r\n\t\tif (node){\r\n\t\t\tif (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);\r\n\t\t\telse this['combinator:+'](node, tag, id, classes, attributes, pseudos);\r\n\t\t}\r\n\t},\r\n\r\n\t'~': function(node, tag, id, classes, attributes, pseudos){ // next siblings\r\n\t\twhile ((node = node.nextSibling)){\r\n\t\t\tif (node.nodeType != 1) continue;\r\n\t\t\tvar uid = this.getUID(node);\r\n\t\t\tif (this.bitUniques[uid]) break;\r\n\t\t\tthis.bitUniques[uid] = true;\r\n\t\t\tthis.push(node, tag, id, classes, attributes, pseudos);\r\n\t\t}\r\n\t},\r\n\r\n\t'++': function(node, tag, id, classes, attributes, pseudos){ // next sibling and previous sibling\r\n\t\tthis['combinator:+'](node, tag, id, classes, attributes, pseudos);\r\n\t\tthis['combinator:!+'](node, tag, id, classes, attributes, pseudos);\r\n\t},\r\n\r\n\t'~~': function(node, tag, id, classes, attributes, pseudos){ // next siblings and previous siblings\r\n\t\tthis['combinator:~'](node, tag, id, classes, attributes, pseudos);\r\n\t\tthis['combinator:!~'](node, tag, id, classes, attributes, pseudos);\r\n\t},\r\n\r\n\t'!': function(node, tag, id, classes, attributes, pseudos){ // all parent nodes up to document\r\n\t\twhile ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);\r\n\t},\r\n\r\n\t'!>': function(node, tag, id, classes, attributes, pseudos){ // direct parent (one level)\r\n\t\tnode = node.parentNode;\r\n\t\tif (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);\r\n\t},\r\n\r\n\t'!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibling\r\n\t\twhile ((node = node.previousSibling)) if (node.nodeType == 1){\r\n\t\t\tthis.push(node, tag, id, classes, attributes, pseudos);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t},\r\n\r\n\t'!^': function(node, tag, id, classes, attributes, pseudos){ // last child\r\n\t\tnode = node.lastChild;\r\n\t\tif (node){\r\n\t\t\tif (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);\r\n\t\t\telse this['combinator:!+'](node, tag, id, classes, attributes, pseudos);\r\n\t\t}\r\n\t},\r\n\r\n\t'!~': function(node, tag, id, classes, attributes, pseudos){ // previous siblings\r\n\t\twhile ((node = node.previousSibling)){\r\n\t\t\tif (node.nodeType != 1) continue;\r\n\t\t\tvar uid = this.getUID(node);\r\n\t\t\tif (this.bitUniques[uid]) break;\r\n\t\t\tthis.bitUniques[uid] = true;\r\n\t\t\tthis.push(node, tag, id, classes, attributes, pseudos);\r\n\t\t}\r\n\t}\r\n\r\n};\r\n\r\nfor (var c in combinators) local['combinator:' + c] = combinators[c];\r\n\r\nvar pseudos = {\r\n\r\n\t/**/\r\n\r\n\t'empty': function(node){\r\n\t\tvar child = node.firstChild;\r\n\t\treturn !(child && child.nodeType == 1) && !(node.innerText || node.textContent || '').length;\r\n\t},\r\n\r\n\t'not': function(node, expression){\r\n\t\treturn !this.matchNode(node, expression);\r\n\t},\r\n\r\n\t'contains': function(node, text){\r\n\t\treturn (node.innerText || node.textContent || '').indexOf(text) > -1;\r\n\t},\r\n\r\n\t'first-child': function(node){\r\n\t\twhile ((node = node.previousSibling)) if (node.nodeType == 1) return false;\r\n\t\treturn true;\r\n\t},\r\n\r\n\t'last-child': function(node){\r\n\t\twhile ((node = node.nextSibling)) if (node.nodeType == 1) return false;\r\n\t\treturn true;\r\n\t},\r\n\r\n\t'only-child': function(node){\r\n\t\tvar prev = node;\r\n\t\twhile ((prev = prev.previousSibling)) if (prev.nodeType == 1) return false;\r\n\t\tvar next = node;\r\n\t\twhile ((next = next.nextSibling)) if (next.nodeType == 1) return false;\r\n\t\treturn true;\r\n\t},\r\n\r\n\t/**/\r\n\r\n\t'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH'),\r\n\r\n\t'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHLast'),\r\n\r\n\t'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTHType', true),\r\n\r\n\t'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHTypeLast', true),\r\n\r\n\t'index': function(node, index){\r\n\t\treturn this['pseudo:nth-child'](node, '' + (index + 1));\r\n\t},\r\n\r\n\t'even': function(node){\r\n\t\treturn this['pseudo:nth-child'](node, '2n');\r\n\t},\r\n\r\n\t'odd': function(node){\r\n\t\treturn this['pseudo:nth-child'](node, '2n+1');\r\n\t},\r\n\r\n\t/**/\r\n\r\n\t/**/\r\n\r\n\t'first-of-type': function(node){\r\n\t\tvar nodeName = node.nodeName;\r\n\t\twhile ((node = node.previousSibling)) if (node.nodeName == nodeName) return false;\r\n\t\treturn true;\r\n\t},\r\n\r\n\t'last-of-type': function(node){\r\n\t\tvar nodeName = node.nodeName;\r\n\t\twhile ((node = node.nextSibling)) if (node.nodeName == nodeName) return false;\r\n\t\treturn true;\r\n\t},\r\n\r\n\t'only-of-type': function(node){\r\n\t\tvar prev = node, nodeName = node.nodeName;\r\n\t\twhile ((prev = prev.previousSibling)) if (prev.nodeName == nodeName) return false;\r\n\t\tvar next = node;\r\n\t\twhile ((next = next.nextSibling)) if (next.nodeName == nodeName) return false;\r\n\t\treturn true;\r\n\t},\r\n\r\n\t/**/\r\n\r\n\t// custom pseudos\r\n\r\n\t'enabled': function(node){\r\n\t\treturn !node.disabled;\r\n\t},\r\n\r\n\t'disabled': function(node){\r\n\t\treturn node.disabled;\r\n\t},\r\n\r\n\t'checked': function(node){\r\n\t\treturn node.checked || node.selected;\r\n\t},\r\n\r\n\t'focus': function(node){\r\n\t\treturn this.isHTMLDocument && this.document.activeElement === node && (node.href || node.type || this.hasAttribute(node, 'tabindex'));\r\n\t},\r\n\r\n\t'root': function(node){\r\n\t\treturn (node === this.root);\r\n\t},\r\n\r\n\t'selected': function(node){\r\n\t\treturn node.selected;\r\n\t}\r\n\r\n\t/**/\r\n};\r\n\r\nfor (var p in pseudos) local['pseudo:' + p] = pseudos[p];\r\n\r\n// attributes methods\r\n\r\nvar attributeGetters = local.attributeGetters = {\r\n\r\n\t'for': function(){\r\n\t\treturn ('htmlFor' in this) ? this.htmlFor : this.getAttribute('for');\r\n\t},\r\n\r\n\t'href': function(){\r\n\t\treturn ('href' in this) ? this.getAttribute('href', 2) : this.getAttribute('href');\r\n\t},\r\n\r\n\t'style': function(){\r\n\t\treturn (this.style) ? this.style.cssText : this.getAttribute('style');\r\n\t},\r\n\r\n\t'tabindex': function(){\r\n\t\tvar attributeNode = this.getAttributeNode('tabindex');\r\n\t\treturn (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;\r\n\t},\r\n\r\n\t'type': function(){\r\n\t\treturn this.getAttribute('type');\r\n\t},\r\n\r\n\t'maxlength': function(){\r\n\t\tvar attributeNode = this.getAttributeNode('maxLength');\r\n\t\treturn (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;\r\n\t}\r\n\r\n};\r\n\r\nattributeGetters.MAXLENGTH = attributeGetters.maxLength = attributeGetters.maxlength;\r\n\r\n// Slick\r\n\r\nvar Slick = local.Slick = (this.Slick || {});\r\n\r\nSlick.version = '1.1.7';\r\n\r\n// Slick finder\r\n\r\nSlick.search = function(context, expression, append){\r\n\treturn local.search(context, expression, append);\r\n};\r\n\r\nSlick.find = function(context, expression){\r\n\treturn local.search(context, expression, null, true);\r\n};\r\n\r\n// Slick containment checker\r\n\r\nSlick.contains = function(container, node){\r\n\tlocal.setDocument(container);\r\n\treturn local.contains(container, node);\r\n};\r\n\r\n// Slick attribute getter\r\n\r\nSlick.getAttribute = function(node, name){\r\n\tlocal.setDocument(node);\r\n\treturn local.getAttribute(node, name);\r\n};\r\n\r\nSlick.hasAttribute = function(node, name){\r\n\tlocal.setDocument(node);\r\n\treturn local.hasAttribute(node, name);\r\n};\r\n\r\n// Slick matcher\r\n\r\nSlick.match = function(node, selector){\r\n\tif (!(node && selector)) return false;\r\n\tif (!selector || selector === node) return true;\r\n\tlocal.setDocument(node);\r\n\treturn local.matchNode(node, selector);\r\n};\r\n\r\n// Slick attribute accessor\r\n\r\nSlick.defineAttributeGetter = function(name, fn){\r\n\tlocal.attributeGetters[name] = fn;\r\n\treturn this;\r\n};\r\n\r\nSlick.lookupAttributeGetter = function(name){\r\n\treturn local.attributeGetters[name];\r\n};\r\n\r\n// Slick pseudo accessor\r\n\r\nSlick.definePseudo = function(name, fn){\r\n\tlocal['pseudo:' + name] = function(node, argument){\r\n\t\treturn fn.call(node, argument);\r\n\t};\r\n\treturn this;\r\n};\r\n\r\nSlick.lookupPseudo = function(name){\r\n\tvar pseudo = local['pseudo:' + name];\r\n\tif (pseudo) return function(argument){\r\n\t\treturn pseudo.call(this, argument);\r\n\t};\r\n\treturn null;\r\n};\r\n\r\n// Slick overrides accessor\r\n\r\nSlick.override = function(regexp, fn){\r\n\tlocal.override(regexp, fn);\r\n\treturn this;\r\n};\r\n\r\nSlick.isXML = local.isXML;\r\n\r\nSlick.uidOf = function(node){\r\n\treturn local.getUIDHTML(node);\r\n};\r\n\r\nif (!this.Slick) this.Slick = Slick;\r\n\r\n}).apply(/**/(typeof exports != 'undefined') ? exports : /**/this);\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Element\r\n\r\ndescription: Contains the dollar function, the dollars function, and an handful of cross-browser, time-saver methods to let you easily work with HTML Elements.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Window, Document, Array, String, Function, Object, Number, Slick.Parser, Slick.Finder]\r\n\r\nprovides: [Element, Elements, $, $$, Iframe, Selectors]\r\n\r\n...\r\n*/\r\n\r\nvar Element = function(tag, props){\r\n\tvar konstructor = Element.Constructors[tag];\r\n\tif (konstructor) return konstructor(props);\r\n\tif (typeof tag != 'string') return document.id(tag).set(props);\r\n\r\n\tif (!props) props = {};\r\n\r\n\tif (!(/^[\\w-]+$/).test(tag)){\r\n\t\tvar parsed = Slick.parse(tag).expressions[0][0];\r\n\t\ttag = (parsed.tag == '*') ? 'div' : parsed.tag;\r\n\t\tif (parsed.id && props.id == null) props.id = parsed.id;\r\n\r\n\t\tvar attributes = parsed.attributes;\r\n\t\tif (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){\r\n\t\t\tattr = attributes[i];\r\n\t\t\tif (props[attr.key] != null) continue;\r\n\r\n\t\t\tif (attr.value != null && attr.operator == '=') props[attr.key] = attr.value;\r\n\t\t\telse if (!attr.value && !attr.operator) props[attr.key] = true;\r\n\t\t}\r\n\r\n\t\tif (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');\r\n\t}\r\n\r\n\treturn document.newElement(tag, props);\r\n};\r\n\r\n\r\nif (Browser.Element){\r\n\tElement.prototype = Browser.Element.prototype;\r\n\t// IE8 and IE9 require the wrapping.\r\n\tElement.prototype._fireEvent = (function(fireEvent){\r\n\t\treturn function(type, event){\r\n\t\t\treturn fireEvent.call(this, type, event);\r\n\t\t};\r\n\t})(Element.prototype.fireEvent);\r\n}\r\n\r\nnew Type('Element', Element).mirror(function(name){\r\n\tif (Array.prototype[name]) return;\r\n\r\n\tvar obj = {};\r\n\tobj[name] = function(){\r\n\t\tvar results = [], args = arguments, elements = true;\r\n\t\tfor (var i = 0, l = this.length; i < l; i++){\r\n\t\t\tvar element = this[i], result = results[i] = element[name].apply(element, args);\r\n\t\t\telements = (elements && typeOf(result) == 'element');\r\n\t\t}\r\n\t\treturn (elements) ? new Elements(results) : results;\r\n\t};\r\n\r\n\tElements.implement(obj);\r\n});\r\n\r\nif (!Browser.Element){\r\n\tElement.parent = Object;\r\n\r\n\tElement.Prototype = {\r\n\t\t'$constructor': Element,\r\n\t\t'$family': Function.from('element').hide()\r\n\t};\r\n\r\n\tElement.mirror(function(name, method){\r\n\t\tElement.Prototype[name] = method;\r\n\t});\r\n}\r\n\r\nElement.Constructors = {};\r\n\r\n//<1.2compat>\r\n\r\nElement.Constructors = new Hash;\r\n\r\n//\r\n\r\nvar IFrame = new Type('IFrame', function(){\r\n\tvar params = Array.link(arguments, {\r\n\t\tproperties: Type.isObject,\r\n\t\tiframe: function(obj){\r\n\t\t\treturn (obj != null);\r\n\t\t}\r\n\t});\r\n\r\n\tvar props = params.properties || {}, iframe;\r\n\tif (params.iframe) iframe = document.id(params.iframe);\r\n\tvar onload = props.onload || function(){};\r\n\tdelete props.onload;\r\n\tprops.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + String.uniqueID()].pick();\r\n\tiframe = new Element(iframe || 'iframe', props);\r\n\r\n\tvar onLoad = function(){\r\n\t\tonload.call(iframe.contentWindow);\r\n\t};\r\n\r\n\tif (window.frames[props.id]) onLoad();\r\n\telse iframe.addListener('load', onLoad);\r\n\treturn iframe;\r\n});\r\n\r\nvar Elements = this.Elements = function(nodes){\r\n\tif (nodes && nodes.length){\r\n\t\tvar uniques = {}, node;\r\n\t\tfor (var i = 0; node = nodes[i++];){\r\n\t\t\tvar uid = Slick.uidOf(node);\r\n\t\t\tif (!uniques[uid]){\r\n\t\t\t\tuniques[uid] = true;\r\n\t\t\t\tthis.push(node);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nElements.prototype = {length: 0};\r\nElements.parent = Array;\r\n\r\nnew Type('Elements', Elements).implement({\r\n\r\n\tfilter: function(filter, bind){\r\n\t\tif (!filter) return this;\r\n\t\treturn new Elements(Array.filter(this, (typeOf(filter) == 'string') ? function(item){\r\n\t\t\treturn item.match(filter);\r\n\t\t} : filter, bind));\r\n\t}.protect(),\r\n\r\n\tpush: function(){\r\n\t\tvar length = this.length;\r\n\t\tfor (var i = 0, l = arguments.length; i < l; i++){\r\n\t\t\tvar item = document.id(arguments[i]);\r\n\t\t\tif (item) this[length++] = item;\r\n\t\t}\r\n\t\treturn (this.length = length);\r\n\t}.protect(),\r\n\r\n\tunshift: function(){\r\n\t\tvar items = [];\r\n\t\tfor (var i = 0, l = arguments.length; i < l; i++){\r\n\t\t\tvar item = document.id(arguments[i]);\r\n\t\t\tif (item) items.push(item);\r\n\t\t}\r\n\t\treturn Array.prototype.unshift.apply(this, items);\r\n\t}.protect(),\r\n\r\n\tconcat: function(){\r\n\t\tvar newElements = new Elements(this);\r\n\t\tfor (var i = 0, l = arguments.length; i < l; i++){\r\n\t\t\tvar item = arguments[i];\r\n\t\t\tif (Type.isEnumerable(item)) newElements.append(item);\r\n\t\t\telse newElements.push(item);\r\n\t\t}\r\n\t\treturn newElements;\r\n\t}.protect(),\r\n\r\n\tappend: function(collection){\r\n\t\tfor (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]);\r\n\t\treturn this;\r\n\t}.protect(),\r\n\r\n\tempty: function(){\r\n\t\twhile (this.length) delete this[--this.length];\r\n\t\treturn this;\r\n\t}.protect()\r\n\r\n});\r\n\r\n//<1.2compat>\r\n\r\nElements.alias('extend', 'append');\r\n\r\n//\r\n\r\n(function(){\r\n\r\n// FF, IE\r\nvar splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2};\r\n\r\nsplice.call(object, 1, 1);\r\nif (object[1] == 1) Elements.implement('splice', function(){\r\n\tvar length = this.length;\r\n\tvar result = splice.apply(this, arguments);\r\n\twhile (length >= this.length) delete this[length--];\r\n\treturn result;\r\n}.protect());\r\n\r\nArray.forEachMethod(function(method, name){\r\n\tElements.implement(name, method);\r\n});\r\n\r\nArray.mirror(Elements);\r\n\r\n/**/\r\nvar createElementAcceptsHTML;\r\ntry {\r\n\tcreateElementAcceptsHTML = (document.createElement('').name == 'x');\r\n} catch (e){}\r\n\r\nvar escapeQuotes = function(html){\r\n\treturn ('' + html).replace(/&/g, '&').replace(/\"/g, '"');\r\n};\r\n/**/\r\n\r\nDocument.implement({\r\n\r\n\tnewElement: function(tag, props){\r\n\t\tif (props && props.checked != null) props.defaultChecked = props.checked;\r\n\t\t/**/// Fix for readonly name and type properties in IE < 8\r\n\t\tif (createElementAcceptsHTML && props){\r\n\t\t\ttag = '<' + tag;\r\n\t\t\tif (props.name) tag += ' name=\"' + escapeQuotes(props.name) + '\"';\r\n\t\t\tif (props.type) tag += ' type=\"' + escapeQuotes(props.type) + '\"';\r\n\t\t\ttag += '>';\r\n\t\t\tdelete props.name;\r\n\t\t\tdelete props.type;\r\n\t\t}\r\n\t\t/**/\r\n\t\treturn this.id(this.createElement(tag)).set(props);\r\n\t}\r\n\r\n});\r\n\r\n})();\r\n\r\n(function(){\r\n\r\nSlick.uidOf(window);\r\nSlick.uidOf(document);\r\n\r\nDocument.implement({\r\n\r\n\tnewTextNode: function(text){\r\n\t\treturn this.createTextNode(text);\r\n\t},\r\n\r\n\tgetDocument: function(){\r\n\t\treturn this;\r\n\t},\r\n\r\n\tgetWindow: function(){\r\n\t\treturn this.window;\r\n\t},\r\n\r\n\tid: (function(){\r\n\r\n\t\tvar types = {\r\n\r\n\t\t\tstring: function(id, nocash, doc){\r\n\t\t\t\tid = Slick.find(doc, '#' + id.replace(/(\\W)/g, '\\\\$1'));\r\n\t\t\t\treturn (id) ? types.element(id, nocash) : null;\r\n\t\t\t},\r\n\r\n\t\t\telement: function(el, nocash){\r\n\t\t\t\tSlick.uidOf(el);\r\n\t\t\t\tif (!nocash && !el.$family && !(/^(?:object|embed)$/i).test(el.tagName)){\r\n\t\t\t\t\tvar fireEvent = el.fireEvent;\r\n\t\t\t\t\t// wrapping needed in IE7, or else crash\r\n\t\t\t\t\tel._fireEvent = function(type, event){\r\n\t\t\t\t\t\treturn fireEvent(type, event);\r\n\t\t\t\t\t};\r\n\t\t\t\t\tObject.append(el, Element.Prototype);\r\n\t\t\t\t}\r\n\t\t\t\treturn el;\r\n\t\t\t},\r\n\r\n\t\t\tobject: function(obj, nocash, doc){\r\n\t\t\t\tif (obj.toElement) return types.element(obj.toElement(doc), nocash);\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t};\r\n\r\n\t\ttypes.textnode = types.whitespace = types.window = types.document = function(zero){\r\n\t\t\treturn zero;\r\n\t\t};\r\n\r\n\t\treturn function(el, nocash, doc){\r\n\t\t\tif (el && el.$family && el.uniqueNumber) return el;\r\n\t\t\tvar type = typeOf(el);\r\n\t\t\treturn (types[type]) ? types[type](el, nocash, doc || document) : null;\r\n\t\t};\r\n\r\n\t})()\r\n\r\n});\r\n\r\nif (window.$ == null) Window.implement('$', function(el, nc){\r\n\treturn document.id(el, nc, this.document);\r\n});\r\n\r\nWindow.implement({\r\n\r\n\tgetDocument: function(){\r\n\t\treturn this.document;\r\n\t},\r\n\r\n\tgetWindow: function(){\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n[Document, Element].invoke('implement', {\r\n\r\n\tgetElements: function(expression){\r\n\t\treturn Slick.search(this, expression, new Elements);\r\n\t},\r\n\r\n\tgetElement: function(expression){\r\n\t\treturn document.id(Slick.find(this, expression));\r\n\t}\r\n\r\n});\r\n\r\nvar contains = {contains: function(element){\r\n\treturn Slick.contains(this, element);\r\n}};\r\n\r\nif (!document.contains) Document.implement(contains);\r\nif (!document.createElement('div').contains) Element.implement(contains);\r\n\r\n//<1.2compat>\r\n\r\nElement.implement('hasChild', function(element){\r\n\treturn this !== element && this.contains(element);\r\n});\r\n\r\n(function(search, find, match){\r\n\r\n\tthis.Selectors = {};\r\n\tvar pseudos = this.Selectors.Pseudo = new Hash();\r\n\r\n\tvar addSlickPseudos = function(){\r\n\t\tfor (var name in pseudos) if (pseudos.hasOwnProperty(name)){\r\n\t\t\tSlick.definePseudo(name, pseudos[name]);\r\n\t\t\tdelete pseudos[name];\r\n\t\t}\r\n\t};\r\n\r\n\tSlick.search = function(context, expression, append){\r\n\t\taddSlickPseudos();\r\n\t\treturn search.call(this, context, expression, append);\r\n\t};\r\n\r\n\tSlick.find = function(context, expression){\r\n\t\taddSlickPseudos();\r\n\t\treturn find.call(this, context, expression);\r\n\t};\r\n\r\n\tSlick.match = function(node, selector){\r\n\t\taddSlickPseudos();\r\n\t\treturn match.call(this, node, selector);\r\n\t};\r\n\r\n})(Slick.search, Slick.find, Slick.match);\r\n\r\n//\r\n\r\n// tree walking\r\n\r\nvar injectCombinator = function(expression, combinator){\r\n\tif (!expression) return combinator;\r\n\r\n\texpression = Object.clone(Slick.parse(expression));\r\n\r\n\tvar expressions = expression.expressions;\r\n\tfor (var i = expressions.length; i--;)\r\n\t\texpressions[i][0].combinator = combinator;\r\n\r\n\treturn expression;\r\n};\r\n\r\nObject.forEach({\r\n\tgetNext: '~',\r\n\tgetPrevious: '!~',\r\n\tgetParent: '!'\r\n}, function(combinator, method){\r\n\tElement.implement(method, function(expression){\r\n\t\treturn this.getElement(injectCombinator(expression, combinator));\r\n\t});\r\n});\r\n\r\nObject.forEach({\r\n\tgetAllNext: '~',\r\n\tgetAllPrevious: '!~',\r\n\tgetSiblings: '~~',\r\n\tgetChildren: '>',\r\n\tgetParents: '!'\r\n}, function(combinator, method){\r\n\tElement.implement(method, function(expression){\r\n\t\treturn this.getElements(injectCombinator(expression, combinator));\r\n\t});\r\n});\r\n\r\nElement.implement({\r\n\r\n\tgetFirst: function(expression){\r\n\t\treturn document.id(Slick.search(this, injectCombinator(expression, '>'))[0]);\r\n\t},\r\n\r\n\tgetLast: function(expression){\r\n\t\treturn document.id(Slick.search(this, injectCombinator(expression, '>')).getLast());\r\n\t},\r\n\r\n\tgetWindow: function(){\r\n\t\treturn this.ownerDocument.window;\r\n\t},\r\n\r\n\tgetDocument: function(){\r\n\t\treturn this.ownerDocument;\r\n\t},\r\n\r\n\tgetElementById: function(id){\r\n\t\treturn document.id(Slick.find(this, '#' + ('' + id).replace(/(\\W)/g, '\\\\$1')));\r\n\t},\r\n\r\n\tmatch: function(expression){\r\n\t\treturn !expression || Slick.match(this, expression);\r\n\t}\r\n\r\n});\r\n\r\n//<1.2compat>\r\n\r\nif (window.$$ == null) Window.implement('$$', function(selector){\r\n\tvar elements = new Elements;\r\n\tif (arguments.length == 1 && typeof selector == 'string') return Slick.search(this.document, selector, elements);\r\n\tvar args = Array.flatten(arguments);\r\n\tfor (var i = 0, l = args.length; i < l; i++){\r\n\t\tvar item = args[i];\r\n\t\tswitch (typeOf(item)){\r\n\t\t\tcase 'element': elements.push(item); break;\r\n\t\t\tcase 'string': Slick.search(this.document, item, elements);\r\n\t\t}\r\n\t}\r\n\treturn elements;\r\n});\r\n\r\n//\r\n\r\nif (window.$$ == null) Window.implement('$$', function(selector){\r\n\tif (arguments.length == 1){\r\n\t\tif (typeof selector == 'string') return Slick.search(this.document, selector, new Elements);\r\n\t\telse if (Type.isEnumerable(selector)) return new Elements(selector);\r\n\t}\r\n\treturn new Elements(arguments);\r\n});\r\n\r\n// Inserters\r\n\r\nvar inserters = {\r\n\r\n\tbefore: function(context, element){\r\n\t\tvar parent = element.parentNode;\r\n\t\tif (parent) parent.insertBefore(context, element);\r\n\t},\r\n\r\n\tafter: function(context, element){\r\n\t\tvar parent = element.parentNode;\r\n\t\tif (parent) parent.insertBefore(context, element.nextSibling);\r\n\t},\r\n\r\n\tbottom: function(context, element){\r\n\t\telement.appendChild(context);\r\n\t},\r\n\r\n\ttop: function(context, element){\r\n\t\telement.insertBefore(context, element.firstChild);\r\n\t}\r\n\r\n};\r\n\r\ninserters.inside = inserters.bottom;\r\n\r\n//<1.2compat>\r\n\r\nObject.each(inserters, function(inserter, where){\r\n\r\n\twhere = where.capitalize();\r\n\r\n\tvar methods = {};\r\n\r\n\tmethods['inject' + where] = function(el){\r\n\t\tinserter(this, document.id(el, true));\r\n\t\treturn this;\r\n\t};\r\n\r\n\tmethods['grab' + where] = function(el){\r\n\t\tinserter(document.id(el, true), this);\r\n\t\treturn this;\r\n\t};\r\n\r\n\tElement.implement(methods);\r\n\r\n});\r\n\r\n//\r\n\r\n// getProperty / setProperty\r\n\r\nvar propertyGetters = {}, propertySetters = {};\r\n\r\n// properties\r\n\r\nvar properties = {};\r\nArray.forEach([\r\n\t'type', 'value', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan',\r\n\t'frameBorder', 'rowSpan', 'tabIndex', 'useMap'\r\n], function(property){\r\n\tproperties[property.toLowerCase()] = property;\r\n});\r\n\r\nproperties.html = 'innerHTML';\r\nproperties.text = (document.createElement('div').textContent == null) ? 'innerText': 'textContent';\r\n\r\nObject.forEach(properties, function(real, key){\r\n\tpropertySetters[key] = function(node, value){\r\n\t\tnode[real] = value;\r\n\t};\r\n\tpropertyGetters[key] = function(node){\r\n\t\treturn node[real];\r\n\t};\r\n});\r\n\r\n// Booleans\r\n\r\nvar bools = [\r\n\t'compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked',\r\n\t'disabled', 'readOnly', 'multiple', 'selected', 'noresize',\r\n\t'defer', 'defaultChecked', 'autofocus', 'controls', 'autoplay',\r\n\t'loop'\r\n];\r\n\r\nvar booleans = {};\r\nArray.forEach(bools, function(bool){\r\n\tvar lower = bool.toLowerCase();\r\n\tbooleans[lower] = bool;\r\n\tpropertySetters[lower] = function(node, value){\r\n\t\tnode[bool] = !!value;\r\n\t};\r\n\tpropertyGetters[lower] = function(node){\r\n\t\treturn !!node[bool];\r\n\t};\r\n});\r\n\r\n// Special cases\r\n\r\nObject.append(propertySetters, {\r\n\r\n\t'class': function(node, value){\r\n\t\t('className' in node) ? node.className = (value || '') : node.setAttribute('class', value);\r\n\t},\r\n\r\n\t'for': function(node, value){\r\n\t\t('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value);\r\n\t},\r\n\r\n\t'style': function(node, value){\r\n\t\t(node.style) ? node.style.cssText = value : node.setAttribute('style', value);\r\n\t},\r\n\r\n\t'value': function(node, value){\r\n\t\tnode.value = (value != null) ? value : '';\r\n\t}\r\n\r\n});\r\n\r\npropertyGetters['class'] = function(node){\r\n\treturn ('className' in node) ? node.className || null : node.getAttribute('class');\r\n};\r\n\r\n/* */\r\nvar el = document.createElement('button');\r\n// IE sets type as readonly and throws\r\ntry { el.type = 'button'; } catch(e){}\r\nif (el.type != 'button') propertySetters.type = function(node, value){\r\n\tnode.setAttribute('type', value);\r\n};\r\nel = null;\r\n/* */\r\n\r\n/**/\r\nvar input = document.createElement('input');\r\ninput.value = 't';\r\ninput.type = 'submit';\r\nif (input.value != 't') propertySetters.type = function(node, type){\r\n\tvar value = node.value;\r\n\tnode.type = type;\r\n\tnode.value = value;\r\n};\r\ninput = null;\r\n/**/\r\n\r\n/* getProperty, setProperty */\r\n\r\n/* */\r\nvar pollutesGetAttribute = (function(div){\r\n\tdiv.random = 'attribute';\r\n\treturn (div.getAttribute('random') == 'attribute');\r\n})(document.createElement('div'));\r\n\r\n/* */\r\n\r\nElement.implement({\r\n\r\n\tsetProperty: function(name, value){\r\n\t\tvar setter = propertySetters[name.toLowerCase()];\r\n\t\tif (setter){\r\n\t\t\tsetter(this, value);\r\n\t\t} else {\r\n\t\t\t/* */\r\n\t\t\tif (pollutesGetAttribute) var attributeWhiteList = this.retrieve('$attributeWhiteList', {});\r\n\t\t\t/* */\r\n\r\n\t\t\tif (value == null){\r\n\t\t\t\tthis.removeAttribute(name);\r\n\t\t\t\t/* */\r\n\t\t\t\tif (pollutesGetAttribute) delete attributeWhiteList[name];\r\n\t\t\t\t/* */\r\n\t\t\t} else {\r\n\t\t\t\tthis.setAttribute(name, '' + value);\r\n\t\t\t\t/* */\r\n\t\t\t\tif (pollutesGetAttribute) attributeWhiteList[name] = true;\r\n\t\t\t\t/* */\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\tsetProperties: function(attributes){\r\n\t\tfor (var attribute in attributes) this.setProperty(attribute, attributes[attribute]);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tgetProperty: function(name){\r\n\t\tvar getter = propertyGetters[name.toLowerCase()];\r\n\t\tif (getter) return getter(this);\r\n\t\t/* */\r\n\t\tif (pollutesGetAttribute){\r\n\t\t\tvar attr = this.getAttributeNode(name), attributeWhiteList = this.retrieve('$attributeWhiteList', {});\r\n\t\t\tif (!attr) return null;\r\n\t\t\tif (attr.expando && !attributeWhiteList[name]){\r\n\t\t\t\tvar outer = this.outerHTML;\r\n\t\t\t\t// segment by the opening tag and find mention of attribute name\r\n\t\t\t\tif (outer.substr(0, outer.search(/\\/?['\"]?>(?![^<]*<['\"])/)).indexOf(name) < 0) return null;\r\n\t\t\t\tattributeWhiteList[name] = true;\r\n\t\t\t}\r\n\t\t}\r\n\t\t/* */\r\n\t\tvar result = Slick.getAttribute(this, name);\r\n\t\treturn (!result && !Slick.hasAttribute(this, name)) ? null : result;\r\n\t},\r\n\r\n\tgetProperties: function(){\r\n\t\tvar args = Array.from(arguments);\r\n\t\treturn args.map(this.getProperty, this).associate(args);\r\n\t},\r\n\r\n\tremoveProperty: function(name){\r\n\t\treturn this.setProperty(name, null);\r\n\t},\r\n\r\n\tremoveProperties: function(){\r\n\t\tArray.each(arguments, this.removeProperty, this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tset: function(prop, value){\r\n\t\tvar property = Element.Properties[prop];\r\n\t\t(property && property.set) ? property.set.call(this, value) : this.setProperty(prop, value);\r\n\t}.overloadSetter(),\r\n\r\n\tget: function(prop){\r\n\t\tvar property = Element.Properties[prop];\r\n\t\treturn (property && property.get) ? property.get.apply(this) : this.getProperty(prop);\r\n\t}.overloadGetter(),\r\n\r\n\terase: function(prop){\r\n\t\tvar property = Element.Properties[prop];\r\n\t\t(property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop);\r\n\t\treturn this;\r\n\t},\r\n\r\n\thasClass: function(className){\r\n\t\treturn this.className.clean().contains(className, ' ');\r\n\t},\r\n\r\n\taddClass: function(className){\r\n\t\tif (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();\r\n\t\treturn this;\r\n\t},\r\n\r\n\tremoveClass: function(className){\r\n\t\tthis.className = this.className.replace(new RegExp('(^|\\\\s)' + className + '(?:\\\\s|$)'), '$1');\r\n\t\treturn this;\r\n\t},\r\n\r\n\ttoggleClass: function(className, force){\r\n\t\tif (force == null) force = !this.hasClass(className);\r\n\t\treturn (force) ? this.addClass(className) : this.removeClass(className);\r\n\t},\r\n\r\n\tadopt: function(){\r\n\t\tvar parent = this, fragment, elements = Array.flatten(arguments), length = elements.length;\r\n\t\tif (length > 1) parent = fragment = document.createDocumentFragment();\r\n\r\n\t\tfor (var i = 0; i < length; i++){\r\n\t\t\tvar element = document.id(elements[i], true);\r\n\t\t\tif (element) parent.appendChild(element);\r\n\t\t}\r\n\r\n\t\tif (fragment) this.appendChild(fragment);\r\n\r\n\t\treturn this;\r\n\t},\r\n\r\n\tappendText: function(text, where){\r\n\t\treturn this.grab(this.getDocument().newTextNode(text), where);\r\n\t},\r\n\r\n\tgrab: function(el, where){\r\n\t\tinserters[where || 'bottom'](document.id(el, true), this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tinject: function(el, where){\r\n\t\tinserters[where || 'bottom'](this, document.id(el, true));\r\n\t\treturn this;\r\n\t},\r\n\r\n\treplaces: function(el){\r\n\t\tel = document.id(el, true);\r\n\t\tel.parentNode.replaceChild(this, el);\r\n\t\treturn this;\r\n\t},\r\n\r\n\twraps: function(el, where){\r\n\t\tel = document.id(el, true);\r\n\t\treturn this.replaces(el).grab(el, where);\r\n\t},\r\n\r\n\tgetSelected: function(){\r\n\t\tthis.selectedIndex; // Safari 3.2.1\r\n\t\treturn new Elements(Array.from(this.options).filter(function(option){\r\n\t\t\treturn option.selected;\r\n\t\t}));\r\n\t},\r\n\r\n\ttoQueryString: function(){\r\n\t\tvar queryString = [];\r\n\t\tthis.getElements('input, select, textarea').each(function(el){\r\n\t\t\tvar type = el.type;\r\n\t\t\tif (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;\r\n\r\n\t\t\tvar value = (el.get('tag') == 'select') ? el.getSelected().map(function(opt){\r\n\t\t\t\t// IE\r\n\t\t\t\treturn document.id(opt).get('value');\r\n\t\t\t}) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el.get('value');\r\n\r\n\t\t\tArray.from(value).each(function(val){\r\n\t\t\t\tif (typeof val != 'undefined') queryString.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(val));\r\n\t\t\t});\r\n\t\t});\r\n\t\treturn queryString.join('&');\r\n\t}\r\n\r\n});\r\n\r\nvar collected = {}, storage = {};\r\n\r\nvar get = function(uid){\r\n\treturn (storage[uid] || (storage[uid] = {}));\r\n};\r\n\r\nvar clean = function(item){\r\n\tvar uid = item.uniqueNumber;\r\n\tif (item.removeEvents) item.removeEvents();\r\n\tif (item.clearAttributes) item.clearAttributes();\r\n\tif (uid != null){\r\n\t\tdelete collected[uid];\r\n\t\tdelete storage[uid];\r\n\t}\r\n\r\n\tvar props = ['_fireEvent','$family','$constructor'];\r\n\tprops.each(function(property) {\r\n\t // If the item doesn't have hasOwnProperty, wrap it in a Hash and use its version\r\n\t\tif ((property in item) && ((typeOf(item) != \"document\") && ((!item.hasOwnProperty && new Hash(item).has(property)) || item.hasOwnProperty(property)))) {\r\n\t\t\titem[property] = null;\r\n\t\t}\r\n\t});\r\n\r\n\treturn item;\r\n};\r\n\r\nvar formProps = {input: 'checked', option: 'selected', textarea: 'value'};\r\n\r\nElement.implement({\r\n\r\n\tdestroy: function(){\r\n\t\tif (this.nodeType == 1) {\r\n\t\t\tvar children = clean(this).getElementsByTagName('*');\r\n\t\t\tArray.each(children, clean);\r\n\t\t}\r\n\t\tElement.dispose(this);\r\n\t\treturn null;\r\n\t},\r\n\r\n\tempty: function(){\r\n\t\tArray.from(this.childNodes).each(Element.destroy);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tdispose: function(){\r\n\t\treturn (this.parentNode) ? this.parentNode.removeChild(this) : this;\r\n\t},\r\n\r\n\tclone: function(contents, keepid){\r\n\t\tcontents = contents !== false;\r\n\t\tvar clone = this.cloneNode(contents), ce = [clone], te = [this], i;\r\n\r\n\t\tif (contents){\r\n\t\t\tce.append(Array.from(clone.getElementsByTagName('*')));\r\n\t\t\tte.append(Array.from(this.getElementsByTagName('*')));\r\n\t\t}\r\n\r\n\t\tfor (i = ce.length; i--;){\r\n\t\t\tvar node = ce[i], element = te[i];\r\n\t\t\tif (!keepid) node.removeAttribute('id');\r\n\t\t\t/**/\r\n\t\t\tif (node.clearAttributes){\r\n\t\t\t\tnode.clearAttributes();\r\n\t\t\t\tnode.mergeAttributes(element);\r\n\t\t\t\tnode.removeAttribute('uniqueNumber');\r\n\t\t\t\tif (node.options){\r\n\t\t\t\t\tvar no = node.options, eo = element.options;\r\n\t\t\t\t\tfor (var j = no.length; j--;) no[j].selected = eo[j].selected;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t/**/\r\n\t\t\tvar prop = formProps[element.tagName.toLowerCase()];\r\n\t\t\tif (prop && element[prop]) node[prop] = element[prop];\r\n\t\t}\r\n\r\n\t\t/**/\r\n\t\tif (Browser.ie){\r\n\t\t\tvar co = clone.getElementsByTagName('object'), to = this.getElementsByTagName('object');\r\n\t\t\tfor (i = co.length; i--;) co[i].outerHTML = to[i].outerHTML;\r\n\t\t}\r\n\t\t/**/\r\n\t\treturn document.id(clone);\r\n\t}\r\n\r\n});\r\n\r\n[Element, Window, Document].invoke('implement', {\r\n\r\n\taddListener: function(type, fn){\r\n\t\tif (type == 'unload'){\r\n\t\t\tvar old = fn, self = this;\r\n\t\t\tfn = function(){\r\n\t\t\t\tself.removeListener('unload', fn);\r\n\t\t\t\told();\r\n\t\t\t};\r\n\t\t} else if (window.attachEvent && !window.addEventListener) {\r\n\t\t\tcollected[Slick.uidOf(this)] = this;\r\n\t\t}\r\n\t\tif (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]);\r\n\t\telse this.attachEvent('on' + type, fn);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tremoveListener: function(type, fn){\r\n\t\tif (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]);\r\n\t\telse this.detachEvent('on' + type, fn);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tretrieve: function(property, dflt){\r\n\t\tvar storage = get(Slick.uidOf(this)), prop = storage[property];\r\n\t\tif (dflt != null && prop == null) prop = storage[property] = dflt;\r\n\t\treturn prop != null ? prop : null;\r\n\t},\r\n\r\n\tstore: function(property, value){\r\n\t\tvar storage = get(Slick.uidOf(this));\r\n\t\tstorage[property] = value;\r\n\t\treturn this;\r\n\t},\r\n\r\n\teliminate: function(property){\r\n\t\tvar storage = get(Slick.uidOf(this));\r\n\t\tdelete storage[property];\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n/**/\r\nif (window.attachEvent && !window.addEventListener) window.addListener('unload', function(){\r\n\tObject.each(collected, clean);\r\n\tif (window.CollectGarbage) CollectGarbage();\r\n});\r\n/**/\r\n\r\nElement.Properties = {};\r\n\r\n//<1.2compat>\r\n\r\nElement.Properties = new Hash;\r\n\r\n//\r\n\r\nElement.Properties.style = {\r\n\r\n\tset: function(style){\r\n\t\tthis.style.cssText = style;\r\n\t},\r\n\r\n\tget: function(){\r\n\t\treturn this.style.cssText;\r\n\t},\r\n\r\n\terase: function(){\r\n\t\tthis.style.cssText = '';\r\n\t}\r\n\r\n};\r\n\r\nElement.Properties.tag = {\r\n\r\n\tget: function(){\r\n\t\treturn this.tagName.toLowerCase();\r\n\t}\r\n\r\n};\r\n\r\nElement.Properties.html = {\r\n\r\n\tset: function(html){\r\n\t\tif (html == null) html = '';\r\n\t\telse if (typeOf(html) == 'array') html = html.join('');\r\n\t\tthis.innerHTML = html;\r\n\t},\r\n\r\n\terase: function(){\r\n\t\tthis.innerHTML = '';\r\n\t}\r\n\r\n};\r\n\r\n// Fix for IE leak on Element.set('text','')\r\nElement.Properties.text = {\r\n\r\n\tset: function(text) {\r\n\t\tthis.empty().setProperty('text', text);\r\n\t}\r\n};\r\n\r\n/**/\r\n// technique by jdbarlett - http://jdbartlett.com/innershiv/\r\nvar div = document.createElement('div');\r\ndiv.innerHTML = '';\r\nvar supportsHTML5Elements = (div.childNodes.length == 1);\r\nif (!supportsHTML5Elements){\r\n\tvar tags = 'abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video'.split(' '),\r\n\t\tfragment = document.createDocumentFragment(), l = tags.length;\r\n\twhile (l--) fragment.createElement(tags[l]);\r\n}\r\ndiv = null;\r\n/**/\r\n\r\n/**/\r\nvar supportsTableInnerHTML = Function.attempt(function(){\r\n\tvar table = document.createElement('table');\r\n\ttable.innerHTML = '';\r\n\treturn true;\r\n});\r\n\r\n/**/\r\nvar tr = document.createElement('tr'), html = '';\r\ntr.innerHTML = html;\r\nvar supportsTRInnerHTML = (tr.innerHTML == html);\r\ntr = null;\r\n/**/\r\n\r\nif (!supportsTableInnerHTML || !supportsTRInnerHTML || !supportsHTML5Elements){\r\n\r\n\tElement.Properties.html.set = (function(set){\r\n\r\n\t\tvar translations = {\r\n\t\t\ttable: [1, '', '
'],\r\n\t\t\tselect: [1, ''],\r\n\t\t\ttbody: [2, '', '
'],\r\n\t\t\ttr: [3, '', '
']\r\n\t\t};\r\n\r\n\t\ttranslations.thead = translations.tfoot = translations.tbody;\r\n\r\n\t\treturn function(html){\r\n\t\t\tvar wrap = translations[this.get('tag')];\r\n\t\t\tif (!wrap && !supportsHTML5Elements) wrap = [0, '', ''];\r\n\t\t\tif (!wrap) return set.call(this, html);\r\n\r\n\t\t\tvar level = wrap[0], wrapper = document.createElement('div'), target = wrapper;\r\n\t\t\tif (!supportsHTML5Elements) fragment.appendChild(wrapper);\r\n\t\t\twrapper.innerHTML = [wrap[1], html, wrap[2]].flatten().join('');\r\n\t\t\twhile (level--) target = target.firstChild;\r\n\t\t\tthis.empty().adopt(target.childNodes);\r\n\t\t\tif (!supportsHTML5Elements) fragment.removeChild(wrapper);\r\n\t\t\twrapper = null;\r\n\t\t};\r\n\r\n\t})(Element.Properties.html.set);\r\n}\r\n/*
*/\r\n\r\n/**/\r\nvar testForm = document.createElement('form');\r\ntestForm.innerHTML = '';\r\n\r\nif (testForm.firstChild.value != 's') Element.Properties.value = {\r\n\r\n\tset: function(value){\r\n\t\tvar tag = this.get('tag');\r\n\t\tif (tag != 'select') return this.setProperty('value', value);\r\n\t\tvar options = this.getElements('option');\r\n\t\tfor (var i = 0; i < options.length; i++){\r\n\t\t\tvar option = options[i],\r\n\t\t\t\tattr = option.getAttributeNode('value'),\r\n\t\t\t\toptionValue = (attr && attr.specified) ? option.value : option.get('text');\r\n\t\t\tif (optionValue == value) return option.selected = true;\r\n\t\t}\r\n\t},\r\n\r\n\tget: function(){\r\n\t\tvar option = this, tag = option.get('tag');\r\n\r\n\t\tif (tag != 'select' && tag != 'option') return this.getProperty('value');\r\n\r\n\t\tif (tag == 'select' && !(option = option.getSelected()[0])) return '';\r\n\r\n\t\tvar attr = option.getAttributeNode('value');\r\n\t\treturn (attr && attr.specified) ? option.value : option.get('text');\r\n\t}\r\n\r\n};\r\ntestForm = null;\r\n/**/\r\n\r\n/**/\r\nif (document.createElement('div').getAttributeNode('id')) Element.Properties.id = {\r\n\tset: function(id){\r\n\t\tthis.id = this.getAttributeNode('id').value = id;\r\n\t},\r\n\tget: function(){\r\n\t\treturn this.id || null;\r\n\t},\r\n\terase: function(){\r\n\t\tthis.id = this.getAttributeNode('id').value = '';\r\n\t}\r\n};\r\n/**/\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Element.Style\r\n\r\ndescription: Contains methods for interacting with the styles of Elements in a fashionable way.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Element\r\n\r\nprovides: Element.Style\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar html = document.html;\r\n\r\n//\r\n// Check for oldIE, which does not remove styles when they're set to null\r\nvar el = document.createElement('div');\r\nel.style.color = 'red';\r\nel.style.color = null;\r\nvar doesNotRemoveStyles = el.style.color == 'red';\r\nel = null;\r\n//\r\n\r\nElement.Properties.styles = {set: function(styles){\r\n\tthis.setStyles(styles);\r\n}};\r\n\r\nvar hasOpacity = (html.style.opacity != null),\r\n\thasFilter = (html.style.filter != null),\r\n\treAlpha = /alpha\\(opacity=([\\d.]+)\\)/i;\r\n\r\nvar setVisibility = function(element, opacity){\r\n\telement.store('$opacity', opacity);\r\n\telement.style.visibility = opacity > 0 || opacity == null ? 'visible' : 'hidden';\r\n};\r\n\r\nvar setOpacity = (hasOpacity ? function(element, opacity){\r\n\telement.style.opacity = opacity;\r\n} : (hasFilter ? function(element, opacity){\r\n\tvar style = element.style;\r\n\tif (!element.currentStyle || !element.currentStyle.hasLayout) style.zoom = 1;\r\n\tif (opacity == null || opacity == 1) opacity = '';\r\n\telse opacity = 'alpha(opacity=' + (opacity * 100).limit(0, 100).round() + ')';\r\n\tvar filter = style.filter || element.getComputedStyle('filter') || '';\r\n\tstyle.filter = reAlpha.test(filter) ? filter.replace(reAlpha, opacity) : filter + opacity;\r\n\tif (!style.filter) style.removeAttribute('filter');\r\n} : setVisibility));\r\n\r\nvar getOpacity = (hasOpacity ? function(element){\r\n\tvar opacity = element.style.opacity || element.getComputedStyle('opacity');\r\n\treturn (opacity == '') ? 1 : opacity.toFloat();\r\n} : (hasFilter ? function(element){\r\n\tvar filter = (element.style.filter || element.getComputedStyle('filter')),\r\n\t\topacity;\r\n\tif (filter) opacity = filter.match(reAlpha);\r\n\treturn (opacity == null || filter == null) ? 1 : (opacity[1] / 100);\r\n} : function(element){\r\n\tvar opacity = element.retrieve('$opacity');\r\n\tif (opacity == null) opacity = (element.style.visibility == 'hidden' ? 0 : 1);\r\n\treturn opacity;\r\n}));\r\n\r\nvar floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat';\r\n\r\nElement.implement({\r\n\r\n\tgetComputedStyle: function(property){\r\n\t\tif (this.currentStyle) return this.currentStyle[property.camelCase()];\r\n\t\tvar defaultView = Element.getDocument(this).defaultView,\r\n\t\t\tcomputed = defaultView ? defaultView.getComputedStyle(this, null) : null;\r\n\t\treturn (computed) ? computed.getPropertyValue((property == floatName) ? 'float' : property.hyphenate()) : null;\r\n\t},\r\n\r\n\tsetStyle: function(property, value){\r\n\t\tif (property == 'opacity'){\r\n\t\t\tif (value != null) value = parseFloat(value);\r\n\t\t\tsetOpacity(this, value);\r\n\t\t\treturn this;\r\n\t\t}\r\n\t\tproperty = (property == 'float' ? floatName : property).camelCase();\r\n\t\tif (typeOf(value) != 'string'){\r\n\t\t\tvar map = (Element.Styles[property] || '@').split(' ');\r\n\t\t\tvalue = Array.from(value).map(function(val, i){\r\n\t\t\t\tif (!map[i]) return '';\r\n\t\t\t\treturn (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;\r\n\t\t\t}).join(' ');\r\n\t\t} else if (value == String(Number(value))){\r\n\t\t\tvalue = Math.round(value);\r\n\t\t}\r\n\t\tthis.style[property] = value;\r\n\t\t//\r\n\t\tif ((value == '' || value == null) && doesNotRemoveStyles && this.style.removeAttribute){\r\n\t\t\tthis.style.removeAttribute(property);\r\n\t\t}\r\n\t\t//\r\n\t\treturn this;\r\n\t},\r\n\r\n\tgetStyle: function(property){\r\n\t\tif (property == 'opacity') return getOpacity(this);\r\n\t\tproperty = (property == 'float' ? floatName : property).camelCase();\r\n\t\tvar result = this.style[property];\r\n\t\tif (!result || property == 'zIndex'){\r\n\t\t\tresult = [];\r\n\t\t\tfor (var style in Element.ShortStyles){\r\n\t\t\t\tif (property != style) continue;\r\n\t\t\t\tfor (var s in Element.ShortStyles[style]) result.push(this.getStyle(s));\r\n\t\t\t\treturn result.join(' ');\r\n\t\t\t}\r\n\t\t\tresult = this.getComputedStyle(property);\r\n\t\t}\r\n\t\tif (result){\r\n\t\t\tresult = String(result);\r\n\t\t\tvar color = result.match(/rgba?\\([\\d\\s,]+\\)/);\r\n\t\t\tif (color) result = result.replace(color[0], color[0].rgbToHex());\r\n\t\t}\r\n\t\tif (Browser.opera || Browser.ie){\r\n\t\t\tif ((/^(height|width)$/).test(property) && !(/px$/.test(result))){\r\n\t\t\t\tvar values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;\r\n\t\t\t\tvalues.each(function(value){\r\n\t\t\t\t\tsize += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();\r\n\t\t\t\t}, this);\r\n\t\t\t\treturn this['offset' + property.capitalize()] - size + 'px';\r\n\t\t\t}\r\n\t\t\tif (Browser.ie && (/^border(.+)Width|margin|padding/).test(property) && isNaN(parseFloat(result))){\r\n\t\t\t\treturn '0px';\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result;\r\n\t},\r\n\r\n\tsetStyles: function(styles){\r\n\t\tfor (var style in styles) this.setStyle(style, styles[style]);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tgetStyles: function(){\r\n\t\tvar result = {};\r\n\t\tArray.flatten(arguments).each(function(key){\r\n\t\t\tresult[key] = this.getStyle(key);\r\n\t\t}, this);\r\n\t\treturn result;\r\n\t}\r\n\r\n});\r\n\r\nElement.Styles = {\r\n\tleft: '@px', top: '@px', bottom: '@px', right: '@px',\r\n\twidth: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',\r\n\tbackgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',\r\n\tfontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',\r\n\tmargin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',\r\n\tborderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',\r\n\tzIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'\r\n};\r\n\r\n//<1.3compat>\r\n\r\nElement.implement({\r\n\r\n\tsetOpacity: function(value){\r\n\t\tsetOpacity(this, value);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tgetOpacity: function(){\r\n\t\treturn getOpacity(this);\r\n\t}\r\n\r\n});\r\n\r\nElement.Properties.opacity = {\r\n\r\n\tset: function(opacity){\r\n\t\tsetOpacity(this, opacity);\r\n\t\tsetVisibility(this, opacity);\r\n\t},\r\n\r\n\tget: function(){\r\n\t\treturn getOpacity(this);\r\n\t}\r\n\r\n};\r\n\r\n//\r\n\r\n//<1.2compat>\r\n\r\nElement.Styles = new Hash(Element.Styles);\r\n\r\n//\r\n\r\nElement.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};\r\n\r\n['Top', 'Right', 'Bottom', 'Left'].each(function(direction){\r\n\tvar Short = Element.ShortStyles;\r\n\tvar All = Element.Styles;\r\n\t['margin', 'padding'].each(function(style){\r\n\t\tvar sd = style + direction;\r\n\t\tShort[style][sd] = All[sd] = '@px';\r\n\t});\r\n\tvar bd = 'border' + direction;\r\n\tShort.border[bd] = All[bd] = '@px @ rgb(@, @, @)';\r\n\tvar bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';\r\n\tShort[bd] = {};\r\n\tShort.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';\r\n\tShort.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';\r\n\tShort.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';\r\n});\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Element.Event\r\n\r\ndescription: Contains Element methods for dealing with events. This file also includes mouseenter and mouseleave custom Element Events, if necessary.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Element, Event]\r\n\r\nprovides: Element.Event\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nElement.Properties.events = {set: function(events){\r\n\tthis.addEvents(events);\r\n}};\r\n\r\n[Element, Window, Document].invoke('implement', {\r\n\r\n\taddEvent: function(type, fn){\r\n\t\tvar events = this.retrieve('events', {});\r\n\t\tif (!events[type]) events[type] = {keys: [], values: []};\r\n\t\tif (events[type].keys.contains(fn)) return this;\r\n\t\tevents[type].keys.push(fn);\r\n\t\tvar realType = type,\r\n\t\t\tcustom = Element.Events[type],\r\n\t\t\tcondition = fn,\r\n\t\t\tself = this;\r\n\t\tif (custom){\r\n\t\t\tif (custom.onAdd) custom.onAdd.call(this, fn, type);\r\n\t\t\tif (custom.condition){\r\n\t\t\t\tcondition = function(event){\r\n\t\t\t\t\tif (custom.condition.call(this, event, type)) return fn.call(this, event);\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\tif (custom.base) realType = Function.from(custom.base).call(this, type);\r\n\t\t}\r\n\t\tvar defn = function(){\r\n\t\t\treturn fn.call(self);\r\n\t\t};\r\n\t\tvar nativeEvent = Element.NativeEvents[realType];\r\n\t\tif (nativeEvent){\r\n\t\t\tif (nativeEvent == 2){\r\n\t\t\t\tdefn = function(event){\r\n\t\t\t\t\tevent = new DOMEvent(event, self.getWindow());\r\n\t\t\t\t\tif (condition.call(self, event) === false) event.stop();\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\tthis.addListener(realType, defn, arguments[2]);\r\n\t\t}\r\n\t\tevents[type].values.push(defn);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tremoveEvent: function(type, fn){\r\n\t\tvar events = this.retrieve('events');\r\n\t\tif (!events || !events[type]) return this;\r\n\t\tvar list = events[type];\r\n\t\tvar index = list.keys.indexOf(fn);\r\n\t\tif (index == -1) return this;\r\n\t\tvar value = list.values[index];\r\n\t\tdelete list.keys[index];\r\n\t\tdelete list.values[index];\r\n\t\tvar custom = Element.Events[type];\r\n\t\tif (custom){\r\n\t\t\tif (custom.onRemove) custom.onRemove.call(this, fn, type);\r\n\t\t\tif (custom.base) type = Function.from(custom.base).call(this, type);\r\n\t\t}\r\n\t\treturn (Element.NativeEvents[type]) ? this.removeListener(type, value, arguments[2]) : this;\r\n\t},\r\n\r\n\taddEvents: function(events){\r\n\t\tfor (var event in events) this.addEvent(event, events[event]);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tremoveEvents: function(events){\r\n\t\tvar type;\r\n\t\tif (typeOf(events) == 'object'){\r\n\t\t\tfor (type in events) this.removeEvent(type, events[type]);\r\n\t\t\treturn this;\r\n\t\t}\r\n\t\tvar attached = this.retrieve('events');\r\n\t\tif (!attached) return this;\r\n\t\tif (!events){\r\n\t\t\tfor (type in attached) this.removeEvents(type);\r\n\t\t\tthis.eliminate('events');\r\n\t\t} else if (attached[events]){\r\n\t\t\tattached[events].keys.each(function(fn){\r\n\t\t\t\tthis.removeEvent(events, fn);\r\n\t\t\t}, this);\r\n\t\t\tdelete attached[events];\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\tfireEvent: function(type, args, delay){\r\n\t\tvar events = this.retrieve('events');\r\n\t\tif (!events || !events[type]) return this;\r\n\t\targs = Array.from(args);\r\n\r\n\t\tevents[type].keys.each(function(fn){\r\n\t\t\tif (delay) fn.delay(delay, this, args);\r\n\t\t\telse fn.apply(this, args);\r\n\t\t}, this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tcloneEvents: function(from, type){\r\n\t\tfrom = document.id(from);\r\n\t\tvar events = from.retrieve('events');\r\n\t\tif (!events) return this;\r\n\t\tif (!type){\r\n\t\t\tfor (var eventType in events) this.cloneEvents(from, eventType);\r\n\t\t} else if (events[type]){\r\n\t\t\tevents[type].keys.each(function(fn){\r\n\t\t\t\tthis.addEvent(type, fn);\r\n\t\t\t}, this);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\nElement.NativeEvents = {\r\n\tclick: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons\r\n\tmousewheel: 2, DOMMouseScroll: 2, //mouse wheel\r\n\tmouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement\r\n\tkeydown: 2, keypress: 2, keyup: 2, //keyboard\r\n\torientationchange: 2, // mobile\r\n\ttouchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch\r\n\tgesturestart: 2, gesturechange: 2, gestureend: 2, // gesture\r\n\tfocus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, paste: 2, input: 2, //form elements\r\n\tload: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window\r\n\terror: 1, abort: 1, scroll: 1 //misc\r\n};\r\n\r\nElement.Events = {mousewheel: {\r\n\tbase: (Browser.firefox) ? 'DOMMouseScroll' : 'mousewheel'\r\n}};\r\n\r\nif ('onmouseenter' in document.documentElement){\r\n\tElement.NativeEvents.mouseenter = Element.NativeEvents.mouseleave = 2;\r\n} else {\r\n\tvar check = function(event){\r\n\t\tvar related = event.relatedTarget;\r\n\t\tif (related == null) return true;\r\n\t\tif (!related) return false;\r\n\t\treturn (related != this && related.prefix != 'xul' && typeOf(this) != 'document' && !this.contains(related));\r\n\t};\r\n\r\n\tElement.Events.mouseenter = {\r\n\t\tbase: 'mouseover',\r\n\t\tcondition: check\r\n\t};\r\n\r\n\tElement.Events.mouseleave = {\r\n\t\tbase: 'mouseout',\r\n\t\tcondition: check\r\n\t};\r\n}\r\n\r\n/**/\r\nif (!window.addEventListener){\r\n\tElement.NativeEvents.propertychange = 2;\r\n\tElement.Events.change = {\r\n\t\tbase: function(){\r\n\t\t\tvar type = this.type;\r\n\t\t\treturn (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbox')) ? 'propertychange' : 'change'\r\n\t\t},\r\n\t\tcondition: function(event){\r\n\t\t\treturn this.type != 'radio' || (event.event.propertyName == 'checked' && this.checked);\r\n\t\t}\r\n\t}\r\n}\r\n/**/\r\n\r\n//<1.2compat>\r\n\r\nElement.Events = new Hash(Element.Events);\r\n\r\n//\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Element.Delegation\r\n\r\ndescription: Extends the Element native object to include the delegate method for more efficient event management.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Element.Event]\r\n\r\nprovides: [Element.Delegation]\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar eventListenerSupport = !!window.addEventListener;\r\n\r\nElement.NativeEvents.focusin = Element.NativeEvents.focusout = 2;\r\n\r\nvar bubbleUp = function(self, match, fn, event, target){\r\n\twhile (target && target != self){\r\n\t\tif (match(target, event)) return fn.call(target, event, target);\r\n\t\ttarget = document.id(target.parentNode);\r\n\t}\r\n};\r\n\r\nvar map = {\r\n\tmouseenter: {\r\n\t\tbase: 'mouseover'\r\n\t},\r\n\tmouseleave: {\r\n\t\tbase: 'mouseout'\r\n\t},\r\n\tfocus: {\r\n\t\tbase: 'focus' + (eventListenerSupport ? '' : 'in'),\r\n\t\tcapture: true\r\n\t},\r\n\tblur: {\r\n\t\tbase: eventListenerSupport ? 'blur' : 'focusout',\r\n\t\tcapture: true\r\n\t}\r\n};\r\n\r\n/**/\r\nvar _key = '$delegation:';\r\nvar formObserver = function(type){\r\n\r\n\treturn {\r\n\r\n\t\tbase: 'focusin',\r\n\r\n\t\tremove: function(self, uid){\r\n\t\t\tvar list = self.retrieve(_key + type + 'listeners', {})[uid];\r\n\t\t\tif (list && list.forms) for (var i = list.forms.length; i--;){\r\n\t\t\t\tlist.forms[i].removeEvent(type, list.fns[i]);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tlisten: function(self, match, fn, event, target, uid){\r\n\t\t\tvar form = (target.get('tag') == 'form') ? target : event.target.getParent('form');\r\n\t\t\tif (!form) return;\r\n\r\n\t\t\tvar listeners = self.retrieve(_key + type + 'listeners', {}),\r\n\t\t\t\tlistener = listeners[uid] || {forms: [], fns: []},\r\n\t\t\t\tforms = listener.forms, fns = listener.fns;\r\n\r\n\t\t\tif (forms.indexOf(form) != -1) return;\r\n\t\t\tforms.push(form);\r\n\r\n\t\t\tvar _fn = function(event){\r\n\t\t\t\tbubbleUp(self, match, fn, event, target);\r\n\t\t\t};\r\n\t\t\tform.addEvent(type, _fn);\r\n\t\t\tfns.push(_fn);\r\n\r\n\t\t\tlisteners[uid] = listener;\r\n\t\t\tself.store(_key + type + 'listeners', listeners);\r\n\t\t}\r\n\t};\r\n};\r\n\r\nvar inputObserver = function(type){\r\n\treturn {\r\n\t\tbase: 'focusin',\r\n\t\tlisten: function(self, match, fn, event, target){\r\n\t\t\tvar events = {blur: function(){\r\n\t\t\t\tthis.removeEvents(events);\r\n\t\t\t}};\r\n\t\t\tevents[type] = function(event){\r\n\t\t\t\tbubbleUp(self, match, fn, event, target);\r\n\t\t\t};\r\n\t\t\tevent.target.addEvents(events);\r\n\t\t}\r\n\t};\r\n};\r\n\r\nif (!eventListenerSupport) Object.append(map, {\r\n\tsubmit: formObserver('submit'),\r\n\treset: formObserver('reset'),\r\n\tchange: inputObserver('change'),\r\n\tselect: inputObserver('select')\r\n});\r\n/**/\r\n\r\nvar proto = Element.prototype,\r\n\taddEvent = proto.addEvent,\r\n\tremoveEvent = proto.removeEvent;\r\n\r\nvar relay = function(old, method){\r\n\treturn function(type, fn, useCapture){\r\n\t\tif (type.indexOf(':relay') == -1) return old.call(this, type, fn, useCapture);\r\n\t\tvar parsed = Slick.parse(type).expressions[0][0];\r\n\t\tif (parsed.pseudos[0].key != 'relay') return old.call(this, type, fn, useCapture);\r\n\t\tvar newType = parsed.tag;\r\n\t\tparsed.pseudos.slice(1).each(function(pseudo){\r\n\t\t\tnewType += ':' + pseudo.key + (pseudo.value ? '(' + pseudo.value + ')' : '');\r\n\t\t});\r\n\t\told.call(this, type, fn);\r\n\t\treturn method.call(this, newType, parsed.pseudos[0].value, fn);\r\n\t};\r\n};\r\n\r\nvar delegation = {\r\n\r\n\taddEvent: function(type, match, fn){\r\n\t\tvar storage = this.retrieve('$delegates', {}), stored = storage[type];\r\n\t\tif (stored) for (var _uid in stored){\r\n\t\t\tif (stored[_uid].fn == fn && stored[_uid].match == match) return this;\r\n\t\t}\r\n\r\n\t\tvar _type = type, _match = match, _fn = fn, _map = map[type] || {};\r\n\t\ttype = _map.base || _type;\r\n\r\n\t\tmatch = function(target){\r\n\t\t\treturn Slick.match(target, _match);\r\n\t\t};\r\n\r\n\t\tvar elementEvent = Element.Events[_type];\r\n\t\tif (elementEvent && elementEvent.condition){\r\n\t\t\tvar __match = match, condition = elementEvent.condition;\r\n\t\t\tmatch = function(target, event){\r\n\t\t\t\treturn __match(target, event) && condition.call(target, event, type);\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tvar self = this, uid = String.uniqueID();\r\n\t\tvar delegator = _map.listen ? function(event, target){\r\n\t\t\tif (!target && event && event.target) target = event.target;\r\n\t\t\tif (target) _map.listen(self, match, fn, event, target, uid);\r\n\t\t} : function(event, target){\r\n\t\t\tif (!target && event && event.target) target = event.target;\r\n\t\t\tif (target) bubbleUp(self, match, fn, event, target);\r\n\t\t};\r\n\r\n\t\tif (!stored) stored = {};\r\n\t\tstored[uid] = {\r\n\t\t\tmatch: _match,\r\n\t\t\tfn: _fn,\r\n\t\t\tdelegator: delegator\r\n\t\t};\r\n\t\tstorage[_type] = stored;\r\n\t\treturn addEvent.call(this, type, delegator, _map.capture);\r\n\t},\r\n\r\n\tremoveEvent: function(type, match, fn, _uid){\r\n\t\tvar storage = this.retrieve('$delegates', {}), stored = storage[type];\r\n\t\tif (!stored) return this;\r\n\r\n\t\tif (_uid){\r\n\t\t\tvar _type = type, delegator = stored[_uid].delegator, _map = map[type] || {};\r\n\t\t\ttype = _map.base || _type;\r\n\t\t\tif (_map.remove) _map.remove(this, _uid);\r\n\t\t\tdelete stored[_uid];\r\n\t\t\tstorage[_type] = stored;\r\n\t\t\treturn removeEvent.call(this, type, delegator);\r\n\t\t}\r\n\r\n\t\tvar __uid, s;\r\n\t\tif (fn) for (__uid in stored){\r\n\t\t\ts = stored[__uid];\r\n\t\t\tif (s.match == match && s.fn == fn) return delegation.removeEvent.call(this, type, match, fn, __uid);\r\n\t\t} else for (__uid in stored){\r\n\t\t\ts = stored[__uid];\r\n\t\t\tif (s.match == match) delegation.removeEvent.call(this, type, match, s.fn, __uid);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\r\n};\r\n\r\n[Element, Window, Document].invoke('implement', {\r\n\taddEvent: relay(addEvent, delegation.addEvent),\r\n\tremoveEvent: relay(removeEvent, delegation.removeEvent)\r\n});\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Element.Dimensions\r\n\r\ndescription: Contains methods to work with size, scroll, or positioning of Elements and the window object.\r\n\r\nlicense: MIT-style license.\r\n\r\ncredits:\r\n - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html).\r\n - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html).\r\n\r\nrequires: [Element, Element.Style]\r\n\r\nprovides: [Element.Dimensions]\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar element = document.createElement('div'),\r\n\tchild = document.createElement('div');\r\nelement.style.height = '0';\r\nelement.appendChild(child);\r\nvar brokenOffsetParent = (child.offsetParent === element);\r\nelement = child = null;\r\n\r\nvar isOffset = function(el){\r\n\treturn styleString(el, 'position') != 'static' || isBody(el);\r\n};\r\n\r\nvar isOffsetStatic = function(el){\r\n\treturn isOffset(el) || (/^(?:table|td|th)$/i).test(el.tagName);\r\n};\r\n\r\nElement.implement({\r\n\r\n\tscrollTo: function(x, y){\r\n\t\tif (isBody(this)){\r\n\t\t\tthis.getWindow().scrollTo(x, y);\r\n\t\t} else {\r\n\t\t\tthis.scrollLeft = x;\r\n\t\t\tthis.scrollTop = y;\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\tgetSize: function(){\r\n\t\tif (isBody(this)) return this.getWindow().getSize();\r\n\t\treturn {x: this.offsetWidth, y: this.offsetHeight};\r\n\t},\r\n\r\n\tgetScrollSize: function(){\r\n\t\tif (isBody(this)) return this.getWindow().getScrollSize();\r\n\t\treturn {x: this.scrollWidth, y: this.scrollHeight};\r\n\t},\r\n\r\n\tgetScroll: function(){\r\n\t\tif (isBody(this)) return this.getWindow().getScroll();\r\n\t\treturn {x: this.scrollLeft, y: this.scrollTop};\r\n\t},\r\n\r\n\tgetScrolls: function(){\r\n\t\tvar element = this.parentNode, position = {x: 0, y: 0};\r\n\t\twhile (element && !isBody(element)){\r\n\t\t\tposition.x += element.scrollLeft;\r\n\t\t\tposition.y += element.scrollTop;\r\n\t\t\telement = element.parentNode;\r\n\t\t}\r\n\t\treturn position;\r\n\t},\r\n\r\n\tgetOffsetParent: brokenOffsetParent ? function(){\r\n\t\tvar element = this;\r\n\t\tif (isBody(element) || styleString(element, 'position') == 'fixed') return null;\r\n\r\n\t\tvar isOffsetCheck = (styleString(element, 'position') == 'static') ? isOffsetStatic : isOffset;\r\n\t\twhile ((element = element.parentNode)){\r\n\t\t\tif (isOffsetCheck(element)) return element;\r\n\t\t}\r\n\t\treturn null;\r\n\t} : function(){\r\n\t\tvar element = this;\r\n\t\tif (isBody(element) || styleString(element, 'position') == 'fixed') return null;\r\n\r\n\t\ttry {\r\n\t\t\treturn element.offsetParent;\r\n\t\t} catch(e) {}\r\n\t\treturn null;\r\n\t},\r\n\r\n\tgetOffsets: function(){\r\n\t\tif (this.getBoundingClientRect && !Browser.Platform.ios){\r\n\t\t\tvar bound = this.getBoundingClientRect(),\r\n\t\t\t\thtml = document.id(this.getDocument().documentElement),\r\n\t\t\t\thtmlScroll = html.getScroll(),\r\n\t\t\t\telemScrolls = this.getScrolls(),\r\n\t\t\t\tisFixed = (styleString(this, 'position') == 'fixed');\r\n\r\n\t\t\treturn {\r\n\t\t\t\tx: bound.left.toInt() + elemScrolls.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft,\r\n\t\t\t\ty: bound.top.toInt() + elemScrolls.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tvar element = this, position = {x: 0, y: 0};\r\n\t\tif (isBody(this)) return position;\r\n\r\n\t\twhile (element && !isBody(element)){\r\n\t\t\tposition.x += element.offsetLeft;\r\n\t\t\tposition.y += element.offsetTop;\r\n\r\n\t\t\tif (Browser.firefox){\r\n\t\t\t\tif (!borderBox(element)){\r\n\t\t\t\t\tposition.x += leftBorder(element);\r\n\t\t\t\t\tposition.y += topBorder(element);\r\n\t\t\t\t}\r\n\t\t\t\tvar parent = element.parentNode;\r\n\t\t\t\tif (parent && styleString(parent, 'overflow') != 'visible'){\r\n\t\t\t\t\tposition.x += leftBorder(parent);\r\n\t\t\t\t\tposition.y += topBorder(parent);\r\n\t\t\t\t}\r\n\t\t\t} else if (element != this && Browser.safari){\r\n\t\t\t\tposition.x += leftBorder(element);\r\n\t\t\t\tposition.y += topBorder(element);\r\n\t\t\t}\r\n\r\n\t\t\telement = element.offsetParent;\r\n\t\t}\r\n\t\tif (Browser.firefox && !borderBox(this)){\r\n\t\t\tposition.x -= leftBorder(this);\r\n\t\t\tposition.y -= topBorder(this);\r\n\t\t}\r\n\t\treturn position;\r\n\t},\r\n\r\n\tgetPosition: function(relative){\r\n\t\tvar offset = this.getOffsets(),\r\n\t\t\tscroll = this.getScrolls();\r\n\t\tvar position = {\r\n\t\t\tx: offset.x - scroll.x,\r\n\t\t\ty: offset.y - scroll.y\r\n\t\t};\r\n\r\n\t\tif (relative && (relative = document.id(relative))){\r\n\t\t\tvar relativePosition = relative.getPosition();\r\n\t\t\treturn {x: position.x - relativePosition.x - leftBorder(relative), y: position.y - relativePosition.y - topBorder(relative)};\r\n\t\t}\r\n\t\treturn position;\r\n\t},\r\n\r\n\tgetCoordinates: function(element){\r\n\t\tif (isBody(this)) return this.getWindow().getCoordinates();\r\n\t\tvar position = this.getPosition(element),\r\n\t\t\tsize = this.getSize();\r\n\t\tvar obj = {\r\n\t\t\tleft: position.x,\r\n\t\t\ttop: position.y,\r\n\t\t\twidth: size.x,\r\n\t\t\theight: size.y\r\n\t\t};\r\n\t\tobj.right = obj.left + obj.width;\r\n\t\tobj.bottom = obj.top + obj.height;\r\n\t\treturn obj;\r\n\t},\r\n\r\n\tcomputePosition: function(obj){\r\n\t\treturn {\r\n\t\t\tleft: obj.x - styleNumber(this, 'margin-left'),\r\n\t\t\ttop: obj.y - styleNumber(this, 'margin-top')\r\n\t\t};\r\n\t},\r\n\r\n\tsetPosition: function(obj){\r\n\t\treturn this.setStyles(this.computePosition(obj));\r\n\t}\r\n\r\n});\r\n\r\n\r\n[Document, Window].invoke('implement', {\r\n\r\n\tgetSize: function(){\r\n\t\tvar doc = getCompatElement(this);\r\n\t\treturn {x: doc.clientWidth, y: doc.clientHeight};\r\n\t},\r\n\r\n\tgetScroll: function(){\r\n\t\tvar win = this.getWindow(), doc = getCompatElement(this);\r\n\t\treturn {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};\r\n\t},\r\n\r\n\tgetScrollSize: function(){\r\n\t\tvar doc = getCompatElement(this),\r\n\t\t\tmin = this.getSize(),\r\n\t\t\tbody = this.getDocument().body;\r\n\r\n\t\treturn {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(doc.scrollHeight, body.scrollHeight, min.y)};\r\n\t},\r\n\r\n\tgetPosition: function(){\r\n\t\treturn {x: 0, y: 0};\r\n\t},\r\n\r\n\tgetCoordinates: function(){\r\n\t\tvar size = this.getSize();\r\n\t\treturn {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};\r\n\t}\r\n\r\n});\r\n\r\n// private methods\r\n\r\nvar styleString = Element.getComputedStyle;\r\n\r\nfunction styleNumber(element, style){\r\n\treturn styleString(element, style).toInt() || 0;\r\n}\r\n\r\nfunction borderBox(element){\r\n\treturn styleString(element, '-moz-box-sizing') == 'border-box';\r\n}\r\n\r\nfunction topBorder(element){\r\n\treturn styleNumber(element, 'border-top-width');\r\n}\r\n\r\nfunction leftBorder(element){\r\n\treturn styleNumber(element, 'border-left-width');\r\n}\r\n\r\nfunction isBody(element){\r\n\treturn (/^(?:body|html)$/i).test(element.tagName);\r\n}\r\n\r\nfunction getCompatElement(element){\r\n\tvar doc = element.getDocument();\r\n\treturn (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;\r\n}\r\n\r\n})();\r\n\r\n//aliases\r\nElement.alias({position: 'setPosition'}); //compatability\r\n\r\n[Window, Document, Element].invoke('implement', {\r\n\r\n\tgetHeight: function(includeMargin){\r\n var height = this.getSize().y;\r\n\r\n if (includeMargin) {\r\n height += this.getStyle(\"margin-top\").toInt() + this.getStyle(\"margin-bottom\").toInt();\r\n }\r\n\r\n return height;\r\n\t},\r\n\r\n\tgetWidth: function(includeMargin) {\r\n var width = this.getSize().x;\r\n\r\n if (includeMargin) {\r\n width += this.getStyle(\"margin-left\").toInt() + this.getStyle(\"margin-right\").toInt();\r\n }\r\n\r\n return width;\r\n\t},\r\n\r\n\tgetScrollTop: function(){\r\n\t\treturn this.getScroll().y;\r\n\t},\r\n\r\n\tgetScrollLeft: function(){\r\n\t\treturn this.getScroll().x;\r\n\t},\r\n\r\n\tgetScrollHeight: function(){\r\n\t\treturn this.getScrollSize().y;\r\n\t},\r\n\r\n\tgetScrollWidth: function(){\r\n\t\treturn this.getScrollSize().x;\r\n\t},\r\n\r\n\tgetTop: function(){\r\n\t\treturn this.getPosition().y;\r\n\t},\r\n\r\n\tgetLeft: function(){\r\n\t\treturn this.getPosition().x;\r\n\t}\r\n\r\n});\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Fx\r\n\r\ndescription: Contains the basic animation logic to be extended by all other Fx Classes.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Chain, Events, Options]\r\n\r\nprovides: Fx\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar Fx = this.Fx = new Class({\r\n\r\n\tImplements: [Chain, Events, Options],\r\n\r\n\toptions: {\r\n\t\t/*\r\n\t\tonStart: nil,\r\n\t\tonCancel: nil,\r\n\t\tonComplete: nil,\r\n\t\t*/\r\n\t\tfps: 60,\r\n\t\tunit: false,\r\n\t\tduration: 500,\r\n\t\tframes: null,\r\n\t\tframeSkip: true,\r\n\t\tlink: 'ignore'\r\n\t},\r\n\r\n\tinitialize: function(options){\r\n\t\tthis.subject = this.subject || this;\r\n\t\tthis.setOptions(options);\r\n\t},\r\n\r\n\tgetTransition: function(){\r\n\t\treturn function(p){\r\n\t\t\treturn -(Math.cos(Math.PI * p) - 1) / 2;\r\n\t\t};\r\n\t},\r\n\r\n\tstep: function(now){\r\n\t\tif (this.options.frameSkip){\r\n\t\t\tvar diff = (this.time != null) ? (now - this.time) : 0, frames = diff / this.frameInterval;\r\n\t\t\tthis.time = now;\r\n\t\t\tthis.frame += frames;\r\n\t\t} else {\r\n\t\t\tthis.frame++;\r\n\t\t}\r\n\r\n\t\tif (this.frame < this.frames){\r\n\t\t\tvar delta = this.transition(this.frame / this.frames);\r\n\t\t\tthis.set(this.compute(this.from, this.to, delta));\r\n\t\t} else {\r\n\t\t\tthis.frame = this.frames;\r\n\t\t\tthis.set(this.compute(this.from, this.to, 1));\r\n\t\t\tthis.stop();\r\n\t\t}\r\n\t},\r\n\r\n\tset: function(now){\r\n\t\treturn now;\r\n\t},\r\n\r\n\tcompute: function(from, to, delta){\r\n\t\treturn Fx.compute(from, to, delta);\r\n\t},\r\n\r\n\tcheck: function(){\r\n\t\tif (!this.isRunning()) return true;\r\n\t\tswitch (this.options.link){\r\n\t\t\tcase 'cancel': this.cancel(); return true;\r\n\t\t\tcase 'chain': this.chain(this.caller.pass(arguments, this)); return false;\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\r\n\tstart: function(from, to){\r\n\t\tif (!this.check(from, to)) return this;\r\n\t\tthis.from = from;\r\n\t\tthis.to = to;\r\n\t\tthis.frame = (this.options.frameSkip) ? 0 : -1;\r\n\t\tthis.time = null;\r\n\t\tthis.transition = this.getTransition();\r\n\t\tvar frames = this.options.frames, fps = this.options.fps, duration = this.options.duration;\r\n\t\tthis.duration = Fx.Durations[duration] || duration.toInt();\r\n\t\tthis.frameInterval = 1000 / fps;\r\n\t\tthis.frames = frames || Math.round(this.duration / this.frameInterval);\r\n\t\tthis.fireEvent('start', this.subject);\r\n\t\tpushInstance.call(this, fps);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tstop: function(){\r\n\t\tif (this.isRunning()){\r\n\t\t\tthis.time = null;\r\n\t\t\tpullInstance.call(this, this.options.fps);\r\n\t\t\tif (this.frames == this.frame){\r\n\t\t\t\tthis.fireEvent('complete', this.subject);\r\n\t\t\t\tif (!this.callChain()) this.fireEvent('chainComplete', this.subject);\r\n\t\t\t} else {\r\n\t\t\t\tthis.fireEvent('stop', this.subject);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\tcancel: function(){\r\n\t\tif (this.isRunning()){\r\n\t\t\tthis.time = null;\r\n\t\t\tpullInstance.call(this, this.options.fps);\r\n\t\t\tthis.frame = this.frames;\r\n\t\t\tthis.fireEvent('cancel', this.subject).clearChain();\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\tpause: function(){\r\n\t\tif (this.isRunning()){\r\n\t\t\tthis.time = null;\r\n\t\t\tpullInstance.call(this, this.options.fps);\r\n\t\t}\r\n\t\treturn this;\r\n\t},\r\n\r\n\tresume: function(){\r\n\t\tif ((this.frame < this.frames) && !this.isRunning()) pushInstance.call(this, this.options.fps);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tisRunning: function(){\r\n\t\tvar list = instances[this.options.fps];\r\n\t\treturn list && list.contains(this);\r\n\t}\r\n\r\n});\r\n\r\nFx.compute = function(from, to, delta){\r\n\treturn (to - from) * delta + from;\r\n};\r\n\r\nFx.Durations = {'short': 250, 'normal': 500, 'long': 1000};\r\n\r\n// global timers\r\n\r\nvar instances = {}, timers = {};\r\n\r\nvar loop = function(){\r\n\tvar now = Date.now();\r\n\tfor (var i = this.length; i--;){\r\n\t\tvar instance = this[i];\r\n\t\tif (instance) instance.step(now);\r\n\t}\r\n};\r\n\r\nvar pushInstance = function(fps){\r\n\tvar list = instances[fps] || (instances[fps] = []);\r\n\tlist.push(this);\r\n\tif (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list);\r\n};\r\n\r\nvar pullInstance = function(fps){\r\n\tvar list = instances[fps];\r\n\tif (list){\r\n\t\tlist.erase(this);\r\n\t\tif (!list.length && timers[fps]){\r\n\t\t\tdelete instances[fps];\r\n\t\t\ttimers[fps] = clearInterval(timers[fps]);\r\n\t\t}\r\n\t}\r\n};\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Fx.CSS\r\n\r\ndescription: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Fx, Element.Style]\r\n\r\nprovides: Fx.CSS\r\n\r\n...\r\n*/\r\n\r\nFx.CSS = new Class({\r\n\r\n\tExtends: Fx,\r\n\r\n\t//prepares the base from/to object\r\n\r\n\tprepare: function(element, property, values){\r\n\t\tvalues = Array.from(values);\r\n\t\tvar from = values[0], to = values[1];\r\n\t\tif (to == null){\r\n\t\t\tto = from;\r\n\t\t\tfrom = element.getStyle(property);\r\n\t\t\tvar unit = this.options.unit;\r\n\t\t\t// adapted from: https://github.com/ryanmorr/fx/blob/master/fx.js#L299\r\n\t\t\tif (unit && from.slice(-unit.length) != unit && parseFloat(from) != 0){\r\n\t\t\t\telement.setStyle(property, to + unit);\r\n\t\t\t\tvar value = element.getComputedStyle(property);\r\n\t\t\t\t// IE and Opera support pixelLeft or pixelWidth\r\n\t\t\t\tif (!(/px$/.test(value))){\r\n\t\t\t\t\tvalue = element.style[('pixel-' + property).camelCase()];\r\n\t\t\t\t\tif (value == null){\r\n\t\t\t\t\t\t// adapted from Dean Edwards' http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\r\n\t\t\t\t\t\tvar left = element.style.left;\r\n\t\t\t\t\t\telement.style.left = to + unit;\r\n\t\t\t\t\t\tvalue = element.style.pixelLeft;\r\n\t\t\t\t\t\telement.style.left = left;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tfrom = (to || 1) / (parseFloat(value) || 1) * (parseFloat(from) || 0);\r\n\t\t\t\telement.setStyle(property, from + unit);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn {from: this.parse(from), to: this.parse(to)};\r\n\t},\r\n\r\n\t//parses a value into an array\r\n\r\n\tparse: function(value){\r\n\t\tvalue = Function.from(value)();\r\n\t\tvalue = (typeof value == 'string') ? value.split(' ') : Array.from(value);\r\n\t\treturn value.map(function(val){\r\n\t\t\tval = String(val);\r\n\t\t\tvar found = false;\r\n\t\t\tObject.each(Fx.CSS.Parsers, function(parser, key){\r\n\t\t\t\tif (found) return;\r\n\t\t\t\tvar parsed = parser.parse(val);\r\n\t\t\t\tif (parsed || parsed === 0) found = {value: parsed, parser: parser};\r\n\t\t\t});\r\n\t\t\tfound = found || {value: val, parser: Fx.CSS.Parsers.String};\r\n\t\t\treturn found;\r\n\t\t});\r\n\t},\r\n\r\n\t//computes by a from and to prepared objects, using their parsers.\r\n\r\n\tcompute: function(from, to, delta){\r\n\t\tvar computed = [];\r\n\t\t(Math.min(from.length, to.length)).times(function(i){\r\n\t\t\tcomputed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser});\r\n\t\t});\r\n\t\tcomputed.$family = Function.from('fx:css:value');\r\n\t\treturn computed;\r\n\t},\r\n\r\n\t//serves the value as settable\r\n\r\n\tserve: function(value, unit){\r\n\t\tif (typeOf(value) != 'fx:css:value') value = this.parse(value);\r\n\t\tvar returned = [];\r\n\t\tvalue.each(function(bit){\r\n\t\t\treturned = returned.concat(bit.parser.serve(bit.value, unit));\r\n\t\t});\r\n\t\treturn returned;\r\n\t},\r\n\r\n\t//renders the change to an element\r\n\r\n\trender: function(element, property, value, unit){\r\n\t\telement.setStyle(property, this.serve(value, unit));\r\n\t},\r\n\r\n\t//searches inside the page css to find the values for a selector\r\n\r\n\tsearch: function(selector){\r\n\t\tif (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];\r\n\t\tvar to = {}, selectorTest = new RegExp('^' + selector.escapeRegExp() + '$');\r\n\t\tArray.each(document.styleSheets, function(sheet, j){\r\n\t\t\tvar href = sheet.href;\r\n\t\t\tif (href && href.contains('://') && !href.contains(document.domain)) return;\r\n\t\t\tvar rules = sheet.rules || sheet.cssRules;\r\n\t\t\tArray.each(rules, function(rule, i){\r\n\t\t\t\tif (!rule.style) return;\r\n\t\t\t\tvar selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\\w+/, function(m){\r\n\t\t\t\t\treturn m.toLowerCase();\r\n\t\t\t\t}) : null;\r\n\t\t\t\tif (!selectorText || !selectorTest.test(selectorText)) return;\r\n\t\t\t\tObject.each(Element.Styles, function(value, style){\r\n\t\t\t\t\tif (!rule.style[style] || Element.ShortStyles[style]) return;\r\n\t\t\t\t\tvalue = String(rule.style[style]);\r\n\t\t\t\t\tto[style] = ((/^rgb/).test(value)) ? value.rgbToHex() : value;\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\t\treturn Fx.CSS.Cache[selector] = to;\r\n\t}\r\n\r\n});\r\n\r\nFx.CSS.Cache = {};\r\n\r\nFx.CSS.Parsers = {\r\n\r\n\tColor: {\r\n\t\tparse: function(value){\r\n\t\t\tif (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true);\r\n\t\t\treturn ((value = value.match(/(\\d+),\\s*(\\d+),\\s*(\\d+)/))) ? [value[1], value[2], value[3]] : false;\r\n\t\t},\r\n\t\tcompute: function(from, to, delta){\r\n\t\t\treturn from.map(function(value, i){\r\n\t\t\t\treturn Math.round(Fx.compute(from[i], to[i], delta));\r\n\t\t\t});\r\n\t\t},\r\n\t\tserve: function(value){\r\n\t\t\treturn value.map(Number);\r\n\t\t}\r\n\t},\r\n\r\n\tNumber: {\r\n\t\tparse: parseFloat,\r\n\t\tcompute: Fx.compute,\r\n\t\tserve: function(value, unit){\r\n\t\t\treturn (unit) ? value + unit : value;\r\n\t\t}\r\n\t},\r\n\r\n\tString: {\r\n\t\tparse: Function.from(false),\r\n\t\tcompute: function(zero, one){\r\n\t\t\treturn one;\r\n\t\t},\r\n\t\tserve: function(zero){\r\n\t\t\treturn zero;\r\n\t\t}\r\n\t}\r\n\r\n};\r\n\r\n//<1.2compat>\r\n\r\nFx.CSS.Parsers = new Hash(Fx.CSS.Parsers);\r\n\r\n//\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Fx.Tween\r\n\r\ndescription: Formerly Fx.Style, effect to transition any CSS property for an element.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Fx.CSS\r\n\r\nprovides: [Fx.Tween, Element.fade, Element.highlight]\r\n\r\n...\r\n*/\r\n\r\nFx.Tween = new Class({\r\n\r\n\tExtends: Fx.CSS,\r\n\r\n\tinitialize: function(element, options){\r\n\t\tthis.element = this.subject = document.id(element);\r\n\t\tthis.parent(options);\r\n\t},\r\n\r\n\tset: function(property, now){\r\n\t\tif (arguments.length == 1){\r\n\t\t\tnow = property;\r\n\t\t\tproperty = this.property || this.options.property;\r\n\t\t}\r\n\t\tthis.render(this.element, property, now, this.options.unit);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tstart: function(property, from, to){\r\n\t\tif (!this.check(property, from, to)) return this;\r\n\t\tvar args = Array.flatten(arguments);\r\n\t\tthis.property = this.options.property || args.shift();\r\n\t\tvar parsed = this.prepare(this.element, this.property, args);\r\n\t\treturn this.parent(parsed.from, parsed.to);\r\n\t}\r\n\r\n});\r\n\r\nElement.Properties.tween = {\r\n\r\n\tset: function(options){\r\n\t\tthis.get('tween').cancel().setOptions(options);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tget: function(){\r\n\t\tvar tween = this.retrieve('tween');\r\n\t\tif (!tween){\r\n\t\t\ttween = new Fx.Tween(this, {link: 'cancel'});\r\n\t\t\tthis.store('tween', tween);\r\n\t\t}\r\n\t\treturn tween;\r\n\t}\r\n\r\n};\r\n\r\nElement.implement({\r\n\r\n\ttween: function(property, from, to){\r\n\t\tthis.get('tween').start(property, from, to);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tfade: function(how){\r\n\t\tvar fade = this.get('tween'), method, args = ['opacity'].append(arguments), toggle;\r\n\t\tif (args[1] == null) args[1] = 'toggle';\r\n\t\tswitch (args[1]){\r\n\t\t\tcase 'in': method = 'start'; args[1] = 1; break;\r\n\t\t\tcase 'out': method = 'start'; args[1] = 0; break;\r\n\t\t\tcase 'show': method = 'set'; args[1] = 1; break;\r\n\t\t\tcase 'hide': method = 'set'; args[1] = 0; break;\r\n\t\t\tcase 'toggle':\r\n\t\t\t\tvar flag = this.retrieve('fade:flag', this.getStyle('opacity') == 1);\r\n\t\t\t\tmethod = 'start';\r\n\t\t\t\targs[1] = flag ? 0 : 1;\r\n\t\t\t\tthis.store('fade:flag', !flag);\r\n\t\t\t\ttoggle = true;\r\n\t\t\tbreak;\r\n\t\t\tdefault: method = 'start';\r\n\t\t}\r\n\t\tif (!toggle) this.eliminate('fade:flag');\r\n\t\tfade[method].apply(fade, args);\r\n\t\tvar to = args[args.length - 1];\r\n\t\tif (method == 'set' || to != 0) this.setStyle('visibility', to == 0 ? 'hidden' : 'visible');\r\n\t\telse fade.chain(function(){\r\n\t\t\tthis.element.setStyle('visibility', 'hidden');\r\n\t\t\tthis.callChain();\r\n\t\t});\r\n\t\treturn this;\r\n\t},\r\n\r\n\thighlight: function(start, end){\r\n\t\tif (!end){\r\n\t\t\tend = this.retrieve('highlight:original', this.getStyle('background-color'));\r\n\t\t\tend = (end == 'transparent') ? '#fff' : end;\r\n\t\t}\r\n\t\tvar tween = this.get('tween');\r\n\t\ttween.start('background-color', start || '#ffff88', end).chain(function(){\r\n\t\t\tthis.setStyle('background-color', this.retrieve('highlight:original'));\r\n\t\t\ttween.callChain();\r\n\t\t}.bind(this));\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Fx.Morph\r\n\r\ndescription: Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: Fx.CSS\r\n\r\nprovides: Fx.Morph\r\n\r\n...\r\n*/\r\n\r\nFx.Morph = new Class({\r\n\r\n\tExtends: Fx.CSS,\r\n\r\n\tinitialize: function(element, options){\r\n\t\tthis.element = this.subject = document.id(element);\r\n\t\tthis.parent(options);\r\n\t},\r\n\r\n\tset: function(now){\r\n\t\tif (typeof now == 'string') now = this.search(now);\r\n\t\tfor (var p in now) this.render(this.element, p, now[p], this.options.unit);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tcompute: function(from, to, delta){\r\n\t\tvar now = {};\r\n\t\tfor (var p in from) now[p] = this.parent(from[p], to[p], delta);\r\n\t\treturn now;\r\n\t},\r\n\r\n\tstart: function(properties){\r\n\t\tif (!this.check(properties)) return this;\r\n\t\tif (typeof properties == 'string') properties = this.search(properties);\r\n\t\tvar from = {}, to = {};\r\n\t\tfor (var p in properties){\r\n\t\t\tvar parsed = this.prepare(this.element, p, properties[p]);\r\n\t\t\tfrom[p] = parsed.from;\r\n\t\t\tto[p] = parsed.to;\r\n\t\t}\r\n\t\treturn this.parent(from, to);\r\n\t}\r\n\r\n});\r\n\r\nElement.Properties.morph = {\r\n\r\n\tset: function(options){\r\n\t\tthis.get('morph').cancel().setOptions(options);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tget: function(){\r\n\t\tvar morph = this.retrieve('morph');\r\n\t\tif (!morph){\r\n\t\t\tmorph = new Fx.Morph(this, {link: 'cancel'});\r\n\t\t\tthis.store('morph', morph);\r\n\t\t}\r\n\t\treturn morph;\r\n\t}\r\n\r\n};\r\n\r\nElement.implement({\r\n\r\n\tmorph: function(props){\r\n\t\tthis.get('morph').start(props);\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Fx.Transitions\r\n\r\ndescription: Contains a set of advanced transitions to be used with any of the Fx Classes.\r\n\r\nlicense: MIT-style license.\r\n\r\ncredits:\r\n - Easing Equations by Robert Penner, , modified and optimized for this framework\r\n\r\nrequires: Fx\r\n\r\nprovides: Fx.Transitions\r\n\r\n...\r\n*/\r\n\r\nFx.implement({\r\n\r\n\tgetTransition: function(){\r\n\t\tvar trans = this.options.transition || Fx.Transitions.Sine.easeInOut;\r\n\t\tif (typeof trans == 'string'){\r\n\t\t\tvar data = trans.split(':');\r\n\t\t\ttrans = Fx.Transitions;\r\n\t\t\ttrans = trans[data[0]] || trans[data[0].capitalize()];\r\n\t\t\tif (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')];\r\n\t\t}\r\n\t\treturn trans;\r\n\t}\r\n\r\n});\r\n\r\nFx.Transition = function(transition, params){\r\n\tparams = Array.from(params);\r\n\tvar easeIn = function(pos){\r\n\t\treturn transition(pos, params);\r\n\t};\r\n\treturn Object.append(easeIn, {\r\n\t\teaseIn: easeIn,\r\n\t\teaseOut: function(pos){\r\n\t\t\treturn 1 - transition(1 - pos, params);\r\n\t\t},\r\n\t\teaseInOut: function(pos){\r\n\t\t\treturn (pos <= 0.5 ? transition(2 * pos, params) : (2 - transition(2 * (1 - pos), params))) / 2;\r\n\t\t}\r\n\t});\r\n};\r\n\r\nFx.Transitions = {\r\n\r\n\tlinear: function(zero){\r\n\t\treturn zero;\r\n\t}\r\n\r\n};\r\n\r\n//<1.2compat>\r\n\r\nFx.Transitions = new Hash(Fx.Transitions);\r\n\r\n//\r\n\r\nFx.Transitions.extend = function(transitions){\r\n\tfor (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);\r\n};\r\n\r\nFx.Transitions.extend({\r\n\r\n\tPow: function(p, x){\r\n\t\treturn Math.pow(p, x && x[0] || 6);\r\n\t},\r\n\r\n\tExpo: function(p){\r\n\t\treturn Math.pow(2, 8 * (p - 1));\r\n\t},\r\n\r\n\tCirc: function(p){\r\n\t\treturn 1 - Math.sin(Math.acos(p));\r\n\t},\r\n\r\n\tSine: function(p){\r\n\t\treturn 1 - Math.cos(p * Math.PI / 2);\r\n\t},\r\n\r\n\tBack: function(p, x){\r\n\t\tx = x && x[0] || 1.618;\r\n\t\treturn Math.pow(p, 2) * ((x + 1) * p - x);\r\n\t},\r\n\r\n\tBounce: function(p){\r\n\t\tvar value;\r\n\t\tfor (var a = 0, b = 1; 1; a += b, b /= 2){\r\n\t\t\tif (p >= (7 - 4 * a) / 11){\r\n\t\t\t\tvalue = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn value;\r\n\t},\r\n\r\n\tElastic: function(p, x){\r\n\t\treturn Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x && x[0] || 1) / 3);\r\n\t}\r\n\r\n});\r\n\r\n['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){\r\n\tFx.Transitions[transition] = new Fx.Transition(function(p){\r\n\t\treturn Math.pow(p, i + 2);\r\n\t});\r\n});\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Request\r\n\r\ndescription: Powerful all purpose Request Class. Uses XMLHTTPRequest.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Object, Element, Chain, Events, Options, Browser]\r\n\r\nprovides: Request\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar empty = function(){},\r\n\tprogressSupport = ('onprogress' in new Browser.Request);\r\n\r\nvar Request = this.Request = new Class({\r\n\r\n\tImplements: [Chain, Events, Options],\r\n\r\n\toptions: {/*\r\n\t\tonRequest: function(){},\r\n\t\tonLoadstart: function(event, xhr){},\r\n\t\tonProgress: function(event, xhr){},\r\n\t\tonComplete: function(){},\r\n\t\tonCancel: function(){},\r\n\t\tonSuccess: function(responseText, responseXML){},\r\n\t\tonFailure: function(xhr){},\r\n\t\tonException: function(headerName, value){},\r\n\t\tonTimeout: function(){},\r\n\t\tuser: '',\r\n\t\tpassword: '',*/\r\n\t\turl: '',\r\n\t\tdata: '',\r\n\t\theaders: {\r\n\t\t\t'X-Requested-With': 'XMLHttpRequest',\r\n\t\t\t'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'\r\n\t\t},\r\n\t\tasync: true,\r\n\t\tformat: false,\r\n\t\tmethod: 'post',\r\n\t\tlink: 'ignore',\r\n\t\tisSuccess: null,\r\n\t\temulation: true,\r\n\t\turlEncoded: true,\r\n\t\tencoding: 'utf-8',\r\n\t\tevalScripts: false,\r\n\t\tevalResponse: false,\r\n\t\ttimeout: 0,\r\n\t\tnoCache: false\r\n\t},\r\n\r\n\tinitialize: function(options){\r\n\t\tthis.xhr = new Browser.Request();\r\n\t\tthis.setOptions(options);\r\n\t\tthis.headers = this.options.headers;\r\n\t},\r\n\r\n\tonStateChange: function(){\r\n\t\tvar xhr = this.xhr;\r\n\t\tif (xhr.readyState != 4 || !this.running) return;\r\n\t\tthis.running = false;\r\n\t\tthis.status = 0;\r\n\t\tFunction.attempt(function(){\r\n\t\t\tvar status = xhr.status;\r\n\t\t\tthis.status = (status == 1223) ? 204 : status;\r\n\t\t}.bind(this));\r\n\t\txhr.onreadystatechange = empty;\r\n\t\tif (progressSupport) xhr.onprogress = xhr.onloadstart = empty;\r\n\t\tclearTimeout(this.timer);\r\n\r\n\t\tthis.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML};\r\n\t\tif (this.options.isSuccess.call(this, this.status))\r\n\t\t\tthis.success(this.response.text, this.response.xml);\r\n\t\telse\r\n\t\t\tthis.failure();\r\n\t},\r\n\r\n\tisSuccess: function(){\r\n\t\tvar status = this.status;\r\n\t\treturn (status >= 200 && status < 300);\r\n\t},\r\n\r\n\tisRunning: function(){\r\n\t\treturn !!this.running;\r\n\t},\r\n\r\n\tprocessScripts: function(text){\r\n\t\tif (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text);\r\n\t\treturn text.stripScripts(this.options.evalScripts);\r\n\t},\r\n\r\n\tsuccess: function(text, xml){\r\n\t\tthis.onSuccess(this.processScripts(text), xml);\r\n\t},\r\n\r\n\tonSuccess: function(){\r\n\t\tthis.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();\r\n\t},\r\n\r\n\tfailure: function(){\r\n\t\tthis.onFailure();\r\n\t},\r\n\r\n\tonFailure: function(){\r\n\t\tthis.fireEvent('complete').fireEvent('failure', this.xhr);\r\n\t},\r\n\r\n\tloadstart: function(event){\r\n\t\tthis.fireEvent('loadstart', [event, this.xhr]);\r\n\t},\r\n\r\n\tprogress: function(event){\r\n\t\tthis.fireEvent('progress', [event, this.xhr]);\r\n\t},\r\n\r\n\ttimeout: function(){\r\n\t\tthis.fireEvent('timeout', this.xhr);\r\n\t},\r\n\r\n\tsetHeader: function(name, value){\r\n\t\tthis.headers[name] = value;\r\n\t\treturn this;\r\n\t},\r\n\r\n\tgetHeader: function(name){\r\n\t\treturn Function.attempt(function(){\r\n\t\t\treturn this.xhr.getResponseHeader(name);\r\n\t\t}.bind(this));\r\n\t},\r\n\r\n\tcheck: function(){\r\n\t\tif (!this.running) return true;\r\n\t\tswitch (this.options.link){\r\n\t\t\tcase 'cancel': this.cancel(); return true;\r\n\t\t\tcase 'chain': this.chain(this.caller.pass(arguments, this)); return false;\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\r\n\tsend: function(options){\r\n\t\tif (!this.check(options)) return this;\r\n\r\n\t\tthis.options.isSuccess = this.options.isSuccess || this.isSuccess;\r\n\t\tthis.running = true;\r\n\r\n\t\tvar type = typeOf(options);\r\n\t\tif (type == 'string' || type == 'element') options = {data: options};\r\n\r\n\t\tvar old = this.options;\r\n\t\toptions = Object.append({data: old.data, url: old.url, method: old.method}, options);\r\n\tvar data = options.data, url = String(options.url), method = options.method.toLowerCase();\r\n\r\n\t\t// Leave FormData as is, so browser will post it correctly\r\n\t\tif (!(data instanceof FormData)) {\r\n\t\t\tswitch (typeOf(data)) {\r\n\t\t\t\tcase 'element': data = document.id(data).toQueryString(); break;\r\n\t\t\t\tcase 'object': case 'hash': data = Object.toQueryString(data);\r\n\t\t\t}\r\n\r\n\t\t\tif (this.options.format){\r\n\t\t\t\tvar format = 'format=' + this.options.format;\r\n\t\t\t\tdata = (data) ? format + '&' + data : format;\r\n\t\t\t}\r\n\r\n\t\t\tif (this.options.emulation && !['get', 'post'].contains(method)){\r\n\t\t\t\tvar _method = '_method=' + method;\r\n\t\t\t\tdata = (data) ? _method + '&' + data : _method;\r\n\t\t\t\tmethod = 'post';\r\n\t\t\t}\r\n\r\n\t\t\tif (this.options.urlEncoded && ['post', 'put'].contains(method)){\r\n\t\t\t\tvar encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';\r\n\t\t\t\tthis.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!url) url = document.location.pathname;\r\n\r\n\t\tvar trimPosition = url.lastIndexOf('/');\r\n\t\tif (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);\r\n\r\n\t\tif (this.options.noCache)\r\n\t\t\turl += (url.contains('?') ? '&' : '?') + String.uniqueID();\r\n\r\n\t\tif (data && method == 'get'){\r\n\t\t\turl += (url.contains('?') ? '&' : '?') + data;\r\n\t\t\tdata = null;\r\n\t\t}\r\n\r\n\t\tvar xhr = this.xhr;\r\n\t\tif (progressSupport){\r\n\t\t\txhr.onloadstart = this.loadstart.bind(this);\r\n\t\t\txhr.onprogress = this.progress.bind(this);\r\n\t\t}\r\n\r\n\t\txhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);\r\n\t\tif (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;\r\n\r\n\t\txhr.onreadystatechange = this.onStateChange.bind(this);\r\n\r\n\t\tObject.each(this.headers, function(value, key){\r\n\t\t\ttry {\r\n\t\t\t\txhr.setRequestHeader(key, value);\r\n\t\t\t} catch (e){\r\n\t\t\t\tthis.fireEvent('exception', [key, value]);\r\n\t\t\t}\r\n\t\t}, this);\r\n\r\n\t\tthis.fireEvent('request');\r\n\t\txhr.send(data);\r\n\t\tif (!this.options.async) this.onStateChange();\r\n\t\telse if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tcancel: function(){\r\n\t\tif (!this.running) return this;\r\n\t\tthis.running = false;\r\n\t\tvar xhr = this.xhr;\r\n\t\txhr.abort();\r\n\t\tclearTimeout(this.timer);\r\n\t\txhr.onreadystatechange = empty;\r\n\t\tif (progressSupport) xhr.onprogress = xhr.onloadstart = empty;\r\n\t\tthis.xhr = new Browser.Request();\r\n\t\tthis.fireEvent('cancel');\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\nvar methods = {};\r\n['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){\r\n\tmethods[method] = function(data){\r\n\t\tvar object = {\r\n\t\t\tmethod: method\r\n\t\t};\r\n\t\tif (data != null) object.data = data;\r\n\t\treturn this.send(object);\r\n\t};\r\n});\r\n\r\nRequest.implement(methods);\r\n\r\nElement.Properties.send = {\r\n\r\n\tset: function(options){\r\n\t\tvar send = this.get('send').cancel();\r\n\t\tsend.setOptions(options);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tget: function(){\r\n\t\tvar send = this.retrieve('send');\r\n\t\tif (!send){\r\n\t\t\tsend = new Request({\r\n\t\t\t\tdata: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action')\r\n\t\t\t});\r\n\t\t\tthis.store('send', send);\r\n\t\t}\r\n\t\treturn send;\r\n\t}\r\n\r\n};\r\n\r\nElement.implement({\r\n\r\n\tsend: function(url){\r\n\t\tvar sender = this.get('send');\r\n\t\tsender.send({data: this, url: url || sender.options.url});\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Request.HTML\r\n\r\ndescription: Extends the basic Request Class with additional methods for interacting with HTML responses.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Element, Request]\r\n\r\nprovides: Request.HTML\r\n\r\n...\r\n*/\r\n\r\nRequest.HTML = new Class({\r\n\r\n\tExtends: Request,\r\n\r\n\toptions: {\r\n\t\tupdate: false,\r\n\t\tappend: false,\r\n\t\tevalScripts: true,\r\n\t\tfilter: false,\r\n\t\theaders: {\r\n\t\t\tAccept: 'text/html, application/xml, text/xml, */*'\r\n\t\t}\r\n\t},\r\n\r\n\tsuccess: function(text){\r\n\t\tvar options = this.options, response = this.response;\r\n\r\n\t\tresponse.html = text.stripScripts(function(script){\r\n\t\t\tresponse.javascript = script;\r\n\t\t});\r\n\r\n\t\tvar match = response.html.match(/]*>([\\s\\S]*?)<\\/body>/i);\r\n\t\tif (match) response.html = match[1];\r\n\t\tvar temp = new Element('div').set('html', response.html);\r\n\r\n\t\tresponse.tree = temp.childNodes;\r\n\t\tresponse.elements = temp.getElements(options.filter || '*');\r\n\r\n\t\tif (options.filter) response.tree = response.elements;\r\n\t\tif (options.update){\r\n\t\t\tvar update = document.id(options.update).empty();\r\n\t\t\tif (options.filter) update.adopt(response.elements);\r\n\t\t\telse update.set('html', response.html);\r\n\t\t} else if (options.append){\r\n\t\t\tvar append = document.id(options.append);\r\n\t\t\tif (options.filter) response.elements.reverse().inject(append);\r\n\t\t\telse append.adopt(temp.getChildren());\r\n\t\t}\r\n\t\tif (options.evalScripts) Browser.exec(response.javascript);\r\n\r\n\t\tthis.onSuccess(response.tree, response.elements, response.html, response.javascript);\r\n\t}\r\n\r\n});\r\n\r\nElement.Properties.load = {\r\n\r\n\tset: function(options){\r\n\t\tvar load = this.get('load').cancel();\r\n\t\tload.setOptions(options);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tget: function(){\r\n\t\tvar load = this.retrieve('load');\r\n\t\tif (!load){\r\n\t\t\tload = new Request.HTML({data: this, link: 'cancel', update: this, method: 'get'});\r\n\t\t\tthis.store('load', load);\r\n\t\t}\r\n\t\treturn load;\r\n\t}\r\n\r\n};\r\n\r\nElement.implement({\r\n\r\n\tload: function(){\r\n\t\tthis.get('load').send(Array.link(arguments, {data: Type.isObject, url: Type.isString}));\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\n\r\n/*\r\n---\r\n\r\nname: JSON\r\n\r\ndescription: JSON encoder and decoder.\r\n\r\nlicense: MIT-style license.\r\n\r\nSeeAlso: \r\n\r\nrequires: [Array, String, Number, Function]\r\n\r\nprovides: JSON\r\n\r\n...\r\n*/\r\n\r\nif (typeof JSON == 'undefined') this.JSON = {};\r\n\r\n//<1.2compat>\r\n\r\nJSON = new Hash({\r\n\tstringify: JSON.stringify,\r\n\tparse: JSON.parse\r\n});\r\n\r\n//\r\n\r\n(function(){\r\n\r\nvar special = {'\\b': '\\\\b', '\\t': '\\\\t', '\\n': '\\\\n', '\\f': '\\\\f', '\\r': '\\\\r', '\"' : '\\\\\"', '\\\\': '\\\\\\\\'};\r\n\r\nvar escape = function(chr){\r\n\treturn special[chr] || '\\\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);\r\n};\r\n\r\nJSON.validate = function(string){\r\n\tstring = string.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').\r\n\t\t\t\t\treplace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, ']').\r\n\t\t\t\t\treplace(/(?:^|:|,)(?:\\s*\\[)+/g, '');\r\n\r\n\treturn (/^[\\],:{}\\s]*$/).test(string);\r\n};\r\n\r\nJSON.encode = JSON.stringify ? function(obj){\r\n\treturn JSON.stringify(obj);\r\n} : function(obj){\r\n\tif (obj && obj.toJSON) obj = obj.toJSON();\r\n\r\n\tswitch (typeOf(obj)){\r\n\t\tcase 'string':\r\n\t\t\treturn '\"' + obj.replace(/[\\x00-\\x1f\\\\\"]/g, escape) + '\"';\r\n\t\tcase 'array':\r\n\t\t\treturn '[' + obj.map(JSON.encode).clean() + ']';\r\n\t\tcase 'object': case 'hash':\r\n\t\t\tvar string = [];\r\n\t\t\tObject.each(obj, function(value, key){\r\n\t\t\t\tvar json = JSON.encode(value);\r\n\t\t\t\tif (json) string.push(JSON.encode(key) + ':' + json);\r\n\t\t\t});\r\n\t\t\treturn '{' + string + '}';\r\n\t\tcase 'number': case 'boolean': return '' + obj;\r\n\t\tcase 'null': return 'null';\r\n\t}\r\n\r\n\treturn null;\r\n};\r\n\r\nJSON.decode = function(string, secure){\r\n\tif (!string || typeOf(string) != 'string') return null;\r\n\r\n\tif (secure || JSON.secure){\r\n\t\tif (JSON.parse) return JSON.parse(string);\r\n\t\tif (!JSON.validate(string)) throw new Error('JSON could not decode the input; security is enabled and the value is not secure.');\r\n\t}\r\n\r\n\treturn eval('(' + string + ')');\r\n};\r\n\r\n})();\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Request.JSON\r\n\r\ndescription: Extends the basic Request Class with additional methods for sending and receiving JSON data.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Request, JSON]\r\n\r\nprovides: Request.JSON\r\n\r\n...\r\n*/\r\n\r\nRequest.JSON = new Class({\r\n\r\n\tExtends: Request,\r\n\r\n\toptions: {\r\n\t\t/*onError: function(text, error){},*/\r\n\t\tsecure: true\r\n\t},\r\n\r\n\tinitialize: function(options){\r\n\t\tthis.parent(options);\r\n\t\tObject.append(this.headers, {\r\n\t\t\t'Accept': 'application/json',\r\n\t\t\t'X-Request': 'JSON'\r\n\t\t});\r\n\t},\r\n\r\n\tsuccess: function(text){\r\n\t\tvar json;\r\n\t\ttry {\r\n\t\t\tjson = this.response.json = JSON.decode(text, this.options.secure);\r\n\t\t} catch (error){\r\n\t\t\tthis.fireEvent('error', [text, error]);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t//if (json == null)\r\n\t\t//\tthis.onFailure();\r\n\t\t//else\r\n\t\t\tthis.onSuccess(json, text);\r\n\t}\r\n\r\n});\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Cookie\r\n\r\ndescription: Class for creating, reading, and deleting browser Cookies.\r\n\r\nlicense: MIT-style license.\r\n\r\ncredits:\r\n - Based on the functions by Peter-Paul Koch (http://quirksmode.org).\r\n\r\nrequires: [Options, Browser]\r\n\r\nprovides: Cookie\r\n\r\n...\r\n*/\r\n\r\nvar Cookie = new Class({\r\n\r\n\tImplements: Options,\r\n\r\n\toptions: {\r\n\t\tpath: '/',\r\n\t\tdomain: false,\r\n\t\tduration: false,\r\n\t\tsecure: false,\r\n\t\tdocument: document,\r\n\t\tencode: true\r\n\t},\r\n\r\n\tinitialize: function(key, options){\r\n\t\tthis.key = key;\r\n\t\tthis.setOptions(options);\r\n\t},\r\n\r\n\twrite: function(value){\r\n\t\tif (this.options.encode) value = encodeURIComponent(value);\r\n\t\tif (this.options.domain) value += '; domain=' + this.options.domain;\r\n\t\tif (this.options.path) value += '; path=' + this.options.path;\r\n\t\tif (this.options.duration){\r\n\t\t\tvar date = new Date();\r\n\t\t\tdate.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);\r\n\t\t\tvalue += '; expires=' + date.toGMTString();\r\n\t\t}\r\n\t\tif (this.options.secure) value += '; secure';\r\n\t\tthis.options.document.cookie = this.key + '=' + value;\r\n\t\treturn this;\r\n\t},\r\n\r\n\tread: function(){\r\n\t\tvar value = this.options.document.cookie.match('(?:^|;)\\\\s*' + this.key.escapeRegExp() + '=([^;]*)');\r\n\t\treturn (value) ? decodeURIComponent(value[1]) : null;\r\n\t},\r\n\r\n\tdispose: function(){\r\n\t\tnew Cookie(this.key, Object.merge({}, this.options, {duration: -1})).write('');\r\n\t\treturn this;\r\n\t}\r\n\r\n});\r\n\r\nCookie.write = function(key, value, options){\r\n\treturn new Cookie(key, options).write(value);\r\n};\r\n\r\nCookie.read = function(key){\r\n\treturn new Cookie(key).read();\r\n};\r\n\r\nCookie.dispose = function(key, options){\r\n\treturn new Cookie(key, options).dispose();\r\n};\r\n\r\n\r\n/*\r\n---\r\n\r\nname: DOMReady\r\n\r\ndescription: Contains the custom event domready.\r\n\r\nlicense: MIT-style license.\r\n\r\nrequires: [Browser, Element, Element.Event]\r\n\r\nprovides: [DOMReady, DomReady]\r\n\r\n...\r\n*/\r\n\r\n(function(window, document){\r\n\r\nvar ready,\r\n\tloaded,\r\n\tchecks = [],\r\n\tshouldPoll,\r\n\ttimer,\r\n\ttestElement = document.createElement('div');\r\n\r\nvar domready = function(){\r\n\tclearTimeout(timer);\r\n\tif (ready) return;\r\n\tBrowser.loaded = ready = true;\r\n\tdocument.removeListener('DOMContentLoaded', domready).removeListener('readystatechange', check);\r\n\r\n\tdocument.fireEvent('domready');\r\n\twindow.fireEvent('domready');\r\n};\r\n\r\nvar check = function(){\r\n\tfor (var i = checks.length; i--;) if (checks[i]()){\r\n\t\tdomready();\r\n\t\treturn true;\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nvar poll = function(){\r\n\tclearTimeout(timer);\r\n\tif (!check()) timer = setTimeout(poll, 10);\r\n};\r\n\r\ndocument.addListener('DOMContentLoaded', domready);\r\n\r\n/**/\r\n// doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/\r\n// testElement.doScroll() throws when the DOM is not ready, only in the top window\r\nvar doScrollWorks = function(){\r\n\ttry {\r\n\t\ttestElement.doScroll();\r\n\t\treturn true;\r\n\t} catch (e){}\r\n\treturn false;\r\n};\r\n// If doScroll works already, it can't be used to determine domready\r\n// e.g. in an iframe\r\nif (testElement.doScroll && !doScrollWorks()){\r\n\tchecks.push(doScrollWorks);\r\n\tshouldPoll = true;\r\n}\r\n/**/\r\n\r\nif (document.readyState) checks.push(function(){\r\n\tvar state = document.readyState;\r\n\treturn (state == 'loaded' || state == 'complete');\r\n});\r\n\r\nif ('onreadystatechange' in document) document.addListener('readystatechange', check);\r\nelse shouldPoll = true;\r\n\r\nif (shouldPoll) poll();\r\n\r\nElement.Events.domready = {\r\n\tonAdd: function(fn){\r\n\t\tif (ready) fn.call(this);\r\n\t}\r\n};\r\n\r\n// Make sure that domready fires before load\r\nElement.Events.load = {\r\n\tbase: 'load',\r\n\tonAdd: function(fn){\r\n\t\tif (loaded && this == window) fn.call(this);\r\n\t},\r\n\tcondition: function(){\r\n\t\tif (this == window){\r\n\t\t\tdomready();\r\n\t\t\tdelete Element.Events.load;\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n};\r\n\r\n// This is based on the custom load event\r\nwindow.addEvent('load', function(){\r\n\tloaded = true;\r\n});\r\n\r\n})(window, document);\r\n\r\n\r\n/*\r\n---\r\n\r\nname: Swiff\r\n\r\ndescription: Wrapper for embedding SWF movies. Supports External Interface Communication.\r\n\r\nlicense: MIT-style license.\r\n\r\ncredits:\r\n - Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject.\r\n\r\nrequires: [Options, Object, Element]\r\n\r\nprovides: Swiff\r\n\r\n...\r\n*/\r\n\r\n(function(){\r\n\r\nvar Swiff = this.Swiff = new Class({\r\n\r\n\tImplements: Options,\r\n\r\n\toptions: {\r\n\t\tid: null,\r\n\t\theight: 1,\r\n\t\twidth: 1,\r\n\t\tcontainer: null,\r\n\t\tproperties: {},\r\n\t\tparams: {\r\n\t\t\tquality: 'high',\r\n\t\t\tallowScriptAccess: 'always',\r\n\t\t\twMode: 'window',\r\n\t\t\tswLiveConnect: true\r\n\t\t},\r\n\t\tcallBacks: {},\r\n\t\tvars: {}\r\n\t},\r\n\r\n\ttoElement: function(){\r\n\t\treturn this.object;\r\n\t},\r\n\r\n\tinitialize: function(path, options){\r\n\t\tthis.instance = 'Swiff_' + String.uniqueID();\r\n\r\n\t\tthis.setOptions(options);\r\n\t\toptions = this.options;\r\n\t\tvar id = this.id = options.id || this.instance;\r\n\t\tvar container = document.id(options.container);\r\n\r\n\t\tSwiff.CallBacks[this.instance] = {};\r\n\r\n\t\tvar params = options.params, vars = options.vars, callBacks = options.callBacks;\r\n\t\tvar properties = Object.append({height: options.height, width: options.width}, options.properties);\r\n\r\n\t\tvar self = this;\r\n\r\n\t\tfor (var callBack in callBacks){\r\n\t\t\tSwiff.CallBacks[this.instance][callBack] = (function(option){\r\n\t\t\t\treturn function(){\r\n\t\t\t\t\treturn option.apply(self.object, arguments);\r\n\t\t\t\t};\r\n\t\t\t})(callBacks[callBack]);\r\n\t\t\tvars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack;\r\n\t\t}\r\n\r\n\t\tparams.flashVars = Object.toQueryString(vars);\r\n\t\tif (Browser.ie){\r\n\t\t\tproperties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';\r\n\t\t\tparams.movie = path;\r\n\t\t} else {\r\n\t\t\tproperties.type = 'application/x-shockwave-flash';\r\n\t\t}\r\n\t\tproperties.data = path;\r\n\r\n\t\tvar build = '';\r\n\t\t}\r\n\t\tbuild += '';\r\n\t\tthis.object = ((container) ? container.empty() : new Element('div')).set('html', build).firstChild;\r\n\t},\r\n\r\n\treplaces: function(element){\r\n\t\telement = document.id(element, true);\r\n\t\telement.parentNode.replaceChild(this.toElement(), element);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tinject: function(element){\r\n\t\tdocument.id(element, true).appendChild(this.toElement());\r\n\t\treturn this;\r\n\t},\r\n\r\n\tremote: function(){\r\n\t\treturn Swiff.remote.apply(Swiff, [this.toElement()].append(arguments));\r\n\t}\r\n\r\n});\r\n\r\nSwiff.CallBacks = {};\r\n\r\nSwiff.remote = function(obj, fn){\r\n\tvar rs = obj.CallFunction('' + __flash__argumentsToXML(arguments, 2) + '');\r\n\treturn eval(rs);\r\n};\r\n\r\n})();\r\n\r\n","/*\n---\n\nscript: More.js\n\nname: More\n\ndescription: Additional features\n\nlicense: MIT-style license\n\nauthors:\n - Guillermo Rauch\n - Thomas Aylott\n - Scott Kyle\n - Arian Stolwijk\n - Tim Wienk\n - Christoph Pojer\n - Aaron Newton\n - Jacob Thornton\n\nrequires:\n - Core\n\nprovides: [More]\n\n...\n*/\n\n\ngetTouchOrMouseEvent = function(mouseEvent) {\n if (Browser.isMobile) {\n if (mouseEvent == \"mousedown\")\n return \"touchstart\";\n if (mouseEvent == \"mouseup\")\n return \"touchend\";\n if (mouseEvent == \"click\")\n return \"touchstart\";\n if (mouseEvent == \"dblclick\")\n return \"touchstart\";\n if (mouseEvent == \"mousemove\")\n return \"touchmove\";\n if (mouseEvent == \"mousewheel\")\n return \"touchmove\";\n }\n\n return mouseEvent;\n};\n\n\n/*\n---\n\nname: Events.Pseudos\n\ndescription: Adds the functionality to add pseudo events\n\nlicense: MIT-style license\n\nauthors:\n - Arian Stolwijk\n\nrequires: [Core/Class.Extras, Core/Slick.Parser, More]\n\nprovides: [Events.Pseudos]\n\n...\n*/\n\n(function(){\n\nEvents.Pseudos = function(pseudos, addEvent, removeEvent){\n\n\tvar storeKey = '_monitorEvents:';\n\n\tvar storageOf = function(object){\n\t\treturn {\n\t\t\tstore: object.store ? function(key, value){\n\t\t\t\tobject.store(storeKey + key, value);\n\t\t\t} : function(key, value){\n\t\t\t\t(object._monitorEvents || (object._monitorEvents = {}))[key] = value;\n\t\t\t},\n\t\t\tretrieve: object.retrieve ? function(key, dflt){\n\t\t\t\treturn object.retrieve(storeKey + key, dflt);\n\t\t\t} : function(key, dflt){\n\t\t\t\tif (!object._monitorEvents) return dflt;\n\t\t\t\treturn object._monitorEvents[key] || dflt;\n\t\t\t}\n\t\t};\n\t};\n\n\tvar splitType = function(type){\n\t\tif (type.indexOf(':') == -1 || !pseudos) return null;\n\n\t\tvar parsed = Slick.parse(type).expressions[0][0],\n\t\t\tparsedPseudos = parsed.pseudos,\n\t\t\tl = parsedPseudos.length,\n\t\t\tsplits = [];\n\n\t\twhile (l--){\n\t\t\tvar pseudo = parsedPseudos[l].key,\n\t\t\t\tlistener = pseudos[pseudo];\n\t\t\tif (listener != null) splits.push({\n\t\t\t\tevent: parsed.tag,\n\t\t\t\tvalue: parsedPseudos[l].value,\n\t\t\t\tpseudo: pseudo,\n\t\t\t\toriginal: type,\n\t\t\t\tlistener: listener\n\t\t\t});\n\t\t}\n\t\treturn splits.length ? splits : null;\n\t};\n\n\treturn {\n\n\t\taddEvent: function(type, fn, internal){\n\t\t\tvar split = splitType(type);\n\t\t\tif (!split) return addEvent.call(this, type, fn, internal);\n\n\t\t\tvar storage = storageOf(this),\n\t\t\t\tevents = storage.retrieve(type, []),\n\t\t\t\teventType = split[0].event,\n\t\t\t\targs = Array.slice(arguments, 2),\n\t\t\t\tstack = fn,\n\t\t\t\tself = this;\n\n\t\t\tsplit.each(function(item){\n\t\t\t\tvar listener = item.listener,\n\t\t\t\t\tstackFn = stack;\n\t\t\t\tif (listener == false) eventType += ':' + item.pseudo + '(' + item.value + ')';\n\t\t\t\telse stack = function(){\n\t\t\t\t\tlistener.call(self, item, stackFn, arguments, stack);\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tevents.include({type: eventType, event: fn, monitor: stack});\n\t\t\tstorage.store(type, events);\n\n\t\t\tif (type != eventType) addEvent.apply(this, [type, fn].concat(args));\n\t\t\treturn addEvent.apply(this, [eventType, stack].concat(args));\n\t\t},\n\n\t\tremoveEvent: function(type, fn){\n\t\t\tvar split = splitType(type);\n\t\t\tif (!split) return removeEvent.call(this, type, fn);\n\n\t\t\tvar storage = storageOf(this),\n\t\t\t\tevents = storage.retrieve(type);\n\t\t\tif (!events) return this;\n\n\t\t\tvar args = Array.slice(arguments, 2);\n\n\t\t\tremoveEvent.apply(this, [type, fn].concat(args));\n\t\t\tevents.each(function(monitor, i){\n\t\t\t\tif (!fn || monitor.event == fn) removeEvent.apply(this, [monitor.type, monitor.monitor].concat(args));\n\t\t\t\tdelete events[i];\n\t\t\t}, this);\n\n\t\t\tstorage.store(type, events);\n\t\t\treturn this;\n\t\t}\n\n\t};\n\n};\n\nvar pseudos = {\n\n\tonce: function(split, fn, args, monitor){\n\t\tfn.apply(this, args);\n\t\tthis.removeEvent(split.event, monitor)\n\t\t\t.removeEvent(split.original, fn);\n\t},\n\n\tthrottle: function(split, fn, args){\n\t\tif (!fn._throttled){\n\t\t\tfn.apply(this, args);\n\t\t\tfn._throttled = setTimeout(function(){\n\t\t\t\tfn._throttled = false;\n\t\t\t}, split.value || 250);\n\t\t}\n\t},\n\n\tpause: function(split, fn, args){\n\t\tclearTimeout(fn._pause);\n\t\tfn._pause = fn.delay(split.value || 250, this, args);\n\t}\n\n};\n\nEvents.definePseudo = function(key, listener){\n\tpseudos[key] = listener;\n\treturn this;\n};\n\nEvents.lookupPseudo = function(key){\n\treturn pseudos[key];\n};\n\nvar proto = Events.prototype;\nEvents.implement(Events.Pseudos(pseudos, proto.addEvent, proto.removeEvent));\n\n['Request', 'Fx'].each(function(klass){\n\tif (this[klass]) this[klass].implement(Events.prototype);\n});\n\n})();\n\n\n/*\n---\n\nscript: Class.Refactor.js\n\nname: Class.Refactor\n\ndescription: Extends a class onto itself with new property, preserving any items attached to the class's namespace.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Class\n - /More\n\n# Some modules declare themselves dependent on Class.Refactor\nprovides: [Class.refactor, Class.Refactor]\n\n...\n*/\n\nClass.refactor = function(original, refactors){\n\n\tObject.each(refactors, function(item, name){\n\t\tvar origin = original.prototype[name];\n\t\torigin = (origin && origin.$origin) || origin || function(){};\n\t\toriginal.implement(name, (typeof item == 'function') ? function(){\n\t\t\tvar old = this.previous;\n\t\t\tthis.previous = origin;\n\t\t\tvar value = item.apply(this, arguments);\n\t\t\tthis.previous = old;\n\t\t\treturn value;\n\t\t} : item);\n\t});\n\n\treturn original;\n\n};\n\n\n/*\n---\n\nscript: Class.Binds.js\n\nname: Class.Binds\n\ndescription: Automagically binds specified methods in a class to the instance of the class.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Class\n - /More\n\nprovides: [Class.Binds]\n\n...\n*/\n\nClass.Mutators.Binds = function(binds){\n\tif (!this.prototype.initialize) this.implement('initialize', function(){});\n\treturn Array.from(binds).concat(this.prototype.Binds || []);\n};\n\nClass.Mutators.initialize = function(initialize){\n\treturn function(){\n\t\tArray.from(this.Binds).each(function(name){\n\t\t\tvar original = this[name];\n\t\t\tif (original) this[name] = original.bind(this);\n\t\t}, this);\n\t\treturn initialize.apply(this, arguments);\n\t};\n};\n\n\n/*\n---\n\nscript: Class.Occlude.js\n\nname: Class.Occlude\n\ndescription: Prevents a class from being applied to a DOM element twice.\n\nlicense: MIT-style license.\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Class\n - Core/Element\n - /More\n\nprovides: [Class.Occlude]\n\n...\n*/\n\nClass.Occlude = new Class({\n\n\tocclude: function(property, element){\n\t\telement = document.id(element || this.element);\n\t\tvar instance = element.retrieve(property || this.property);\n\t\tif (instance && !this.occluded)\n\t\t\treturn (this.occluded = instance);\n\n\t\tthis.occluded = false;\n\t\telement.store(property || this.property, this);\n\t\treturn this.occluded;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Chain.Wait.js\n\nname: Chain.Wait\n\ndescription: value, Adds a method to inject pauses between chained events.\n\nlicense: MIT-style license.\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Chain\n - Core/Element\n - Core/Fx\n - /More\n\nprovides: [Chain.Wait]\n\n...\n*/\n\n(function(){\n\n\tvar wait = {\n\t\twait: function(duration){\n\t\t\treturn this.chain(function(){\n\t\t\t\tthis.callChain.delay(duration == null ? 500 : duration, this);\n\t\t\t\treturn this;\n\t\t\t}.bind(this));\n\t\t}\n\t};\n\n\tChain.implement(wait);\n\n\tif (this.Fx) Fx.implement(wait);\n\n\tif (this.Element && Element.implement && this.Fx){\n\t\tElement.implement({\n\n\t\t\tchains: function(effects){\n\t\t\t\tArray.from(effects || ['tween', 'morph', 'reveal']).each(function(effect){\n\t\t\t\t\teffect = this.get(effect);\n\t\t\t\t\tif (!effect) return;\n\t\t\t\t\teffect.setOptions({\n\t\t\t\t\t\tlink:'chain'\n\t\t\t\t\t});\n\t\t\t\t}, this);\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\tpauseFx: function(duration, effect){\n\t\t\t\tthis.chains(effect).get(effect || 'tween').wait(duration);\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t});\n\t}\n\n})();\n\n\n/*\n---\n\nscript: Array.Extras.js\n\nname: Array.Extras\n\ndescription: Extends the Array native object to include useful methods to work with arrays.\n\nlicense: MIT-style license\n\nauthors:\n - Christoph Pojer\n - Sebastian Markbåge\n\nrequires:\n - Core/Array\n - More\n\nprovides: [Array.Extras]\n\n...\n*/\n\n(function(nil){\n\nArray.implement({\n\n\tmin: function(){\n\t\treturn Math.min.apply(null, this);\n\t},\n\n\tmax: function(){\n\t\treturn Math.max.apply(null, this);\n\t},\n\n\taverage: function(){\n\t\treturn this.length ? this.sum() / this.length : 0;\n\t},\n\n\tsum: function(){\n\t\tvar result = 0, l = this.length;\n\t\tif (l){\n\t\t\twhile (l--) result += this[l];\n\t\t}\n\t\treturn result;\n\t},\n\n\tunique: function(){\n\t\treturn [].combine(this);\n\t},\n\n\tshuffle: function(){\n\t\tfor (var i = this.length; i && --i;){\n\t\t\tvar temp = this[i], r = Math.floor(Math.random() * ( i + 1 ));\n\t\t\tthis[i] = this[r];\n\t\t\tthis[r] = temp;\n\t\t}\n\t\treturn this;\n\t},\n\n\treduce: function(fn, value){\n\t\tfor (var i = 0, l = this.length; i < l; i++){\n\t\t\tif (i in this) value = value === nil ? this[i] : fn.call(null, value, this[i], i, this);\n\t\t}\n\t\treturn value;\n\t},\n\n\treduceRight: function(fn, value){\n\t\tvar i = this.length;\n\t\twhile (i--){\n\t\t\tif (i in this) value = value === nil ? this[i] : fn.call(null, value, this[i], i, this);\n\t\t}\n\t\treturn value;\n\t}\n\n});\n\n})();\n\n\n/*\n---\n\nscript: Object.Extras.js\n\nname: Object.Extras\n\ndescription: Extra Object generics, like getFromPath which allows a path notation to child elements.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Object\n - /More\n\nprovides: [Object.Extras]\n\n...\n*/\n\n(function(){\n\nvar defined = function(value){\n\treturn value != null;\n};\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nObject.extend({\n\n\tgetFromPath: function(source, parts){\n\t\tif (typeof parts == 'string') parts = parts.split('.');\n\t\tfor (var i = 0, l = parts.length; i < l; i++){\n\t\t\tif (hasOwnProperty.call(source, parts[i])) source = source[parts[i]];\n\t\t\telse return null;\n\t\t}\n\t\treturn source;\n\t},\n\n\tcleanValues: function(object, method){\n\t\tmethod = method || defined;\n\t\tfor (var key in object) if (!method(object[key])){\n\t\t\tdelete object[key];\n\t\t}\n\t\treturn object;\n\t},\n\n\terase: function(object, key){\n\t\tif (hasOwnProperty.call(object, key)) delete object[key];\n\t\treturn object;\n\t},\n\n\trun: function(object){\n\t\tvar args = Array.slice(arguments, 1);\n\t\tfor (var key in object) if (object[key].apply){\n\t\t\tobject[key].apply(object, args);\n\t\t}\n\t\treturn object;\n\t}\n\n});\n\n})();\n\n\n/*\n---\n\nscript: Locale.js\n\nname: Locale\n\ndescription: Provides methods for localization.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n - Arian Stolwijk\n\nrequires:\n - Core/Events\n - /Object.Extras\n - /More\n\nprovides: [Locale, Lang]\n\n...\n*/\n\n(function(){\n\nvar current = null,\n\tlocales = {},\n\tinherits = {};\n\nvar getSet = function(set){\n\tif (instanceOf(set, Locale.Set)) return set;\n\telse return locales[set];\n};\n\nvar Locale = this.Locale = {\n\n\tdefine: function(locale, set, key, value){\n\t\tvar name;\n\t\tif (instanceOf(locale, Locale.Set)){\n\t\t\tname = locale.name;\n\t\t\tif (name) locales[name] = locale;\n\t\t} else {\n\t\t\tname = locale;\n\t\t\tif (!locales[name]) locales[name] = new Locale.Set(name);\n\t\t\tlocale = locales[name];\n\t\t}\n\n\t\tif (set) locale.define(set, key, value);\n\n\t\t\n\n\t\tif (!current) current = locale;\n\n\t\treturn locale;\n\t},\n\n\tuse: function(locale){\n\t\tlocale = getSet(locale);\n\n\t\tif (locale){\n\t\t\tcurrent = locale;\n\n\t\t\tthis.fireEvent('change', locale);\n\n\t\t\t\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tgetCurrent: function(){\n\t\treturn current;\n\t},\n\n\tget: function(key, args){\n\t\treturn (current) ? current.get(key, args) : '';\n\t},\n\n\tinherit: function(locale, inherits, set){\n\t\tlocale = getSet(locale);\n\n\t\tif (locale) locale.inherit(inherits, set);\n\t\treturn this;\n\t},\n\n\tlist: function(){\n\t\treturn Object.keys(locales);\n\t}\n\n};\n\nObject.append(Locale, new Events);\n\nLocale.Set = new Class({\n\n\tsets: {},\n\n\tinherits: {\n\t\tlocales: [],\n\t\tsets: {}\n\t},\n\n\tinitialize: function(name){\n\t\tthis.name = name || '';\n\t},\n\n\tdefine: function(set, key, value){\n\t\tvar defineData = this.sets[set];\n\t\tif (!defineData) defineData = {};\n\n\t\tif (key){\n\t\t\tif (typeOf(key) == 'object') defineData = Object.merge(defineData, key);\n\t\t\telse defineData[key] = value;\n\t\t}\n\t\tthis.sets[set] = defineData;\n\n\t\treturn this;\n\t},\n\n\tget: function(key, args, _base){\n\t\tvar value = Object.getFromPath(this.sets, key);\n\t\tif (value != null){\n\t\t\tvar type = typeOf(value);\n\t\t\tif (type == 'function') value = value.apply(null, Array.from(args));\n\t\t\telse if (type == 'object') value = Object.clone(value);\n\t\t\treturn value;\n\t\t}\n\n\t\t// get value of inherited locales\n\t\tvar index = key.indexOf('.'),\n\t\t\tset = index < 0 ? key : key.substr(0, index),\n\t\t\tnames = (this.inherits.sets[set] || []).combine(this.inherits.locales).include('en-US');\n\t\tif (!_base) _base = [];\n\n\t\tfor (var i = 0, l = names.length; i < l; i++){\n\t\t\tif (_base.contains(names[i])) continue;\n\t\t\t_base.include(names[i]);\n\n\t\t\tvar locale = locales[names[i]];\n\t\t\tif (!locale) continue;\n\n\t\t\tvalue = locale.get(key, args, _base);\n\t\t\tif (value != null) return value;\n\t\t}\n\n\t\treturn '';\n\t},\n\n\tinherit: function(names, set){\n\t\tnames = Array.from(names);\n\n\t\tif (set && !this.inherits.sets[set]) this.inherits.sets[set] = [];\n\n\t\tvar l = names.length;\n\t\twhile (l--) (set ? this.inherits.sets[set] : this.inherits.locales).unshift(names[l]);\n\n\t\treturn this;\n\t}\n\n});\n\n\n\n})();\n\n\n/*\n---\n\nname: Locale.en-US.Date\n\ndescription: Date messages for US English.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - /Locale\n\nprovides: [Locale.en-US.Date]\n\n...\n*/\n\nLocale.define('en-US', 'Date', {\n\n\tmonths: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n\tmonths_abbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n\tdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n\tdays_abbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n\n\t// Culture's date order: MM/DD/YYYY\n\tdateOrder: ['month', 'date', 'year'],\n\tshortDate: '%m/%d/%Y',\n\tshortTime: '%I:%M %p',\n\tAM: 'AM',\n\tPM: 'PM',\n\tfirstDayOfWeek: 0,\n\n\t// Date.Extras\n\tordinal: function(dayOfMonth){\n\t\t// 1st, 2nd, 3rd, etc.\n\t\treturn (dayOfMonth > 3 && dayOfMonth < 21) ? 'th' : ['th', 'st', 'nd', 'rd', 'th'][Math.min(dayOfMonth % 10, 4)];\n\t},\n\n\tlessThanMinuteAgo: 'less than a minute ago',\n\tminuteAgo: 'about a minute ago',\n\tminutesAgo: '{delta} minutes ago',\n\thourAgo: 'about an hour ago',\n\thoursAgo: 'about {delta} hours ago',\n\tdayAgo: '1 day ago',\n\tdaysAgo: '{delta} days ago',\n\tweekAgo: '1 week ago',\n\tweeksAgo: '{delta} weeks ago',\n\tmonthAgo: '1 month ago',\n\tmonthsAgo: '{delta} months ago',\n\tyearAgo: '1 year ago',\n\tyearsAgo: '{delta} years ago',\n\n\tlessThanMinuteUntil: 'less than a minute from now',\n\tminuteUntil: 'about a minute from now',\n\tminutesUntil: '{delta} minutes from now',\n\thourUntil: 'about an hour from now',\n\thoursUntil: 'about {delta} hours from now',\n\tdayUntil: '1 day from now',\n\tdaysUntil: '{delta} days from now',\n\tweekUntil: '1 week from now',\n\tweeksUntil: '{delta} weeks from now',\n\tmonthUntil: '1 month from now',\n\tmonthsUntil: '{delta} months from now',\n\tyearUntil: '1 year from now',\n\tyearsUntil: '{delta} years from now'\n\n});\n\n\n/*\n---\n\nscript: Date.js\n\nname: Date\n\ndescription: Extends the Date native object to include methods useful in managing dates.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n - Nicholas Barthelemy - https://svn.nbarthelemy.com/date-js/\n - Harald Kirshner - mail [at] digitarald.de; http://digitarald.de\n - Scott Kyle - scott [at] appden.com; http://appden.com\n\nrequires:\n - Core/Array\n - Core/String\n - Core/Number\n - More\n - Locale\n - Locale.en-US.Date\n\nprovides: [Date]\n\n...\n*/\n\n(function(){\n\nvar Date = this.Date;\n\nvar DateMethods = Date.Methods = {\n\tms: 'Milliseconds',\n\tyear: 'FullYear',\n\tmin: 'Minutes',\n\tmo: 'Month',\n\tsec: 'Seconds',\n\thr: 'Hours'\n};\n\n['Date', 'Day', 'FullYear', 'Hours', 'Milliseconds', 'Minutes', 'Month', 'Seconds', 'Time', 'TimezoneOffset',\n\t'Week', 'Timezone', 'GMTOffset', 'DayOfYear', 'LastMonth', 'LastDayOfMonth', 'UTCDate', 'UTCDay', 'UTCFullYear',\n\t'AMPM', 'Ordinal', 'UTCHours', 'UTCMilliseconds', 'UTCMinutes', 'UTCMonth', 'UTCSeconds', 'UTCMilliseconds'].each(function(method){\n\tDate.Methods[method.toLowerCase()] = method;\n});\n\nvar pad = function(n, digits, string){\n\tif (digits == 1) return n;\n\treturn n < Math.pow(10, digits - 1) ? (string || '0') + pad(n, digits - 1, string) : n;\n};\n\nDate.implement({\n\n\tset: function(prop, value){\n\t\tprop = prop.toLowerCase();\n\t\tvar method = DateMethods[prop] && 'set' + DateMethods[prop];\n\t\tif (method && this[method]) this[method](value);\n\t\treturn this;\n\t}.overloadSetter(),\n\n\tget: function(prop){\n\t\tprop = prop.toLowerCase();\n\t\tvar method = DateMethods[prop] && 'get' + DateMethods[prop];\n\t\tif (method && this[method]) return this[method]();\n\t\treturn null;\n\t}.overloadGetter(),\n\n\tclone: function(){\n\t\treturn new Date(this.get('time'));\n\t},\n\n\tincrement: function(interval, times){\n\t\tinterval = interval || 'day';\n\t\ttimes = times != null ? times : 1;\n\n\t\tswitch (interval){\n\t\t\tcase 'year':\n\t\t\t\treturn this.increment('month', times * 12);\n\t\t\tcase 'month':\n\t\t\t\tvar d = this.get('date');\n\t\t\t\tthis.set('date', 1).set('mo', this.get('mo') + times);\n\t\t\t\treturn this.set('date', d.min(this.get('lastdayofmonth')));\n\t\t\tcase 'week':\n\t\t\t\treturn this.increment('day', times * 7);\n\t\t\tcase 'day':\n\t\t\t\treturn this.set('date', this.get('date') + times);\n\t\t}\n\n\t\tif (!Date.units[interval]) throw new Error(interval + ' is not a supported interval');\n\n\t\treturn this.set('time', this.get('time') + times * Date.units[interval]());\n\t},\n\n\tdecrement: function(interval, times){\n\t\treturn this.increment(interval, -1 * (times != null ? times : 1));\n\t},\n\n\tisLeapYear: function(){\n\t\treturn Date.isLeapYear(this.get('year'));\n\t},\n\n\tclearTime: function(){\n\t\treturn this.set({hr: 0, min: 0, sec: 0, ms: 0});\n\t},\n\n\tdiff: function(date, resolution){\n\t\tif (typeOf(date) == 'string') date = Date.parse(date);\n\n\t\treturn ((date - this) / Date.units[resolution || 'day'](3, 3)).round(); // non-leap year, 30-day month\n\t},\n\n\tgetLastDayOfMonth: function(){\n\t\treturn Date.daysInMonth(this.get('mo'), this.get('year'));\n\t},\n\n\tgetDayOfYear: function(){\n\t\treturn (Date.UTC(this.get('year'), this.get('mo'), this.get('date') + 1)\n\t\t\t- Date.UTC(this.get('year'), 0, 1)) / Date.units.day();\n\t},\n\n\tsetDay: function(day, firstDayOfWeek){\n\t\tif (firstDayOfWeek == null){\n\t\t\tfirstDayOfWeek = Date.getMsg('firstDayOfWeek');\n\t\t\tif (firstDayOfWeek === '') firstDayOfWeek = 1;\n\t\t}\n\n\t\tday = (7 + Date.parseDay(day, true) - firstDayOfWeek) % 7;\n\t\tvar currentDay = (7 + this.get('day') - firstDayOfWeek) % 7;\n\n\t\treturn this.increment('day', day - currentDay);\n\t},\n\n\tgetWeek: function(firstDayOfWeek){\n\t\tif (firstDayOfWeek == null){\n\t\t\tfirstDayOfWeek = Date.getMsg('firstDayOfWeek');\n\t\t\tif (firstDayOfWeek === '') firstDayOfWeek = 1;\n\t\t}\n\n\t\tvar date = this,\n\t\t\tdayOfWeek = (7 + date.get('day') - firstDayOfWeek) % 7,\n\t\t\tdividend = 0,\n\t\t\tfirstDayOfYear;\n\n\t\tif (firstDayOfWeek == 1){\n\t\t\t// ISO-8601, week belongs to year that has the most days of the week (i.e. has the thursday of the week)\n\t\t\tvar month = date.get('month'),\n\t\t\t\tstartOfWeek = date.get('date') - dayOfWeek;\n\n\t\t\tif (month == 11 && startOfWeek > 28) return 1; // Week 1 of next year\n\n\t\t\tif (month == 0 && startOfWeek < -2){\n\t\t\t\t// Use a date from last year to determine the week\n\t\t\t\tdate = new Date(date).decrement('day', dayOfWeek);\n\t\t\t\tdayOfWeek = 0;\n\t\t\t}\n\n\t\t\tfirstDayOfYear = new Date(date.get('year'), 0, 1).get('day') || 7;\n\t\t\tif (firstDayOfYear > 4) dividend = -7; // First week of the year is not week 1\n\t\t} else {\n\t\t\t// In other cultures the first week of the year is always week 1 and the last week always 53 or 54.\n\t\t\t// Days in the same week can have a different weeknumber if the week spreads across two years.\n\t\t\tfirstDayOfYear = new Date(date.get('year'), 0, 1).get('day');\n\t\t}\n\n\t\tdividend += date.get('dayofyear');\n\t\tdividend += 6 - dayOfWeek; // Add days so we calculate the current date's week as a full week\n\t\tdividend += (7 + firstDayOfYear - firstDayOfWeek) % 7; // Make up for first week of the year not being a full week\n\n\t\treturn (dividend / 7);\n\t},\n\n\tgetOrdinal: function(day){\n\t\treturn Date.getMsg('ordinal', day || this.get('date'));\n\t},\n\n\tgetTimezone: function(){\n\t\treturn this.toString()\n\t\t\t.replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/, '$1')\n\t\t\t.replace(/^.*?\\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\\)$/, '$1$2$3');\n\t},\n\n\tgetGMTOffset: function(){\n\t\tvar off = this.get('timezoneOffset');\n\t\treturn ((off > 0) ? '-' : '+') + pad((off.abs() / 60).floor(), 2) + pad(off % 60, 2);\n\t},\n\n\tsetAMPM: function(ampm){\n\t\tampm = ampm.toUpperCase();\n\t\tvar hr = this.get('hr');\n\t\tif (hr > 11 && ampm == 'AM') return this.decrement('hour', 12);\n\t\telse if (hr < 12 && ampm == 'PM') return this.increment('hour', 12);\n\t\treturn this;\n\t},\n\n\tgetAMPM: function(){\n\t\treturn (this.get('hr') < 12) ? 'AM' : 'PM';\n\t},\n\n\tparse: function(str){\n\t\tthis.set('time', Date.parse(str));\n\t\treturn this;\n\t},\n\n\tisValid: function(date){\n\t\tif (!date) date = this;\n\t\treturn typeOf(date) == 'date' && !isNaN(date.valueOf());\n\t},\n\n\tformat: function(format){\n\t\tif (!this.isValid()) return 'invalid date';\n\n\t\tif (!format) format = '%x %X';\n\t\tif (typeof format == 'string') format = formats[format.toLowerCase()] || format;\n\t\tif (typeof format == 'function') return format(this);\n\n\t\tvar d = this;\n\t\treturn format.replace(/%([a-z%])/gi,\n\t\t\tfunction($0, $1){\n\t\t\t\tswitch ($1){\n\t\t\t\t\tcase 'a': return Date.getMsg('days_abbr')[d.get('day')];\n\t\t\t\t\tcase 'A': return Date.getMsg('days')[d.get('day')];\n\t\t\t\t\tcase 'b': return Date.getMsg('months_abbr')[d.get('month')];\n\t\t\t\t\tcase 'B': return Date.getMsg('months')[d.get('month')];\n\t\t\t\t\tcase 'c': return d.format('%a %b %d %H:%M:%S %Y');\n\t\t\t\t\tcase 'd': return pad(d.get('date'), 2);\n\t\t\t\t\tcase 'e': return pad(d.get('date'), 2, ' ');\n\t\t\t\t\tcase 'H': return pad(d.get('hr'), 2);\n\t\t\t\t\tcase 'I': return pad((d.get('hr') % 12) || 12, 2);\n\t\t\t\t\tcase 'j': return pad(d.get('dayofyear'), 3);\n\t\t\t\t\tcase 'k': return pad(d.get('hr'), 2, ' ');\n\t\t\t\t\tcase 'l': return pad((d.get('hr') % 12) || 12, 2, ' ');\n\t\t\t\t\tcase 'L': return pad(d.get('ms'), 3);\n\t\t\t\t\tcase 'm': return pad((d.get('mo') + 1), 2);\n\t\t\t\t\tcase 'M': return pad(d.get('min'), 2);\n\t\t\t\t\tcase 'o': return d.get('ordinal');\n\t\t\t\t\tcase 'p': return Date.getMsg(d.get('ampm'));\n\t\t\t\t\tcase 's': return Math.round(d / 1000);\n\t\t\t\t\tcase 'S': return pad(d.get('seconds'), 2);\n\t\t\t\t\tcase 'T': return d.format('%H:%M:%S');\n\t\t\t\t\tcase 'U': return pad(d.get('week'), 2);\n\t\t\t\t\tcase 'w': return d.get('day');\n\t\t\t\t\tcase 'x': return d.format(Date.getMsg('shortDate'));\n\t\t\t\t\tcase 'X': return d.format(Date.getMsg('shortTime'));\n\t\t\t\t\tcase 'y': return d.get('year').toString().substr(2);\n\t\t\t\t\tcase 'Y': return d.get('year');\n\t\t\t\t\tcase 'z': return d.get('GMTOffset');\n\t\t\t\t\tcase 'Z': return d.get('Timezone');\n\t\t\t\t}\n\t\t\t\treturn $1;\n\t\t\t}\n\t\t);\n\t},\n\n\ttoISOString: function(){\n\t\treturn this.format('iso8601');\n\t}\n\n}).alias({\n\ttoJSON: 'toISOString',\n\tcompare: 'diff',\n\tstrftime: 'format'\n});\n\n// The day and month abbreviations are standardized, so we cannot use simply %a and %b because they will get localized\nvar rfcDayAbbr = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n\trfcMonthAbbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\nvar formats = {\n\tdb: '%Y-%m-%d %H:%M:%S',\n\tcompact: '%Y%m%dT%H%M%S',\n\t'short': '%d %b %H:%M',\n\t'long': '%B %d, %Y %H:%M',\n\trfc822: function(date){\n\t\treturn rfcDayAbbr[date.get('day')] + date.format(', %d ') + rfcMonthAbbr[date.get('month')] + date.format(' %Y %H:%M:%S %Z');\n\t},\n\trfc2822: function(date){\n\t\treturn rfcDayAbbr[date.get('day')] + date.format(', %d ') + rfcMonthAbbr[date.get('month')] + date.format(' %Y %H:%M:%S %z');\n\t},\n\tiso8601: function(date){\n\t\treturn (\n\t\t\tdate.getUTCFullYear() + '-' +\n\t\t\tpad(date.getUTCMonth() + 1, 2) + '-' +\n\t\t\tpad(date.getUTCDate(), 2) + 'T' +\n\t\t\tpad(date.getUTCHours(), 2) + ':' +\n\t\t\tpad(date.getUTCMinutes(), 2) + ':' +\n\t\t\tpad(date.getUTCSeconds(), 2) + '.' +\n\t\t\tpad(date.getUTCMilliseconds(), 3) + 'Z'\n\t\t);\n\t}\n};\n\nvar parsePatterns = [],\n\tnativeParse = Date.parse;\n\nvar parseWord = function(type, word, num){\n\tvar ret = -1,\n\t\ttranslated = Date.getMsg(type + 's');\n\tswitch (typeOf(word)){\n\t\tcase 'object':\n\t\t\tret = translated[word.get(type)];\n\t\t\tbreak;\n\t\tcase 'number':\n\t\t\tret = translated[word];\n\t\t\tif (!ret) throw new Error('Invalid ' + type + ' index: ' + word);\n\t\t\tbreak;\n\t\tcase 'string':\n\t\t\tvar match = translated.filter(function(name){\n\t\t\t\treturn this.test(name);\n\t\t\t}, new RegExp('^' + word, 'i'));\n\t\t\tif (!match.length) throw new Error('Invalid ' + type + ' string');\n\t\t\tif (match.length > 1) throw new Error('Ambiguous ' + type);\n\t\t\tret = match[0];\n\t}\n\n\treturn (num) ? translated.indexOf(ret) : ret;\n};\n\nvar startCentury = 1900,\n\tstartYear = 70;\n\nDate.extend({\n\n\tgetMsg: function(key, args){\n\t\treturn Locale.get('Date.' + key, args);\n\t},\n\n\tunits: {\n\t\tms: Function.from(1),\n\t\tsecond: Function.from(1000),\n\t\tminute: Function.from(60000),\n\t\thour: Function.from(3600000),\n\t\tday: Function.from(86400000),\n\t\tweek: Function.from(608400000),\n\t\tmonth: function(month, year){\n\t\t\tvar d = new Date;\n\t\t\treturn Date.daysInMonth(month != null ? month : d.get('mo'), year != null ? year : d.get('year')) * 86400000;\n\t\t},\n\t\tyear: function(year){\n\t\t\tyear = year || new Date().get('year');\n\t\t\treturn Date.isLeapYear(year) ? 31622400000 : 31536000000;\n\t\t}\n\t},\n\n\tdaysInMonth: function(month, year){\n\t\treturn [31, Date.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n\t},\n\n\tisLeapYear: function(year){\n\t\treturn ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);\n\t},\n\n\tparse: function(from){\n\t\tvar t = typeOf(from);\n\t\tif (t == 'number') return new Date(from);\n\t\tif (t != 'string') return from;\n\t\tfrom = from.clean();\n\t\tif (!from.length) return null;\n\n\t\tvar parsed;\n\t\tparsePatterns.some(function(pattern){\n\t\t\tvar bits = pattern.re.exec(from);\n\t\t\treturn (bits) ? (parsed = pattern.handler(bits)) : false;\n\t\t});\n\n\t\tif (!(parsed && parsed.isValid())){\n\t\t\tparsed = new Date(nativeParse(from));\n\t\t\tif (!(parsed && parsed.isValid())) parsed = new Date(from.toInt());\n\t\t}\n\t\treturn parsed;\n\t},\n\n\tparseDay: function(day, num){\n\t\treturn parseWord('day', day, num);\n\t},\n\n\tparseMonth: function(month, num){\n\t\treturn parseWord('month', month, num);\n\t},\n\n\tparseUTC: function(value){\n\t\tvar localDate = new Date(value);\n\t\tvar utcSeconds = Date.UTC(\n\t\t\tlocalDate.get('year'),\n\t\t\tlocalDate.get('mo'),\n\t\t\tlocalDate.get('date'),\n\t\t\tlocalDate.get('hr'),\n\t\t\tlocalDate.get('min'),\n\t\t\tlocalDate.get('sec'),\n\t\t\tlocalDate.get('ms')\n\t\t);\n\t\treturn new Date(utcSeconds);\n\t},\n\n\torderIndex: function(unit){\n\t\treturn Date.getMsg('dateOrder').indexOf(unit) + 1;\n\t},\n\n\tdefineFormat: function(name, format){\n\t\tformats[name] = format;\n\t\treturn this;\n\t},\n\n\t\n\n\tdefineParser: function(pattern){\n\t\tparsePatterns.push((pattern.re && pattern.handler) ? pattern : build(pattern));\n\t\treturn this;\n\t},\n\n\tdefineParsers: function(){\n\t\tArray.flatten(arguments).each(Date.defineParser);\n\t\treturn this;\n\t},\n\n\tdefine2DigitYearStart: function(year){\n\t\tstartYear = year % 100;\n\t\tstartCentury = year - startYear;\n\t\treturn this;\n\t}\n\n}).extend({\n\tdefineFormats: Date.defineFormat.overloadSetter()\n});\n\nvar regexOf = function(type){\n\treturn new RegExp('(?:' + Date.getMsg(type).map(function(name){\n\t\treturn name.substr(0, 3);\n\t}).join('|') + ')[a-z]*');\n};\n\nvar replacers = function(key){\n\tswitch (key){\n\t\tcase 'T':\n\t\t\treturn '%H:%M:%S';\n\t\tcase 'x': // iso8601 covers yyyy-mm-dd, so just check if month is first\n\t\t\treturn ((Date.orderIndex('month') == 1) ? '%m[-./]%d' : '%d[-./]%m') + '([-./]%y)?';\n\t\tcase 'X':\n\t\t\treturn '%H([.:]%M)?([.:]%S([.:]%s)?)? ?%p? ?%z?';\n\t}\n\treturn null;\n};\n\nvar keys = {\n\td: /[0-2]?[0-9]|3[01]/,\n\tH: /[01]?[0-9]|2[0-3]/,\n\tI: /0?[1-9]|1[0-2]/,\n\tM: /[0-5]?\\d/,\n\ts: /\\d+/,\n\to: /[a-z]*/,\n\tp: /[ap]\\.?m\\.?/,\n\ty: /\\d{2}|\\d{4}/,\n\tY: /\\d{4}/,\n\tz: /Z|[+-]\\d{2}(?::?\\d{2})?/\n};\n\nkeys.m = keys.I;\nkeys.S = keys.M;\n\nvar currentLanguage;\n\nvar recompile = function(language){\n\tcurrentLanguage = language;\n\n\tkeys.a = keys.A = regexOf('days');\n\tkeys.b = keys.B = regexOf('months');\n\n\tparsePatterns.each(function(pattern, i){\n\t\tif (pattern.format) parsePatterns[i] = build(pattern.format);\n\t});\n};\n\nvar build = function(format){\n\tif (!currentLanguage) return {format: format};\n\n\tvar parsed = [];\n\tvar re = (format.source || format) // allow format to be regex\n\t .replace(/%([a-z])/gi,\n\t\tfunction($0, $1){\n\t\t\treturn replacers($1) || $0;\n\t\t}\n\t).replace(/\\((?!\\?)/g, '(?:') // make all groups non-capturing\n\t .replace(/ (?!\\?|\\*)/g, ',? ') // be forgiving with spaces and commas\n\t .replace(/%([a-z%])/gi,\n\t\tfunction($0, $1){\n\t\t\tvar p = keys[$1];\n\t\t\tif (!p) return $1;\n\t\t\tparsed.push($1);\n\t\t\treturn '(' + p.source + ')';\n\t\t}\n\t).replace(/\\[a-z\\]/gi, '[a-z\\\\u00c0-\\\\uffff;\\&]'); // handle unicode words\n\n\treturn {\n\t\tformat: format,\n\t\tre: new RegExp('^' + re + '$', 'i'),\n\t\thandler: function(bits){\n\t\t\tbits = bits.slice(1).associate(parsed);\n\t\t\tvar date = new Date().clearTime(),\n\t\t\t\tyear = bits.y || bits.Y;\n\n\t\t\tif (year != null) handle.call(date, 'y', year); // need to start in the right year\n\t\t\tif ('d' in bits) handle.call(date, 'd', 1);\n\t\t\tif ('m' in bits || bits.b || bits.B) handle.call(date, 'm', 1);\n\n\t\t\tfor (var key in bits) handle.call(date, key, bits[key]);\n\t\t\treturn date;\n\t\t}\n\t};\n};\n\nvar handle = function(key, value){\n\tif (!value) return this;\n\n\tswitch (key){\n\t\tcase 'a': case 'A': return this.set('day', Date.parseDay(value, true));\n\t\tcase 'b': case 'B': return this.set('mo', Date.parseMonth(value, true));\n\t\tcase 'd': return this.set('date', value);\n\t\tcase 'H': case 'I': return this.set('hr', value);\n\t\tcase 'm': return this.set('mo', value - 1);\n\t\tcase 'M': return this.set('min', value);\n\t\tcase 'p': return this.set('ampm', value.replace(/\\./g, ''));\n\t\tcase 'S': return this.set('sec', value);\n\t\tcase 's': return this.set('ms', ('0.' + value) * 1000);\n\t\tcase 'w': return this.set('day', value);\n\t\tcase 'Y': return this.set('year', value);\n\t\tcase 'y':\n\t\t\tvalue = +value;\n\t\t\tif (value < 100) value += startCentury + (value < startYear ? 100 : 0);\n\t\t\treturn this.set('year', value);\n\t\tcase 'z':\n\t\t\tif (value == 'Z') value = '+00';\n\t\t\tvar offset = value.match(/([+-])(\\d{2}):?(\\d{2})?/);\n\t\t\toffset = (offset[1] + '1') * (offset[2] * 60 + (+offset[3] || 0)) + this.getTimezoneOffset();\n\t\t\treturn this.set('time', this - offset * 60000);\n\t}\n\n\treturn this;\n};\n\nDate.defineParsers(\n\t'%Y([-./]%m([-./]%d((T| )%X)?)?)?', // \"1999-12-31\", \"1999-12-31 11:59pm\", \"1999-12-31 23:59:59\", ISO8601\n\t'%Y%m%d(T%H(%M%S?)?)?', // \"19991231\", \"19991231T1159\", compact\n\t'%x( %X)?', // \"12/31\", \"12.31.99\", \"12-31-1999\", \"12/31/2008 11:59 PM\"\n\t'%d%o( %b( %Y)?)?( %X)?', // \"31st\", \"31st December\", \"31 Dec 1999\", \"31 Dec 1999 11:59pm\"\n\t'%b( %d%o)?( %Y)?( %X)?', // Same as above with month and day switched\n\t'%Y %b( %d%o( %X)?)?', // Same as above with year coming first\n\t'%o %b %d %X %z %Y', // \"Thu Oct 22 08:11:23 +0000 2009\"\n\t'%T', // %H:%M:%S\n\t'%H:%M( ?%p)?' // \"11:05pm\", \"11:05 am\" and \"11:05\"\n);\n\nLocale.addEvent('change', function(language){\n\tif (Locale.get('Date')) recompile(language);\n}).fireEvent('change', Locale.getCurrent());\n\n})();\n\n\n/*\n---\n\nscript: Date.Extras.js\n\nname: Date.Extras\n\ndescription: Extends the Date native object to include extra methods (on top of those in Date.js).\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n - Scott Kyle\n\nrequires:\n - /Date\n\nprovides: [Date.Extras]\n\n...\n*/\n\nDate.implement({\n\n\ttimeDiffInWords: function(to){\n\t\treturn Date.distanceOfTimeInWords(this, to || new Date);\n\t},\n\n\ttimeDiff: function(to, separator){\n\t\tif (to == null) to = new Date;\n\t\tvar delta = ((to - this) / 1000).floor().abs();\n\n\t\tvar vals = [],\n\t\t\tdurations = [60, 60, 24, 365, 0],\n\t\t\tnames = ['s', 'm', 'h', 'd', 'y'],\n\t\t\tvalue, duration;\n\n\t\tfor (var item = 0; item < durations.length; item++){\n\t\t\tif (item && !delta) break;\n\t\t\tvalue = delta;\n\t\t\tif ((duration = durations[item])){\n\t\t\t\tvalue = (delta % duration);\n\t\t\t\tdelta = (delta / duration).floor();\n\t\t\t}\n\t\t\tvals.unshift(value + (names[item] || ''));\n\t\t}\n\n\t\treturn vals.join(separator || ':');\n\t}\n\n}).extend({\n\n\tdistanceOfTimeInWords: function(from, to){\n\t\treturn Date.getTimePhrase(((to - from) / 1000).toInt());\n\t},\n\n\tgetTimePhrase: function(delta){\n\t\tvar suffix = (delta < 0) ? 'Until' : 'Ago';\n\t\tif (delta < 0) delta *= -1;\n\n\t\tvar units = {\n\t\t\tminute: 60,\n\t\t\thour: 60,\n\t\t\tday: 24,\n\t\t\tweek: 7,\n\t\t\tmonth: 52 / 12,\n\t\t\tyear: 12,\n\t\t\teon: Infinity\n\t\t};\n\n\t\tvar msg = 'lessThanMinute';\n\n\t\tfor (var unit in units){\n\t\t\tvar interval = units[unit];\n\t\t\tif (delta < 1.5 * interval){\n\t\t\t\tif (delta > 0.75 * interval) msg = unit;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdelta /= interval;\n\t\t\tmsg = unit + 's';\n\t\t}\n\n\t\tdelta = delta.round();\n\t\treturn Date.getMsg(msg + suffix, delta).substitute({delta: delta});\n\t}\n\n}).defineParsers(\n\n\t{\n\t\t// \"today\", \"tomorrow\", \"yesterday\"\n\t\tre: /^(?:tod|tom|yes)/i,\n\t\thandler: function(bits){\n\t\t\tvar d = new Date().clearTime();\n\t\t\tswitch (bits[0]){\n\t\t\t\tcase 'tom': return d.increment();\n\t\t\t\tcase 'yes': return d.decrement();\n\t\t\t\tdefault: return d;\n\t\t\t}\n\t\t}\n\t},\n\n\t{\n\t\t// \"next Wednesday\", \"last Thursday\"\n\t\tre: /^(next|last) ([a-z]+)$/i,\n\t\thandler: function(bits){\n\t\t\tvar d = new Date().clearTime();\n\t\t\tvar day = d.getDay();\n\t\t\tvar newDay = Date.parseDay(bits[2], true);\n\t\t\tvar addDays = newDay - day;\n\t\t\tif (newDay <= day) addDays += 7;\n\t\t\tif (bits[1] == 'last') addDays -= 7;\n\t\t\treturn d.set('date', d.getDate() + addDays);\n\t\t}\n\t}\n\n).alias('timeAgoInWords', 'timeDiffInWords');\n\n\n/*\n---\n\nname: Locale.en-US.Number\n\ndescription: Number messages for US English.\n\nlicense: MIT-style license\n\nauthors:\n - Arian Stolwijk\n\nrequires:\n - /Locale\n\nprovides: [Locale.en-US.Number]\n\n...\n*/\n\nLocale.define('en-US', 'Number', {\n\n\tdecimal: '.',\n\tgroup: ',',\n\n/* \tCommented properties are the defaults for Number.format\n\tdecimals: 0,\n\tprecision: 0,\n\tscientific: null,\n\n\tprefix: null,\n\tsuffic: null,\n\n\t// Negative/Currency/percentage will mixin Number\n\tnegative: {\n\t\tprefix: '-'\n\t},*/\n\n\tcurrency: {\n//\t\tdecimals: 2,\n\t\tprefix: '$ '\n\t}/*,\n\n\tpercentage: {\n\t\tdecimals: 2,\n\t\tsuffix: '%'\n\t}*/\n\n});\n\n\n\n\n/*\n---\nname: Number.Format\ndescription: Extends the Number Type object to include a number formatting method.\nlicense: MIT-style license\nauthors: [Arian Stolwijk]\nrequires: [Core/Number, Locale.en-US.Number]\n# Number.Extras is for compatibility\nprovides: [Number.Format, Number.Extras]\n...\n*/\n\n\nNumber.implement({\n\n\tformat: function(options){\n\t\t// Thanks dojo and YUI for some inspiration\n\t\tvar value = this;\n\t\toptions = options ? Object.clone(options) : {};\n\t\tvar getOption = function(key){\n\t\t\tif (options[key] != null) return options[key];\n\t\t\treturn Locale.get('Number.' + key);\n\t\t};\n\n\t\tvar negative = value < 0,\n\t\t\tdecimal = getOption('decimal'),\n\t\t\tprecision = getOption('precision'),\n\t\t\tgroup = getOption('group'),\n\t\t\tdecimals = getOption('decimals');\n\n\t\tif (negative){\n\t\t\tvar negativeLocale = getOption('negative') || {};\n\t\t\tif (negativeLocale.prefix == null && negativeLocale.suffix == null) negativeLocale.prefix = '-';\n\t\t\t['prefix', 'suffix'].each(function(key){\n\t\t\t\tif (negativeLocale[key]) options[key] = getOption(key) + negativeLocale[key];\n\t\t\t});\n\n\t\t\tvalue = -value;\n\t\t}\n\n\t\tvar prefix = getOption('prefix'),\n\t\t\tsuffix = getOption('suffix');\n\n\t\tif (decimals !== '' && decimals >= 0 && decimals <= 20) value = value.toFixed(decimals);\n\t\tif (precision >= 1 && precision <= 21) value = (+value).toPrecision(precision);\n\n\t\tvalue += '';\n\t\tvar index;\n\t\tif (getOption('scientific') === false && value.indexOf('e') > -1){\n\t\t\tvar match = value.split('e'),\n\t\t\t\tzeros = +match[1];\n\t\t\tvalue = match[0].replace('.', '');\n\n\t\t\tif (zeros < 0){\n\t\t\t\tzeros = -zeros - 1;\n\t\t\t\tindex = match[0].indexOf('.');\n\t\t\t\tif (index > -1) zeros -= index - 1;\n\t\t\t\twhile (zeros--) value = '0' + value;\n\t\t\t\tvalue = '0.' + value;\n\t\t\t} else {\n\t\t\t\tindex = match[0].lastIndexOf('.');\n\t\t\t\tif (index > -1) zeros -= match[0].length - index - 1;\n\t\t\t\twhile (zeros--) value += '0';\n\t\t\t}\n\t\t}\n\n\t\tif (decimal != '.') value = value.replace('.', decimal);\n\n\t\tif (group){\n\t\t\tindex = value.lastIndexOf(decimal);\n\t\t\tindex = (index > -1) ? index : value.length;\n\t\t\tvar newOutput = value.substring(index),\n\t\t\t\ti = index;\n\n\t\t\twhile (i--){\n\t\t\t\tif ((index - i - 1) % 3 == 0 && i != (index - 1)) newOutput = group + newOutput;\n\t\t\t\tnewOutput = value.charAt(i) + newOutput;\n\t\t\t}\n\n\t\t\tvalue = newOutput;\n\t\t}\n\n\t\tif (prefix) value = prefix + value;\n\t\tif (suffix) value += suffix;\n\n\t\treturn value;\n\t},\n\n\tformatCurrency: function(decimals){\n\t\tvar locale = Locale.get('Number.currency') || {};\n\t\tif (locale.scientific == null) locale.scientific = false;\n\t\tlocale.decimals = decimals != null ? decimals\n\t\t\t: (locale.decimals == null ? 2 : locale.decimals);\n\n\t\treturn this.format(locale);\n\t},\n\n\tformatPercentage: function(decimals){\n\t\tvar locale = Locale.get('Number.percentage') || {};\n\t\tif (locale.suffix == null) locale.suffix = '%';\n\t\tlocale.decimals = decimals != null ? decimals\n\t\t\t: (locale.decimals == null ? 2 : locale.decimals);\n\n\t\treturn this.format(locale);\n\t}\n\n});\n\n\n/*\n---\n\nscript: String.Extras.js\n\nname: String.Extras\n\ndescription: Extends the String native object to include methods useful in managing various kinds of strings (query strings, urls, html, etc).\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n - Guillermo Rauch\n - Christopher Pitt\n\nrequires:\n - Core/String\n - Core/Array\n - More\n\nprovides: [String.Extras]\n\n...\n*/\n\n(function(){\n\nvar special = {\n\t'a': /[àáâãäåăą]/g,\n\t'A': /[ÀÁÂÃÄÅĂĄ]/g,\n\t'c': /[ćčç]/g,\n\t'C': /[ĆČÇ]/g,\n\t'd': /[ďđ]/g,\n\t'D': /[ĎÐ]/g,\n\t'e': /[èéêëěę]/g,\n\t'E': /[ÈÉÊËĚĘ]/g,\n\t'g': /[ğ]/g,\n\t'G': /[Ğ]/g,\n\t'i': /[ìíîï]/g,\n\t'I': /[ÌÍÎÏ]/g,\n\t'l': /[ĺľł]/g,\n\t'L': /[ĹĽŁ]/g,\n\t'n': /[ñňń]/g,\n\t'N': /[ÑŇŃ]/g,\n\t'o': /[òóôõöøő]/g,\n\t'O': /[ÒÓÔÕÖØ]/g,\n\t'r': /[řŕ]/g,\n\t'R': /[ŘŔ]/g,\n\t's': /[ššş]/g,\n\t'S': /[ŠŞŚ]/g,\n\t't': /[ťţ]/g,\n\t'T': /[ŤŢ]/g,\n\t'ue': /[ü]/g,\n\t'UE': /[Ü]/g,\n\t'u': /[ùúûůµ]/g,\n\t'U': /[ÙÚÛŮ]/g,\n\t'y': /[ÿý]/g,\n\t'Y': /[ŸÝ]/g,\n\t'z': /[žźż]/g,\n\t'Z': /[ŽŹŻ]/g,\n\t'th': /[þ]/g,\n\t'TH': /[Þ]/g,\n\t'dh': /[ð]/g,\n\t'DH': /[Ð]/g,\n\t'ss': /[ß]/g,\n\t'oe': /[œ]/g,\n\t'OE': /[Œ]/g,\n\t'ae': /[æ]/g,\n\t'AE': /[Æ]/g\n},\n\ntidy = {\n\t' ': /[\\xa0\\u2002\\u2003\\u2009]/g,\n\t'*': /[\\xb7]/g,\n\t'\\'': /[\\u2018\\u2019]/g,\n\t'\"': /[\\u201c\\u201d]/g,\n\t'...': /[\\u2026]/g,\n\t'-': /[\\u2013]/g,\n//\t'--': /[\\u2014]/g,\n\t'»': /[\\uFFFD]/g\n};\n\nvar walk = function(string, replacements){\n\tvar result = string, key;\n\tfor (key in replacements) result = result.replace(replacements[key], key);\n\treturn result;\n};\n\nvar getRegexForTag = function(tag, contents){\n\ttag = tag || '';\n\tvar regstr = contents ? \"<\" + tag + \"(?!\\\\w)[^>]*>([\\\\s\\\\S]*?)<\\/\" + tag + \"(?!\\\\w)>\" : \"<\\/?\" + tag + \"([^>]+)?>\",\n\t\treg = new RegExp(regstr, \"gi\");\n\treturn reg;\n};\n\nString.implement({\n\n\tstandardize: function(){\n\t\treturn walk(this, special);\n\t},\n\n\trepeat: function(times){\n\t\treturn new Array(times + 1).join(this);\n\t},\n\n\tpad: function(length, str, direction){\n\t\tif (this.length >= length) return this;\n\n\t\tvar pad = (str == null ? ' ' : '' + str)\n\t\t\t.repeat(length - this.length)\n\t\t\t.substr(0, length - this.length);\n\n\t\tif (!direction || direction == 'right') return this + pad;\n\t\tif (direction == 'left') return pad + this;\n\n\t\treturn pad.substr(0, (pad.length / 2).floor()) + this + pad.substr(0, (pad.length / 2).ceil());\n\t},\n\n\tgetTags: function(tag, contents){\n\t\treturn this.match(getRegexForTag(tag, contents)) || [];\n\t},\n\n\tstripTags: function(tag, contents){\n\t\treturn this.replace(getRegexForTag(tag, contents), '');\n\t},\n\n\ttidy: function(){\n\t\treturn walk(this, tidy);\n\t},\n\n\ttruncate: function(max, trail, atChar){\n\t\tvar string = this;\n\t\tif (trail == null && arguments.length == 1) trail = '…';\n\t\tif (string.length > max){\n\t\t\tstring = string.substring(0, max);\n\t\t\tif (atChar){\n\t\t\t\tvar index = string.lastIndexOf(atChar);\n\t\t\t\tif (index != -1) string = string.substr(0, index);\n\t\t\t}\n\t\t\tif (trail) string += trail;\n\t\t}\n\t\treturn string;\n\t}\n\n});\n\n})();\n\n\n/*\n---\n\nscript: String.QueryString.js\n\nname: String.QueryString\n\ndescription: Methods for dealing with URI query strings.\n\nlicense: MIT-style license\n\nauthors:\n - Sebastian Markbåge\n - Aaron Newton\n - Lennart Pilon\n - Valerio Proietti\n\nrequires:\n - Core/Array\n - Core/String\n - /More\n\nprovides: [String.QueryString]\n\n...\n*/\n\nString.implement({\n\n\tparseQueryString: function(decodeKeys, decodeValues){\n\t\tif (decodeKeys == null) decodeKeys = true;\n\t\tif (decodeValues == null) decodeValues = true;\n\n\t\tvar vars = this.split(/[&;]/),\n\t\t\tobject = {};\n\t\tif (!vars.length) return object;\n\n\t\tvars.each(function(val){\n\t\t\tvar index = val.indexOf('=') + 1,\n\t\t\t\tvalue = index ? val.substr(index) : '',\n\t\t\t\tkeys = index ? val.substr(0, index - 1).match(/([^\\]\\[]+|(\\B)(?=\\]))/g) : [val],\n\t\t\t\tobj = object;\n\t\t\tif (!keys) return;\n\t\t\tif (decodeValues) value = decodeURIComponent(value);\n\t\t\tkeys.each(function(key, i){\n\t\t\t\tif (decodeKeys) key = decodeURIComponent(key);\n\t\t\t\tvar current = obj[key];\n\n\t\t\t\tif (i < keys.length - 1) obj = obj[key] = current || {};\n\t\t\t\telse if (typeOf(current) == 'array') current.push(value);\n\t\t\t\telse obj[key] = current != null ? [current, value] : value;\n\t\t\t});\n\t\t});\n\n\t\treturn object;\n\t},\n\n\tcleanQueryString: function(method){\n\t\treturn this.split('&').filter(function(val){\n\t\t\tvar index = val.indexOf('='),\n\t\t\t\tkey = index < 0 ? '' : val.substr(0, index),\n\t\t\t\tvalue = val.substr(index + 1);\n\n\t\t\treturn method ? method.call(null, key, value) : (value || value === 0);\n\t\t}).join('&');\n\t}\n\n});\n\n\n/*\n---\n\nscript: URI.js\n\nname: URI\n\ndescription: Provides methods useful in managing the window location and uris.\n\nlicense: MIT-style license\n\nauthors:\n - Sebastian Markbåge\n - Aaron Newton\n\nrequires:\n - Core/Object\n - Core/Class\n - Core/Class.Extras\n - Core/Element\n - /String.QueryString\n\nprovides: [URI]\n\n...\n*/\n\n(function(){\n\nvar toString = function(){\n\treturn this.get('value');\n};\n\nvar URI = this.URI = new Class({\n\n\tImplements: Options,\n\n\toptions: {\n\t\t/*base: false*/\n\t},\n\n\tregex: /^(?:(\\w+):)?(?:\\/\\/(?:(?:([^:@\\/]*):?([^:@\\/]*))?@)?([^:\\/?#]*)(?::(\\d*))?)?(\\.\\.?$|(?:[^?#\\/]*\\/)*)([^?#]*)(?:\\?([^#]*))?(?:#(.*))?/,\n\tparts: ['scheme', 'user', 'password', 'host', 'port', 'directory', 'file', 'query', 'fragment'],\n\tschemes: {http: 80, https: 443, ftp: 21, rtsp: 554, mms: 1755, file: 0},\n\n\tinitialize: function(uri, options){\n\t\tthis.setOptions(options);\n\t\tvar base = this.options.base || URI.base;\n\t\tif (!uri) uri = base;\n\n\t\tif (uri && uri.parsed) this.parsed = Object.clone(uri.parsed);\n\t\telse this.set('value', uri.href || uri.toString(), base ? new URI(base) : false);\n\t},\n\n\tparse: function(value, base){\n\t\tvar bits = value.match(this.regex);\n\t\tif (!bits) return false;\n\t\tbits.shift();\n\t\treturn this.merge(bits.associate(this.parts), base);\n\t},\n\n\tmerge: function(bits, base){\n\t\tif ((!bits || !bits.scheme) && (!base || !base.scheme)) return false;\n\t\tif (base){\n\t\t\tthis.parts.every(function(part){\n\t\t\t\tif (bits[part]) return false;\n\t\t\t\tbits[part] = base[part] || '';\n\t\t\t\treturn true;\n\t\t\t});\n\t\t}\n\t\tbits.port = bits.port || this.schemes[bits.scheme.toLowerCase()];\n\t\tbits.directory = bits.directory ? this.parseDirectory(bits.directory, base ? base.directory : '') : '/';\n\t\treturn bits;\n\t},\n\n\tparseDirectory: function(directory, baseDirectory){\n\t\tdirectory = (directory.substr(0, 1) == '/' ? '' : (baseDirectory || '/')) + directory;\n\t\tif (!directory.test(URI.regs.directoryDot)) return directory;\n\t\tvar result = [];\n\t\tdirectory.replace(URI.regs.endSlash, '').split('/').each(function(dir){\n\t\t\tif (dir == '..' && result.length > 0) result.pop();\n\t\t\telse if (dir != '.') result.push(dir);\n\t\t});\n\t\treturn result.join('/') + '/';\n\t},\n\n\tcombine: function(bits){\n\t\treturn bits.value || bits.scheme + '://' +\n\t\t\t(bits.user ? bits.user + (bits.password ? ':' + bits.password : '') + '@' : '') +\n\t\t\t(bits.host || '') + (bits.port && bits.port != this.schemes[bits.scheme] ? ':' + bits.port : '') +\n\t\t\t(bits.directory || '/') + (bits.file || '') +\n\t\t\t(bits.query ? '?' + bits.query : '') +\n\t\t\t(bits.fragment ? '#' + bits.fragment : '');\n\t},\n\n\tset: function(part, value, base){\n\t\tif (part == 'value'){\n\t\t\tvar scheme = value.match(URI.regs.scheme);\n\t\t\tif (scheme) scheme = scheme[1];\n\t\t\tif (scheme && this.schemes[scheme.toLowerCase()] == null) this.parsed = { scheme: scheme, value: value };\n\t\t\telse this.parsed = this.parse(value, (base || this).parsed) || (scheme ? { scheme: scheme, value: value } : { value: value });\n\t\t} else if (part == 'data'){\n\t\t\tthis.setData(value);\n\t\t} else {\n\t\t\tthis.parsed[part] = value;\n\t\t}\n\t\treturn this;\n\t},\n\n\tget: function(part, base){\n\t\tswitch (part){\n\t\t\tcase 'value': return this.combine(this.parsed, base ? base.parsed : false);\n\t\t\tcase 'data' : return this.getData();\n\t\t}\n\t\treturn this.parsed[part] || '';\n\t},\n\n\tgo: function(){\n\t\tdocument.location.href = this.toString();\n\t},\n\n\ttoURI: function(){\n\t\treturn this;\n\t},\n\n\tgetData: function(key, part){\n\t\tvar qs = this.get(part || 'query');\n\t\tif (!(qs || qs === 0)) return key ? null : {};\n\t\tvar obj = qs.parseQueryString();\n\t\treturn key ? obj[key] : obj;\n\t},\n\n\tsetData: function(values, merge, part){\n\t\tif (typeof values == 'string'){\n\t\t\tvar data = this.getData();\n\t\t\tdata[arguments[0]] = arguments[1];\n\t\t\tvalues = data;\n\t\t} else if (merge){\n\t\t\tvalues = Object.merge(this.getData(), values);\n\t\t}\n\t\treturn this.set(part || 'query', Object.toQueryString(values));\n\t},\n\n\tclearData: function(part){\n\t\treturn this.set(part || 'query', '');\n\t},\n\n\ttoString: toString,\n\tvalueOf: toString\n\n});\n\nURI.regs = {\n\tendSlash: /\\/$/,\n\tscheme: /^(\\w+):/,\n\tdirectoryDot: /\\.\\/|\\.$/\n};\n\nURI.base = new URI(Array.from(document.getElements('base[href]', true)).getLast(), {base: document.location});\n\nString.implement({\n\n\ttoURI: function(options){\n\t\treturn new URI(this, options);\n\t}\n\n});\n\n})();\n\n\n/*\n---\n\nscript: URI.Relative.js\n\nname: URI.Relative\n\ndescription: Extends the URI class to add methods for computing relative and absolute urls.\n\nlicense: MIT-style license\n\nauthors:\n - Sebastian Markbåge\n\n\nrequires:\n - /Class.refactor\n - /URI\n\nprovides: [URI.Relative]\n\n...\n*/\n\nURI = Class.refactor(URI, {\n\n\tcombine: function(bits, base){\n\t\tif (!base || bits.scheme != base.scheme || bits.host != base.host || bits.port != base.port)\n\t\t\treturn this.previous.apply(this, arguments);\n\t\tvar end = bits.file + (bits.query ? '?' + bits.query : '') + (bits.fragment ? '#' + bits.fragment : '');\n\n\t\tif (!base.directory) return (bits.directory || (bits.file ? '' : './')) + end;\n\n\t\tvar baseDir = base.directory.split('/'),\n\t\t\trelDir = bits.directory.split('/'),\n\t\t\tpath = '',\n\t\t\toffset;\n\n\t\tvar i = 0;\n\t\tfor (offset = 0; offset < baseDir.length && offset < relDir.length && baseDir[offset] == relDir[offset]; offset++);\n\t\tfor (i = 0; i < baseDir.length - offset - 1; i++) path += '../';\n\t\tfor (i = offset; i < relDir.length - 1; i++) path += relDir[i] + '/';\n\n\t\treturn (path || (bits.file ? '' : './')) + end;\n\t},\n\n\ttoAbsolute: function(base){\n\t\tbase = new URI(base);\n\t\tif (base) base.set('directory', '').set('file', '');\n\t\treturn this.toRelative(base);\n\t},\n\n\ttoRelative: function(base){\n\t\treturn this.get('value', new URI(base));\n\t}\n\n});\n\n\n/*\n---\n\nname: Hash\n\ndescription: Contains Hash Prototypes. Provides a means for overcoming the JavaScript practical impossibility of extending native Objects.\n\nlicense: MIT-style license.\n\nrequires:\n - Core/Object\n - More\n\nprovides: [Hash]\n\n...\n*/\n\n(function(){\n\nif (this.Hash) return;\n\nvar Hash = this.Hash = new Type('Hash', function(object){\n\tif (typeOf(object) == 'hash') object = Object.clone(object.getClean());\n\tfor (var key in object) this[key] = object[key];\n\treturn this;\n});\n\nthis.$H = function(object){\n\treturn new Hash(object);\n};\n\nHash.implement({\n\n\tforEach: function(fn, bind){\n\t\tObject.forEach(this, fn, bind);\n\t},\n\n\tgetClean: function(){\n\t\tvar clean = {};\n\t\tfor (var key in this){\n\t\t\tif (this.hasOwnProperty(key)) clean[key] = this[key];\n\t\t}\n\t\treturn clean;\n\t},\n\n\tgetLength: function(){\n\t\tvar length = 0;\n\t\tfor (var key in this){\n\t\t\tif (this.hasOwnProperty(key)) length++;\n\t\t}\n\t\treturn length;\n\t}\n\n});\n\nHash.alias('each', 'forEach');\n\nHash.implement({\n\n\thas: Object.prototype.hasOwnProperty,\n\n\tkeyOf: function(value){\n\t\treturn Object.keyOf(this, value);\n\t},\n\n\thasValue: function(value){\n\t\treturn Object.contains(this, value);\n\t},\n\n\textend: function(properties){\n\t\tHash.each(properties || {}, function(value, key){\n\t\t\tHash.set(this, key, value);\n\t\t}, this);\n\t\treturn this;\n\t},\n\n\tcombine: function(properties){\n\t\tHash.each(properties || {}, function(value, key){\n\t\t\tHash.include(this, key, value);\n\t\t}, this);\n\t\treturn this;\n\t},\n\n\terase: function(key){\n\t\tif (this.hasOwnProperty(key)) delete this[key];\n\t\treturn this;\n\t},\n\n\tget: function(key){\n\t\treturn (this.hasOwnProperty(key)) ? this[key] : null;\n\t},\n\n\tset: function(key, value){\n\t\tif (!this[key] || this.hasOwnProperty(key)) this[key] = value;\n\t\treturn this;\n\t},\n\n\tempty: function(){\n\t\tHash.each(this, function(value, key){\n\t\t\tdelete this[key];\n\t\t}, this);\n\t\treturn this;\n\t},\n\n\tinclude: function(key, value){\n\t\tif (this[key] == undefined) this[key] = value;\n\t\treturn this;\n\t},\n\n\tmap: function(fn, bind){\n\t\treturn new Hash(Object.map(this, fn, bind));\n\t},\n\n\tfilter: function(fn, bind){\n\t\treturn new Hash(Object.filter(this, fn, bind));\n\t},\n\n\tevery: function(fn, bind){\n\t\treturn Object.every(this, fn, bind);\n\t},\n\n\tsome: function(fn, bind){\n\t\treturn Object.some(this, fn, bind);\n\t},\n\n\tgetKeys: function(){\n\t\treturn Object.keys(this);\n\t},\n\n\tgetValues: function(){\n\t\treturn Object.values(this);\n\t},\n\n\ttoQueryString: function(base){\n\t\treturn Object.toQueryString(this, base);\n\t}\n\n});\n\nHash.alias({indexOf: 'keyOf', contains: 'hasValue'});\n\n\n})();\n\n\n\n/*\n---\n\nscript: Hash.Extras.js\n\nname: Hash.Extras\n\ndescription: Extends the Hash Type to include getFromPath which allows a path notation to child elements.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - /Hash\n - /Object.Extras\n\nprovides: [Hash.Extras]\n\n...\n*/\n\nHash.implement({\n\n\tgetFromPath: function(notation){\n\t\treturn Object.getFromPath(this, notation);\n\t},\n\n\tcleanValues: function(method){\n\t\treturn new Hash(Object.cleanValues(this, method));\n\t},\n\n\trun: function(){\n\t\tObject.run(arguments);\n\t}\n\n});\n\n\n/*\n---\n\nscript: Element.Forms.js\n\nname: Element.Forms\n\ndescription: Extends the Element native object to include methods useful in managing inputs.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Element\n - /String.Extras\n - More\n\nprovides: [Element.Forms]\n\n...\n*/\n\nElement.implement({\n\n\ttidy: function(){\n\t\tthis.set('value', this.get('value').tidy());\n\t},\n\n\tgetTextInRange: function(start, end){\n\t\treturn this.get('value').substring(start, end);\n\t},\n\n\tgetSelectedText: function(){\n\t\tif (this.setSelectionRange) return this.getTextInRange(this.getSelectionStart(), this.getSelectionEnd());\n\t\treturn document.selection.createRange().text;\n\t},\n\n\tgetSelectedRange: function(){\n\t\tif (this.selectionStart != null){\n\t\t\treturn {\n\t\t\t\tstart: this.selectionStart,\n\t\t\t\tend: this.selectionEnd\n\t\t\t};\n\t\t}\n\n\t\tvar pos = {\n\t\t\tstart: 0,\n\t\t\tend: 0\n\t\t};\n\t\tvar range = this.getDocument().selection.createRange();\n\t\tif (!range || range.parentElement() != this) return pos;\n\t\tvar duplicate = range.duplicate();\n\n\t\tif (this.type == 'text'){\n\t\t\tpos.start = 0 - duplicate.moveStart('character', -100000);\n\t\t\tpos.end = pos.start + range.text.length;\n\t\t} else {\n\t\t\tvar value = this.get('value');\n\t\t\tvar offset = value.length;\n\t\t\tduplicate.moveToElementText(this);\n\t\t\tduplicate.setEndPoint('StartToEnd', range);\n\t\t\tif (duplicate.text.length) offset -= value.match(/[\\n\\r]*$/)[0].length;\n\t\t\tpos.end = offset - duplicate.text.length;\n\t\t\tduplicate.setEndPoint('StartToStart', range);\n\t\t\tpos.start = offset - duplicate.text.length;\n\t\t}\n\t\treturn pos;\n\t},\n\n\tgetSelectionStart: function(){\n\t\treturn this.getSelectedRange().start;\n\t},\n\n\tgetSelectionEnd: function(){\n\t\treturn this.getSelectedRange().end;\n\t},\n\n\tsetCaretPosition: function(pos){\n\t\tif (pos == 'end') pos = this.get('value').length;\n\t\tthis.selectRange(pos, pos);\n\t\treturn this;\n\t},\n\n\tgetCaretPosition: function(){\n\t\treturn this.getSelectedRange().start;\n\t},\n\n\tselectRange: function(start, end){\n\t\tif (this.setSelectionRange){\n\t\t\tthis.focus();\n\t\t\tthis.setSelectionRange(start, end);\n\t\t} else {\n\t\t\tvar value = this.get('value');\n\t\t\tvar diff = value.substr(start, end - start).replace(/\\r/g, '').length;\n\t\t\tstart = value.substr(0, start).replace(/\\r/g, '').length;\n\t\t\tvar range = this.createTextRange();\n\t\t\trange.collapse(true);\n\t\t\trange.moveEnd('character', start + diff);\n\t\t\trange.moveStart('character', start);\n\t\t\trange.select();\n\t\t}\n\t\treturn this;\n\t},\n\n\tinsertAtCursor: function(value, select){\n\t\tvar pos = this.getSelectedRange();\n\t\tvar text = this.get('value');\n\t\tthis.set('value', text.substring(0, pos.start) + value + text.substring(pos.end, text.length));\n\t\tif (select !== false) this.selectRange(pos.start, pos.start + value.length);\n\t\telse this.setCaretPosition(pos.start + value.length);\n\t\treturn this;\n\t},\n\n\tinsertAroundCursor: function(options, select){\n\t\toptions = Object.append({\n\t\t\tbefore: '',\n\t\t\tdefaultMiddle: '',\n\t\t\tafter: ''\n\t\t}, options);\n\n\t\tvar value = this.getSelectedText() || options.defaultMiddle;\n\t\tvar pos = this.getSelectedRange();\n\t\tvar text = this.get('value');\n\n\t\tif (pos.start == pos.end){\n\t\t\tthis.set('value', text.substring(0, pos.start) + options.before + value + options.after + text.substring(pos.end, text.length));\n\t\t\tthis.selectRange(pos.start + options.before.length, pos.end + options.before.length + value.length);\n\t\t} else {\n\t\t\tvar current = text.substring(pos.start, pos.end);\n\t\t\tthis.set('value', text.substring(0, pos.start) + options.before + current + options.after + text.substring(pos.end, text.length));\n\t\t\tvar selStart = pos.start + options.before.length;\n\t\t\tif (select !== false) this.selectRange(selStart, selStart + current.length);\n\t\t\telse this.setCaretPosition(selStart + text.length);\n\t\t}\n\t\treturn this;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Elements.From.js\n\nname: Elements.From\n\ndescription: Returns a collection of elements from a string of html.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/String\n - Core/Element\n - More\n\nprovides: [Elements.from, Elements.From]\n\n...\n*/\n\nElements.from = function(text, excludeScripts){\n\tif (excludeScripts || excludeScripts == null) text = text.stripScripts();\n\n\tvar container, match = text.match(/^\\s*<(t[dhr]|tbody|tfoot|thead)/i);\n\n\tif (match){\n\t\tcontainer = new Element('table');\n\t\tvar tag = match[1].toLowerCase();\n\t\tif (['td', 'th', 'tr'].contains(tag)){\n\t\t\tcontainer = new Element('tbody').inject(container);\n\t\t\tif (tag != 'tr') container = new Element('tr').inject(container);\n\t\t}\n\t}\n\n\treturn (container || new Element('div')).set('html', text).getChildren();\n};\n\nElement.from = function(text, excludeScripts) {\n var elements = Elements.from(text, excludeScripts);\n\n return elements[0];\n};\n\n/*\n---\n\nname: Element.Event.Pseudos\n\ndescription: Adds the functionality to add pseudo events for Elements\n\nlicense: MIT-style license\n\nauthors:\n - Arian Stolwijk\n\nrequires: [Core/Element.Event, Core/Element.Delegation, Events.Pseudos]\n\nprovides: [Element.Event.Pseudos, Element.Delegation]\n\n...\n*/\n\n(function(){\n\nvar pseudos = {relay: false},\n\tcopyFromEvents = ['once', 'throttle', 'pause'],\n\tcount = copyFromEvents.length;\n\nwhile (count--) pseudos[copyFromEvents[count]] = Events.lookupPseudo(copyFromEvents[count]);\n\nDOMEvent.definePseudo = function(key, listener){\n\tpseudos[key] = listener;\n\treturn this;\n};\n\nvar proto = Element.prototype;\n[Element, Window, Document].invoke('implement', Events.Pseudos(pseudos, proto.addEvent, proto.removeEvent));\n\n})();\n\n\n/*\n---\n\nname: Element.Event.Pseudos.Keys\n\ndescription: Adds functionality fire events if certain keycombinations are pressed\n\nlicense: MIT-style license\n\nauthors:\n - Arian Stolwijk\n\nrequires: [Element.Event.Pseudos]\n\nprovides: [Element.Event.Pseudos.Keys]\n\n...\n*/\n\n(function(){\n\nvar keysStoreKey = '$moo:keys-pressed',\n\tkeysKeyupStoreKey = '$moo:keys-keyup';\n\n\nDOMEvent.definePseudo('keys', function(split, fn, args){\n\n\tvar event = args[0],\n\t\tkeys = [],\n\t\tpressed = this.retrieve(keysStoreKey, []);\n\n\tkeys.append(split.value.replace('++', function(){\n\t\tkeys.push('+'); // shift++ and shift+++a\n\t\treturn '';\n\t}).split('+'));\n\n\tpressed.include(event.key);\n\n\tif (keys.every(function(key){\n\t\treturn pressed.contains(key);\n\t})) fn.apply(this, args);\n\n\tthis.store(keysStoreKey, pressed);\n\n\tif (!this.retrieve(keysKeyupStoreKey)){\n\t\tvar keyup = function(event){\n\t\t\t(function(){\n\t\t\t\tpressed = this.retrieve(keysStoreKey, []).erase(event.key);\n\t\t\t\tthis.store(keysStoreKey, pressed);\n\t\t\t}).delay(0, this); // Fix for IE\n\t\t};\n\t\tthis.store(keysKeyupStoreKey, keyup).addEvent('keyup', keyup);\n\t}\n\n});\n\nDOMEvent.defineKeys({\n\t'16': 'shift',\n\t'17': 'control',\n\t'18': 'alt',\n\t'20': 'capslock',\n\t'33': 'pageup',\n\t'34': 'pagedown',\n\t'35': 'end',\n\t'36': 'home',\n\t'144': 'numlock',\n\t'145': 'scrolllock',\n\t'186': ';',\n\t'187': '=',\n\t'188': ',',\n\t'190': '.',\n\t'191': '/',\n\t'192': '`',\n\t'219': '[',\n\t'220': '\\\\',\n\t'221': ']',\n\t'222': \"'\",\n\t'107': '+'\n}).defineKey(Browser.firefox ? 109 : 189, '-');\n\n})();\n\n\n/*\n---\n\nscript: Element.Measure.js\n\nname: Element.Measure\n\ndescription: Extends the Element native object to include methods useful in measuring dimensions.\n\ncredits: \"Element.measure / .expose methods by Daniel Steigerwald License: MIT-style license. Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz\"\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Element.Style\n - Core/Element.Dimensions\n - More\n\nprovides: [Element.Measure]\n\n...\n*/\n\n(function(){\n\nvar getStylesList = function(styles, planes){\n\tvar list = [];\n\tObject.each(planes, function(directions){\n\t\tObject.each(directions, function(edge){\n\t\t\tstyles.each(function(style){\n\t\t\t\tlist.push(style + '-' + edge + (style == 'border' ? '-width' : ''));\n\t\t\t});\n\t\t});\n\t});\n\treturn list;\n};\n\nvar calculateEdgeSize = function(edge, styles){\n\tvar total = 0;\n\tObject.each(styles, function(value, style){\n\t\tif (style.test(edge)) total = total + value.toInt();\n\t});\n\treturn total;\n};\n\nvar isVisible = function(el){\n\treturn !!(!el || el.offsetHeight || el.offsetWidth);\n};\n\n\nElement.implement({\n\n\tmeasure: function(fn){\n\t\tif (isVisible(this)) return fn.call(this);\n\t\tvar parent = this.getParent(),\n\t\t\ttoMeasure = [];\n\t\twhile (!isVisible(parent) && parent != document.body){\n\t\t\ttoMeasure.push(parent.expose());\n\t\t\tparent = parent.getParent();\n\t\t}\n\t\tvar restore = this.expose(),\n\t\t\tresult = fn.call(this);\n\t\trestore();\n\t\ttoMeasure.each(function(restore){\n\t\t\trestore();\n\t\t});\n\t\treturn result;\n\t},\n\n\texpose: function(){\n\t\tif (this.getStyle('display') != 'none') return function(){};\n\t\tvar before = this.style.cssText;\n\t\tthis.setStyles({\n\t\t\tdisplay: 'block',\n\t\t\tposition: 'absolute',\n\t\t\tvisibility: 'hidden'\n\t\t});\n\t\treturn function(){\n\t\t\tthis.style.cssText = before;\n\t\t}.bind(this);\n\t},\n\n\tgetDimensions: function(options){\n\t\toptions = Object.merge({computeSize: false}, options);\n\t\tvar dim = {x: 0, y: 0};\n\n\t\tvar getSize = function(el, options){\n\t\t\treturn (options.computeSize) ? el.getComputedSize(options) : el.getSize();\n\t\t};\n\n\t\tvar parent = this.getParent('body');\n\n\t\tif (parent && this.getStyle('display') == 'none'){\n\t\t\tdim = this.measure(function(){\n\t\t\t\treturn getSize(this, options);\n\t\t\t});\n\t\t} else if (parent){\n\t\t\ttry { //safari sometimes crashes here, so catch it\n\t\t\t\tdim = getSize(this, options);\n\t\t\t}catch(e){}\n\t\t}\n\n\t\treturn Object.append(dim, (dim.x || dim.x === 0) ? {\n\t\t\t\twidth: dim.x,\n\t\t\t\theight: dim.y\n\t\t\t} : {\n\t\t\t\tx: dim.width,\n\t\t\t\ty: dim.height\n\t\t\t}\n\t\t);\n\t},\n\n\tgetComputedSize: function(options){\n\t\t\n\n\t\toptions = Object.merge({\n\t\t\tstyles: ['padding','border'],\n\t\t\tplanes: {\n\t\t\t\theight: ['top','bottom'],\n\t\t\t\twidth: ['left','right']\n\t\t\t},\n\t\t\tmode: 'both'\n\t\t}, options);\n\n\t\tvar styles = {},\n\t\t\tsize = {width: 0, height: 0},\n\t\t\tdimensions;\n\n\t\tif (options.mode == 'vertical'){\n\t\t\tdelete size.width;\n\t\t\tdelete options.planes.width;\n\t\t} else if (options.mode == 'horizontal'){\n\t\t\tdelete size.height;\n\t\t\tdelete options.planes.height;\n\t\t}\n\n\t\tgetStylesList(options.styles, options.planes).each(function(style){\n\t\t\tstyles[style] = this.getStyle(style).toInt();\n\t\t}, this);\n\n\t\tObject.each(options.planes, function(edges, plane){\n\n\t\t\tvar capitalized = plane.capitalize(),\n\t\t\t\tstyle = this.getStyle(plane);\n\n\t\t\tif (style == 'auto' && !dimensions) dimensions = this.getDimensions();\n\n\t\t\tstyle = styles[plane] = (style == 'auto') ? dimensions[plane] : style.toInt();\n\t\t\tsize['total' + capitalized] = style;\n\n\t\t\tedges.each(function(edge){\n\t\t\t\tvar edgesize = calculateEdgeSize(edge, styles);\n\t\t\t\tsize['computed' + edge.capitalize()] = edgesize;\n\t\t\t\tsize['total' + capitalized] += edgesize;\n\t\t\t});\n\n\t\t}, this);\n\n\t\treturn Object.append(size, styles);\n\t}\n\n});\n\n})();\n\n\n/*\n---\n\nscript: Element.Pin.js\n\nname: Element.Pin\n\ndescription: Extends the Element native object to include the pin method useful for fixed positioning for elements.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Element.Event\n - Core/Element.Dimensions\n - Core/Element.Style\n - More\n\nprovides: [Element.Pin]\n\n...\n*/\n\n(function(){\n\tvar supportsPositionFixed = false,\n\t\tsupportTested = false;\n\n\tvar testPositionFixed = function(){\n\t\tvar test = new Element('div').setStyles({\n\t\t\tposition: 'fixed',\n\t\t\ttop: 0,\n\t\t\tright: 0\n\t\t}).inject(document.body);\n\t\tsupportsPositionFixed = (test.offsetTop === 0);\n\t\ttest.dispose();\n\t\tsupportTested = true;\n\t};\n\n\tElement.implement({\n\n\t\tpin: function(enable, forceScroll){\n\t\t\tif (!supportTested) testPositionFixed();\n\t\t\tif (this.getStyle('display') == 'none') return this;\n\n\t\t\tvar pinnedPosition,\n\t\t\t\tscroll = window.getScroll(),\n\t\t\t\tparent,\n\t\t\t\tscrollFixer;\n\n\t\t\tif (enable !== false){\n\t\t\t\tpinnedPosition = this.getPosition(supportsPositionFixed ? document.body : this.getOffsetParent());\n\t\t\t\tif (!this.retrieve('pin:_pinned')){\n\t\t\t\t\tvar currentPosition = {\n\t\t\t\t\t\ttop: pinnedPosition.y - scroll.y,\n\t\t\t\t\t\tleft: pinnedPosition.x - scroll.x\n\t\t\t\t\t};\n\n\t\t\t\t\tif (supportsPositionFixed && !forceScroll){\n\t\t\t\t\t\tthis.setStyle('position', 'fixed').setStyles(currentPosition);\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tparent = this.getOffsetParent();\n\t\t\t\t\t\tvar position = this.getPosition(parent),\n\t\t\t\t\t\t\tstyles = this.getStyles('left', 'top');\n\n\t\t\t\t\t\tif (parent && styles.left == 'auto' || styles.top == 'auto') this.setPosition(position);\n\t\t\t\t\t\tif (this.getStyle('position') == 'static') this.setStyle('position', 'absolute');\n\n\t\t\t\t\t\tposition = {\n\t\t\t\t\t\t\tx: styles.left.toInt() - scroll.x,\n\t\t\t\t\t\t\ty: styles.top.toInt() - scroll.y\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tscrollFixer = function(){\n\t\t\t\t\t\t\tif (!this.retrieve('pin:_pinned')) return;\n\t\t\t\t\t\t\tvar scroll = window.getScroll();\n\t\t\t\t\t\t\tthis.setStyles({\n\t\t\t\t\t\t\t\tleft: position.x + scroll.x,\n\t\t\t\t\t\t\t\ttop: position.y + scroll.y\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}.bind(this);\n\n\t\t\t\t\t\tthis.store('pin:_scrollFixer', scrollFixer);\n\t\t\t\t\t\twindow.addEvent('scroll', scrollFixer);\n\t\t\t\t\t}\n\t\t\t\t\tthis.store('pin:_pinned', true);\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tif (!this.retrieve('pin:_pinned')) return this;\n\n\t\t\t\tparent = this.getParent();\n\t\t\t\tvar offsetParent = (parent.getComputedStyle('position') != 'static' ? parent : parent.getOffsetParent());\n\n\t\t\t\tpinnedPosition = this.getPosition(offsetParent);\n\n\t\t\t\tthis.store('pin:_pinned', false);\n\t\t\t\tscrollFixer = this.retrieve('pin:_scrollFixer');\n\t\t\t\tif (!scrollFixer){\n\t\t\t\t\tthis.setStyles({\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: pinnedPosition.y + scroll.y,\n\t\t\t\t\t\tleft: pinnedPosition.x + scroll.x\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthis.store('pin:_scrollFixer', null);\n\t\t\t\t\twindow.removeEvent('scroll', scrollFixer);\n\t\t\t\t}\n\t\t\t\tthis.removeClass('isPinned');\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\tunpin: function(){\n\t\t\treturn this.pin(false);\n\t\t},\n\n\t\ttogglePin: function(){\n\t\t\treturn this.pin(!this.retrieve('pin:_pinned'));\n\t\t}\n\n\t});\n\n\n\n})();\n\n\n/*\n---\n\nscript: Element.Position.js\n\nname: Element.Position\n\ndescription: Extends the Element native object to include methods useful positioning elements relative to others.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n - Jacob Thornton\n\nrequires:\n - Core/Options\n - Core/Element.Dimensions\n - Element.Measure\n\nprovides: [Element.Position]\n\n...\n*/\n\n(function(original){\n\nvar local = Element.Position = {\n\n\toptions: {/*\n\t\tedge: false,\n\t\treturnPos: false,\n\t\tminimum: {x: 0, y: 0},\n\t\tmaximum: {x: 0, y: 0},\n\t\trelFixedPosition: false,\n\t\tignoreMargins: false,\n\t\tignoreScroll: false,\n\t\tallowNegative: false,*/\n\t\trelativeTo: document.body,\n\t\tposition: {\n\t\t\tx: 'center', //left, center, right\n\t\t\ty: 'center' //top, center, bottom\n\t\t},\n\t\toffset: {x: 0, y: 0}\n\t},\n\n\tgetOptions: function(element, options){\n\t\toptions = Object.merge({}, local.options, options);\n\t\tlocal.setPositionOption(options);\n\t\tlocal.setEdgeOption(options);\n\t\tlocal.setOffsetOption(element, options);\n\t\tlocal.setDimensionsOption(element, options);\n\t\treturn options;\n\t},\n\n\tsetPositionOption: function(options){\n\t\toptions.position = local.getCoordinateFromValue(options.position);\n\t},\n\n\tsetEdgeOption: function(options){\n\t\tvar edgeOption = local.getCoordinateFromValue(options.edge);\n\t\toptions.edge = edgeOption ? edgeOption :\n\t\t\t(options.position.x == 'center' && options.position.y == 'center') ? {x: 'center', y: 'center'} :\n\t\t\t{x: 'left', y: 'top'};\n\t},\n\n\tsetOffsetOption: function(element, options){\n\t\tvar parentOffset = {x: 0, y: 0},\n\t\t\toffsetParent = element.measure(function(){\n\t\t\t\treturn document.id(this.getOffsetParent());\n\t\t\t}),\n\t\t\tparentScroll = offsetParent.getScroll();\n\n\t\tif (!offsetParent || offsetParent == element.getDocument().body) return;\n\t\tparentOffset = offsetParent.measure(function(){\n\t\t\tvar position = this.getPosition();\n\t\t\tif (this.getStyle('position') == 'fixed'){\n\t\t\t\tvar scroll = window.getScroll();\n\t\t\t\tposition.x += scroll.x;\n\t\t\t\tposition.y += scroll.y;\n\t\t\t}\n\t\t\treturn position;\n\t\t});\n\n\t\toptions.offset = {\n\t\t\tparentPositioned: offsetParent != document.id(options.relativeTo),\n\t\t\tx: options.offset.x - parentOffset.x + parentScroll.x,\n\t\t\ty: options.offset.y - parentOffset.y + parentScroll.y\n\t\t};\n\t},\n\n\tsetDimensionsOption: function(element, options){\n\t\toptions.dimensions = element.getDimensions({\n\t\t\tcomputeSize: true,\n\t\t\tstyles: ['padding', 'border', 'margin']\n\t\t});\n\t},\n\n\tgetPosition: function(element, options){\n\t\tvar position = {};\n\t\toptions = local.getOptions(element, options);\n\t\tvar relativeTo = document.id(options.relativeTo) || document.body;\n\n\t\tlocal.setPositionCoordinates(options, position, relativeTo);\n\t\tif (options.edge) local.toEdge(position, options);\n\n\t\tvar offset = options.offset;\n\t\tposition.left = ((position.x >= 0 || offset.parentPositioned || options.allowNegative) ? position.x : 0).toInt();\n\t\tposition.top = ((position.y >= 0 || offset.parentPositioned || options.allowNegative) ? position.y : 0).toInt();\n\n\t\tlocal.toMinMax(position, options);\n\n\t\tif (options.relFixedPosition || relativeTo.getStyle('position') == 'fixed') local.toRelFixedPosition(relativeTo, position);\n\t\tif (options.ignoreScroll) local.toIgnoreScroll(relativeTo, position);\n\t\tif (options.ignoreMargins) local.toIgnoreMargins(position, options);\n\n\t\tposition.left = Math.ceil(position.left);\n\t\tposition.top = Math.ceil(position.top);\n\t\tdelete position.x;\n\t\tdelete position.y;\n\n\t\treturn position;\n\t},\n\n\tsetPositionCoordinates: function(options, position, relativeTo){\n\t\tvar offsetY = options.offset.y,\n\t\t\toffsetX = options.offset.x,\n\t\t\tcalc = (relativeTo == document.body) ? window.getScroll() : relativeTo.getPosition(),\n\t\t\ttop = calc.y,\n\t\t\tleft = calc.x,\n\t\t\twinSize = window.getSize();\n\n\t\tswitch(options.position.x){\n\t\t\tcase 'left': position.x = left + offsetX; break;\n\t\t\tcase 'right': position.x = left + offsetX + relativeTo.offsetWidth; break;\n\t\t\tdefault: position.x = left + ((relativeTo == document.body ? winSize.x : relativeTo.offsetWidth) / 2) + offsetX; break;\n\t\t}\n\n\t\tswitch(options.position.y){\n\t\t\tcase 'top': position.y = top + offsetY; break;\n\t\t\tcase 'bottom': position.y = top + offsetY + relativeTo.offsetHeight; break;\n\t\t\tdefault: position.y = top + ((relativeTo == document.body ? winSize.y : relativeTo.offsetHeight) / 2) + offsetY; break;\n\t\t}\n\t},\n\n\ttoMinMax: function(position, options){\n\t\tvar xy = {left: 'x', top: 'y'}, value;\n\t\t['minimum', 'maximum'].each(function(minmax){\n\t\t\t['left', 'top'].each(function(lr){\n\t\t\t\tvalue = options[minmax] ? options[minmax][xy[lr]] : null;\n\t\t\t\tif (value != null && ((minmax == 'minimum') ? position[lr] < value : position[lr] > value)) position[lr] = value;\n\t\t\t});\n\t\t});\n\t},\n\n\ttoRelFixedPosition: function(relativeTo, position){\n\t\tvar winScroll = window.getScroll();\n\t\tposition.top += winScroll.y;\n\t\tposition.left += winScroll.x;\n\t},\n\n\ttoIgnoreScroll: function(relativeTo, position){\n\t\tvar relScroll = relativeTo.getScroll();\n\t\tposition.top -= relScroll.y;\n\t\tposition.left -= relScroll.x;\n\t},\n\n\ttoIgnoreMargins: function(position, options){\n\t\tposition.left += options.edge.x == 'right'\n\t\t\t? options.dimensions['margin-right']\n\t\t\t: (options.edge.x != 'center'\n\t\t\t\t? -options.dimensions['margin-left']\n\t\t\t\t: -options.dimensions['margin-left'] + ((options.dimensions['margin-right'] + options.dimensions['margin-left']) / 2));\n\n\t\tposition.top += options.edge.y == 'bottom'\n\t\t\t? options.dimensions['margin-bottom']\n\t\t\t: (options.edge.y != 'center'\n\t\t\t\t? -options.dimensions['margin-top']\n\t\t\t\t: -options.dimensions['margin-top'] + ((options.dimensions['margin-bottom'] + options.dimensions['margin-top']) / 2));\n\t},\n\n\ttoEdge: function(position, options){\n\t\tvar edgeOffset = {},\n\t\t\tdimensions = options.dimensions,\n\t\t\tedge = options.edge;\n\n\t\tswitch(edge.x){\n\t\t\tcase 'left': edgeOffset.x = 0; break;\n\t\t\tcase 'right': \n // Case for IE which doesn't return computed values and they need to be manually calculated\n\t\t\t if (dimensions.computedRight && dimensions.computedLeft)\n\t\t\t edgeOffset.x = -dimensions.x - dimensions.computedRight - dimensions.computedLeft;\n\t\t\t else\n\t\t\t edgeOffset.x = -dimensions.x - ((dimensions[\"border-right-width\"] || 0 ) + (dimensions[\"margin-right\"] || 0 ) + (dimensions[\"padding-right\"] || 0 )) - ((dimensions[\"border-left-width\"] || 0 ) + (dimensions[\"margin-left\"] || 0 ) + (dimensions[\"padding-left\"] || 0 ));\n break;\n\t\t\t// center\n\t\t\tdefault: \n if (dimensions.totalWidth)\n edgeOffset.x = -(Math.round(dimensions.totalWidth / 2)); \n else\n edgeOffset.x = -(Math.round((dimensions.x + ((dimensions[\"border-right-width\"] || 0 ) + (dimensions[\"margin-right\"] || 0 ) + (dimensions[\"padding-right\"] || 0 )) + ((dimensions[\"border-left-width\"] || 0 ) + (dimensions[\"margin-left\"] || 0 ) + (dimensions[\"padding-left\"] || 0 )) )/ 2)); \n break;\n\t\t}\n\n\t\tswitch(edge.y){\n\t\t\tcase 'top': edgeOffset.y = 0; break;\n\t\t\tcase 'bottom': \n // Case for IE which doesn't return computed values and they need to be manually calculated\n\t\t\t if (dimensions.computedTop && dimensions.computedBottom)\n\t\t\t edgeOffset.y = -dimensions.y - dimensions.computedTop - dimensions.computedBottom;\n\t\t\t else\n\t\t\t edgeOffset.y = -dimensions.y - ((dimensions[\"border-top-width\"] || 0 ) + (dimensions[\"margin-top\"] || 0 ) + (dimensions[\"padding-top\"] || 0 )) - ((dimensions[\"border-bottom-width\"] || 0 ) + (dimensions[\"margin-bottom\"] || 0 ) + (dimensions[\"padding-bottom\"] || 0 ));\n break;\n\t\t\t// center\n\t\t\tdefault: \n if (dimensions.totalHeight)\n edgeOffset.y = -(Math.round(dimensions.totalHeight / 2));\n else\n edgeOffset.y = -(Math.round((dimensions.y + ((dimensions[\"border-top-width\"] || 0 ) + (dimensions[\"margin-top\"] || 0 ) + (dimensions[\"padding-top\"] || 0 )) + ((dimensions[\"border-bottom-width\"] || 0 ) + (dimensions[\"margin-bottom\"] || 0 ) + (dimensions[\"padding-bottom\"] || 0 ))) / 2));\n break;\n\t\t}\n\t\tposition.x += edgeOffset.x;\n\t\tposition.y += edgeOffset.y;\n\t},\n\n\tgetCoordinateFromValue: function(option){\n\t\tif (typeOf(option) != 'string') return option;\n\t\toption = option.toLowerCase();\n\n\t\treturn {\n\t\t\tx: option.test('left') ? 'left'\n\t\t\t\t: (option.test('right') ? 'right' : 'center'),\n\t\t\ty: option.test(/upper|top/) ? 'top'\n\t\t\t\t: (option.test('bottom') ? 'bottom' : 'center')\n\t\t};\n\t}\n\n};\n\nElement.implement({\n\n\tposition: function(options){\n\t\tif (options && (options.x != null || options.y != null)){\n\t\t\treturn (original ? original.apply(this, arguments) : this);\n\t\t}\n\t\tvar position = this.setStyle('position', 'absolute').calculatePosition(options);\n\t\treturn (options && options.returnPos) ? position : this.setStyles(position);\n\t},\n\n\tcalculatePosition: function(options){\n\t\treturn local.getPosition(this, options);\n\t}\n\n});\n\n})(Element.prototype.position);\n\n\n/*\n---\n\nscript: Element.Shortcuts.js\n\nname: Element.Shortcuts\n\ndescription: Extends the Element native object to include some shortcut methods.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Element.Style\n - More\n\nprovides: [Element.Shortcuts]\n\n...\n*/\n\nElement.implement({\n\n\tisDisplayed: function(){\n\t\treturn this.getStyle('display') != 'none';\n\t},\n\n\tisVisible: function(){\n\t\tvar w = this.offsetWidth,\n\t\t\th = this.offsetHeight;\n\t\treturn (w == 0 && h == 0) ? false : (w > 0 && h > 0) ? true : this.style.display != 'none';\n\t},\n\n\ttoggle: function(show){\n\t\tif (show == null)\n\t\t\tshow = !this.isDisplayed();\n\n\t\treturn this[show ? 'show' : 'hide']();\n\t},\n\n\thide: function(){\n\t\tvar d;\n\t\ttry {\n\t\t\t//IE fails here if the element is not in the dom\n\t\t\td = this.getStyle('display');\n\t\t} catch(e){}\n\t\tif (d == 'none') return this;\n\t\treturn this.store('element:_originalDisplay', d || '').setStyle('display', 'none');\n\t},\n\n\tshow: function(display){\n\t\tif (!display && this.isDisplayed()) return this;\n\t\tdisplay = display || this.retrieve('element:_originalDisplay') || this.dataset[\"display\"] || 'block';\n\t\treturn this.setStyle('display', (display == 'none') ? 'block' : display);\n\t},\n\n\tswapClass: function(remove, add){\n\t\treturn this.removeClass(remove).addClass(add);\n\t}\n\n});\n\nDocument.implement({\n\n\tclearSelection: function(){\n\t\tif (window.getSelection){\n\t\t\tvar selection = window.getSelection();\n\t\t\tif (selection && selection.removeAllRanges) selection.removeAllRanges();\n\t\t} else if (document.selection && document.selection.empty){\n\t\t\ttry {\n\t\t\t\t//IE fails here if selected element is not in dom\n\t\t\t\tdocument.selection.empty();\n\t\t\t} catch(e){}\n\t\t}\n\t}\n\n});\n\n\n/*\n---\n\nscript: IframeShim.js\n\nname: IframeShim\n\ndescription: Defines IframeShim, a class for obscuring select lists and flash objects in IE.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Element.Event\n - Core/Element.Style\n - Core/Options\n - Core/Events\n - /Element.Position\n - /Class.Occlude\n\nprovides: [IframeShim]\n\n...\n*/\n\nvar IframeShim = new Class({\n\n\tImplements: [Options, Events, Class.Occlude],\n\n\toptions: {\n\t\tclassName: 'iframeShim',\n\t\tsrc: 'javascript:false;document.write(\"\");',\n\t\tdisplay: false,\n\t\tzIndex: null,\n\t\tmargin: 0,\n\t\toffset: {x: 0, y: 0},\n\t\tbrowsers: (Browser.ie6 || (Browser.firefox && Browser.version < 3 && Browser.Platform.mac))\n\t},\n\n\tproperty: 'IframeShim',\n\n\tinitialize: function(element, options){\n\t\tthis.element = document.id(element);\n\t\tif (this.occlude()) return this.occluded;\n\t\tthis.setOptions(options);\n\t\tthis.makeShim();\n\t\treturn this;\n\t},\n\n\tmakeShim: function(){\n\t\tif (this.options.browsers){\n\t\t\tvar zIndex = this.element.getStyle('zIndex').toInt();\n\n\t\t\tif (!zIndex){\n\t\t\t\tzIndex = 1;\n\t\t\t\tvar pos = this.element.getStyle('position');\n\t\t\t\tif (pos == 'static' || !pos) this.element.setStyle('position', 'relative');\n\t\t\t\tthis.element.setStyle('zIndex', zIndex);\n\t\t\t}\n\t\t\tzIndex = ((this.options.zIndex != null || this.options.zIndex === 0) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1;\n\t\t\tif (zIndex < 0) zIndex = 1;\n\t\t\tthis.shim = new Element('iframe', {\n\t\t\t\tsrc: this.options.src,\n\t\t\t\tscrolling: 'no',\n\t\t\t\tframeborder: 0,\n\t\t\t\tstyles: {\n\t\t\t\t\tzIndex: zIndex,\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\tborder: 'none',\n\t\t\t\t\tfilter: 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'\n\t\t\t\t},\n\t\t\t\t'class': this.options.className\n\t\t\t}).store('IframeShim', this);\n\t\t\tvar inject = (function(){\n\t\t\t\tthis.shim.inject(this.element, 'after');\n\t\t\t\tthis[this.options.display ? 'show' : 'hide']();\n\t\t\t\tthis.fireEvent('inject');\n\t\t\t}).bind(this);\n\t\t\tif (!IframeShim.ready) window.addEvent('load', inject);\n\t\t\telse inject();\n\t\t} else {\n\t\t\tthis.position = this.hide = this.show = this.dispose = Function.from(this);\n\t\t}\n\t},\n\n\tposition: function(){\n\t\tif (!IframeShim.ready || !this.shim) return this;\n\t\tvar size = this.element.measure(function(){\n\t\t\treturn this.getSize();\n\t\t});\n\t\tif (this.options.margin != undefined){\n\t\t\tsize.x = size.x - (this.options.margin * 2);\n\t\t\tsize.y = size.y - (this.options.margin * 2);\n\t\t\tthis.options.offset.x += this.options.margin;\n\t\t\tthis.options.offset.y += this.options.margin;\n\t\t}\n\t\tthis.shim.set({width: size.x, height: size.y}).position({\n\t\t\trelativeTo: this.element,\n\t\t\toffset: this.options.offset\n\t\t});\n\t\treturn this;\n\t},\n\n\thide: function(){\n\t\tif (this.shim) this.shim.setStyle('display', 'none');\n\t\treturn this;\n\t},\n\n\tshow: function(){\n\t\tif (this.shim) this.shim.setStyle('display', 'block');\n\t\treturn this.position();\n\t},\n\n\tdispose: function(){\n\t\tif (this.shim) this.shim.dispose();\n\t\treturn this;\n\t},\n\n\tdestroy: function(){\n\t\tif (this.shim) this.shim.destroy();\n\t\treturn this;\n\t}\n\n});\n\nwindow.addEvent('load', function(){\n\tIframeShim.ready = true;\n});\n\n\n/*\n---\n\nscript: Mask.js\n\nname: Mask\n\ndescription: Creates a mask element to cover another.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Options\n - Core/Events\n - Core/Element.Event\n - /Class.Binds\n - /Element.Position\n - /IframeShim\n\nprovides: [Mask]\n\n...\n*/\n\nvar Mask = new Class({\n\n\tImplements: [Options, Events],\n\n\tBinds: ['position'],\n\n\toptions: {/*\n\t\tonShow: function(){},\n\t\tonHide: function(){},\n\t\tonDestroy: function(){},\n\t\tonClick: function(event){},\n\t\tinject: {\n\t\t\twhere: 'after',\n\t\t\ttarget: null,\n\t\t},\n\t\thideOnClick: false,\n\t\tid: null,\n\t\tdestroyOnHide: false,*/\n\t\tstyle: {},\n\t\t'class': 'mask',\n\t\tmaskMargins: false,\n\t\tuseIframeShim: true,\n\t\tiframeShimOptions: {}\n\t},\n\n\tinitialize: function(target, options){\n\t\tthis.target = document.id(target) || document.id(document.body);\n\t\tthis.target.store('mask', this);\n\t\tthis.setOptions(options);\n\t\tthis.render();\n\t\tthis.inject();\n\t},\n\n\trender: function(){\n\t\tthis.element = new Element('div', {\n\t\t\t'class': this.options['class'],\n\t\t\tid: this.options.id || 'mask-' + String.uniqueID(),\n\t\t\tstyles: Object.merge({}, this.options.style, {\n\t\t\t\tdisplay: 'none'\n\t\t\t}),\n\t\t\tevents: {\n\t\t\t\tclick: function(event){\n\t\t\t\t\tthis.fireEvent('click', event);\n\t\t\t\t\tif (this.options.hideOnClick) this.hide();\n\t\t\t\t}.bind(this)\n\t\t\t}\n\t\t});\n\n\t\tthis.hidden = true;\n\t},\n\n\ttoElement: function(){\n\t\treturn this.element;\n\t},\n\n\tinject: function(target, where){\n\t\twhere = where || (this.options.inject ? this.options.inject.where : '') || this.target == document.body ? 'inside' : 'after';\n\t\ttarget = target || (this.options.inject && this.options.inject.target) || this.target;\n\n\t\tthis.element.inject(target, where);\n\n\t\tif (this.options.useIframeShim){\n\t\t\tthis.shim = new IframeShim(this.element, this.options.iframeShimOptions);\n\n\t\t\tthis.addEvents({\n\t\t\t\tshow: this.shim.show.bind(this.shim),\n\t\t\t\thide: this.shim.hide.bind(this.shim),\n\t\t\t\tdestroy: this.shim.destroy.bind(this.shim)\n\t\t\t});\n\t\t}\n\t},\n\n\tposition: function(){\n\t\tthis.resize(this.options.width, this.options.height);\n\n\t\tthis.element.position({\n\t\t\trelativeTo: this.target,\n\t\t\tposition: 'topLeft',\n\t\t\tignoreMargins: !this.options.maskMargins,\n\t\t\tignoreScroll: this.target == document.body\n\t\t});\n\n\t\treturn this;\n\t},\n\n\tresize: function(x, y){\n\t\tvar opt = {\n\t\t\tstyles: ['padding', 'border']\n\t\t};\n\t\tif (this.options.maskMargins) opt.styles.push('margin');\n\n\t\tvar dim = this.target.getComputedSize(opt);\n\t\tif (this.target == document.body){\n\t\t\tthis.element.setStyles({width: 0, height: 0});\n\t\t\tvar win = window.getScrollSize();\n\t\t\tif (dim.totalHeight < win.y) dim.totalHeight = win.y;\n\t\t\tif (dim.totalWidth < win.x) dim.totalWidth = win.x;\n\t\t}\n\t\tthis.element.setStyles({\n\t\t\twidth: Array.pick([x, dim.totalWidth, dim.x]),\n\t\t\theight: Array.pick([y, dim.totalHeight, dim.y])\n\t\t});\n\n\t\treturn this;\n\t},\n\n\tshow: function(){\n\t\tif (!this.hidden) return this;\n\n\t\twindow.addEvent('resize', this.position);\n\t\tthis.position();\n\t\tthis.showMask.apply(this, arguments);\n\n\t\treturn this;\n\t},\n\n\tshowMask: function(){\n\t\tthis.element.setStyle('display', 'block');\n\t\tthis.hidden = false;\n\t\tthis.fireEvent('show');\n\t},\n\n\thide: function(){\n\t\tif (this.hidden) return this;\n\n\t\twindow.removeEvent('resize', this.position);\n\t\tthis.hideMask.apply(this, arguments);\n\t\tif (this.options.destroyOnHide) return this.destroy();\n\n\t\treturn this;\n\t},\n\n\thideMask: function(){\n\t\tthis.element.setStyle('display', 'none');\n\t\tthis.hidden = true;\n\t\tthis.fireEvent('hide');\n\t},\n\n\ttoggle: function(){\n\t\tthis[this.hidden ? 'show' : 'hide']();\n\t},\n\n\tdestroy: function(){\n\t\tthis.hide();\n\t\tthis.element.destroy();\n\t\tthis.fireEvent('destroy');\n\t\tthis.target.eliminate('mask');\n\t}\n\n});\n\nElement.Properties.mask = {\n\n\tset: function(options){\n\t\tvar mask = this.retrieve('mask');\n\t\tif (mask) mask.destroy();\n\t\treturn this.eliminate('mask').store('mask:options', options);\n\t},\n\n\tget: function(){\n\t\tvar mask = this.retrieve('mask');\n\t\tif (!mask){\n\t\t\tmask = new Mask(this, this.retrieve('mask:options'));\n\t\t\tthis.store('mask', mask);\n\t\t}\n\t\treturn mask;\n\t}\n\n};\n\nElement.implement({\n\n\tmask: function(options){\n\t\tif (options) this.set('mask', options);\n\t\tthis.get('mask').show();\n\t\treturn this;\n\t},\n\n\tunmask: function(){\n\t\tthis.get('mask').hide();\n\t\treturn this;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Spinner.js\n\nname: Spinner\n\ndescription: Adds a semi-transparent overlay over a dom element with a spinnin ajax icon.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Fx.Tween\n - Core/Request\n - /Class.refactor\n - /Mask\n\nprovides: [Spinner]\n\n...\n*/\n\nvar Spinner = new Class({\n\n\tExtends: Mask,\n\n\tImplements: Chain,\n\n\toptions: {/*\n\t\tmessage: false,*/\n\t\t'class': 'spinner',\n\t\tcontainerPosition: {},\n\t\tcontent: {\n\t\t\t'class': 'spinner-content'\n\t\t},\n\t\tmessageContainer: {\n\t\t\t'class': 'spinner-msg'\n\t\t},\n\t\timg: {\n\t\t\t'class': 'spinner-img'\n\t\t},\n\t\tfxOptions: {\n\t\t\tlink: 'chain'\n\t\t}\n\t},\n\n\tinitialize: function(target, options){\n\t\tthis.target = document.id(target) || document.id(document.body);\n\t\tthis.target.store('spinner', this);\n\t\tthis.setOptions(options);\n\t\tthis.render();\n\t\tthis.inject();\n\n\t\t// Add this to events for when noFx is true; parent methods handle hide/show.\n\t\tvar deactivate = function(){ this.active = false; }.bind(this);\n\t\tthis.addEvents({\n\t\t\thide: deactivate,\n\t\t\tshow: deactivate\n\t\t});\n\t},\n\n\trender: function(){\n\t\tthis.parent();\n\n\t\tthis.element.set('id', this.options.id || 'spinner-' + String.uniqueID());\n\n\t\tthis.content = document.id(this.options.content) || new Element('div', this.options.content);\n\t\tthis.content.inject(this.element);\n\n\t\tif (this.options.message){\n\t\t\tthis.msg = document.id(this.options.message) || new Element('p', this.options.messageContainer).appendText(this.options.message);\n\t\t\tthis.msg.inject(this.content);\n\t\t}\n\n\t\tif (this.options.img){\n\t\t\tthis.img = document.id(this.options.img) || new Element('div', this.options.img);\n\t\t\tthis.img.inject(this.content);\n\t\t}\n\n\t\tthis.element.set('tween', this.options.fxOptions);\n\t},\n\n\tshow: function(noFx){\n\t\tif (this.active) return this.chain(this.show.bind(this));\n\t\tif (!this.hidden){\n\t\t\tthis.callChain.delay(20, this);\n\t\t\treturn this;\n\t\t}\n\n\t\tthis.active = true;\n\n\t\treturn this.parent(noFx);\n\t},\n\n\tshowMask: function(noFx){\n\t\tvar pos = function(){\n\t\t\tthis.content.position(Object.merge({\n\t\t\t\trelativeTo: this.element\n\t\t\t}, this.options.containerPosition));\n\t\t}.bind(this);\n\n\t\tif (noFx){\n\t\t\tthis.parent();\n\t\t\tpos();\n\t\t} else {\n\t\t\tif (!this.options.style.opacity) this.options.style.opacity = this.element.getStyle('opacity').toFloat();\n\t\t\tthis.element.setStyles({\n\t\t\t\tdisplay: 'block',\n\t\t\t\topacity: 0\n\t\t\t}).tween('opacity', this.options.style.opacity);\n\t\t\tpos();\n\t\t\tthis.hidden = false;\n\t\t\tthis.fireEvent('show');\n\t\t\tthis.callChain();\n\t\t}\n\t},\n\n\thide: function(noFx){\n\t\tif (this.active) return this.chain(this.hide.bind(this));\n\t\tif (this.hidden){\n\t\t\tthis.callChain.delay(20, this);\n\t\t\treturn this;\n\t\t}\n\t\tthis.active = true;\n\t\treturn this.parent(noFx);\n\t},\n\n\thideMask: function(noFx){\n\t\tif (noFx) return this.parent();\n\t\tthis.element.tween('opacity', 0).get('tween').chain(function(){\n\t\t\tthis.element.setStyle('display', 'none');\n\t\t\tthis.hidden = true;\n\t\t\tthis.fireEvent('hide');\n\t\t\tthis.callChain();\n\t\t}.bind(this));\n\t},\n\n\tdestroy: function(){\n\t\tthis.content.destroy();\n\t\tthis.parent();\n\t\tthis.target.eliminate('spinner');\n\t}\n\n});\n\nRequest = Class.refactor(Request, {\n\n\toptions: {\n\t\tuseSpinner: false,\n\t\tspinnerOptions: {},\n\t\tspinnerTarget: false\n\t},\n\n\tinitialize: function(options) {\n\t this._send = this.send;\n\t\tthis.send = function(options) {\n\t\t var spinner = null;\n\t\t if (typeof this.getSpinner == \"function\")\n\t\t spinner = this.getSpinner();\n\t\t else\n\t\t console.warn(\"getSpinner is not a function\", this);\n\t\t \n\t\t\tif (spinner)\n\t\t\t spinner.chain(this._send.pass(options, this)).show();\n\t\t\telse\n\t\t\t this._send(options);\n\n\t\t\treturn this;\n\t\t};\n\t\tthis.previous(options);\n\t},\n\n\tgetSpinner: function(){\n\t\tif (!this.spinner){\n\t\t\tvar update = document.id(this.options.spinnerTarget) || document.id(this.options.update);\n\t\t\tif (this.options.useSpinner && update){\n\t\t\t\tupdate.set('spinner', this.options.spinnerOptions);\n\t\t\t\tvar spinner = this.spinner = update.get('spinner');\n\t\t\t\t['complete', 'exception', 'cancel'].each(function(event){\n\t\t\t\t\tthis.addEvent(event, spinner.hide.bind(spinner));\n\t\t\t\t}, this);\n\t\t\t}\n\t\t}\n\t\treturn this.spinner;\n\t}\n\n});\n\nElement.Properties.spinner = {\n\n\tset: function(options){\n\t\tvar spinner = this.retrieve('spinner');\n\t\tif (spinner) spinner.destroy();\n\t\treturn this.eliminate('spinner').store('spinner:options', options);\n\t},\n\n\tget: function(){\n\t\tvar spinner = this.retrieve('spinner');\n\t\tif (!spinner){\n\t\t\tspinner = new Spinner(this, this.retrieve('spinner:options'));\n\t\t\tthis.store('spinner', spinner);\n\t\t}\n\t\treturn spinner;\n\t}\n\n};\n\nElement.implement({\n\n\tspin: function(options){\n\t\tif (options) this.set('spinner', options);\n\t\tthis.get('spinner').show();\n\t\treturn this;\n\t},\n\n\tunspin: function(){\n\t\tthis.get('spinner').hide();\n\t\treturn this;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Form.Request.js\n\nname: Form.Request\n\ndescription: Handles the basic functionality of submitting a form and updating a dom element with the result.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Request.HTML\n - /Class.Binds\n - /Class.Occlude\n - /Spinner\n - /String.QueryString\n - /Element.Delegation\n\nprovides: [Form.Request]\n\n...\n*/\n\nif (!window.Form) window.Form = {};\n\n(function(){\n\n\tForm.Request = new Class({\n\n\t\tBinds: ['onSubmit', 'onFormValidate'],\n\n\t\tImplements: [Options, Events, Class.Occlude],\n\n\t\toptions: {/*\n\t\t\tonFailure: function(){},\n\t\t\tonSuccess: function(){}, // aliased to onComplete,\n\t\t\tonSend: function(){}*/\n\t\t\trequestOptions: {\n\t\t\t\tevalScripts: true,\n\t\t\t\tuseSpinner: true,\n\t\t\t\temulation: false,\n\t\t\t\tlink: 'ignore'\n\t\t\t},\n\t\t\tsendButtonClicked: true,\n\t\t\textraData: {},\n\t\t\tresetForm: true\n\t\t},\n\n\t\tproperty: 'form.request',\n\n\t\tinitialize: function(form, target, options){\n\t\t\tthis.element = document.id(form);\n\t\t\tif (this.occlude()) return this.occluded;\n\t\t\tthis.setOptions(options)\n\t\t\t\t.setTarget(target)\n\t\t\t\t.attach();\n\t\t},\n\n\t\tsetTarget: function(target){\n\t\t\tthis.target = document.id(target);\n\t\t\tif (!this.request){\n\t\t\t\tthis.makeRequest();\n\t\t\t} else {\n\t\t\t\tthis.request.setOptions({\n\t\t\t\t\tupdate: this.target\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\ttoElement: function(){\n\t\t\treturn this.element;\n\t\t},\n\n\t\tmakeRequest: function(){\n\t\t\tvar self = this;\n\t\t\tthis.request = new Request.HTML(Object.merge({\n\t\t\t\t\tupdate: this.target,\n\t\t\t\t\temulation: false,\n\t\t\t\t\tspinnerTarget: this.element,\n\t\t\t\t\tmethod: this.element.get('method') || 'post'\n\t\t\t}, this.options.requestOptions)).addEvents({\n\t\t\t\tsuccess: function(tree, elements, html, javascript){\n\t\t\t\t\t['complete', 'success'].each(function(evt){\n\t\t\t\t\t\tself.fireEvent(evt, [self.target, tree, elements, html, javascript]);\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tfailure: function(){\n\t\t\t\t\tself.fireEvent('complete', arguments).fireEvent('failure', arguments);\n\t\t\t\t},\n\t\t\t\texception: function(){\n\t\t\t\t\tself.fireEvent('failure', arguments);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn this.attachReset();\n\t\t},\n\n\t\tattachReset: function(){\n\t\t\tif (!this.options.resetForm) return this;\n\t\t\tthis.request.addEvent('success', function(){\n\t\t\t\tFunction.attempt(function(){\n\t\t\t\t\tthis.element.reset();\n\t\t\t\t}.bind(this));\n\t\t\t\tif (window.OverText) OverText.update();\n\t\t\t}.bind(this));\n\t\t\treturn this;\n\t\t},\n\n\t\tattach: function(attach){\n\t\t\tvar method = (attach != false) ? 'addEvent' : 'removeEvent';\n\t\t\tthis.element[method]('click:relay(button, input[type=submit])', this.saveClickedButton.bind(this));\n\n\t\t\tvar fv = this.element.retrieve('validator');\n\t\t\tif (fv) fv[method]('onFormValidate', this.onFormValidate);\n\t\t\telse this.element[method]('submit', this.onSubmit);\n\n\t\t\treturn this;\n\t\t},\n\n\t\tdetach: function(){\n\t\t\treturn this.attach(false);\n\t\t},\n\n\t\t//public method\n\t\tenable: function(){\n\t\t\treturn this.attach();\n\t\t},\n\n\t\t//public method\n\t\tdisable: function(){\n\t\t\treturn this.detach();\n\t\t},\n\n\t\tonFormValidate: function(valid, form, event){\n\t\t\t//if there's no event, then this wasn't a submit event\n\t\t\tif (!event) return;\n\t\t\tvar fv = this.element.retrieve('validator');\n\t\t\tif (valid || (fv && !fv.options.stopOnFailure)){\n\t\t\t\tevent.stop();\n\t\t\t\tthis.send();\n\t\t\t}\n\t\t},\n\n\t\tonSubmit: function(event){\n\t\t\tvar fv = this.element.retrieve('validator');\n\t\t\tif (fv){\n\t\t\t\t//form validator was created after Form.Request\n\t\t\t\tthis.element.removeEvent('submit', this.onSubmit);\n\t\t\t\tfv.addEvent('onFormValidate', this.onFormValidate);\n\t\t\t\tthis.element.validate();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event) event.stop();\n\t\t\tthis.send();\n\t\t},\n\n\t\tsaveClickedButton: function(event, target){\n\t\t\tvar targetName = target.get('name');\n\t\t\tif (!targetName || !this.options.sendButtonClicked) return;\n\t\t\tthis.options.extraData[targetName] = target.get('value') || true;\n\t\t\tthis.clickedCleaner = function(){\n\t\t\t\tdelete this.options.extraData[targetName];\n\t\t\t\tthis.clickedCleaner = function(){};\n\t\t\t}.bind(this);\n\t\t},\n\n\t\tclickedCleaner: function(){},\n\n\t\tsend: function(){\n\t\t\tvar str = this.element.toQueryString().trim(),\n\t\t\t\tdata = Object.toQueryString(this.options.extraData);\n\n\t\t\tif (str) str += \"&\" + data;\n\t\t\telse str = data;\n\n\t\t\tthis.fireEvent('send', [this.element, str.parseQueryString()]);\n\t\t\tthis.request.send({\n\t\t\t\tdata: str,\n\t\t\t\turl: this.options.requestOptions.url || this.element.get('action')\n\t\t\t});\n\t\t\tthis.clickedCleaner();\n\t\t\treturn this;\n\t\t}\n\n\t});\n\n\tElement.implement('formUpdate', function(update, options){\n\t\tvar fq = this.retrieve('form.request');\n\t\tif (!fq){\n\t\t\tfq = new Form.Request(this, update, options);\n\t\t} else {\n\t\t\tif (update) fq.setTarget(update);\n\t\t\tif (options) fq.setOptions(options).makeRequest();\n\t\t}\n\t\tfq.send();\n\t\treturn this;\n\t});\n\n})();\n\n\n/*\n---\n\nscript: Fx.Reveal.js\n\nname: Fx.Reveal\n\ndescription: Defines Fx.Reveal, a class that shows and hides elements with a transition.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Fx.Morph\n - /Element.Shortcuts\n - /Element.Measure\n\nprovides: [Fx.Reveal]\n\n...\n*/\n\n(function(){\n\n\nvar hideTheseOf = function(object){\n\tvar hideThese = object.options.hideInputs;\n\tif (window.OverText){\n\t\tvar otClasses = [null];\n\t\tOverText.each(function(ot){\n\t\t\totClasses.include('.' + ot.options.labelClass);\n\t\t});\n\t\tif (otClasses) hideThese += otClasses.join(', ');\n\t}\n\treturn (hideThese) ? object.element.getElements(hideThese) : null;\n};\n\n\nFx.Reveal = new Class({\n\n\tExtends: Fx.Morph,\n\n\toptions: {/*\n\t\tonShow: function(thisElement){},\n\t\tonHide: function(thisElement){},\n\t\tonComplete: function(thisElement){},\n\t\theightOverride: null,\n\t\twidthOverride: null,*/\n\t\tlink: 'cancel',\n\t\tstyles: ['padding', 'border', 'margin'],\n\t\ttransitionOpacity: !Browser.ie6,\n\t\tmode: 'vertical',\n\t\tdisplay: function(){\n\t\t\treturn this.element.get('tag') != 'tr' ? 'block' : 'table-row';\n\t\t},\n\t\topacity: 1,\n\t\thideInputs: Browser.ie ? 'select, input, textarea, object, embed' : null\n\t},\n\n\tdissolve: function(){\n\t\tif (!this.hiding && !this.showing){\n\t\t\tif (this.element.getStyle('display') != 'none'){\n\t\t\t\tthis.hiding = true;\n\t\t\t\tthis.showing = false;\n\t\t\t\tthis.hidden = true;\n\t\t\t\tthis.cssText = this.element.style.cssText;\n\n\t\t\t\tvar startStyles = this.element.getComputedSize({\n\t\t\t\t\tstyles: this.options.styles,\n\t\t\t\t\tmode: this.options.mode\n\t\t\t\t});\n\t\t\t\tif (this.options.transitionOpacity) startStyles.opacity = this.options.opacity;\n\n\t\t\t\tvar zero = {};\n\t\t\t\tObject.each(startStyles, function(style, name){\n\t\t\t\t\tzero[name] = [style, 0];\n\t\t\t\t});\n\n\t\t\t\tthis.element.setStyles({\n\t\t\t\t\tdisplay: Function.from(this.options.display).call(this),\n\t\t\t\t\toverflow: 'hidden'\n\t\t\t\t});\n\n\t\t\t\tvar hideThese = hideTheseOf(this);\n\t\t\t\tif (hideThese) hideThese.setStyle('visibility', 'hidden');\n\n\t\t\t\tthis.$chain.unshift(function(){\n\t\t\t\t\tif (this.hidden){\n\t\t\t\t\t\tthis.hiding = false;\n\t\t\t\t\t\tthis.element.style.cssText = this.cssText;\n\t\t\t\t\t\tthis.element.setStyle('display', 'none');\n\t\t\t\t\t\tif (hideThese) hideThese.setStyle('visibility', 'visible');\n\t\t\t\t\t}\n\t\t\t\t\tthis.fireEvent('hide', this.element);\n\t\t\t\t\tthis.callChain();\n\t\t\t\t}.bind(this));\n\n\t\t\t\tthis.start(zero);\n\t\t\t} else {\n\t\t\t\tthis.callChain.delay(10, this);\n\t\t\t\tthis.fireEvent('complete', this.element);\n\t\t\t\tthis.fireEvent('hide', this.element);\n\t\t\t}\n\t\t} else if (this.options.link == 'chain'){\n\t\t\tthis.chain(this.dissolve.bind(this));\n\t\t} else if (this.options.link == 'cancel' && !this.hiding){\n\t\t\tthis.cancel();\n\t\t\tthis.dissolve();\n\t\t}\n\t\treturn this;\n\t},\n\n\treveal: function(){\n\t\tif (!this.showing && !this.hiding){\n\t\t\tif (this.element.getStyle('display') == 'none'){\n\t\t\t\tthis.hiding = false;\n\t\t\t\tthis.showing = true;\n\t\t\t\tthis.hidden = false;\n\t\t\t\tthis.cssText = this.element.style.cssText;\n\n\t\t\t\tvar startStyles;\n\t\t\t\tthis.element.measure(function(){\n\t\t\t\t\tstartStyles = this.element.getComputedSize({\n\t\t\t\t\t\tstyles: this.options.styles,\n\t\t\t\t\t\tmode: this.options.mode\n\t\t\t\t\t});\n\t\t\t\t}.bind(this));\n\t\t\t\tif (this.options.heightOverride != null) startStyles.height = this.options.heightOverride.toInt();\n\t\t\t\tif (this.options.widthOverride != null) startStyles.width = this.options.widthOverride.toInt();\n\t\t\t\tif (this.options.transitionOpacity){\n\t\t\t\t\tthis.element.setStyle('opacity', 0);\n\t\t\t\t\tstartStyles.opacity = this.options.opacity;\n\t\t\t\t}\n\n\t\t\t\tvar zero = {\n\t\t\t\t\theight: 0,\n\t\t\t\t\tdisplay: Function.from(this.options.display).call(this)\n\t\t\t\t};\n\t\t\t\tObject.each(startStyles, function(style, name){\n\t\t\t\t\tzero[name] = 0;\n\t\t\t\t});\n\t\t\t\tzero.overflow = 'hidden';\n\n\t\t\t\tthis.element.setStyles(zero);\n\n\t\t\t\tvar hideThese = hideTheseOf(this);\n\t\t\t\tif (hideThese) hideThese.setStyle('visibility', 'hidden');\n\n\t\t\t\tthis.$chain.unshift(function(){\n\t\t\t\t\tthis.element.style.cssText = this.cssText;\n\t\t\t\t\tthis.element.setStyle('display', Function.from(this.options.display).call(this));\n\t\t\t\t\tif (!this.hidden) this.showing = false;\n\t\t\t\t\tif (hideThese) hideThese.setStyle('visibility', 'visible');\n\t\t\t\t\tthis.callChain();\n\t\t\t\t\tthis.fireEvent('show', this.element);\n\t\t\t\t}.bind(this));\n\n\t\t\t\tthis.start(startStyles);\n\t\t\t} else {\n\t\t\t\tthis.callChain();\n\t\t\t\tthis.fireEvent('complete', this.element);\n\t\t\t\tthis.fireEvent('show', this.element);\n\t\t\t}\n\t\t} else if (this.options.link == 'chain'){\n\t\t\tthis.chain(this.reveal.bind(this));\n\t\t} else if (this.options.link == 'cancel' && !this.showing){\n\t\t\tthis.cancel();\n\t\t\tthis.reveal();\n\t\t}\n\t\treturn this;\n\t},\n\n\ttoggle: function(){\n\t\tif (this.element.getStyle('display') == 'none'){\n\t\t\tthis.reveal();\n\t\t} else {\n\t\t\tthis.dissolve();\n\t\t}\n\t\treturn this;\n\t},\n\n\tcancel: function(){\n\t\tthis.parent.apply(this, arguments);\n\t\tif (this.cssText != null) this.element.style.cssText = this.cssText;\n\t\tthis.hiding = false;\n\t\tthis.showing = false;\n\t\treturn this;\n\t}\n\n});\n\nElement.Properties.reveal = {\n\n\tset: function(options){\n\t\tthis.get('reveal').cancel().setOptions(options);\n\t\treturn this;\n\t},\n\n\tget: function(){\n\t\tvar reveal = this.retrieve('reveal');\n\t\tif (!reveal){\n\t\t\treveal = new Fx.Reveal(this);\n\t\t\tthis.store('reveal', reveal);\n\t\t}\n\t\treturn reveal;\n\t}\n\n};\n\nElement.Properties.dissolve = Element.Properties.reveal;\n\nElement.implement({\n\n\treveal: function(options){\n\t\tthis.get('reveal').setOptions(options).reveal();\n\t\treturn this;\n\t},\n\n\tdissolve: function(options){\n\t\tthis.get('reveal').setOptions(options).dissolve();\n\t\treturn this;\n\t},\n\n\tnix: function(options){\n\t\tvar params = Array.link(arguments, {destroy: Type.isBoolean, options: Type.isObject});\n\t\tthis.get('reveal').setOptions(options).dissolve().chain(function(){\n\t\t\tthis[params.destroy ? 'destroy' : 'dispose']();\n\t\t}.bind(this));\n\t\treturn this;\n\t},\n\n\twink: function(){\n\t\tvar params = Array.link(arguments, {duration: Type.isNumber, options: Type.isObject});\n\t\tvar reveal = this.get('reveal').setOptions(params.options);\n\t\treveal.reveal().chain(function(){\n\t\t\t(function(){\n\t\t\t\treveal.dissolve();\n\t\t\t}).delay(params.duration || 2000);\n\t\t});\n\t}\n\n});\n\n})();\n\n\n/*\n---\n\nscript: Form.Request.Append.js\n\nname: Form.Request.Append\n\ndescription: Handles the basic functionality of submitting a form and updating a dom element with the result. The result is appended to the DOM element instead of replacing its contents.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - /Form.Request\n - /Fx.Reveal\n - /Elements.from\n\nprovides: [Form.Request.Append]\n\n...\n*/\n\nForm.Request.Append = new Class({\n\n\tExtends: Form.Request,\n\n\toptions: {\n\t\t//onBeforeEffect: function(){},\n\t\tuseReveal: true,\n\t\trevealOptions: {},\n\t\tinject: 'bottom'\n\t},\n\n\tmakeRequest: function(){\n\t\tthis.request = new Request.HTML(Object.merge({\n\t\t\t\turl: this.element.get('action'),\n\t\t\t\tmethod: this.element.get('method') || 'post',\n\t\t\t\tspinnerTarget: this.element\n\t\t\t}, this.options.requestOptions, {\n\t\t\t\tevalScripts: false\n\t\t\t})\n\t\t).addEvents({\n\t\t\tsuccess: function(tree, elements, html, javascript){\n\t\t\t\tvar container;\n\t\t\t\tvar kids = Elements.from(html);\n\t\t\t\tif (kids.length == 1){\n\t\t\t\t\tcontainer = kids[0];\n\t\t\t\t} else {\n\t\t\t\t\t container = new Element('div', {\n\t\t\t\t\t\tstyles: {\n\t\t\t\t\t\t\tdisplay: 'none'\n\t\t\t\t\t\t}\n\t\t\t\t\t}).adopt(kids);\n\t\t\t\t}\n\t\t\t\tcontainer.inject(this.target, this.options.inject);\n\t\t\t\tif (this.options.requestOptions.evalScripts) Browser.exec(javascript);\n\t\t\t\tthis.fireEvent('beforeEffect', container);\n\t\t\t\tvar finish = function(){\n\t\t\t\t\tthis.fireEvent('success', [container, this.target, tree, elements, html, javascript]);\n\t\t\t\t}.bind(this);\n\t\t\t\tif (this.options.useReveal){\n\t\t\t\t\tcontainer.set('reveal', this.options.revealOptions).get('reveal').chain(finish);\n\t\t\t\t\tcontainer.reveal();\n\t\t\t\t} else {\n\t\t\t\t\tfinish();\n\t\t\t\t}\n\t\t\t}.bind(this),\n\t\t\tfailure: function(xhr){\n\t\t\t\tthis.fireEvent('failure', xhr);\n\t\t\t}.bind(this)\n\t\t});\n\t\tthis.attachReset();\n\t}\n\n});\n\n\n/*\n---\n\nname: Locale.en-US.Form.Validator\n\ndescription: Form Validator messages for English.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - /Locale\n\nprovides: [Locale.en-US.Form.Validator]\n\n...\n*/\n\nLocale.define('en-US', 'FormValidator', {\n\n\trequired: 'This field is required.',\n\tlength: 'Please enter {length} characters (you entered {elLength} characters)',\n\tminLength: 'Please enter at least {minLength} characters (you entered {length} characters).',\n\tmaxLength: 'Please enter no more than {maxLength} characters (you entered {length} characters).',\n\tinteger: 'Please enter an integer in this field. Numbers with decimals (e.g. 1.25) are not permitted.',\n\tnumeric: 'Please enter only numeric values in this field (i.e. \"1\" or \"1.1\" or \"-1\" or \"-1.1\").',\n\tdigits: 'Please use numbers and punctuation only in this field (for example, a phone number with dashes or dots is permitted).',\n\talpha: 'Please use only letters (a-z) within this field. No spaces or other characters are allowed.',\n\talphanum: 'Please use only letters (a-z) or numbers (0-9) in this field. No spaces or other characters are allowed.',\n\tdateSuchAs: 'Please enter a valid date such as {date}',\n\tdateInFormatMDY: 'Please enter a valid date such as MM/DD/YYYY (i.e. \"12/31/1999\")',\n\temail: 'Please enter a valid email address. For example \"fred@domain.com\".',\n\turl: 'Please enter a valid URL such as http://www.example.com.',\n\tcurrencyDollar: 'Please enter a valid $ amount. For example $100.00 .',\n\toneRequired: 'Please enter something for at least one of these inputs.',\n\terrorPrefix: 'Error: ',\n\twarningPrefix: 'Warning: ',\n\n\t// Form.Validator.Extras\n\tnoSpace: 'There can be no spaces in this input.',\n\treqChkByNode: 'No items are selected.',\n\trequiredChk: 'This field is required.',\n\treqChkByName: 'Please select a {label}.',\n\tmatch: 'This field needs to match the {matchName} field',\n\tstartDate: 'the start date',\n\tendDate: 'the end date',\n\tcurrendDate: 'the current date',\n\tafterDate: 'The date should be the same or after {label}.',\n\tbeforeDate: 'The date should be the same or before {label}.',\n\tstartMonth: 'Please select a start month',\n\tsameMonth: 'These two dates must be in the same month - you must change one or the other.',\n\tcreditcard: 'The credit card number entered is invalid. Please check the number and try again. {length} digits entered.'\n\n});\n\n\n/*\n---\n\nscript: Form.Validator.js\n\nname: Form.Validator\n\ndescription: A css-class based form validation system.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Options\n - Core/Events\n - Core/Slick.Finder\n - Core/Element.Event\n - Core/Element.Style\n - Core/JSON\n - /Locale\n - /Class.Binds\n - /Date\n - /Element.Forms\n - /Locale.en-US.Form.Validator\n - /Element.Shortcuts\n\nprovides: [Form.Validator, InputValidator, FormValidator.BaseValidators]\n\n...\n*/\nif (!window.Form) window.Form = {};\n\nvar InputValidator = this.InputValidator = new Class({\n\n\tImplements: [Options],\n\n\toptions: {\n\t\terrorMsg: 'Validation failed.',\n\t\ttest: Function.from(true)\n\t},\n\n\tinitialize: function(className, options){\n\t\tthis.setOptions(options);\n\t\tthis.className = className;\n\t},\n\n\ttest: function(field, props){\n\t\tfield = document.id(field);\n\t\treturn (field) ? this.options.test(field, props || this.getProps(field)) : false;\n\t},\n\n\tgetError: function(field, props){\n\t\tfield = document.id(field);\n\t\tvar err = this.options.errorMsg;\n\t\tif (typeOf(err) == 'function') err = err(field, props || this.getProps(field));\n\t\treturn err;\n\t},\n\n\tgetProps: function(field){\n\t\tfield = document.id(field);\n\t\treturn (field) ? field.get('validatorProps') : {};\n\t}\n\n});\n\nElement.Properties.validators = {\n\n\tget: function(){\n\t\treturn (this.get('data-validators') || this.className).clean().split(' ');\n\t}\n\n};\n\nElement.Properties.validatorProps = {\n\n\tset: function(props){\n\t\treturn this.eliminate('$moo:validatorProps').store('$moo:validatorProps', props);\n\t},\n\n\tget: function(props){\n\t\tif (props) this.set(props);\n\t\tif (this.retrieve('$moo:validatorProps')) return this.retrieve('$moo:validatorProps');\n\t\tif (this.getProperty('data-validator-properties') || this.getProperty('validatorProps')){\n\t\t\ttry {\n\t\t\t\tthis.store('$moo:validatorProps', JSON.decode(this.getProperty('validatorProps') || this.getProperty('data-validator-properties')));\n\t\t\t}catch(e){\n\t\t\t\treturn {};\n\t\t\t}\n\t\t} else {\n\t\t\tvar vals = this.get('validators').filter(function(cls){\n\t\t\t\treturn cls.test(':');\n\t\t\t});\n\t\t\tif (!vals.length){\n\t\t\t\tthis.store('$moo:validatorProps', {});\n\t\t\t} else {\n\t\t\t\tprops = {};\n\t\t\t\tvals.each(function(cls){\n\t\t\t\t\tvar split = cls.split(':');\n\t\t\t\t\tif (split[1]){\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tprops[split[0]] = JSON.decode(split[1]);\n\t\t\t\t\t\t} catch(e){}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis.store('$moo:validatorProps', props);\n\t\t\t}\n\t\t}\n\t\treturn this.retrieve('$moo:validatorProps');\n\t}\n\n};\n\nForm.Validator = new Class({\n\n\tImplements: [Options, Events],\n\n\tBinds: ['onSubmit'],\n\n\toptions: {/*\n\t\tonFormValidate: function(isValid, form, event){},\n\t\tonElementValidate: function(isValid, field, className, warn){},\n\t\tonElementPass: function(field){},\n\t\tonElementFail: function(field, validatorsFailed){}, */\n\t\tfieldSelectors: 'input, select, textarea',\n\t\tignoreHidden: true,\n\t\tignoreDisabled: true,\n\t\tuseTitles: false,\n\t\tevaluateOnSubmit: true,\n\t\tevaluateFieldsOnBlur: true,\n\t\tevaluateFieldsOnChange: true,\n\t\tserial: true,\n\t\tstopOnFailure: true,\n\t\twarningPrefix: function(){\n\t\t\treturn Form.Validator.getMsg('warningPrefix') || 'Warning: ';\n\t\t},\n\t\terrorPrefix: function(){\n\t\t\treturn Form.Validator.getMsg('errorPrefix') || 'Error: ';\n\t\t}\n\t},\n\n\tinitialize: function(form, options){\n\t\tthis.setOptions(options);\n\t\tthis.element = document.id(form);\n\t\tthis.element.store('validator', this);\n\t\tthis.warningPrefix = Function.from(this.options.warningPrefix)();\n\t\tthis.errorPrefix = Function.from(this.options.errorPrefix)();\n\t\tif (this.options.evaluateOnSubmit) this.element.addEvent('submit', this.onSubmit);\n\t\tif (this.options.evaluateFieldsOnBlur || this.options.evaluateFieldsOnChange) this.watchFields(this.getFields());\n\t},\n\n\ttoElement: function(){\n\t\treturn this.element;\n\t},\n\n\tgetFields: function(){\n\t\treturn (this.fields = this.element.getElements(this.options.fieldSelectors));\n\t},\n\n\twatchFields: function(fields){\n\t\tfields.each(function(el){\n\t\t\tif (this.options.evaluateFieldsOnBlur)\n\t\t\t\tel.addEvent('blur', this.validationMonitor.pass([el, false], this));\n\t\t\tif (this.options.evaluateFieldsOnChange)\n\t\t\t\tel.addEvent('change', this.validationMonitor.pass([el, true], this));\n\t\t}, this);\n\t},\n\n\tvalidationMonitor: function(){\n\t\tclearTimeout(this.timer);\n\t\tthis.timer = this.validateField.delay(50, this, arguments);\n\t},\n\n\tonSubmit: function(event){\n\t\tif (this.validate(event)) this.reset();\n\t},\n\n\treset: function(){\n\t\tthis.getFields().each(this.resetField, this);\n\t\treturn this;\n\t},\n\n\tvalidate: function(event){\n\t\tvar result = this.getFields().map(function(field){\n\t\t\treturn this.validateField(field, true);\n\t\t}, this).every(function(v){\n\t\t\treturn v;\n\t\t});\n\t\tthis.fireEvent('formValidate', [result, this.element, event]);\n\t\tif (this.options.stopOnFailure && !result && event) event.preventDefault();\n\t\treturn result;\n\t},\n\n\tvalidateField: function(field, force){\n\t\tif (this.paused) return true;\n\t\tfield = document.id(field);\n\t\tvar passed = !field.hasClass('validation-failed');\n\t\tvar failed, warned;\n\t\tif (this.options.serial && !force){\n\t\t\tfailed = this.element.getElement('.validation-failed');\n\t\t\twarned = this.element.getElement('.warning');\n\t\t}\n\t\tif (field && (!failed || force || field.hasClass('validation-failed') || (failed && !this.options.serial))){\n\t\t\tvar validationTypes = field.get('validators');\n\t\t\tvar validators = validationTypes.some(function(cn){\n\t\t\t\treturn this.getValidator(cn);\n\t\t\t}, this);\n\t\t\tvar validatorsFailed = [];\n\t\t\tvalidationTypes.each(function(className){\n\t\t\t\tif (className && !this.test(className, field)) validatorsFailed.include(className);\n\t\t\t}, this);\n\t\t\tpassed = validatorsFailed.length === 0;\n\t\t\tif (validators && !this.hasValidator(field, 'warnOnly')){\n\t\t\t\tif (passed){\n\t\t\t\t\tfield.addClass('validation-passed').removeClass('validation-failed');\n\t\t\t\t\tthis.fireEvent('elementPass', [field]);\n\t\t\t\t} else {\n\t\t\t\t\tfield.addClass('validation-failed').removeClass('validation-passed');\n\t\t\t\t\tthis.fireEvent('elementFail', [field, validatorsFailed]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!warned){\n\t\t\t\tvar warnings = validationTypes.some(function(cn){\n\t\t\t\t\tif (cn.test('^warn'))\n\t\t\t\t\t\treturn this.getValidator(cn.replace(/^warn-/,''));\n\t\t\t\t\telse return null;\n\t\t\t\t}, this);\n\t\t\t\tfield.removeClass('warning');\n\t\t\t\tvar warnResult = validationTypes.map(function(cn){\n\t\t\t\t\tif (cn.test('^warn'))\n\t\t\t\t\t\treturn this.test(cn.replace(/^warn-/,''), field, true);\n\t\t\t\t\telse return null;\n\t\t\t\t}, this);\n\t\t\t}\n\t\t}\n\t\treturn passed;\n\t},\n\n\ttest: function(className, field, warn){\n\t\tfield = document.id(field);\n\t\tif ((this.options.ignoreHidden && !field.isVisible()) || (this.options.ignoreDisabled && field.get('disabled'))) return true;\n\t\tvar validator = this.getValidator(className);\n\t\tif (warn != null) warn = false;\n\t\tif (this.hasValidator(field, 'warnOnly')) warn = true;\n\t\tvar isValid = this.hasValidator(field, 'ignoreValidation') || (validator ? validator.test(field) : true);\n\t\tif (validator && field.isVisible()) this.fireEvent('elementValidate', [isValid, field, className, warn]);\n\t\tif (warn) return true;\n\t\treturn isValid;\n\t},\n\n\thasValidator: function(field, value){\n\t\treturn field.get('validators').contains(value);\n\t},\n\n\tresetField: function(field){\n\t\tfield = document.id(field);\n\t\tif (field){\n\t\t\tfield.get('validators').each(function(className){\n\t\t\t\tif (className.test('^warn-')) className = className.replace(/^warn-/, '');\n\t\t\t\tfield.removeClass('validation-failed');\n\t\t\t\tfield.removeClass('warning');\n\t\t\t\tfield.removeClass('validation-passed');\n\t\t\t}, this);\n\t\t}\n\t\treturn this;\n\t},\n\n\tstop: function(){\n\t\tthis.paused = true;\n\t\treturn this;\n\t},\n\n\tstart: function(){\n\t\tthis.paused = false;\n\t\treturn this;\n\t},\n\n\tignoreField: function(field, warn){\n\t\tfield = document.id(field);\n\t\tif (field){\n\t\t\tthis.enforceField(field);\n\t\t\tif (warn) field.addClass('warnOnly');\n\t\t\telse field.addClass('ignoreValidation');\n\t\t}\n\t\treturn this;\n\t},\n\n\tenforceField: function(field){\n\t\tfield = document.id(field);\n\t\tif (field) field.removeClass('warnOnly').removeClass('ignoreValidation');\n\t\treturn this;\n\t}\n\n});\n\nForm.Validator.getMsg = function(key){\n\treturn Locale.get('FormValidator.' + key);\n};\n\nForm.Validator.adders = {\n\n\tvalidators:{},\n\n\tadd : function(className, options){\n\t\tthis.validators[className] = new InputValidator(className, options);\n\t\t//if this is a class (this method is used by instances of Form.Validator and the Form.Validator namespace)\n\t\t//extend these validators into it\n\t\t//this allows validators to be global and/or per instance\n\t\tif (!this.initialize){\n\t\t\tthis.implement({\n\t\t\t\tvalidators: this.validators\n\t\t\t});\n\t\t}\n\t},\n\n\taddAllThese : function(validators){\n\t\tArray.from(validators).each(function(validator){\n\t\t\tthis.add(validator[0], validator[1]);\n\t\t}, this);\n\t},\n\n\tgetValidator: function(className){\n\t\treturn this.validators[className.split(':')[0]];\n\t}\n\n};\n\nObject.append(Form.Validator, Form.Validator.adders);\n\nForm.Validator.implement(Form.Validator.adders);\n\nForm.Validator.add('IsEmpty', {\n\n\terrorMsg: false,\n\ttest: function(element){\n\t\tif (element.type == 'select-one' || element.type == 'select')\n\t\t\treturn !(element.selectedIndex >= 0 && element.options[element.selectedIndex].value != '');\n\t\telse\n\t\t\treturn ((element.get('value') == null) || (element.get('value').length == 0));\n\t}\n\n});\n\nForm.Validator.addAllThese([\n\n\t['required', {\n\t\terrorMsg: function(){\n\t\t\treturn Form.Validator.getMsg('required');\n\t\t},\n\t\ttest: function(element){\n\t\t\treturn !Form.Validator.getValidator('IsEmpty').test(element);\n\t\t}\n\t}],\n\n\t['length', {\n\t\terrorMsg: function(element, props){\n\t\t\tif (typeOf(props.length) != 'null')\n\t\t\t\treturn Form.Validator.getMsg('length').substitute({length: props.length, elLength: element.get('value').length});\n\t\t\telse return '';\n\t\t},\n\t\ttest: function(element, props){\n\t\t\tif (typeOf(props.length) != 'null') return (element.get('value').length == props.length || element.get('value').length == 0);\n\t\t\telse return true;\n\t\t}\n\t}],\t\n\n\t['minLength', {\n\t\terrorMsg: function(element, props){\n\t\t\tif (typeOf(props.minLength) != 'null')\n\t\t\t\treturn Form.Validator.getMsg('minLength').substitute({minLength: props.minLength, length: element.get('value').length});\n\t\t\telse return '';\n\t\t},\n\t\ttest: function(element, props){\n\t\t\tif (typeOf(props.minLength) != 'null') return (element.get('value').length >= (props.minLength || 0));\n\t\t\telse return true;\n\t\t}\n\t}],\n\n\t['maxLength', {\n\t\terrorMsg: function(element, props){\n\t\t\t//props is {maxLength:10}\n\t\t\tif (typeOf(props.maxLength) != 'null')\n\t\t\t\treturn Form.Validator.getMsg('maxLength').substitute({maxLength: props.maxLength, length: element.get('value').length});\n\t\t\telse return '';\n\t\t},\n\t\ttest: function(element, props){\n\t\t\treturn element.get('value').length <= (props.maxLength || 10000);\n\t\t}\n\t}],\n\n\t['validate-integer', {\n\t\terrorMsg: Form.Validator.getMsg.pass('integer'),\n\t\ttest: function(element){\n\t\t\treturn Form.Validator.getValidator('IsEmpty').test(element) || (/^(-?[1-9]\\d*|0)$/).test(element.get('value'));\n\t\t}\n\t}],\n\n\t['validate-numeric', {\n\t\terrorMsg: Form.Validator.getMsg.pass('numeric'),\n\t\ttest: function(element){\n\t\t\treturn Form.Validator.getValidator('IsEmpty').test(element) ||\n\t\t\t\t(/^-?(?:0$0(?=\\d*\\.)|[1-9]|0)\\d*(\\.\\d+)?$/).test(element.get('value'));\n\t\t}\n\t}],\n\n\t['validate-digits', {\n\t\terrorMsg: Form.Validator.getMsg.pass('digits'),\n\t\ttest: function(element){\n\t\t\treturn Form.Validator.getValidator('IsEmpty').test(element) || (/^[\\d() .:\\-\\+#]+$/.test(element.get('value')));\n\t\t}\n\t}],\n\n\t['validate-alpha', {\n\t\terrorMsg: Form.Validator.getMsg.pass('alpha'),\n\t\ttest: function(element){\n\t\t\treturn Form.Validator.getValidator('IsEmpty').test(element) || (/^[a-zA-Z]+$/).test(element.get('value'));\n\t\t}\n\t}],\n\n\t['validate-alphanum', {\n\t\terrorMsg: Form.Validator.getMsg.pass('alphanum'),\n\t\ttest: function(element){\n\t\t\treturn Form.Validator.getValidator('IsEmpty').test(element) || !(/\\W/).test(element.get('value'));\n\t\t}\n\t}],\n\n\t['validate-date', {\n\t\terrorMsg: function(element, props){\n\t\t\tif (Date.parse){\n\t\t\t\tvar format = props.dateFormat || '%x';\n\t\t\t\treturn Form.Validator.getMsg('dateSuchAs').substitute({date: new Date().format(format)});\n\t\t\t} else {\n\t\t\t\treturn Form.Validator.getMsg('dateInFormatMDY');\n\t\t\t}\n\t\t},\n\t\ttest: function(element, props){\n\t\t\tif (Form.Validator.getValidator('IsEmpty').test(element)) return true;\n\t\t\tvar dateLocale = Locale.getCurrent().sets.Date,\n\t\t\t\tdateNouns = new RegExp([dateLocale.days, dateLocale.days_abbr, dateLocale.months, dateLocale.months_abbr].flatten().join('|'), 'i'),\n\t\t\t\tvalue = element.get('value'),\n\t\t\t\twordsInValue = value.match(/[a-z]+/gi);\n\n\t\t\t\tif (wordsInValue && !wordsInValue.every(dateNouns.exec, dateNouns)) return false;\n\n\t\t\t\tvar date = Date.parse(value),\n\t\t\t\t\tformat = props.dateFormat || '%x',\n\t\t\t\t\tformatted = date.format(format);\n\n\t\t\t\tif (formatted != 'invalid date') element.set('value', formatted);\n\t\t\t\treturn date.isValid();\n\t\t}\n\t}],\n\n\t['validate-email', {\n\t\terrorMsg: Form.Validator.getMsg.pass('email'),\n\t\ttest: function(element){\n\t\t\t/*\n\t\t\tvar chars = \"[a-z0-9!#$%&'*+/=?^_`{|}~-]\",\n\t\t\t\tlocal = '(?:' + chars + '\\\\.?){0,63}' + chars,\n\n\t\t\t\tlabel = '[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?',\n\t\t\t\thostname = '(?:' + label + '\\\\.)*' + label;\n\n\t\t\t\toctet = '(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)',\n\t\t\t\tipv4 = '\\\\[(?:' + octet + '\\\\.){3}' + octet + '\\\\]',\n\n\t\t\t\tdomain = '(?:' + hostname + '|' + ipv4 + ')';\n\n\t\t\tvar regex = new RegExp('^' + local + '@' + domain + '$', 'i');\n\t\t\t*/\n\t\t\treturn Form.Validator.getValidator('IsEmpty').test(element) || (/^(?:[a-z0-9!#$%&'*+\\/=?^_`{|}~-]\\.?){0,63}[a-z0-9!#$%&'*+\\/=?^_`{|}~-]@(?:(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\])$/i).test(element.get('value'));\n\t\t}\n\t}],\n\n\t['validate-url', {\n\t\terrorMsg: Form.Validator.getMsg.pass('url'),\n\t\ttest: function(element){\n\t\t\treturn Form.Validator.getValidator('IsEmpty').test(element) || (/^(https?|ftp|rmtp|mms):\\/\\/(([A-Z0-9][A-Z0-9_-]*)(\\.[A-Z0-9][A-Z0-9_-]*)+)(:(\\d+))?\\/?/i).test(element.get('value'));\n\t\t}\n\t}],\n\n\t['validate-currency-dollar', {\n\t\terrorMsg: Form.Validator.getMsg.pass('currencyDollar'),\n\t\ttest: function(element){\n\t\t\treturn Form.Validator.getValidator('IsEmpty').test(element) || (/^\\$?\\-?([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}\\d*(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$/).test(element.get('value'));\n\t\t}\n\t}],\n\n\t['validate-one-required', {\n\t\terrorMsg: Form.Validator.getMsg.pass('oneRequired'),\n\t\ttest: function(element, props){\n\t\t\tvar p = document.id(props['validate-one-required']) || element.getParent(props['validate-one-required']);\n\t\t\treturn p.getElements('input').some(function(el){\n\t\t\t\tif (['checkbox', 'radio'].contains(el.get('type'))) return el.get('checked');\n\t\t\t\treturn el.get('value');\n\t\t\t});\n\t\t}\n\t}]\n\n]);\n\nElement.Properties.validator = {\n\n\tset: function(options){\n\t\tthis.get('validator').setOptions(options);\n\t},\n\n\tget: function(){\n\t\tvar validator = this.retrieve('validator');\n\t\tif (!validator){\n\t\t\tvalidator = new Form.Validator(this);\n\t\t\tthis.store('validator', validator);\n\t\t}\n\t\treturn validator;\n\t}\n\n};\n\nElement.implement({\n\n\tvalidate: function(options){\n\t\tif (options) this.set('validator', options);\n\t\treturn this.get('validator').validate();\n\t}\n\n});\n\n\n\n\n\n\n\n/*\n---\n\nscript: Form.Validator.Inline.js\n\nname: Form.Validator.Inline\n\ndescription: Extends Form.Validator to add inline messages.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - /Form.Validator\n\nprovides: [Form.Validator.Inline]\n\n...\n*/\n\nForm.Validator.Inline = new Class({\n\n\tExtends: Form.Validator,\n\n\toptions: {\n\t\tshowError: function(errorElement){\n\t\t\tif (errorElement.reveal) errorElement.reveal();\n\t\t\telse errorElement.setStyle('display', 'block');\n\t\t},\n\t\thideError: function(errorElement){\n\t\t\tif (errorElement.dissolve) errorElement.dissolve();\n\t\t\telse errorElement.setStyle('display', 'none');\n\t\t},\n\t\tscrollToErrorsOnSubmit: true,\n\t\tscrollToErrorsOnBlur: false,\n\t\tscrollToErrorsOnChange: false,\n\t\tscrollFxOptions: {\n\t\t\ttransition: 'quad:out',\n\t\t\toffset: {\n\t\t\t\ty: -20\n\t\t\t}\n\t\t}\n\t},\n\n\tinitialize: function(form, options){\n\t\tthis.parent(form, options);\n\t\tthis.addEvent('onElementValidate', function(isValid, field, className, warn){\n\t\t\tvar validator = this.getValidator(className);\n\t\t\tif (!isValid && validator.getError(field)){\n\t\t\t\tif (warn) field.addClass('warning');\n\t\t\t\tvar advice = this.makeAdvice(className, field, validator.getError(field), warn);\n\t\t\t\tthis.insertAdvice(advice, field);\n\t\t\t\tthis.showAdvice(className, field);\n\t\t\t} else {\n\t\t\t\tthis.hideAdvice(className, field);\n\t\t\t}\n\t\t});\n\t},\n\n\tmakeAdvice: function(className, field, error, warn){\n\t\tvar errorMsg = (warn) ? this.warningPrefix : this.errorPrefix;\n\t\t\terrorMsg += (this.options.useTitles) ? field.title || error:error;\n\t\tvar cssClass = (warn) ? 'warning-advice' : 'validation-advice';\n\t\tvar advice = this.getAdvice(className, field);\n\t\tif (advice){\n\t\t\tadvice = advice.set('html', errorMsg);\n\t\t} else {\n\t\t\tadvice = new Element('div', {\n\t\t\t\thtml: errorMsg,\n\t\t\t\tstyles: { display: 'none' },\n\t\t\t\tid: 'advice-' + className.split(':')[0] + '-' + this.getFieldId(field)\n\t\t\t}).addClass(cssClass);\n\t\t}\n\t\tfield.store('$moo:advice-' + className, advice);\n\t\treturn advice;\n\t},\n\n\tgetFieldId : function(field){\n\t\treturn field.id ? field.id : field.id = 'input_' + field.name;\n\t},\n\n\tshowAdvice: function(className, field){\n\t\tvar advice = this.getAdvice(className, field);\n\t\tif (\n\t\t\tadvice &&\n\t\t\t!field.retrieve('$moo:' + this.getPropName(className)) &&\n\t\t\t(\n\t\t\t\tadvice.getStyle('display') == 'none' ||\n\t\t\t\tadvice.getStyle('visiblity') == 'hidden' ||\n\t\t\t\tadvice.getStyle('opacity') == 0\n\t\t\t)\n\t\t){\n\t\t\tfield.store('$moo:' + this.getPropName(className), true);\n\t\t\tthis.options.showError(advice);\n\t\t\tthis.fireEvent('showAdvice', [field, advice, className]);\n\t\t}\n\t},\n\n\thideAdvice: function(className, field){\n\t\tvar advice = this.getAdvice(className, field);\n\t\tif (advice && field.retrieve('$moo:' + this.getPropName(className))){\n\t\t\tfield.store('$moo:' + this.getPropName(className), false);\n\t\t\tthis.options.hideError(advice);\n\t\t\tthis.fireEvent('hideAdvice', [field, advice, className]);\n\t\t}\n\t},\n\n\tgetPropName: function(className){\n\t\treturn 'advice' + className;\n\t},\n\n\tresetField: function(field){\n\t\tfield = document.id(field);\n\t\tif (!field) return this;\n\t\tthis.parent(field);\n\t\tfield.get('validators').each(function(className){\n\t\t\tthis.hideAdvice(className, field);\n\t\t}, this);\n\t\treturn this;\n\t},\n\n\tgetAllAdviceMessages: function(field, force){\n\t\tvar advice = [];\n\t\tif (field.hasClass('ignoreValidation') && !force) return advice;\n\t\tvar validators = field.get('validators').some(function(cn){\n\t\t\tvar warner = cn.test('^warn-') || field.hasClass('warnOnly');\n\t\t\tif (warner) cn = cn.replace(/^warn-/, '');\n\t\t\tvar validator = this.getValidator(cn);\n\t\t\tif (!validator) return;\n\t\t\tadvice.push({\n\t\t\t\tmessage: validator.getError(field),\n\t\t\t\twarnOnly: warner,\n\t\t\t\tpassed: validator.test(),\n\t\t\t\tvalidator: validator\n\t\t\t});\n\t\t}, this);\n\t\treturn advice;\n\t},\n\n\tgetAdvice: function(className, field){\n\t\treturn field.retrieve('$moo:advice-' + className);\n\t},\n\n\tinsertAdvice: function(advice, field){\n\t\t//Check for error position prop\n\t\tvar props = field.get('validatorProps');\n\t\t//Build advice\n\t\tif (!props.msgPos || !document.id(props.msgPos)){\n\t\t\tif (field.type && field.type.toLowerCase() == 'radio') field.getParent().adopt(advice);\n\t\t\telse advice.inject(document.id(field), 'after');\n\t\t} else {\n\t\t\tdocument.id(props.msgPos).grab(advice);\n\t\t}\n\t},\n\n\tvalidateField: function(field, force, scroll){\n\t\tvar result = this.parent(field, force);\n\t\tif (((this.options.scrollToErrorsOnSubmit && scroll == null) || scroll) && !result){\n\t\t\tvar failed = document.id(this).getElement('.validation-failed');\n\t\t\tvar par = document.id(this).getParent();\n\t\t\twhile (par != document.body && par.getScrollSize().y == par.getSize().y){\n\t\t\t\tpar = par.getParent();\n\t\t\t}\n\t\t\tvar fx = par.retrieve('$moo:fvScroller');\n\t\t\tif (!fx && window.Fx && Fx.Scroll){\n\t\t\t\tfx = new Fx.Scroll(par, this.options.scrollFxOptions);\n\t\t\t\tpar.store('$moo:fvScroller', fx);\n\t\t\t}\n\t\t\tif (failed){\n\t\t\t\tif (fx) fx.toElement(failed);\n\t\t\t\telse par.scrollTo(par.getScroll().x, failed.getPosition(par).y - 20);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t},\n\n\twatchFields: function(fields){\n\t\tfields.each(function(el){\n\t\tif (this.options.evaluateFieldsOnBlur){\n\t\t\tel.addEvent('blur', this.validationMonitor.pass([el, false, this.options.scrollToErrorsOnBlur], this));\n\t\t}\n\t\tif (this.options.evaluateFieldsOnChange){\n\t\t\t\tel.addEvent('change', this.validationMonitor.pass([el, true, this.options.scrollToErrorsOnChange], this));\n\t\t\t}\n\t\t}, this);\n\t}\n\n});\n\n\n/*\n---\n\nscript: Form.Validator.Extras.js\n\nname: Form.Validator.Extras\n\ndescription: Additional validators for the Form.Validator class.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - /Form.Validator\n\nprovides: [Form.Validator.Extras]\n\n...\n*/\nForm.Validator.addAllThese([\n\n\t['validate-enforce-oncheck', {\n\t\ttest: function(element, props){\n\t\t\tvar fv = element.getParent('form').retrieve('validator');\n\t\t\tif (!fv) return true;\n\t\t\t(props.toEnforce || document.id(props.enforceChildrenOf).getElements('input, select, textarea')).map(function(item){\n\t\t\t\tif (element.checked){\n\t\t\t\t\tfv.enforceField(item);\n\t\t\t\t} else {\n\t\t\t\t\tfv.ignoreField(item);\n\t\t\t\t\tfv.resetField(item);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\t}],\n\n\t['validate-ignore-oncheck', {\n\t\ttest: function(element, props){\n\t\t\tvar fv = element.getParent('form').retrieve('validator');\n\t\t\tif (!fv) return true;\n\t\t\t(props.toIgnore || document.id(props.ignoreChildrenOf).getElements('input, select, textarea')).each(function(item){\n\t\t\t\tif (element.checked){\n\t\t\t\t\tfv.ignoreField(item);\n\t\t\t\t\tfv.resetField(item);\n\t\t\t\t} else {\n\t\t\t\t\tfv.enforceField(item);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\t}],\n\n\t['validate-nospace', {\n\t\terrorMsg: function(){\n\t\t\treturn Form.Validator.getMsg('noSpace');\n\t\t},\n\t\ttest: function(element, props){\n\t\t\treturn !element.get('value').test(/\\s/);\n\t\t}\n\t}],\n\n\t['validate-toggle-oncheck', {\n\t\ttest: function(element, props){\n\t\t\tvar fv = element.getParent('form').retrieve('validator');\n\t\t\tif (!fv) return true;\n\t\t\tvar eleArr = props.toToggle || document.id(props.toToggleChildrenOf).getElements('input, select, textarea');\n\t\t\tif (!element.checked){\n\t\t\t\teleArr.each(function(item){\n\t\t\t\t\tfv.ignoreField(item);\n\t\t\t\t\tfv.resetField(item);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\teleArr.each(function(item){\n\t\t\t\t\tfv.enforceField(item);\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}],\n\n\t['validate-reqchk-bynode', {\n\t\terrorMsg: function(){\n\t\t\treturn Form.Validator.getMsg('reqChkByNode');\n\t\t},\n\t\ttest: function(element, props){\n\t\t\treturn (document.id(props.nodeId).getElements(props.selector || 'input[type=checkbox], input[type=radio]')).some(function(item){\n\t\t\t\treturn item.checked;\n\t\t\t});\n\t\t}\n\t}],\n\n\t['validate-required-check', {\n\t\terrorMsg: function(element, props){\n\t\t\treturn props.useTitle ? element.get('title') : Form.Validator.getMsg('requiredChk');\n\t\t},\n\t\ttest: function(element, props){\n\t\t\treturn !!element.checked;\n\t\t}\n\t}],\n\n\t['validate-reqchk-byname', {\n\t\terrorMsg: function(element, props){\n\t\t\treturn Form.Validator.getMsg('reqChkByName').substitute({label: props.label || element.get('type')});\n\t\t},\n\t\ttest: function(element, props){\n\t\t\tvar grpName = props.groupName || element.get('name');\n\t\t\tvar oneCheckedItem = $$(document.getElementsByName(grpName)).some(function(item, index){\n\t\t\t\treturn item.checked;\n\t\t\t});\n\t\t\tvar fv = element.getParent('form').retrieve('validator');\n\t\t\tif (oneCheckedItem && fv) fv.resetField(element);\n\t\t\treturn oneCheckedItem;\n\t\t}\n\t}],\n\n\t['validate-match', {\n\t\terrorMsg: function(element, props){\n\t\t\treturn Form.Validator.getMsg('match').substitute({matchName: props.matchName || document.id(props.matchInput).get('name')});\n\t\t},\n\t\ttest: function(element, props){\n\t\t\tvar eleVal = element.get('value');\n\t\t\tvar matchVal = document.id(props.matchInput) && document.id(props.matchInput).get('value');\n\t\t\treturn eleVal && matchVal ? eleVal == matchVal : true;\n\t\t}\n\t}],\n\n\t['validate-after-date', {\n\t\terrorMsg: function(element, props){\n\t\t\treturn Form.Validator.getMsg('afterDate').substitute({\n\t\t\t\tlabel: props.afterLabel || (props.afterElement ? Form.Validator.getMsg('startDate') : Form.Validator.getMsg('currentDate'))\n\t\t\t});\n\t\t},\n\t\ttest: function(element, props){\n\t\t\tvar start = document.id(props.afterElement) ? Date.parse(document.id(props.afterElement).get('value')) : new Date();\n\t\t\tvar end = Date.parse(element.get('value'));\n\t\t\treturn end && start ? end >= start : true;\n\t\t}\n\t}],\n\n\t['validate-before-date', {\n\t\terrorMsg: function(element, props){\n\t\t\treturn Form.Validator.getMsg('beforeDate').substitute({\n\t\t\t\tlabel: props.beforeLabel || (props.beforeElement ? Form.Validator.getMsg('endDate') : Form.Validator.getMsg('currentDate'))\n\t\t\t});\n\t\t},\n\t\ttest: function(element, props){\n\t\t\tvar start = Date.parse(element.get('value'));\n\t\t\tvar end = document.id(props.beforeElement) ? Date.parse(document.id(props.beforeElement).get('value')) : new Date();\n\t\t\treturn end && start ? end >= start : true;\n\t\t}\n\t}],\n\n\t['validate-custom-required', {\n\t\terrorMsg: function(){\n\t\t\treturn Form.Validator.getMsg('required');\n\t\t},\n\t\ttest: function(element, props){\n\t\t\treturn element.get('value') != props.emptyValue;\n\t\t}\n\t}],\n\n\t['validate-same-month', {\n\t\terrorMsg: function(element, props){\n\t\t\tvar startMo = document.id(props.sameMonthAs) && document.id(props.sameMonthAs).get('value');\n\t\t\tvar eleVal = element.get('value');\n\t\t\tif (eleVal != '') return Form.Validator.getMsg(startMo ? 'sameMonth' : 'startMonth');\n\t\t},\n\t\ttest: function(element, props){\n\t\t\tvar d1 = Date.parse(element.get('value'));\n\t\t\tvar d2 = Date.parse(document.id(props.sameMonthAs) && document.id(props.sameMonthAs).get('value'));\n\t\t\treturn d1 && d2 ? d1.format('%B') == d2.format('%B') : true;\n\t\t}\n\t}],\n\n\n\t['validate-cc-num', {\n\t\terrorMsg: function(element){\n\t\t\tvar ccNum = element.get('value').replace(/[^0-9]/g, '');\n\t\t\treturn Form.Validator.getMsg('creditcard').substitute({length: ccNum.length});\n\t\t},\n\t\ttest: function(element){\n\t\t\t// required is a different test\n\t\t\tif (Form.Validator.getValidator('IsEmpty').test(element)) return true;\n\n\t\t\t// Clean number value\n\t\t\tvar ccNum = element.get('value');\n\t\t\tccNum = ccNum.replace(/[^0-9]/g, '');\n\n\t\t\tvar valid_type = false;\n\n\t\t\tif (ccNum.test(/^4[0-9]{12}([0-9]{3})?$/)) valid_type = 'Visa';\n\t\t\telse if (ccNum.test(/^5[1-5]([0-9]{14})$/)) valid_type = 'Master Card';\n\t\t\telse if (ccNum.test(/^3[47][0-9]{13}$/)) valid_type = 'American Express';\n\t\t\telse if (ccNum.test(/^6011[0-9]{12}$/)) valid_type = 'Discover';\n\n\t\t\tif (valid_type){\n\t\t\t\tvar sum = 0;\n\t\t\t\tvar cur = 0;\n\n\t\t\t\tfor (var i=ccNum.length-1; i>=0; --i){\n\t\t\t\t\tcur = ccNum.charAt(i).toInt();\n\t\t\t\t\tif (cur == 0) continue;\n\n\t\t\t\t\tif ((ccNum.length-i) % 2 == 0) cur += cur;\n\t\t\t\t\tif (cur > 9){\n\t\t\t\t\t\tcur = cur.toString().charAt(0).toInt() + cur.toString().charAt(1).toInt();\n\t\t\t\t\t}\n\n\t\t\t\t\tsum += cur;\n\t\t\t\t}\n\t\t\t\tif ((sum % 10) == 0) return true;\n\t\t\t}\n\n\t\t\tvar chunks = '';\n\t\t\twhile (ccNum != ''){\n\t\t\t\tchunks += ' ' + ccNum.substr(0,4);\n\t\t\t\tccNum = ccNum.substr(4);\n\t\t\t}\n\n\t\t\telement.getParent('form').retrieve('validator').ignoreField(element);\n\t\t\telement.set('value', chunks.clean());\n\t\t\telement.getParent('form').retrieve('validator').enforceField(element);\n\t\t\treturn false;\n\t\t}\n\t}]\n\n\n]);\n\n\n/*\n---\n\nscript: OverText.js\n\nname: OverText\n\ndescription: Shows text over an input that disappears when the user clicks into it. The text remains hidden if the user adds a value.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Options\n - Core/Events\n - Core/Element.Event\n - Class.Binds\n - Class.Occlude\n - Element.Position\n - Element.Shortcuts\n\nprovides: [OverText]\n\n...\n*/\n\nvar OverText = new Class({\n\n\tImplements: [Options, Events, Class.Occlude],\n\n\tBinds: ['reposition', 'assert', 'focus', 'hide'],\n\n\toptions: {/*\n\t\ttextOverride: null,\n\t\tonFocus: function(){},\n\t\tonTextHide: function(textEl, inputEl){},\n\t\tonTextShow: function(textEl, inputEl){}, */\n\t\telement: 'label',\n\t\tlabelClass: 'overTxtLabel',\n\t\tpositionOptions: {\n\t\t\tposition: 'upperLeft',\n\t\t\tedge: 'upperLeft',\n\t\t\toffset: {\n\t\t\t\tx: 4,\n\t\t\t\ty: 2\n\t\t\t}\n\t\t},\n\t\tpoll: false,\n\t\tpollInterval: 250,\n\t\twrap: false\n\t},\n\n\tproperty: 'OverText',\n\n\tinitialize: function(element, options){\n\t\telement = this.element = document.id(element);\n\n\t\tif (this.occlude()) return this.occluded;\n\t\tthis.setOptions(options);\n\n\t\tthis.attach(element);\n\t\tOverText.instances.push(this);\n\n\t\tif (this.options.poll) this.poll();\n\t},\n\n\ttoElement: function(){\n\t\treturn this.element;\n\t},\n\n\tattach: function(){\n\t\tvar element = this.element,\n\t\t\toptions = this.options,\n\t\t\tvalue = options.textOverride || element.get('alt') || element.get('title');\n\n\t\tif (!value) return this;\n\n\t\tvar text = this.text = new Element(options.element, {\n\t\t\t'class': options.labelClass,\n\t\t\tstyles: {\n\t\t\t\tlineHeight: 'normal',\n\t\t\t\tposition: 'absolute',\n\t\t\t\tcursor: 'text'\n\t\t\t},\n\t\t\thtml: value,\n\t\t\tevents: {\n\t\t\t\tclick: this.hide.pass(options.element == 'label', this)\n\t\t\t}\n\t\t}).inject(element, 'after');\n\n\t\tif (options.element == 'label'){\n\t\t\tif (!element.get('id')) element.set('id', 'input_' + String.uniqueID());\n\t\t\ttext.set('for', element.get('id'));\n\t\t}\n\n\t\tif (options.wrap){\n\t\t\tthis.textHolder = new Element('div.overTxtWrapper', {\n\t\t\t\tstyles: {\n\t\t\t\t\tlineHeight: 'normal',\n\t\t\t\t\tposition: 'relative'\n\t\t\t\t}\n\t\t\t}).grab(text).inject(element, 'before');\n\t\t}\n\n\t\treturn this.enable();\n\t},\n\n\tdestroy: function(){\n\t\tthis.element.eliminate(this.property); // Class.Occlude storage\n\t\tthis.disable();\n\t\tif (this.text) this.text.destroy();\n\t\tif (this.textHolder) this.textHolder.destroy();\n\t\treturn this;\n\t},\n\n\tdisable: function(){\n\t\tthis.element.removeEvents({\n\t\t\tfocus: this.focus,\n\t\t\tblur: this.assert,\n\t\t\tchange: this.assert\n\t\t});\n\t\twindow.removeEvent('resize', this.reposition);\n\t\tthis.hide(true, true);\n\t\treturn this;\n\t},\n\n\tenable: function(){\n\t\tthis.element.addEvents({\n\t\t\tfocus: this.focus,\n\t\t\tblur: this.assert,\n\t\t\tchange: this.assert\n\t\t});\n\t\twindow.addEvent('resize', this.reposition);\n\t\tthis.reposition();\n\t\treturn this;\n\t},\n\n\twrap: function(){\n\t\tif (this.options.element == 'label'){\n\t\t\tif (!this.element.get('id')) this.element.set('id', 'input_' + String.uniqueID());\n\t\t\tthis.text.set('for', this.element.get('id'));\n\t\t}\n\t},\n\n\tstartPolling: function(){\n\t\tthis.pollingPaused = false;\n\t\treturn this.poll();\n\t},\n\n\tpoll: function(stop){\n\t\t//start immediately\n\t\t//pause on focus\n\t\t//resumeon blur\n\t\tif (this.poller && !stop) return this;\n\t\tif (stop){\n\t\t\tclearInterval(this.poller);\n\t\t} else {\n\t\t\tthis.poller = (function(){\n\t\t\t\tif (!this.pollingPaused) this.assert(true);\n\t\t\t}).periodical(this.options.pollInterval, this);\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tstopPolling: function(){\n\t\tthis.pollingPaused = true;\n\t\treturn this.poll(true);\n\t},\n\n\tfocus: function(){\n\t\tif (this.text && (!this.text.isDisplayed() || this.element.get('disabled'))) return this;\n\t\treturn this.hide();\n\t},\n\n\thide: function(suppressFocus, force){\n\t\tif (this.text && (this.text.isDisplayed() && (!this.element.get('disabled') || force))){\n\t\t\tthis.text.hide();\n\t\t\tthis.fireEvent('textHide', [this.text, this.element]);\n\t\t\tthis.pollingPaused = true;\n\t\t\tif (!suppressFocus){\n\t\t\t\ttry {\n\t\t\t\t\tthis.element.fireEvent('focus');\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t} catch(e){} //IE barfs if you call focus on hidden elements\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t},\n\n\tshow: function(){\n\t\tif (this.text && !this.text.isDisplayed()){\n\t\t\tthis.text.show();\n\t\t\tthis.reposition();\n\t\t\tthis.fireEvent('textShow', [this.text, this.element]);\n\t\t\tthis.pollingPaused = false;\n\t\t}\n\t\treturn this;\n\t},\n\n\ttest: function(){\n\t\treturn !this.element.get('value');\n\t},\n\n\tassert: function(suppressFocus){\n\t\treturn this[this.test() ? 'show' : 'hide'](suppressFocus);\n\t},\n\n\treposition: function(){\n\t\tthis.assert(true);\n\t\tif (!this.element.isVisible()) return this.stopPolling().hide();\n\t\tif (this.text && this.test()){\n\t\t\tthis.text.position(Object.merge(this.options.positionOptions, {\n\t\t\t\trelativeTo: this.element\n\t\t\t}));\n\t\t}\n\t\treturn this;\n\t}\n\n});\n\nOverText.instances = [];\n\nObject.append(OverText, {\n\n\teach: function(fn){\n\t\treturn OverText.instances.each(function(ot, i){\n\t\t\tif (ot.element && ot.text) fn.call(OverText, ot, i);\n\t\t});\n\t},\n\n\tupdate: function(){\n\n\t\treturn OverText.each(function(ot){\n\t\t\treturn ot.reposition();\n\t\t});\n\n\t},\n\n\thideAll: function(){\n\n\t\treturn OverText.each(function(ot){\n\t\t\treturn ot.hide(true, true);\n\t\t});\n\n\t},\n\n\tshowAll: function(){\n\t\treturn OverText.each(function(ot){\n\t\t\treturn ot.show();\n\t\t});\n\t}\n\n});\n\n\n\n/*\n---\n\nscript: Fx.Elements.js\n\nname: Fx.Elements\n\ndescription: Effect to change any number of CSS properties of any number of Elements.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Fx.CSS\n - More\n\nprovides: [Fx.Elements]\n\n...\n*/\n\nFx.Elements = new Class({\n\n\tExtends: Fx.CSS,\n\n\tinitialize: function(elements, options){\n\t\tthis.elements = this.subject = $$(elements);\n\t\tthis.parent(options);\n\t},\n\n\tcompute: function(from, to, delta){\n\t\tvar now = {};\n\n\t\tfor (var i in from){\n\t\t\tvar iFrom = from[i], iTo = to[i], iNow = now[i] = {};\n\t\t\tfor (var p in iFrom) iNow[p] = this.parent(iFrom[p], iTo[p], delta);\n\t\t}\n\n\t\treturn now;\n\t},\n\n\tset: function(now){\n\t\tfor (var i in now){\n\t\t\tif (!this.elements[i]) continue;\n\n\t\t\tvar iNow = now[i];\n\t\t\tfor (var p in iNow) this.render(this.elements[i], p, iNow[p], this.options.unit);\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tstart: function(obj){\n\t\tif (!this.check(obj)) return this;\n\t\tvar from = {}, to = {};\n\n\t\tfor (var i in obj){\n\t\t\tif (!this.elements[i]) continue;\n\n\t\t\tvar iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {};\n\n\t\t\tfor (var p in iProps){\n\t\t\t\tvar parsed = this.prepare(this.elements[i], p, iProps[p]);\n\t\t\t\tiFrom[p] = parsed.from;\n\t\t\t\tiTo[p] = parsed.to;\n\t\t\t}\n\t\t}\n\n\t\treturn this.parent(from, to);\n\t}\n\n});\n\n\n/*\n---\n\nscript: Fx.Accordion.js\n\nname: Fx.Accordion\n\ndescription: An Fx.Elements extension which allows you to easily create accordion type controls.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Element.Event\n - /Fx.Elements\n\nprovides: [Fx.Accordion]\n\n...\n*/\n\nFx.Accordion = new Class({\n\n\tExtends: Fx.Elements,\n\n\toptions: {/*\n\t\tonActive: function(toggler, section){},\n\t\tonBackground: function(toggler, section){},*/\n\t\tfixedHeight: false,\n\t\tfixedWidth: false,\n\t\tdisplay: 0,\n\t\tshow: false,\n\t\theight: true,\n\t\twidth: false,\n\t\topacity: true,\n\t\talwaysHide: false,\n\t\ttrigger: 'click',\n\t\tinitialDisplayFx: true,\n\t\tresetHeight: true\n\t},\n\n\tinitialize: function(){\n\t\tvar defined = function(obj){\n\t\t\treturn obj != null;\n\t\t};\n\n\t\tvar params = Array.link(arguments, {\n\t\t\t'container': Type.isElement, //deprecated\n\t\t\t'options': Type.isObject,\n\t\t\t'togglers': defined,\n\t\t\t'elements': defined\n\t\t});\n\t\tthis.parent(params.elements, params.options);\n\n\t\tvar options = this.options,\n\t\t\ttogglers = this.togglers = $$(params.togglers);\n\n\t\tthis.previous = -1;\n\t\tthis.internalChain = new Chain();\n\n\t\tif (options.alwaysHide) this.options.link = 'chain';\n\n\t\tif (options.show || this.options.show === 0){\n\t\t\toptions.display = false;\n\t\t\tthis.previous = options.show;\n\t\t}\n\n\t\tif (options.start){\n\t\t\toptions.display = false;\n\t\t\toptions.show = false;\n\t\t}\n\n\t\tvar effects = this.effects = {};\n\n\t\tif (options.opacity) effects.opacity = 'fullOpacity';\n\t\tif (options.width) effects.width = options.fixedWidth ? 'fullWidth' : 'offsetWidth';\n\t\tif (options.height) effects.height = options.fixedHeight ? 'fullHeight' : 'scrollHeight';\n\n\t\tfor (var i = 0, l = togglers.length; i < l; i++) this.addSection(togglers[i], this.elements[i]);\n\n\t\tthis.elements.each(function(el, i){\n\t\t\tif (options.show === i){\n\t\t\t\tthis.fireEvent('active', [togglers[i], el]);\n\t\t\t} else {\n\t\t\t\tfor (var fx in effects) el.setStyle(fx, 0);\n\t\t\t}\n\t\t}, this);\n\n\t\tif (options.display || options.display === 0 || options.initialDisplayFx === false){\n\t\t\tthis.display(options.display, options.initialDisplayFx);\n\t\t}\n\n\t\tif (options.fixedHeight !== false) options.resetHeight = false;\n\t\tthis.addEvent('complete', this.internalChain.callChain.bind(this.internalChain));\n\t},\n\n\taddSection: function(toggler, element){\n\t\ttoggler = document.id(toggler);\n\t\telement = document.id(element);\n\t\tthis.togglers.include(toggler);\n\t\tthis.elements.include(element);\n\n\t\tvar togglers = this.togglers,\n\t\t\toptions = this.options,\n\t\t\ttest = togglers.contains(toggler),\n\t\t\tidx = togglers.indexOf(toggler),\n\t\t\tdisplayer = this.display.pass(idx, this);\n\n\t\ttoggler.store('accordion:display', displayer)\n\t\t\t.addEvent(options.trigger, displayer);\n\n\t\tif (options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'});\n\t\tif (options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'});\n\n\t\telement.fullOpacity = 1;\n\t\tif (options.fixedWidth) element.fullWidth = options.fixedWidth;\n\t\tif (options.fixedHeight) element.fullHeight = options.fixedHeight;\n\t\telement.setStyle('overflow', 'hidden');\n\n\t\tif (!test) for (var fx in this.effects){\n\t\t\telement.setStyle(fx, 0);\n\t\t}\n\t\treturn this;\n\t},\n\n\tremoveSection: function(toggler, displayIndex){\n\t\tvar togglers = this.togglers,\n\t\t\tidx = togglers.indexOf(toggler),\n\t\t\telement = this.elements[idx];\n\n\t\tvar remover = function(){\n\t\t\ttogglers.erase(toggler);\n\t\t\tthis.elements.erase(element);\n\t\t\tthis.detach(toggler);\n\t\t}.bind(this);\n\n\t\tif (this.now == idx || displayIndex != null){\n\t\t\tthis.display(displayIndex != null ? displayIndex : (idx - 1 >= 0 ? idx - 1 : 0)).chain(remover);\n\t\t} else {\n\t\t\tremover();\n\t\t}\n\t\treturn this;\n\t},\n\n\tdetach: function(toggler){\n\t\tvar remove = function(toggler){\n\t\t\ttoggler.removeEvent(this.options.trigger, toggler.retrieve('accordion:display'));\n\t\t}.bind(this);\n\n\t\tif (!toggler) this.togglers.each(remove);\n\t\telse remove(toggler);\n\t\treturn this;\n\t},\n\n\tdisplay: function(index, useFx){\n\t\tif (!this.check(index, useFx)) return this;\n\n\t\tvar obj = {},\n\t\t\telements = this.elements,\n\t\t\toptions = this.options,\n\t\t\teffects = this.effects;\n\n\t\tif (useFx == null) useFx = true;\n\t\tif (typeOf(index) == 'element') index = elements.indexOf(index);\n\t\tif (index == this.previous && !options.alwaysHide) return this;\n\n\t\tif (options.resetHeight){\n\t\t\tvar prev = elements[this.previous];\n\t\t\tif (prev && !this.selfHidden){\n\t\t\t\tfor (var fx in effects) prev.setStyle(fx, prev[effects[fx]]);\n\t\t\t}\n\t\t}\n\n\t\tif ((this.timer && options.link == 'chain') || (index === this.previous && !options.alwaysHide)) return this;\n\n\t\tthis.previous = index;\n\t\tthis.selfHidden = false;\n\n\t\telements.each(function(el, i){\n\t\t\tobj[i] = {};\n\t\t\tvar hide;\n\t\t\tif (i != index){\n\t\t\t\thide = true;\n\t\t\t} else if (options.alwaysHide && ((el.offsetHeight > 0 && options.height) || el.offsetWidth > 0 && options.width)){\n\t\t\t\thide = true;\n\t\t\t\tthis.selfHidden = true;\n\t\t\t}\n\t\t\tthis.fireEvent(hide ? 'background' : 'active', [this.togglers[i], el]);\n\t\t\tfor (var fx in effects) obj[i][fx] = hide ? 0 : el[effects[fx]];\n\t\t\tif (!useFx && !hide && options.resetHeight) obj[i].height = 'auto';\n\t\t}, this);\n\n\t\tthis.internalChain.clearChain();\n\t\tthis.internalChain.chain(function(){\n\t\t\tif (options.resetHeight && !this.selfHidden){\n\t\t\t\tvar el = elements[index];\n\t\t\t\tif (el) el.setStyle('height', 'auto');\n\t\t\t}\n\t\t}.bind(this));\n\n\t\treturn useFx ? this.start(obj) : this.set(obj).internalChain.callChain();\n\t}\n\n});\n\n\n\n\n/*\n---\n\nscript: Fx.Move.js\n\nname: Fx.Move\n\ndescription: Defines Fx.Move, a class that works with Element.Position.js to transition an element from one location to another.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Fx.Morph\n - /Element.Position\n\nprovides: [Fx.Move]\n\n...\n*/\n\nFx.Move = new Class({\n\n\tExtends: Fx.Morph,\n\n\toptions: {\n\t\trelativeTo: document.body,\n\t\tposition: 'center',\n\t\tedge: false,\n\t\toffset: {x: 0, y: 0}\n\t},\n\n\tstart: function(destination){\n\t\tvar element = this.element,\n\t\t\ttopLeft = element.getStyles('top', 'left');\n\t\tif (topLeft.top == 'auto' || topLeft.left == 'auto'){\n\t\t\telement.setPosition(element.getPosition(element.getOffsetParent()));\n\t\t}\n\t\treturn this.parent(element.position(Object.merge({}, this.options, destination, {returnPos: true})));\n\t}\n\n});\n\nElement.Properties.move = {\n\n\tset: function(options){\n\t\tthis.get('move').cancel().setOptions(options);\n\t\treturn this;\n\t},\n\n\tget: function(){\n\t\tvar move = this.retrieve('move');\n\t\tif (!move){\n\t\t\tmove = new Fx.Move(this, {link: 'cancel'});\n\t\t\tthis.store('move', move);\n\t\t}\n\t\treturn move;\n\t}\n\n};\n\nElement.implement({\n\n\tmove: function(options){\n\t\tthis.get('move').start(options);\n\t\treturn this;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Fx.Scroll.js\n\nname: Fx.Scroll\n\ndescription: Effect to smoothly scroll any element, including the window.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Fx\n - Core/Element.Event\n - Core/Element.Dimensions\n - More\n\nprovides: [Fx.Scroll]\n\n...\n*/\n\n(function(){\n\nFx.Scroll = new Class({\n\n\tExtends: Fx,\n\n\toptions: {\n\t\toffset: {x: 0, y: 0},\n\t\twheelStops: true\n\t},\n\n\tinitialize: function(element, options){\n\t\tthis.element = this.subject = document.id(element);\n\t\tthis.parent(options);\n\n\t\tif (typeOf(this.element) != 'element') this.element = document.id(this.element.getDocument().body);\n\n\t\tif (this.options.wheelStops){\n\t\t\tvar stopper = this.element,\n\t\t\t\tcancel = this.cancel.pass(false, this);\n\t\t\tthis.addEvent('start', function(){\n\t\t\t\tstopper.addEvent('mousewheel', cancel);\n\t\t\t}, true);\n\t\t\tthis.addEvent('complete', function(){\n\t\t\t\tstopper.removeEvent('mousewheel', cancel);\n\t\t\t}, true);\n\t\t}\n\t},\n\n\tset: function(){\n\t\tvar now = Array.flatten(arguments);\n\t\tif (Browser.firefox) now = [Math.round(now[0]), Math.round(now[1])]; // not needed anymore in newer firefox versions\n\t\tthis.element.scrollTo(now[0], now[1]);\n\t\treturn this;\n\t},\n\n\tcompute: function(from, to, delta){\n\t\treturn [0, 1].map(function(i){\n\t\t\treturn Fx.compute(from[i], to[i], delta);\n\t\t});\n\t},\n\n\tstart: function(x, y){\n\t\tif (!this.check(x, y)) return this;\n\t\tvar scroll = this.element.getScroll();\n\t\treturn this.parent([scroll.x, scroll.y], [x, y]);\n\t},\n\n\tcalculateScroll: function(x, y){\n\t\tvar element = this.element,\n\t\t\tscrollSize = element.getScrollSize(),\n\t\t\tscroll = element.getScroll(),\n\t\t\tsize = element.getSize(),\n\t\t\toffset = this.options.offset,\n\t\t\tvalues = {x: x, y: y};\n\n\t\tfor (var z in values){\n\t\t\tif (!values[z] && values[z] !== 0) values[z] = scroll[z];\n\t\t\tif (typeOf(values[z]) != 'number') values[z] = scrollSize[z] - size[z];\n\t\t\tvalues[z] += offset[z];\n\t\t}\n\n\t\treturn [values.x, values.y];\n\t},\n\n\ttoTop: function(){\n\t\treturn this.start.apply(this, this.calculateScroll(false, 0));\n\t},\n\n\ttoLeft: function(){\n\t\treturn this.start.apply(this, this.calculateScroll(0, false));\n\t},\n\n\ttoRight: function(){\n\t\treturn this.start.apply(this, this.calculateScroll('right', false));\n\t},\n\n\ttoBottom: function(){\n\t\treturn this.start.apply(this, this.calculateScroll(false, 'bottom'));\n\t},\n\n\ttoElement: function(el, axes){\n\t\taxes = axes ? Array.from(axes) : ['x', 'y'];\n\t\tvar scroll = isBody(this.element) ? {x: 0, y: 0} : this.element.getScroll();\n\t\tvar position = Object.map(document.id(el).getPosition(this.element), function(value, axis){\n\t\t\treturn axes.contains(axis) ? value + scroll[axis] : false;\n\t\t});\n\t\treturn this.start.apply(this, this.calculateScroll(position.x, position.y));\n\t},\n\n\ttoElementEdge: function(el, axes, offset){\n\t\taxes = axes ? Array.from(axes) : ['x', 'y'];\n\t\tel = document.id(el);\n\t\tvar to = {},\n\t\t\tposition = el.getPosition(this.element),\n\t\t\tsize = el.getSize(),\n\t\t\tscroll = this.element.getScroll(),\n\t\t\tcontainerSize = this.element.getSize(),\n\t\t\tedge = {\n\t\t\t\tx: position.x + size.x,\n\t\t\t\ty: position.y + size.y\n\t\t\t};\n\n\t\t['x', 'y'].each(function(axis){\n\t\t\tif (axes.contains(axis)){\n\t\t\t\tif (edge[axis] > scroll[axis] + containerSize[axis]) to[axis] = edge[axis] - containerSize[axis];\n\t\t\t\tif (position[axis] < scroll[axis]) to[axis] = position[axis];\n\t\t\t}\n\t\t\tif (to[axis] == null) to[axis] = scroll[axis];\n\t\t\tif (offset && offset[axis]) to[axis] = to[axis] + offset[axis];\n\t\t}, this);\n\n\t\tif (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);\n\t\treturn this;\n\t},\n\n\ttoElementCenter: function(el, axes, offset){\n\t\taxes = axes ? Array.from(axes) : ['x', 'y'];\n\t\tel = document.id(el);\n\t\tvar to = {},\n\t\t\tposition = el.getPosition(this.element),\n\t\t\tsize = el.getSize(),\n\t\t\tscroll = this.element.getScroll(),\n\t\t\tcontainerSize = this.element.getSize();\n\n\t\t['x', 'y'].each(function(axis){\n\t\t\tif (axes.contains(axis)){\n\t\t\t\tto[axis] = position[axis] - (containerSize[axis] - size[axis]) / 2;\n\t\t\t}\n\t\t\tif (to[axis] == null) to[axis] = scroll[axis];\n\t\t\tif (offset && offset[axis]) to[axis] = to[axis] + offset[axis];\n\t\t}, this);\n\n\t\tif (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);\n\t\treturn this;\n\t}\n\n});\n\n\n\nfunction isBody(element){\n\treturn (/^(?:body|html)$/i).test(element.tagName);\n}\n\n})();\n\n\n/*\n---\n\nscript: Fx.Slide.js\n\nname: Fx.Slide\n\ndescription: Effect to slide an element in and out of view.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Fx\n - Core/Element.Style\n - More\n\nprovides: [Fx.Slide]\n\n...\n*/\n\nFx.Slide = new Class({\n\n\tExtends: Fx,\n\n\toptions: {\n\t\tmode: 'vertical',\n\t\twrapper: false,\n\t\thideOverflow: true,\n\t\tresetHeight: false\n\t},\n\n\tinitialize: function(element, options){\n\t\telement = this.element = this.subject = document.id(element);\n\t\tthis.parent(options);\n\t\toptions = this.options;\n\n\t\tvar wrapper = element.retrieve('wrapper'),\n\t\t\tstyles = element.getStyles('margin', 'position', 'overflow');\n\n\t\tif (options.hideOverflow) styles = Object.append(styles, {overflow: 'hidden'});\n\t\tif (options.wrapper) wrapper = document.id(options.wrapper).setStyles(styles);\n\n\t\tif (!wrapper) wrapper = new Element('div', {\n\t\t\tstyles: styles\n\t\t}).wraps(element);\n\n\t\telement.store('wrapper', wrapper).setStyle('margin', 0);\n\t\tif (element.getStyle('overflow') == 'visible') element.setStyle('overflow', 'hidden');\n\n\t\tthis.now = [];\n\t\tthis.open = true;\n\t\tthis.wrapper = wrapper;\n\n\t\tthis.addEvent('complete', function(){\n\t\t\tthis.open = (wrapper['offset' + this.layout.capitalize()] != 0);\n\t\t\tif (this.open && this.options.resetHeight) wrapper.setStyle('height', '');\n\t\t}, true);\n\t},\n\n\tvertical: function(){\n\t\tthis.margin = 'margin-top';\n\t\tthis.layout = 'height';\n\t\tthis.offset = this.element.offsetHeight;\n\t},\n\n\thorizontal: function(){\n\t\tthis.margin = 'margin-left';\n\t\tthis.layout = 'width';\n\t\tthis.offset = this.element.offsetWidth;\n\t},\n\n\tset: function(now){\n\t\tthis.element.setStyle(this.margin, now[0]);\n\t\tthis.wrapper.setStyle(this.layout, now[1]);\n\t\treturn this;\n\t},\n\n\tcompute: function(from, to, delta){\n\t\treturn [0, 1].map(function(i){\n\t\t\treturn Fx.compute(from[i], to[i], delta);\n\t\t});\n\t},\n\n\tstart: function(how, mode){\n\t\tif (!this.check(how, mode)) return this;\n\t\tthis[mode || this.options.mode]();\n\n\t\tvar margin = this.element.getStyle(this.margin).toInt(),\n\t\t\tlayout = this.wrapper.getStyle(this.layout).toInt(),\n\t\t\tcaseIn = [[margin, layout], [0, this.offset]],\n\t\t\tcaseOut = [[margin, layout], [-this.offset, 0]],\n\t\t\tstart;\n\n\t\tswitch (how){\n\t\t\tcase 'in': start = caseIn; break;\n\t\t\tcase 'out': start = caseOut; break;\n\t\t\tcase 'toggle': start = (layout == 0) ? caseIn : caseOut;\n\t\t}\n\t\treturn this.parent(start[0], start[1]);\n\t},\n\n\tslideIn: function(mode){\n\t\treturn this.start('in', mode);\n\t},\n\n\tslideOut: function(mode){\n\t\treturn this.start('out', mode);\n\t},\n\n\thide: function(mode){\n\t\tthis[mode || this.options.mode]();\n\t\tthis.open = false;\n\t\treturn this.set([-this.offset, 0]);\n\t},\n\n\tshow: function(mode){\n\t\tthis[mode || this.options.mode]();\n\t\tthis.open = true;\n\t\treturn this.set([0, this.offset]);\n\t},\n\n\ttoggle: function(mode){\n\t\treturn this.start('toggle', mode);\n\t}\n\n});\n\nElement.Properties.slide = {\n\n\tset: function(options){\n\t\tthis.get('slide').cancel().setOptions(options);\n\t\treturn this;\n\t},\n\n\tget: function(){\n\t\tvar slide = this.retrieve('slide');\n\t\tif (!slide){\n\t\t\tslide = new Fx.Slide(this, {link: 'cancel'});\n\t\t\tthis.store('slide', slide);\n\t\t}\n\t\treturn slide;\n\t}\n\n};\n\nElement.implement({\n\n\tslide: function(how, mode){\n\t\thow = how || 'toggle';\n\t\tvar slide = this.get('slide'), toggle;\n\t\tswitch (how){\n\t\t\tcase 'hide': slide.hide(mode); break;\n\t\t\tcase 'show': slide.show(mode); break;\n\t\t\tcase 'toggle':\n\t\t\t\tvar flag = this.retrieve('slide:flag', slide.open);\n\t\t\t\tslide[flag ? 'slideOut' : 'slideIn'](mode);\n\t\t\t\tthis.store('slide:flag', !flag);\n\t\t\t\ttoggle = true;\n\t\t\tbreak;\n\t\t\tdefault: slide.start(how, mode);\n\t\t}\n\t\tif (!toggle) this.eliminate('slide:flag');\n\t\treturn this;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Fx.SmoothScroll.js\n\nname: Fx.SmoothScroll\n\ndescription: Class for creating a smooth scrolling effect to all internal links on the page.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Slick.Finder\n - /Fx.Scroll\n\nprovides: [Fx.SmoothScroll]\n\n...\n*/\n\nFx.SmoothScroll = new Class({\n\n\tExtends: Fx.Scroll,\n\n\toptions: {\n\t\taxes: ['x', 'y']\n\t},\n\n\tinitialize: function(options, context){\n\t\tcontext = context || document;\n\t\tthis.doc = context.getDocument();\n\t\tthis.parent(this.doc, options);\n\n\t\tvar win = context.getWindow(),\n\t\t\tlocation = win.location.href.match(/^[^#]*/)[0] + '#',\n\t\t\tlinks = $$(this.options.links || this.doc.links);\n\n\t\tlinks.each(function(link){\n\t\t\tif (link.href.indexOf(location) != 0) return;\n\t\t\tvar anchor = link.href.substr(location.length);\n\t\t\tif (anchor) this.useLink(link, anchor);\n\t\t}, this);\n\n\t\tthis.addEvent('complete', function(){\n\t\t\twin.location.hash = this.anchor;\n\t\t\tthis.element.scrollTo(this.to[0], this.to[1]);\n\t\t}, true);\n\t},\n\n\tuseLink: function(link, anchor){\n\n\t\tlink.addEvent('click', function(event){\n\t\t\tvar el = document.id(anchor) || this.doc.getElement('a[name=' + anchor + ']');\n\t\t\tif (!el) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tthis.toElement(el, this.options.axes).chain(function(){\n\t\t\t\tthis.fireEvent('scrolledTo', [link, el]);\n\t\t\t}.bind(this));\n\n\t\t\tthis.anchor = anchor;\n\n\t\t}.bind(this));\n\n\t\treturn this;\n\t}\n});\n\n\n/*\n---\n\nscript: Fx.Sort.js\n\nname: Fx.Sort\n\ndescription: Defines Fx.Sort, a class that reorders lists with a transition.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Element.Dimensions\n - /Fx.Elements\n - /Element.Measure\n\nprovides: [Fx.Sort]\n\n...\n*/\n\nFx.Sort = new Class({\n\n\tExtends: Fx.Elements,\n\n\toptions: {\n\t\tmode: 'vertical'\n\t},\n\n\tinitialize: function(elements, options){\n\t\tthis.parent(elements, options);\n\t\tthis.elements.each(function(el){\n\t\t\tif (el.getStyle('position') == 'static') el.setStyle('position', 'relative');\n\t\t});\n\t\tthis.setDefaultOrder();\n\t},\n\n\tsetDefaultOrder: function(){\n\t\tthis.currentOrder = this.elements.map(function(el, index){\n\t\t\treturn index;\n\t\t});\n\t},\n\n\tsort: function(){\n\t\tif (!this.check(arguments)) return this;\n\t\tvar newOrder = Array.flatten(arguments);\n\n\t\tvar top = 0,\n\t\t\tleft = 0,\n\t\t\tnext = {},\n\t\t\tzero = {},\n\t\t\tvert = this.options.mode == 'vertical';\n\n\t\tvar current = this.elements.map(function(el, index){\n\t\t\tvar size = el.getComputedSize({styles: ['border', 'padding', 'margin']});\n\t\t\tvar val;\n\t\t\tif (vert){\n\t\t\t\tval = {\n\t\t\t\t\ttop: top,\n\t\t\t\t\tmargin: size['margin-top'],\n\t\t\t\t\theight: size.totalHeight\n\t\t\t\t};\n\t\t\t\ttop += val.height - size['margin-top'];\n\t\t\t} else {\n\t\t\t\tval = {\n\t\t\t\t\tleft: left,\n\t\t\t\t\tmargin: size['margin-left'],\n\t\t\t\t\twidth: size.totalWidth\n\t\t\t\t};\n\t\t\t\tleft += val.width;\n\t\t\t}\n\t\t\tvar plane = vert ? 'top' : 'left';\n\t\t\tzero[index] = {};\n\t\t\tvar start = el.getStyle(plane).toInt();\n\t\t\tzero[index][plane] = start || 0;\n\t\t\treturn val;\n\t\t}, this);\n\n\t\tthis.set(zero);\n\t\tnewOrder = newOrder.map(function(i){ return i.toInt(); });\n\t\tif (newOrder.length != this.elements.length){\n\t\t\tthis.currentOrder.each(function(index){\n\t\t\t\tif (!newOrder.contains(index)) newOrder.push(index);\n\t\t\t});\n\t\t\tif (newOrder.length > this.elements.length)\n\t\t\t\tnewOrder.splice(this.elements.length-1, newOrder.length - this.elements.length);\n\t\t}\n\t\tvar margin = 0;\n\t\ttop = left = 0;\n\t\tnewOrder.each(function(item){\n\t\t\tvar newPos = {};\n\t\t\tif (vert){\n\t\t\t\tnewPos.top = top - current[item].top - margin;\n\t\t\t\ttop += current[item].height;\n\t\t\t} else {\n\t\t\t\tnewPos.left = left - current[item].left;\n\t\t\t\tleft += current[item].width;\n\t\t\t}\n\t\t\tmargin = margin + current[item].margin;\n\t\t\tnext[item]=newPos;\n\t\t}, this);\n\t\tvar mapped = {};\n\t\tArray.clone(newOrder).sort().each(function(index){\n\t\t\tmapped[index] = next[index];\n\t\t});\n\t\tthis.start(mapped);\n\t\tthis.currentOrder = newOrder;\n\n\t\treturn this;\n\t},\n\n\trearrangeDOM: function(newOrder){\n\t\tnewOrder = newOrder || this.currentOrder;\n\t\tvar parent = this.elements[0].getParent();\n\t\tvar rearranged = [];\n\t\tthis.elements.setStyle('opacity', 0);\n\t\t//move each element and store the new default order\n\t\tnewOrder.each(function(index){\n\t\t\trearranged.push(this.elements[index].inject(parent).setStyles({\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0\n\t\t\t}));\n\t\t}, this);\n\t\tthis.elements.setStyle('opacity', 1);\n\t\tthis.elements = $$(rearranged);\n\t\tthis.setDefaultOrder();\n\t\treturn this;\n\t},\n\n\tgetDefaultOrder: function(){\n\t\treturn this.elements.map(function(el, index){\n\t\t\treturn index;\n\t\t});\n\t},\n\n\tgetCurrentOrder: function(){\n\t\treturn this.currentOrder;\n\t},\n\n\tforward: function(){\n\t\treturn this.sort(this.getDefaultOrder());\n\t},\n\n\tbackward: function(){\n\t\treturn this.sort(this.getDefaultOrder().reverse());\n\t},\n\n\treverse: function(){\n\t\treturn this.sort(this.currentOrder.reverse());\n\t},\n\n\tsortByElements: function(elements){\n\t\treturn this.sort(elements.map(function(el){\n\t\t\treturn this.elements.indexOf(el);\n\t\t}, this));\n\t},\n\n\tswap: function(one, two){\n\t\tif (typeOf(one) == 'element') one = this.elements.indexOf(one);\n\t\tif (typeOf(two) == 'element') two = this.elements.indexOf(two);\n\n\t\tvar newOrder = Array.clone(this.currentOrder);\n\t\tnewOrder[this.currentOrder.indexOf(one)] = two;\n\t\tnewOrder[this.currentOrder.indexOf(two)] = one;\n\n\t\treturn this.sort(newOrder);\n\t}\n\n});\n\n\n/*\n---\n\nscript: Drag.js\n\nname: Drag\n\ndescription: The base Drag Class. Can be used to drag and resize Elements using mouse events.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n - Tom Occhinno\n - Jan Kassens\n\nrequires:\n - Core/Events\n - Core/Options\n - Core/Element.Event\n - Core/Element.Style\n - Core/Element.Dimensions\n - More\n\nprovides: [Drag]\n...\n\n*/\n\nvar Drag = new Class({\n\n\tImplements: [Events, Options],\n\n\toptions: {/*\n\t\tonBeforeStart: function(thisElement){},\n\t\tonStart: function(thisElement, event){},\n\t\tonSnap: function(thisElement){},\n\t\tonDrag: function(thisElement, event){},\n\t\tonCancel: function(thisElement){},\n\t\tonComplete: function(thisElement, event){},*/\n\t\tsnap: 6,\n\t\tunit: 'px',\n\t\tgrid: false,\n\t\tstyle: true,\n\t\tlimit: false,\n\t\thandle: false,\n\t\tinvert: false,\n\t\tpreventDefault: false,\n\t\tstopPropagation: false,\n\t\tmodifiers: {x: 'left', y: 'top'}\n\t},\n\n\tinitialize: function(){\n\t\tvar params = Array.link(arguments, {\n\t\t\t'options': Type.isObject,\n\t\t\t'element': function(obj){\n\t\t\t\treturn obj != null;\n\t\t\t}\n\t\t});\n\n\t\tthis.element = document.id(params.element);\n\t\tthis.document = this.element.getDocument();\n\t\tthis.setOptions(params.options || {});\n\t\tvar htype = typeOf(this.options.handle);\n\t\tthis.handles = ((htype == 'array' || htype == 'collection') ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;\n\t\tthis.mouse = {'now': {}, 'pos': {}};\n\t\tthis.value = {'start': {}, 'now': {}};\n\n\t\tthis.selection = (Browser.ie) ? 'selectstart' : 'mousedown';\n\n\n\t\tif (Browser.ie && !Drag.ondragstartFixed){\n\t\t\tdocument.ondragstart = Function.from(false);\n\t\t\tDrag.ondragstartFixed = true;\n\t\t}\n\n\t\tthis.bound = {\n\t\t\tstart: this.start.bind(this),\n\t\t\tcheck: this.check.bind(this),\n\t\t\tdrag: this.drag.bind(this),\n\t\t\tstop: this.stop.bind(this),\n\t\t\tcancel: this.cancel.bind(this),\n\t\t\teventStop: Function.from(false)\n\t\t};\n\t\tthis.attach();\n\t},\n\n\tattach: function(){\n\t\tthis.handles.addEvent('mousedown', this.bound.start);\n\t\treturn this;\n\t},\n\n\tdetach: function(){\n\t\tthis.handles.removeEvent('mousedown', this.bound.start);\n\t\treturn this;\n\t},\n\n\tstart: function(event){\n\t\tvar options = this.options;\n\n\t\tif (event.rightClick) return;\n\n\t\tif (options.preventDefault) event.preventDefault();\n\t\tif (options.stopPropagation) event.stopPropagation();\n\t\tthis.mouse.start = event.page;\n\n\t\tthis.fireEvent('beforeStart', this.element);\n\n\t\tvar limit = options.limit;\n\t\tthis.limit = {x: [], y: []};\n\n\t\tvar z, coordinates;\n\t\tfor (z in options.modifiers){\n\t\t\tif (!options.modifiers[z]) continue;\n\n\t\t\tvar style = this.element.getStyle(options.modifiers[z]);\n\n\t\t\t// Some browsers (IE and Opera) don't always return pixels.\n\t\t\tif (style && !style.match(/px$/)){\n\t\t\t\tif (!coordinates) coordinates = this.element.getCoordinates(this.element.getOffsetParent());\n\t\t\t\tstyle = coordinates[options.modifiers[z]];\n\t\t\t}\n\n\t\t\tif (options.style) this.value.now[z] = (style || 0).toInt();\n\t\t\telse this.value.now[z] = this.element[options.modifiers[z]];\n\n\t\t\tif (options.invert) this.value.now[z] *= -1;\n\n\t\t\tthis.mouse.pos[z] = event.page[z] - this.value.now[z];\n\n\t\t\tif (limit && limit[z]){\n\t\t\t\tvar i = 2;\n\t\t\t\twhile (i--){\n\t\t\t\t\tvar limitZI = limit[z][i];\n\t\t\t\t\tif (limitZI || limitZI === 0) this.limit[z][i] = (typeof limitZI == 'function') ? limitZI() : limitZI;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (typeOf(this.options.grid) == 'number') this.options.grid = {\n\t\t\tx: this.options.grid,\n\t\t\ty: this.options.grid\n\t\t};\n\n\t\tvar events = {\n\t\t\tmousemove: this.bound.check,\n\t\t\tmouseup: this.bound.cancel\n\t\t};\n\t\tevents[this.selection] = this.bound.eventStop;\n\t\tthis.document.addEvents(events);\n\t},\n\n\tcheck: function(event){\n\t\tif (this.options.preventDefault) event.preventDefault();\n\t\tvar distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));\n\t\tif (distance > this.options.snap){\n\t\t\tthis.cancel();\n\t\t\tthis.document.addEvents({\n\t\t\t\tmousemove: this.bound.drag,\n\t\t\t\tmouseup: this.bound.stop\n\t\t\t});\n\t\t\tthis.fireEvent('start', [this.element, event]).fireEvent('snap', this.element);\n\t\t}\n\t},\n\n\tdrag: function(event){\n\t\tvar options = this.options;\n\n\t\tif (options.preventDefault) event.preventDefault();\n\t\tthis.mouse.now = event.page;\n\n\t\tfor (var z in options.modifiers){\n\t\t\tif (!options.modifiers[z]) continue;\n\t\t\tthis.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];\n\n\t\t\tif (options.invert) this.value.now[z] *= -1;\n\n\t\t\tif (options.limit && this.limit[z]){\n\t\t\t\tif ((this.limit[z][1] || this.limit[z][1] === 0) && (this.value.now[z] > this.limit[z][1])){\n\t\t\t\t\tthis.value.now[z] = this.limit[z][1];\n\t\t\t\t} else if ((this.limit[z][0] || this.limit[z][0] === 0) && (this.value.now[z] < this.limit[z][0])){\n\t\t\t\t\tthis.value.now[z] = this.limit[z][0];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (options.grid[z]) this.value.now[z] -= ((this.value.now[z] - (this.limit[z][0]||0)) % options.grid[z]);\n\n\t\t\tif (options.style) this.element.setStyle(options.modifiers[z], this.value.now[z] + options.unit);\n\t\t\telse this.element[options.modifiers[z]] = this.value.now[z];\n\t\t}\n\n\t\tthis.fireEvent('drag', [this.element, event]);\n\t},\n\n\tcancel: function(event){\n\t\tthis.document.removeEvents({\n\t\t\tmousemove: this.bound.check,\n\t\t\tmouseup: this.bound.cancel\n\t\t});\n\t\tif (event){\n\t\t\tthis.document.removeEvent(this.selection, this.bound.eventStop);\n\t\t\tthis.fireEvent('cancel', this.element);\n\t\t}\n\t},\n\n\tstop: function(event){\n\t\tvar events = {\n\t\t\tmousemove: this.bound.drag,\n\t\t\tmouseup: this.bound.stop\n\t\t};\n\t\tevents[this.selection] = this.bound.eventStop;\n\t\tthis.document.removeEvents(events);\n\t\tif (event) this.fireEvent('complete', [this.element, event]);\n\t}\n\n});\n\nElement.implement({\n\n\tmakeResizable: function(options){\n\t\tvar drag = new Drag(this, Object.merge({\n\t\t\tmodifiers: {\n\t\t\t\tx: 'width',\n\t\t\t\ty: 'height'\n\t\t\t}\n\t\t}, options));\n\n\t\tthis.store('resizer', drag);\n\t\treturn drag.addEvent('drag', function(){\n\t\t\tthis.fireEvent('resize', drag);\n\t\t}.bind(this));\n\t}\n\n});\n\n\n/*\n---\n\nscript: Drag.Move.js\n\nname: Drag.Move\n\ndescription: A Drag extension that provides support for the constraining of draggables to containers and droppables.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n - Tom Occhinno\n - Jan Kassens\n - Aaron Newton\n - Scott Kyle\n\nrequires:\n - Core/Element.Dimensions\n - /Drag\n\nprovides: [Drag.Move]\n\n...\n*/\n\nDrag.Move = new Class({\n\n\tExtends: Drag,\n\n\toptions: {/*\n\t\tonEnter: function(thisElement, overed){},\n\t\tonLeave: function(thisElement, overed){},\n\t\tonDrop: function(thisElement, overed, event){},*/\n\t\tdroppables: [],\n\t\tcontainer: false,\n\t\tprecalculate: false,\n\t\tincludeMargins: true,\n\t\tcheckDroppables: true\n\t},\n\n\tinitialize: function(element, options){\n\t\tthis.parent(element, options);\n\t\telement = this.element;\n\n\t\tthis.droppables = $$(this.options.droppables);\n\t\tthis.container = document.id(this.options.container);\n\n\t\tif (this.container && typeOf(this.container) != 'element')\n\t\t\tthis.container = document.id(this.container.getDocument().body);\n\n\t\tif (this.options.style){\n\t\t\tif (this.options.modifiers.x == 'left' && this.options.modifiers.y == 'top'){\n\t\t\t\tvar parent = element.getOffsetParent(),\n\t\t\t\t\tstyles = element.getStyles('left', 'top');\n\t\t\t\tif (parent && (styles.left == 'auto' || styles.top == 'auto')){\n\t\t\t\t\telement.setPosition(element.getPosition(parent));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (element.getStyle('position') == 'static') element.setStyle('position', 'absolute');\n\t\t}\n\n\t\tthis.addEvent('start', this.checkDroppables, true);\n\t\tthis.overed = null;\n\t},\n\n\tstart: function(event){\n\t\tif (this.container) this.options.limit = this.calculateLimit();\n\n\t\tif (this.options.precalculate){\n\t\t\tthis.positions = this.droppables.map(function(el){\n\t\t\t\treturn el.getCoordinates();\n\t\t\t});\n\t\t}\n\n\t\tthis.parent(event);\n\t},\n\n\tcalculateLimit: function(){\n\t\tvar element = this.element,\n\t\t\tcontainer = this.container,\n\n\t\t\toffsetParent = document.id(element.getOffsetParent()) || document.body,\n\t\t\tcontainerCoordinates = container.getCoordinates(offsetParent),\n\t\t\telementMargin = {},\n\t\t\telementBorder = {},\n\t\t\tcontainerMargin = {},\n\t\t\tcontainerBorder = {},\n\t\t\toffsetParentPadding = {};\n\n\t\t['top', 'right', 'bottom', 'left'].each(function(pad){\n\t\t\telementMargin[pad] = element.getStyle('margin-' + pad).toInt();\n\t\t\telementBorder[pad] = element.getStyle('border-' + pad).toInt();\n\t\t\tcontainerMargin[pad] = container.getStyle('margin-' + pad).toInt();\n\t\t\tcontainerBorder[pad] = container.getStyle('border-' + pad).toInt();\n\t\t\toffsetParentPadding[pad] = offsetParent.getStyle('padding-' + pad).toInt();\n\t\t}, this);\n\n\t\tvar width = element.offsetWidth + elementMargin.left + elementMargin.right,\n\t\t\theight = element.offsetHeight + elementMargin.top + elementMargin.bottom,\n\t\t\tleft = 0,\n\t\t\ttop = 0,\n\t\t\tright = containerCoordinates.right - containerBorder.right - width,\n\t\t\tbottom = containerCoordinates.bottom - containerBorder.bottom - height;\n\n\t\tif (this.options.includeMargins){\n\t\t\tleft += elementMargin.left;\n\t\t\ttop += elementMargin.top;\n\t\t} else {\n\t\t\tright += elementMargin.right;\n\t\t\tbottom += elementMargin.bottom;\n\t\t}\n\n\t\tif (element.getStyle('position') == 'relative'){\n\t\t\tvar coords = element.getCoordinates(offsetParent);\n\t\t\tcoords.left -= element.getStyle('left').toInt();\n\t\t\tcoords.top -= element.getStyle('top').toInt();\n\n\t\t\tleft -= coords.left;\n\t\t\ttop -= coords.top;\n\t\t\tif (container.getStyle('position') != 'relative'){\n\t\t\t\tleft += containerBorder.left;\n\t\t\t\ttop += containerBorder.top;\n\t\t\t}\n\t\t\tright += elementMargin.left - coords.left;\n\t\t\tbottom += elementMargin.top - coords.top;\n\n\t\t\tif (container != offsetParent){\n\t\t\t\tleft += containerMargin.left + offsetParentPadding.left;\n\t\t\t\ttop += ((Browser.ie6 || Browser.ie7) ? 0 : containerMargin.top) + offsetParentPadding.top;\n\t\t\t}\n\t\t} else {\n\t\t\tleft -= elementMargin.left;\n\t\t\ttop -= elementMargin.top;\n\t\t\tif (container != offsetParent){\n\t\t\t\tleft += containerCoordinates.left + containerBorder.left;\n\t\t\t\ttop += containerCoordinates.top + containerBorder.top;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tx: [left, right],\n\t\t\ty: [top, bottom]\n\t\t};\n\t},\n\n\tgetDroppableCoordinates: function(element){\n\t\tvar position = element.getCoordinates();\n\t\tif (element.getStyle('position') == 'fixed'){\n\t\t\tvar scroll = window.getScroll();\n\t\t\tposition.left += scroll.x;\n\t\t\tposition.right += scroll.x;\n\t\t\tposition.top += scroll.y;\n\t\t\tposition.bottom += scroll.y;\n\t\t}\n\t\treturn position;\n\t},\n\n\tcheckDroppables: function(){\n\t\tvar overed = this.droppables.filter(function(el, i){\n\t\t\tel = this.positions ? this.positions[i] : this.getDroppableCoordinates(el);\n\t\t\tvar now = this.mouse.now;\n\t\t\treturn (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);\n\t\t}, this).getLast();\n\n\t\tif (this.overed != overed){\n\t\t\tif (this.overed) this.fireEvent('leave', [this.element, this.overed]);\n\t\t\tif (overed) this.fireEvent('enter', [this.element, overed]);\n\t\t\tthis.overed = overed;\n\t\t}\n\t},\n\n\tdrag: function(event){\n\t\tthis.parent(event);\n\t\tif (this.options.checkDroppables && this.droppables.length) this.checkDroppables();\n\t},\n\n\tstop: function(event){\n\t\tthis.checkDroppables();\n\t\tthis.fireEvent('drop', [this.element, this.overed, event]);\n\t\tthis.overed = null;\n\t\treturn this.parent(event);\n\t}\n\n});\n\nElement.implement({\n\n\tmakeDraggable: function(options){\n\t\tvar drag = new Drag.Move(this, options);\n\t\tthis.store('dragger', drag);\n\t\treturn drag;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Slider.js\n\nname: Slider\n\ndescription: Class for creating horizontal and vertical slider controls.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Element.Dimensions\n - /Class.Binds\n - /Drag\n - /Element.Measure\n\nprovides: [Slider]\n\n...\n*/\n\nvar Slider = new Class({\n\n\tImplements: [Events, Options],\n\n\tBinds: ['clickedElement', 'draggedKnob', 'scrolledElement'],\n\n\toptions: {/*\n\t\tonTick: function(intPosition){},\n\t\tonChange: function(intStep){},\n\t\tonComplete: function(strStep){},*/\n\t\tonTick: function(position){\n\t\t\tthis.setKnobPosition(position);\n\t\t},\n\t\tinitialStep: 0,\n\t\tsnap: false,\n\t\toffset: 0,\n\t\trange: false,\n\t\twheel: false,\n\t\tsteps: 100,\n\t\tmode: 'horizontal'\n\t},\n\n\tinitialize: function(element, knob, options){\n\t\tthis.setOptions(options);\n\t\toptions = this.options;\n\t\tthis.element = document.id(element);\n\t\tknob = this.knob = document.id(knob);\n\t\tthis.previousChange = this.previousEnd = this.step = -1;\n\n\t\tvar limit = {},\n\t\t\tmodifiers = {x: false, y: false};\n\n\t\tswitch (options.mode){\n\t\t\tcase 'vertical':\n\t\t\t\tthis.axis = 'y';\n\t\t\t\tthis.property = 'top';\n\t\t\t\tthis.offset = 'offsetHeight';\n\t\t\t\tbreak;\n\t\t\tcase 'horizontal':\n\t\t\t\tthis.axis = 'x';\n\t\t\t\tthis.property = 'left';\n\t\t\t\tthis.offset = 'offsetWidth';\n\t\t}\n\n\t\tthis.setSliderDimensions();\n\t\tthis.setRange(options.range);\n\n\t\tif (knob.getStyle('position') == 'static') knob.setStyle('position', 'relative');\n\t\tknob.setStyle(this.property, -options.offset);\n\t\tmodifiers[this.axis] = this.property;\n\t\tlimit[this.axis] = [-options.offset, this.full - options.offset];\n\n\t\tvar dragOptions = {\n\t\t\tsnap: 0,\n\t\t\tlimit: limit,\n\t\t\tmodifiers: modifiers,\n\t\t\tonDrag: this.draggedKnob,\n\t\t\tonStart: this.draggedKnob,\n\t\t\tonBeforeStart: (function(){\n\t\t\t\tthis.isDragging = true;\n\t\t\t}).bind(this),\n\t\t\tonCancel: function(){\n\t\t\t\tthis.isDragging = false;\n\t\t\t}.bind(this),\n\t\t\tonComplete: function(){\n\t\t\t\tthis.isDragging = false;\n\t\t\t\tthis.draggedKnob();\n\t\t\t\tthis.end();\n\t\t\t}.bind(this)\n\t\t};\n\t\tif (options.snap) this.setSnap(dragOptions);\n\n\t\tthis.drag = new Drag(knob, dragOptions);\n\t\tthis.attach();\n\t\tif (options.initialStep != null) this.set(options.initialStep);\n\t},\n\n\tattach: function(){\n\t\tthis.element.addEvent('mousedown', this.clickedElement);\n\t\tif (this.options.wheel) this.element.addEvent('mousewheel', this.scrolledElement);\n\t\tthis.drag.attach();\n\t\treturn this;\n\t},\n\n\tdetach: function(){\n\t\tthis.element.removeEvent('mousedown', this.clickedElement)\n\t\t\t.removeEvent('mousewheel', this.scrolledElement);\n\t\tthis.drag.detach();\n\t\treturn this;\n\t},\n\n\tautosize: function(){\n\t\tthis.setSliderDimensions()\n\t\t\t.setKnobPosition(this.toPosition(this.step));\n\t\tthis.drag.options.limit[this.axis] = [-this.options.offset, this.full - this.options.offset];\n\t\tif (this.options.snap) this.setSnap();\n\t\treturn this;\n\t},\n\n\tsetSnap: function(options){\n\t\tif (!options) options = this.drag.options;\n\t\toptions.grid = Math.ceil(this.stepWidth);\n\t\toptions.limit[this.axis][1] = this.full;\n\t\treturn this;\n\t},\n\n\tsetKnobPosition: function(position){\n\t\tif (this.options.snap) position = this.toPosition(this.step);\n\t\tthis.knob.setStyle(this.property, position);\n\t\treturn this;\n\t},\n\n\tsetSliderDimensions: function(){\n\t\tthis.full = this.element.measure(function(){\n\t\t\tthis.half = this.knob[this.offset] / 2;\n\t\t\treturn this.element[this.offset] - this.knob[this.offset] + (this.options.offset * 2);\n\t\t}.bind(this));\n\t\treturn this;\n\t},\n\n\tset: function(step){\n\t\tif (!((this.range > 0) ^ (step < this.min))) step = this.min;\n\t\tif (!((this.range > 0) ^ (step > this.max))) step = this.max;\n\n\t\tthis.step = Math.round(step);\n\t\treturn this.checkStep()\n\t\t\t.fireEvent('tick', this.toPosition(this.step))\n\t\t\t.end();\n\t},\n\n\tsetRange: function(range, pos){\n\t\tthis.min = Array.pick([range[0], 0]);\n\t\tthis.max = Array.pick([range[1], this.options.steps]);\n\t\tthis.range = this.max - this.min;\n\t\tthis.steps = this.options.steps || this.full;\n\t\tthis.stepSize = Math.abs(this.range) / this.steps;\n\t\tthis.stepWidth = this.stepSize * this.full / Math.abs(this.range);\n\t\tif (range) this.set(Array.pick([pos, this.step]).floor(this.min).max(this.max));\n\t\treturn this;\n\t},\n\n\tclickedElement: function(event){\n\t\tif (this.isDragging || event.target == this.knob) return;\n\n\t\tvar dir = this.range < 0 ? -1 : 1,\n\t\t\tposition = event.page[this.axis] - this.element.getPosition()[this.axis] - this.half;\n\n\t\tposition = position.limit(-this.options.offset, this.full - this.options.offset);\n\n\t\tthis.step = Math.round(this.min + dir * this.toStep(position));\n\n\t\tthis.checkStep()\n\t\t\t.fireEvent('tick', position)\n\t\t\t.end();\n\t},\n\n\tscrolledElement: function(event){\n\t\tvar mode = (this.options.mode == 'horizontal') ? (event.wheel < 0) : (event.wheel > 0);\n\t\tthis.set(this.step + (mode ? -1 : 1) * this.stepSize);\n\t\tevent.stop();\n\t},\n\n\tdraggedKnob: function(){\n\t\tvar dir = this.range < 0 ? -1 : 1,\n\t\t\tposition = this.drag.value.now[this.axis];\n\n\t\tposition = position.limit(-this.options.offset, this.full -this.options.offset);\n\n\t\tthis.step = Math.round(this.min + dir * this.toStep(position));\n\t\tthis.checkStep();\n\t},\n\n\tcheckStep: function(){\n\t\tvar step = this.step;\n\t\tif (this.previousChange != step){\n\t\t\tthis.previousChange = step;\n\t\t\tthis.fireEvent('change', step);\n\t\t}\n\t\treturn this;\n\t},\n\n\tend: function(){\n\t\tvar step = this.step;\n\t\tif (this.previousEnd !== step){\n\t\t\tthis.previousEnd = step;\n\t\t\tthis.fireEvent('complete', step + '');\n\t\t}\n\t\treturn this;\n\t},\n\n\ttoStep: function(position){\n\t\tvar step = (position + this.options.offset) * this.stepSize / this.full * this.steps;\n\t\treturn this.options.steps ? Math.round(step -= step % this.stepSize) : step;\n\t},\n\n\ttoPosition: function(step){\n\t\treturn (this.full * Math.abs(this.min - step)) / (this.steps * this.stepSize) - this.options.offset;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Sortables.js\n\nname: Sortables\n\ndescription: Class for creating a drag and drop sorting interface for lists of items.\n\nlicense: MIT-style license\n\nauthors:\n - Tom Occhino\n\nrequires:\n - Core/Fx.Morph\n - /Drag.Move\n\nprovides: [Sortables]\n\n...\n*/\n\nvar Sortables = new Class({\n\n\tImplements: [Events, Options],\n\n\toptions: {/*\n\t\tonSort: function(element, clone){},\n\t\tonStart: function(element, clone){},\n\t\tonComplete: function(element){},*/\n\t\topacity: 1,\n\t\tclone: false,\n\t\trevert: false,\n\t\thandle: false,\n\t\tdragOptions: {}\n\t},\n\n\tinitialize: function(lists, options){\n\t\tthis.setOptions(options);\n\n\t\tthis.elements = [];\n\t\tthis.lists = [];\n\t\tthis.idle = true;\n\n\t\tthis.addLists($$(document.id(lists) || lists));\n\n\t\tif (!this.options.clone) this.options.revert = false;\n\t\tif (this.options.revert) this.effect = new Fx.Morph(null, Object.merge({\n\t\t\tduration: 250,\n\t\t\tlink: 'cancel'\n\t\t}, this.options.revert));\n\t},\n\n\tattach: function(){\n\t\tthis.addLists(this.lists);\n\t\treturn this;\n\t},\n\n\tdetach: function(){\n\t\tthis.lists = this.removeLists(this.lists);\n\t\treturn this;\n\t},\n\n\taddItems: function(){\n\t\tArray.flatten(arguments).each(function(element){\n\t\t\tthis.elements.push(element);\n\t\t\tvar start = element.retrieve('sortables:start', function(event){\n\t\t\t\tthis.start.call(this, event, element);\n\t\t\t}.bind(this));\n\t\t\t(this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start);\n\t\t}, this);\n\t\treturn this;\n\t},\n\n\taddLists: function(){\n\t\tArray.flatten(arguments).each(function(list){\n\t\t\tthis.lists.include(list);\n\t\t\tthis.addItems(list.getChildren());\n\t\t}, this);\n\t\treturn this;\n\t},\n\n\tremoveItems: function(){\n\t\treturn $$(Array.flatten(arguments).map(function(element){\n\t\t\tthis.elements.erase(element);\n\t\t\tvar start = element.retrieve('sortables:start');\n\t\t\t(this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start);\n\n\t\t\treturn element;\n\t\t}, this));\n\t},\n\n\tremoveLists: function(){\n\t\treturn $$(Array.flatten(arguments).map(function(list){\n\t\t\tthis.lists.erase(list);\n\t\t\tthis.removeItems(list.getChildren());\n\n\t\t\treturn list;\n\t\t}, this));\n\t},\n\n\tgetClone: function(event, element){\n\t\tif (!this.options.clone) return new Element(element.tagName).inject(document.body);\n\t\tif (typeOf(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list);\n\t\tvar clone = element.clone(true).setStyles({\n\t\t\tmargin: 0,\n\t\t\tposition: 'absolute',\n\t\t\tvisibility: 'hidden',\n\t\t\twidth: element.getStyle('width')\n\t\t}).addEvent('mousedown', function(event){\n\t\t\telement.fireEvent('mousedown', event);\n\t\t});\n\t\t//prevent the duplicated radio inputs from unchecking the real one\n\t\tif (clone.get('html').test('radio')){\n\t\t\tclone.getElements('input[type=radio]').each(function(input, i){\n\t\t\t\tinput.set('name', 'clone_' + i);\n\t\t\t\tif (input.get('checked')) element.getElements('input[type=radio]')[i].set('checked', true);\n\t\t\t});\n\t\t}\n\n\t\treturn clone.inject(this.list).setPosition(element.getPosition(element.getOffsetParent()));\n\t},\n\n\tgetDroppables: function(){\n\t\tvar droppables = this.list.getChildren().erase(this.clone).erase(this.element);\n\t\tif (!this.options.constrain) droppables.append(this.lists).erase(this.list);\n\t\treturn droppables;\n\t},\n\n\tinsert: function(dragging, element){\n\t\tvar where = 'inside';\n\t\tif (this.lists.contains(element)){\n\t\t\tthis.list = element;\n\t\t\tthis.drag.droppables = this.getDroppables();\n\t\t} else {\n\t\t\twhere = this.element.getAllPrevious().contains(element) ? 'before' : 'after';\n\t\t}\n\t\tthis.element.inject(element, where);\n\t\tthis.fireEvent('sort', [this.element, this.clone]);\n\t},\n\n\tstart: function(event, element){\n\t\tif (\n\t\t\t!this.idle ||\n\t\t\tevent.rightClick ||\n\t\t\t['button', 'input', 'a', 'textarea'].contains(event.target.get('tag'))\n\t\t) return;\n\n\t\tthis.idle = false;\n\t\tthis.element = element;\n\t\tthis.opacity = element.getStyle('opacity');\n\t\tthis.list = element.getParent();\n\t\tthis.clone = this.getClone(event, element);\n\n\t\tthis.drag = new Drag.Move(this.clone, Object.merge({\n\t\t\t\n\t\t\tdroppables: this.getDroppables()\n\t\t}, this.options.dragOptions)).addEvents({\n\t\t\tonSnap: function(){\n\t\t\t\tevent.stop();\n\t\t\t\tthis.clone.setStyle('visibility', 'visible');\n\t\t\t\tthis.element.setStyle('opacity', this.options.opacity || 0);\n\t\t\t\tthis.fireEvent('start', [this.element, this.clone]);\n\t\t\t}.bind(this),\n\t\t\tonEnter: this.insert.bind(this),\n\t\t\tonCancel: this.end.bind(this),\n\t\t\tonComplete: this.end.bind(this)\n\t\t});\n\n\t\tthis.clone.inject(this.element, 'before');\n\t\tthis.drag.start(event);\n\t},\n\n\tend: function(){\n\t\tthis.drag.detach();\n\t\tthis.element.setStyle('opacity', this.opacity);\n\t\tif (this.effect){\n\t\t\tvar dim = this.element.getStyles('width', 'height'),\n\t\t\t\tclone = this.clone,\n\t\t\t\tpos = clone.computePosition(this.element.getPosition(this.clone.getOffsetParent()));\n\n\t\t\tvar destroy = function(){\n\t\t\t\tthis.removeEvent('cancel', destroy);\n\t\t\t\tclone.destroy();\n\t\t\t};\n\n\t\t\tthis.effect.element = clone;\n\t\t\tthis.effect.start({\n\t\t\t\ttop: pos.top,\n\t\t\t\tleft: pos.left,\n\t\t\t\twidth: dim.width,\n\t\t\t\theight: dim.height,\n\t\t\t\topacity: 0.25\n\t\t\t}).addEvent('cancel', destroy).chain(destroy);\n\t\t} else {\n\t\t\tthis.clone.destroy();\n\t\t}\n\t\tthis.reset();\n\t},\n\n\treset: function(){\n\t\tthis.idle = true;\n\t\tthis.fireEvent('complete', this.element);\n\t},\n\n\tserialize: function(){\n\t\tvar params = Array.link(arguments, {\n\t\t\tmodifier: Type.isFunction,\n\t\t\tindex: function(obj){\n\t\t\t\treturn obj != null;\n\t\t\t}\n\t\t});\n\t\tvar serial = this.lists.map(function(list){\n\t\t\treturn list.getChildren().map(params.modifier || function(element){\n\t\t\t\treturn element.get('id');\n\t\t\t}, this);\n\t\t}, this);\n\n\t\tvar index = params.index;\n\t\tif (this.lists.length == 1) index = 0;\n\t\treturn (index || index === 0) && index >= 0 && index < this.lists.length ? serial[index] : serial;\n\t}\n\n});\n\n\n/*\n---\n\nscript: Request.JSONP.js\n\nname: Request.JSONP\n\ndescription: Defines Request.JSONP, a class for cross domain javascript via script injection.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n - Guillermo Rauch\n - Arian Stolwijk\n\nrequires:\n - Core/Element\n - Core/Request\n - More\n\nprovides: [Request.JSONP]\n\n...\n*/\n\nRequest.JSONP = new Class({\n\n\tImplements: [Chain, Events, Options],\n\n\toptions: {/*\n\t\tonRequest: function(src, scriptElement){},\n\t\tonComplete: function(data){},\n\t\tonSuccess: function(data){},\n\t\tonCancel: function(){},\n\t\tonTimeout: function(){},\n\t\tonError: function(){}, */\n\t\tonRequest: function(src){\n\t\t\tif (this.options.log && window.console && console.log){\n\t\t\t\tconsole.log('JSONP retrieving script with url:' + src);\n\t\t\t}\n\t\t},\n\t\tonError: function(src){\n\t\t\tif (this.options.log && window.console && console.warn){\n\t\t\t\tconsole.warn('JSONP '+ src +' will fail in Internet Explorer, which enforces a 2083 bytes length limit on URIs');\n\t\t\t}\n\t\t},\n\t\turl: '',\n\t\tcallbackKey: 'callback',\n\t\tinjectScript: document.head,\n\t\tdata: '',\n\t\tlink: 'ignore',\n\t\ttimeout: 0,\n\t\tlog: false\n\t},\n\n\tinitialize: function(options){\n\t\tthis.setOptions(options);\n\t},\n\n\tsend: function(options){\n\t\tif (!Request.prototype.check.call(this, options)) return this;\n\t\tthis.running = true;\n\n\t\tvar type = typeOf(options);\n\t\tif (type == 'string' || type == 'element') options = {data: options};\n\t\toptions = Object.merge(this.options, options || {});\n\n\t\tvar data = options.data;\n\t\tswitch (typeOf(data)){\n\t\t\tcase 'element': data = document.id(data).toQueryString(); break;\n\t\t\tcase 'object': case 'hash': data = Object.toQueryString(data);\n\t\t}\n\n\t\tvar index = this.index = Request.JSONP.counter++;\n\n\t\tvar src = options.url +\n\t\t\t(options.url.test('\\\\?') ? '&' :'?') +\n\t\t\t(options.callbackKey) +\n\t\t\t'=Request.JSONP.request_map.request_'+ index +\n\t\t\t(data ? '&' + data : '');\n\n\t\tif (src.length > 2083) this.fireEvent('error', src);\n\n\t\tRequest.JSONP.request_map['request_' + index] = function(){\n\t\t\tthis.success(arguments, index);\n\t\t}.bind(this);\n\n\t\tvar script = this.getScript(src).inject(options.injectScript);\n\t\tthis.fireEvent('request', [src, script]);\n\n\t\tif (options.timeout) this.timeout.delay(options.timeout, this);\n\n\t\treturn this;\n\t},\n\n\tgetScript: function(src){\n\t\tif (!this.script) this.script = new Element('script', {\n\t\t\ttype: 'text/javascript',\n\t\t\tasync: true,\n\t\t\tsrc: src\n\t\t});\n\t\treturn this.script;\n\t},\n\n\tsuccess: function(args, index){\n\t\tif (!this.running) return;\n\t\tthis.clear()\n\t\t\t.fireEvent('complete', args).fireEvent('success', args)\n\t\t\t.callChain();\n\t},\n\n\tcancel: function(){\n\t\tif (this.running) this.clear().fireEvent('cancel');\n\t\treturn this;\n\t},\n\n\tisRunning: function(){\n\t\treturn !!this.running;\n\t},\n\n\tclear: function(){\n\t\tthis.running = false;\n\t\tif (this.script){\n\t\t\tthis.script.destroy();\n\t\t\tthis.script = null;\n\t\t}\n\t\treturn this;\n\t},\n\n\ttimeout: function(){\n\t\tif (this.running){\n\t\t\tthis.running = false;\n\t\t\tthis.fireEvent('timeout', [this.script.get('src'), this.script]).fireEvent('failure').cancel();\n\t\t}\n\t\treturn this;\n\t}\n\n});\n\nRequest.JSONP.counter = 0;\nRequest.JSONP.request_map = {};\n\n\n/*\n---\n\nscript: Request.Queue.js\n\nname: Request.Queue\n\ndescription: Controls several instances of Request and its variants to run only one request at a time.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Element\n - Core/Request\n - /Class.Binds\n\nprovides: [Request.Queue]\n\n...\n*/\n\nRequest.Queue = new Class({\n\n\tImplements: [Options, Events],\n\n\tBinds: ['attach', 'request', 'complete', 'cancel', 'success', 'failure', 'exception'],\n\n\toptions: {/*\n\t\tonRequest: function(argsPassedToOnRequest){},\n\t\tonSuccess: function(argsPassedToOnSuccess){},\n\t\tonComplete: function(argsPassedToOnComplete){},\n\t\tonCancel: function(argsPassedToOnCancel){},\n\t\tonException: function(argsPassedToOnException){},\n\t\tonFailure: function(argsPassedToOnFailure){},\n\t\tonEnd: function(){},\n\t\t*/\n\t\tstopOnFailure: true,\n\t\tautoAdvance: true,\n\t\tconcurrent: 1,\n\t\trequests: {}\n\t},\n\n\tinitialize: function(options){\n\t\tvar requests;\n\t\tif (options){\n\t\t\trequests = options.requests;\n\t\t\tdelete options.requests;\n\t\t}\n\t\tthis.setOptions(options);\n\t\tthis.requests = {};\n\t\tthis.queue = [];\n\t\tthis.reqBinders = {};\n\n\t\tif (requests) this.addRequests(requests);\n\t},\n\n\taddRequest: function(name, request){\n\t\tthis.requests[name] = request;\n\t\tthis.attach(name, request);\n\t\treturn this;\n\t},\n\n\taddRequests: function(obj){\n\t\tObject.each(obj, function(req, name){\n\t\t\tthis.addRequest(name, req);\n\t\t}, this);\n\t\treturn this;\n\t},\n\n\tgetName: function(req){\n\t\treturn Object.keyOf(this.requests, req);\n\t},\n\n\tattach: function(name, req){\n\t\tif (req._groupSend) return this;\n\t\t['request', 'complete', 'cancel', 'success', 'failure', 'exception'].each(function(evt){\n\t\t\tif (!this.reqBinders[name]) this.reqBinders[name] = {};\n\t\t\tthis.reqBinders[name][evt] = function(){\n\t\t\t\tthis['on' + evt.capitalize()].apply(this, [name, req].append(arguments));\n\t\t\t}.bind(this);\n\t\t\treq.addEvent(evt, this.reqBinders[name][evt]);\n\t\t}, this);\n\t\treq._groupSend = req.send;\n\t\treq.send = function(options){\n\t\t\tthis.send(name, options);\n\t\t\treturn req;\n\t\t}.bind(this);\n\t\treturn this;\n\t},\n\n\tremoveRequest: function(req){\n\t\tvar name = typeOf(req) == 'object' ? this.getName(req) : req;\n\t\tif (!name && typeOf(name) != 'string') return this;\n\t\treq = this.requests[name];\n\t\tif (!req) return this;\n\t\t['request', 'complete', 'cancel', 'success', 'failure', 'exception'].each(function(evt){\n\t\t\treq.removeEvent(evt, this.reqBinders[name][evt]);\n\t\t}, this);\n\t\treq.send = req._groupSend;\n\t\tdelete req._groupSend;\n\t\treturn this;\n\t},\n\n\tgetRunning: function(){\n\t\treturn Object.filter(this.requests, function(r){\n\t\t\treturn r.running;\n\t\t});\n\t},\n\n\tisRunning: function(){\n\t\treturn !!(Object.keys(this.getRunning()).length);\n\t},\n\n\tsend: function(name, options){\n\t\tvar q = function(){\n\t\t\tthis.requests[name]._groupSend(options);\n\t\t\tthis.queue.erase(q);\n\t\t}.bind(this);\n\n\t\tq.name = name;\n\t\tif (Object.keys(this.getRunning()).length >= this.options.concurrent || (this.error && this.options.stopOnFailure)) this.queue.push(q);\n\t\telse q();\n\t\treturn this;\n\t},\n\n\thasNext: function(name){\n\t\treturn (!name) ? !!this.queue.length : !!this.queue.filter(function(q){ return q.name == name; }).length;\n\t},\n\n\tresume: function(){\n\t\tthis.error = false;\n\t\t(this.options.concurrent - Object.keys(this.getRunning()).length).times(this.runNext, this);\n\t\treturn this;\n\t},\n\n\trunNext: function(name){\n\t\tif (!this.queue.length) return this;\n\t\tif (!name){\n\t\t\tthis.queue[0]();\n\t\t} else {\n\t\t\tvar found;\n\t\t\tthis.queue.each(function(q){\n\t\t\t\tif (!found && q.name == name){\n\t\t\t\t\tfound = true;\n\t\t\t\t\tq();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn this;\n\t},\n\n\trunAll: function(){\n\t\tthis.queue.each(function(q){\n\t\t\tq();\n\t\t});\n\t\treturn this;\n\t},\n\n\tclear: function(name){\n\t\tif (!name){\n\t\t\tthis.queue.empty();\n\t\t} else {\n\t\t\tthis.queue = this.queue.map(function(q){\n\t\t\t\tif (q.name != name) return q;\n\t\t\t\telse return false;\n\t\t\t}).filter(function(q){\n\t\t\t\treturn q;\n\t\t\t});\n\t\t}\n\t\treturn this;\n\t},\n\n\tcancel: function(name){\n\t\tthis.requests[name].cancel();\n\t\treturn this;\n\t},\n\n\tonRequest: function(){\n\t\tthis.fireEvent('request', arguments);\n\t},\n\n\tonComplete: function(){\n\t\tthis.fireEvent('complete', arguments);\n\t\tif (!this.queue.length) this.fireEvent('end');\n\t},\n\n\tonCancel: function(){\n\t\tif (this.options.autoAdvance && !this.error) this.runNext();\n\t\tthis.fireEvent('cancel', arguments);\n\t},\n\n\tonSuccess: function(){\n\t\tif (this.options.autoAdvance && !this.error) this.runNext();\n\t\tthis.fireEvent('success', arguments);\n\t},\n\n\tonFailure: function(){\n\t\tthis.error = true;\n\t\tif (!this.options.stopOnFailure && this.options.autoAdvance) this.runNext();\n\t\tthis.fireEvent('failure', arguments);\n\t},\n\n\tonException: function(){\n\t\tthis.error = true;\n\t\tif (!this.options.stopOnFailure && this.options.autoAdvance) this.runNext();\n\t\tthis.fireEvent('exception', arguments);\n\t}\n\n});\n\n\n/*\n---\n\nscript: Request.Periodical.js\n\nname: Request.Periodical\n\ndescription: Requests the same URL to pull data from a server but increases the intervals if no data is returned to reduce the load\n\nlicense: MIT-style license\n\nauthors:\n - Christoph Pojer\n\nrequires:\n - Core/Request\n - More\n\nprovides: [Request.Periodical]\n\n...\n*/\n\nRequest.implement({\n\n\toptions: {\n\t\tinitialDelay: 5000,\n\t\tdelay: 5000,\n\t\tlimit: 60000\n\t},\n\n\tstartTimer: function(data){\n\t\tvar fn = function(){\n\t\t\tif (!this.running) this.send({data: data});\n\t\t};\n\t\tthis.lastDelay = this.options.initialDelay;\n\t\tthis.timer = fn.delay(this.lastDelay, this);\n\t\tthis.completeCheck = function(response){\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.lastDelay = (response) ? this.options.delay : (this.lastDelay + this.options.delay).min(this.options.limit);\n\t\t\tthis.timer = fn.delay(this.lastDelay, this);\n\t\t};\n\t\treturn this.addEvent('complete', this.completeCheck);\n\t},\n\n\tstopTimer: function(){\n\t\tclearTimeout(this.timer);\n\t\treturn this.removeEvent('complete', this.completeCheck);\n\t}\n\n});\n\n\n/*\n---\n\nscript: Assets.js\n\nname: Assets\n\ndescription: Provides methods to dynamically load JavaScript, CSS, and Image files into the document.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Element.Event\n - More\n\nprovides: [Assets]\n\n...\n*/\n\nvar Asset = {\n\n\tjavascript: function(source, properties){\n\t\tif (!properties) properties = {};\n\n\t\tvar script = new Element('script', {src: source, type: 'text/javascript'}),\n\t\t\tdoc = properties.document || document,\n\t\t\tload = properties.onload || properties.onLoad;\n\n\t\tdelete properties.onload;\n\t\tdelete properties.onLoad;\n\t\tdelete properties.document;\n\n\t\tif (load){\n\t\t\tif (typeof script.onreadystatechange != 'undefined'){\n\t\t\t\tscript.addEvent('readystatechange', function(){\n\t\t\t\t\tif (['loaded', 'complete'].contains(this.readyState)) load.call(this);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tscript.addEvent('load', load);\n\t\t\t}\n\t\t}\n\n\t\treturn script.set(properties).inject(doc.head);\n\t},\n\n\tcss: function(source, properties){\n\t\tif (!properties) properties = {};\n\n\t\tvar link = new Element('link', {\n\t\t\trel: 'stylesheet',\n\t\t\tmedia: 'screen',\n\t\t\ttype: 'text/css',\n\t\t\thref: source\n\t\t});\n\n\t\tvar load = properties.onload || properties.onLoad,\n\t\t\tdoc = properties.document || document;\n\n\t\tdelete properties.onload;\n\t\tdelete properties.onLoad;\n\t\tdelete properties.document;\n\n\t\tif (load) link.addEvent('load', load);\n\t\treturn link.set(properties).inject(doc.head);\n\t},\n\n\timage: function(source, properties){\n\t\tif (!properties) properties = {};\n\n\t\tvar image = new Image(),\n\t\t\telement = document.id(image) || new Element('img');\n\n\t\t['load', 'abort', 'error'].each(function(name){\n\t\t\tvar type = 'on' + name,\n\t\t\t\tcap = 'on' + name.capitalize(),\n\t\t\t\tevent = properties[type] || properties[cap] || function(){};\n\n\t\t\tdelete properties[cap];\n\t\t\tdelete properties[type];\n\n\t\t\timage[type] = function(){\n\t\t\t\tif (!image) return;\n\t\t\t\tif (!element.parentNode){\n\t\t\t\t\telement.width = image.width;\n\t\t\t\t\telement.height = image.height;\n\t\t\t\t}\n\t\t\t\timage = image.onload = image.onabort = image.onerror = null;\n\t\t\t\tevent.delay(1, element, element);\n\t\t\t\telement.fireEvent(name, element, 1);\n\t\t\t};\n\t\t});\n\n\t\timage.src = element.src = source;\n\t\tif (image && image.complete) image.onload.delay(1);\n\t\treturn element.set(properties);\n\t},\n\n\timages: function(sources, options){\n\t\tsources = Array.from(sources);\n\n\t\tvar fn = function(){},\n\t\t\tcounter = 0;\n\n\t\toptions = Object.merge({\n\t\t\tonComplete: fn,\n\t\t\tonProgress: fn,\n\t\t\tonError: fn,\n\t\t\tproperties: {}\n\t\t}, options);\n\n\t\treturn new Elements(sources.map(function(source, index){\n\t\t\treturn Asset.image(source, Object.append(options.properties, {\n\t\t\t\tonload: function(){\n\t\t\t\t\tcounter++;\n\t\t\t\t\toptions.onProgress.call(this, counter, index, source);\n\t\t\t\t\tif (counter == sources.length) options.onComplete();\n\t\t\t\t},\n\t\t\t\tonerror: function(){\n\t\t\t\t\tcounter++;\n\t\t\t\t\toptions.onError.call(this, counter, index, source);\n\t\t\t\t\tif (counter == sources.length) options.onComplete();\n\t\t\t\t}\n\t\t\t}));\n\t\t}));\n\t}\n\n};\n\n\n/*\n---\n\nscript: Color.js\n\nname: Color\n\ndescription: Class for creating and manipulating colors in JavaScript. Supports HSB -> RGB Conversions and vice versa.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Array\n - Core/String\n - Core/Number\n - Core/Hash\n - Core/Function\n - More\n\nprovides: [Color]\n\n...\n*/\n\n(function(){\n\nvar Color = this.Color = new Type('Color', function(color, type){\n\tif (arguments.length >= 3){\n\t\ttype = 'rgb'; color = Array.slice(arguments, 0, 3);\n\t} else if (typeof color == 'string'){\n\t\tif (color.match(/rgb/)) color = color.rgbToHex().hexToRgb(true);\n\t\telse if (color.match(/hsb/)) color = color.hsbToRgb();\n\t\telse color = color.hexToRgb(true);\n\t}\n\ttype = type || 'rgb';\n\tswitch (type){\n\t\tcase 'hsb':\n\t\t\tvar old = color;\n\t\t\tcolor = color.hsbToRgb();\n\t\t\tcolor.hsb = old;\n\t\tbreak;\n\t\tcase 'hex': color = color.hexToRgb(true); break;\n\t}\n\tcolor.rgb = color.slice(0, 3);\n\tcolor.hsb = color.hsb || color.rgbToHsb();\n\tcolor.hex = color.rgbToHex();\n\treturn Object.append(color, this);\n});\n\nColor.implement({\n\n\tmix: function(){\n\t\tvar colors = Array.slice(arguments);\n\t\tvar alpha = (typeOf(colors.getLast()) == 'number') ? colors.pop() : 50;\n\t\tvar rgb = this.slice();\n\t\tcolors.each(function(color){\n\t\t\tcolor = new Color(color);\n\t\t\tfor (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));\n\t\t});\n\t\treturn new Color(rgb, 'rgb');\n\t},\n\n\tinvert: function(){\n\t\treturn new Color(this.map(function(value){\n\t\t\treturn 255 - value;\n\t\t}));\n\t},\n\n\tsetHue: function(value){\n\t\treturn new Color([value, this.hsb[1], this.hsb[2]], 'hsb');\n\t},\n\n\tsetSaturation: function(percent){\n\t\treturn new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');\n\t},\n\n\tsetBrightness: function(percent){\n\t\treturn new Color([this.hsb[0], this.hsb[1], percent], 'hsb');\n\t}\n\n});\n\nthis.$RGB = function(r, g, b){\n\treturn new Color([r, g, b], 'rgb');\n};\n\nthis.$HSB = function(h, s, b){\n\treturn new Color([h, s, b], 'hsb');\n};\n\nthis.$HEX = function(hex){\n\treturn new Color(hex, 'hex');\n};\n\nArray.implement({\n\n\trgbToHsb: function(){\n\t\tvar red = this[0],\n\t\t\t\tgreen = this[1],\n\t\t\t\tblue = this[2],\n\t\t\t\thue = 0;\n\t\tvar max = Math.max(red, green, blue),\n\t\t\t\tmin = Math.min(red, green, blue);\n\t\tvar delta = max - min;\n\t\tvar brightness = max / 255,\n\t\t\t\tsaturation = (max != 0) ? delta / max : 0;\n\t\tif (saturation != 0){\n\t\t\tvar rr = (max - red) / delta;\n\t\t\tvar gr = (max - green) / delta;\n\t\t\tvar br = (max - blue) / delta;\n\t\t\tif (red == max) hue = br - gr;\n\t\t\telse if (green == max) hue = 2 + rr - br;\n\t\t\telse hue = 4 + gr - rr;\n\t\t\thue /= 6;\n\t\t\tif (hue < 0) hue++;\n\t\t}\n\t\treturn [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];\n\t},\n\n\thsbToRgb: function(){\n\t\tvar br = Math.round(this[2] / 100 * 255);\n\t\tif (this[1] == 0){\n\t\t\treturn [br, br, br];\n\t\t} else {\n\t\t\tvar hue = this[0] % 360;\n\t\t\tvar f = hue % 60;\n\t\t\tvar p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);\n\t\t\tvar q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);\n\t\t\tvar t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);\n\t\t\tswitch (Math.floor(hue / 60)){\n\t\t\t\tcase 0: return [br, t, p];\n\t\t\t\tcase 1: return [q, br, p];\n\t\t\t\tcase 2: return [p, br, t];\n\t\t\t\tcase 3: return [p, q, br];\n\t\t\t\tcase 4: return [t, p, br];\n\t\t\t\tcase 5: return [br, p, q];\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n});\n\nString.implement({\n\n\trgbToHsb: function(){\n\t\tvar rgb = this.match(/\\d{1,3}/g);\n\t\treturn (rgb) ? rgb.rgbToHsb() : null;\n\t},\n\n\thsbToRgb: function(){\n\t\tvar hsb = this.match(/\\d{1,3}/g);\n\t\treturn (hsb) ? hsb.hsbToRgb() : null;\n\t}\n\n});\n\n})();\n\n\n\n/*\n---\n\nscript: Group.js\n\nname: Group\n\ndescription: Class for monitoring collections of events\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Events\n - More\n\nprovides: [Group]\n\n...\n*/\n\n(function(){\n\nthis.Group = new Class({\n\n\tinitialize: function(){\n\t\tthis.instances = Array.flatten(arguments);\n\t},\n\n\taddEvent: function(type, fn){\n\t\tvar instances = this.instances,\n\t\t\tlen = instances.length,\n\t\t\ttogo = len,\n\t\t\targs = new Array(len),\n\t\t\tself = this;\n\n\t\tinstances.each(function(instance, i){\n\t\t\tinstance.addEvent(type, function(){\n\t\t\t\tif (!args[i]) togo--;\n\t\t\t\targs[i] = arguments;\n\t\t\t\tif (!togo){\n\t\t\t\t\tfn.call(self, instances, instance, args);\n\t\t\t\t\ttogo = len;\n\t\t\t\t\targs = new Array(len);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n});\n\n})();\n\n\n/*\n---\n\nscript: Hash.Cookie.js\n\nname: Hash.Cookie\n\ndescription: Class for creating, reading, and deleting Cookies in JSON format.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n - Aaron Newton\n\nrequires:\n - Core/Cookie\n - Core/JSON\n - More\n - /Hash\n\nprovides: [Hash.Cookie]\n\n...\n*/\n\nHash.Cookie = new Class({\n\n\tExtends: Cookie,\n\n\toptions: {\n\t\tautoSave: true\n\t},\n\n\tinitialize: function(name, options){\n\t\tthis.parent(name, options);\n\t\tthis.load();\n\t},\n\n\tsave: function(){\n\t\tvar value = JSON.encode(this.hash);\n\t\tif (!value || value.length > 4096) return false; //cookie would be truncated!\n\t\tif (value == '{}') this.dispose();\n\t\telse this.write(value);\n\t\treturn true;\n\t},\n\n\tload: function(){\n\t\tthis.hash = new Hash(JSON.decode(this.read(), true));\n\t\treturn this;\n\t}\n\n});\n\nHash.each(Hash.prototype, function(method, name){\n\tif (typeof method == 'function') Hash.Cookie.implement(name, function(){\n\t\tvar value = method.apply(this.hash, arguments);\n\t\tif (this.options.autoSave) this.save();\n\t\treturn value;\n\t});\n});\n\n\n/*\n---\nname: Table\ndescription: LUA-Style table implementation.\nlicense: MIT-style license\nauthors:\n - Valerio Proietti\nrequires: [Core/Array]\nprovides: [Table]\n...\n*/\n\n(function(){\n\nvar Table = this.Table = function(){\n\n\tthis.length = 0;\n\tvar keys = [],\n\t values = [];\n\t\n\tthis.set = function(key, value){\n\t\tvar index = keys.indexOf(key);\n\t\tif (index == -1){\n\t\t\tvar length = keys.length;\n\t\t\tkeys[length] = key;\n\t\t\tvalues[length] = value;\n\t\t\tthis.length++;\n\t\t} else {\n\t\t\tvalues[index] = value;\n\t\t}\n\t\treturn this;\n\t};\n\n\tthis.get = function(key){\n\t\tvar index = keys.indexOf(key);\n\t\treturn (index == -1) ? null : values[index];\n\t};\n\n\tthis.erase = function(key){\n\t\tvar index = keys.indexOf(key);\n\t\tif (index != -1){\n\t\t\tthis.length--;\n\t\t\tkeys.splice(index, 1);\n\t\t\treturn values.splice(index, 1)[0];\n\t\t}\n\t\treturn null;\n\t};\n\n\tthis.each = this.forEach = function(fn, bind){\n\t\tfor (var i = 0, l = this.length; i < l; i++) fn.call(bind, keys[i], values[i], this);\n\t};\n\t\n};\n\nif (this.Type) new Type('Table', Table);\n\n})();\n\n\n/*\n---\n\nscript: HtmlTable.js\n\nname: HtmlTable\n\ndescription: Builds table elements with methods to add rows.\n\nlicense: MIT-style license\n\nauthors:\n - Aaron Newton\n\nrequires:\n - Core/Options\n - Core/Events\n - /Class.Occlude\n\nprovides: [HtmlTable]\n\n...\n*/\n\nvar HtmlTable = new Class({\n\n\tImplements: [Options, Events, Class.Occlude],\n\n\toptions: {\n\t\tproperties: {\n\t\t\tcellpadding: 0,\n\t\t\tcellspacing: 0,\n\t\t\tborder: 0\n\t\t},\n\t\trows: [],\n\t\theaders: [],\n\t\tfooters: []\n\t},\n\n\tproperty: 'HtmlTable',\n\n\tinitialize: function(){\n\t\tvar params = Array.link(arguments, {options: Type.isObject, table: Type.isElement, id: Type.isString});\n\t\tthis.setOptions(params.options);\n\t\tif (!params.table && params.id) params.table = document.id(params.id);\n\t\tthis.element = params.table || new Element('table', this.options.properties);\n\t\tif (this.occlude()) return this.occluded;\n\t\tthis.build();\n\t},\n\n\tbuild: function(){\n\t\tthis.element.store('HtmlTable', this);\n\n\t\tthis.body = document.id(this.element.tBodies[0]) || new Element('tbody').inject(this.element);\n\t\t$$(this.body.rows);\n\n\t\tif (this.options.headers.length) this.setHeaders(this.options.headers);\n\t\telse this.thead = document.id(this.element.tHead);\n\n\t\tif (this.thead) this.head = this.getHead();\n\t\tif (this.options.footers.length) this.setFooters(this.options.footers);\n\n\t\tthis.tfoot = document.id(this.element.tFoot);\n\t\tif (this.tfoot) this.foot = document.id(this.tfoot.rows[0]);\n\n\t\tthis.options.rows.each(function(row){\n\t\t\tthis.push(row);\n\t\t}, this);\n\t},\n\n\ttoElement: function(){\n\t\treturn this.element;\n\t},\n\n\tempty: function(){\n\t\tthis.body.empty();\n\t\treturn this;\n\t},\n\n\tset: function(what, items){\n\t\tvar target = (what == 'headers') ? 'tHead' : 'tFoot',\n\t\t\tlower = target.toLowerCase();\n\n\t\tthis[lower] = (document.id(this.element[target]) || new Element(lower).inject(this.element, 'top')).empty();\n\t\tvar data = this.push(items, {}, this[lower], what == 'headers' ? 'th' : 'td');\n\n\t\tif (what == 'headers') this.head = this.getHead();\n\t\telse this.foot = this.getHead();\n\n\t\treturn data;\n\t},\n\n\tgetHead: function(){\n\t\tvar rows = this.thead.rows;\n\t\treturn rows.length > 1 ? $$(rows) : rows.length ? document.id(rows[0]) : false;\n\t},\n\n\tsetHeaders: function(headers){\n\t\tthis.set('headers', headers);\n\t\treturn this;\n\t},\n\n\tsetFooters: function(footers){\n\t\tthis.set('footers', footers);\n\t\treturn this;\n\t},\n\n\tupdate: function(tr, row, tag){\n\t\tvar tds = tr.getChildren(tag || 'td'), last = tds.length - 1;\n\n\t\trow.each(function(data, index){\n\t\t\tvar td = tds[index] || new Element(tag || 'td').inject(tr),\n\t\t\t\tcontent = (data ? data.content : '') || data,\n\t\t\t\ttype = typeOf(content);\n\n\t\t\tif (data && data.properties) td.set(data.properties);\n\t\t\tif (/(element(s?)|array|collection)/.test(type)) td.empty().adopt(content);\n\t\t\telse td.set('html', content);\n\n\t\t\tif (index > last) tds.push(td);\n\t\t\telse tds[index] = td;\n\t\t});\n\n\t\treturn {\n\t\t\ttr: tr,\n\t\t\ttds: tds\n\t\t};\n\t},\n\n\tpush: function(row, rowProperties, target, tag, where){\n\t\tif (typeOf(row) == 'element' && row.get('tag') == 'tr'){\n\t\t\trow.inject(target || this.body, where);\n\t\t\treturn {\n\t\t\t\ttr: row,\n\t\t\t\ttds: row.getChildren('td')\n\t\t\t};\n\t\t}\n\t\treturn this.update(new Element('tr', rowProperties).inject(target || this.body, where), row, tag);\n\t},\n\n\tpushMany: function(rows, rowProperties, target, tag, where){\n\t\treturn rows.map(function(row){\n\t\t\treturn this.push(row, rowProperties, target, tag, where);\n\t\t}, this);\n\t}\n\n});\n\n\n['adopt', 'inject', 'wraps', 'grab', 'replaces', 'dispose'].each(function(method){\n\tHtmlTable.implement(method, function(){\n\t\tthis.element[method].apply(this.element, arguments);\n\t\treturn this;\n\t});\n});\n\n\n\n\n/*\n---\n\nscript: HtmlTable.Zebra.js\n\nname: HtmlTable.Zebra\n\ndescription: Builds a stripy table with methods to add rows.\n\nlicense: MIT-style license\n\nauthors:\n - Harald Kirschner\n - Aaron Newton\n\nrequires:\n - /HtmlTable\n - /Element.Shortcuts\n - /Class.refactor\n\nprovides: [HtmlTable.Zebra]\n\n...\n*/\n\nHtmlTable = Class.refactor(HtmlTable, {\n\n\toptions: {\n\t\tclassZebra: 'table-tr-odd',\n\t\tzebra: true,\n\t\tzebraOnlyVisibleRows: true\n\t},\n\n\tinitialize: function(){\n\t\tthis.previous.apply(this, arguments);\n\t\tif (this.occluded) return this.occluded;\n\t\tif (this.options.zebra) this.updateZebras();\n\t},\n\n\tupdateZebras: function(){\n\t\tvar index = 0;\n\t\tArray.each(this.body.rows, function(row){\n\t\t\tif (!this.options.zebraOnlyVisibleRows || row.isDisplayed()){\n\t\t\t\tthis.zebra(row, index++);\n\t\t\t}\n\t\t}, this);\n\t},\n\n\tsetRowStyle: function(row, i){\n\t\tif (this.previous) this.previous(row, i);\n\t\tthis.zebra(row, i);\n\t},\n\n\tzebra: function(row, i){\n\t\treturn row[((i % 2) ? 'remove' : 'add')+'Class'](this.options.classZebra);\n\t},\n\n\tpush: function(){\n\t\tvar pushed = this.previous.apply(this, arguments);\n\t\tif (this.options.zebra) this.updateZebras();\n\t\treturn pushed;\n\t}\n\n});\n\n\n/*\n---\n\nscript: HtmlTable.Sort.js\n\nname: HtmlTable.Sort\n\ndescription: Builds a stripy, sortable table with methods to add rows.\n\nlicense: MIT-style license\n\nauthors:\n - Harald Kirschner\n - Aaron Newton\n - Jacob Thornton\n\nrequires:\n - Core/Hash\n - /HtmlTable\n - /Class.refactor\n - /Element.Delegation\n - /String.Extras\n - /Date\n\nprovides: [HtmlTable.Sort]\n\n...\n*/\n\nHtmlTable = Class.refactor(HtmlTable, {\n\n\toptions: {/*\n\t\tonSort: function(){}, */\n\t\tsortIndex: 0,\n\t\tsortReverse: false,\n\t\tparsers: [],\n\t\tdefaultParser: 'string',\n\t\tclassSortable: 'table-sortable',\n\t\tclassHeadSort: 'table-th-sort',\n\t\tclassHeadSortRev: 'table-th-sort-rev',\n\t\tclassNoSort: 'table-th-nosort',\n\t\tclassGroupHead: 'table-tr-group-head',\n\t\tclassGroup: 'table-tr-group',\n\t\tclassCellSort: 'table-td-sort',\n\t\tclassSortSpan: 'table-th-sort-span',\n\t\tsortable: false,\n\t\tthSelector: 'th'\n\t},\n\n\tinitialize: function (){\n\t\tthis.previous.apply(this, arguments);\n\t\tif (this.occluded) return this.occluded;\n\t\tthis.sorted = {index: null, dir: 1};\n\t\tif (!this.bound) this.bound = {};\n\t\tthis.bound.headClick = this.headClick.bind(this);\n\t\tthis.sortSpans = new Elements();\n\t\tif (this.options.sortable){\n\t\t\tthis.enableSort();\n\t\t\tif (this.options.sortIndex != null) this.sort(this.options.sortIndex, this.options.sortReverse);\n\t\t}\n\t},\n\n\tattachSorts: function(attach){\n\t\tthis.detachSorts();\n\t\tif (attach !== false) this.element.addEvent('click:relay(' + this.options.thSelector + ')', this.bound.headClick);\n\t},\n\n\tdetachSorts: function(){\n\t\tthis.element.removeEvents('click:relay(' + this.options.thSelector + ')');\n\t},\n\n\tsetHeaders: function(){\n\t\tthis.previous.apply(this, arguments);\n\t\tif (this.sortEnabled) this.setParsers();\n\t},\n\n\tsetParsers: function(){\n\t\tthis.parsers = this.detectParsers();\n\t},\n\n\tdetectParsers: function(){\n\t\treturn this.head && this.head.getElements(this.options.thSelector).flatten().map(this.detectParser, this);\n\t},\n\n\tdetectParser: function(cell, index){\n\t\tif (cell.hasClass(this.options.classNoSort) || cell.retrieve('htmltable-parser')) return cell.retrieve('htmltable-parser');\n\t\tvar thDiv = new Element('div');\n\t\tthDiv.adopt(cell.childNodes).inject(cell);\n\t\tvar sortSpan = new Element('span', {'class': this.options.classSortSpan}).inject(thDiv, 'top');\n\t\tthis.sortSpans.push(sortSpan);\n\t\tvar parser = this.options.parsers[index],\n\t\t\trows = this.body.rows,\n\t\t\tcancel;\n\t\tswitch (typeOf(parser)){\n\t\t\tcase 'function': parser = {convert: parser}; cancel = true; break;\n\t\t\tcase 'string': parser = parser; cancel = true; break;\n\t\t}\n\t\tif (!cancel){\n\t\t\tHtmlTable.ParserPriority.some(function(parserName){\n\t\t\t\tvar current = HtmlTable.Parsers[parserName],\n\t\t\t\t\tmatch = current.match;\n\t\t\t\tif (!match) return false;\n\t\t\t\tfor (var i = 0, j = rows.length; i < j; i++){\n\t\t\t\t\tvar cell = document.id(rows[i].cells[index]),\n\t\t\t\t\t\ttext = cell ? cell.get('html').clean() : '';\n\t\t\t\t\tif (text && match.test(text)){\n\t\t\t\t\t\tparser = current;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (!parser) parser = this.options.defaultParser;\n\t\tcell.store('htmltable-parser', parser);\n\t\treturn parser;\n\t},\n\n\theadClick: function(event, el){\n\t\tif (!this.head || el.hasClass(this.options.classNoSort)) return;\n\t\treturn this.sort(Array.indexOf(this.head.getElements(this.options.thSelector).flatten(), el) % this.body.rows[0].cells.length);\n\t},\n\n\tserialize: function(){\n\t\tvar previousSerialization = this.previous.apply(this, arguments) || {};\n\t\tif (this.options.sortable){\n\t\t\tpreviousSerialization.sortIndex = this.sorted.index;\n\t\t\tpreviousSerialization.sortReverse = this.sorted.reverse;\n\t\t}\n\t\treturn previousSerialization;\n\t},\n\n\trestore: function(tableState){\n\t\tif(this.options.sortable && tableState.sortIndex){\n\t\t\tthis.sort(tableState.sortIndex, tableState.sortReverse);\n\t\t}\n\t\tthis.previous.apply(this, arguments);\n\t},\n\n\tsetSortedState: function(index, reverse){\n\t\tif (reverse != null) this.sorted.reverse = reverse;\n\t\telse if (this.sorted.index == index) this.sorted.reverse = !this.sorted.reverse;\n\t\telse this.sorted.reverse = this.sorted.index == null;\n\n\t\tif (index != null) this.sorted.index = index;\n\t},\n\n\tsetHeadSort: function(sorted){\n\t\tvar head = $$(!this.head.length ? this.head.cells[this.sorted.index] : this.head.map(function(row){\n\t\t\treturn row.getElements(this.options.thSelector)[this.sorted.index];\n\t\t}, this).clean());\n\t\tif (!head.length) return;\n\t\tif (sorted){\n\t\t\thead.addClass(this.options.classHeadSort);\n\t\t\tif (this.sorted.reverse) head.addClass(this.options.classHeadSortRev);\n\t\t\telse head.removeClass(this.options.classHeadSortRev);\n\t\t} else {\n\t\t\thead.removeClass(this.options.classHeadSort).removeClass(this.options.classHeadSortRev);\n\t\t}\n\t},\n\n\tsetRowSort: function(data, pre){\n\t\tvar count = data.length,\n\t\t\tbody = this.body,\n\t\t\tgroup,\n\t\t\trowIndex;\n\n\t\twhile (count){\n\t\t\tvar item = data[--count],\n\t\t\t\tposition = item.position,\n\t\t\t\trow = body.rows[position];\n\n\t\t\tif (row.disabled) continue;\n\t\t\tif (!pre){\n\t\t\t\tgroup = this.setGroupSort(group, row, item);\n\t\t\t\tthis.setRowStyle(row, count);\n\t\t\t}\n\t\t\tbody.appendChild(row);\n\n\t\t\tfor (rowIndex = 0; rowIndex < count; rowIndex++){\n\t\t\t\tif (data[rowIndex].position > position) data[rowIndex].position--;\n\t\t\t}\n\t\t}\n\t},\n\n\tsetRowStyle: function(row, i){\n\t\tthis.previous(row, i);\n\t\trow.cells[this.sorted.index].addClass(this.options.classCellSort);\n\t},\n\n\tsetGroupSort: function(group, row, item){\n\t\tif (group == item.value) row.removeClass(this.options.classGroupHead).addClass(this.options.classGroup);\n\t\telse row.removeClass(this.options.classGroup).addClass(this.options.classGroupHead);\n\t\treturn item.value;\n\t},\n\n\tgetParser: function(){\n\t\tvar parser = this.parsers[this.sorted.index];\n\t\treturn typeOf(parser) == 'string' ? HtmlTable.Parsers[parser] : parser;\n\t},\n\n\tsort: function(index, reverse, pre){\n\t\tif (!this.head) return;\n\n\t\tif (!pre){\n\t\t\tthis.clearSort();\n\t\t\tthis.setSortedState(index, reverse);\n\t\t\tthis.setHeadSort(true);\n\t\t}\n\n\t\tvar parser = this.getParser();\n\t\tif (!parser) return;\n\n\t\tvar rel;\n\t\tif (!Browser.ie){\n\t\t\trel = this.body.getParent();\n\t\t\tthis.body.dispose();\n\t\t}\n\n\t\tvar data = this.parseData(parser).sort(function(a, b){\n\t\t\tif (a.value === b.value) return 0;\n\t\t\treturn a.value > b.value ? 1 : -1;\n\t\t});\n\n\t\tif (this.sorted.reverse == (parser == HtmlTable.Parsers['input-checked'])) data.reverse(true);\n\t\tthis.setRowSort(data, pre);\n\n\t\tif (rel) rel.grab(this.body);\n\t\tthis.fireEvent('stateChanged');\n\t\treturn this.fireEvent('sort', [this.body, this.sorted.index]);\n\t},\n\n\tparseData: function(parser){\n\t\treturn Array.map(this.body.rows, function(row, i){\n\t\t\tvar value = parser.convert.call(document.id(row.cells[this.sorted.index]));\n\t\t\treturn {\n\t\t\t\tposition: i,\n\t\t\t\tvalue: value\n\t\t\t};\n\t\t}, this);\n\t},\n\n\tclearSort: function(){\n\t\tthis.setHeadSort(false);\n\t\tthis.body.getElements('td').removeClass(this.options.classCellSort);\n\t},\n\n\treSort: function(){\n\t\tif (this.sortEnabled) this.sort.call(this, this.sorted.index, this.sorted.reverse);\n\t\treturn this;\n\t},\n\n\tenableSort: function(){\n\t\tthis.element.addClass(this.options.classSortable);\n\t\tthis.attachSorts(true);\n\t\tthis.setParsers();\n\t\tthis.sortEnabled = true;\n\t\treturn this;\n\t},\n\n\tdisableSort: function(){\n\t\tthis.element.removeClass(this.options.classSortable);\n\t\tthis.attachSorts(false);\n\t\tthis.sortSpans.each(function(span){\n\t\t\tspan.destroy();\n\t\t});\n\t\tthis.sortSpans.empty();\n\t\tthis.sortEnabled = false;\n\t\treturn this;\n\t}\n\n});\n\nHtmlTable.ParserPriority = ['date', 'input-checked', 'input-value', 'float', 'number'];\n\nHtmlTable.Parsers = {\n\n\t'date': {\n\t\tmatch: /^\\d{2}[-\\/ ]\\d{2}[-\\/ ]\\d{2,4}$/,\n\t\tconvert: function(){\n\t\t\tvar d = Date.parse(this.get('text').stripTags());\n\t\t\treturn (typeOf(d) == 'date') ? d.format('db') : '';\n\t\t},\n\t\ttype: 'date'\n\t},\n\t'input-checked': {\n\t\tmatch: / type=\"(radio|checkbox)\" /,\n\t\tconvert: function(){\n\t\t\treturn this.getElement('input').checked;\n\t\t}\n\t},\n\t'input-value': {\n\t\tmatch: / 0)) return null;\n\t\tif (includeHiddenRows){\n\t\t\tindex += offset;\n\t\t} else {\n\t\t\tvar limit = 0,\n\t\t\t count = 0;\n\t\t\tif (offset > 0){\n\t\t\t\twhile (count < offset && index < this.body.rows.length -1){\n\t\t\t\t\tif (this.body.rows[++index].isDisplayed()) count++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile (count > offset && index > 0){\n\t\t\t\t\tif (this.body.rows[--index].isDisplayed()) count--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn index;\n\t},\n\n\tattachSelects: function(attach){\n\t\tattach = attach != null ? attach : true;\n\n\t\tvar method = attach ? 'addEvents' : 'removeEvents';\n\t\tthis.element[method]({\n\t\t\tmouseleave: this.bound.mouseleave,\n\t\t\tclick: this.bound.activateKeyboard\n\t\t});\n\n\t\tthis.body[method]({\n\t\t\t'click:relay(tr)': this.bound.clickRow,\n\t\t\t'contextmenu:relay(tr)': this.bound.clickRow\n\t\t});\n\n\t\tif (this.options.useKeyboard || this.keyboard){\n\t\t\tif (!this.keyboard) this.keyboard = new Keyboard();\n\t\t\tif (!this.selectKeysDefined){\n\t\t\t\tthis.selectKeysDefined = true;\n\t\t\t\tvar timer, held;\n\n\t\t\t\tvar move = function(offset){\n\t\t\t\t\tvar mover = function(e){\n\t\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvar to = this.body.rows[this.getRowByOffset(offset, this.options.selectHiddenRows)];\n\t\t\t\t\t\tif (e.shift && to && this.isSelected(to)){\n\t\t\t\t\t\t\tthis.deselectRow(this.focused);\n\t\t\t\t\t\t\tthis.focused = to;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (to && (!this.options.allowMultiSelect || !e.shift)){\n\t\t\t\t\t\t\t\tthis.selectNone();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.shiftFocus(offset, e);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (held){\n\t\t\t\t\t\t\ttimer = mover.delay(100, this, e);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttimer = (function(){\n\t\t\t\t\t\t\t\theld = true;\n\t\t\t\t\t\t\t\tmover(e);\n\t\t\t\t\t\t\t}).delay(400);\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this);\n\t\t\t\t\treturn mover;\n\t\t\t\t}.bind(this);\n\n\t\t\t\tvar clear = function(){\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\theld = false;\n\t\t\t\t};\n\n\t\t\t\tthis.keyboard.addEvents({\n\t\t\t\t\t'keydown:shift+up': move(-1),\n\t\t\t\t\t'keydown:shift+down': move(1),\n\t\t\t\t\t'keyup:shift+up': clear,\n\t\t\t\t\t'keyup:shift+down': clear,\n\t\t\t\t\t'keyup:up': clear,\n\t\t\t\t\t'keyup:down': clear\n\t\t\t\t});\n\n\t\t\t\tvar shiftHint = '';\n\t\t\t\tif (this.options.allowMultiSelect && this.options.shiftForMultiSelect && this.options.useKeyboard){\n\t\t\t\t\tshiftHint = \" (Shift multi-selects).\";\n\t\t\t\t}\n\n\t\t\t\tthis.keyboard.addShortcuts({\n\t\t\t\t\t'Select Previous Row': {\n\t\t\t\t\t\tkeys: 'up',\n\t\t\t\t\t\tshortcut: 'up arrow',\n\t\t\t\t\t\thandler: move(-1),\n\t\t\t\t\t\tdescription: 'Select the previous row in the table.' + shiftHint\n\t\t\t\t\t},\n\t\t\t\t\t'Select Next Row': {\n\t\t\t\t\t\tkeys: 'down',\n\t\t\t\t\t\tshortcut: 'down arrow',\n\t\t\t\t\t\thandler: move(1),\n\t\t\t\t\t\tdescription: 'Select the next row in the table.' + shiftHint\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t}\n\t\t\tthis.keyboard[attach ? 'activate' : 'deactivate']();\n\t\t}\n\t\tthis.updateSelects();\n\t},\n\n\tmouseleave: function(){\n\t\tif (this.hovered) this.leaveRow(this.hovered);\n\t}\n\n});\n\n\n/*\n---\n\nscript: Scroller.js\n\nname: Scroller\n\ndescription: Class which scrolls the contents of any Element (including the window) when the mouse reaches the Element's boundaries.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n\nrequires:\n - Core/Events\n - Core/Options\n - Core/Element.Event\n - Core/Element.Dimensions\n - More\n\nprovides: [Scroller]\n\n...\n*/\n\nvar Scroller = new Class({\n\n\tImplements: [Events, Options],\n\n\toptions: {\n\t\tarea: 20,\n\t\tvelocity: 1,\n\t\tonChange: function(x, y){\n\t\t\tthis.element.scrollTo(x, y);\n\t\t},\n\t\tfps: 50\n\t},\n\n\tinitialize: function(element, options){\n\t\tthis.setOptions(options);\n\t\tthis.element = document.id(element);\n\t\tthis.docBody = document.id(this.element.getDocument().body);\n\t\tthis.listener = (typeOf(this.element) != 'element') ? this.docBody : this.element;\n\t\tthis.timer = null;\n\t\tthis.bound = {\n\t\t\tattach: this.attach.bind(this),\n\t\t\tdetach: this.detach.bind(this),\n\t\t\tgetCoords: this.getCoords.bind(this)\n\t\t};\n\t},\n\n\tstart: function(){\n\t\tthis.listener.addEvents({\n\t\t\tmouseover: this.bound.attach,\n\t\t\tmouseleave: this.bound.detach\n\t\t});\n\t\treturn this;\n\t},\n\n\tstop: function(){\n\t\tthis.listener.removeEvents({\n\t\t\tmouseover: this.bound.attach,\n\t\t\tmouseleave: this.bound.detach\n\t\t});\n\t\tthis.detach();\n\t\tthis.timer = clearInterval(this.timer);\n\t\treturn this;\n\t},\n\n\tattach: function(){\n\t\tthis.listener.addEvent('mousemove', this.bound.getCoords);\n\t},\n\n\tdetach: function(){\n\t\tthis.listener.removeEvent('mousemove', this.bound.getCoords);\n\t\tthis.timer = clearInterval(this.timer);\n\t},\n\n\tgetCoords: function(event){\n\t\tthis.page = (this.listener.get('tag') == 'body') ? event.client : event.page;\n\t\tif (!this.timer) this.timer = this.scroll.periodical(Math.round(1000 / this.options.fps), this);\n\t},\n\n\tscroll: function(){\n\t\tvar size = this.element.getSize(),\n\t\t\tscroll = this.element.getScroll(),\n\t\t\tpos = this.element != this.docBody ? this.element.getOffsets() : {x: 0, y:0},\n\t\t\tscrollSize = this.element.getScrollSize(),\n\t\t\tchange = {x: 0, y: 0},\n\t\t\ttop = this.options.area.top || this.options.area,\n\t\t\tbottom = this.options.area.bottom || this.options.area;\n\t\tfor (var z in this.page){\n\t\t\tif (this.page[z] < (top + pos[z]) && scroll[z] != 0){\n\t\t\t\tchange[z] = (this.page[z] - top - pos[z]) * this.options.velocity;\n\t\t\t} else if (this.page[z] + bottom > (size[z] + pos[z]) && scroll[z] + size[z] != scrollSize[z]){\n\t\t\t\tchange[z] = (this.page[z] - size[z] + bottom - pos[z]) * this.options.velocity;\n\t\t\t}\n\t\t\tchange[z] = change[z].round();\n\t\t}\n\t\tif (change.y || change.x) this.fireEvent('change', [scroll.x + change.x, scroll.y + change.y]);\n\t}\n\n});\n\n\n/*\n---\n\nscript: Tips.js\n\nname: Tips\n\ndescription: Class for creating nice tips that follow the mouse cursor when hovering an element.\n\nlicense: MIT-style license\n\nauthors:\n - Valerio Proietti\n - Christoph Pojer\n - Luis Merino\n\nrequires:\n - Core/Options\n - Core/Events\n - Core/Element.Event\n - Core/Element.Style\n - Core/Element.Dimensions\n - More\n\nprovides: [Tips]\n\n...\n*/\n\n(function(){\n\nvar read = function(option, element){\n\treturn (option) ? (typeOf(option) == 'function' ? option(element) : element.get(option)) : '';\n};\n\nthis.Tips = new Class({\n\n\tImplements: [Events, Options],\n\n\toptions: {/*\n\t\tid: null,\n\t\tonAttach: function(element){},\n\t\tonDetach: function(element){},\n\t\tonBound: function(coords){},*/\n\t\tonShow: function(){\n\t\t\tthis.tip.setStyle('display', 'block');\n\t\t},\n\t\tonHide: function(){\n\t\t\tthis.tip.setStyle('display', 'none');\n\t\t},\n\t\ttitle: 'title',\n\t\ttext: function(element){\n\t\t\treturn element.get('rel') || element.get('href');\n\t\t},\n\t\tshowDelay: 100,\n\t\thideDelay: 100,\n\t\tclassName: 'tip-wrap',\n\t\toffset: {x: 16, y: 16},\n\t\twindowPadding: {x:0, y:0},\n\t\tfixed: false,\n\t\twaiAria: true\n\t},\n\n\tinitialize: function(){\n\t\tvar params = Array.link(arguments, {\n\t\t\toptions: Type.isObject,\n\t\t\telements: function(obj){\n\t\t\t\treturn obj != null;\n\t\t\t}\n\t\t});\n\t\tthis.setOptions(params.options);\n\t\tif (params.elements) this.attach(params.elements);\n\t\tthis.container = new Element('div', {'class': 'tip'});\n\n\t\tif (this.options.id){\n\t\t\tthis.container.set('id', this.options.id);\n\t\t\tif (this.options.waiAria) this.attachWaiAria();\n\t\t}\n\t},\n\n\ttoElement: function(){\n\t\tif (this.tip) return this.tip;\n\n\t\tthis.tip = new Element('div', {\n\t\t\t'class': this.options.className,\n\t\t\tstyles: {\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0\n\t\t\t}\n\t\t}).adopt(\n\t\t\tnew Element('div', {'class': 'tip-top'}),\n\t\t\tthis.container,\n\t\t\tnew Element('div', {'class': 'tip-bottom'})\n\t\t);\n\n\t\treturn this.tip;\n\t},\n\n\tattachWaiAria: function(){\n\t\tvar id = this.options.id;\n\t\tthis.container.set('role', 'tooltip');\n\n\t\tif (!this.waiAria){\n\t\t\tthis.waiAria = {\n\t\t\t\tshow: function(element){\n\t\t\t\t\tif (id) element.set('aria-describedby', id);\n\t\t\t\t\tthis.container.set('aria-hidden', 'false');\n\t\t\t\t},\n\t\t\t\thide: function(element){\n\t\t\t\t\tif (id) element.erase('aria-describedby');\n\t\t\t\t\tthis.container.set('aria-hidden', 'true');\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tthis.addEvents(this.waiAria);\n\t},\n\n\tdetachWaiAria: function(){\n\t\tif (this.waiAria){\n\t\t\tthis.container.erase('role');\n\t\t\tthis.container.erase('aria-hidden');\n\t\t\tthis.removeEvents(this.waiAria);\n\t\t}\n\t},\n\n\tattach: function(elements){\n\t\t$$(elements).each(function(element){\n\t\t\tvar title = read(this.options.title, element),\n\t\t\t\ttext = read(this.options.text, element);\n\n\t\t\telement.set('title', '').store('tip:native', title).retrieve('tip:title', title);\n\t\t\telement.retrieve('tip:text', text);\n\t\t\tthis.fireEvent('attach', [element]);\n\n\t\t\tvar events = ['enter', 'leave'];\n\t\t\tif (!this.options.fixed) events.push('move');\n\n\t\t\tevents.each(function(value){\n\t\t\t\tvar event = element.retrieve('tip:' + value);\n\t\t\t\tif (!event) event = function(event){\n\t\t\t\t\tthis['element' + value.capitalize()].apply(this, [event, element]);\n\t\t\t\t}.bind(this);\n\n\t\t\t\telement.store('tip:' + value, event).addEvent('mouse' + value, event);\n\t\t\t}, this);\n\t\t}, this);\n\n\t\treturn this;\n\t},\n\n\tdetach: function(elements){\n\t\t$$(elements).each(function(element){\n\t\t\t['enter', 'leave', 'move'].each(function(value){\n\t\t\t\telement.removeEvent('mouse' + value, element.retrieve('tip:' + value)).eliminate('tip:' + value);\n\t\t\t});\n\n\t\t\tthis.fireEvent('detach', [element]);\n\n\t\t\tif (this.options.title == 'title'){ // This is necessary to check if we can revert the title\n\t\t\t\tvar original = element.retrieve('tip:native');\n\t\t\t\tif (original) element.set('title', original);\n\t\t\t}\n\t\t}, this);\n\n\t\treturn this;\n\t},\n\n\telementEnter: function(event, element){\n\t\tclearTimeout(this.timer);\n\t\tthis.timer = (function(){\n\t\t\tthis.container.empty();\n\n\t\t\t['title', 'text'].each(function(value){\n\t\t\t\tvar content = element.retrieve('tip:' + value);\n\t\t\t\tvar div = this['_' + value + 'Element'] = new Element('div', {\n\t\t\t\t\t\t'class': 'tip-' + value\n\t\t\t\t\t}).inject(this.container);\n\t\t\t\tif (content) this.fill(div, content);\n\t\t\t}, this);\n\t\t\tthis.show(element);\n\t\t\tthis.position((this.options.fixed) ? {page: element.getPosition()} : event);\n\t\t}).delay(this.options.showDelay, this);\n\t},\n\n\telementLeave: function(event, element){\n\t\tclearTimeout(this.timer);\n\t\tthis.timer = this.hide.delay(this.options.hideDelay, this, element);\n\t\tthis.fireForParent(event, element);\n\t},\n\n\tsetTitle: function(title){\n\t\tif (this._titleElement){\n\t\t\tthis._titleElement.empty();\n\t\t\tthis.fill(this._titleElement, title);\n\t\t}\n\t\treturn this;\n\t},\n\n\tsetText: function(text){\n\t\tif (this._textElement){\n\t\t\tthis._textElement.empty();\n\t\t\tthis.fill(this._textElement, text);\n\t\t}\n\t\treturn this;\n\t},\n\n\tfireForParent: function(event, element){\n\t\telement = element.getParent();\n\t\tif (!element || element == document.body) return;\n\t\tif (element.retrieve('tip:enter')) element.fireEvent('mouseenter', event);\n\t\telse this.fireForParent(event, element);\n\t},\n\n\telementMove: function(event, element){\n\t\tthis.position(event);\n\t},\n\n\tposition: function(event){\n\t\tif (!this.tip) document.id(this);\n\n\t\tvar size = window.getSize(), scroll = window.getScroll(),\n\t\t\ttip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight},\n\t\t\tprops = {x: 'left', y: 'top'},\n\t\t\tbounds = {y: false, x2: false, y2: false, x: false},\n\t\t\tobj = {};\n\n\t\tfor (var z in props){\n\t\t\tobj[props[z]] = event.page[z] + this.options.offset[z];\n\t\t\tif (obj[props[z]] < 0) bounds[z] = true;\n\t\t\tif ((obj[props[z]] + tip[z] - scroll[z]) > size[z] - this.options.windowPadding[z]){\n\t\t\t\tobj[props[z]] = event.page[z] - this.options.offset[z] - tip[z];\n\t\t\t\tbounds[z+'2'] = true;\n\t\t\t}\n\t\t}\n\n\t\tthis.fireEvent('bound', bounds);\n\t\tthis.tip.setStyles(obj);\n\t},\n\n\tfill: function(element, contents){\n\t\tif (typeof contents == 'string') element.set('html', contents);\n\t\telse element.adopt(contents);\n\t},\n\n\tshow: function(element){\n\t\tif (!this.tip) document.id(this);\n\t\tif (!this.tip.getParent()) this.tip.inject(document.body);\n\t\tthis.fireEvent('show', [this.tip, element]);\n\t},\n\n\thide: function(element){\n\t\tif (!this.tip) document.id(this);\n\t\tthis.fireEvent('hide', [this.tip, element]);\n\t}\n\n});\n\n})();\n\n\n/*\n---\n\nscript: Locale.Set.From.js\n\nname: Locale.Set.From\n\ndescription: Provides an alternative way to create Locale.Set objects.\n\nlicense: MIT-style license\n\nauthors:\n - Tim Wienk\n\nrequires:\n - Core/JSON\n - /Locale\n\nprovides: Locale.Set.From\n\n...\n*/\n\n(function(){\n\nvar parsers = {\n\t'json': JSON.decode\n};\n\nLocale.Set.defineParser = function(name, fn){\n\tparsers[name] = fn;\n};\n\nLocale.Set.from = function(set, type){\n\tif (instanceOf(set, Locale.Set)) return set;\n\n\tif (!type && typeOf(set) == 'string') type = 'json';\n\tif (parsers[type]) set = parsers[type](set);\n\n\tvar locale = new Locale.Set;\n\n\tlocale.sets = set.sets || {};\n\n\tif (set.inherits){\n\t\tlocale.inherits.locales = Array.from(set.inherits.locales);\n\t\tlocale.inherits.sets = set.inherits.sets || {};\n\t}\n\n\treturn locale;\n};\n\n})();\n\n","/*\r\n---\r\nname: Browser.Mobile\r\ndescription: Provides useful information about the browser environment\r\nauthors: Christoph Pojer (@cpojer)\r\nlicense: MIT-style license.\r\nrequires: [Core/Browser]\r\nprovides: Browser.Mobile\r\n...\r\n*/\r\n(function() {\r\n Browser.Device = {\r\n name: 'other'\r\n };\r\n\r\n if (Browser.Platform.ios) {\r\n var device = navigator.userAgent.toLowerCase().match(/(ip(ad|od|hone))/)[0];\r\n Browser.Device[device] = true;\r\n Browser.Device.name = device;\r\n }\r\n\r\n if (this.devicePixelRatio == 2)\r\n Browser.hasHighResolution = true;\r\n\r\n Browser.isMobile = !['mac', 'linux', 'win'].contains(Browser.Platform.name);\r\n}).call(this);\r\n\r\n/*\r\n---\r\nname: Browser.Features.Touch\r\ndescription: Checks whether the used Browser has touch events\r\nauthors: Christoph Pojer (@cpojer)\r\nlicense: MIT-style license.\r\nrequires: [Core/Browser]\r\nprovides: Browser.Features.Touch\r\n...\r\n*/\r\nBrowser.Features.Touch = (function() {\r\n try {\r\n document.createEvent('TouchEvent').initTouchEvent('touchstart');\r\n return true;\r\n } catch (exception) { }\r\n return false;\r\n})();\r\n\r\n// Android doesn't have a touch delay and dispatchEvent does not fire the handler\r\nBrowser.Features.iOSTouch = (function() {\r\n var name = 'cantouch', // Name does not matter\r\n html = document.html,\r\n hasTouch = false;\r\n\r\n if (!html.addEventListener)\r\n return false;\r\n\r\n var handler = function() {\r\n html.removeEventListener(name, handler, true);\r\n hasTouch = true;\r\n };\r\n try {\r\n html.addEventListener(name, handler, true);\r\n var event = document.createEvent('TouchEvent');\r\n event.initTouchEvent(name);\r\n html.dispatchEvent(event);\r\n return hasTouch;\r\n }\r\n catch (exception) {\r\n }\r\n handler(); // Remove listener\r\n\r\n return false;\r\n})();\r\n"]}