{"version":3,"file":"product.92c23e94cc115a454667.js","mappings":";;;;;;;;;;;;AAAA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC71DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACzKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACtFA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AClKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACrDA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;;;;;;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC3IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC9GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AE/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;AClLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACzIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/RA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;ACxKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AClGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACxHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACtFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9pBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;ACxKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AC37BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACt7CA;AACA;AACA;;;;;;;;;;;;ACFA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACpyCA;AACA","sources":["webpack://advantshop/./bundle_config/product.js","webpack://advantshop/./scripts/_common/carousel/carousel.module.js","webpack://advantshop/./scripts/_common/carousel/carouselNative.js","webpack://advantshop/./scripts/_common/carousel/controllers/carouselController.js","webpack://advantshop/./scripts/_common/carousel/directives/carouselDirectives.js","webpack://advantshop/./scripts/_common/carousel/services/carouselService.js","webpack://advantshop/./scripts/_common/iframe-responsive/controllers/iframeResponsiveController.js","webpack://advantshop/./scripts/_common/iframe-responsive/directives/iframeResponsiveDirective.js","webpack://advantshop/./scripts/_common/iframe-responsive/iframeResponsive.module.js","webpack://advantshop/./scripts/_common/iframe-responsive/services/iframeResponsiveService.js","webpack://advantshop/./scripts/_common/rating/controllers/ratingController.js","webpack://advantshop/./scripts/_common/rating/directives/ratingDirectives.js","webpack://advantshop/./scripts/_common/rating/rating.module.js","webpack://advantshop/./scripts/_common/rotate/controllers/rotateController.js","webpack://advantshop/./scripts/_common/rotate/directives/rotateDirectives.js","webpack://advantshop/./scripts/_common/rotate/rotate.module.js","webpack://advantshop/./scripts/_common/tabs/controllers/tabContentController.js","webpack://advantshop/./scripts/_common/tabs/controllers/tabHeaderController.js","webpack://advantshop/./scripts/_common/tabs/controllers/tabsController.js","webpack://advantshop/./scripts/_common/tabs/directives/tabsDirectives.js","webpack://advantshop/./scripts/_common/tabs/services/tabsService.js","webpack://advantshop/./scripts/_common/tabs/tabs.module.js","webpack://advantshop/./scripts/_common/urlHelper/urlHelperService.js","webpack://advantshop/./scripts/_common/urlHelper/urlHelperService.module.js","webpack://advantshop/./scripts/_common/zoomer/controllers/zoomerController.js","webpack://advantshop/./scripts/_common/zoomer/directives/zoomerDirectives.js","webpack://advantshop/./scripts/_common/zoomer/zoomer.module.js","webpack://advantshop/./scripts/_partials/buy-one-click/buyOneClick.module.js","webpack://advantshop/./scripts/_partials/buy-one-click/controllers/buyOneClickFormController.js","webpack://advantshop/./scripts/_partials/buy-one-click/controllers/buyOneClickTriggerController.js","webpack://advantshop/./scripts/_partials/buy-one-click/directives/buyOneClickDirectives.js","webpack://advantshop/./scripts/_partials/buy-one-click/services/buyOneClickService.js","webpack://advantshop/./scripts/_partials/colors-viewer/colorsViewer.module.js","webpack://advantshop/./scripts/_partials/colors-viewer/controllers/colorsViewerController.js","webpack://advantshop/./scripts/_partials/colors-viewer/directives/colorsViewerDirectives.js","webpack://advantshop/./scripts/_partials/compare/compare.module.js","webpack://advantshop/./scripts/_partials/compare/controllers/compareController.js","webpack://advantshop/./scripts/_partials/compare/controllers/compareCountController.js","webpack://advantshop/./scripts/_partials/compare/directives/compareDirectives.js","webpack://advantshop/./scripts/_partials/compare/services/compareService.js","webpack://advantshop/./scripts/_partials/custom-options/controllers/customOptionsController.js","webpack://advantshop/./scripts/_partials/custom-options/customOptions.module.js","webpack://advantshop/./scripts/_partials/custom-options/directives/customOptionsDirectives.js","webpack://advantshop/./scripts/_partials/custom-options/services/customOptionsService.js","webpack://advantshop/./scripts/_partials/photo-view-list/photo-view-list.ctrl.js","webpack://advantshop/./scripts/_partials/photo-view-list/photo-view-list.directive.js","webpack://advantshop/./scripts/_partials/photo-view-list/photoViewList.module.js","webpack://advantshop/./scripts/_partials/product-view/controllers/productViewCarouselPhotosController.js","webpack://advantshop/./scripts/_partials/product-view/controllers/productViewChangeModeController.js","webpack://advantshop/./scripts/_partials/product-view/controllers/productViewItemController.js","webpack://advantshop/./scripts/_partials/product-view/controllers/productViewModeController.js","webpack://advantshop/./scripts/_partials/product-view/directives/productViewDirectives.js","webpack://advantshop/./scripts/_partials/product-view/productView.module.js","webpack://advantshop/./scripts/_partials/product-view/services/productViewService.js","webpack://advantshop/./scripts/_partials/products-carousel/controllers/productsCarouselController.js","webpack://advantshop/./scripts/_partials/products-carousel/directives/productsCarouselDirectives.js","webpack://advantshop/./scripts/_partials/products-carousel/productsCarousel.module.js","webpack://advantshop/./scripts/_partials/products-carousel/services/productsCarouselService.js","webpack://advantshop/./scripts/_partials/quickview/controllers/quickviewController.js","webpack://advantshop/./scripts/_partials/quickview/directives/quickviewDirectives.js","webpack://advantshop/./scripts/_partials/quickview/quickview.module.js","webpack://advantshop/./scripts/_partials/quickview/services/quickviewService.js","webpack://advantshop/./scripts/_partials/reviews/controllers/reviewItemRatingController.js","webpack://advantshop/./scripts/_partials/reviews/controllers/reviewsController.js","webpack://advantshop/./scripts/_partials/reviews/controllers/reviewsFormController.js","webpack://advantshop/./scripts/_partials/reviews/directives/reviewsDirectives.js","webpack://advantshop/./scripts/_partials/reviews/reviews.module.js","webpack://advantshop/./scripts/_partials/shipping/controllers/shippingListController.js","webpack://advantshop/./scripts/_partials/shipping/controllers/shippingTemplateController.js","webpack://advantshop/./scripts/_partials/shipping/controllers/shippingVariantsController.js","webpack://advantshop/./scripts/_partials/shipping/directives/shippingDirectives.js","webpack://advantshop/./scripts/_partials/shipping/shipping.module.js","webpack://advantshop/./scripts/_partials/sizes-viewer/controllers/sizesViewerController.js","webpack://advantshop/./scripts/_partials/sizes-viewer/directives/sizesViewerDirectives.js","webpack://advantshop/./scripts/_partials/sizes-viewer/sizesViewer.module.js","webpack://advantshop/./scripts/_partials/videos/controllers/videosController.js","webpack://advantshop/./scripts/_partials/videos/directives/videosDirective.js","webpack://advantshop/./scripts/_partials/videos/videos.module.js","webpack://advantshop/./scripts/appDependency.js","webpack://advantshop/./scripts/product/controllers/productController.js","webpack://advantshop/./scripts/product/product.module.js","webpack://advantshop/./scripts/product/services/productService.js","webpack://advantshop/./vendors/threesixty/threesixty.js","webpack://advantshop/./vendors/ui-bootstrap-custom/ui-bootstrap-custom-tpls-2.5.0.js","webpack://advantshop/./vendors/ui-bootstrap-custom/ui-bootstrap.module.js","webpack://advantshop/./scripts/_common/carousel/styles/carousel.scss?a989","webpack://advantshop/./scripts/_common/iframe-responsive/styles/iframe-responsive.css?74c1","webpack://advantshop/./scripts/_common/rating/styles/rating.scss?1795","webpack://advantshop/./scripts/_common/tabs/styles/tabs.scss?4ab8","webpack://advantshop/./scripts/_common/zoomer/styles/zoomer.scss?33bc","webpack://advantshop/./scripts/_partials/buy-one-click/styles/buyOneClick.scss?3a24","webpack://advantshop/./scripts/_partials/colors-viewer/styles/colors-viewer.scss?be5c","webpack://advantshop/./scripts/_partials/compare/styles/compare.scss?905e","webpack://advantshop/./scripts/_partials/custom-options/styles/customOptions.scss?0fd2","webpack://advantshop/./scripts/_partials/photo-view-list/photo-view-list.scss?3921","webpack://advantshop/./scripts/_partials/product-view/styles/product-view.scss?fa97","webpack://advantshop/./scripts/_partials/quickview/styles/quickview.scss?54ee","webpack://advantshop/./scripts/_partials/reviews/styles/reviews.scss?728d","webpack://advantshop/./scripts/_partials/shipping/styles/shipping.scss?4d25","webpack://advantshop/./scripts/_partials/sizes-viewer/styles/sizes-viewer.scss?2a0d","webpack://advantshop/./styles/partials/gallery.scss?551d","webpack://advantshop/./styles/partials/product-color.scss?6e19","webpack://advantshop/./styles/partials/properties.scss?fc03","webpack://advantshop/./styles/partials/social-share42.scss?044e","webpack://advantshop/./styles/views/product.scss?ce10","webpack://advantshop/./vendors/threesixty/styles/threesixty.css?6ba5","webpack://advantshop/./vendors/ui-bootstrap-custom/styles/ui-popover.css?40f0","webpack://advantshop/./node_modules/ng-file-upload/dist/ng-file-upload-all.js","webpack://advantshop/./node_modules/ng-file-upload/index.js"],"sourcesContent":["import productModule from '../scripts/product/product.module.js';\nimport appDependency from '../scripts/appDependency.js';\nappDependency.addItem(productModule);","import './styles/carousel.scss';\nimport './carouselNative.js';\nimport carouselService from './services/carouselService.js';\nimport { carouselDirective, carouselImgDirective } from './directives/carouselDirectives.js';\nimport CarouselCtrl from './controllers/carouselController.js';\nvar moduleName = 'carousel';\nangular.module(moduleName, []).directive('carousel', carouselDirective).directive('carouselImg', carouselImgDirective).service('carouselService', carouselService).controller('CarouselCtrl', CarouselCtrl).constant('carouselDefault', {\n isVertical: false,\n scrollCount: 1,\n nav: true,\n dots: false,\n speed: 600,\n auto: false,\n autoPause: 5000,\n indexActive: 0,\n prevIcon: 'icon-left-open-after',\n nextIcon: 'icon-right-open-after',\n prevIconVertical: 'icon-up-open-after',\n nextIconVertical: 'icon-down-open-after',\n prevClass: 'cs-l-1-interactive',\n nextClass: 'cs-l-1-interactive',\n dotsClass: undefined,\n dotsItemClass: 'cs-bg-i-1',\n dotsItemSelectedClass: null,\n dotsItemInnerSelectedClass: null,\n visibleMax: null,\n visibleMin: null,\n itemSelectClass: null,\n carouselClass: null,\n stretch: true,\n navPosition: 'inside',\n //inside or outside\n responsive: null\n});\nexport default moduleName;",";\n\n(function (window) {\n 'use strict';\n\n var isTouchDevice = ('ontouchstart' in document.documentElement),\n autoStop = false,\n clonesForCreate = {},\n transformName = 'transform',\n transitionDurationName = 'transitionDuration',\n webkitTransitionDuration = 'webkitTransitionDuration',\n Carousel,\n storage = {},\n idIncrement = 0,\n deferList = {},\n isOverScrollX = false,\n isScrolling = false;\n\n Carousel = function Carousel(element, options) {\n var id = element.getAttribute('id') || 'carousel_' + (idIncrement += 1);\n this.list = element;\n this.items = Array.prototype.slice.call(element.children).filter(function (x) {\n return x.classList.contains('js-carousel-clone') === false;\n });\n this.options = options;\n this.responsive = options.responsive;\n this.responsiveOption = this.options.responsive != null ? this.checkResponsive() : null;\n this.propName = this.getPropName(this.getIsVerticalOption());\n this.cache = this.items.slice();\n this.id = id;\n this.dots = [];\n storage[id] = {\n state: {\n callAsNav: false\n },\n obj: this\n };\n this.resolveAsNavForReady(this.id);\n return this;\n };\n\n Carousel.prototype.addToCache = function (item) {\n this.cache.push(item);\n };\n\n Carousel.prototype.getFromCache = function (item) {\n var index;\n\n if (typeof item === 'number') {\n index = item;\n } else {\n index = this.cache.indexOf(item);\n }\n\n return this.cache[index];\n };\n\n Carousel.prototype.removeFromCache = function (item) {\n var index;\n\n if (typeof item === 'number') {\n index = item;\n } else {\n index = this.cache.indexOf(item);\n }\n\n if (index !== -1) {\n this.cache.splice(index, 1);\n }\n\n return this.cache[index];\n };\n\n Carousel.prototype.clearCache = function () {\n this.cache.length = 0;\n };\n\n Carousel.prototype.getSize = function (totalCount, maxWidth, maxHeight, isVertical, diff) {\n var size = {};\n\n if (isVertical === false) {\n size['width'] = totalCount * maxWidth - (diff || 0);\n size['height'] = maxHeight;\n } else {\n size['width'] = maxWidth;\n size['height'] = totalCount * maxHeight - (diff || 0);\n }\n\n return size;\n };\n\n Carousel.prototype.getPropName = function (isVertical) {\n return isVertical === false ? 'width' : 'height';\n };\n\n Carousel.prototype.getItemsMaxSizes = function (items) {\n var tempWidth = 0,\n tempHeight = 0,\n maxWidth = 0,\n maxHeigth = 0;\n\n for (var i = items.length - 1; i >= 0; i--) {\n if (items[i].carouselItemData == null) {\n continue;\n }\n\n tempWidth = items[i].carouselItemData.originalWidth;\n\n if (tempWidth > maxWidth) {\n maxWidth = tempWidth;\n }\n\n tempHeight = items[i].carouselItemData.originalHeight;\n\n if (tempHeight > maxHeigth) {\n maxHeigth = tempHeight;\n }\n }\n\n return {\n 'width': maxWidth,\n 'height': maxHeigth\n };\n };\n\n Carousel.prototype.setItemSize = function (item, value) {\n var self = this,\n valueStr = value + 'px';\n item.style[self.propName] = valueStr; //item.style['min' + self.propName.charAt(0).toUpperCase() + self.propName.slice(1)] = valueStr;\n\n item.style['max' + self.propName.charAt(0).toUpperCase() + self.propName.slice(1)] = valueStr;\n item.style['flexBasis'] = valueStr;\n item.style['msFlexPreferredSize'] = valueStr;\n item.style['webkitFlexBasis'] = valueStr;\n };\n\n Carousel.prototype.processItems = function (items, saveStyleAttribute) {\n var self = this;\n\n for (var i = 0, len = items.length - 1; i <= len; i++) {\n self.processItem(items[i], i, saveStyleAttribute);\n }\n };\n\n Carousel.prototype.processItem = function (item, index, saveStyleAttribute) {\n var self = this;\n var itemStylesComputed = getComputedStyle(item),\n itemBorderLeft,\n itemBorderRight,\n itemBorderTop,\n itemBorderBottom;\n itemBorderLeft = parseInt(itemStylesComputed['border-left-width'], 10);\n itemBorderRight = parseInt(itemStylesComputed['border-right-width'], 10);\n itemBorderTop = parseInt(itemStylesComputed['border-top-width'], 10);\n itemBorderBottom = parseInt(itemStylesComputed['border-bottom-width'], 10);\n itemBorderLeft = isNaN(itemBorderLeft) ? 0 : itemBorderLeft;\n itemBorderRight = isNaN(itemBorderRight) ? 0 : itemBorderRight;\n itemBorderTop = isNaN(itemBorderTop) ? 0 : itemBorderTop;\n itemBorderBottom = isNaN(itemBorderBottom) ? 0 : itemBorderBottom;\n /*,\n itemStylesComputed = getComputedStyle(item),\n itemStylesComputed = item.getBoundingClientRect(),\n itemPaddingLeft,\n itemPaddingRight,\n itemPaddingTop,\n itemPaddingBottom;*/\n\n /*itemPaddingLeft = parseInt(itemStylesComputed['padding-left'], 10);\n itemPaddingRight = parseInt(itemStylesComputed['padding-right'], 10);\n itemPaddingTop = parseInt(itemStylesComputed['padding-top'], 10);\n itemPaddingBottom = parseInt(itemStylesComputed['padding-bottom'], 10);\n itemPaddingLeft = isNaN(itemPaddingLeft) ? 0 : itemPaddingLeft;\n itemPaddingRight = isNaN(itemPaddingRight) ? 0 : itemPaddingRight;\n itemPaddingTop = isNaN(itemPaddingTop) ? 0 : itemPaddingTop;\n itemPaddingBottom = isNaN(itemPaddingBottom) ? 0 : itemPaddingBottom;*/\n\n item.carouselItemData = item.carouselItemData || {};\n item.carouselItemData.originalWidth = item.getBoundingClientRect().width;\n item.carouselItemData.originalHeight = item.getBoundingClientRect().height;\n item.carouselItemData.index = index != null ? index : self.items.length;\n item.carouselItemData.parameters = item.getAttribute('data-parameters') != null ? new Function('return ' + item.getAttribute('data-parameters'))() : null;\n item.carouselItemData.stylesRaw = saveStyleAttribute === true ? item.getAttribute('style') : item.carouselItemData != null ? item.carouselItemData.stylesRaw : null;\n item.classList.add('js-carousel-item');\n item.classList.add('carousel-item');\n return item;\n };\n\n Carousel.prototype.setSizes = function (wrapSize, innerSize, listSize, itemsSizes) {\n var self = this; //if (wrapSize != null) {\n // self.wrap.style[self.propName] = wrapSize[self.propName] + 'px';\n //}\n\n if (innerSize != null) {\n self.inner.style[self.propName] = innerSize[self.propName] + 'px';\n }\n\n if (listSize != null) {\n self.list.style[self.propName] = listSize[self.propName] + 'px';\n }\n\n if (itemsSizes != null) {\n for (var i = self.items.length - 1; i >= 0; i--) {\n self.setItemSize(self.items[i], itemsSizes[self.propName]);\n }\n }\n };\n\n Carousel.prototype.calc = function (items, options, responsiveOptions) {\n var self = this;\n var result = responsiveOptions != null ? self.calcResponsive(items, options, responsiveOptions) : self.calcAuto(items, options);\n self.countVisible = result.countVisible;\n self.wrapSize = result.wrapSize;\n self.listSize = result.listSize;\n self.innerSize = result.innerSize;\n self.itemsSize = result.itemsSize;\n self.slidesSize = result.slidesSize;\n return result;\n };\n\n Carousel.prototype.getCarouselSize = function () {\n var self = this,\n carouselStylesComputed,\n carouselPaddingLeft,\n carouselPaddingRight,\n carouselPaddingTop,\n carouselPaddingBottom;\n carouselStylesComputed = getComputedStyle(self.wrap);\n carouselPaddingLeft = parseInt(carouselStylesComputed['padding-left'], 10);\n carouselPaddingRight = parseInt(carouselStylesComputed['padding-right'], 10);\n carouselPaddingTop = parseInt(carouselStylesComputed['padding-top'], 10);\n carouselPaddingBottom = parseInt(carouselStylesComputed['padding-bottom'], 10);\n carouselPaddingLeft = isNaN(carouselPaddingLeft) ? 0 : carouselPaddingLeft;\n carouselPaddingRight = isNaN(carouselPaddingRight) ? 0 : carouselPaddingRight;\n carouselPaddingTop = isNaN(carouselPaddingTop) ? 0 : carouselPaddingTop;\n carouselPaddingBottom = isNaN(carouselPaddingBottom) ? 0 : carouselPaddingBottom;\n return {\n width: Math.floor(self.wrap.clientWidth - carouselPaddingLeft - carouselPaddingRight),\n height: Math.floor(self.wrap.clientHeight - carouselPaddingTop - carouselPaddingBottom)\n };\n };\n\n Carousel.prototype.calcAuto = function (items, options) {\n var self = this,\n result = {},\n slidesMaxSize,\n countVisibleDirty,\n carouselSizes,\n countVisible,\n dimension,\n propName,\n slidesSize;\n propName = self.propName;\n carouselSizes = self.getCarouselSize();\n slidesMaxSize = self.getItemsMaxSizes(items);\n countVisibleDirty = carouselSizes[propName] / (slidesMaxSize[propName] || 1);\n countVisible = Math.floor(countVisibleDirty); //Math.round\n\n if (options.visibleMin != null && options.visibleMin > items.length) {\n countVisible = items.length;\n dimension = countVisibleDirty - countVisible;\n } else if (countVisible > items.length) {\n countVisible = items.length;\n dimension = 0;\n } else if (countVisible < 1) {\n countVisible = 1;\n dimension = countVisibleDirty - countVisible;\n } else {\n dimension = countVisibleDirty - countVisible;\n }\n\n if (options.visibleMax != null && options.visibleMax < countVisible || options.visibleMin != null && options.visibleMin > countVisible) {\n if (options.visibleMax != null && options.visibleMax < countVisible) {\n countVisible = options.visibleMax;\n } else if (options.visibleMin != null && options.visibleMin > countVisible) {\n countVisible = options.visibleMin;\n slidesMaxSize[propName] = carouselSizes.width / countVisible;\n }\n\n if (options.stretch) {\n slidesMaxSize[propName] = carouselSizes[propName] / countVisible;\n } else {\n //carouselSizes[propName] = carouselSizes[propName] - (slidesMaxSize[propName] * countVisible);\n var sizeSlides = slidesMaxSize[propName] * countVisible;\n carouselSizes[propName] = sizeSlides >= carouselSizes[propName] ? carouselSizes[propName] : carouselSizes[propName] - (carouselSizes[propName] - sizeSlides);\n }\n } else {\n if (isNaN(dimension) == false && dimension !== 0) {\n if (options.stretch) {\n slidesMaxSize[propName] += slidesMaxSize[propName] * dimension / countVisible;\n } else {\n if (dimension > 0) {\n carouselSizes[propName] = carouselSizes[propName] - slidesMaxSize[propName] * dimension;\n } else {\n slidesMaxSize[propName] += slidesMaxSize[propName] * dimension / countVisible;\n\n if (slidesMaxSize[propName] <= 0) {\n slidesMaxSize[propName] = carouselSizes[propName];\n }\n }\n }\n }\n }\n\n if (countVisible <= 1) {\n countVisible = 1;\n result = slidesMaxSize[propName];\n } else {\n result = slidesMaxSize[propName];\n }\n\n var diff = countVisible < items.length ? self.getScrollDiff(result, countVisible) : 0;\n\n if (options.isVertical === false) {\n slidesSize = {\n width: result - diff,\n height: slidesMaxSize.height\n };\n } else {\n slidesSize = {\n width: slidesMaxSize.width,\n height: result - diff\n };\n }\n\n return {\n countVisible: countVisible,\n wrapSize: carouselSizes,\n listSize: self.getSize(self.items.length, slidesMaxSize.width, slidesMaxSize.height, options.isVertical, diff * self.items.length),\n innerSize: self.getSize(countVisible, slidesMaxSize.width, slidesMaxSize.height, options.isVertical),\n itemsSize: slidesSize,\n slidesSize: slidesSize\n };\n };\n\n Carousel.prototype.calcResponsive = function (items, options, responsiveOptions) {\n var self = this,\n propName = self.propName,\n carouselSizes,\n slidesSize,\n slidesMaxSize,\n countVisible;\n\n if (responsiveOptions.slidesToShow != undefined) {\n countVisible = responsiveOptions.slidesToShow;\n } else {\n throw new Error(\"Count sliders to show is not set\");\n }\n\n carouselSizes = self.getCarouselSize();\n slidesMaxSize = self.getItemsMaxSizes(items);\n\n if (options.stretch) {\n slidesMaxSize[propName] = carouselSizes[propName] / countVisible;\n } else {\n //carouselSizes[propName] = carouselSizes[propName] - (slidesMaxSize[propName] * countVisible);\n var sizeSlides = slidesMaxSize[propName] * countVisible;\n carouselSizes[propName] = sizeSlides >= carouselSizes[propName] ? carouselSizes[propName] : carouselSizes[propName] - (carouselSizes[propName] - sizeSlides);\n }\n\n slidesMaxSize = {\n width: carouselSizes.width / countVisible,\n height: carouselSizes.height / countVisible\n };\n var isVertical = self.getIsVerticalOption();\n var diff = self.getScrollDiff(slidesMaxSize[self.getPropName(isVertical)], countVisible);\n\n if (isVertical === false) {\n slidesSize = {\n width: slidesMaxSize.width - diff //height: slidesMaxSize.height\n\n };\n } else {\n slidesSize = {\n //width: slidesMaxSize.width,\n height: slidesMaxSize.height - diff\n };\n }\n\n return {\n countVisible: countVisible,\n wrapSize: carouselSizes,\n listSize: self.getSize(self.items.length, slidesMaxSize.width, slidesMaxSize.height, isVertical, diff * self.items.length),\n innerSize: self.getSize(countVisible, slidesMaxSize.width, slidesMaxSize.height, isVertical),\n itemsSize: slidesSize,\n slidesSize: slidesSize\n };\n };\n\n Carousel.prototype.checkDots = function () {\n var self = this;\n var need;\n\n if (self.options.dots === true) {\n need = self.items.length !== 1 && self.countVisible !== self.items.length;\n\n if (need === false) {\n if (self.dotsContainer != null && self.dotsContainer.parentNode != null) {\n self.dotsContainer.parentNode.removeChild(self.dotsContainer);\n }\n\n self.dotsContainer = null;\n self.dots.length = 0;\n } else {\n self.renderDots();\n self.selectDots(self.options.indexActive);\n }\n }\n };\n\n Carousel.prototype.renderDots = function () {\n var self = this,\n coeffCountVisible = self.options.auto === true ? 0 : self.countVisible,\n newCount,\n dot,\n isRenderContaner = false,\n dim,\n dimAbs,\n itemTemp;\n\n if (self.dotsContainer == null) {\n self.dotsContainer = self.wrap.querySelector('.carousel-dots');\n\n if (self.dotsContainer != null) {\n Array.prototype.forEach.call(self.dotsContainer.children, function (el) {\n self.dots.push(el);\n });\n } else {\n self.dotsContainer = createComponent('ul');\n self.dotsContainer.className = 'carousel-dots ' + (self.options.dotsClass || '');\n isRenderContaner = true;\n }\n }\n\n newCount = self.items.length - coeffCountVisible + (self.options.auto === true ? 0 : 1);\n dim = self.dots.length - newCount;\n dimAbs = Math.abs(dim);\n\n if (dim < 0) {\n for (var d = 0, len = dimAbs; d < len; d++) {\n dot = createComponent('li');\n dot.classList.add('carousel-dots-item');\n dot.innerHTML = '';\n self.dotsContainer.appendChild(dot);\n self.dots.push(dot);\n }\n\n self.dots.forEach(function (el, index) {\n el.setAttribute('data-index', index);\n });\n\n if (isRenderContaner === true) {\n self.wrap.appendChild(self.dotsContainer);\n }\n } else {\n for (var r = dimAbs - 1; r >= 0; r--) {\n itemTemp = self.dots.pop();\n itemTemp.parentNode.removeChild(itemTemp);\n }\n }\n };\n\n Carousel.prototype.renderNav = function () {\n var self = this,\n nav = self.wrap.querySelector('.carousel-nav'),\n navPrev,\n navNext,\n needRenderNav,\n needRenderPrev,\n needRenderNext; //#region nav find or create\n\n if (nav == null || nav.parentNode !== self.wrap) {\n nav = createComponent('div');\n needRenderNav = true;\n }\n\n nav.className = 'carousel-nav ' + ('carousel-nav-' + self.options.navPosition);\n self.nav = nav; //#endregion\n //#region prev find or create\n\n navPrev = nav.querySelector('.carousel-nav-prev');\n\n if (navPrev == null) {\n navPrev = createComponent('button');\n needRenderPrev = true;\n }\n\n self.navPrev = navPrev; //var isVertical = self.getIsVerticalOption();\n //navPrev.className = 'carousel-nav-prev ' + (isVertical ? self.options.prevIconVertical : self.options.prevIcon);\n //if (self.options.prevClass) {\n // self.options.prevClass.split(' ').forEach(function (item) {\n // navPrev.classList.add(item);\n // });\n //}\n\n self.navPrev = navPrev; //#endregion\n //#region next find or create\n\n navNext = nav.querySelector('.carousel-nav-next');\n\n if (navNext == null) {\n navNext = createComponent('button');\n needRenderNext = true;\n }\n\n self.navNext = navNext;\n self.addDirectionClassFromNav(); //navNext.className = 'carousel-nav-next ' + (isVertical ? self.options.nextIconVertical : self.options.nextIcon);\n //if (self.options.nextClass) {\n // self.options.nextClass.split(' ').forEach(function (item) {\n // navNext.classList.add(item);\n // });\n //}\n //#endregion\n\n if (needRenderPrev === true) {\n nav.appendChild(navPrev);\n }\n\n if (needRenderNext === true) {\n nav.appendChild(navNext);\n }\n\n if (needRenderNav === true) {\n self.wrap.appendChild(nav);\n }\n };\n\n Carousel.prototype.removeDirectionClassFromNav = function () {\n var isVertical = this.getIsVerticalOption();\n var self = this;\n self.navNext.className = isVertical ? self.options.nextIconVertical : self.options.nextIcon;\n\n if (self.options.nextClass) {\n self.options.nextClass.split(' ').forEach(function (item) {\n self.navNext.classList.remove(item);\n });\n }\n\n self.navPrev.className = isVertical ? self.options.prevIconVertical : self.options.prevIcon;\n\n if (self.options.prevClass) {\n self.options.prevClass.split(' ').forEach(function (item) {\n self.navPrev.classList.remove(item);\n });\n }\n };\n\n Carousel.prototype.addDirectionClassFromNav = function () {\n var isVertical = this.getIsVerticalOption();\n var self = this;\n self.navNext.className = 'carousel-nav-next ' + (isVertical ? self.options.nextIconVertical : self.options.nextIcon);\n\n if (self.options.nextClass) {\n self.options.nextClass.split(' ').forEach(function (item) {\n self.navNext.classList.add(item);\n });\n }\n\n self.navPrev.className = 'carousel-nav-prev ' + (isVertical ? self.options.prevIconVertical : self.options.prevIcon);\n\n if (self.options.prevClass) {\n self.options.prevClass.split(' ').forEach(function (item) {\n self.navPrev.classList.add(item);\n });\n }\n };\n\n Carousel.prototype.generate = function (element) {\n var self = this,\n wrap,\n inner,\n needRenderInner,\n needRenderWrap;\n element.classList.add('carousel-list');\n\n if (self.options.itemActiveClass != null && self.options.itemActiveClass.length > 0) {\n self.options.itemActiveClass.split(' ').forEach(function (classNameValue) {\n self.items[self.options.indexActive].classList.add(classNameValue);\n });\n }\n\n if (self.options.itemSelectClass != null && self.options.itemSelectClass.length > 0) {\n self.options.itemSelectClass.split(' ').forEach(function (classNameValue) {\n self.items[self.options.indexActive].classList.add(classNameValue);\n });\n } //#region inner find or create\n\n\n if (self.list.parentNode != null && self.list.parentNode.classList.contains('carousel-inner') === true) {\n inner = self.list.parentNode;\n } else {\n inner = createComponent('div');\n needRenderInner = true;\n }\n\n inner.classList.add('carousel-inner');\n self.inner = inner; //#endregion\n //#region wrap find or create\n\n if (self.inner.parentNode != null && self.inner.parentNode.classList.contains('carousel') === true) {\n wrap = self.inner.parentNode;\n } else {\n wrap = createComponent('div');\n needRenderWrap = true;\n }\n\n var isVertical = self.getIsVerticalOption();\n wrap.classList.add('carousel');\n wrap.classList.add('carousel-' + (isVertical ? 'vertical' : 'horizontal'));\n wrap.classList.add('carousel-wrap-nav-' + self.options.navPosition);\n\n if (self.options.carouselClass != null && self.options.carouselClass.length > 0) {\n self.options.carouselClass.split(' ').filter(function (item) {\n return item.length > 0;\n }).forEach(function (item) {\n wrap.classList.add(item);\n });\n }\n\n if (self.options.scrollNav === true) {\n wrap.classList.add('carousel-scroll-nav');\n }\n\n self.wrap = wrap; //#endregion\n //TODO подумать, можно ли оптимизировать рендеринг\n\n if (needRenderInner) {\n wrap.appendChild(inner);\n }\n\n if (needRenderWrap) {\n //element.parentNode.appendChild(wrap);\n element.insertAdjacentElement('beforebegin', wrap);\n }\n\n if (needRenderInner) {\n inner.appendChild(element);\n }\n };\n\n Carousel.prototype.selectDots = function (index) {\n var self = this;\n\n if (self.dots == null || self.dotActive === self.dots[index]) {\n return;\n }\n\n if (self.dotActive != null) {\n self.dotActive.classList.remove('carousel-dots-selected');\n\n if (self.options.dotsItemSelectedClass != null && self.options.dotsItemSelectedClass.length > 0) {\n self.options.dotsItemSelectedClass.split(' ').forEach(function (classNameValue) {\n self.dotActive.classList.remove(classNameValue);\n });\n }\n\n if (self.options.dotsItemInnerSelectedClass != null && self.options.dotsItemInnerSelectedClass.length > 0) {\n self.options.dotsItemInnerSelectedClass.split(' ').forEach(function (classNameValue) {\n self.dotActive.children[0].classList.remove(classNameValue);\n });\n }\n }\n\n if (self.dots[index] != null) {\n self.dotActive = self.dots[index];\n self.dots[index].classList.add('carousel-dots-selected');\n\n if (self.options.dotsItemSelectedClass != null && self.options.dotsItemSelectedClass.length > 0) {\n self.options.dotsItemSelectedClass.split(' ').forEach(function (classNameValue) {\n self.dots[index].classList.add(classNameValue);\n });\n }\n\n if (self.options.dotsItemInnerSelectedClass != null && self.options.dotsItemInnerSelectedClass.length > 0) {\n self.options.dotsItemInnerSelectedClass.split(' ').forEach(function (classNameValue) {\n self.dots[index].children[0].classList.add(classNameValue);\n });\n }\n }\n };\n\n Carousel.prototype.doClone = function () {\n var self = this,\n oldClones,\n itemsDuplicate,\n itemsClonePrev,\n itemsCloneNext,\n fragmentPrev,\n fragmentNext,\n clonePrev,\n cloneNext,\n marginLeftValue;\n var clonesNext = [];\n var clonesPrev = []; //#region find and delete old clones\n\n oldClones = self.list.querySelectorAll('.js-carousel-clone');\n\n for (var c = oldClones.length - 1; c >= 0; c--) {\n oldClones[c].parentNode.removeChild(oldClones[c]);\n }\n\n for (var i = self.items.length - 1; i >= 0; i--) {\n delete self.items[i].carouselItemData.clone;\n }\n\n self.list.style.marginLeft = '0px'; //#endregion\n\n if (self.countVisible >= self.items.length) {\n return null;\n }\n\n itemsDuplicate = self.items.slice();\n itemsClonePrev = Array.prototype.slice.call(itemsDuplicate.reverse(), 0, self.countVisible).reverse();\n itemsCloneNext = Array.prototype.slice.call(itemsDuplicate.reverse(), 0, self.countVisible);\n fragmentPrev = document.createDocumentFragment();\n fragmentNext = document.createDocumentFragment();\n\n for (var p = 0, len = itemsClonePrev.length; p < len; p++) {\n clonePrev = (itemsClonePrev[p].carouselItemData.originalClone || itemsClonePrev[p]).cloneNode(true);\n clonePrev.classList.add('js-carousel-clone');\n self.setItemSize(clonePrev, self.slidesSize[self.propName]);\n fragmentPrev.appendChild(clonePrev);\n clonesPrev.push(clonePrev);\n itemsClonePrev[p].carouselItemData.clone = clonePrev;\n }\n\n for (var n = 0, l = itemsCloneNext.length; n < l; n++) {\n cloneNext = (itemsCloneNext[n].carouselItemData.originalClone || itemsCloneNext[n]).cloneNode(true);\n cloneNext.classList.add('js-carousel-clone');\n self.setItemSize(cloneNext, self.slidesSize[self.propName]);\n fragmentNext.appendChild(cloneNext);\n clonesNext.push(cloneNext);\n itemsCloneNext[n].carouselItemData.clone = cloneNext;\n } //insert for prev\n\n\n self.list.insertBefore(fragmentPrev, self.items[0]); //insert for next\n\n self.list.appendChild(fragmentNext);\n marginLeftValue = -itemsClonePrev.length * self.slidesSize[self.propName];\n self.list.style.marginLeft = marginLeftValue + 'px';\n self.hasClones = true;\n self.countClone = itemsClonePrev.length + itemsCloneNext.length;\n self.clonesInOneDirection = (itemsClonePrev.length + itemsCloneNext.length) / 2;\n var result = {\n clonesNext: clonesNext,\n clonesPrev: clonesPrev,\n clonesNextCount: itemsCloneNext.length,\n clonesPrevCount: itemsClonePrev.length,\n marginLeftValue: marginLeftValue\n };\n\n if (self.options.onDoClone != null) {\n self.options.onDoClone(result);\n }\n\n return result;\n };\n\n Carousel.prototype.getMoveData = function (index) {\n var self = this,\n result;\n\n if (self.items.length > self.countVisible) {\n result = Math.abs(index) * (self.options.scrollCount * self.slidesSize[self.propName]) * (index < 0 ? 1 : -1);\n } else {\n result = 0;\n }\n\n return result;\n };\n\n Carousel.prototype.move = function (transformValue, useAnimate) {\n useAnimate = useAnimate != null ? useAnimate : true;\n var self = this,\n transformObj = {},\n transformStyle;\n var isVertical = self.getIsVerticalOption();\n transformObj[isVertical ? 'top' : 'left'] = transformValue;\n\n if (self.options.scrollNav === false) {\n //elStyle.webkitTransitionDuration = duration;\n //elStyle.transitionDuration = duration;\n self.list.style[transitionDurationName] = useAnimate === false ? '0ms' : self.options.speed / 1000 + 's';\n self.list.style[webkitTransitionDuration] = useAnimate === false ? '0ms' : self.options.speed / 1000 + 's';\n transformStyle = ['translate3d(', transformObj.left || 0, 'px,', ' ', transformObj.top || 0, 'px, 0px)'].join('');\n self.list.style[transformName] = transformStyle;\n } else {\n var scrollValue = Math.floor(isVertical ? self.inner.scrollTop : self.inner.scrollLeft);\n var scrollValueEnd = Math.floor(Math.abs((isVertical ? transformObj.top : transformObj.left) || 0));\n smoothScroll(self.inner, scrollValue, scrollValueEnd, isVertical);\n }\n\n self.transformValue = transformValue;\n };\n\n Carousel.prototype.moveAuto = function () {\n var self = this;\n\n if (autoStop === true) {\n return;\n }\n\n clearTimeout(self.timerAuto);\n self.timerAuto = setTimeout(function () {\n if (autoStop === true) {\n return;\n }\n\n self.next();\n self.moveAuto();\n }, self.options.autoPause);\n };\n\n Carousel.prototype.stopAuto = function () {\n autoStop = true;\n\n if (self.timerAuto != null) {\n clearTimeout(self.timerAuto);\n }\n };\n\n Carousel.prototype.startAuto = function () {\n var self = this;\n autoStop = false;\n self.moveAuto();\n };\n\n Carousel.prototype.checkNav = function () {\n var self = this,\n itemsCount = self.items.length;\n self.isPrevDisabled = self.options.auto === false && 0 === self.options.indexActive || self.countVisible >= itemsCount;\n self.isNextDisabled = self.options.auto === false && self.options.indexActive + self.countVisible === self.items.length || self.countVisible >= itemsCount;\n self.isNavNotShow = itemsCount <= self.countVisible;\n self.isPrevDisabled ? self.navPrev.setAttribute('disabled', 'disabled') : self.navPrev.removeAttribute('disabled');\n self.isNextDisabled ? self.navNext.setAttribute('disabled', 'disabled') : self.navNext.removeAttribute('disabled');\n self.wrap.classList[self.isNavNotShow === true ? 'add' : 'remove']('carousel-nav-not-show');\n };\n\n Carousel.prototype.prev = function () {\n var self = this,\n newIndex;\n var carouselAsNavFor = self.getCarouselAsNav();\n\n if (self.isPrevDisabled === true || self.animationLoop === true) {\n return;\n }\n\n newIndex = self.options.indexActive - self.options.scrollCount; //go to last item\n\n if (self.options.auto === true && newIndex < 0) {\n self.animationLoop = true;\n\n var returnFn = function returnFn() {\n self.list.removeEventListener('transitionend', returnFn);\n setTimeout(function () {\n self.animationLoop = false;\n self.goto(self.items.length - 1, false);\n\n if (carouselAsNavFor != null) {\n carouselAsNavFor.goto(self.items.length - 1, false);\n }\n }, 0);\n };\n\n self.list.addEventListener('transitionend', returnFn);\n }\n\n self.goto(newIndex, true, 'backwards');\n\n if (carouselAsNavFor != null) {\n carouselAsNavFor.goto(newIndex, true, 'backwards');\n }\n };\n\n Carousel.prototype.next = function () {\n var self = this,\n newIndex;\n var carouselAsNavFor = self.getCarouselAsNav();\n\n if (self.isNextDisabled === true || self.animationLoop === true) {\n return;\n }\n\n newIndex = self.options.indexActive + self.options.scrollCount; //go to first item\n\n if (self.options.auto === true && newIndex > self.items.length) {\n self.goto(0, false);\n newIndex = self.options.scrollCount;\n setTimeout(function () {\n self.goto(newIndex, true, 'forward');\n }, 0);\n return;\n }\n\n if (self.options.auto === true && newIndex === self.items.length) {\n // newIndex > self.items.length - self.countVisible\n self.animationLoop = true;\n\n var returnFn = function returnFn() {\n self.list.removeEventListener('transitionend', returnFn);\n setTimeout(function () {\n self.animationLoop = false;\n self.goto(0, false);\n\n if (carouselAsNavFor != null) {\n carouselAsNavFor.goto(0, false);\n }\n }, 0);\n };\n\n self.list.addEventListener('transitionend', returnFn);\n }\n\n self.goto(newIndex, true, 'forward');\n\n if (carouselAsNavFor != null) {\n carouselAsNavFor.goto(newIndex, true, 'forward');\n }\n };\n\n Carousel.prototype.loadImg = function (objForLoad, preload) {\n var self = this;\n var list, img;\n\n if (objForLoad != null) {\n list = Array.prototype.slice.call(objForLoad instanceof NodeList ? objForLoad : [objForLoad]);\n\n for (var i = 0, len = list.length; i < len; i++) {\n img = list[i];\n\n if (img.dataset != null && img.dataset.carouselImg != null) {\n if (self.options.onLazyLoad != null) {\n img.addEventListener('load', function () {\n img.classList.remove('carousel-placeholder');\n });\n self.options.onLazyLoad(img, img);\n }\n } else if (img.dataset != null && img.dataset.src != null && img.classList.contains('loaded') === false && img.dataset.src.indexOf('{{') === -1) {\n // {{ - выражение ангуляра\n img.addEventListener('load', function () {\n img.classList.remove('carousel-placeholder');\n });\n img.src = img.dataset.src;\n img.classList.add('loaded');\n\n if (preload === true) {\n var fakeImg = new Image();\n fakeImg.src = img.dataset.src;\n }\n }\n }\n }\n };\n\n Carousel.prototype.loadImgInsideItems = function (start, end) {\n var self = this;\n var list = [];\n\n if (self.options.auto === true) {\n start = start < 0 ? 0 : start;\n list = list.concat(self.cloneResult.clonesPrev.slice());\n list = list.concat(self.items, self.cloneResult != null ? self.cloneResult.clonesNext : []);\n } else {\n list = list.concat(self.items);\n }\n\n for (var i = start; i < end; i++) {\n self.loadImg(list[i].querySelectorAll('img'));\n }\n };\n\n Carousel.prototype.goto = function (index, isAnimate, direction) {\n var self = this;\n var carouselAsNavFor = self.getCarouselAsNav();\n\n if (self.options.itemActiveClass != null && self.options.itemActiveClass.length > 0) {\n self.options.itemActiveClass.split(' ').forEach(function (classNameValue) {\n self.items[self.options.indexActive].classList.remove(classNameValue);\n self.items[index].classList.add(classNameValue);\n });\n }\n\n if (self.countVisible === 1) {\n if (self.options.itemSelectClass != null && self.options.itemSelectClass.length > 0) {\n self.items[self.options.indexActive].classList.remove(self.options.itemSelectClass);\n self.items[index].classList.add(self.options.itemSelectClass);\n }\n\n if (carouselAsNavFor != null) {\n self.callFnCarouselAsNavFor(self.setItemSelect, [index]);\n }\n }\n\n self.options.indexActive = index;\n var maxIndex;\n\n if (self.items.length < self.countVisible) {\n maxIndex = 0;\n } else {\n maxIndex = self.items.length - self.countVisible + (self.options.auto === true ? self.countVisible : 0);\n }\n\n var minIndex = 0 - (self.options.auto === true ? self.countVisible : 0);\n\n if (self.options.auto === false) {\n if (index < minIndex) {\n index = minIndex;\n self.options.indexActive = minIndex;\n } else if (index > maxIndex) {\n index = maxIndex;\n self.options.indexActive = maxIndex;\n }\n }\n\n isAnimate = isAnimate != null ? isAnimate : true;\n var transform = self.getMoveData(self.options.indexActive);\n self.move(transform, isAnimate);\n\n if (self.options.nav === true) {\n self.checkNav();\n }\n\n if (self.options.dots) {\n var dotsIndex = self.options.indexActive;\n\n if (self.options.auto === true && self.options.indexActive === self.items.length) {\n dotsIndex = 0;\n } else if (self.options.auto === true && self.options.indexActive < 0) {\n dotsIndex = self.items.length - -self.options.indexActive;\n }\n\n self.selectDots(dotsIndex);\n }\n };\n\n Carousel.prototype.removeItem = function (child, keepInCache) {\n var self = this,\n index,\n clone;\n index = self.items.indexOf(child);\n\n if (index < 0) {\n return;\n }\n\n keepInCache = keepInCache != null ? keepInCache : true;\n\n if (child != null && child.parentNode != null) {\n if (self.options.auto === true && child.carouselItemData.clone != null) {\n clone = child.carouselItemData.clone;\n clone.parentNode.removeChild(clone);\n }\n\n child.parentNode.removeChild(child);\n self.items.splice(index, 1);\n }\n\n if (keepInCache === false) {\n self.removeFromCache(child);\n } //else {\n // self.addToCache(child);\n //}\n\n\n self.checkDots();\n return child;\n };\n\n Carousel.prototype.addItem = function (item, positonIndex) {\n var self = this,\n index = self.cache.indexOf(item),\n indexSibling = index - 1;\n\n if (index == -1 || self.items.length === 0 || self.items[indexSibling] == null || self.items[indexSibling].carouselItemData == null) {\n indexSibling = null;\n }\n\n if (indexSibling == null && positonIndex == null) {\n self.items.push(item);\n self.list.insertAdjacentElement('beforeend', item);\n } else {\n self.items.splice(positonIndex != null ? positonIndex : indexSibling + 1, 0, item);\n self.items[positonIndex != null ? positonIndex - 1 : indexSibling].insertAdjacentElement('afterend', item);\n }\n\n if (item.carouselItemData == null) {\n self.processItem(item);\n }\n\n return item;\n };\n\n Carousel.prototype.updateItems = function (newItems, keepInCache) {\n var self = this;\n var insertContent = document.createDocumentFragment();\n self.items.length = 0;\n keepInCache = keepInCache != null ? keepInCache : true;\n\n if (keepInCache === false) {\n self.clearCache();\n }\n\n for (var i = 0, len = newItems.length; i < len; i++) {\n insertContent.appendChild(newItems[i]);\n\n if (i < self.countVisible) {\n self.loadImg(newItems[i].querySelectorAll('img'), true);\n }\n }\n\n self.list.innerHTML = '';\n self.list.appendChild(insertContent);\n self.processItems(newItems, true);\n return newItems;\n };\n\n Carousel.prototype.getItems = function () {\n return this.items;\n };\n\n Carousel.prototype.filterItems = function (filterFunction) {\n var self = this,\n arrayAll = self.cache,\n itemsForVisible;\n var carouselAsNavFor = self.getCarouselAsNav();\n\n if (self.options.filterFn) {\n filterFunction = self.options.filterFn;\n }\n\n itemsForVisible = arrayAll.filter(filterFunction);\n\n for (var i = 0, len = arrayAll.length - 1; i <= len; i++) {\n if (self.observer != null) {\n if (arrayAll[i] != null) {\n var img = arrayAll[i].querySelector('img');\n\n if (img != null) {\n img.classList.remove('loaded');\n self.observer.unobserve(img);\n }\n }\n }\n }\n\n self.items = self.updateItems(itemsForVisible, true);\n\n for (var j = 0; itemsForVisible.length > j; j++) {\n if (self.observer != null) {\n if (itemsForVisible[j] != null) {\n var img = itemsForVisible[j].querySelector('img');\n\n if (img != null) {\n self.observer.observe(img);\n }\n }\n }\n }\n\n self.options.indexActive = 0;\n self.update();\n\n if (carouselAsNavFor != null) {\n self.callFnCarouselAsNavFor(self.filterItems, [filterFunction]);\n }\n\n return self.items;\n };\n\n Carousel.prototype.clearFilterItems = function () {\n var self = this;\n self.filterItems(function () {\n return true;\n });\n };\n\n Carousel.prototype.getActiveItem = function () {\n return this.items[this.options.indexActive];\n };\n\n Carousel.prototype.getSelectedItem = function () {\n return this.itemSelected;\n };\n\n Carousel.prototype.setItemSelect = function (item) {\n var self = this;\n var itemIndex;\n var carouselAsNavFor = self.getCarouselAsNav();\n\n if (item == null) {\n return;\n }\n\n self.itemSelected = null;\n\n if (typeof item === 'number') {\n itemIndex = item;\n item = self.items[item];\n\n if (item == null) {\n return;\n }\n } else {\n itemIndex = self.items.indexOf(item);\n }\n\n for (var j = self.items.length - 1; j >= 0; j--) {\n if (self.options.itemSelectClass != null) {\n self.options.itemSelectClass.split(' ').forEach(function (classNameValue) {\n self.items[j].classList.remove(classNameValue);\n });\n }\n\n if (self.items[j].carouselItemData != null) {\n self.items[j].carouselItemData.isSelect = false;\n }\n }\n\n if (self.options.itemSelectClass != null) {\n self.options.itemSelectClass.split(' ').forEach(function (cssClass) {\n item.classList.add(cssClass);\n\n if (self.options.auto === true && item.carouselItemData != null && item.carouselItemData.clone != null) {\n item.carouselItemData.clone.classList.add(cssClass);\n }\n });\n }\n\n if (item.carouselItemData != null) {\n item.carouselItemData.isSelect = true;\n self.itemSelected = item;\n }\n\n if (carouselAsNavFor != null) {\n self.callFnCarouselAsNavFor(self.setItemSelect, [itemIndex]);\n }\n };\n\n Carousel.prototype.dotClick = function (event) {\n var self = this,\n currentDot,\n index;\n\n if (event.target.tagName.toLowerCase() === 'i') {\n currentDot = event.target.parentNode;\n } else if (event.target.tagName.toLowerCase() === 'li') {\n currentDot = event.target;\n } else {\n return;\n }\n\n index = parseInt(currentDot.getAttribute('data-index'));\n self.goto(index);\n };\n\n Carousel.prototype.itemClick = function (item) {\n var self = this;\n var itemIndex;\n var itemObj;\n var carouselAsNavFor = self.getCarouselAsNav();\n\n if (typeof item === 'number') {\n itemIndex = item;\n itemObj = self.items[itemIndex];\n } else {\n itemIndex = self.items.indexOf(item);\n itemObj = item;\n }\n\n self.setItemSelect(itemObj);\n\n if (self.options.itemSelect != null) {\n self.options.itemSelect(self, itemObj, itemIndex);\n }\n\n if (carouselAsNavFor != null) {\n if (carouselAsNavFor.isVisibleItem(itemIndex) === false) {\n carouselAsNavFor.goto(itemIndex, true);\n }\n\n self.callFnCarouselAsNavFor(self.itemClick, [itemIndex]);\n }\n };\n\n Carousel.prototype.touch = function () {\n var self = this;\n var startCoords, movedCoords;\n\n function touchStart(event) {\n event.stopPropagation();\n startCoords = self.getCoordinates(event);\n movedCoords = startCoords;\n\n if (self.options.auto === true) {\n self.stopAuto();\n }\n\n self.list.addEventListener('touchmove', touchMove, {\n passive: true\n });\n self.list.addEventListener('touchend', touchEnd, {\n passive: true\n });\n }\n\n function touchStartScroll() {\n var scrollEvent = debounce(function () {\n self.inner.removeEventListener('scroll', scrollEvent);\n self.inner.removeEventListener('touchend', scrollEvent);\n var isVertical = self.getIsVerticalOption();\n var newIndex = Math.ceil(self.inner.scrollLeft / self.itemsSize[self.getPropName(isVertical)]);\n self.goto(newIndex, true);\n }, 700);\n self.inner.addEventListener('scroll', scrollEvent, {\n passive: true\n });\n self.inner.addEventListener('touchend', scrollEvent, {\n passive: true\n });\n }\n\n function touchMove(event) {\n var validSwipe;\n var coords = self.getCoordinates(event);\n var dim = coords.main - movedCoords.main;\n var dimAllTime = movedCoords.main - startCoords.main;\n isOverScrollX = self.listSize.width + Math.abs(dimAllTime) - self.slidesSize.width > self.listSize.width;\n\n if (self.options.auto === true) {\n self.goToFirstInMobile();\n }\n\n if (!isScrolling) {\n validSwipe = self.validSwipe(startCoords, coords, dim >= 0 ? 1 : -1);\n\n if (validSwipe === true) {\n isScrolling = true;\n } else {\n isScrolling = false;\n }\n }\n\n if (isScrolling) {\n event.stopPropagation();\n self.move((self.transformValue || 0) + dim, false);\n movedCoords = coords;\n } else {\n if (self.options.scrollNav === false) {\n self.list.removeEventListener('touchmove', touchMove);\n }\n\n self.list.removeEventListener('touchend', touchEnd);\n\n if (self.options.auto === true) {\n self.startAuto();\n }\n }\n }\n\n function touchEnd(event) {\n self.list.removeEventListener('touchmove', touchMove);\n self.list.removeEventListener('touchend', touchEnd);\n var dim = movedCoords.main - startCoords.main;\n\n if (isScrolling) {\n gotoByTouhMove(dim);\n }\n\n if (self.options.auto === true) {\n self.startAuto();\n }\n\n isScrolling = false;\n }\n\n function gotoByTouhMove(dim) {\n var dimAllTime = movedCoords.main - startCoords.main;\n var maxIndex = self.items.length - self.countVisible + (self.options.auto === true ? self.countVisible - 1 : 0);\n var minIndex = 0 - (self.options.auto === true ? self.countVisible - 1 : 0);\n var isVertical = self.getIsVerticalOption();\n var touchMoveItemsCount = Math.abs(Math.round(dimAllTime / self.slidesSize[self.getPropName(isVertical)])) || 1;\n var index = dimAllTime < 0 ? self.options.indexActive + touchMoveItemsCount : self.options.indexActive - touchMoveItemsCount;\n var carouselAsNavFor = self.getCarouselAsNav();\n var direction = dim >= 0 ? 'forward' : 'backward';\n\n if (self.options.auto === false && index > maxIndex) {\n index = maxIndex;\n } else if (self.options.auto === false && index < minIndex) {\n index = minIndex;\n }\n\n if (self.options.auto === true && isOverScrollX && direction === 'backward') {\n index = self.items.length - self.countVisible + self.clonesInOneDirection;\n } else if (self.options.auto === true && isOverScrollX && direction === 'forward') {\n index = 0 - self.countVisible;\n }\n\n if (carouselAsNavFor != null && carouselAsNavFor.isVisibleItem(index) === false) {\n carouselAsNavFor.goto(index, true);\n }\n\n self.goto(index, true);\n isOverScrollX = false;\n }\n\n self.list.addEventListener('touchstart', self.options.scrollNav === false ? touchStart : touchStartScroll, {\n passive: true\n });\n };\n\n Carousel.prototype.getCoordinates = function (event) {\n var self = this;\n var originalEvent = event.originalEvent || event;\n var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];\n var e = originalEvent.changedTouches && originalEvent.changedTouches[0] || touches[0];\n var result;\n var isVertical = self.getIsVerticalOption();\n\n if (isVertical) {\n result = {\n main: e.clientY,\n alt: e.clientX\n };\n } else {\n result = {\n main: e.clientX,\n alt: e.clientY\n };\n }\n\n return result;\n };\n\n Carousel.prototype.validSwipe = function (startCoords, coords) {\n var deltaAlt = Math.abs(coords.alt - startCoords.alt);\n var deltaMain = Math.abs(coords.main - startCoords.main);\n var self = this;\n var touchAngle = Math.atan2(Math.abs(deltaAlt), Math.abs(deltaMain)) * 180 / Math.PI;\n var isVertical = self.getIsVerticalOption();\n\n if (isVertical === false && touchAngle > 45) {\n return false;\n }\n\n if (isVertical === false && touchAngle <= 45) {\n return true;\n }\n\n if (isVertical === true && 90 - touchAngle > 45) {\n return true;\n } else {\n return false;\n }\n };\n\n Carousel.prototype.bindIt = function () {\n var self = this,\n options = self.options;\n\n if (isTouchDevice === true) {\n self.touch();\n window.addEventListener('orientationchange', self.update.bind(self));\n } else {\n window.addEventListener('resize', function () {\n self.update();\n });\n }\n\n if (options.auto === true && isTouchDevice === false) {\n //self.wrap.removeEventListener('mouseenter', self.stopAuto);\n self.wrap.addEventListener('mouseenter', function () {\n self.stopAuto();\n }); //self.wrap.removeEventListener('mouseleave', self.startAuto);\n\n self.wrap.addEventListener('mouseleave', function () {\n self.startAuto();\n });\n }\n\n self.wrap.addEventListener('click', function (event) {\n var itemClicked;\n\n if (options.nav === true) {\n if (event.target === self.navNext) {\n self.next();\n return;\n } else if (event.target === self.navPrev) {\n self.prev();\n return;\n }\n }\n\n if (options.dots === true && closest(event.target, self.dotsContainer) !== null) {\n self.dotClick(event);\n return;\n }\n\n itemClicked = closest(event.target, '.js-carousel-item');\n\n if (itemClicked !== null) {\n self.itemClick(itemClicked);\n }\n });\n\n if (self.options.responsive != null) {\n Object.keys(self.options.responsive).forEach(function (mqRule) {\n var mq = getMediaQuery(mqRule);\n mq.addListener(function (event) {\n if (event.matches === true) {\n self.update();\n }\n });\n });\n }\n\n if (self.options.auto) {\n document.addEventListener('visibilitychange', function () {\n if (document.visibilityState === 'visible') {\n self.startAuto();\n } else {\n self.stopAuto();\n }\n });\n }\n };\n\n Carousel.prototype.init = function () {\n var self = this,\n sizes; //self.cache.length = 0;\n\n self.processItems(self.items, true);\n self.generate(self.list);\n self.sizes = self.calc(self.items, self.options, self.options.responsive != null ? self.responsiveOption : null); //self.wrap, self.inner, self.list,\n\n self.setSizes(self.sizes.wrapSize, self.sizes.innerSize, self.sizes.listSize, self.sizes.itemsSize);\n self.checkDots();\n\n if (self.options.nav === true) {\n self.renderNav();\n }\n\n if (self.options.auto === true && self.countVisible < self.items.length) {\n self.cloneResult = self.doClone();\n self.sizes.listSize[self.propName] += Math.abs(self.cloneResult.marginLeftValue) * 2; //2 - с обеих сторон ширина клонированных слайдов\n\n self.setSizes(self.sizes.wrapSize, self.sizes.innerSize, self.sizes.listSize, self.sizes.itemsSize);\n self.goto(self.options.indexActive, false);\n }\n\n if (self.options.nav === true) {\n self.checkNav();\n }\n\n if (self.options.auto === true) {\n self.startAuto();\n }\n\n if (self.dots != null) {\n self.selectDots(self.options.indexActive);\n }\n\n if (self.options.initFn != null) {\n self.options.initFn(self);\n }\n\n self.bindIt();\n self.setIntersectionObserver();\n self.initilized = true;\n self.wrap.classList.add('carousel-initilized');\n self.addDirectionCarouselClass();\n return self;\n };\n\n Carousel.prototype.resetSizes = function (callback) {\n var self = this;\n var isVertical = self.getIsVerticalOption();\n self.wrap.style[self.propName] = isVertical ? '100%' : 'auto';\n self.inner.style[self.propName] = isVertical ? '100%' : 'auto';\n self.list.style[self.propName] = isVertical ? '100%' : 'auto';\n self.list.style.marginLeft = '0';\n self.removeDirectionCarouselClass();\n\n if (self.navPref != null && self.navNext != null) {\n self.removeDirectionClassFromNav();\n }\n\n var oldClones = self.list.querySelectorAll('.js-carousel-clone');\n\n for (var c = oldClones.length - 1; c >= 0; c--) {\n clearStyleSlide(oldClones[c], self);\n }\n\n for (var i = self.items.length - 1; i >= 0; i--) {\n clearStyleSlide(self.items[i], self);\n self.items[i].setAttribute('style', self.items[i].carouselItemData.stylesRaw || '');\n }\n\n setTimeout(function () {\n callback();\n }, 500);\n };\n\n function clearStyleSlide(slide, carousel) {\n slide.style[carousel.propName] = 'auto';\n slide.style['flex-basis'] = 'auto';\n slide.style['msFlexPreferredSize'] = 'auto';\n slide.style['webkitFlexBasis'] = 'auto';\n\n if (self.propName === 'width') {\n slide.style.maxWidth = 'none';\n } else {\n slide.style.maxHeight = 'none';\n }\n }\n\n Carousel.prototype.update = function () {\n var self = this,\n sizes;\n self.wrap.classList.remove('carousel-nav-not-show');\n self.wrap.classList.add('carousel-update');\n self.resetSizes(function () {\n if (self.list.children != null && self.list.children.length > 0) {\n var childrenWithoutClone = Array.prototype.filter.call(self.list.children, function (child) {\n return child.classList.contains('js-carousel-clone') === false;\n });\n } else {\n return;\n }\n\n self.responsiveOption = self.options.responsive != null ? self.checkResponsive() : null;\n var isVertical = self.getIsVerticalOption();\n self.addDirectionCarouselClass();\n\n if (self.navPref != null && self.navNext != null) {\n self.addDirectionClassFromNav();\n }\n\n self.propName = self.getPropName(isVertical);\n self.items = Array.prototype.slice.call(childrenWithoutClone);\n self.processItems(self.items);\n sizes = self.calc(self.items, self.options, self.responsiveOption);\n self.setSizes(sizes.wrapSize, sizes.innerSize, sizes.listSize, sizes.itemsSize);\n\n if (self.options.auto === true) {\n self.cloneResult = self.doClone();\n\n if (self.cloneResult != null) {\n sizes.listSize[self.propName] += Math.abs(self.cloneResult.marginLeftValue) * 2; //2 - с обеих сторон ширина клонированных слайдов\n }\n\n self.setSizes(sizes.wrapSize, sizes.innerSize, sizes.listSize, sizes.itemsSize); //self.options.indexActive = 0;\n } else {\n if (self.options.nav === true) {\n self.checkNav();\n }\n }\n\n self.goto(self.options.indexActive, false);\n\n if (self.options.dots === true) {\n self.checkDots();\n self.selectDots(self.options.indexActive);\n }\n\n self.wrap.classList.remove('carousel-update');\n });\n };\n\n Carousel.prototype.checkResponsive = function () {\n var self = this;\n var mq;\n var mqOptions;\n var mqRules = Object.keys(this.options.responsive);\n\n for (var i = mqRules.length - 1; i >= 0; i--) {\n mq = getMediaQuery(mqRules[i]);\n mqOptions = self.options.responsive[mqRules[i]];\n\n if (mq.matches === true) {\n break;\n }\n }\n\n return mqOptions;\n };\n\n Carousel.prototype.getCarouselAsNav = function () {\n return storage[this.options.asNavFor] && storage[this.options.asNavFor].obj;\n };\n\n Carousel.prototype.callFnCarouselAsNavFor = function (fn, params) {\n var self = this;\n\n if (self.options.asNavFor != null && self.options.asNavFor.length > 0 && storage[self.options.asNavFor] && storage[self.options.asNavFor].state.callAsNav !== true) {\n storage[self.options.asNavFor].state.callAsNav = true;\n fn.apply(storage[self.options.asNavFor].obj, params);\n storage[self.options.asNavFor].state.callAsNav = false;\n }\n };\n\n Carousel.prototype.whenAsNavForReady = function (idAsNavFor, callback) {\n if (storage[idAsNavFor] != null) {\n callback(storage[idAsNavFor]);\n } else {\n deferList[idAsNavFor] = callback;\n }\n };\n\n Carousel.prototype.resolveAsNavForReady = function (idAsNavFor) {\n if (deferList[idAsNavFor] != null) {\n deferList[idAsNavFor](storage[idAsNavFor]);\n }\n };\n\n Carousel.prototype.isVisibleItem = function (item) {\n var self = this;\n var itemObj = typeof item === 'number' ? self.items[item] : item;\n var itemIndex = itemObj.carouselItemData.index;\n var isVertical = self.getIsVerticalOption();\n var minIndex = (self.options.scrollNav === true ? self.inner.scrollLeft : Math.abs(self.transformValue)) / self.slidesSize[self.getPropName(isVertical)];\n var maxIndex = minIndex + self.countVisible;\n return minIndex < itemIndex && maxIndex > itemIndex;\n };\n\n Carousel.prototype.getScrollDiff = function (itemSize, countVisible) {\n return this.options.scrollNav === true ? Math.ceil(itemSize / 2 / countVisible) : 0;\n };\n\n Carousel.prototype.goToFirstInMobile = function () {\n var self = this;\n\n if (self.options.indexActive >= self.items.length + self.clonesInOneDirection - self.countVisible) {\n self.goto(0, false);\n } else if (self.options.indexActive <= 0 - self.clonesInOneDirection) {\n self.goto(self.items.length - self.countVisible, false);\n }\n };\n\n Carousel.prototype.setIntersectionObserver = function (objOptions, funcCallback, classElement) {\n var self = this;\n var targetArr = self.inner.querySelectorAll(classElement || 'img');\n\n if (targetArr != null && targetArr.length > 0) {\n var isVertical = self.getIsVerticalOption();\n var options = objOptions || {\n root: self.inner,\n rootMargin: (isVertical ? self.innerSize.height : self.innerSize.width) + 'px',\n threshold: 0\n };\n\n var callback = funcCallback || function (entries, observer) {\n entries.forEach(function (entry) {\n if (entry.isIntersecting) {\n var img = entry.target;\n self.loadImg(img);\n self.observer.unobserve(img);\n }\n });\n };\n\n if (window.IntersectionObserver) {\n self.observer = new IntersectionObserver(callback, options);\n\n for (var i = 0; i < targetArr.length; i++) {\n self.observer.observe(targetArr[i]);\n }\n } else {\n for (var i = 0; i < targetArr.length; i++) {\n var img = targetArr[i];\n self.loadImg(img);\n }\n }\n }\n };\n\n Carousel.prototype.getIsVerticalOption = function () {\n var self = this;\n return self.responsiveOption != null && self.responsiveOption.isVertical != null ? self.responsiveOption.isVertical : self.options.isVertical;\n };\n\n Carousel.prototype.removeDirectionCarouselClass = function () {\n this.wrap.classList.remove('carousel-vertical');\n this.wrap.classList.remove('carousel-horizontal');\n };\n\n Carousel.prototype.addDirectionCarouselClass = function () {\n var isVertical = this.getIsVerticalOption();\n this.wrap.classList.add(isVertical ? 'carousel-vertical' : 'carousel-horizontal');\n };\n\n window.Carousel = Carousel;\n\n function createComponent(tagName) {\n if (clonesForCreate[tagName] == null) {\n clonesForCreate[tagName] = document.createElement(tagName);\n }\n\n return clonesForCreate[tagName].cloneNode();\n }\n\n function closest(element, selector) {\n var parent = element,\n matchesSelector;\n\n if (parent == null) {\n return null;\n }\n\n matchesSelector = parent.matches || parent.webkitMatchesSelector || parent.mozMatchesSelector || parent.msMatchesSelector;\n\n while (parent != document.body && parent != document && parent != null) {\n if (typeof selector === 'string') {\n if (matchesSelector.bind(parent)(selector) === true) {\n return parent;\n }\n } else {\n if (parent == selector) {\n return parent;\n }\n }\n\n parent = parent.parentNode;\n }\n\n return null;\n }\n\n function getMediaQuery(value) {\n return window.matchMedia('(min-width:' + value + 'px)');\n }\n\n function smoothScroll(element, scrollValue, scrollEnd, isVertical) {\n var timeLapsed = 0,\n start,\n speed = 700,\n percentage,\n position;\n var distance = scrollEnd - scrollValue;\n\n function go(timestamp) {\n var finish = true;\n\n if (!start) {\n start = timestamp;\n }\n\n timeLapsed += timestamp - start;\n percentage = speed === 0 ? 0 : timeLapsed / speed;\n percentage = percentage > 1 ? 1 : percentage;\n position = Math.floor(scrollValue + distance * animateValue(percentage));\n\n if (position != scrollEnd) {\n finish = false;\n start = timestamp;\n }\n\n element.scrollTo(!isVertical && position, isVertical && position);\n\n if (finish === false) {\n window.requestAnimationFrame(go, element);\n }\n }\n\n window.requestAnimationFrame(go, element);\n }\n\n function debounce(func, ms) {\n var timer;\n return function () {\n if (timer != null) {\n clearTimeout(timer);\n }\n\n var vm = this;\n var args = arguments;\n timer = setTimeout(function () {\n func.apply(vm, args);\n }, ms);\n };\n } //easeInOutCubic\n\n\n function animateValue(time) {\n return time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1;\n }\n})(window);","var CarouselCtrl = function CarouselCtrl($element, $scope, $q, carouselService) {\n var ctrl = this;\n var carouselImgList = {};\n var deferList = [];\n\n ctrl.init = function () {\n var element = $element[0];\n return carouselService.waitLoadImages(element.querySelectorAll('img'), ctrl.carouselOptions).then(function () {\n setTimeout(function () {\n var carouselEl = element;\n\n if (ctrl.initilazeTo != null) {\n carouselEl = carouselEl.querySelector(ctrl.initilazeTo);\n }\n\n ctrl.carouselNative = new Carousel(carouselEl, ctrl.carouselOptions).init();\n\n if (deferList.length > 0) {\n deferList.forEach(function (item) {\n item.resolve(ctrl);\n });\n }\n\n $scope.$digest();\n }, 0);\n });\n };\n\n ctrl.addCarouselImg = function (carouselImg) {\n var id = ctrl.generateCarouselImgId();\n carouselImgList[id] = carouselImg;\n return id;\n };\n\n ctrl.callFnFromCarouselImg = function (img, carouselItem) {\n var id = img.dataset.carouselImgId;\n\n if (carouselImgList[id] != null) {\n carouselImgList[id].callback();\n }\n };\n\n ctrl.generateCarouselImgId = function () {\n return 'carouselImgId_' + Math.random();\n };\n\n ctrl.whenCarouselInit = function () {\n var defer = $q.defer();\n\n if (ctrl.carouselNative == null) {\n deferList.push(defer);\n } else {\n defer.resolve(ctrl);\n }\n\n return defer.promise;\n };\n};\n\nCarouselCtrl.$inject = ['$element', '$scope', '$q', 'carouselService'];\nexport default CarouselCtrl;","carouselImgDirective.$inject = [\"$parse\"];\ncarouselDirective.$inject = [\"$compile\", \"$document\", \"$window\", \"carouselDefault\"];\n\n/* @ngInject */\nfunction carouselDirective($compile, $document, $window, carouselDefault) {\n return {\n restrict: 'A',\n scope: {\n isVertical: '&',\n scrollCount: '&',\n nav: '&',\n dots: '&',\n speed: '&',\n auto: '&',\n autoPause: '&',\n indexActive: '=?',\n prevIcon: '@',\n nextIcon: '@',\n filterFn: '&',\n prevIconVertical: '@',\n nextIconVertical: '@',\n prevClass: '@',\n nextClass: '@',\n dotsClass: '@',\n dotsItemClass: '@',\n dotsItemSelectedClass: '@',\n dotsItemInnerSelectedClass: '@',\n visibleMax: '&',\n visibleMin: '&',\n itemSelectClass: '@',\n itemActiveClass: '@',\n carouselClass: '@',\n stretch: '&',\n navPosition: '@',\n initOnLoad: ' 0) {\n if (children.length === 1 && children[0].classList.contains('carousel-inner')) {\n children = children[0].children;\n }\n\n if (children != null) {\n for (var i = 0, len = children.length; i < len; i++) {\n children[i].carouselItemData = children[i].carouselItemData || {};\n children[i].carouselItemData.originalClone = children[i].cloneNode(true);\n }\n }\n }\n }\n\n memoryItemsAsClone();\n\n if ($document[0].readyState !== 'complete') {\n $window.addEventListener('load', function () {\n _initWrap();\n });\n } else {\n _initWrap();\n }\n }\n };\n}\n\n;\n/* @ngInject */\n\nfunction carouselImgDirective($parse) {\n return {\n require: '^?carousel',\n link: function link(scope, element, attrs, carouselCtrl) {\n if (carouselCtrl != null) {\n var callbackParsed = $parse(attrs.carouselImg);\n\n var callback = function callback(img, carouselItem) {\n return callbackParsed(scope, {\n img: img,\n carouselItem: carouselItem\n });\n };\n\n var carouselImgId = carouselCtrl.addCarouselImg({\n callback: callback\n });\n attrs.$set('dataCarouselImgId', carouselImgId);\n }\n }\n };\n}\n\n;\nmodule.exports = {\n carouselDirective: carouselDirective,\n carouselImgDirective: carouselImgDirective\n};","var carouselService = function carouselService($q) {\n var service = this;\n\n var imageLoad = function imageLoad(imageSrc) {\n var deferItem = $q.defer(),\n imageFake = new Image();\n imageFake.addEventListener('load', function () {\n deferItem.resolve(true);\n });\n imageFake.addEventListener('error', function () {\n deferItem.resolve();\n });\n imageFake.src = imageSrc;\n return deferItem.promise;\n };\n\n var checkNeedLoad = function checkNeedLoad(image) {\n return !image.complete || typeof image.naturalWidth === 'undefined' || image.naturalWidth === 0;\n };\n\n service.waitLoadImages = function (images, carouselOptions) {\n var deferMain = $q.defer(),\n promises = [];\n var countLoadImageInit = carouselOptions.visibleMax;\n var countLoadImage;\n\n if (countLoadImageInit != null) {\n countLoadImage = images.length - 1 <= countLoadImageInit ? images.length - 1 : countLoadImageInit;\n } else {\n countLoadImage = images.length - 1;\n }\n\n for (var i = 0; i <= countLoadImage; i++) {\n if (checkNeedLoad(images[i]) === true) {\n promises.push(imageLoad(images[i].src || images[i].dataset.src));\n }\n\n if ((images[i].src == null || images[i].src.length === 0) && images[i].dataset.src != null && images[i].dataset.src.length > 0) {\n images[i].src = images[i].dataset.src;\n }\n }\n\n if (carouselOptions.auto === true && countLoadImageInit != null) {\n for (var k = images.length - 1; k >= images.length - countLoadImageInit; k--) {\n if (checkNeedLoad(images[k]) === true) {\n promises.push(imageLoad(images[k].src || images[k].dataset.src));\n }\n\n if ((images[k].src == null || images[k].src.length === 0) && images[k].dataset.src != null && images[k].dataset.src.length > 0) {\n images[k].src = images[k].dataset.src;\n }\n }\n }\n\n if (promises.length === 0) {\n promises.push(deferMain.promise);\n deferMain.resolve();\n }\n\n return $q.all(promises);\n };\n};\n\ncarouselService.$inject = ['$q'];\nexport default carouselService;","iframeResponsiveCtrl.$inject = [\"$sce\", \"iframeResponsiveService\", \"$scope\", \"$timeout\"];\n\n/*@ngInject*/\nfunction iframeResponsiveCtrl($sce, iframeResponsiveService, $scope, $timeout) {\n var ctrl = this,\n urlRegex = new RegExp('(https?:\\/\\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\\/\\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})'),\n stateChangeFlag = true;\n\n ctrl.showContent = function () {\n ctrl.isShowContent = true;\n\n if (ctrl.deviceMobile && ctrl.asBackground) {\n if (ctrl.useVimeo) {\n var vimeoVideoId = iframeResponsiveService.getVideoIdFromVimeo(ctrl.src);\n iframeResponsiveService.getVimeoCover(vimeoVideoId).then(function (response) {\n if (response.data != null) {\n ctrl.coverVideoPath = response.data.thumbnail_url;\n }\n });\n } else if (ctrl.useYouTube) {\n var YTVideoId = iframeResponsiveService.getVideoIdFromYouTube(ctrl.src);\n ctrl.coverVideoPath = iframeResponsiveService.getYTCover(YTVideoId);\n }\n } else {\n if (ctrl.isPlayerCode) {\n ctrl.playerCode = ctrl.src;\n } else {\n ctrl.src = iframeResponsiveService.getSrc(ctrl.src);\n }\n\n if (ctrl.inModal === true) {\n ctrl.pasteVideoForModal(ctrl.src);\n } else {\n //$timeout(function () {\n ctrl.pasteVideo(ctrl.src, ctrl.autoplay, ctrl.loop); //}, 0);\n }\n }\n };\n\n ctrl.pasteVideoForModal = function (src) {\n ctrl.stopOthersVideo();\n ctrl.showVideo();\n ctrl.hideCover();\n\n if (ctrl.useYouTube) {\n src = iframeResponsiveService.getYouTubeCode(src, true);\n }\n\n if (ctrl.useVimeo) {\n src = iframeResponsiveService.getVimeoCode(src, true);\n }\n\n ctrl.iframeSrc = $sce.trustAsResourceUrl(src);\n };\n\n ctrl.onPlayerReady = function (event) {\n if (ctrl.autoplay) {\n ctrl.player.mute();\n ctrl.player.playVideo();\n }\n\n if (stateChangeFlag) {\n stateChangeFlag = false;\n }\n };\n\n ctrl.onPlayerStateChange = function (event) {\n ctrl.videoLoaded = true;\n\n if (event.data === -1) {\n ctrl.muteOn = true; // autoplay\n\n $timeout(function () {\n ctrl.hideCover();\n }, 100);\n } else if (event.data === 1) {\n if (!ctrl.disabledStop) {\n iframeResponsiveService.run(ctrl, 'youtube');\n }\n }\n };\n\n ctrl.showVideo = function () {\n ctrl.visibleVideo = true;\n };\n\n ctrl.hideVideo = function () {\n ctrl.visibleVideo = false;\n };\n\n ctrl.showCover = function () {\n ctrl.visibleCover = true;\n };\n\n ctrl.hideCover = function () {\n ctrl.visibleCover = false;\n };\n\n ctrl.stopOthersVideo = function () {\n if (!ctrl.disabledStop) {\n iframeResponsiveService.run(ctrl, 'vimeo');\n iframeResponsiveService.run(ctrl, 'youtube');\n }\n };\n\n ctrl.pasteYTIframeSrc = function (src, playerId, autoplay, loop) {\n var YTVideoId = iframeResponsiveService.getVideoIdFromYouTube(src);\n ctrl.coverVideoPath = iframeResponsiveService.getYTCover(YTVideoId);\n $timeout(function () {\n if (!iframeResponsiveService.checkInitYouTubeIframeAPI()) {\n iframeResponsiveService.addOnYouTubeIframeAPIReady().then(function () {\n ctrl.player = iframeResponsiveService.getYTPlayerAPI(playerId, YTVideoId, {\n 'onReady': ctrl.onPlayerReady,\n 'onStateChange': ctrl.onPlayerStateChange\n }, autoplay, loop);\n }).catch(function (error) {\n console.error(error);\n });\n } else {\n ctrl.player = iframeResponsiveService.getYTPlayerAPI(ctrl.playerId, YTVideoId, {\n 'onReady': ctrl.onPlayerReady,\n 'onStateChange': ctrl.onPlayerStateChange\n }, autoplay);\n }\n });\n var YTCode = iframeResponsiveService.getYouTubeCode(src, autoplay, YTVideoId, loop);\n ctrl.iframeSrc = $sce.trustAsResourceUrl(YTCode);\n };\n\n ctrl.pasteVimeoIframeSrc = function (src, playerId, autoplay, loop) {\n var vimeoVideoId = iframeResponsiveService.getVideoIdFromVimeo(src);\n iframeResponsiveService.getVimeoCover(vimeoVideoId).then(function (response) {\n if (response.data != null) {\n ctrl.coverVideoPath = response.data.thumbnail_url;\n }\n });\n $timeout(function () {\n if (!iframeResponsiveService.checkInitVimeoIframeAPI()) {\n iframeResponsiveService.addVimeoIframeAPI().then(function () {\n ctrl.player = iframeResponsiveService.getVimeoPlayerAPI(playerId, vimeoVideoId, autoplay, loop);\n ctrl.player.on('play', function () {\n ctrl.stopOthersVideo();\n iframeResponsiveService.run(ctrl, 'vimeo');\n ctrl.hideCover();\n $scope.$digest();\n });\n }).catch(function (error) {\n console.error(error);\n });\n } else {\n ctrl.player = iframeResponsiveService.getVimeoPlayerAPI(playerId, vimeoVideoId, autoplay, loop);\n }\n });\n };\n\n ctrl.pasteVideo = function (src, autoplay, loop) {\n ctrl.playerId = iframeResponsiveService.getPlayerId();\n\n if (ctrl.useYouTube) {\n ctrl.pasteYTIframeSrc(src, ctrl.playerId, autoplay, loop);\n }\n\n if (ctrl.useVimeo) {\n ctrl.pasteVimeoIframeSrc(src, ctrl.playerId, autoplay, loop);\n }\n };\n}\n\n;\nexport default iframeResponsiveCtrl;","iframeResponsiveDirective.$inject = [\"iframeResponsiveService\", \"$templateRequest\", \"$compile\"];\n\n/*@ngInject*/\nexport default function iframeResponsiveDirective(iframeResponsiveService, $templateRequest, $compile) {\n return {\n controller: 'IframeResponsiveCtrl',\n controllerAs: '$ctrl',\n bindToController: true,\n priority: 100,\n scope: {\n src: '@',\n videoWidth: '@',\n videoHeight: '@',\n autoplay: '
'\n };\n}\n;","import './styles/iframe-responsive.css';\nimport iframeResponsiveCtrl from './controllers/iframeResponsiveController.js';\nimport iframeResponsiveDirective from './directives/iframeResponsiveDirective.js';\nimport iframeResponsiveService from './services/iframeResponsiveService.js';\nvar moduleName = 'iframeResponsive';\nangular.module(moduleName, []).directive('iframeResponsive', iframeResponsiveDirective).service('iframeResponsiveService', iframeResponsiveService).controller('IframeResponsiveCtrl', iframeResponsiveCtrl);\nexport default moduleName;","export default function iframeResponsiveService($q, $window, $http) {\n var service = this,\n initializedYTList = [],\n initializedVimeoList = [],\n playerId = 0,\n regExpIdVideo = /^.*(youtu.be\\/|v\\/|e\\/|u\\/\\w+\\/|embed\\/|v=)([^#\\&\\?]*).*/,\n regExpIframe = new RegExp('(?:])'),\n regExpGetUrlFromSrc = new RegExp('(?:src=\").*?(?=[\\?\"])'),\n urlRegex = new RegExp('(https?:\\/\\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\\/\\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})'),\n loadedYouTubeIframeAPI = false,\n loadedVimeoIframeAPI = false,\n activeItem;\n\n service.checkInitYouTubeIframeAPI = function () {\n return loadedYouTubeIframeAPI;\n };\n\n service.checkInitVimeoIframeAPI = function () {\n return loadedVimeoIframeAPI;\n };\n\n service.addYouTubeIframeAPI = function () {\n var tag = document.createElement('script');\n tag.src = \"https://www.youtube.com/iframe_api\";\n var firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n };\n\n service.addVimeoIframeAPI = function () {\n var defer = $q.defer();\n initializedVimeoList.push(defer);\n var tag = document.createElement('script');\n tag.src = 'https://player.vimeo.com/api/player.js';\n\n tag.onload = function () {\n initializedVimeoList.forEach(function (defer) {\n defer.resolve();\n });\n loadedVimeoIframeAPI = true;\n };\n\n var firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n return defer.promise;\n };\n\n service.addOnYouTubeIframeAPIReady = function () {\n window.onYouTubeIframeAPIReady = function () {\n initializedYTList.forEach(function (defer) {\n defer.resolve();\n });\n loadedYouTubeIframeAPI = true;\n };\n\n var defer = $q.defer();\n initializedYTList.push(defer);\n\n if (!service.checkInitYouTubeIframeAPI()) {\n service.addYouTubeIframeAPI();\n }\n\n return defer.promise;\n };\n\n service.getPlayerId = function () {\n return 'player' + (playerId += 1);\n };\n\n service.getVideoIdFromYouTube = function (url) {\n return url.match(regExpIdVideo)[2];\n };\n\n service.getVideoIdFromVimeo = function (url) {\n return url.split('vimeo.com/')[url.split('vimeo.com').length - 1];\n };\n\n service.getYTPlayerAPI = function (elId, videoId, callbacks, autoplay, loop) {\n return new YT.Player(elId, {\n videoId: videoId,\n host: 'https://www.youtube.com',\n playerVars: {\n 'rel': 0,\n 'enablejsapi': 1,\n 'modestbranding': 1,\n 'showinfo': 0,\n 'iv_load_policy': 3,\n 'origin': location.origin.toString(),\n 'autoplay': autoplay ? 1 : 0,\n 'controls': loop ? 0 : 1,\n 'loop': loop ? 1 : 0,\n 'playlist': videoId,\n 'mute': loop ? 1 : 0\n },\n events: callbacks\n });\n };\n\n service.getVimeoPlayerAPI = function (elId, videoId, autoplay, loop) {\n return new Vimeo.Player(elId, {\n id: videoId,\n autoplay: autoplay != null ? autoplay : false,\n muted: autoplay != null ? autoplay : false,\n loop: loop === true\n });\n };\n\n service.run = function (obj, type) {\n if (activeItem != null && activeItem.obj !== obj && activeItem.obj.player != null) {\n if (activeItem.type === 'youtube') {\n activeItem.obj.player.pauseVideo();\n } else if (activeItem.type === 'vimeo') {\n activeItem.obj.player.pause();\n }\n }\n\n activeItem = {\n obj: obj,\n type: type\n };\n };\n\n service.checkUrlFromIframe = function (url) {\n return url.match(regExpIframe);\n };\n\n service.getSrc = function (url) {\n if (service.checkUrlFromIframe(url)) {\n return url.match(regExpGetUrlFromSrc)[0].match(urlRegex)[0];\n }\n\n return url;\n };\n\n service.isPlayerCode = function (url) {\n return url.match(urlRegex) == null;\n };\n\n service.getYouTubeCode = function (link, autoplay, videoId, loop) {\n link = link.indexOf('https://') === -1 ? 'https://' + link : link;\n return link.replace('youtu.be', 'youtube.com/embed/').replace('watch?v=', 'embed/').split('&')[0] + '?rel=0&enablejsapi=1&modestbranding=1&showinfo=0&iv_load_policy=3' + (autoplay || loop ? '&autoplay=1&mute=1' : '') + (loop ? '&loop=1&controls=0&wmode=transparent&playlist=' + videoId + '' : '') + '&origin=' + location.origin;\n };\n\n service.getVimeoCode = function (link, autoplay, loop) {\n return 'https://player.vimeo.com/video' + link.split('vimeo.com')[link.split('vimeo.com').length - 1] + '?title=0&byline=0&portrait=0' + (autoplay ? '&autoplay=1&muted=1' : '') + (loop ? '&loop=1' : '');\n };\n\n service.getYTCover = function (YTVideoId) {\n return 'https://i.ytimg.com/vi/' + YTVideoId + '/maxresdefault.jpg';\n };\n\n service.getVimeoCover = function (vimeoId) {\n return $http.get('https://vimeo.com/api/oembed.json?url=https%3A//vimeo.com/' + vimeoId, {\n format: 'json',\n width: '1280'\n }).then(function (response) {\n return response;\n }).catch(function (error) {\n console.error(error);\n });\n };\n}\n;\niframeResponsiveService.$inject = ['$q', '$window', '$http'];","RatingCtrl.$inject = [\"$http\"];\n\n/* @ngInject */\nfunction RatingCtrl($http) {\n var ctrl = this;\n ctrl.items = [];\n\n ctrl.select = function (val) {\n if (ctrl.readonly === false) {\n ctrl.current = val;\n\n for (var i = 0; i < val; i++) {\n ctrl.items[i].isSelected = true;\n }\n\n if (ctrl.url) {\n return $http.post(ctrl.url, {\n objId: ctrl.objId,\n rating: ctrl.current\n }).then(function (response) {\n ctrl.current = response.data;\n });\n }\n }\n };\n}\n\n;\nexport default RatingCtrl;","function ratingDirective() {\n return {\n require: ['rating', '?ngModel'],\n restrict: 'A',\n scope: true,\n controller: 'RatingCtrl',\n controllerAs: 'rating',\n bindToController: true,\n link: function link(scope, element, attrs, ctrls) {\n var rating = ctrls[0];\n var ngModel = ctrls[1];\n var childs = element[0].children;\n rating.max = parseInt(attrs.max) || 5;\n rating.readonly = attrs.readonly != null ? attrs.readonly === 'true' : false;\n\n if (rating.readonly) {\n element[0].classList.add(\"rating-readonly\");\n }\n\n rating.current = parseInt(attrs.current);\n rating.url = attrs.url;\n rating.objId = attrs.objId;\n rating.rateBinding = attrs.rateBinding;\n\n for (var i = 0; i <= childs.length - 1; i++) {\n childs[i].setAttribute(\"data-index\", childs.length - i);\n rating.items[i] = {\n isSelected: rating.current - 1 < i\n };\n }\n\n if (rating.readonly === false) {\n element[0].addEventListener('click', function (event) {\n if (event.target.classList.contains('rating-item') === true) {\n if (ngModel != null) {\n ngModel.$setViewValue(parseInt(event.target.getAttribute('data-index')));\n }\n\n var promise = rating.select(parseInt(event.target.getAttribute('data-index')));\n\n if (promise) {\n promise.then(function () {\n element[0].classList.add(\"rating-readonly\");\n });\n }\n\n scope.$digest();\n }\n });\n }\n }\n };\n}\n\nexport { ratingDirective };","import './styles/rating.scss';\nimport { ratingDirective } from './directives/ratingDirectives.js';\nimport RatingCtrl from './controllers/ratingController.js';\nvar moduleName = 'rating';\nangular.module(moduleName, []).controller('RatingCtrl', RatingCtrl).directive('rating', ratingDirective);\nexport default moduleName;","function RotateCtrl() {\n var ctrl = this;\n\n ctrl.$onInit = function () {\n ctrl.rotateOptions = {\n totalFrames: parseInt(ctrl.totalFrames),\n // Total no. of image you have for 360 slider\n endFrame: parseInt(ctrl.endFrame),\n // end frame for the auto spin animation\n currentFrame: parseInt(ctrl.currentFrame) || 1,\n // This the start frame for auto spin\n imgList: ctrl.imgList,\n // selector for image list\n progress: ctrl.progress,\n // selector to show the loading progress\n imagePath: ctrl.imagePath,\n // path of the image assets\n ext: ctrl.ext || '.png',\n // extention for the assets\n height: parseInt(ctrl.height) || 300,\n width: parseInt(ctrl.width) || 300,\n navigation: ctrl.navigation() || false,\n responsive: ctrl.responsive() || false,\n autoplayDirection: parseInt(ctrl.autoplayDirection) || 1,\n framerate: parseInt(ctrl.framerate) || 60,\n disableSpin: false\n };\n };\n}\n\n;\nexport default RotateCtrl;","rotateDirective.$inject = [\"$window\"];\n\n/*@ngInject*/\nfunction rotateDirective($window) {\n return {\n restrict: 'A',\n scope: {\n imagePath: '@',\n totalFrames: '@',\n endFrame: '@',\n height: '@',\n width: '@',\n imgList: '@',\n progress: '@',\n navigation: '&',\n responsive: '&',\n autoplayDirection: '@',\n // -1 or 1\n autoplay: '&',\n ext: '@',\n framerate: '@'\n },\n controller: 'RotateCtrl',\n controllerAs: 'rotate',\n bindToController: true,\n replace: true,\n template: '
0%
    ',\n link: function link(scope, element, attrs, ctrl) {\n var img = new Image();\n img.addEventListener('load', function () {\n var wInnerWidthCut = $window.innerWidth * 0.75;\n var wInnerHeightCut = $window.innerHeight * 0.75;\n var resultWidth = Math.min(wInnerWidthCut, img.naturalWidth);\n var diffWidth = img.naturalWidth > wInnerWidthCut ? img.naturalWidth - wInnerWidthCut : 0;\n var resultHeight;\n\n if (wInnerWidthCut < img.naturalWidth) {\n resultHeight = (img.naturalWidth - diffWidth) * img.naturalHeight / img.naturalWidth;\n } else {\n resultHeight = img.naturalHeight;\n }\n\n ctrl.rotateOptions.width = resultWidth;\n ctrl.rotateOptions.height = resultHeight;\n element.ThreeSixty(ctrl.rotateOptions);\n });\n img.src = ctrl.rotateOptions.imagePath + '1' + ctrl.rotateOptions.ext;\n }\n };\n}\n\n;\nexport { rotateDirective };","import '../../../vendors/threesixty/styles/threesixty.css';\nimport '../../../vendors/threesixty/threesixty.js';\nimport RotateCtrl from './controllers/rotateController.js';\nimport { rotateDirective } from './directives/rotateDirectives.js';\nvar moduleName = 'rotate';\nangular.module(moduleName, []).controller('RotateCtrl', RotateCtrl).directive('rotate', rotateDirective);\nexport default moduleName;","function TabContentCtrl() {}\n\n;\nexport default TabContentCtrl;","function TabHeaderCtrl() {\n this.selected = {};\n this.isRender = true;\n}\n\n;\nexport default TabHeaderCtrl;","TabsCtrl.$inject = [\"$q\", \"tabsService\", \"urlHelper\", \"$scope\"];\n\n/* @ngInject */\nfunction TabsCtrl($q, tabsService, urlHelper, $scope) {\n var ctrl = this,\n panes = ctrl.panes = {},\n queueHeader = {},\n queueContent = {},\n tabSelected,\n locationUnwatch;\n\n ctrl.$postLink = function () {\n ctrl.selectFromUrl();\n window.addEventListener('popstate', function (e) {\n ctrl.selectFromUrl();\n });\n };\n\n ctrl.selectFromUrl = function () {\n var tabId = urlHelper.getUrlParam('tab', false);\n\n if (tabId != null && panes[tabId] != null) {\n if (tabId != null && ctrl.tabsOnSelect != null) {\n ctrl.tabsOnSelect($scope, {\n tabHeader: panes[tabId],\n fromUrl: true\n });\n }\n\n var tabObj = tabsService.findTabByid(tabId);\n\n if (panes[tabId].headerTab != null && panes[tabId].headerTab.length > 0) {\n ctrl.headerTab = panes[tabId].headerTab;\n }\n\n if (tabObj != null && tabObj.pane != null && tabObj.pane.selected === false) {\n ctrl.change(tabObj.pane, true);\n }\n }\n };\n\n ctrl.select = function (tabHeader) {\n var keys = Object.keys(panes);\n\n if (ctrl.tabsOnSelect != null) {\n ctrl.tabsOnSelect($scope, {\n tabHeader: tabHeader\n });\n }\n\n if (ctrl.isToggle === false) {\n for (var i = 0, len = keys.length; i < len; i++) {\n panes[keys[i]].selected = false;\n }\n\n tabHeader.selected = true;\n tabSelected = tabHeader;\n } else {\n tabHeader.selected = !tabHeader.selected;\n tabSelected = tabHeader.selected === false ? null : tabHeader;\n }\n };\n\n ctrl.addHeader = function (tabHeader) {\n var defer = $q.defer(),\n searchTabId = urlHelper.getUrlParam('tab', false);\n panes[tabHeader.id] = tabHeader;\n\n if (queueHeader[tabHeader.id] != null) {\n queueHeader[tabHeader.id].resolve(tabHeader);\n queueHeader[tabHeader.id].promise.then(function () {\n tabHeader.isRender = tabContent.isRender;\n\n if (tabHeader.isRender === true && (tabHeader.id == searchTabId || tabSelected == null)) {\n ctrl.select(tabHeader);\n } else {\n tabHeader.selected = false;\n }\n });\n } else {\n if (tabHeader.content == null) {\n queueContent[tabHeader.id] = defer;\n } else {\n defer.resolve(header);\n }\n\n defer.promise.then(function (tabContent) {\n tabHeader.content = tabContent;\n tabHeader.isRender = tabContent.isRender;\n\n if (tabHeader.isRender === true && (tabHeader.id == searchTabId || tabSelected == null)) {\n ctrl.select(tabHeader);\n } else {\n tabHeader.selected = false;\n }\n\n return tabContent;\n });\n }\n };\n\n ctrl.addContent = function (tabContent) {\n var header = panes[tabContent.headerId],\n defer = $q.defer(); //если заголовок ещё не проинициализовался\n\n if (header == null) {\n queueHeader[tabContent.headerId] = defer;\n } else {\n defer.resolve(header);\n }\n\n defer.promise.then(function (header) {\n tabContent.header = header;\n return header;\n }); //проверяем если обещания на получения контента\n\n if (queueContent[tabContent.headerId] != null) {\n queueContent[tabContent.headerId].resolve(tabContent);\n }\n };\n\n ctrl.change = function (tabHeader, ignoreUrl) {\n if (ctrl.allowHideAll === true && tabHeader.selected === true) {\n tabHeader.selected = false;\n } else {\n ctrl.select(tabHeader);\n\n if (tabHeader.headerTab != null && tabHeader.headerTab.length > 0) {\n ctrl.headerTab = tabHeader.headerTab;\n }\n\n if (angular.isDefined(tabHeader.id) && !ignoreUrl) {\n urlHelper.setLocationQueryParams('tab', tabHeader.id);\n }\n }\n };\n}\n\n;\nexport default TabsCtrl;","tabsGotoDirective.$inject = [\"$window\", \"tabsService\"];\ntabsDirective.$inject = [\"tabsService\", \"$parse\", \"urlHelper\"];\n\n/* @ngInject */\nfunction tabsDirective(tabsService, $parse, urlHelper) {\n return {\n restrict: 'A',\n scope: true,\n controller: 'TabsCtrl',\n controllerAs: 'tabs',\n bindToController: true,\n compile: function compile(cElement, cAttrs) {\n var onSelect;\n\n if (cAttrs.type == null) {\n cAttrs.$set('type', 'horizontal');\n }\n\n if (cAttrs.classesTabActive == null) {\n cAttrs.$set('classesTabActive', 'tabs-header-active cs-br-1');\n }\n\n if (cAttrs.classesLinkActive == null) {\n cAttrs.$set('classesLinkActive', 'cs-l-2 link-dotted-invert link-dotted-none');\n }\n\n if (cAttrs.classesLink == null) {\n cAttrs.$set('classesLink', 'link-dotted-invert');\n }\n\n if (cAttrs.tabsOnSelect) {\n onSelect = $parse(cAttrs.tabsOnSelect);\n }\n\n return function (scope, element, attrs, ctrl) {\n ctrl.tabsOnSelect = onSelect;\n ctrl.type = attrs.type;\n ctrl.classesTabActive = attrs.classesTabActive;\n ctrl.classesTab = attrs.classesTab;\n ctrl.classesLinkActive = attrs.classesLinkActive;\n ctrl.classesLink = attrs.classesLink;\n ctrl.allowHideAll = attrs.allowHideAll != null && attrs.allowHideAll === 'true' ? true : false;\n ctrl.isToggle = attrs.isToggle != null && attrs.isToggle === 'true' ? true : false;\n tabsService.addInStorage(ctrl, attrs.id);\n element.on('$destroy', function () {\n urlHelper.setLocationQueryParams('tab', null);\n });\n };\n }\n };\n}\n\n;\n\nfunction tabHeaderDirective() {\n return {\n require: ['tabHeader', '^tabs'],\n restrict: 'A',\n scope: true,\n controller: 'TabHeaderCtrl',\n controllerAs: 'tabHeader',\n bindToController: true,\n link: function link(scope, element, attrs, ctrls) {\n ctrls[0].id = attrs.id;\n ctrls[1].addHeader(ctrls[0]);\n ctrls[0].headerTab = attrs.tabHeader;\n }\n };\n}\n\n;\n\nfunction tabContentDirective() {\n return {\n require: ['tabContent', '^tabs'],\n restrict: 'A',\n scope: true,\n controller: 'TabContentCtrl',\n controllerAs: 'tabContent',\n bindToController: true,\n link: function link(scope, element, attrs, ctrls) {\n ctrls[0].isRender = element.html().replace(//gi, '').trim().length > 0;\n ctrls[0].headerId = attrs.tabContent;\n ctrls[1].addContent(ctrls[0]);\n }\n };\n}\n\n;\n/* @ngInject */\n\nfunction tabsGotoDirective($window, tabsService) {\n return {\n restrict: 'A',\n link: function link(scope, element, attrs, ctrl) {\n element.on('click', function (event) {\n event.stopPropagation();\n event.preventDefault();\n var tab = document.getElementById(attrs.tabsGoto);\n\n if (tab != null) {\n tabsService.change(attrs.tabsGoto);\n tab.scrollIntoView();\n scope.$apply();\n }\n });\n }\n };\n}\n\n;\nexport { tabsDirective, tabHeaderDirective, tabContentDirective, tabsGotoDirective };","/* @ngInject */\nfunction tabsService() {\n var service = this,\n countInStorage = -1,\n storage = {};\n\n service.addInStorage = function (tabs, id) {\n storage[id || (countInStorage += +1)] = tabs;\n };\n\n service.change = function (id) {\n var data = service.findTabByid(id);\n\n if (data != null) {\n data.tabs.change(data.pane);\n }\n };\n\n service.findTabByid = function (id) {\n var tabs, pane;\n\n for (var key in storage) {\n if (pane != null) {\n break;\n }\n\n tabs = storage[key];\n\n if (storage.hasOwnProperty(key)) {\n pane = tabs.panes[id];\n break;\n }\n }\n\n return pane != null ? {\n tabs: tabs,\n pane: pane\n } : null;\n };\n}\n\n;\nexport default tabsService;","import './styles/tabs.scss';\nimport tabsService from './services/tabsService.js';\nimport { tabsDirective, tabHeaderDirective, tabContentDirective, tabsGotoDirective } from './directives/tabsDirectives.js';\nimport TabsCtrl from './controllers/tabsController.js';\nimport TabHeaderCtrl from './controllers/tabHeaderController.js';\nimport TabContentCtrl from './controllers/tabContentController.js';\nvar moduleName = 'tabs';\nangular.module('tabs', []).service('tabsService', tabsService).controller('TabsCtrl', TabsCtrl).controller('TabHeaderCtrl', TabHeaderCtrl).controller('TabContentCtrl', TabContentCtrl).directive('tabs', tabsDirective).directive('tabHeader', tabHeaderDirective).directive('tabContent', tabContentDirective).directive('tabsGoto', tabsGotoDirective);\nexport default moduleName;",";\n\n(function (ng) {\n 'use strict';\n\n var urlHelperService = function urlHelperService($window, urlHelperConfig) {\n var service = this,\n tagBaseHref = document.getElementsByTagName('base')[0].getAttribute('href'),\n regexDomain = new RegExp('^(?:[a-z]+:)?//', 'i');\n\n service.getUrlParam = function (paramName, toLower) {\n paramName = toLower !== false ? paramName.toLowerCase() : paramName;\n var query = toLower !== false ? $window.location.search.substring(1).toLowerCase() : $window.location.search.substring(1);\n var vars = query.split(\"&\");\n\n for (var i = 0; i < vars.length; i++) {\n var pair = vars[i].split(\"=\");\n\n if (pair[0] == paramName) {\n return pair[1];\n }\n }\n\n return null;\n };\n\n service.getUrlParamByName = function (name) {\n var url = $window.location.href.toLowerCase();\n name = name.toLowerCase().replace(/[\\[\\]]/g, \"\\\\$&\");\n var regex = new RegExp(\"[?&]\" + name + \"(=([^&#]*)|&|#|$)\"),\n results = regex.exec(url);\n if (!results) return null;\n if (!results[2]) return '';\n return decodeURIComponent(results[2].replace(/\\+/g, \" \"));\n };\n\n service.getUrlParamDictionaryByNameFunc = function (fn, paramsAsObject) {\n if (!paramsAsObject) return;\n var result = [];\n var paramsName = Object.keys(paramsAsObject);\n\n for (var i = 0; i < paramsName.length; i++) {\n if (fn(paramsName[i]) === true) {\n result.push({\n name: paramsName[i],\n value: paramsAsObject[paramsName[i]]\n });\n }\n }\n\n return result;\n };\n\n service.getUrlParamsAsObject = function (string) {\n var seachParams = new URLSearchParams(string);\n var obj = {};\n seachParams.forEach(function (key, value) {\n obj[value] = key;\n });\n return obj;\n };\n\n service.getBaseHref = function () {\n return tagBaseHref;\n };\n\n service.hasDomain = function (url) {\n return regexDomain.test(url);\n };\n\n service.getAbsUrl = function (url, excludeAdmin) {\n var base = service.getBaseHref(),\n basePrepare;\n\n if (excludeAdmin != null && excludeAdmin === true || urlHelperConfig.isAdmin === false) {\n basePrepare = base.replace(urlHelperConfig.adminPath, '');\n } else {\n basePrepare = base;\n }\n\n if (service.hasDomain(url) === false) {\n //убераем впереди слеш\n if (url.charAt(0) === '/') {\n url = url.substring(1);\n }\n\n url = basePrepare + url;\n }\n\n return url;\n };\n\n service.getUrl = function (url, excludeAdmin) {\n var base = service.getBaseHref(),\n basePrepare = base.replace(/.*\\/\\/[^\\/]*/, '');\n\n if (excludeAdmin != null && excludeAdmin === true || urlHelperConfig.isAdmin === false) {\n basePrepare = basePrepare.replace(urlHelperConfig.adminPath, '');\n }\n\n if (service.hasDomain(url) === false) {\n if (url.charAt(0) === '/') {\n url = url.substring(1);\n }\n\n url = basePrepare + url;\n }\n\n return url;\n };\n\n service.paramsToString = function (object) {\n //var result = \"\";\n var result = [];\n\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n //result += key + \"=\" + object[key] + \"&\";\n result.push(key + \"=\" + object[key]);\n }\n }\n\n return result.join(\"&\");\n };\n\n service.updateQueryStringParameter = function (uri, key, value) {\n var _uri = new URL(uri);\n\n var seachParams = new URLSearchParams(_uri.search);\n\n if (value == null) {\n seachParams.delete(key);\n } else if (seachParams.has(key)) {\n seachParams.set(key, value);\n } else {\n seachParams.append(key, value);\n }\n\n return _uri.href.split('?')[0] + '?' + seachParams.toString();\n };\n\n service.setLocationQueryParams = function (key, value, replace) {\n var url = service.updateQueryStringParameter($window.location.href, key, value);\n history[replace ? 'replaceState' : 'pushState']({\n url: url\n }, '', url);\n };\n\n service.getHashFromString = function (string, withHash) {\n var hash = string.split('#')[1];\n return withHash ? '#' + hash : hash;\n };\n };\n\n urlHelperService.$inject = ['$window', 'urlHelperConfig'];\n angular.module('urlHelper', []).service('urlHelper', urlHelperService).constant('urlHelperConfig', {\n isAdmin: false,\n adminPath: /adminv2\\/|adminv3\\//g\n });\n})(window.angular);","import './urlHelperService.js';","ZoomerCtrl.$inject = [\"$element\", \"$q\", \"$window\"];\n\n/* @ngInject */\nfunction ZoomerCtrl($element, $q, $window) {\n var ctrl = this;\n ctrl.isShowZoom = false;\n ctrl.isProcessing = false;\n ctrl.zoomPos = {\n left: 0,\n top: 0\n };\n ctrl.zoomSizes = {\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n originalWidth: 0,\n originalHeight: 0\n };\n ctrl.zoomerSizes = {\n top: 0,\n left: 0,\n width: 0,\n height: 0\n };\n ctrl.lensSizes = {\n top: 0,\n left: 0,\n width: 0,\n height: 0\n };\n\n ctrl.getSizePreview = function () {\n return {\n left: $element[0].offsetLeft,\n top: $element[0].offsetTop,\n width: $element[0].offsetWidth,\n height: $element[0].offsetHeight\n };\n };\n\n ctrl.getSizeOriginal = function (url) {\n return ctrl.getImage(url).then(function (image) {\n return {\n width: image.naturalWidth,\n height: image.naturalHeight\n };\n });\n };\n\n ctrl.getImage = function (url) {\n ctrl.isProcessing = true;\n var defered = $q.defer(),\n img = new Image();\n img.src = url;\n\n if (img.complete == true || typeof img.naturalWidth !== \"undefined\" && img.naturalWidth > 0) {\n defered.resolve(img);\n } else {\n img.onload = function (e) {\n defered.resolve(img);\n };\n }\n\n return defered.promise.then(function (response) {\n ctrl.isProcessing = false;\n return response;\n });\n };\n\n ctrl.active = function (event) {\n event.preventDefault();\n event.stopPropagation();\n ctrl.getSizeOriginal(ctrl.originalPath).then(function (imageOriginalSize) {\n var previewSize = ctrl.getSizePreview();\n ctrl.zoomerSizes.left = previewSize.left;\n ctrl.zoomerSizes.top = previewSize.top;\n ctrl.zoomerSizes.width = previewSize.width;\n ctrl.zoomerSizes.height = previewSize.height;\n\n if (ctrl.type == \"inner\") {\n ctrl.zoomSizes.top = previewSize.top;\n ctrl.zoomSizes.left = previewSize.left;\n ctrl.zoomSizes.height = previewSize.height;\n ctrl.zoomSizes.width = previewSize.width;\n } else {\n switch (ctrl.type) {\n case 'right':\n ctrl.zoomSizes.top = previewSize.top;\n ctrl.zoomSizes.left = previewSize.left + previewSize.width;\n break;\n\n case 'left':\n ctrl.zoomSizes.top = previewSize.top;\n ctrl.zoomSizes.left = previewSize.left - previewSize.width;\n break;\n\n default:\n ctrl.zoomSizes.top = previewSize.top;\n ctrl.zoomSizes.left = previewSize.left + previewSize.width;\n }\n\n ctrl.zoomSizes.width = ctrl.zoomWidth < imageOriginalSize.width ? ctrl.zoomWidth : imageOriginalSize.width;\n ctrl.zoomSizes.height = ctrl.zoomHeight < imageOriginalSize.height ? ctrl.zoomHeight : imageOriginalSize.height;\n }\n\n ctrl.zoomSizes.originalHeight = imageOriginalSize.height;\n ctrl.zoomSizes.originalWidth = imageOriginalSize.width;\n ctrl.isShowZoom = true;\n });\n };\n\n ctrl.update = function (event) {\n event.preventDefault();\n event.stopPropagation();\n var rect, pointX, pointY;\n rect = $element[0].getBoundingClientRect();\n pointX = event.pageX - (rect.left + $window.pageXOffset);\n pointY = event.pageY - (rect.top + $window.pageYOffset);\n\n if (ctrl.isShowZoom == true) {\n var scaleOriginal = ctrl.zoomSizes.originalWidth / ctrl.zoomerSizes.width,\n scalePreview = ctrl.zoomerSizes.width / ctrl.zoomSizes.originalWidth;\n ctrl.lensSizes.width = ctrl.zoomSizes.width * scalePreview;\n ctrl.lensSizes.height = ctrl.zoomSizes.height * scalePreview;\n var lensLeft = pointX - ctrl.lensSizes.width / 2,\n lensTop = pointY - ctrl.lensSizes.height / 2;\n var lensLimit = {\n left: 0,\n top: 0,\n right: ctrl.zoomerSizes.width - ctrl.lensSizes.width,\n bottom: ctrl.zoomerSizes.height - ctrl.lensSizes.height\n };\n\n if (lensTop < lensLimit.top) {\n ctrl.lensSizes.top = 0;\n } else if (lensTop > lensLimit.bottom) {\n ctrl.lensSizes.top = lensLimit.bottom;\n } else {\n ctrl.lensSizes.top = lensTop;\n }\n\n if (lensLeft < lensLimit.left) {\n ctrl.lensSizes.left = 0;\n } else if (lensLeft > lensLimit.right) {\n ctrl.lensSizes.left = lensLimit.right;\n } else {\n ctrl.lensSizes.left = lensLeft;\n }\n\n var zoomImageLeft = (ctrl.lensSizes.left + ctrl.lensSizes.width) * scaleOriginal,\n zoomImageTop = (ctrl.lensSizes.top + ctrl.lensSizes.height) * scaleOriginal;\n\n if (zoomImageLeft >= ctrl.zoomSizes.width) {\n ctrl.zoomPos.left = -(zoomImageLeft - ctrl.zoomSizes.width);\n }\n\n if (zoomImageTop >= ctrl.zoomSizes.height) {\n ctrl.zoomPos.top = -(zoomImageTop - ctrl.zoomSizes.height);\n }\n }\n };\n\n ctrl.deactive = function () {\n ctrl.isShowZoom = false;\n };\n\n ctrl.lensMove = ctrl.update;\n\n ctrl.getZoomerClass = function () {\n var obj = {};\n obj['zoomer-' + ctrl.type] = true;\n obj['zoomer-processing'] = ctrl.isProcessing;\n return obj;\n };\n}\n\n;\nexport default ZoomerCtrl;","zoomerDirective.$inject = [\"$rootScope\", \"$window\", \"$compile\", \"zoomerConfig\"];\nvar isTouchDevice = ('ontouchstart' in document.documentElement);\n/* @ngInject */\n\nfunction zoomerDirective($rootScope, $window, $compile, zoomerConfig) {\n return {\n restrict: 'A',\n scope: {\n previewPath: '=',\n originalPath: '=',\n type: '@',\n zoomWidth: '=?',\n zoomHeight: '=?',\n zoomerTitle: '=?'\n },\n replace: true,\n transclude: true,\n template: '',\n controller: 'ZoomerCtrl',\n controllerAs: 'zoomer',\n bindToController: true,\n link: function link(scope, element, attrs, ctrl) {\n var init = function init() {\n if (angular.isUndefined(ctrl.zoomWidth)) {\n ctrl.zoomWidth = zoomerConfig.zoomWidth;\n }\n\n if (angular.isUndefined(ctrl.zoomHeight)) {\n ctrl.zoomHeight = zoomerConfig.zoomHeight;\n }\n\n if (angular.isUndefined(ctrl.type)) {\n ctrl.type = zoomerConfig.type;\n }\n\n var scopeWindow = scope.$new(),\n zoomerWindow = angular.element('
    ');\n scopeWindow.parentScope = ctrl;\n element.after(zoomerWindow);\n $compile(zoomerWindow)(scopeWindow);\n ['touchstart', 'mouseenter'].forEach(function (eventName) {\n element[0].addEventListener(eventName, function (event) {\n ctrl.active(event);\n scope.$apply();\n });\n });\n ['touchmove', 'mousemove'].forEach(function (eventName) {\n element[0].addEventListener(eventName, function (event) {\n ctrl.update(event);\n scope.$apply();\n });\n });\n ['touchend', 'mouseleave'].forEach(function (eventName) {\n element[0].addEventListener(eventName, function (event) {\n ctrl.deactive(event);\n scope.$apply();\n });\n });\n\n if (ctrl.type !== 'inner') {\n var scopeLens = $rootScope.$new(),\n zoomerLens = angular.element('
    ');\n scopeLens.parentScope = ctrl;\n element.append(zoomerLens);\n $compile(zoomerLens)(scopeLens);\n }\n };\n\n if (document.readyState != \"complete\") {\n $window.addEventListener('load', function load() {\n $window.removeEventListener('load', load);\n init();\n });\n } else {\n init();\n }\n }\n };\n}\n\n;\n/* @ngInject */\n\nfunction zoomerLensDirective() {\n return {\n //require: '^zoomer',\n restrict: 'A',\n replace: true,\n scope: true,\n template: '
    ',\n link: function link(scope, element, attrs, ctrl) {//var zoomerCtrl = ctrl;\n //element[0].addEventListener('touchmove', function (event) {\n // zoomerCtrl.update(event);\n // scope.$apply();\n //});\n }\n };\n}\n\n;\n\nfunction zoomerWindowDirective() {\n return {\n restrict: 'A',\n replace: true,\n scope: true,\n templateUrl: '/scripts/_common/zoomer/templates/zoomerWindow.html',\n link: function link(scope, element, attrm, ctrls) {\n //var zoomerCtrl = ctrls[0];\n //element[0].addEventListener('mouseenter', zoomerCtrl.active);\n //element[0].addEventListener('mouseleave', zoomerCtrl.deactive);\n //element[0].addEventListener('mousemove', zoomerCtrl.update);\n if (scope.$parent.parentScope.type === 'inner') {\n ['touchstart', 'mouseenter'].forEach(function (eventName) {\n element[0].addEventListener(eventName, function (event) {\n scope.$parent.parentScope.active(event);\n scope.$apply();\n });\n });\n }\n\n ['touchmove', 'mousemove'].forEach(function (eventName) {\n element[0].addEventListener(eventName, function (event) {\n scope.$parent.parentScope.update(event);\n scope.$apply();\n });\n });\n ['touchend', 'mouseleave'].forEach(function (eventName) {\n element[0].addEventListener(eventName, function (event) {\n scope.$parent.parentScope.deactive(event);\n scope.$apply();\n });\n });\n }\n };\n}\n\n;\nexport { zoomerDirective, zoomerLensDirective, zoomerWindowDirective };","import './styles/zoomer.scss';\nimport ZoomerCtrl from './controllers/zoomerController.js';\nimport { zoomerDirective, zoomerLensDirective, zoomerWindowDirective } from './directives/zoomerDirectives.js';\nvar moduleName = 'zoomer';\nangular.module(moduleName, []).controller('ZoomerCtrl', ZoomerCtrl).directive('zoomer', zoomerDirective).directive('zoomerLens', zoomerLensDirective).directive('zoomerWindow', zoomerWindowDirective).constant('zoomerConfig', {\n zoomWidth: 350,\n zoomHeight: 350,\n type: 'right' // right/inner\n\n});\nexport default moduleName;","import './styles/buyOneClick.scss';\nimport BuyOneClickTriggerCtrl from './controllers/buyOneClickTriggerController.js';\nimport BuyOneClickFormCtrl from './controllers/buyOneClickFormController.js';\nimport { buyOneClickFormDirective, buyOneClickTriggerDirective } from './directives/buyOneClickDirectives.js';\nimport buyOneClickService from './services/buyOneClickService.js';\nvar moduleName = 'buyOneClick';\nangular.module(moduleName, []).service('buyOneClickService', buyOneClickService).directive('buyOneClickForm', buyOneClickFormDirective).directive('buyOneClickTrigger', buyOneClickTriggerDirective).controller('BuyOneClickTriggerCtrl', BuyOneClickTriggerCtrl).controller('BuyOneClickFormCtrl', BuyOneClickFormCtrl);\nexport default moduleName;","BuyOneClickFormCtrl.$inject = [\"$sce\", \"$timeout\", \"$window\", \"buyOneClickService\", \"toaster\", \"$scope\", \"$http\"];\n\n/* @ngInject */\nfunction BuyOneClickFormCtrl($sce, $timeout, $window, buyOneClickService, toaster, $scope, $http) {\n var ctrl = this;\n\n ctrl.$onInit = function () {\n ctrl.success = false;\n ctrl.process = false;\n ctrl.showRedirectButton = false; //ctrl.compactMode = ctrl.compactMode === 'True' ? true : false;\n\n buyOneClickService.getFieldsOptions().then(function (fields) {\n ctrl.fields = angular.extend(fields, ctrl.fieldsOptions);\n ctrl.fields.BuyInOneClickFirstText = $sce.trustAsHtml(ctrl.fields.BuyInOneClickFirstText);\n ctrl.fields.BuyInOneClickFinalText = $sce.trustAsHtml(ctrl.fields.BuyInOneClickFinalText);\n ctrl.fullNameListMaxHeight = 50 + (50 * (ctrl.fields.IsShowBuyInOneClickEmail + ctrl.fields.IsShowBuyInOneClickPhone + ctrl.fields.IsShowBuyInOneClickComment * 2 + ctrl.fields.IsShowUserAgreementText) || 50);\n\n if (ctrl.fields.EnableCaptchaInBuyInOneClick) {\n ctrl.initCaptcha(\"buyOneClickForm.captchaCode\").then(function (data) {\n ctrl.captchaHtml = data;\n });\n }\n });\n buyOneClickService.getCustomerInfo().then(function (data) {\n ctrl.name = data.name;\n ctrl.email = data.email;\n ctrl.phone = data.phone;\n });\n\n if (ctrl.formInit != null) {\n ctrl.formInit({\n form: ctrl\n });\n }\n };\n\n ctrl.reset = function () {\n ctrl.name = '';\n ctrl.email = '';\n ctrl.phone = '';\n ctrl.comment = '';\n ctrl.success = false;\n ctrl.showRedirectButton = false;\n ctrl.result = null;\n ctrl.form.$setPristine();\n };\n\n ctrl.send = function () {\n var isValid = ctrl.buyOneClickValid();\n\n if (isValid === true || isValid == null) {\n ctrl.process = true;\n var captchaExist = typeof CaptchaSourceBuyInOneClick != \"undefined\" && CaptchaSourceBuyInOneClick != null;\n var captchaInstanceId = captchaExist ? CaptchaSourceBuyInOneClick.InstanceId : null;\n buyOneClickService.checkout(ctrl.page, ctrl.orderType, ctrl.offerId, ctrl.productId, ctrl.amount, ctrl.attributesXml, ctrl.name, ctrl.email, ctrl.phone, ctrl.comment, ctrl.captchaCode, captchaInstanceId).then(function (result) {\n if (result.error != null && result.error.length > 0) {\n toaster.pop('error', null, result.error);\n\n if (captchaExist) {\n CaptchaSourceBuyInOneClick.ReloadImage();\n }\n } else {\n ctrl.result = result;\n ctrl.success = true;\n ctrl.successFn({\n result: result\n });\n\n if (ctrl.autoReset != null) {\n $timeout(ctrl.reset, ctrl.autoReset);\n }\n }\n\n ctrl.process = false;\n });\n }\n };\n\n ctrl.initCaptcha = function (ngModel) {\n return $http.post('/commonExt/getCaptchaHtml', {\n ngModel: ngModel,\n captchaId: 'CaptchaSourceBuyInOneClick'\n }).then(function (response) {\n return $sce.trustAsHtml(response.data);\n });\n };\n}\n\n;\nexport default BuyOneClickFormCtrl;","BuyOneClickTriggerCtrl.$inject = [\"$window\", \"toaster\", \"buyOneClickService\"];\n\n/* @ngInject */\nfunction BuyOneClickTriggerCtrl($window, toaster, buyOneClickService) {\n var ctrl = this;\n\n ctrl.formInit = function (form) {\n ctrl.form = form;\n };\n\n ctrl.modalCallbackClose = function (modalScope) {\n if (ctrl.form.result != null && ctrl.form.showRedirectButton === true) {\n window.location = ctrl.form.result.url;\n }\n\n if (ctrl.form.success === true) {\n ctrl.form.reset();\n }\n };\n\n ctrl.successFn = function (result) {\n if (result.url != null && result.doGo === true) {\n ctrl.form.success = false;\n window.location = result.url;\n } else {\n if (result.url != null) {\n ctrl.form.showRedirectButton = true;\n } else {\n buyOneClickService.modalFooterShow(ctrl.modalId, false);\n }\n }\n };\n}\n\n;\nexport default BuyOneClickTriggerCtrl;","buyOneClickTriggerDirective.$inject = [\"buyOneClickService\"];\n\n/* @ngInject */\nfunction buyOneClickTriggerDirective(buyOneClickService) {\n return {\n restrict: 'A',\n scope: true,\n controller: 'BuyOneClickTriggerCtrl',\n controllerAs: 'buyOneClickTrigger',\n bindToController: true,\n link: function link(scope, element, attrs, ctrl) {\n element.on('click', function (event) {\n event.preventDefault();\n var modalId = element[0].getAttribute('data-buy-one-click-modal');\n ctrl.modalId = modalId != null ? modalId : 'modalBuyOneClick';\n scope.$apply(function () {\n buyOneClickService.showDialog(ctrl.modalId);\n });\n });\n }\n };\n}\n\nfunction buyOneClickFormDirective() {\n return {\n restrict: 'A',\n scope: {\n buttonText: '@',\n page: '@',\n orderType: '@',\n offerId: '=?',\n productId: '=?',\n amount: '=?',\n attributesXml: '=?',\n formInit: '&',\n successFn: '&',\n fieldsOptions: '=?',\n autoReset: '=?',\n buyOneClickValid: '&',\n compactMode: '@',\n agreementDefaultChecked: ' 0) {\n for (var i = 0, len = ctrl.colors.length; i < len; i++) {\n if (ctrl.colors[i].Selected === true) {\n ctrl.colorSelected.push(ctrl.colors[i]);\n }\n }\n }\n\n ctrl.colorSelectedNamesList = ctrl.colorSelected.join(',');\n } else {\n if (ctrl.startSelectedColors != null && ctrl.startSelectedColors.length > 0) {\n for (var s = 0, lenS = ctrl.startSelectedColors.length; s < lenS; s++) {\n for (var c = 0, lenC = ctrl.colors.length; c < lenC; c++) {\n if (ctrl.colors[c].ColorId === ctrl.startSelectedColors[s]) {\n if (ctrl.colors[c].Main === 1) {\n findedStartColorByIdAndMain = ctrl.colors[c];\n stopLoop = true;\n } else if (findedStartColorById == null) {\n findedStartColorById = ctrl.colors[c];\n }\n\n isFindedByStart = true;\n }\n }\n\n if (stopLoop === true) {\n stopLoop = false;\n break;\n }\n }\n }\n\n if (isFindedByStart === false) {\n for (var m = 0, l = ctrl.colors.length; m < l; m++) {\n if (ctrl.colors[m].Main == true) {\n ctrl.colorSelected = ctrl.colors[m];\n break;\n }\n }\n\n if (ctrl.colorSelected == null) {\n ctrl.colorSelected = ctrl.colors[0];\n }\n } else {\n ctrl.colorSelected = findedStartColorByIdAndMain || findedStartColorById;\n }\n }\n\n if (ctrl.initColors != null) {\n ctrl.initColors({\n colorsViewer: ctrl\n });\n }\n };\n\n ctrl.$postLink = function () {\n if (ctrl.carousel != null) {\n var colorSelectedFirst = ctrl.multiselect ? ctrl.colorSelected[0] : ctrl.colorSelected;\n var colorSelectedFirstIndex = ctrl.colors.indexOf(colorSelectedFirst);\n ctrl.carousel.load = true;\n ctrl.carousel.whenCarouselInit().then(function (carousel) {\n carousel.carouselNative.setItemSelect(colorSelectedFirstIndex);\n carousel.carouselNative.goto(colorSelectedFirstIndex, false);\n });\n }\n };\n\n ctrl.getImagePath = function (photoName) {\n return photoName.indexOf('://') != -1 ? photoName : 'pictures/color/' + ctrl.imageType.toLowerCase() + '/' + photoName;\n };\n\n ctrl.selectColor = function (event, color) {\n var indexInSelectedArray;\n\n if (ctrl.multiselect === true) {\n indexInSelectedArray = ctrl.colorSelected.indexOf(color);\n\n if (indexInSelectedArray > -1) {\n ctrl.colorSelected.splice(indexInSelectedArray, 1); //свойство используется в фильтрах\n\n color.Selected = false;\n } else {\n ctrl.colorSelected.push(color); //свойство используется в фильтрах\n\n color.Selected = true;\n }\n\n ctrl.colorSelectedNamesList = ctrl.colorSelected.join(',');\n } else {\n ctrl.colorSelected = color;\n }\n\n ctrl.dirty = true;\n ctrl.changeColor({\n event: event,\n color: color\n });\n };\n\n ctrl.selectColorById = function (colorId) {\n var color = ctrl.colors.filter(function (x) {\n return x.ColorId == colorId;\n });\n\n if (color != null && color.length > 0) {\n ctrl.selectColor(null, color[0]);\n }\n };\n\n ctrl.getDirtyState = function () {\n return ctrl.dirty;\n };\n}\n\n;\nexport default ColorsViewerCtrl;","function colorsViewerDirective() {\n return {\n require: {\n carousel: '?^carousel'\n },\n restrict: 'A',\n replace: true,\n templateUrl: '/scripts/_partials/colors-viewer/templates/colors.html',\n controller: 'ColorsViewerCtrl',\n controllerAs: 'colorsViewer',\n bindToController: true,\n scope: {\n colors: '=',\n colorSelected: '=?',\n startSelectedColors: '= 0; i--) {\n val = null;\n item = customOptions[i];\n\n if (item.SelectedOptions != null) {\n //DropDownList = 0,\n //RadioButton = 1,\n //CheckBox = 2,\n //TextBoxSingleLine = 3,\n //TextBoxMultiLine = 4\n switch (item.InputType) {\n case 0:\n case 1:\n val = item.SelectedOptions.ID;\n break;\n\n case 2:\n val = !item.SelectedOptions ? '0' : '1'; //item.SelectedOptions может содержать объект или true\n\n break;\n\n case 3:\n case 4:\n val = item.SelectedOptions.OptionText;\n break;\n\n default:\n throw Error('Not found InputType for custom options: ' + item.InputType);\n break;\n }\n\n if (val != null) {\n arrayTemp.push(i + '_' + val);\n }\n }\n }\n\n return arrayTemp.join(';');\n };\n}\n\n;\nexport default customOptionsService;","export default function PhotoViewListCtrl() {\n var ctrl = this;\n\n ctrl.updateActiveElements = function () {\n ctrl.activeNavIndex = 0;\n ctrl.activeItemIndex = 0;\n };\n}","PhotoViewList.$inject = [\"$parse\"];\n\n/* @ngInject */\nfunction PhotoViewList($parse) {\n return {\n scope: true,\n controller: 'PhotoViewListCtrl',\n controllerAs: 'photoViewList',\n bindToController: true,\n link: function link(scope, element, attrs, ctrl) {\n element[0].classList.add('photo-view-list');\n var onHoverNavItem;\n\n if (attrs.photoViewListOnHoverNavItem != null) {\n onHoverNavItem = $parse(attrs.photoViewListOnHoverNavItem);\n }\n\n ctrl.onHoverNavItem = function () {\n if (onHoverNavItem != null) {\n onHoverNavItem(scope);\n }\n };\n }\n };\n}\n\nfunction PhotoViewListItem() {\n return {\n scope: true,\n require: ['^photoViewList'],\n bindToController: true,\n link: function link(scope, element, attrs, ctrls) {\n var photoViewListCtrl = ctrls[0];\n element[0].classList.add('photo-view-list__item');\n\n if (element[0].parentNode != null && !element[0].parentNode.classList.contains('photo-view-list__item-wrap')) {\n element[0].parentNode.classList.add('photo-view-list__item-wrap');\n }\n\n photoViewListCtrl.activeItemIndex = 0;\n photoViewListCtrl.isActiveElement = true;\n }\n };\n}\n\nfunction PhotoViewListNav() {\n return {\n scope: true,\n require: ['^photoViewList'],\n bindToController: true,\n link: function link(scope, element, attrs, ctrls) {\n var photoViewListCtrl = ctrls[0];\n element[0].classList.add('photo-view-list__nav');\n photoViewListCtrl.activeNavIndex = 0;\n photoViewListCtrl.isActiveElementNav = true;\n element[0].addEventListener('mouseenter', function (e) {\n var target = e.target;\n var indexActiveNav = target.getAttribute('data-nav-index');\n photoViewListCtrl.activeNavIndex = parseFloat(indexActiveNav);\n photoViewListCtrl.activeItemIndex = parseFloat(indexActiveNav);\n photoViewListCtrl.onHoverNavItem();\n scope.$apply();\n }, true);\n }\n };\n}\n\nexport { PhotoViewList, PhotoViewListItem, PhotoViewListNav };","import PhotoViewListCtrl from './photo-view-list.ctrl.js';\nimport { PhotoViewList, PhotoViewListItem, PhotoViewListNav } from './photo-view-list.directive.js';\nimport './photo-view-list.scss';\nvar moduleName = \"photoViewList\";\nangular.module(moduleName, []).directive(\"photoViewList\", PhotoViewList).directive(\"photoViewListItem\", PhotoViewListItem).directive(\"photoViewListNav\", PhotoViewListNav).controller(\"PhotoViewListCtrl\", PhotoViewListCtrl);\nexport default moduleName;","function ProductViewCarouselPhotosCtrl() {\n var ctrl = this;\n\n ctrl.carouselInit = function (carousel) {\n ctrl.carousel = carousel;\n };\n}\n\n;\nexport default ProductViewCarouselPhotosCtrl;","ProductViewChangeModeCtrl.$inject = [\"productViewService\", \"viewList\"];\n\n/* @ngInject */\nfunction ProductViewChangeModeCtrl(productViewService, viewList) {\n var ctrl = this;\n\n ctrl.setView = function (name, view, isMobile) {\n ctrl.current = view;\n productViewService.setView(name, view, ctrl.currentViewList, isMobile);\n };\n\n ctrl.toggle = function (name) {\n var index = ctrl.currentViewList.indexOf(ctrl.current);\n var nextViewIndex = index !== -1 ? index + 1 : 0;\n ctrl.setView(name, ctrl.currentViewList[nextViewIndex < ctrl.currentViewList.length ? nextViewIndex : 0], ctrl.currentViewList, ctrl.isMobile);\n };\n}\n\n;\nexport default ProductViewChangeModeCtrl;","ProductViewItemCtrl.$inject = [\"$q\", \"$timeout\", \"productViewService\", \"$translate\", \"$scope\", \"$parse\", \"urlHelper\"];\n\n/*@ngInject*/\nfunction ProductViewItemCtrl($q, $timeout, productViewService, $translate, $scope, $parse, urlHelper) {\n var ctrl = this,\n controls = {},\n needCarouselUpdate = false,\n requestGetPhotosInPending = false,\n isPhotosStorageMutation = false,\n photosStorage;\n ctrl.photosVisible = false;\n ctrl.photos = [];\n ctrl.picture = {};\n ctrl.promisesGetPhotos = [];\n ctrl.colorSelected = null;\n\n ctrl.getOffersProduct = function (productId) {\n return productViewService.getOfferId(productId).then(function (result) {\n if (result != null) {\n return result.Offers;\n }\n });\n };\n\n ctrl.getPhotos = function (productId) {\n var defer = $q.defer(),\n promise;\n\n if (requestGetPhotosInPending === false && (photosStorage == null || needCarouselUpdate === true)) {\n requestGetPhotosInPending = true;\n promise = productViewService.getPhotos(ctrl.productId || productId).then(function (photos) {\n isPhotosStorageMutation = true;\n\n for (var i = 0, len = ctrl.promisesGetPhotos.length; i < len; i++) {\n ctrl.promisesGetPhotos[i].resolve(photos);\n }\n\n ctrl.promisesGetPhotos.length = 0;\n requestGetPhotosInPending = false;\n return photosStorage = photos;\n });\n } else if (requestGetPhotosInPending === true) {\n promise = defer.promise;\n ctrl.promisesGetPhotos.push(defer);\n } else {\n promise = defer.promise;\n defer.resolve(photosStorage);\n }\n\n ctrl.gotPhotos = true;\n return promise;\n };\n\n ctrl.numberals = function (num) {\n if (num <= 0) return ctrl.textNumberals = num + ' ' + $translate.instant('Js.ProductView.Photos0');\n num = num % 100;\n var nums = num % 10;\n if (num > 10 && num < 20) return ctrl.textNumberals = num + ' ' + $translate.instant('Js.ProductView.Photos5');\n if (nums > 1 && nums < 5) return ctrl.textNumberals = num + ' ' + $translate.instant('Js.ProductView.Photos2');\n return nums === 1 ? ctrl.textNumberals = num + ' ' + $translate.instant('Js.ProductView.Photos1') : ctrl.textNumberals = num + ' ' + $translate.instant('Js.ProductView.Photos5');\n };\n\n ctrl.fill = function (photos) {\n if (ctrl.getControl('colorsViewer') != null) {\n ctrl.photos = ctrl.filterPhotos(photosStorage == null && isPhotosStorageMutation === false ? ctrl.getPhotos() : photos, ctrl.getControl('colorsViewer').colorSelected.ColorId, ctrl.onlyPhotoWithColor);\n } else {\n ctrl.photos = photos;\n }\n\n if (ctrl.photos.length === 0) {\n ctrl.photos.length = 0;\n ctrl.photos.push.apply(ctrl.photos, ctrl.getMainPhoto(photos));\n }\n\n if (ctrl.maxPhotoView != null) {\n ctrl.photos = ctrl.photos.slice(0, ctrl.maxPhotoView);\n }\n\n ctrl.numberals(ctrl.photos.length);\n return photos;\n };\n\n ctrl.process = function (productId) {\n return ctrl.getPhotos(productId).then(function (photos) {\n ctrl.fill(photos);\n $timeout(function () {\n ctrl.carouselInit = true;\n\n if (needCarouselUpdate === true && ctrl.getControl('photosCarousel') != null && ctrl.getControl('photosCarousel').carousel != null) {\n ctrl.getControl('photosCarousel').carousel.update();\n needCarouselUpdate = false;\n }\n }, 0);\n return photos;\n });\n };\n\n ctrl.clearPhotos = function () {\n photosStorage = null;\n needCarouselUpdate = true;\n };\n\n ctrl.enter = function () {\n ctrl.photosVisible = true;\n ctrl.process();\n };\n\n ctrl.leave = function () {\n ctrl.photosVisible = false;\n ctrl.carouselInit = false;\n };\n\n ctrl.changePhoto = function (photo) {\n ctrl.picture = photo;\n };\n\n ctrl.initColors = function (colorsViewer) {\n ctrl.addControl('colorsViewer', colorsViewer);\n\n if (colorsViewer.changeStartSelectedColor != null) {\n setTimeout(function () {\n colorsViewer.selectColorById(colorsViewer.changeStartSelectedColor);\n }, 500);\n }\n };\n\n ctrl.getSelectedColorId = function () {\n var colorsViewer = ctrl.getControl('colorsViewer'),\n colorId;\n\n if (colorsViewer != null && colorsViewer.colorSelected != null && colorsViewer.getDirtyState() === true) {\n colorId = colorsViewer.colorSelected.ColorId;\n }\n\n return colorId;\n };\n\n ctrl.initColorsCarousel = function (carousel) {\n ctrl.addControl('colorsViewerCarousel', carousel);\n };\n\n ctrl.changeColor = function (color) {\n ctrl.getOffersProduct(ctrl.productId).then(function (result) {\n ctrl.productOffers = result;\n\n if (ctrl.productOffers != null && ctrl.productOffers.length > 0) {\n ctrl.selectedProductOffer = ctrl.productOffers.filter(function (offer) {\n return offer.Color.ColorId === color.ColorId;\n });\n\n if (ctrl.selectedProductOffer != null && ctrl.selectedProductOffer.length > 0) {\n var o = null;\n\n for (var i = 0; i < ctrl.selectedProductOffer.length; i++) {\n if (ctrl.selectedProductOffer[i].Amount > 0) {\n o = ctrl.selectedProductOffer[i];\n break;\n }\n }\n\n ctrl.offer = o == null ? ctrl.selectedProductOffer[0] : o;\n }\n }\n\n var defaultPhoto;\n\n if (photosStorage == null && isPhotosStorageMutation === false) {\n ctrl.getPhotos().then(function (result) {\n ctrl.photos = ctrl.filterPhotos(result, color.ColorId, ctrl.getControl('colorsViewer') != null ? ctrl.onlyPhotoWithColor : false);\n defaultPhoto = ctrl.getMainPhoto(ctrl.photos); //if (ctrl.photos.length === 0) {\n // ctrl.photos = defaultPhoto;\n //}\n //if (ctrl.maxPhotoView != null) {\n // ctrl.photos = ctrl.photos.slice(0, ctrl.maxPhotoView);\n //}\n\n ctrl.setColor(defaultPhoto);\n });\n } else {\n defaultPhoto = ctrl.getMainPhoto(photosStorage != null && photosStorage.length !== 0 ? photosStorage : ctrl.photos);\n ctrl.photos = ctrl.filterPhotos(photosStorage, color.ColorId, ctrl.getControl('colorsViewer') != null ? ctrl.onlyPhotoWithColor : false);\n ctrl.setColor(defaultPhoto);\n }\n\n if (ctrl.onChangeColor != null) {\n $parse(ctrl.onChangeColor)($scope);\n }\n\n if (ctrl.photos.length === 0) {\n ctrl.photos.length = 0;\n ctrl.photos.push.apply(ctrl.photos, defaultPhoto); //ctrl.photos = ctrl.photos.concat(defaultPhoto);\n }\n\n if (ctrl.maxPhotoView != null) {\n ctrl.photos = ctrl.photos.slice(0, ctrl.maxPhotoView);\n }\n }).catch(function (error) {\n console.error(error);\n });\n };\n\n ctrl.setColor = function (defaultPhoto) {\n ctrl.picture = ctrl.photos.length === 0 && defaultPhoto != null ? defaultPhoto[0] : ctrl.photos[0];\n ctrl.numberals(ctrl.photos.length);\n var photosCarousel = ctrl.getControl('photosCarousel');\n\n if (photosCarousel != null && photosCarousel.carousel != null) {\n $timeout(function () {\n photosCarousel.carousel.options.indexActive = 0;\n photosCarousel.carousel.update();\n });\n }\n\n if (ctrl.photoViewer != null) {\n ctrl.photoViewer.reinit();\n }\n };\n\n ctrl.addControl = function (name, scope) {\n controls[name] = scope;\n };\n\n ctrl.getControl = function (name) {\n return controls[name];\n };\n\n ctrl.filterPhotos = function (photos, colorId, onlyColorPhoto) {\n return photos.filter(function (item) {\n if (onlyColorPhoto) {\n return item.ColorID === colorId;\n }\n\n return item.ColorID === colorId || item.ColorID == null;\n });\n };\n\n ctrl.getUrl = function (url) {\n var result = url,\n colorId = ctrl.getSelectedColorId();\n\n if (colorId != null) {\n result = urlHelper.updateQueryStringParameter(result, 'color', colorId);\n }\n\n return result;\n };\n\n ctrl.addPhotoViewer = function (photoViewer) {\n ctrl.photoViewer = photoViewer;\n };\n\n ctrl.getPictureByViewMode = function (photos, defaultViewMode, lazyLoadMode) {\n var result;\n\n if (lazyLoadMode === 'Carousel' && ctrl.isCarouselImgVisible !== true || lazyLoadMode === 'Default' && ctrl.isImgVisible !== true) {\n return null;\n }\n\n if (ctrl.viewMode != null) {\n result = ctrl.getPictureBySize(ctrl.viewMode.viewName === 'single' ? 'PathMiddle' : 'PathSmall', ctrl.picture != null && Object.keys(ctrl.picture).length > 0 ? ctrl.picture : photos[0]);\n } else {\n result = ctrl.getPictureBySize(defaultViewMode === 'small' ? 'PathSmall' : 'PathMiddle', ctrl.picture != null && Object.keys(ctrl.picture).length > 0 ? ctrl.picture : photos[0]);\n }\n\n return result;\n };\n\n ctrl.lazyLoadImgInCarousel = function () {\n ctrl.isCarouselImgVisible = true;\n };\n\n ctrl.lazyLoadImg = function () {\n ctrl.isImgVisible = true;\n };\n\n ctrl.getPictureBySize = function (size, photos) {\n return photos[size];\n };\n\n ctrl.getMainPhoto = function (photos) {\n return photos.filter(function (photo) {\n return photo.Main === true;\n });\n };\n}\n\n;\nexport default ProductViewItemCtrl;","function ProductViewModeCtrl() {}\n\n;\nexport default ProductViewModeCtrl;","productViewModeDirective.$inject = [\"productViewService\", \"viewList\", \"viewPrefix\"];\nproductViewChangeModeDirective.$inject = [\"productViewService\", \"viewList\"];\nproductViewItemDirective.$inject = [\"productViewService\", \"domService\", \"windowService\", \"$parse\"];\n\n/* @ngInject */\nfunction productViewItemDirective(productViewService, domService, windowService, $parse) {\n return {\n require: ['^productViewItem'],\n restrict: 'A',\n controller: 'ProductViewItemCtrl',\n controllerAs: 'productViewItem',\n bindToController: true,\n scope: true,\n link: function link(scope, element, attrs, ctrls) {\n var productViewItemCtrl = ctrls[0],\n timerHover;\n productViewItemCtrl.productId = parseInt(attrs.productId);\n\n if (attrs.offer != null) {\n productViewItemCtrl.offer = $parse(attrs.offer)(scope);\n }\n\n if (attrs.onChangeColor != null) {\n productViewItemCtrl.onChangeColor = attrs.onChangeColor;\n }\n\n if (attrs.maxPhotoView != null) {\n productViewItemCtrl.maxPhotoView = parseFloat(attrs.maxPhotoView);\n }\n\n if (attrs.onlyPhotoWithColor != null) {\n productViewItemCtrl.onlyPhotoWithColor = attrs.onlyPhotoWithColor === 'true';\n }\n\n productViewItemCtrl.offerId = parseInt(attrs.offerId); //productViewItemCtrl.getOffersProduct(productViewItemCtrl.productId);\n\n productViewService.addCallback('setView', function (viewMode) {\n productViewItemCtrl.viewMode = viewMode;\n setTimeout(function () {\n var colorsViewerCarousel = productViewItemCtrl.getControl('colorsViewerCarousel');\n\n if (colorsViewerCarousel != null) {\n colorsViewerCarousel.update();\n }\n\n scope.$digest();\n }, 50);\n });\n element[0].addEventListener('mouseenter', function () {\n if (timerHover != null) {\n clearTimeout(timerHover);\n }\n\n timerHover = setTimeout(function () {\n productViewItemCtrl.enter();\n scope.$digest();\n }, 100);\n });\n element[0].addEventListener('mouseleave', function () {\n clearTimeout(timerHover);\n productViewItemCtrl.leave();\n scope.$digest();\n });\n element[0].addEventListener('touchstart', function () {\n productViewItemCtrl.enter();\n scope.$digest();\n }, {\n passive: true\n });\n windowService.addCallback('touchstart', function (eventObj) {\n var isClickedMe = domService.closest(eventObj.event.target, element[0]) != null;\n\n if (isClickedMe === false) {\n productViewItemCtrl.leave();\n scope.$digest();\n }\n });\n }\n };\n}\n\n;\n\nfunction productViewCarouselPhotosDirective() {\n return {\n require: ['^productViewCarouselPhotos', '^productViewItem'],\n restrict: 'A',\n scope: {\n photoHeight: '@',\n photoWidth: '@',\n changePhoto: '&'\n },\n replace: true,\n templateUrl: '/scripts/_partials/product-view/templates/photos.html',\n controller: 'ProductViewCarouselPhotosCtrl',\n controllerAs: 'photosCarousel',\n bindToController: true,\n link: function link(scope, element, attrs, ctrl) {\n var carouselPhotosCtrl = ctrl[0],\n productViewItemCtrl = ctrl[1];\n carouselPhotosCtrl.parentScope = productViewItemCtrl;\n productViewItemCtrl.addControl('photosCarousel', carouselPhotosCtrl);\n }\n };\n}\n\n;\n/* @ngInject */\n\nfunction productViewChangeModeDirective(productViewService, viewList) {\n return {\n restrict: 'A',\n scope: true,\n controller: 'ProductViewChangeModeCtrl',\n controllerAs: 'changeMode',\n bindToController: true,\n link: function link(scope, element, attrs, ctrl) {\n ctrl.name = attrs.name;\n ctrl.currentViewList = viewList[attrs.viewListName || 'desktop'];\n ctrl.isMobile = attrs.isMobile === 'true';\n ctrl.isReadyViewMode = false;\n\n if (ctrl.isMobile === true) {\n ctrl.current = productViewService.getViewFromCookie('mobile_viewmode', ctrl.currentViewList);\n } else {\n ctrl.current = attrs.viewMode;\n }\n\n ctrl.isReadyViewMode = true;\n }\n };\n}\n\n;\n/* @ngInject */\n\nfunction productViewModeDirective(productViewService, viewList, viewPrefix) {\n return {\n restrict: 'A',\n scope: true,\n controller: 'ProductViewModeCtrl',\n controllerAs: 'productViewMode',\n bindToController: true,\n link: function link(scope, element, attrs, ctrl) {\n ctrl.isMobile = attrs.isMobile === 'true';\n ctrl.currentViewList = viewList[attrs.viewListName || 'desktop'];\n ctrl.currentViewPrefix = viewPrefix[attrs.viewListName || 'desktop'];\n\n if (ctrl.isMobile === true) {\n ctrl.viewName = productViewService.getViewFromCookie('mobile_viewmode', ctrl.currentViewList);\n element[0].classList.add('products-view-' + ctrl.currentViewPrefix + ctrl.viewName);\n } else {\n ctrl.viewName = attrs.current;\n }\n\n productViewService.addCallback('setView', onChangeMode);\n\n function onChangeMode(view) {\n view.viewList.forEach(function (item) {\n element[0].classList.remove('products-view-' + ctrl.currentViewPrefix + item);\n });\n element[0].classList.add('products-view-' + ctrl.currentViewPrefix + view.viewName);\n ctrl.viewName = view.viewName;\n }\n }\n };\n}\n\n;\nexport { productViewItemDirective, productViewCarouselPhotosDirective, productViewChangeModeDirective, productViewModeDirective };","import carouselModule from '../../_common/carousel/carousel.module.js';\nimport ratingModule from '../../_common/rating/rating.module.js';\nimport quickviewModule from '../quickview/quickview.module.js';\nimport colorsViewerModule from '../colors-viewer/colorsViewer.module.js';\nimport productsCarouselModule from '../products-carousel/productsCarousel.module.js';\nimport photoViewListModule from '../../../scripts/_partials/photo-view-list/photoViewList.module.js';\nimport './styles/product-view.scss';\nimport productViewService from './services/productViewService.js';\nimport { productViewItemDirective, productViewCarouselPhotosDirective, productViewChangeModeDirective, productViewModeDirective } from './directives/productViewDirectives.js';\nimport ProductViewCarouselPhotosCtrl from './controllers/productViewCarouselPhotosController.js';\nimport ProductViewChangeModeCtrl from './controllers/productViewChangeModeController.js';\nimport ProductViewItemCtrl from './controllers/productViewItemController.js';\nimport ProductViewModeCtrl from './controllers/productViewModeController.js';\nvar moduleName = 'productView';\nangular.module(moduleName, [ratingModule, quickviewModule, colorsViewerModule, productsCarouselModule, photoViewListModule, carouselModule]).constant('viewPrefix', {\n desktop: '',\n mobile: 'mobile-',\n mobileModern: 'mobile-modern-'\n}).constant('viewList', {\n desktop: ['tile', 'list', 'table'],\n mobile: ['tile', 'list', 'single'],\n mobileModern: ['tile', 'list', 'single']\n}).service('productViewService', productViewService).directive('productViewItem', productViewItemDirective).directive('productViewCarouselPhotos', productViewCarouselPhotosDirective).directive('productViewChangeMode', productViewChangeModeDirective).directive('productViewMode', productViewModeDirective).controller('ProductViewCarouselPhotosCtrl', ProductViewCarouselPhotosCtrl).controller('ProductViewChangeModeCtrl', ProductViewChangeModeCtrl).controller('ProductViewItemCtrl', ProductViewItemCtrl).controller('ProductViewModeCtrl', ProductViewModeCtrl);\nexport default moduleName;","productViewService.$inject = [\"$http\", \"$q\", \"$cookies\", \"$window\"];\n\n/* @ngInject */\nfunction productViewService($http, $q, $cookies, $window) {\n var service = this,\n productViewTransformers = {},\n queue = {},\n callbacks = {};\n\n service.getPhotos = function (productId) {\n return $http.get('productExt/getphotos', {\n params: {\n productId: productId,\n rnd: Math.random()\n }\n }).then(function (response) {\n return response.data;\n });\n };\n\n service.getView = function (name) {\n var defer = $q.defer();\n\n if (productViewTransformers[name] == null) {\n queue[name] = defer;\n } else {\n defer.resolve(productViewTransformers[name]);\n }\n\n return defer.promise.finally(function () {\n delete queue[name];\n });\n };\n\n service.addCallback = function (name, func) {\n callbacks[name] = callbacks[name] || [];\n callbacks[name].push(func);\n };\n\n service.pricessCallback = function (name, data) {\n if (callbacks[name] != null) {\n for (var i = 0, len = callbacks[name].length - 1; i <= len; i++) {\n callbacks[name][i](data);\n }\n }\n };\n\n service.setView = function (name, view, viewList, isMobile) {\n if (isMobile) {\n $cookies.put('mobile_viewmode', view);\n } else {\n if ($window.location.pathname.indexOf('/search') !== -1) {\n $cookies.put('search_viewmode', view);\n } else {\n $cookies.put('viewmode', view);\n }\n }\n\n productViewTransformers[name] = productViewTransformers[name] || {};\n productViewTransformers[name].viewName = view;\n productViewTransformers[name].viewList = viewList;\n\n if (queue[name] != null) {\n queue[name].resolve(productViewTransformers[name]);\n }\n\n service.pricessCallback('setView', productViewTransformers[name]);\n return productViewTransformers[name];\n };\n\n service.getViewFromCookie = function (cookieName, viewList) {\n var value = $cookies.get(cookieName);\n var item;\n\n for (var i = 0; i < viewList.length; i++) {\n if (viewList[i].indexOf(value) !== -1) {\n item = viewList[i];\n break;\n }\n }\n\n return item != null ? item : viewList[0];\n };\n\n service.getOfferId = function (productId, colorId, sizeId) {\n return $http.get('productExt/GetOffers', {\n params: {\n productId: productId,\n colorId: colorId,\n sizeId: sizeId,\n rnd: Math.random()\n }\n }).then(function (response) {\n return response.data;\n });\n };\n}\n\n;\nexport default productViewService;","ProductsCarouselCtrl.$inject = [\"$scope\", \"$compile\", \"$element\", \"productsCarouselService\"];\n\n/* @ngInject */\nfunction ProductsCarouselCtrl($scope, $compile, $element, productsCarouselService) {\n var ctrl = this;\n\n ctrl.$onInit = function () {\n ctrl.update();\n };\n\n ctrl.generate = function (ids, title, type, visibleItems, carouselResponsive) {\n productsCarouselService.getData(ids, title, type, visibleItems, carouselResponsive).then(function (result) {\n $element.empty();\n $element.append(result);\n $compile($element.contents())($scope);\n });\n };\n\n ctrl.update = function () {\n ctrl.generate(ctrl.ids, ctrl.title, ctrl.type, ctrl.visibleItems, ctrl.carouselResponsive);\n };\n}\n\n;\nexport default ProductsCarouselCtrl;","function productsCarouselDirective() {\n return {\n restrict: 'A',\n scope: {\n ids: '@',\n title: '@',\n type: '@',\n visibleItems: '@',\n carouselResponsive: ' {\n // quickviewService.dialogOpen(ctrl, productId, colorId, typeView, modalClass, landingId, hideShipping, showLeadButton, blockId, showVideo, modalId, openFromHash, sizeId, onOpenModalCallback, spyAddress, descriptionMode);\n // ctrl.cartAddTriggerName = 'quckview_' + Date.now();\n // cartService.addCallback(cartConfig.callbackNames.add, ctrl.hideModal, ctrl.cartAddTriggerName);\n // });\n\n /*ВЫЗЫВАЕТ АНГУЛЯР НЕСКОЛЬКОР РАЗ!!!!!!!!! Fly runtime*/\n import(\n /* webpackChunkName: \"productQuickview\" */\n\n /* webpackMode: \"lazy\" */\n '../../../product/productQuickview.module.js').then(function (module) {\n $ocLazyLoad.inject(module.default);\n }).then(function () {\n quickviewService.dialogOpen(ctrl, productId, colorId, typeView, modalClass, landingId, hideShipping, showLeadButton, blockId, showVideo, modalId, openFromHash, sizeId, onOpenModalCallback, spyAddress, descriptionMode);\n ctrl.cartAddTriggerName = 'quckview_' + Date.now();\n cartService.addCallback(cartConfig.callbackNames.add, ctrl.hideModal, ctrl.cartAddTriggerName);\n });\n };\n\n ctrl.hideModal = function () {\n quickviewService.dialogClose();\n cartService.removeCallback(cartConfig.callbackNames.add, ctrl.cartAddTriggerName);\n };\n\n ctrl.setSiblings = function (element) {\n var items, sibling, id, modalId;\n ctrl.siblings = [];\n ctrl.modalIds = {};\n items = domService.closest(element, '.js-products-view-block').parentNode.children;\n\n for (var i = 0, len = items.length - 1; i <= len; i++) {\n sibling = items[i].querySelector('.js-products-view-item');\n\n if (sibling != null) {\n id = parseInt(sibling.getAttribute('data-product-id'));\n modalId = sibling.getAttribute('data-modal-id');\n\n if (angular.isNumber(id)) {\n ctrl.siblings.push(id);\n ctrl.modalIds[id] = modalId;\n }\n }\n }\n };\n\n ctrl.onChangeSizeAndColor = function (data) {\n if (ctrl.isSpyAddress && data != null) {\n var hash = $location.hash();\n var urlParams = hash.split('?');\n var originalHash = urlParams.shift();\n var urlParamsFromHash = urlHelper.getUrlParamsAsObject(urlParams.join('&'));\n\n if (data.ColorId != null) {\n colorsAndSize.colorId = data.ColorId;\n }\n\n if (data.SizeId != null) {\n colorsAndSize.sizeId = data.SizeId;\n }\n\n $location.hash((originalHash || ctrl.modalId) + '?' + urlHelper.paramsToString(Object.assign({}, colorsAndSize, urlParamsFromHash)));\n }\n };\n\n ctrl.onOpenModal = function () {\n if (ctrl.productCtrl != null) {\n ctrl.onChangeSizeAndColor(ctrl.productCtrl.colorSelected);\n ctrl.onChangeSizeAndColor(ctrl.productCtrl.sizeSelected);\n }\n };\n\n ctrl.addProductCtrl = function (productCtrl) {\n ctrl.productCtrl = productCtrl;\n };\n}\n\nexport default QuickviewCtrl;","quickviewTriggerDirective.$inject = [\"$location\", \"urlHelper\", \"$window\", \"modalService\"];\n\n/* @ngInject */\nfunction quickviewTriggerDirective($location, urlHelper, $window, modalService) {\n return {\n require: ['quickviewTrigger', '^productViewItem'],\n restrict: 'A',\n scope: true,\n controller: 'QuickviewCtrl',\n controllerAs: 'quickview',\n bindToController: true,\n link: function link(scope, element, attrs, ctrls) {\n var hash = $location.hash();\n var quickviewCtrl = ctrls[0],\n productViewItemCtrl = ctrls[1];\n\n if (hash != null) {\n var splitedHash = hash.split('?');\n hash = splitedHash != null ? splitedHash[0] : hash;\n }\n\n var colorId, sizeId; //var originalHash = splitedHash[0];\n\n if (splitedHash != null && splitedHash.length > 1) {\n var addParams = urlHelper.getUrlParamsAsObject(splitedHash[1]);\n colorId = addParams.colorId;\n sizeId = addParams.sizeId;\n }\n\n quickviewCtrl.modalId = attrs.modalId != null ? attrs.modalId : null;\n quickviewCtrl.isSpyAddress = attrs.spyAddress === 'true';\n\n if (hash === attrs.modalId) {\n quickviewCtrl.openFromHash = true;\n\n if (attrs.categoryId != null) {\n quickviewCtrl.modalId = attrs.modalId + '?categoryId=' + attrs.categoryId;\n }\n\n if (quickviewCtrl.siblings == null) {\n quickviewCtrl.setSiblings(element[0]);\n }\n\n quickviewCtrl.showModal(productViewItemCtrl.productId || parseInt(attrs.productId), colorId || productViewItemCtrl.getSelectedColorId(), attrs.quickviewTypeView, element[0].getAttribute('data-modal-class'), attrs.landingId, attrs.hideShipping, attrs.showLeadButton, attrs.blockId, attrs.showVideo != null ? attrs.showVideo : null, quickviewCtrl.modalId, quickviewCtrl.openFromHash, sizeId, quickviewCtrl.onOpenModal, quickviewCtrl.isSpyAddress, attrs.descriptionMode); //scope.$digest();\n }\n\n element[0].addEventListener('click', function (event) {\n event.preventDefault();\n event.stopPropagation();\n\n if (quickviewCtrl.siblings == null) {\n quickviewCtrl.setSiblings(element[0]);\n }\n\n if (attrs.modalId != null && attrs.categoryId != null) {\n quickviewCtrl.modalId = attrs.modalId + '?categoryId=' + attrs.categoryId;\n }\n\n quickviewCtrl.showModal(productViewItemCtrl.productId || parseInt(attrs.productId), productViewItemCtrl.getSelectedColorId(), attrs.quickviewTypeView, element[0].getAttribute('data-modal-class'), attrs.landingId, attrs.hideShipping, attrs.showLeadButton, attrs.blockId, attrs.showVideo != null ? attrs.showVideo : null, quickviewCtrl.modalId, quickviewCtrl.openFromHash, sizeId, quickviewCtrl.onOpenModal, quickviewCtrl.isSpyAddress, attrs.descriptionMode);\n scope.$apply();\n });\n }\n };\n}\n\nexport { quickviewTriggerDirective };","import './styles/quickview.scss';\nimport QuickviewCtrl from './controllers/quickviewController.js';\nimport { quickviewTriggerDirective } from './directives/quickviewDirectives.js';\nimport quickviewService from './services/quickviewService.js';\nvar moduleName = 'quickview';\nangular.module(moduleName, []).controller('QuickviewCtrl', QuickviewCtrl).directive('quickviewTrigger', quickviewTriggerDirective).service('quickviewService', quickviewService);\nexport default moduleName;","quickviewService.$inject = [\"modalService\", \"$location\", \"urlHelper\"];\n\n/* @ngInject */\nfunction quickviewService(modalService, $location, urlHelper) {\n var service = this,\n isRender = false,\n modalQuickViewId = null,\n modalsStorage = {},\n data = {};\n\n service.dialogRender = function (parentScope) {\n modalService.renderModal(modalQuickViewId || 'modalQuickView', null, '
    ', null, {\n 'isOpen': false,\n 'modalClass': 'modal-quickview' + ' ' + (parentScope.modalClass || ''),\n 'backgroundEnable': true,\n spyAddress: parentScope.spyAddress,\n anchor: modalQuickViewId || 'modalQuickView',\n callbackOpen: parentScope.spyAddress ? 'quickview.onOpenModalCallback()' : ''\n }, {\n quickview: parentScope\n });\n modalService.getModal(modalQuickViewId || 'modalQuickView').then(function (modal) {\n modal.modalScope.open();\n });\n };\n\n service.getUrl = function (productId, colorId, typeView, landingId, hideShipping, showLeadButton, blockId, showVideo, sizeId, descriptionMode) {\n return 'product/productquickview' + '?productId=' + productId + (colorId != null ? '&color=' + colorId : '') + (sizeId != null ? '&size=' + sizeId : '') + '&from=' + typeView + (landingId != null ? '&landingId=' + landingId : '') + (hideShipping != null ? '&hideShipping=' + hideShipping : '') + (showLeadButton != null ? '&showLeadButton=' + showLeadButton : '') + (blockId != null ? '&blockId=' + blockId : '') + (showVideo != null ? '&showVideo=' + showVideo : '') + (descriptionMode != null ? '&descriptionMode=' + descriptionMode : '');\n };\n\n service.dialogOpen = function (itemData, productId, colorId, typeView, modalClass, landingId, hideShipping, showLeadButton, blockId, showVideo, modalId, openFromHash, sizeId, onOpenModalCallback, spyAddress, descriptionMode) {\n data.url = service.getUrl(productId, colorId, typeView, landingId, hideShipping, showLeadButton, blockId, showVideo, sizeId, descriptionMode);\n data.itemData = itemData;\n data.productId = productId;\n data.next = service.next;\n data.prev = service.prev;\n data.modalClass = modalClass;\n data.typeView = typeView;\n data.landingId = landingId;\n data.hideShipping = hideShipping;\n data.showLeadButton = showLeadButton;\n data.blockId = blockId;\n data.showVideo = showVideo;\n data.modalId = modalId;\n data.onOpenModalCallback = onOpenModalCallback;\n data.spyAddress = spyAddress;\n data.descriptionMode = descriptionMode;\n modalQuickViewId = modalId;\n var hash = $location.hash();\n var splitedHash = hash.split('?');\n var originalHash = splitedHash[0];\n\n if (!modalsStorage[modalId]) {\n service.dialogRender(data);\n } else {\n modalService.open(modalId);\n }\n\n modalsStorage[modalId] = modalId;\n };\n\n service.dialogClose = function () {\n modalService.close(modalQuickViewId || 'modalQuickView');\n };\n\n service.prev = function () {\n var index, indexPrev;\n index = data.itemData.siblings.indexOf(data.productId);\n indexPrev = index - 1;\n\n if (data.itemData.siblings[indexPrev] != null) {\n data.productId = data.itemData.siblings[indexPrev];\n $location.hash(data.itemData.modalIds[data.productId]);\n data.url = service.getUrl(data.productId, null, data.typeView, data.landingId, data.hideShipping, data.showLeadButton, data.blockId, data.showVideo, null, data.descriptionMode);\n }\n };\n\n service.next = function () {\n var index, indexNext;\n index = data.itemData.siblings.indexOf(data.productId);\n indexNext = index + 1;\n\n if (data.itemData.siblings[indexNext] != null) {\n data.productId = data.itemData.siblings[indexNext];\n $location.hash(data.itemData.modalIds[data.productId]);\n data.url = service.getUrl(data.productId, null, data.typeView, data.landingId, data.hideShipping, data.showLeadButton, data.blockId, data.showVideo, null, data.descriptionMode);\n }\n };\n}\n\n;\nexport default quickviewService;","ReviewItemRatingCtrl.$inject = [\"$attrs\", \"$http\", \"$parse\", \"$scope\", \"toaster\"];\n\n/* @ngInject */\nfunction ReviewItemRatingCtrl($attrs, $http, $parse, $scope, toaster) {\n var ctrl = this;\n\n ctrl.$onInit = function () {\n ctrl.actionUrl = $parse($attrs.actionUrl)($scope);\n ctrl.reviewId = $parse($attrs.reviewId)($scope);\n ctrl.likeData = {\n Dislikes: $parse($attrs.countDislikes)($scope),\n Likes: $parse($attrs.countLikes)($scope)\n };\n };\n\n ctrl.like = function () {\n ctrl.voteReview(ctrl.reviewId, true, ctrl.actionUrl);\n };\n\n ctrl.dislike = function () {\n ctrl.voteReview(ctrl.reviewId, false, ctrl.actionUrl);\n };\n\n ctrl.voteReview = function (reviewId, like, actionUrl) {\n return $http.post(actionUrl, {\n reviewId: reviewId,\n vote: like\n }).then(function (response) {\n if (response.data.error) {\n toaster.pop('error', response.data.errors);\n } else {\n angular.extend(ctrl.likeData, response.data.likeData);\n }\n\n return response.data;\n });\n };\n}\n\n;\nexport default ReviewItemRatingCtrl;","ReviewsCtrl.$inject = [\"$element\", \"$compile\", \"$scope\", \"$http\", \"$filter\", \"$templateCache\", \"$timeout\", \"toaster\", \"Upload\", \"$translate\"];\n\n/* @ngInject */\nfunction ReviewsCtrl($element, $compile, $scope, $http, $filter, $templateCache, $timeout, toaster, Upload, $translate) {\n var ctrl = this,\n listRoot,\n items = {},\n form,\n formScope;\n ctrl.visibleFormCancelButton = false;\n ctrl.reviewIdActive = 0;\n\n ctrl.addItemInStorage = function (id, element) {\n items[id] = element;\n };\n\n ctrl.addForm = function (scope, element) {\n form = element;\n formScope = scope;\n };\n\n ctrl.getForm = function () {\n return form;\n };\n\n ctrl.reply = function (parentId) {\n items[parentId].append(ctrl.getForm());\n ctrl.moveFormInside(parentId);\n ctrl.formVisible = true;\n ctrl.focusInput();\n };\n\n ctrl.moveFormInside = function (parentId) {\n ctrl.reviewIdActive = parentId;\n ctrl.visibleFormCancelButton = true;\n };\n\n ctrl.formReset = function () {\n formScope.reset();\n };\n\n ctrl.moveFormDefault = function () {\n $element.append(form);\n };\n\n ctrl.formInStart = function () {\n ctrl.moveFormDefault();\n ctrl.formReset();\n ctrl.reviewIdActive = 0;\n ctrl.visibleFormCancelButton = false;\n };\n\n ctrl.addReview = function (actionUrl, name, email, text, parentId, files, agreement, captchaCode, captchaSource) {\n $(document).trigger(\"add_response\");\n return Upload.upload({\n url: actionUrl,\n data: {\n entityId: ctrl.entityId,\n entityType: ctrl.entityType,\n name: name,\n email: email,\n text: text,\n parentId: parentId,\n agreement: agreement,\n captchaCode: captchaCode,\n captchaSource: captchaSource\n },\n file: files // or list of files (files) for html5 only\n\n });\n };\n\n ctrl.submit = function (form, actionUrl) {\n //if (form.form.captchaCode != undefined) {\n ctrl.addReview(actionUrl, form.name, form.email, form.text, form.reviewId, form.images, form.agreement, form.captchaCode, form.captchaSource).then(function (response) {\n if (response.data.error) {\n toaster.pop('error', response.data.errors);\n return;\n }\n\n var newReview = response.data.review;\n\n if (ctrl.moderate == false) {\n ctrl.renderReviewItem(newReview.ParentId, newReview.ReviewId, newReview.Name, $filter('date')(Date.now(), 'dd MMMM yyyy'), newReview.Text, newReview.Photos, newReview.Likes, newReview.Dislikes, newReview.RatioByLikes);\n\n if (ctrl.onAddComment != null) {\n ctrl.onAddComment($scope);\n }\n } else {\n toaster.pop('info', $translate.instant('Js.Reviews.ThxForReviewTitle'), $translate.instant('Js.Reviews.ThxForReviewMsg'));\n }\n }); //}\n\n if (ctrl.showFormAfterDo === true) {\n ctrl.formInStart();\n } else {\n ctrl.formReset();\n ctrl.reviewIdActive = 0;\n ctrl.visibleFormCancelButton = false;\n ctrl.formVisible = false;\n }\n };\n\n ctrl.renderReviewItem = function (parentId, reviewId, name, date, text, photos, likes, dislikes, ratioByLikes) {\n var parentContainer, list, needContainer, reviewNew, htmlItem, before;\n\n if (items[parentId] != null) {\n list = items[parentId].children('ul');\n\n if (list.length > 0) {\n parentContainer = list;\n needContainer = false;\n } else {\n parentContainer = items[parentId];\n needContainer = true;\n }\n } else {\n if (listRoot) {\n parentContainer = listRoot;\n }\n\n if (parentContainer == null) {\n var reviewslist = $element[0].querySelector('.reviews-list');\n\n if (reviewslist != null) {\n parentContainer = angular.element(reviewslist);\n }\n }\n\n if (parentContainer == null) {\n parentContainer = angular.element($element[0].querySelector('.js-reviews-list-root'));\n }\n\n needContainer = true;\n before = true;\n }\n\n ctrl.getHtmlReviewItem(needContainer).then(function (htmlItem) {\n reviewNew = angular.element(htmlItem);\n\n if (before) {\n parentContainer.before(reviewNew);\n } else {\n parentContainer.append(reviewNew);\n }\n\n var scopeItem = $scope.$new();\n scopeItem.parentId = parentId;\n scopeItem.reviewId = reviewId;\n scopeItem.name = name;\n scopeItem.date = $translate.instant(date);\n scopeItem.text = text;\n scopeItem.photos = photos;\n scopeItem.likes = likes;\n scopeItem.dislikes = dislikes;\n scopeItem.ratioByLikes = ratioByLikes;\n $compile(reviewNew)(scopeItem);\n });\n };\n\n ctrl.getHtmlReviewItem = function (needContainer) {\n return $http.get('reviewItemTemplate.html', {\n cache: $templateCache\n }).then(function (response) {\n var result = response.data;\n\n if (needContainer === true) {\n result = '
      ' + result + '
    ';\n }\n\n return result;\n });\n };\n\n ctrl.cancel = function (form) {\n if (ctrl.showFormAfterDo === true) {\n ctrl.formInStart();\n } else {\n ctrl.formReset();\n ctrl.reviewIdActive = 0;\n ctrl.visibleFormCancelButton = false;\n ctrl.formVisible = false;\n }\n };\n\n ctrl.deleteReviewFromDB = function (reviewId, actionUrl) {\n return $http.post(actionUrl, {\n reviewId: reviewId\n });\n };\n\n ctrl.delete = function (reviewId, actionUrl) {\n if (items[reviewId] != null) {\n ctrl.deleteReviewFromDB(reviewId, actionUrl).then(function (response) {\n items[reviewId].remove();\n\n if (ctrl.onDeleteComment != null) {\n ctrl.onDeleteComment($scope);\n }\n });\n }\n };\n\n ctrl.focusInput = function () {\n formScope.setAutofocus();\n };\n}\n\n;\nexport default ReviewsCtrl;","ReviewsFormCtrl.$inject = [\"$timeout\", \"toaster\", \"$translate\", \"$http\"];\n\n/* @ngInject */\nfunction ReviewsFormCtrl($timeout, toaster, $translate, $http) {\n var ctrl = this;\n ctrl.nameFocus = ctrl.emailFocus = ctrl.textFocus = false;\n ctrl.images = [];\n\n ctrl.selectedImage = function (files) {\n if (files && files.length) {\n for (var i = 0; i < files.length; i++) {\n ctrl.pushImages(files[i]);\n }\n }\n };\n\n ctrl.pushImages = function (image) {\n ctrl.images.push(image || {});\n };\n\n ctrl.deleteImage = function (index) {\n ctrl.images.splice(index, 1);\n };\n\n ctrl.submit = function () {\n if (ctrl.isShowUserAgreementText && !ctrl.agreement) {\n toaster.pop('error', $translate.instant('Js.Subscribe.ErrorAgreement'));\n return;\n }\n\n ctrl.images = ctrl.images.filter(function (image) {\n return image.name;\n });\n var sendResult = false;\n\n if (typeof CaptchaSource != \"undefined\") {\n CaptchaSource.InputId = \"CaptchaCode\";\n ctrl.captchaCode = CaptchaSource.GetInputElement().value;\n ctrl.captchaSource = CaptchaSource.InstanceId;\n $http.get(CaptchaSource.ValidationUrl + '&i=' + CaptchaSource.GetInputElement().value).then(function (result) {\n if (result.data === true) {\n ctrl.submitFn({\n form: ctrl\n });\n sendResult = true;\n } else {\n toaster.pop('error', $translate.instant('Js.Captcha.Wrong'));\n }\n }).then(function () {\n $timeout(function () {\n CaptchaSource.ReloadImage();\n }, 1000);\n CaptchaSource.GetInputElement().value = '';\n\n if ((ctrl.moderate == null || ctrl.moderate == false) && sendResult === true) {\n $translate(['Js.Reviews.SuccessTitle', 'Js.Reviews.SuccessMessage']).then(function (translations) {\n toaster.success(translations['Js.Reviews.SuccessTitle'], translations['Js.Reviews.SuccessMessage']);\n });\n }\n });\n } else {\n ctrl.submitFn({\n form: ctrl\n });\n sendResult = true;\n\n if ((ctrl.moderate == null || ctrl.moderate == false) && sendResult === true) {\n $translate(['Js.Reviews.SuccessTitle', 'Js.Reviews.SuccessMessage']).then(function (translations) {\n toaster.success(translations['Js.Reviews.SuccessTitle'], translations['Js.Reviews.SuccessMessage']);\n });\n }\n }\n };\n\n ctrl.reset = function () {\n //formScope.name = '';\n //formScope.email = '';\n ctrl.text = '';\n ctrl.images = [];\n ctrl.agreement = false;\n ctrl.form.$setPristine();\n };\n\n ctrl.setAutofocus = function () {\n ctrl.nameFocus = ctrl.emailFocus = ctrl.textFocus = false;\n $timeout(function () {\n if (ctrl.name == null || ctrl.name.length === 0) {\n ctrl.nameFocus = true;\n } else if (ctrl.email == null || ctrl.email.length === 0) {\n ctrl.emailFocus = true;\n } else if (ctrl.text == null || ctrl.text.length === 0) {\n ctrl.textFocus = true;\n }\n }, 0);\n };\n}\n\n;\nexport default ReviewsFormCtrl;","reviewsDirective.$inject = [\"$parse\"];\n\n/* @ngInject */\nfunction reviewsDirective($parse) {\n return {\n restrict: 'A',\n scope: true,\n controller: 'ReviewsCtrl',\n controllerAs: 'reviews',\n bindToController: true,\n link: function link(scope, element, attrs, ctrl) {\n ctrl.moderate = attrs.moderate === 'true';\n ctrl.isAdmin = attrs.isAdmin === 'true';\n ctrl.entityId = attrs.entityId;\n ctrl.entityType = attrs.entityType;\n ctrl.name = attrs.name;\n ctrl.email = attrs.email;\n ctrl.actionUrl = attrs.actionUrl;\n ctrl.formVisible = attrs.formVisible !== 'false';\n ctrl.allowImageUpload = attrs.allowImageUpload === 'true';\n ctrl.readonly = attrs.readonly === 'true';\n ctrl.onAddComment = attrs.onAddComment != null ? $parse(attrs.onAddComment) : null;\n ctrl.onDeleteComment = attrs.onDeleteComment != null ? $parse(attrs.onDeleteComment) : null;\n ctrl.showFormAfterDo = attrs.showFormAfterDo != null ? $parse(attrs.showFormAfterDo) : true;\n }\n };\n}\n\n;\n\nfunction reviewItemDirective() {\n return {\n require: '^reviews',\n restrict: 'A',\n scope: true,\n link: function link(scope, element, attrs, ctrl) {\n ctrl.addItemInStorage(attrs.reviewId, element);\n }\n };\n}\n\n;\n\nfunction reviewsFormDirective() {\n return {\n require: ['^reviewsForm', '^reviews'],\n restrict: 'A',\n scope: {\n visibleFormCancelButton: '=',\n reviewId: '=',\n name: '=',\n email: '=',\n submitFn: '&',\n cancelFn: '&',\n formVisible: '=',\n allowImageUpload: '=',\n isShowUserAgreementText: '=',\n agreementDefaultChecked: '',\n link: function link(scope, element, attrs, ctrl) {\n scope.parentScope = ctrl;\n }\n };\n}\n\n;\n\nfunction reviewDeleteDirective() {\n return {\n require: '^reviews',\n restrict: 'A',\n replace: true,\n transclude: true,\n scope: {\n reviewId: '@',\n actionUrl: '@'\n },\n template: '',\n link: function link(scope, element, attrs, ctrl) {\n scope.parentScope = ctrl;\n }\n };\n}\n\n;\n\nfunction reviewItemRatingDirective() {\n return {\n scope: true,\n controller: 'ReviewItemRatingCtrl',\n controllerAs: 'reviewItemRating'\n };\n}\n\n;\nexport { reviewsDirective, reviewItemDirective, reviewsFormDirective, reviewReplyDirective, reviewDeleteDirective, reviewItemRatingDirective };","import ngFileUploadModule from '../../../node_modules/ng-file-upload/index.js';\nimport './styles/reviews.scss';\nimport ReviewsCtrl from './controllers/reviewsController.js';\nimport ReviewsFormCtrl from './controllers/reviewsFormController.js';\nimport ReviewItemRatingCtrl from './controllers/reviewItemRatingController.js';\nimport { reviewsDirective, reviewItemDirective, reviewsFormDirective, reviewReplyDirective, reviewDeleteDirective, reviewItemRatingDirective } from './directives/reviewsDirectives.js';\nvar moduleName = 'reviews';\nangular.module(moduleName, [ngFileUploadModule]).controller('ReviewsCtrl', ReviewsCtrl).controller('ReviewItemRatingCtrl', ReviewItemRatingCtrl).controller('ReviewsFormCtrl', ReviewsFormCtrl).directive('reviews', reviewsDirective).directive('reviewItem', reviewItemDirective).directive('reviewsForm', reviewsFormDirective).directive('reviewReply', reviewReplyDirective).directive('reviewDelete', reviewDeleteDirective).directive('reviewItemRating', reviewItemRatingDirective);\nexport default moduleName;","ShippingListCtrl.$inject = [\"$anchorScroll\", \"$location\"];\n\n/* @ngInject */\nfunction ShippingListCtrl($anchorScroll, $location) {\n var ctrl = this;\n var watchersFn = []; //ctrl.isProgress = null;\n\n $anchorScroll.yOffset = 50; //ctrl.selectedItemIndex = 0;\n //ctrl.collapsed = true;\n\n ctrl.visibleItems = Number.POSITIVE_INFINITY;\n\n ctrl.changeShipping = function (shipping, index) {\n if (index != null) {\n ctrl.selectedItemIndex = index;\n }\n\n ctrl.change({\n shipping: shipping,\n newShipping: ctrl.newShipping\n });\n };\n\n ctrl.changeShippingControl = function (shipping) {\n for (var i = ctrl.items.length - 1; i >= 0; i--) {\n if (ctrl.items[i] == shipping) {\n ctrl.selectShipping = shipping;\n ctrl.selectedItemIndex = i;\n break;\n }\n }\n\n ctrl.change({\n shipping: shipping,\n customShipping: ctrl.customShipping\n });\n };\n\n ctrl.focusEditPrice = function (shipping, index) {\n ctrl.selectShipping = shipping;\n ctrl.selectedItemIndex = index;\n ctrl.focus({\n shipping: shipping,\n customShipping: ctrl.customShipping\n });\n };\n\n ctrl.calc = function (index) {\n var selectItemPos = index + 1;\n ctrl.selectedItemIndex = index;\n ctrl.visibleItems = selectItemPos > ctrl.countVisibleItems ? selectItemPos : ctrl.countVisibleItems;\n return selectItemPos;\n };\n\n ctrl.toggleVisible = function () {\n var selectItemPos = ctrl.calc(ctrl.selectedItemIndex);\n\n if (ctrl.collapsed === true) {\n ctrl.visibleItems = ctrl.items.length;\n ctrl.collapsed = false;\n } else {\n if (selectItemPos === ctrl.items.length) {\n return;\n }\n\n ctrl.visibleItems = selectItemPos > ctrl.countVisibleItems ? selectItemPos : ctrl.countVisibleItems;\n ctrl.collapsed = true;\n $location.hash(ctrl.anchor);\n $anchorScroll();\n }\n };\n\n ctrl.setSelectedIndex = function (index) {\n var selectItemPos = ctrl.calc(index);\n\n if (selectItemPos === ctrl.items.length) {\n ctrl.collapsed = false;\n } else {\n ctrl.collapsed = true;\n }\n };\n\n ctrl.addCallbackOnLoad = function (fn) {\n watchersFn.push(fn);\n };\n\n ctrl.processCallbacks = function () {\n var params = arguments;\n watchersFn.forEach(function (fn) {\n fn(params);\n });\n };\n}\n\n;\nexport default ShippingListCtrl;","ShippingTemplateCtrl.$inject = [\"$timeout\", \"$ocLazyLoad\", \"urlHelper\"];\n\n/* @ngInject */\nfunction ShippingTemplateCtrl($timeout, $ocLazyLoad, urlHelper) {\n var ctrl = this,\n timer;\n\n ctrl.prepereLazyLoadUrl = function (params) {\n for (var i = 0, len = params.length; i < len; i++) {\n params[i] = urlHelper.getAbsUrl(params[i], true);\n }\n\n return params;\n };\n\n ctrl.changePrepare = function (event, field, shipping) {\n if (field == null) {\n return;\n }\n\n angular.extend(ctrl.shipping, shipping);\n\n if (event != null && event.type == 'keyup') {\n if (timer != null) {\n $timeout.cancel(timer);\n }\n\n timer = $timeout(function () {\n ctrl.changeControl({\n shipping: ctrl.shipping\n });\n }, 500);\n } else {\n ctrl.changeControl({\n shipping: ctrl.shipping\n });\n }\n };\n\n ctrl.changeSpinbox = function (value, proxy) {\n ctrl.changeControl({\n shipping: ctrl.shipping\n });\n };\n}\n\n;\nexport default ShippingTemplateCtrl;","ShippingVariantsCtrl.$inject = [\"$http\", \"zoneService\"];\n\n/* @ngInject */\nfunction ShippingVariantsCtrl($http, zoneService) {\n var ctrl = this;\n\n ctrl.$postLink = function () {\n if (ctrl.type === \"display\") {\n ctrl.getData(ctrl.startOfferId, ctrl.startAmount, ctrl.startSvCustomOptions, ctrl.zip);\n }\n\n if (ctrl.type === \"none\") {\n ctrl.getData(ctrl.startOfferId, ctrl.startAmount, ctrl.startSvCustomOptions, ctrl.zip);\n }\n\n if (ctrl.type === \"Always\") {\n ctrl.getData(ctrl.startOfferId, ctrl.startAmount, ctrl.startSvCustomOptions, ctrl.zip);\n }\n\n zoneService.addCallback('set', function (data) {\n ctrl.zip = data.Zip;\n ctrl.getData(ctrl.offerId, ctrl.amount != null ? ctrl.amount : ctrl.startAmount, ctrl.svCustomOptions, ctrl.zip);\n });\n ctrl.initFn({\n shippingVariants: ctrl\n });\n };\n\n ctrl.getData = function (offerId, amount, customOptions, zip) {\n if (offerId == null || amount == null) {\n return null;\n }\n\n ctrl.isProgress = true;\n return $http.post('productExt/getshippings', {\n offerId: offerId,\n amount: amount,\n customOptions: customOptions,\n zip: zip,\n rnd: Math.random()\n }).then(function (response) {\n if (response.data != null) {\n ctrl.items = response.data.Shippings;\n\n if (response.data.AdvancedObj) {\n ctrl.showZip = response.data.AdvancedObj.ShowZip;\n }\n } else {\n ctrl.items = [];\n }\n\n ctrl.isProgress = false;\n return response.data;\n });\n };\n\n ctrl.update = function () {\n return ctrl.getData(ctrl.offerId, ctrl.amount, ctrl.svCustomOptions, ctrl.zip).then(function (data) {\n return data;\n });\n };\n\n ctrl.calcShippings = function () {\n ctrl.type = \"Always\";\n ctrl.getData(ctrl.startOfferId, ctrl.startAmount, ctrl.startSvCustomOptions, ctrl.zip);\n };\n}\n\n;\nexport default ShippingVariantsCtrl;","shippingListDirective.$inject = [\"urlHelper\", \"$timeout\"];\n\n/* @ngInject */\nfunction shippingListDirective(urlHelper, $timeout) {\n return {\n restrict: 'A',\n scope: {\n items: '=',\n selectShipping: '=',\n countVisibleItems: '=',\n change: '&',\n focus: '&',\n anchor: '@',\n isProgress: '=?',\n contact: ''\n };\n}\n\n;\n\nfunction shippingVariantsDirective() {\n return {\n restrict: 'A',\n scope: {\n type: '@',\n offerId: '=',\n amount: '=',\n svCustomOptions: '=',\n startOfferId: '@',\n startAmount: '@',\n startSvCustomOptions: '@',\n zip: '@',\n initFn: '&'\n },\n controller: 'ShippingVariantsCtrl',\n controllerAs: 'shippingVariants',\n bindToController: true,\n replace: true,\n templateUrl: '/scripts/_partials/shipping/templates/shippingVariants.html'\n };\n}\n\n;\nexport { shippingListDirective, shippingTemplateDirective, shippingVariantsDirective };","import './styles/shipping.scss';\nimport ShippingListCtrl from './controllers/shippingListController.js';\nimport ShippingVariantsCtrl from './controllers/shippingVariantsController.js';\nimport ShippingTemplateCtrl from './controllers/shippingTemplateController.js';\nimport { shippingListDirective, shippingTemplateDirective, shippingVariantsDirective } from './directives/shippingDirectives.js';\nvar moduleName = 'shipping';\nangular.module(moduleName, []).controller('ShippingListCtrl', ShippingListCtrl).controller('ShippingTemplateCtrl', ShippingTemplateCtrl).controller('ShippingVariantsCtrl', ShippingVariantsCtrl).directive('shippingList', shippingListDirective).directive('shippingTemplate', shippingTemplateDirective).directive('shippingVariants', shippingVariantsDirective);\nexport default moduleName;","function SizesViewerCtrl() {\n var ctrl = this;\n\n ctrl.$onInit = function () {\n if (ctrl.startSelectedSizes != null && ctrl.startSelectedSizes.length > 0) {\n for (var s = 0, lenS = ctrl.startSelectedSizes.length; s < lenS; s++) {\n for (var c = 0, lenC = ctrl.sizes.length; c < lenC; c++) {\n if (ctrl.sizes[c].SizeId === ctrl.startSelectedSizes[s]) {\n ctrl.sizeSelected = ctrl.sizes[c];\n break;\n }\n }\n }\n }\n\n ctrl.initSizes({\n sizesViewer: ctrl\n });\n };\n}\n\n;\nexport default SizesViewerCtrl;","function sizesViewerDirective() {\n return {\n restrict: 'A',\n replace: true,\n templateUrl: '/scripts/_partials/sizes-viewer/templates/sizes.html',\n controller: 'SizesViewerCtrl',\n controllerAs: 'sizesViewer',\n bindToController: true,\n scope: {\n sizes: ' 0;\n });\n };\n\n ctrl.refreshPrice = function () {\n var defer = $q.defer();\n ctrl.getPrice(ctrl.offerSelected.OfferId, ctrl.customOptions != null ? ctrl.customOptions.xml : null, ctrl.offerSelected.AmountBuy).then(function (price) {\n return ctrl.getFirstPaymentPrice(price.PriceOldNumber != null && price.PriceOldNumber != 0 ? price.PriceOldNumber : price.PriceNumber, ctrl.discount, ctrl.discountAmount);\n }).then(function () {\n if (ctrl.shippingVariants != null) {\n ctrl.shippingVariants.update().then(function (data) {\n defer.resolve(data);\n return data;\n });\n } else {\n defer.resolve();\n }\n\n productService.processCallback('refreshPrice');\n });\n return defer.promise;\n };\n\n ctrl.prepareOffers = function (data) {\n for (var i = 0, len = data.Offers.length; i < len; i++) {\n if (data.Offers[i].Available != null && angular.isString(data.Offers[i].Available) === true) {\n data.Offers[i].Available = $sce.trustAsHtml(data.Offers[i].Available);\n }\n }\n\n return data;\n };\n\n ctrl.loadData = function (productId, colorId, sizeId, hiddenPrice, filterPhotosEnable, preventChangeLocation) {\n ctrl.productId = productId;\n ctrl.hiddenPrice = hiddenPrice;\n ctrl.filterPhotosEnable = filterPhotosEnable != null ? filterPhotosEnable : true;\n ctrl.preventChangeLocation = preventChangeLocation === true;\n return productService.getOffers(productId, colorId, sizeId).then(function (data) {\n if (data == null) {\n if (colorId == null) {\n ctrl.carouselHidden = false;\n }\n\n return null;\n }\n\n ctrl.data = ctrl.prepareOffers(data);\n ctrl.offerSelected = productService.findOfferSelected(data.Offers, data.StartOfferIdSelected);\n ctrl.dirty = true;\n ctrl.getColorsViewer().then(function () {\n if (ctrl.colorsViewer != null && ctrl.offerSelected.Color != null) {\n ctrl.setColorSelected(ctrl.colorsViewer, ctrl.offerSelected.Color != null ? ctrl.offerSelected.Color.ColorId : null);\n }\n\n return ctrl.data;\n }).then(ctrl.getSizesViewer).then(function () {\n if (ctrl.sizesViewer != null && ctrl.offerSelected.Size != null) {\n ctrl.setSizeSelected(ctrl.sizesViewer, ctrl.offerSelected.Size.SizeId);\n }\n\n return ctrl.data;\n }).then(ctrl.getCarousel).then(function () {\n if (ctrl.filterPhotosEnable === true && ctrl.carousel != null) {\n ctrl.filterPhotos(ctrl.offerSelected.Color != null ? ctrl.offerSelected.Color.ColorId : null, ctrl.carousel);\n }\n\n ctrl.carouselHidden = false;\n });\n return ctrl.data;\n });\n };\n\n ctrl.validate = function () {\n var result = true;\n\n if (ctrl.customOptions != null && ctrl.customOptions.customOptionsForm.$invalid === true) {\n ctrl.customOptions.customOptionsForm.$setSubmitted();\n ctrl.customOptions.customOptionsForm.$setDirty();\n toaster.pop('error', $translate.instant('Js.Product.InvalidCustomOptions'));\n result = false;\n }\n\n return result;\n }; //#region compare and wishlist\n\n\n ctrl.compareInit = function (compare) {\n ctrl.compare = compare;\n };\n\n ctrl.wishlistControlInit = function (wishlistControl) {\n ctrl.wishlistControl = wishlistControl;\n }; //#endregion\n //#region customOptions\n\n\n ctrl.customOptionsInitFn = function (customOptions) {\n ctrl.customOptions = customOptions;\n };\n\n ctrl.customOptionsChange = function () {\n if (!ctrl.hiddenPrice) {\n ctrl.refreshPrice();\n }\n }; //#endregion\n //#region colors\n\n\n ctrl.initColors = function (colorsViewer) {\n ctrl.colorsViewer = colorsViewer;\n\n if (ctrl.colorsViewerDefer != null) {\n ctrl.colorsViewerDefer.resolve();\n delete ctrl.colorsViewerDefer;\n }\n };\n\n ctrl.getColorsViewer = function () {\n var defer = $q.defer();\n\n if (ctrl.colorsExist === true && ctrl.colorsViewer == null) {\n ctrl.colorsViewerDefer = defer;\n } else {\n defer.resolve(ctrl.colorsViewer);\n }\n\n return defer.promise;\n };\n\n ctrl.changeColor = function (color) {\n ctrl.colorSelected = color;\n\n if (ctrl.changeSizeAndColorCallback != null) {\n ctrl.changeSizeAndColorCallback(ctrl.colorSelected);\n }\n\n if (ctrl.sizesViewer != null) {\n ctrl.sizeSelected = ctrl.getSizeAvalable(ctrl.data.Offers, ctrl.colorSelected.ColorId, ctrl.sizesViewer.sizes, ctrl.data.AllowPreOrder);\n\n if (ctrl.changeSizeAndColorCallback != null) {\n ctrl.changeSizeAndColorCallback(ctrl.sizeSelected);\n }\n\n if (ctrl.preventChangeLocation !== true) {\n urlHelper.setLocationQueryParams('size', ctrl.sizeSelected.SizeId, true);\n }\n }\n\n ctrl.offerSelected = productService.getOffer(ctrl.data.Offers, ctrl.colorSelected.ColorId, ctrl.sizeSelected != null && ctrl.sizeSelected.isDisabled === false ? ctrl.sizeSelected.SizeId : null, ctrl.data.AllowPreOrder);\n\n if (!ctrl.hiddenPrice) {\n ctrl.refreshPrice();\n }\n\n if (ctrl.compare != null) {\n ctrl.compare.checkStatus(ctrl.offerSelected.OfferId);\n }\n\n if (ctrl.wishlistControl != null) {\n ctrl.wishlistControl.checkStatus(ctrl.offerSelected.OfferId);\n }\n\n ctrl.setPreviewByColorId(ctrl.colorSelected.ColorId, ctrl.filterPhotosEnable, ctrl.carousel);\n\n if (ctrl.preventChangeLocation !== true) {\n urlHelper.setLocationQueryParams('color', ctrl.colorSelected.ColorId, true);\n }\n };\n\n ctrl.setColorSelected = function (colorsViewer, colorId) {\n for (var i = colorsViewer.colors.length - 1; i >= 0; i--) {\n if (colorsViewer.colors[i].ColorId === colorId) {\n ctrl.colorSelected = colorsViewer.colors[i];\n break;\n }\n }\n\n if (ctrl.changeSizeAndColorCallback != null) {\n ctrl.changeSizeAndColorCallback(ctrl.colorSelected);\n }\n }; //#endregion\n //#region sizes\n\n\n ctrl.initSizes = function (sizesViewer) {\n ctrl.sizesViewer = sizesViewer;\n\n if (ctrl.sizesViewerDefer != null) {\n ctrl.sizesViewerDefer.resolve();\n delete ctrl.sizesViewerDefer;\n }\n };\n\n ctrl.getSizesViewer = function () {\n var defer = $q.defer();\n\n if (ctrl.sizesExist === true && ctrl.sizesViewer == null) {\n ctrl.sizesViewerDefer = defer;\n } else {\n defer.resolve(ctrl.sizesViewer);\n }\n\n return defer.promise;\n };\n\n ctrl.changeSize = function (size) {\n ctrl.sizeSelected = size;\n\n if (ctrl.changeSizeAndColorCallback != null) {\n ctrl.changeSizeAndColorCallback(ctrl.sizeSelected);\n }\n\n ctrl.offerSelected = productService.getOffer(ctrl.data.Offers, ctrl.colorSelected != null ? ctrl.colorSelected.ColorId : 0, ctrl.sizeSelected.isDisabled ? null : ctrl.sizeSelected.SizeId, ctrl.data.AllowPreOrder);\n\n if (!ctrl.hiddenPrice) {\n ctrl.refreshPrice();\n }\n\n if (ctrl.compare != null) {\n ctrl.compare.checkStatus(ctrl.offerSelected.OfferId);\n }\n\n if (ctrl.wishlistControl != null) {\n ctrl.wishlistControl.checkStatus(ctrl.offerSelected.OfferId);\n }\n\n if (ctrl.preventChangeLocation !== true) {\n urlHelper.setLocationQueryParams('size', ctrl.sizeSelected.SizeId, true);\n }\n };\n\n ctrl.setSizeSelected = function (sizesViewer, sizeId) {\n for (var i = sizesViewer.sizes.length - 1; i >= 0; i--) {\n if (sizesViewer.sizes[i].SizeId === sizeId) {\n ctrl.sizeSelected = sizesViewer.sizes[i];\n break;\n }\n }\n\n ctrl.sizeSelected = ctrl.getSizeAvalable(ctrl.data.Offers, ctrl.colorSelected != null ? ctrl.colorSelected.ColorId : 0, ctrl.sizesViewer.sizes, ctrl.data.AllowPreOrder);\n\n if (ctrl.changeSizeAndColorCallback != null) {\n ctrl.changeSizeAndColorCallback(ctrl.sizeSelected);\n }\n };\n\n ctrl.getSizeAvalable = function (offers, colorId, sizes, allowPreorder) {\n var offerItem, sizeItem, sizeSelected, loopCheckStart;\n sizes.forEach(function (item) {\n item.isDisabled = true;\n });\n\n for (var i = offers.length - 1; i >= 0; i--) {\n offerItem = offers[i];\n\n if (colorId == null || offerItem.Color == null) {\n loopCheckStart = true;\n } else {\n loopCheckStart = offerItem.Color != null && offerItem.Color.ColorId === colorId;\n }\n\n ;\n\n if (loopCheckStart === true) {\n for (var s = sizes.length - 1; s >= 0; s--) {\n if (offerItem.Size.SizeId == sizes[s].SizeId && (allowPreorder === true || offerItem.Amount > 0)) {\n sizes[s].isDisabled = false;\n break;\n }\n }\n\n ;\n }\n }\n\n if (ctrl.sizeSelected == null || ctrl.sizeSelected.isDisabled === true) {\n for (var j = 0, l = sizes.length; j < l; j++) {\n if (sizes[j].isDisabled == null || sizes[j].isDisabled == false) {\n sizeSelected = sizes[j];\n break;\n }\n }\n } else {\n sizeSelected = ctrl.sizeSelected;\n }\n\n return sizeSelected;\n }; //#endregion\n //#region carousels\n\n\n ctrl.addCarousel = function (carousel) {\n ctrl.carousel = carousel;\n\n if (ctrl.carouselDefer != null) {\n if (ctrl.carousel.options.asNavFor != null) {\n ctrl.carousel.whenAsNavForReady(ctrl.carousel.options.asNavFor, function () {\n ctrl.carouselDefer.resolve();\n delete ctrl.carouselDefer;\n });\n } else {\n ctrl.carouselDefer.resolve();\n delete ctrl.carouselDefer;\n }\n }\n };\n\n ctrl.getCarousel = function () {\n var defer = $q.defer();\n\n if (ctrl.carouselExist === true && ctrl.carousel == null) {\n ctrl.carouselDefer = defer;\n } else {\n defer.resolve();\n }\n\n return defer.promise;\n };\n\n ctrl.carouselItemSelect = function (carousel, item, index) {\n ctrl.setPreview(item.parameters);\n ctrl.updateModalPreview(item.parameters.originalPath);\n\n if (carousel != null && ctrl.carousel != null && carousel != ctrl.carousel) {\n ctrl.carousel.setItemSelect(index);\n } else if (ctrl.carouselPreview != null && carousel != ctrl.carouselPreview) {\n ctrl.carouselPreview.setItemSelect(index);\n }\n }; //#endregion\n //#region modal preview\n\n\n ctrl.carouselPreviewNext = function () {\n var items = ctrl.carouselPreview.getItems(),\n itemSelected,\n itemSelectedNew,\n newIndex;\n itemSelected = ctrl.carouselPreview.getSelectedItem() || (items != null ? items[0] : null);\n\n if (ctrl.carouselPreview.getSelectedItem() === items[items.length - 1]) {\n ctrl.carouselPreview.goto(0, false);\n newIndex = 0;\n } else {\n ctrl.carouselPreview.next();\n newIndex = itemSelected.carouselItemData.index + 1;\n }\n\n if (itemSelected != null) {\n itemSelectedNew = items[newIndex];\n\n if (itemSelectedNew) {\n ctrl.carouselPreview.setItemSelect(itemSelectedNew);\n ctrl.setPreview(itemSelectedNew.carouselItemData.parameters);\n ctrl.updateModalPreview(itemSelectedNew.carouselItemData.parameters.originalPath);\n }\n }\n };\n\n ctrl.carouselPreviewPrev = function () {\n var items = ctrl.carouselPreview.getItems(),\n itemSelected,\n itemSelectedNew,\n newIndex;\n itemSelected = ctrl.carouselPreview.getSelectedItem() || (items != null ? items[0] : null);\n\n if (ctrl.carouselPreview.getSelectedItem() === items[0]) {\n ctrl.carouselPreview.goto(items.length - 1, false);\n newIndex = items.length - 1;\n } else {\n ctrl.carouselPreview.prev();\n newIndex = itemSelected.carouselItemData.index - 1;\n }\n\n if (itemSelected != null) {\n itemSelectedNew = items[newIndex];\n\n if (itemSelectedNew) {\n ctrl.carouselPreview.setItemSelect(itemSelectedNew);\n ctrl.setPreview(itemSelectedNew.carouselItemData.parameters);\n ctrl.updateModalPreview(itemSelectedNew.carouselItemData.parameters.originalPath);\n }\n }\n };\n\n ctrl.addModalPictureCarousel = function (carouselPreview) {\n ctrl.carouselPreview = carouselPreview;\n };\n\n ctrl.carouselPreviewUpdate = function () {\n if (ctrl.carouselPreview != null) {\n ctrl.getDialog().then(function (modal) {\n if (modal.modalScope.isOpen === true) {\n ctrl.carouselPreview.update();\n }\n });\n }\n };\n\n ctrl.updateModalPreview = function (imgSrc) {\n productService.getPhoto(imgSrc).then(function (img) {\n $timeout(function () {\n ctrl.maxHeightModalPreview = ctrl.getMaxHeightModalPreview();\n ctrl.modalPreviewHeight = img.naturalHeight > ctrl.maxHeightModalPreview ? ctrl.maxHeightModalPreview : img.naturalHeight;\n }, 0);\n });\n };\n\n ctrl.modalPreviewCallbackOpen = function (modal) {\n ctrl.setPreviewByColorId(ctrl.offerSelected.Color != null ? ctrl.offerSelected.Color.ColorId : null, ctrl.filterPhotosEnable, ctrl.carouselPreview);\n $timeout(function () {\n ctrl.carouselPreviewUpdate();\n }, 100);\n };\n\n ctrl.modalPreviewCallbackClose = function (modal) {\n if (!('ontouchstart' in window)) {\n $window.removeEventListener(\"keydown\", ctrl.onKeydownBackForward);\n }\n };\n\n ctrl.modalPreviewOpen = function (event, picture) {\n event.preventDefault();\n event.stopPropagation();\n ctrl.modalPreviewState = 'load';\n ctrl.dialogOpen().then(function () {\n productService.getPhoto(picture == null ? ctrl.picture.originalPath : picture.originalPath).then(function (img) {\n $timeout(function () {\n ctrl.maxHeightModalPreview = ctrl.getMaxHeightModalPreview();\n ctrl.modalPreviewHeight = img.naturalHeight > ctrl.maxHeightModalPreview ? ctrl.maxHeightModalPreview : img.naturalHeight; //ctrl.carouselPreviewUpdate();\n\n ctrl.modalPreviewState = 'complete';\n\n if (ctrl.filterPhotosEnable === true && ctrl.carousel != null && picture != null) {\n ctrl.filterPhotos(ctrl.offerSelected.Color != null ? ctrl.offerSelected.Color.ColorId : null, ctrl.carousel, picture.PhotoId);\n }\n\n if (ctrl.carouselPreview != null) {\n var items = ctrl.carouselPreview.getItems();\n\n for (var i = 0; i < items.length; i++) {\n if (items[i].carouselItemData.parameters.PhotoId == picture.PhotoId) {\n ctrl.carouselPreview.setItemSelect(items[i]);\n ctrl.setPreview(items[i].carouselItemData.parameters);\n ctrl.updateModalPreview(items[i].carouselItemData.parameters.originalPath);\n break;\n }\n }\n }\n }, 0);\n });\n });\n };\n\n ctrl.getMaxHeightModalPreview = function () {\n var result = 0,\n height,\n modalElement,\n modaPreview = document.getElementById('modalPreview_' + ctrl.productId);\n\n if (modaPreview != null) {\n modalElement = modaPreview.querySelector('.modal-content');\n }\n\n if (modalElement != null) {\n height = parseFloat(getComputedStyle(modalElement).height);\n result = isNaN(height) === false ? height : 0;\n }\n\n return result;\n };\n\n ctrl.dialogOpen = function () {\n return ctrl.getDialog().then(function (modal) {\n if (!('ontouchstart' in window)) {\n $window.addEventListener(\"keydown\", ctrl.onKeydownBackForward);\n }\n\n modal.modalScope.open();\n return modal;\n });\n };\n\n ctrl.getDialog = function () {\n return modalService.getModal('modalPreview_' + ctrl.productId);\n };\n\n ctrl.resizeModalPreview = function () {\n $scope.$apply(function () {\n ctrl.updateModalPreview(ctrl.picture.originalPath);\n ctrl.carouselPreviewUpdate();\n });\n }; //#endregion\n //#region productViewChange\n\n\n ctrl.showVideo = function (visible) {\n ctrl.visibleVideo = visible;\n\n if (visible === false) {\n ctrl.videosInModalReceived = false;\n ctrl.carouselVideosInModalInit = false;\n }\n };\n\n ctrl.onReceiveVideosInModal = function () {\n ctrl.videosInModalReceived = true;\n };\n\n ctrl.onInitCarouselVideosInModal = function () {\n ctrl.carouselVideosInModalInit = true;\n };\n\n ctrl.showRotate = function (visible) {\n ctrl.visibleRotate = visible;\n }; //#endregion\n //#region shippingVariants\n\n\n ctrl.addShippingVariants = function (shippingVariants) {\n ctrl.shippingVariants = shippingVariants;\n }; //#endregion\n //#region spinbox amount\n\n\n ctrl.updateAmount = function (value, proxy) {\n //if (ctrl.shippingVariants != null) {\n // ctrl.shippingVariants.update();\n //}\n ctrl.refreshPrice();\n }; //#endregion\n\n\n ctrl.filterPhotosFunction = function (item, index) {\n return item != null && (item.carouselItemData.parameters.colorId == null || ctrl.offerSelected.Color == null || item.carouselItemData.parameters.colorId == ctrl.offerSelected.Color.ColorId);\n };\n\n ctrl.setPreviewByColorId = function (colorId, filterEnabled, carousel) {\n var findArray;\n\n if (ctrl.carousel) {\n if (filterEnabled === true) {\n ctrl.filterPhotos(colorId, carousel, ctrl.picture.PhotoId);\n } else {\n findArray = ctrl.carousel.items.filter(ctrl.filterPhotosFunction);\n\n if (findArray != null && findArray.length > 0) {\n ctrl.setPreview(findArray[0].carouselItemData.parameters);\n }\n }\n }\n };\n\n ctrl.filterPhotos = function (colorId, carousel, selectedPhotoId) {\n var selectedItem, items, oldItem;\n\n if (carousel) {\n oldItem = carousel.getActiveItem();\n items = carousel.filterItems(ctrl.filterPhotosFunction, colorId);\n /*if (selectedPhotoId != null) {\n items = carousel.getItems();\n for (var i = 0, len = items.length; i < len; i++) {\n if (items[i].carouselItemData.parameters.colorId === colorId) {\n carousel.setItemSelect(items[i]);\n findedSelected = true;\n break;\n }\n }\n }*/\n\n if (items == null || items.length === 0) {\n carousel.addItem(oldItem);\n }\n\n selectedItem = carousel.getActiveItem();\n\n if (selectedItem != null) {\n carousel.setItemSelect(selectedItem);\n ctrl.setPreview(selectedItem.carouselItemData.parameters);\n }\n }\n };\n\n ctrl.setView = function (viewName) {\n ctrl.productView = viewName;\n ctrl.stopVideo();\n };\n\n ctrl.setPreview = function (picture) {\n ctrl.picture = picture;\n };\n\n ctrl.getUrl = function (url) {\n var result = url,\n params = [];\n\n if (ctrl.colorsViewer != null && ctrl.colorsViewer.colorSelected != null) {\n params.push(\"color=\" + ctrl.colorsViewer.colorSelected.ColorId);\n }\n\n if (ctrl.sizesViewer != null && ctrl.sizesViewer.sizeSelected != null) {\n params.push(\"size=\" + ctrl.sizesViewer.sizeSelected.SizeId);\n }\n\n if (params.length > 0) {\n result = result + '?' + params.join('&');\n }\n\n return result;\n };\n\n ctrl.getCommentsCount = function () {\n productService.getReviewsCount(ctrl.productId).then(function (result) {\n if (result != null) {\n ctrl.reviewsCount = result.reviewsCount;\n }\n });\n };\n\n ctrl.addChangeSizeAndColorCallback = function (callback) {\n ctrl.changeSizeAndColorCallback = callback;\n };\n\n ctrl.onKeydownBackForward = function (e) {\n if (e.code === \"ArrowRight\") {\n ctrl.carouselPreviewNext();\n }\n\n if (e.code === \"ArrowLeft\") {\n ctrl.carouselPreviewPrev();\n }\n };\n};\n\nProductCtrl.$inject = [\"$q\", \"$scope\", \"$sce\", \"$timeout\", \"productService\", \"modalService\", \"toaster\", \"$translate\", \"$window\", \"urlHelper\"];\nexport default ProductCtrl;","import uiBootstrapModule from '../../vendors/ui-bootstrap-custom/ui-bootstrap.module.js';\nimport carouselModule from '../_common/carousel/carousel.module.js';\nimport ratingModule from '../_common/rating/rating.module.js';\nimport rotateModule from '../_common/rotate/rotate.module.js';\nimport videosModule from '../_partials/videos/videos.module.js';\nimport zoomerModule from '../_common/zoomer/zoomer.module.js';\nimport productViewModule from '../_partials/product-view/productView.module.js';\nimport customOptionsModule from '../_partials/custom-options/customOptions.module.js';\nimport colorsViewerModule from '../_partials/colors-viewer/colorsViewer.module.js';\nimport sizesViewerModule from '../_partials/sizes-viewer/sizesViewer.module.js';\nimport buyOneClickModule from '../_partials/buy-one-click/buyOneClick.module.js';\nimport tabsModule from '../_common/tabs/tabs.module.js';\nimport compareModule from '../_partials/compare/compare.module.js';\nimport reviewsModule from '../_partials/reviews/reviews.module.js';\nimport shippingModule from '../_partials/shipping/shipping.module.js';\nimport '../../styles/partials/gallery.scss';\nimport '../../styles/partials/product-color.scss';\nimport '../../styles/partials/properties.scss';\nimport '../../styles/partials/social-share42.scss';\nimport '../../styles/views/product.scss';\nimport ProductCtrl from './controllers/productController.js';\nimport productService from './services/productService.js';\nimport '../_common/urlHelper/urlHelperService.module.js';\nvar moduleName = 'product';\nvar deps = [uiBootstrapModule, tabsModule, ratingModule, carouselModule, productViewModule, rotateModule, compareModule, customOptionsModule, colorsViewerModule, sizesViewerModule, zoomerModule, reviewsModule, shippingModule, buyOneClickModule, videosModule, 'urlHelper'];\nangular.module(moduleName, deps).controller('ProductCtrl', ProductCtrl).service('productService', productService);\nexport default moduleName;","productService.$inject = [\"$http\", \"$q\", \"modalService\"];\n\n/* @ngInject */\nfunction productService($http, $q, modalService) {\n var service = this,\n _product,\n callbacks = {};\n\n service.getOffers = function (productId, colorId, sizeId) {\n return $http.get('productExt/getoffers', {\n params: {\n productId: productId,\n colorId: colorId,\n sizeId: sizeId\n }\n }).then(function (response) {\n return response.data;\n });\n };\n\n service.findOfferSelected = function (offers, offerIdSelected) {\n var offer;\n\n for (var i = offers.length - 1; i >= 0; i--) {\n if (offers[i].OfferId === offerIdSelected) {\n offer = offers[i];\n break;\n }\n }\n\n return offer;\n };\n\n service.findOffersByColorId = function (offers, colorId) {\n return offers.filter(function (item) {\n return colorId != null && item.Color != null && item.Color.ColorId === colorId;\n });\n };\n\n service.findOffersBySizeId = function (offers, sizeId) {\n return offers.filter(function (item) {\n return sizeId != null && item.Size != null && item.Size.SizeId === sizeId;\n });\n };\n\n service.getOffer = function (offers, colorId, sizeId, allowPreOrder) {\n var arrayOffers = offers.slice(),\n arrayOffersByColor = [],\n arrayOffersBySize = [],\n stopLoop = false,\n offer;\n arrayOffersByColor = service.findOffersByColorId(arrayOffers, colorId);\n arrayOffersBySize = service.findOffersBySizeId(arrayOffers, sizeId);\n\n if (arrayOffersByColor.length > 0 && arrayOffersBySize.length > 0) {\n for (var i = 0, lenC = arrayOffersByColor.length; i < lenC; i++) {\n for (var j = 0, lenS = arrayOffersBySize.length; j < lenS; j++) {\n if (arrayOffersByColor[i].OfferId === arrayOffersBySize[j].OfferId) {\n offer = arrayOffersByColor[i];\n stopLoop = true;\n break;\n }\n }\n\n if (stopLoop === true) {\n break;\n }\n }\n }\n\n if (offer == null && arrayOffersByColor.length > 0) {\n offer = arrayOffersByColor[0];\n }\n\n if (offer == null && arrayOffersBySize.length > 0) {\n offer = arrayOffersBySize[0];\n }\n\n return offer;\n };\n\n service.getPrice = function (offerId, attributesXml, lpBlockId) {\n return $http.post('productExt/getofferprice', {\n offerId: offerId,\n attributesXml: attributesXml,\n lpBlockId: lpBlockId\n }).then(function (response) {\n return response.data;\n });\n };\n\n service.getFirstPaymentPrice = function (price, discount, discountAmount) {\n return $http.get('productExt/getfirstpaymentprice', {\n params: {\n price: price,\n discount: discount,\n discountAmount: discountAmount\n }\n }).then(function (response) {\n return response.data;\n });\n };\n\n service.getShippings = function (offerId) {\n return $http.get('productExt/getshippings', {\n params: {\n offerId: offerId\n }\n }).then(function (response) {\n return response.data;\n });\n };\n\n service.addCallback = function (name, func) {\n callbacks[name] = callbacks[name] || [];\n callbacks[name].push(func);\n };\n\n service.processCallback = function (name, data) {\n var arrFunc = callbacks[name];\n\n if (arrFunc != null && arrFunc.length > 0) {\n for (var i = 0, len = arrFunc.length; i < len; i++) {\n arrFunc[i](data);\n }\n }\n\n ;\n };\n\n service.getPhoto = function (url) {\n var defered = $q.defer(),\n img = new Image();\n img.src = url;\n\n if (img.complete == true || typeof img.naturalWidth !== \"undefined\" && img.naturalWidth > 0) {\n defered.resolve(img);\n } else {\n img.onload = function (e) {\n defered.resolve(img);\n };\n }\n\n return defered.promise.then(function (response) {\n return response;\n });\n };\n\n service.addToStorage = function (product) {\n _product = product;\n };\n\n service.getProduct = function () {\n return _product;\n };\n\n service.getReviewsCount = function (productId) {\n return $http.get('productExt/getReviewsCount', {\n params: {\n productId: productId\n }\n }).then(function (response) {\n return response.data;\n });\n };\n}\n\n;\nexport default productService;","/*!\n * 360 degree Image Slider v2.0.4\n * http://gaurav.jassal.me\n *\n * Copyright 2015, gaurav@jassal.me\n * Dual licensed under the MIT or GPL Version 3 licenses.\n *\n */\n(function ($) {\n 'use strict';\n /**\n * @class ThreeSixty\n * **The ThreeSixty slider class**.\n *\n * This as jQuery plugin to create 360 degree product image slider.\n * The plugin is full customizable with number of options provided. The plugin\n * have the power to display images in any angle 360 degrees. This feature can be\n * used successfully in many use cases e.g. on an e-commerce site to help customers\n * look products in detail, from any angle they desire.\n *\n * **Features**\n *\n * - Smooth Animation\n * - Plenty of option parameters for customization\n * - Api interaction\n * - Simple mouse interaction\n * - Custom behavior tweaking\n * - Support for touch devices\n * - Easy to integrate\n * - No flash\n *\n * Example code:\n * var product1 = $('.product1').ThreeSixty({\n * totalFrames: 72,\n * endFrame: 72,\n * currentFrame: 1,\n * imgList: '.threesixty_images',\n * progress: '.spinner',\n * imagePath:'/assets/product1/',\n * filePrefix: 'ipod-',\n * ext: '.jpg',\n * height: 265,\n * width: 400,\n * navigation: true\n * });\n * **Note:** There are loads other options that you can override to customize\n * this plugin.\n * @extends jQuery\n * @singleton\n * @param {String} [el] jQuery selector string for the parent container\n * @param {Object} [options] An optional config object\n *\n * @return this\n */\n\n $.ThreeSixty = function (el, options) {\n // To avoid scope issues, use 'base' instead of 'this'\n // to reference this class from internal events and functions.\n var base = this,\n AppConfig,\n frames = [],\n VERSION = '2.0.5'; // Access to jQuery and DOM versions of element\n\n /**\n * @property {$el}\n * jQuery Dom node attached to the slider inherits all jQuery public functions.\n */\n\n base.$el = $(el);\n base.el = el; // Add a reverse reference to the DOM object\n\n base.$el.data('ThreeSixty', base);\n /**\n * @method init\n * The function extends the user options with default settings for the\n * slider and initilize the slider.\n * **Style Override example**\n *\n * var product1 = $('.product1').ThreeSixty({\n * totalFrames: 72,\n * endFrame: 72,\n * currentFrame: 1,\n * imgList: '.threesixty_images',\n * progress: '.spinner',\n * imagePath:'/assets/product1/',\n * filePrefix: 'ipod-',\n * ext: '.jpg',\n * height: 265,\n * width: 400,\n * navigation: true,\n * styles: {\n * border: 2px solide #b4b4b4,\n * background: url(http://example.com/images/loader.gif) no-repeat\n * }\n * });\n */\n\n base.init = function () {\n AppConfig = $.extend({}, $.ThreeSixty.defaultOptions, options);\n\n if (AppConfig.disableSpin) {\n AppConfig.currentFrame = 1;\n AppConfig.endFrame = 1;\n }\n\n base.initProgress();\n base.loadImages();\n };\n /*\n * Function to resize the height of responsive slider.\n */\n\n\n base.resize = function () {// calculate height\n };\n /**\n * @method initProgress\n * The function sets initial styles and start the progress indicator\n * to show loading of images.\n *\n * @private\n */\n\n\n base.initProgress = function () {\n base.$el.css({\n width: AppConfig.width + 'px',\n height: AppConfig.height + 'px',\n 'background-image': 'none !important'\n });\n\n if (AppConfig.styles) {\n base.$el.css(AppConfig.styles);\n }\n\n base.responsive();\n base.$el.find(AppConfig.progress).css({\n marginTop: AppConfig.height / 2 - 15 + 'px'\n });\n base.$el.find(AppConfig.progress).fadeIn('slow');\n base.$el.find(AppConfig.imgList).hide();\n };\n /**\n * @method loadImages\n * @private\n * The function asynchronously loads images and inject into the slider.\n */\n\n\n base.loadImages = function () {\n var li, imageName, image, host, baseIndex;\n li = document.createElement('li');\n baseIndex = AppConfig.zeroBased ? 0 : 1;\n imageName = !AppConfig.imgArray ? AppConfig.domain + AppConfig.imagePath + AppConfig.filePrefix + base.zeroPad(AppConfig.loadedImages + baseIndex) + AppConfig.ext + (base.browser.isIE() ? '?' + new Date().getTime() : '') : AppConfig.imgArray[AppConfig.loadedImages];\n image = $('').attr('src', imageName).addClass('previous-image').appendTo(li);\n frames.push(image);\n base.$el.find(AppConfig.imgList).append(li);\n $(image).on(\"load\", function () {\n base.imageLoaded();\n });\n };\n /**\n * @method loadImages\n * @private\n * The function gets triggers once the image is loaded. We also update\n * the progress percentage in this function.\n */\n\n\n base.imageLoaded = function () {\n AppConfig.loadedImages += 1;\n $(AppConfig.progress + ' span').text(Math.floor(AppConfig.loadedImages / AppConfig.totalFrames * 100) + '%');\n\n if (AppConfig.loadedImages >= AppConfig.totalFrames) {\n if (AppConfig.disableSpin) {\n frames[0].removeClass('previous-image').addClass('current-image');\n }\n\n $(AppConfig.progress).fadeOut('slow', function () {\n $(this).hide();\n base.showImages();\n base.showNavigation();\n });\n } else {\n base.loadImages();\n }\n };\n /**\n * @method loadImages\n * @private\n * This function is called when all the images are loaded.\n * **The function does following operations**\n * - Removes background image placeholder\n * - Displays the 360 images\n * - Initilizes mouse intraction events\n */\n\n\n base.showImages = function () {\n base.$el.find('.txtC').fadeIn();\n base.$el.find(AppConfig.imgList).fadeIn();\n base.ready = true;\n AppConfig.ready = true;\n\n if (AppConfig.drag) {\n base.initEvents();\n }\n\n base.refresh();\n base.initPlugins();\n AppConfig.onReady();\n setTimeout(function () {\n base.responsive();\n }, 50);\n };\n /**\n * The function to initilize external plugin\n */\n\n\n base.initPlugins = function () {\n $.each(AppConfig.plugins, function (i, plugin) {\n if (typeof $[plugin] === 'function') {\n $[plugin].call(base, base.$el, AppConfig);\n } else {\n throw new Error(plugin + ' not available.');\n }\n });\n };\n /**\n * @method showNavigation\n * Creates a navigation panel if navigation is set to true in the\n * settings.\n */\n\n\n base.showNavigation = function () {\n if (AppConfig.navigation && !AppConfig.navigation_init) {\n var nav_bar, next, previous, play_stop;\n nav_bar = $('
    ').attr('class', 'nav_bar');\n next = $('').attr({\n 'href': '#',\n 'class': 'nav_bar_next'\n }).html('next');\n previous = $('').attr({\n 'href': '#',\n 'class': 'nav_bar_previous'\n }).html('previous');\n play_stop = $('').attr({\n 'href': '#',\n 'class': 'nav_bar_play'\n }).html('play');\n nav_bar.append(previous);\n nav_bar.append(play_stop);\n nav_bar.append(next);\n base.$el.prepend(nav_bar);\n next.bind('mousedown touchstart', base.next);\n previous.bind('mousedown touchstart', base.previous);\n play_stop.bind('mousedown touchstart', base.play_stop);\n AppConfig.navigation_init = true;\n }\n };\n /**\n * @method play_stop\n * @private\n * Function toggles the autoplay rotation of 360 slider\n * @param {Object} [event] jQuery events object.\n *\n */\n\n\n base.play_stop = function (event) {\n event.preventDefault();\n\n if (!AppConfig.autoplay) {\n AppConfig.autoplay = true;\n AppConfig.play = setInterval(base.moveToNextFrame, AppConfig.playSpeed);\n $(event.currentTarget).removeClass('nav_bar_play').addClass('nav_bar_stop');\n } else {\n AppConfig.autoplay = false;\n $(event.currentTarget).removeClass('nav_bar_stop').addClass('nav_bar_play');\n clearInterval(AppConfig.play);\n AppConfig.play = null;\n }\n };\n /**\n * @method next\n * Using this function you can rotate 360 to next 5 frames.\n * @param {Object} [event] jQuery events object.\n *\n */\n\n\n base.next = function (event) {\n if (event) {\n event.preventDefault();\n }\n\n AppConfig.endFrame -= 5;\n base.refresh();\n };\n /**\n * @method previous\n * Using this function you can rotate 360 to previous 5 frames.\n * @param {Object} [event] jQuery events object.\n *\n */\n\n\n base.previous = function (event) {\n if (event) {\n event.preventDefault();\n }\n\n AppConfig.endFrame += 5;\n base.refresh();\n };\n /**\n * @method play\n * You are start the auto rotaion for the slider with this function.\n *\n */\n\n\n base.play = function (speed) {\n var _speed = speed || AppConfig.playSpeed;\n\n if (!AppConfig.autoplay) {\n AppConfig.autoplay = true;\n AppConfig.play = setInterval(base.moveToNextFrame, _speed);\n }\n };\n /**\n * @method stop\n * You can stop the auto rotation of the 360 slider with this function.\n *\n */\n\n\n base.stop = function () {\n if (AppConfig.autoplay) {\n AppConfig.autoplay = false;\n clearInterval(AppConfig.play);\n AppConfig.play = null;\n }\n };\n /**\n * @method endFrame\n * @private\n * Function animates to previous frame\n *\n */\n\n\n base.moveToNextFrame = function () {\n if (AppConfig.autoplayDirection === 1) {\n AppConfig.endFrame -= 1;\n } else {\n AppConfig.endFrame += 1;\n }\n\n base.refresh();\n };\n /**\n * @method gotoAndPlay\n * @public\n * Function animates to previous frame\n *\n */\n\n\n base.gotoAndPlay = function (n) {\n if (AppConfig.disableWrap) {\n AppConfig.endFrame = n;\n base.refresh();\n } else {\n // Since we could be looped around grab the multiplier\n var multiplier = Math.ceil(AppConfig.endFrame / AppConfig.totalFrames);\n\n if (multiplier === 0) {\n multiplier = 1;\n } // Figure out the quickest path to the requested frame\n\n\n var realEndFrame = multiplier > 1 ? AppConfig.endFrame - (multiplier - 1) * AppConfig.totalFrames : AppConfig.endFrame;\n var currentFromEnd = AppConfig.totalFrames - realEndFrame; // Jump past end if it's faster\n\n var newEndFrame = 0;\n\n if (n - realEndFrame > 0) {\n // Faster to move the difference ahead?\n if (n - realEndFrame < realEndFrame + (AppConfig.totalFrames - n)) {\n newEndFrame = AppConfig.endFrame + (n - realEndFrame);\n } else {\n newEndFrame = AppConfig.endFrame - (realEndFrame + (AppConfig.totalFrames - n));\n }\n } else {\n // Faster to move the distance back?\n if (realEndFrame - n < currentFromEnd + n) {\n newEndFrame = AppConfig.endFrame - (realEndFrame - n);\n } else {\n newEndFrame = AppConfig.endFrame + (currentFromEnd + n);\n }\n } // Now set the end frame\n\n\n if (realEndFrame !== n) {\n AppConfig.endFrame = newEndFrame;\n base.refresh();\n }\n }\n };\n /**\n * @method initEvents\n * @private\n * Function initilizes all the mouse and touch events for 360 slider movement.\n *\n */\n\n\n base.initEvents = function () {\n addListenerMulti(base.$el[0], 'touchstart touchmove touchend', function (event) {\n recognizeTypeEvent(event);\n }, {\n passive: true\n });\n base.$el.bind('mousedown mousemove click', function (event) {\n event.preventDefault();\n recognizeTypeEvent(event);\n });\n\n function addListenerMulti(element, eventNames, listener) {\n var events = eventNames.split(' ');\n\n for (var i = 0, iLen = events.length; i < iLen; i++) {\n element.addEventListener(events[i], listener, false);\n }\n }\n\n function recognizeTypeEvent(event) {\n if (event.type === 'mousedown' && event.which === 1 || event.type === 'touchstart') {\n AppConfig.pointerStartPosX = base.getPointerEvent(event).pageX;\n AppConfig.dragging = true;\n } else if (event.type === 'touchmove') {\n base.trackPointer(event);\n } else if (event.type === 'touchend') {\n AppConfig.dragging = false;\n }\n }\n\n ;\n $(document).bind('mouseup', function (event) {\n //event.preventDefault();\n AppConfig.dragging = false;\n $(this).css('cursor', 'none');\n });\n $(window).bind('resize', function (event) {\n base.responsive();\n });\n $(document).bind('mousemove', function (event) {\n if (AppConfig.dragging) {\n event.preventDefault();\n\n if (!base.browser.isIE && AppConfig.showCursor) {\n base.$el.css('cursor', 'url(assets/images/hand_closed.png), auto');\n }\n } else {\n if (!base.browser.isIE && AppConfig.showCursor) {\n base.$el.css('cursor', 'url(assets/images/hand_open.png), auto');\n }\n }\n\n base.trackPointer(event);\n });\n $(window).resize(function () {\n base.resize();\n });\n };\n /**\n * @method getPointerEvent\n * @private\n * Function returns touch pointer events\n *\n * @params {Object} [event]\n */\n\n\n base.getPointerEvent = function (event) {\n var targetTouches = event.originalEvent ? event.originalEvent.targetTouches : event.targetTouches;\n return targetTouches ? targetTouches[0] : event;\n };\n /**\n * @method trackPointer\n * @private\n * Function calculates the distance between the start pointer and end pointer/\n *\n * @params {Object} [event]\n */\n\n\n base.trackPointer = function (event) {\n if (AppConfig.ready && AppConfig.dragging) {\n AppConfig.pointerEndPosX = base.getPointerEvent(event).pageX;\n\n if (AppConfig.monitorStartTime < new Date().getTime() - AppConfig.monitorInt) {\n AppConfig.pointerDistance = AppConfig.pointerEndPosX - AppConfig.pointerStartPosX;\n\n if (AppConfig.pointerDistance > 0) {\n AppConfig.endFrame = AppConfig.currentFrame + Math.ceil((AppConfig.totalFrames - 1) * AppConfig.speedMultiplier * (AppConfig.pointerDistance / base.$el.width()));\n } else {\n AppConfig.endFrame = AppConfig.currentFrame + Math.floor((AppConfig.totalFrames - 1) * AppConfig.speedMultiplier * (AppConfig.pointerDistance / base.$el.width()));\n }\n\n if (AppConfig.disableWrap) {\n AppConfig.endFrame = Math.min(AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0), AppConfig.endFrame);\n AppConfig.endFrame = Math.max(AppConfig.zeroBased ? 0 : 1, AppConfig.endFrame);\n }\n\n base.refresh();\n AppConfig.monitorStartTime = new Date().getTime();\n AppConfig.pointerStartPosX = base.getPointerEvent(event).pageX;\n }\n }\n };\n /**\n * @method refresh\n * @public\n * Function refeshes the timer and set interval for render cycle.\n *\n */\n\n\n base.refresh = function () {\n if (AppConfig.ticker === 0) {\n AppConfig.ticker = setInterval(base.render, Math.round(1000 / AppConfig.framerate));\n }\n };\n /**\n * @method refresh\n * @private\n * Function render the animation frames on the screen with easing effect.\n */\n\n\n base.render = function () {\n var frameEasing;\n\n if (AppConfig.currentFrame !== AppConfig.endFrame) {\n frameEasing = AppConfig.endFrame < AppConfig.currentFrame ? Math.floor((AppConfig.endFrame - AppConfig.currentFrame) * 0.1) : Math.ceil((AppConfig.endFrame - AppConfig.currentFrame) * 0.1);\n base.hidePreviousFrame();\n AppConfig.currentFrame += frameEasing;\n base.showCurrentFrame();\n base.$el.trigger('frameIndexChanged', [base.getNormalizedCurrentFrame(), AppConfig.totalFrames]);\n } else {\n window.clearInterval(AppConfig.ticker);\n AppConfig.ticker = 0;\n }\n };\n /**\n * @method hidePreviousFrame\n * @private\n * Function hide the previous frame in the animation loop.\n */\n\n\n base.hidePreviousFrame = function () {\n frames[base.getNormalizedCurrentFrame()].removeClass('current-image').addClass('previous-image');\n };\n /**\n * @method showCurrentFrame\n * @private\n * Function shows the current frame in the animation loop.\n */\n\n\n base.showCurrentFrame = function () {\n frames[base.getNormalizedCurrentFrame()].removeClass('previous-image').addClass('current-image');\n };\n /**\n * @method getNormalizedCurrentFrame\n * @private\n * Function normalize and calculate the current frame once the user release the mouse and release touch event.\n */\n\n\n base.getNormalizedCurrentFrame = function () {\n var c, e;\n\n if (!AppConfig.disableWrap) {\n c = Math.ceil(AppConfig.currentFrame % AppConfig.totalFrames);\n\n if (c < 0) {\n c += AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0);\n }\n } else {\n c = Math.min(AppConfig.currentFrame, AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0));\n e = Math.min(AppConfig.endFrame, AppConfig.totalFrames - (AppConfig.zeroBased ? 1 : 0));\n c = Math.max(c, AppConfig.zeroBased ? 0 : 1);\n e = Math.max(e, AppConfig.zeroBased ? 0 : 1);\n AppConfig.currentFrame = c;\n AppConfig.endFrame = e;\n }\n\n return c;\n };\n /*\n * @method getCurrentFrame\n * Function returns the current active frame.\n *\n * @return Number\n */\n\n\n base.getCurrentFrame = function () {\n return AppConfig.currentFrame;\n };\n /*\n * @method responsive\n * Function calculates and set responsive height and width\n *\n */\n\n\n base.responsive = function () {\n if (AppConfig.responsive) {\n base.$el.css({\n height: base.$el.find('.current-image').first().css('height'),\n width: '100%'\n });\n }\n };\n /**\n * Function to return with zero padding.\n */\n\n\n base.zeroPad = function (num) {\n function pad(number, length) {\n var str = number.toString();\n\n if (AppConfig.zeroPadding) {\n while (str.length < length) {\n str = '0' + str;\n }\n }\n\n return str;\n }\n\n var approximateLog = Math.log(AppConfig.totalFrames) / Math.LN10;\n var roundTo = 1e3;\n var roundedLog = Math.round(approximateLog * roundTo) / roundTo;\n var numChars = Math.floor(roundedLog) + 1;\n return pad(num, numChars);\n };\n\n base.browser = {};\n /**\n * Function to detect if the brower is IE\n * @return {boolean}\n *\n * http://msdn.microsoft.com/en-gb/library/ms537509(v=vs.85).aspx\n */\n\n base.browser.isIE = function () {\n var rv = -1;\n\n if (navigator.appName === 'Microsoft Internet Explorer') {\n var ua = navigator.userAgent;\n var re = new RegExp('MSIE ([0-9]{1,}[\\\\.0-9]{0,})');\n\n if (re.exec(ua) !== null) {\n rv = parseFloat(RegExp.$1);\n }\n }\n\n return rv !== -1;\n };\n /**\n * @method getConfig\n * The function returns the extended version of config object the plugin is going to\n * user.\n *\n * @public\n *\n * @return Object\n */\n\n\n base.getConfig = function () {\n return AppConfig;\n };\n\n $.ThreeSixty.defaultOptions = {\n /**\n * @cfg {Boolean} dragging [dragging=false]\n * @private\n * Private propery contains a flags if users is in dragging mode.\n */\n dragging: false,\n\n /**\n * @cfg {Boolean} ready [ready=false]\n * @private\n * Private propery is set to true is all assets are loading and application is\n * ready to render 360 slider.\n */\n ready: false,\n\n /**\n * @cfg {Number} pointerStartPosX\n * @private\n * private property mouse pointer start x position when user starts dragging slider.\n */\n pointerStartPosX: 0,\n\n /**\n * @cfg {Number} pointerEndPosX\n * @private\n * private property mouse pointer start x position when user end dragging slider.\n */\n pointerEndPosX: 0,\n\n /**\n * @cfg {Number} pointerDistance\n * @private\n * private property contains the distance between the pointerStartPosX and pointerEndPosX\n */\n pointerDistance: 0,\n\n /**\n * @cfg {Number} monitorStartTime\n * @private\n * private property contains time user took in dragging mouse from pointerStartPosX and pointerEndPosX\n */\n monitorStartTime: 0,\n monitorInt: 10,\n\n /**\n * @cfg {Number} ticker\n * @private\n * Timer event that renders the 360\n */\n ticker: 0,\n\n /**\n * @cfg {Number} speedMultiplier\n * This property controls the sensitivity for the 360 slider\n */\n speedMultiplier: 7,\n\n /**\n * @cfg {Number} totalFrames\n * Set total number for frames used in the 360 rotation\n */\n totalFrames: 180,\n\n /**\n * @cfg {Number} currentFrame\n * Current frame of the slider.\n */\n currentFrame: 0,\n\n /**\n * @cfg {Array} endFrame\n * Private perperty contains information about the end frame when user slides the slider.\n */\n endFrame: 0,\n\n /**\n * @cfg {Number} loadedImages\n * Private property contains count of loaded images.\n */\n loadedImages: 0,\n\n /**\n * @cfg {Array} framerate\n * Set framerate for the slider animation\n */\n framerate: 60,\n\n /**\n * @cfg {String} domains\n * Set comma seprated list of all parallel domain from where 360 assets needs to be loaded.\n */\n domains: null,\n\n /**\n * @cfg {String} domain\n * Domain from where assets needs to be loaded. Use this propery is you want to load all assets from\n * single domain.\n */\n domain: '',\n\n /**\n * @cfg {Boolean} parallel\n * Set to true if you want to load assets from parallel domain. Default false\n */\n parallel: false,\n\n /**\n * @cfg {Number} queueAmount\n * Set number of calls to be made on parallel domains.\n */\n queueAmount: 8,\n\n /**\n * @cfg {Number} idle\n * Mouse Inactivite idle time in seconds. If set more than 0 will auto spine the slider\n */\n idle: 0,\n\n /**\n * @cfg {String} filePrefix\n * Prefix for the image file name before the numeric value.\n */\n filePrefix: '',\n\n /**\n * @cfg {String} ext [ext=.png]\n * Slider image extension.\n */\n ext: 'png',\n\n /**\n * @cfg {Object} height [300]\n * Height of the slider\n */\n height: 300,\n\n /**\n * @cfg {Number} width [300]\n * Width of the slider\n */\n width: 300,\n\n /**\n * @cfg {Object} styles\n * CSS Styles for the 360 slider\n */\n styles: {},\n\n /**\n * @cfg {Boolean} navigation[false]\n * State if navigation controls are visible or not.\n */\n navigation: false,\n\n /**\n * @cfg {Boolean} autoplay[false]\n * Autoplay the 360 animation\n */\n autoplay: false,\n\n /**\n * @cfg {number} autoplayDirection [1]\n * Direction for autoplay the 360 animation. 1 for right spin, and -1 for left spin.\n */\n autoplayDirection: 1,\n\n /**\n * Property to disable auto spin\n * @type {Boolean}\n */\n disableSpin: false,\n\n /**\n * Property to disable infinite wrap\n * @type {Boolean}\n */\n disableWrap: false,\n\n /**\n * Responsive width\n * @type {Boolean}\n */\n responsive: false,\n\n /**\n * Zero Padding for filenames\n * @type {Boolean}\n */\n zeroPadding: false,\n\n /**\n * Zero based for image filenames starting at 0\n * @type {Boolean}\n */\n zeroBased: false,\n\n /**\n * @type {Array}\n * List of plugins\n */\n plugins: [],\n\n /**\n * @type {Boolean}\n * Show hand cursor on drag\n */\n showCursor: false,\n\n /**\n * @cfg {Boolean} drag\n * Set it to false if you want to disable mousedrag or touch events\n */\n drag: true,\n\n /**\n * @cfg {Function} onReady\n * Callback triggers once all images are loaded and ready to render on the screen\n */\n onReady: function onReady() {},\n\n /**\n * @cfg {String} imgList\n * Set ul element where image will be loaded\n */\n imgList: '.threesixty_images',\n\n /**\n * @cfg {Array} imgArray\n * Use set of images in array to load images\n */\n imgArray: null,\n\n /**\n * @cfg {Number} playSpeed\n * Value to control the speed of play button rotation\n */\n playSpeed: 100\n };\n base.init();\n };\n\n $.fn.ThreeSixty = function (options) {\n return Object.create(new $.ThreeSixty(this, options));\n };\n})(jQuery);\n/**\n *\n * Object.create method for perform as a fallback if method not available.\n * The syntax just takes away the illusion that JavaScript uses Classical Inheritance.\n */\n\n\nif (typeof Object.create !== 'function') {\n Object.create = function (o) {\n 'use strict';\n\n function F() {}\n\n F.prototype = o;\n return new F();\n };\n}","/*\n * angular-ui-bootstrap\n * http://angular-ui.github.io/bootstrap/\n\n * Version: 2.5.0 - 2017-01-28\n * License: MIT\n */\nangular.module(\"ui.bootstrap\", [\"ui.bootstrap.tpls\", \"ui.bootstrap.tooltip\", \"ui.bootstrap.position\", \"ui.bootstrap.stackedMap\", \"ui.bootstrap.popover\"]);\nangular.module(\"ui.bootstrap.tpls\", [\"uib/template/tooltip/tooltip-html-popup.html\", \"uib/template/tooltip/tooltip-popup.html\", \"uib/template/tooltip/tooltip-template-popup.html\", \"uib/template/popover/popover-html.html\", \"uib/template/popover/popover-template.html\", \"uib/template/popover/popover.html\"]);\n/**\n * The following features are still outstanding: animation as a\n * function, placement as a function, inside, support for more triggers than\n * just mouse enter/leave, html tooltips, and selector delegation.\n */\n\nangular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.stackedMap'])\n/**\n * The $tooltip service creates tooltip- and popover-like directives as well as\n * houses global options for them.\n */\n.provider('$uibTooltip', function () {\n // The default options tooltip and popover.\n var defaultOptions = {\n placement: 'top',\n placementClassPrefix: '',\n animation: true,\n popupDelay: 0,\n popupCloseDelay: 0,\n useContentExp: false\n }; // Default hide triggers for each show trigger\n\n var triggerMap = {\n 'mouseenter': 'mouseleave',\n 'click': 'click',\n 'outsideClick': 'outsideClick',\n 'focus': 'blur',\n 'none': ''\n }; // The options specified to the provider globally.\n\n var globalOptions = {};\n /**\n * `options({})` allows global configuration of all tooltips in the\n * application.\n *\n * var app = angular.module( 'App', ['ui.bootstrap.tooltip'], function( $tooltipProvider ) {\n * // place tooltips left instead of top by default\n * $tooltipProvider.options( { placement: 'left' } );\n * });\n */\n\n this.options = function (value) {\n angular.extend(globalOptions, value);\n };\n /**\n * This allows you to extend the set of trigger mappings available. E.g.:\n *\n * $tooltipProvider.setTriggers( { 'openTrigger': 'closeTrigger' } );\n */\n\n\n this.setTriggers = function setTriggers(triggers) {\n angular.extend(triggerMap, triggers);\n };\n /**\n * This is a helper function for translating camel-case to snake_case.\n */\n\n\n function snake_case(name) {\n var regexp = /[A-Z]/g;\n var separator = '-';\n return name.replace(regexp, function (letter, pos) {\n return (pos ? separator : '') + letter.toLowerCase();\n });\n }\n /**\n * Returns the actual instance of the $tooltip service.\n * TODO support multiple triggers\n */\n\n\n this.$get = ['$window', '$compile', '$timeout', '$document', '$uibPosition', '$interpolate', '$rootScope', '$parse', '$$stackedMap', function ($window, $compile, $timeout, $document, $position, $interpolate, $rootScope, $parse, $$stackedMap) {\n var openedTooltips = $$stackedMap.createNew();\n $document.on('keyup', keypressListener);\n $rootScope.$on('$destroy', function () {\n $document.off('keyup', keypressListener);\n });\n\n function keypressListener(e) {\n if (e.which === 27) {\n var last = openedTooltips.top();\n\n if (last) {\n last.value.close();\n last = null;\n }\n }\n }\n\n return function $tooltip(ttType, prefix, defaultTriggerShow, options) {\n options = angular.extend({}, defaultOptions, globalOptions, options);\n /**\n * Returns an object of show and hide triggers.\n *\n * If a trigger is supplied,\n * it is used to show the tooltip; otherwise, it will use the `trigger`\n * option passed to the `$tooltipProvider.options` method; else it will\n * default to the trigger supplied to this directive factory.\n *\n * The hide trigger is based on the show trigger. If the `trigger` option\n * was passed to the `$tooltipProvider.options` method, it will use the\n * mapped trigger from `triggerMap` or the passed trigger if the map is\n * undefined; otherwise, it uses the `triggerMap` value of the show\n * trigger; else it will just use the show trigger.\n */\n\n function getTriggers(trigger) {\n var show = (trigger || options.trigger || defaultTriggerShow).split(' ');\n var hide = show.map(function (trigger) {\n return triggerMap[trigger] || trigger;\n });\n return {\n show: show,\n hide: hide\n };\n }\n\n var directiveName = snake_case(ttType);\n var startSym = $interpolate.startSymbol();\n var endSym = $interpolate.endSymbol();\n var template = '
    ' + '
    ';\n return {\n compile: function compile(tElem, tAttrs) {\n var tooltipLinker = $compile(template);\n return function link(scope, element, attrs, tooltipCtrl) {\n var tooltip;\n var tooltipLinkedScope;\n var transitionTimeout;\n var showTimeout;\n var hideTimeout;\n var positionTimeout;\n var adjustmentTimeout;\n var appendToBody = angular.isDefined(options.appendToBody) ? options.appendToBody : false;\n var triggers = getTriggers(undefined);\n var hasEnableExp = angular.isDefined(attrs[prefix + 'Enable']);\n var ttScope = scope.$new(true);\n var repositionScheduled = false;\n var isOpenParse = angular.isDefined(attrs[prefix + 'IsOpen']) ? $parse(attrs[prefix + 'IsOpen']) : false;\n var contentParse = options.useContentExp ? $parse(attrs[ttType]) : false;\n var observers = [];\n var lastPlacement;\n\n var positionTooltip = function positionTooltip() {\n // check if tooltip exists and is not empty\n if (!tooltip || !tooltip.html()) {\n return;\n }\n\n if (!positionTimeout) {\n positionTimeout = $timeout(function () {\n var ttPosition = $position.positionElements(element, tooltip, ttScope.placement, appendToBody);\n var initialHeight = angular.isDefined(tooltip.offsetHeight) ? tooltip.offsetHeight : tooltip.prop('offsetHeight');\n var elementPos = appendToBody ? $position.offset(element) : $position.position(element);\n tooltip.css({\n top: ttPosition.top + 'px',\n left: ttPosition.left + 'px'\n });\n var placementClasses = ttPosition.placement.split('-');\n\n if (!tooltip.hasClass(placementClasses[0])) {\n tooltip.removeClass(lastPlacement.split('-')[0]);\n tooltip.addClass(placementClasses[0]);\n }\n\n if (!tooltip.hasClass(options.placementClassPrefix + ttPosition.placement)) {\n tooltip.removeClass(options.placementClassPrefix + lastPlacement);\n tooltip.addClass(options.placementClassPrefix + ttPosition.placement);\n }\n\n adjustmentTimeout = $timeout(function () {\n var currentHeight = angular.isDefined(tooltip.offsetHeight) ? tooltip.offsetHeight : tooltip.prop('offsetHeight');\n var adjustment = $position.adjustTop(placementClasses, elementPos, initialHeight, currentHeight);\n\n if (adjustment) {\n tooltip.css(adjustment);\n }\n\n adjustmentTimeout = null;\n }, 0, false); // first time through tt element will have the\n // uib-position-measure class or if the placement\n // has changed we need to position the arrow.\n\n if (tooltip.hasClass('uib-position-measure')) {\n $position.positionArrow(tooltip, ttPosition.placement);\n tooltip.removeClass('uib-position-measure');\n } else if (lastPlacement !== ttPosition.placement) {\n $position.positionArrow(tooltip, ttPosition.placement);\n }\n\n lastPlacement = ttPosition.placement;\n positionTimeout = null;\n }, 0, false);\n }\n }; // Set up the correct scope to allow transclusion later\n\n\n ttScope.origScope = scope; // By default, the tooltip is not open.\n // TODO add ability to start tooltip opened\n\n ttScope.isOpen = false;\n\n function toggleTooltipBind() {\n if (!ttScope.isOpen) {\n showTooltipBind();\n } else {\n hideTooltipBind();\n }\n } // Show the tooltip with delay if specified, otherwise show it immediately\n\n\n function showTooltipBind() {\n if (hasEnableExp && !scope.$eval(attrs[prefix + 'Enable'])) {\n return;\n }\n\n cancelHide();\n prepareTooltip();\n\n if (ttScope.popupDelay) {\n // Do nothing if the tooltip was already scheduled to pop-up.\n // This happens if show is triggered multiple times before any hide is triggered.\n if (!showTimeout) {\n showTimeout = $timeout(show, ttScope.popupDelay, false);\n }\n } else {\n show();\n }\n }\n\n function hideTooltipBind() {\n cancelShow();\n\n if (ttScope.popupCloseDelay) {\n if (!hideTimeout) {\n hideTimeout = $timeout(hide, ttScope.popupCloseDelay, false);\n }\n } else {\n hide();\n }\n } // Show the tooltip popup element.\n\n\n function show() {\n cancelShow();\n cancelHide(); // Don't show empty tooltips.\n\n if (!ttScope.content) {\n return angular.noop;\n }\n\n createTooltip(); // And show the tooltip.\n\n ttScope.$evalAsync(function () {\n ttScope.isOpen = true;\n assignIsOpen(true);\n positionTooltip();\n });\n }\n\n function cancelShow() {\n if (showTimeout) {\n $timeout.cancel(showTimeout);\n showTimeout = null;\n }\n\n if (positionTimeout) {\n $timeout.cancel(positionTimeout);\n positionTimeout = null;\n }\n } // Hide the tooltip popup element.\n\n\n function hide() {\n if (!ttScope) {\n return;\n } // First things first: we don't show it anymore.\n\n\n ttScope.$evalAsync(function () {\n if (ttScope) {\n ttScope.isOpen = false;\n assignIsOpen(false); // And now we remove it from the DOM. However, if we have animation, we\n // need to wait for it to expire beforehand.\n // FIXME: this is a placeholder for a port of the transitions library.\n // The fade transition in TWBS is 150ms.\n\n if (ttScope.animation) {\n if (!transitionTimeout) {\n transitionTimeout = $timeout(removeTooltip, 150, false);\n }\n } else {\n removeTooltip();\n }\n }\n });\n }\n\n function cancelHide() {\n if (hideTimeout) {\n $timeout.cancel(hideTimeout);\n hideTimeout = null;\n }\n\n if (transitionTimeout) {\n $timeout.cancel(transitionTimeout);\n transitionTimeout = null;\n }\n }\n\n function createTooltip() {\n // There can only be one tooltip element per directive shown at once.\n if (tooltip) {\n return;\n }\n\n tooltipLinkedScope = ttScope.$new();\n tooltip = tooltipLinker(tooltipLinkedScope, function (tooltip) {\n if (appendToBody) {\n $document.find('body').append(tooltip);\n } else {\n element.after(tooltip);\n }\n });\n openedTooltips.add(ttScope, {\n close: hide\n });\n prepObservers();\n }\n\n function removeTooltip() {\n cancelShow();\n cancelHide();\n unregisterObservers();\n\n if (tooltip) {\n tooltip.remove();\n tooltip = null;\n\n if (adjustmentTimeout) {\n $timeout.cancel(adjustmentTimeout);\n }\n }\n\n openedTooltips.remove(ttScope);\n\n if (tooltipLinkedScope) {\n tooltipLinkedScope.$destroy();\n tooltipLinkedScope = null;\n }\n }\n /**\n * Set the initial scope values. Once\n * the tooltip is created, the observers\n * will be added to keep things in sync.\n */\n\n\n function prepareTooltip() {\n ttScope.title = attrs[prefix + 'Title'];\n\n if (contentParse) {\n ttScope.content = contentParse(scope);\n } else {\n ttScope.content = attrs[ttType];\n }\n\n ttScope.popupClass = attrs[prefix + 'Class'];\n ttScope.placement = angular.isDefined(attrs[prefix + 'Placement']) ? attrs[prefix + 'Placement'] : options.placement;\n var placement = $position.parsePlacement(ttScope.placement);\n lastPlacement = placement[1] ? placement[0] + '-' + placement[1] : placement[0];\n var delay = parseInt(attrs[prefix + 'PopupDelay'], 10);\n var closeDelay = parseInt(attrs[prefix + 'PopupCloseDelay'], 10);\n ttScope.popupDelay = !isNaN(delay) ? delay : options.popupDelay;\n ttScope.popupCloseDelay = !isNaN(closeDelay) ? closeDelay : options.popupCloseDelay;\n }\n\n function assignIsOpen(isOpen) {\n if (isOpenParse && angular.isFunction(isOpenParse.assign)) {\n isOpenParse.assign(scope, isOpen);\n }\n }\n\n ttScope.contentExp = function () {\n return ttScope.content;\n };\n /**\n * Observe the relevant attributes.\n */\n\n\n attrs.$observe('disabled', function (val) {\n if (val) {\n cancelShow();\n }\n\n if (val && ttScope.isOpen) {\n hide();\n }\n });\n\n if (isOpenParse) {\n scope.$watch(isOpenParse, function (val) {\n if (ttScope && !val === ttScope.isOpen) {\n toggleTooltipBind();\n }\n });\n }\n\n function prepObservers() {\n observers.length = 0;\n\n if (contentParse) {\n observers.push(scope.$watch(contentParse, function (val) {\n ttScope.content = val;\n\n if (!val && ttScope.isOpen) {\n hide();\n }\n }));\n observers.push(tooltipLinkedScope.$watch(function () {\n if (!repositionScheduled) {\n repositionScheduled = true;\n tooltipLinkedScope.$$postDigest(function () {\n repositionScheduled = false;\n\n if (ttScope && ttScope.isOpen) {\n positionTooltip();\n }\n });\n }\n }));\n } else {\n observers.push(attrs.$observe(ttType, function (val) {\n ttScope.content = val;\n\n if (!val && ttScope.isOpen) {\n hide();\n } else {\n positionTooltip();\n }\n }));\n }\n\n observers.push(attrs.$observe(prefix + 'Title', function (val) {\n ttScope.title = val;\n\n if (ttScope.isOpen) {\n positionTooltip();\n }\n }));\n observers.push(attrs.$observe(prefix + 'Placement', function (val) {\n ttScope.placement = val ? val : options.placement;\n\n if (ttScope.isOpen) {\n positionTooltip();\n }\n }));\n }\n\n function unregisterObservers() {\n if (observers.length) {\n angular.forEach(observers, function (observer) {\n observer();\n });\n observers.length = 0;\n }\n } // hide tooltips/popovers for outsideClick trigger\n\n\n function bodyHideTooltipBind(e) {\n if (!ttScope || !ttScope.isOpen || !tooltip) {\n return;\n } // make sure the tooltip/popover link or tool tooltip/popover itself were not clicked\n\n\n if (!element[0].contains(e.target) && !tooltip[0].contains(e.target)) {\n hideTooltipBind();\n }\n } // KeyboardEvent handler to hide the tooltip on Escape key press\n\n\n function hideOnEscapeKey(e) {\n if (e.which === 27) {\n hideTooltipBind();\n }\n }\n\n var unregisterTriggers = function unregisterTriggers() {\n triggers.show.forEach(function (trigger) {\n if (trigger === 'outsideClick') {\n element.off('click', toggleTooltipBind);\n } else {\n element.off(trigger, showTooltipBind);\n element.off(trigger, toggleTooltipBind);\n }\n\n element.off('keypress', hideOnEscapeKey);\n });\n triggers.hide.forEach(function (trigger) {\n if (trigger === 'outsideClick') {\n $document.off('click', bodyHideTooltipBind);\n } else {\n element.off(trigger, hideTooltipBind);\n }\n });\n };\n\n function prepTriggers() {\n var showTriggers = [],\n hideTriggers = [];\n var val = scope.$eval(attrs[prefix + 'Trigger']);\n unregisterTriggers();\n\n if (angular.isObject(val)) {\n Object.keys(val).forEach(function (key) {\n showTriggers.push(key);\n hideTriggers.push(val[key]);\n });\n triggers = {\n show: showTriggers,\n hide: hideTriggers\n };\n } else {\n triggers = getTriggers(val);\n }\n\n if (triggers.show !== 'none') {\n triggers.show.forEach(function (trigger, idx) {\n if (trigger === 'outsideClick') {\n element.on('click', toggleTooltipBind);\n $document.on('click', bodyHideTooltipBind);\n } else if (trigger === triggers.hide[idx]) {\n element.on(trigger, toggleTooltipBind);\n } else if (trigger) {\n element.on(trigger, showTooltipBind);\n element.on(triggers.hide[idx], hideTooltipBind);\n }\n\n element.on('keypress', hideOnEscapeKey);\n });\n }\n }\n\n prepTriggers();\n var animation = scope.$eval(attrs[prefix + 'Animation']);\n ttScope.animation = angular.isDefined(animation) ? !!animation : options.animation;\n var appendToBodyVal;\n var appendKey = prefix + 'AppendToBody';\n\n if (appendKey in attrs && attrs[appendKey] === undefined) {\n appendToBodyVal = true;\n } else {\n appendToBodyVal = scope.$eval(attrs[appendKey]);\n }\n\n appendToBody = angular.isDefined(appendToBodyVal) ? appendToBodyVal : appendToBody; // Make sure tooltip is destroyed and removed.\n\n scope.$on('$destroy', function onDestroyTooltip() {\n unregisterTriggers();\n removeTooltip();\n ttScope = null;\n });\n };\n }\n };\n };\n }];\n}) // This is mostly ngInclude code but with a custom scope\n.directive('uibTooltipTemplateTransclude', ['$animate', '$sce', '$compile', '$templateRequest', function ($animate, $sce, $compile, $templateRequest) {\n return {\n link: function link(scope, elem, attrs) {\n var origScope = scope.$eval(attrs.tooltipTemplateTranscludeScope);\n var changeCounter = 0,\n currentScope,\n previousElement,\n currentElement;\n\n var cleanupLastIncludeContent = function cleanupLastIncludeContent() {\n if (previousElement) {\n previousElement.remove();\n previousElement = null;\n }\n\n if (currentScope) {\n currentScope.$destroy();\n currentScope = null;\n }\n\n if (currentElement) {\n $animate.leave(currentElement).then(function () {\n previousElement = null;\n });\n previousElement = currentElement;\n currentElement = null;\n }\n };\n\n scope.$watch($sce.parseAsResourceUrl(attrs.uibTooltipTemplateTransclude), function (src) {\n var thisChangeId = ++changeCounter;\n\n if (src) {\n //set the 2nd param to true to ignore the template request error so that the inner\n //contents and scope can be cleaned up.\n $templateRequest(src, true).then(function (response) {\n if (thisChangeId !== changeCounter) {\n return;\n }\n\n var newScope = origScope.$new();\n var template = response;\n var clone = $compile(template)(newScope, function (clone) {\n cleanupLastIncludeContent();\n $animate.enter(clone, elem);\n });\n currentScope = newScope;\n currentElement = clone;\n currentScope.$emit('$includeContentLoaded', src);\n }, function () {\n if (thisChangeId === changeCounter) {\n cleanupLastIncludeContent();\n scope.$emit('$includeContentError', src);\n }\n });\n scope.$emit('$includeContentRequested', src);\n } else {\n cleanupLastIncludeContent();\n }\n });\n scope.$on('$destroy', cleanupLastIncludeContent);\n }\n };\n}])\n/**\n * Note that it's intentional that these classes are *not* applied through $animate.\n * They must not be animated as they're expected to be present on the tooltip on\n * initialization.\n */\n.directive('uibTooltipClasses', ['$uibPosition', function ($uibPosition) {\n return {\n restrict: 'A',\n link: function link(scope, element, attrs) {\n // need to set the primary position so the\n // arrow has space during position measure.\n // tooltip.positionTooltip()\n if (scope.placement) {\n // // There are no top-left etc... classes\n // // in TWBS, so we need the primary position.\n var position = $uibPosition.parsePlacement(scope.placement);\n element.addClass(position[0]);\n }\n\n if (scope.popupClass) {\n element.addClass(scope.popupClass);\n }\n\n if (scope.animation) {\n element.addClass(attrs.tooltipAnimationClass);\n }\n }\n };\n}]).directive('uibTooltipPopup', function () {\n return {\n restrict: 'A',\n scope: {\n content: '@'\n },\n templateUrl: 'uib/template/tooltip/tooltip-popup.html'\n };\n}).directive('uibTooltip', ['$uibTooltip', function ($uibTooltip) {\n return $uibTooltip('uibTooltip', 'tooltip', 'mouseenter');\n}]).directive('uibTooltipTemplatePopup', function () {\n return {\n restrict: 'A',\n scope: {\n contentExp: '&',\n originScope: '&'\n },\n templateUrl: 'uib/template/tooltip/tooltip-template-popup.html'\n };\n}).directive('uibTooltipTemplate', ['$uibTooltip', function ($uibTooltip) {\n return $uibTooltip('uibTooltipTemplate', 'tooltip', 'mouseenter', {\n useContentExp: true\n });\n}]).directive('uibTooltipHtmlPopup', function () {\n return {\n restrict: 'A',\n scope: {\n contentExp: '&'\n },\n templateUrl: 'uib/template/tooltip/tooltip-html-popup.html'\n };\n}).directive('uibTooltipHtml', ['$uibTooltip', function ($uibTooltip) {\n return $uibTooltip('uibTooltipHtml', 'tooltip', 'mouseenter', {\n useContentExp: true\n });\n}]);\nangular.module('ui.bootstrap.position', [])\n/**\n * A set of utility methods for working with the DOM.\n * It is meant to be used where we need to absolute-position elements in\n * relation to another element (this is the case for tooltips, popovers,\n * typeahead suggestions etc.).\n */\n.factory('$uibPosition', ['$document', '$window', function ($document, $window) {\n /**\n * Used by scrollbarWidth() function to cache scrollbar's width.\n * Do not access this variable directly, use scrollbarWidth() instead.\n */\n var SCROLLBAR_WIDTH;\n /**\n * scrollbar on body and html element in IE and Edge overlay\n * content and should be considered 0 width.\n */\n\n var BODY_SCROLLBAR_WIDTH;\n var OVERFLOW_REGEX = {\n normal: /(auto|scroll)/,\n hidden: /(auto|scroll|hidden)/\n };\n var PLACEMENT_REGEX = {\n auto: /\\s?auto?\\s?/i,\n primary: /^(top|bottom|left|right)$/,\n secondary: /^(top|bottom|left|right|center)$/,\n vertical: /^(top|bottom)$/\n };\n var BODY_REGEX = /(HTML|BODY)/;\n return {\n /**\n * Provides a raw DOM element from a jQuery/jQLite element.\n *\n * @param {element} elem - The element to convert.\n *\n * @returns {element} A HTML element.\n */\n getRawNode: function getRawNode(elem) {\n return elem.nodeName ? elem : elem[0] || elem;\n },\n\n /**\n * Provides a parsed number for a style property. Strips\n * units and casts invalid numbers to 0.\n *\n * @param {string} value - The style value to parse.\n *\n * @returns {number} A valid number.\n */\n parseStyle: function parseStyle(value) {\n value = parseFloat(value);\n return isFinite(value) ? value : 0;\n },\n\n /**\n * Provides the closest positioned ancestor.\n *\n * @param {element} element - The element to get the offest parent for.\n *\n * @returns {element} The closest positioned ancestor.\n */\n offsetParent: function offsetParent(elem) {\n elem = this.getRawNode(elem);\n var offsetParent = elem.offsetParent || $document[0].documentElement;\n\n function isStaticPositioned(el) {\n return ($window.getComputedStyle(el).position || 'static') === 'static';\n }\n\n while (offsetParent && offsetParent !== $document[0].documentElement && isStaticPositioned(offsetParent)) {\n offsetParent = offsetParent.offsetParent;\n }\n\n return offsetParent || $document[0].documentElement;\n },\n\n /**\n * Provides the scrollbar width, concept from TWBS measureScrollbar()\n * function in https://github.com/twbs/bootstrap/blob/master/js/modal.js\n * In IE and Edge, scollbar on body and html element overlay and should\n * return a width of 0.\n *\n * @returns {number} The width of the browser scollbar.\n */\n scrollbarWidth: function scrollbarWidth(isBody) {\n if (isBody) {\n if (angular.isUndefined(BODY_SCROLLBAR_WIDTH)) {\n var bodyElem = $document.find('body');\n bodyElem.addClass('uib-position-body-scrollbar-measure');\n BODY_SCROLLBAR_WIDTH = $window.innerWidth - bodyElem[0].clientWidth;\n BODY_SCROLLBAR_WIDTH = isFinite(BODY_SCROLLBAR_WIDTH) ? BODY_SCROLLBAR_WIDTH : 0;\n bodyElem.removeClass('uib-position-body-scrollbar-measure');\n }\n\n return BODY_SCROLLBAR_WIDTH;\n }\n\n if (angular.isUndefined(SCROLLBAR_WIDTH)) {\n var scrollElem = angular.element('
    ');\n $document.find('body').append(scrollElem);\n SCROLLBAR_WIDTH = scrollElem[0].offsetWidth - scrollElem[0].clientWidth;\n SCROLLBAR_WIDTH = isFinite(SCROLLBAR_WIDTH) ? SCROLLBAR_WIDTH : 0;\n scrollElem.remove();\n }\n\n return SCROLLBAR_WIDTH;\n },\n\n /**\n * Provides the padding required on an element to replace the scrollbar.\n *\n * @returns {object} An object with the following properties:\n *
      \n *
    • **scrollbarWidth**: the width of the scrollbar
    • \n *
    • **widthOverflow**: whether the the width is overflowing
    • \n *
    • **right**: the amount of right padding on the element needed to replace the scrollbar
    • \n *
    • **rightOriginal**: the amount of right padding currently on the element
    • \n *
    • **heightOverflow**: whether the the height is overflowing
    • \n *
    • **bottom**: the amount of bottom padding on the element needed to replace the scrollbar
    • \n *
    • **bottomOriginal**: the amount of bottom padding currently on the element
    • \n *
    \n */\n scrollbarPadding: function scrollbarPadding(elem) {\n elem = this.getRawNode(elem);\n var elemStyle = $window.getComputedStyle(elem);\n var paddingRight = this.parseStyle(elemStyle.paddingRight);\n var paddingBottom = this.parseStyle(elemStyle.paddingBottom);\n var scrollParent = this.scrollParent(elem, false, true);\n var scrollbarWidth = this.scrollbarWidth(BODY_REGEX.test(scrollParent.tagName));\n return {\n scrollbarWidth: scrollbarWidth,\n widthOverflow: scrollParent.scrollWidth > scrollParent.clientWidth,\n right: paddingRight + scrollbarWidth,\n originalRight: paddingRight,\n heightOverflow: scrollParent.scrollHeight > scrollParent.clientHeight,\n bottom: paddingBottom + scrollbarWidth,\n originalBottom: paddingBottom\n };\n },\n\n /**\n * Checks to see if the element is scrollable.\n *\n * @param {element} elem - The element to check.\n * @param {boolean=} [includeHidden=false] - Should scroll style of 'hidden' be considered,\n * default is false.\n *\n * @returns {boolean} Whether the element is scrollable.\n */\n isScrollable: function isScrollable(elem, includeHidden) {\n elem = this.getRawNode(elem);\n var overflowRegex = includeHidden ? OVERFLOW_REGEX.hidden : OVERFLOW_REGEX.normal;\n var elemStyle = $window.getComputedStyle(elem);\n return overflowRegex.test(elemStyle.overflow + elemStyle.overflowY + elemStyle.overflowX);\n },\n\n /**\n * Provides the closest scrollable ancestor.\n * A port of the jQuery UI scrollParent method:\n * https://github.com/jquery/jquery-ui/blob/master/ui/scroll-parent.js\n *\n * @param {element} elem - The element to find the scroll parent of.\n * @param {boolean=} [includeHidden=false] - Should scroll style of 'hidden' be considered,\n * default is false.\n * @param {boolean=} [includeSelf=false] - Should the element being passed be\n * included in the scrollable llokup.\n *\n * @returns {element} A HTML element.\n */\n scrollParent: function scrollParent(elem, includeHidden, includeSelf) {\n elem = this.getRawNode(elem);\n var overflowRegex = includeHidden ? OVERFLOW_REGEX.hidden : OVERFLOW_REGEX.normal;\n var documentEl = $document[0].documentElement;\n var elemStyle = $window.getComputedStyle(elem);\n\n if (includeSelf && overflowRegex.test(elemStyle.overflow + elemStyle.overflowY + elemStyle.overflowX)) {\n return elem;\n }\n\n var excludeStatic = elemStyle.position === 'absolute';\n var scrollParent = elem.parentElement || documentEl;\n\n if (scrollParent === documentEl || elemStyle.position === 'fixed') {\n return documentEl;\n }\n\n while (scrollParent.parentElement && scrollParent !== documentEl) {\n var spStyle = $window.getComputedStyle(scrollParent);\n\n if (excludeStatic && spStyle.position !== 'static') {\n excludeStatic = false;\n }\n\n if (!excludeStatic && overflowRegex.test(spStyle.overflow + spStyle.overflowY + spStyle.overflowX)) {\n break;\n }\n\n scrollParent = scrollParent.parentElement;\n }\n\n return scrollParent;\n },\n\n /**\n * Provides read-only equivalent of jQuery's position function:\n * http://api.jquery.com/position/ - distance to closest positioned\n * ancestor. Does not account for margins by default like jQuery position.\n *\n * @param {element} elem - The element to caclulate the position on.\n * @param {boolean=} [includeMargins=false] - Should margins be accounted\n * for, default is false.\n *\n * @returns {object} An object with the following properties:\n *
      \n *
    • **width**: the width of the element
    • \n *
    • **height**: the height of the element
    • \n *
    • **top**: distance to top edge of offset parent
    • \n *
    • **left**: distance to left edge of offset parent
    • \n *
    \n */\n position: function position(elem, includeMagins) {\n elem = this.getRawNode(elem);\n var elemOffset = this.offset(elem);\n\n if (includeMagins) {\n var elemStyle = $window.getComputedStyle(elem);\n elemOffset.top -= this.parseStyle(elemStyle.marginTop);\n elemOffset.left -= this.parseStyle(elemStyle.marginLeft);\n }\n\n var parent = this.offsetParent(elem);\n var parentOffset = {\n top: 0,\n left: 0\n };\n\n if (parent !== $document[0].documentElement) {\n parentOffset = this.offset(parent);\n parentOffset.top += parent.clientTop - parent.scrollTop;\n parentOffset.left += parent.clientLeft - parent.scrollLeft;\n }\n\n return {\n width: Math.round(angular.isNumber(elemOffset.width) ? elemOffset.width : elem.offsetWidth),\n height: Math.round(angular.isNumber(elemOffset.height) ? elemOffset.height : elem.offsetHeight),\n top: Math.round(elemOffset.top - parentOffset.top),\n left: Math.round(elemOffset.left - parentOffset.left)\n };\n },\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * http://api.jquery.com/offset/ - distance to viewport. Does\n * not account for borders, margins, or padding on the body\n * element.\n *\n * @param {element} elem - The element to calculate the offset on.\n *\n * @returns {object} An object with the following properties:\n *
      \n *
    • **width**: the width of the element
    • \n *
    • **height**: the height of the element
    • \n *
    • **top**: distance to top edge of viewport
    • \n *
    • **right**: distance to bottom edge of viewport
    • \n *
    \n */\n offset: function offset(elem) {\n elem = this.getRawNode(elem);\n var elemBCR = elem.getBoundingClientRect();\n return {\n width: Math.round(angular.isNumber(elemBCR.width) ? elemBCR.width : elem.offsetWidth),\n height: Math.round(angular.isNumber(elemBCR.height) ? elemBCR.height : elem.offsetHeight),\n top: Math.round(elemBCR.top + ($window.pageYOffset || $document[0].documentElement.scrollTop)),\n left: Math.round(elemBCR.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft))\n };\n },\n\n /**\n * Provides offset distance to the closest scrollable ancestor\n * or viewport. Accounts for border and scrollbar width.\n *\n * Right and bottom dimensions represent the distance to the\n * respective edge of the viewport element. If the element\n * edge extends beyond the viewport, a negative value will be\n * reported.\n *\n * @param {element} elem - The element to get the viewport offset for.\n * @param {boolean=} [useDocument=false] - Should the viewport be the document element instead\n * of the first scrollable element, default is false.\n * @param {boolean=} [includePadding=true] - Should the padding on the offset parent element\n * be accounted for, default is true.\n *\n * @returns {object} An object with the following properties:\n *
      \n *
    • **top**: distance to the top content edge of viewport element
    • \n *
    • **bottom**: distance to the bottom content edge of viewport element
    • \n *
    • **left**: distance to the left content edge of viewport element
    • \n *
    • **right**: distance to the right content edge of viewport element
    • \n *
    \n */\n viewportOffset: function viewportOffset(elem, useDocument, includePadding) {\n elem = this.getRawNode(elem);\n includePadding = includePadding !== false ? true : false;\n var elemBCR = elem.getBoundingClientRect();\n var offsetBCR = {\n top: 0,\n left: 0,\n bottom: 0,\n right: 0\n };\n var offsetParent = useDocument ? $document[0].documentElement : this.scrollParent(elem);\n var offsetParentBCR = offsetParent.getBoundingClientRect();\n offsetBCR.top = offsetParentBCR.top + offsetParent.clientTop;\n offsetBCR.left = offsetParentBCR.left + offsetParent.clientLeft;\n\n if (offsetParent === $document[0].documentElement) {\n offsetBCR.top += $window.pageYOffset;\n offsetBCR.left += $window.pageXOffset;\n }\n\n offsetBCR.bottom = offsetBCR.top + offsetParent.clientHeight;\n offsetBCR.right = offsetBCR.left + offsetParent.clientWidth;\n\n if (includePadding) {\n var offsetParentStyle = $window.getComputedStyle(offsetParent);\n offsetBCR.top += this.parseStyle(offsetParentStyle.paddingTop);\n offsetBCR.bottom -= this.parseStyle(offsetParentStyle.paddingBottom);\n offsetBCR.left += this.parseStyle(offsetParentStyle.paddingLeft);\n offsetBCR.right -= this.parseStyle(offsetParentStyle.paddingRight);\n }\n\n return {\n top: Math.round(elemBCR.top - offsetBCR.top),\n bottom: Math.round(offsetBCR.bottom - elemBCR.bottom),\n left: Math.round(elemBCR.left - offsetBCR.left),\n right: Math.round(offsetBCR.right - elemBCR.right)\n };\n },\n\n /**\n * Provides an array of placement values parsed from a placement string.\n * Along with the 'auto' indicator, supported placement strings are:\n *
      \n *
    • top: element on top, horizontally centered on host element.
    • \n *
    • top-left: element on top, left edge aligned with host element left edge.
    • \n *
    • top-right: element on top, lerightft edge aligned with host element right edge.
    • \n *
    • bottom: element on bottom, horizontally centered on host element.
    • \n *
    • bottom-left: element on bottom, left edge aligned with host element left edge.
    • \n *
    • bottom-right: element on bottom, right edge aligned with host element right edge.
    • \n *
    • left: element on left, vertically centered on host element.
    • \n *
    • left-top: element on left, top edge aligned with host element top edge.
    • \n *
    • left-bottom: element on left, bottom edge aligned with host element bottom edge.
    • \n *
    • right: element on right, vertically centered on host element.
    • \n *
    • right-top: element on right, top edge aligned with host element top edge.
    • \n *
    • right-bottom: element on right, bottom edge aligned with host element bottom edge.
    • \n *
    \n * A placement string with an 'auto' indicator is expected to be\n * space separated from the placement, i.e: 'auto bottom-left' If\n * the primary and secondary placement values do not match 'top,\n * bottom, left, right' then 'top' will be the primary placement and\n * 'center' will be the secondary placement. If 'auto' is passed, true\n * will be returned as the 3rd value of the array.\n *\n * @param {string} placement - The placement string to parse.\n *\n * @returns {array} An array with the following values\n *
      \n *
    • **[0]**: The primary placement.
    • \n *
    • **[1]**: The secondary placement.
    • \n *
    • **[2]**: If auto is passed: true, else undefined.
    • \n *
    \n */\n parsePlacement: function parsePlacement(placement) {\n var autoPlace = PLACEMENT_REGEX.auto.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(PLACEMENT_REGEX.auto, '');\n }\n\n placement = placement.split('-');\n placement[0] = placement[0] || 'top';\n\n if (!PLACEMENT_REGEX.primary.test(placement[0])) {\n placement[0] = 'top';\n }\n\n placement[1] = placement[1] || 'center';\n\n if (!PLACEMENT_REGEX.secondary.test(placement[1])) {\n placement[1] = 'center';\n }\n\n if (autoPlace) {\n placement[2] = true;\n } else {\n placement[2] = false;\n }\n\n return placement;\n },\n\n /**\n * Provides coordinates for an element to be positioned relative to\n * another element. Passing 'auto' as part of the placement parameter\n * will enable smart placement - where the element fits. i.e:\n * 'auto left-top' will check to see if there is enough space to the left\n * of the hostElem to fit the targetElem, if not place right (same for secondary\n * top placement). Available space is calculated using the viewportOffset\n * function.\n *\n * @param {element} hostElem - The element to position against.\n * @param {element} targetElem - The element to position.\n * @param {string=} [placement=top] - The placement for the targetElem,\n * default is 'top'. 'center' is assumed as secondary placement for\n * 'top', 'left', 'right', and 'bottom' placements. Available placements are:\n *
      \n *
    • top
    • \n *
    • top-right
    • \n *
    • top-left
    • \n *
    • bottom
    • \n *
    • bottom-left
    • \n *
    • bottom-right
    • \n *
    • left
    • \n *
    • left-top
    • \n *
    • left-bottom
    • \n *
    • right
    • \n *
    • right-top
    • \n *
    • right-bottom
    • \n *
    \n * @param {boolean=} [appendToBody=false] - Should the top and left values returned\n * be calculated from the body element, default is false.\n *\n * @returns {object} An object with the following properties:\n *
      \n *
    • **top**: Value for targetElem top.
    • \n *
    • **left**: Value for targetElem left.
    • \n *
    • **placement**: The resolved placement.
    • \n *
    \n */\n positionElements: function positionElements(hostElem, targetElem, placement, appendToBody) {\n hostElem = this.getRawNode(hostElem);\n targetElem = this.getRawNode(targetElem); // need to read from prop to support tests.\n\n var targetWidth = angular.isDefined(targetElem.offsetWidth) ? targetElem.offsetWidth : targetElem.prop('offsetWidth');\n var targetHeight = angular.isDefined(targetElem.offsetHeight) ? targetElem.offsetHeight : targetElem.prop('offsetHeight');\n placement = this.parsePlacement(placement);\n var hostElemPos = appendToBody ? this.offset(hostElem) : this.position(hostElem);\n var targetElemPos = {\n top: 0,\n left: 0,\n placement: ''\n };\n\n if (placement[2]) {\n var viewportOffset = this.viewportOffset(hostElem, appendToBody);\n var targetElemStyle = $window.getComputedStyle(targetElem);\n var adjustedSize = {\n width: targetWidth + Math.round(Math.abs(this.parseStyle(targetElemStyle.marginLeft) + this.parseStyle(targetElemStyle.marginRight))),\n height: targetHeight + Math.round(Math.abs(this.parseStyle(targetElemStyle.marginTop) + this.parseStyle(targetElemStyle.marginBottom)))\n };\n placement[0] = placement[0] === 'top' && adjustedSize.height > viewportOffset.top && adjustedSize.height <= viewportOffset.bottom ? 'bottom' : placement[0] === 'bottom' && adjustedSize.height > viewportOffset.bottom && adjustedSize.height <= viewportOffset.top ? 'top' : placement[0] === 'left' && adjustedSize.width > viewportOffset.left && adjustedSize.width <= viewportOffset.right ? 'right' : placement[0] === 'right' && adjustedSize.width > viewportOffset.right && adjustedSize.width <= viewportOffset.left ? 'left' : placement[0];\n placement[1] = placement[1] === 'top' && adjustedSize.height - hostElemPos.height > viewportOffset.bottom && adjustedSize.height - hostElemPos.height <= viewportOffset.top ? 'bottom' : placement[1] === 'bottom' && adjustedSize.height - hostElemPos.height > viewportOffset.top && adjustedSize.height - hostElemPos.height <= viewportOffset.bottom ? 'top' : placement[1] === 'left' && adjustedSize.width - hostElemPos.width > viewportOffset.right && adjustedSize.width - hostElemPos.width <= viewportOffset.left ? 'right' : placement[1] === 'right' && adjustedSize.width - hostElemPos.width > viewportOffset.left && adjustedSize.width - hostElemPos.width <= viewportOffset.right ? 'left' : placement[1];\n\n if (placement[1] === 'center') {\n if (PLACEMENT_REGEX.vertical.test(placement[0])) {\n var xOverflow = hostElemPos.width / 2 - targetWidth / 2;\n\n if (viewportOffset.left + xOverflow < 0 && adjustedSize.width - hostElemPos.width <= viewportOffset.right) {\n placement[1] = 'left';\n } else if (viewportOffset.right + xOverflow < 0 && adjustedSize.width - hostElemPos.width <= viewportOffset.left) {\n placement[1] = 'right';\n }\n } else {\n var yOverflow = hostElemPos.height / 2 - adjustedSize.height / 2;\n\n if (viewportOffset.top + yOverflow < 0 && adjustedSize.height - hostElemPos.height <= viewportOffset.bottom) {\n placement[1] = 'top';\n } else if (viewportOffset.bottom + yOverflow < 0 && adjustedSize.height - hostElemPos.height <= viewportOffset.top) {\n placement[1] = 'bottom';\n }\n }\n }\n }\n\n switch (placement[0]) {\n case 'top':\n targetElemPos.top = hostElemPos.top - targetHeight;\n break;\n\n case 'bottom':\n targetElemPos.top = hostElemPos.top + hostElemPos.height;\n break;\n\n case 'left':\n targetElemPos.left = hostElemPos.left - targetWidth;\n break;\n\n case 'right':\n targetElemPos.left = hostElemPos.left + hostElemPos.width;\n break;\n }\n\n switch (placement[1]) {\n case 'top':\n targetElemPos.top = hostElemPos.top;\n break;\n\n case 'bottom':\n targetElemPos.top = hostElemPos.top + hostElemPos.height - targetHeight;\n break;\n\n case 'left':\n targetElemPos.left = hostElemPos.left;\n break;\n\n case 'right':\n targetElemPos.left = hostElemPos.left + hostElemPos.width - targetWidth;\n break;\n\n case 'center':\n if (PLACEMENT_REGEX.vertical.test(placement[0])) {\n targetElemPos.left = hostElemPos.left + hostElemPos.width / 2 - targetWidth / 2;\n } else {\n targetElemPos.top = hostElemPos.top + hostElemPos.height / 2 - targetHeight / 2;\n }\n\n break;\n }\n\n targetElemPos.top = Math.round(targetElemPos.top);\n targetElemPos.left = Math.round(targetElemPos.left);\n targetElemPos.placement = placement[1] === 'center' ? placement[0] : placement[0] + '-' + placement[1];\n return targetElemPos;\n },\n\n /**\n * Provides a way to adjust the top positioning after first\n * render to correctly align element to top after content\n * rendering causes resized element height\n *\n * @param {array} placementClasses - The array of strings of classes\n * element should have.\n * @param {object} containerPosition - The object with container\n * position information\n * @param {number} initialHeight - The initial height for the elem.\n * @param {number} currentHeight - The current height for the elem.\n */\n adjustTop: function adjustTop(placementClasses, containerPosition, initialHeight, currentHeight) {\n if (placementClasses.indexOf('top') !== -1 && initialHeight !== currentHeight) {\n return {\n top: containerPosition.top - currentHeight + 'px'\n };\n }\n },\n\n /**\n * Provides a way for positioning tooltip & dropdown\n * arrows when using placement options beyond the standard\n * left, right, top, or bottom.\n *\n * @param {element} elem - The tooltip/dropdown element.\n * @param {string} placement - The placement for the elem.\n */\n positionArrow: function positionArrow(elem, placement) {\n elem = this.getRawNode(elem);\n var innerElem = elem.querySelector('.tooltip-inner, .popover-inner');\n\n if (!innerElem) {\n return;\n }\n\n var isTooltip = angular.element(innerElem).hasClass('tooltip-inner');\n var arrowElem = isTooltip ? elem.querySelector('.tooltip-arrow') : elem.querySelector('.arrow');\n\n if (!arrowElem) {\n return;\n }\n\n var arrowCss = {\n top: '',\n bottom: '',\n left: '',\n right: ''\n };\n placement = this.parsePlacement(placement);\n\n if (placement[1] === 'center') {\n // no adjustment necessary - just reset styles\n angular.element(arrowElem).css(arrowCss);\n return;\n }\n\n var borderProp = 'border-' + placement[0] + '-width';\n var borderWidth = $window.getComputedStyle(arrowElem)[borderProp];\n var borderRadiusProp = 'border-';\n\n if (PLACEMENT_REGEX.vertical.test(placement[0])) {\n borderRadiusProp += placement[0] + '-' + placement[1];\n } else {\n borderRadiusProp += placement[1] + '-' + placement[0];\n }\n\n borderRadiusProp += '-radius';\n var borderRadius = $window.getComputedStyle(isTooltip ? innerElem : elem)[borderRadiusProp];\n\n switch (placement[0]) {\n case 'top':\n arrowCss.bottom = isTooltip ? '0' : '-' + borderWidth;\n break;\n\n case 'bottom':\n arrowCss.top = isTooltip ? '0' : '-' + borderWidth;\n break;\n\n case 'left':\n arrowCss.right = isTooltip ? '0' : '-' + borderWidth;\n break;\n\n case 'right':\n arrowCss.left = isTooltip ? '0' : '-' + borderWidth;\n break;\n }\n\n arrowCss[placement[1]] = borderRadius;\n angular.element(arrowElem).css(arrowCss);\n }\n };\n}]);\nangular.module('ui.bootstrap.stackedMap', [])\n/**\n * A helper, internal data structure that acts as a map but also allows getting / removing\n * elements in the LIFO order\n */\n.factory('$$stackedMap', function () {\n return {\n createNew: function createNew() {\n var stack = [];\n return {\n add: function add(key, value) {\n stack.push({\n key: key,\n value: value\n });\n },\n get: function get(key) {\n for (var i = 0; i < stack.length; i++) {\n if (key === stack[i].key) {\n return stack[i];\n }\n }\n },\n keys: function keys() {\n var keys = [];\n\n for (var i = 0; i < stack.length; i++) {\n keys.push(stack[i].key);\n }\n\n return keys;\n },\n top: function top() {\n return stack[stack.length - 1];\n },\n remove: function remove(key) {\n var idx = -1;\n\n for (var i = 0; i < stack.length; i++) {\n if (key === stack[i].key) {\n idx = i;\n break;\n }\n }\n\n return stack.splice(idx, 1)[0];\n },\n removeTop: function removeTop() {\n return stack.pop();\n },\n length: function length() {\n return stack.length;\n }\n };\n }\n };\n});\n/**\n * The following features are still outstanding: popup delay, animation as a\n * function, placement as a function, inside, support for more triggers than\n * just mouse enter/leave, and selector delegatation.\n */\n\nangular.module('ui.bootstrap.popover', ['ui.bootstrap.tooltip']).directive('uibPopoverTemplatePopup', function () {\n return {\n restrict: 'A',\n scope: {\n uibTitle: '@',\n contentExp: '&',\n originScope: '&'\n },\n templateUrl: 'uib/template/popover/popover-template.html'\n };\n}).directive('uibPopoverTemplate', ['$uibTooltip', function ($uibTooltip) {\n return $uibTooltip('uibPopoverTemplate', 'popover', 'click', {\n useContentExp: true\n });\n}]).directive('uibPopoverHtmlPopup', function () {\n return {\n restrict: 'A',\n scope: {\n contentExp: '&',\n uibTitle: '@'\n },\n templateUrl: 'uib/template/popover/popover-html.html'\n };\n}).directive('uibPopoverHtml', ['$uibTooltip', function ($uibTooltip) {\n return $uibTooltip('uibPopoverHtml', 'popover', 'click', {\n useContentExp: true\n });\n}]).directive('uibPopoverPopup', function () {\n return {\n restrict: 'A',\n scope: {\n uibTitle: '@',\n content: '@'\n },\n templateUrl: 'uib/template/popover/popover.html'\n };\n}).directive('uibPopover', ['$uibTooltip', function ($uibTooltip) {\n return $uibTooltip('uibPopover', 'popover', 'click');\n}]);\nangular.module(\"uib/template/tooltip/tooltip-html-popup.html\", []).run([\"$templateCache\", function ($templateCache) {\n $templateCache.put(\"uib/template/tooltip/tooltip-html-popup.html\", \"
    \\n\" + \"
    \\n\" + \"\");\n}]);\nangular.module(\"uib/template/tooltip/tooltip-popup.html\", []).run([\"$templateCache\", function ($templateCache) {\n $templateCache.put(\"uib/template/tooltip/tooltip-popup.html\", \"
    \\n\" + \"
    \\n\" + \"\");\n}]);\nangular.module(\"uib/template/tooltip/tooltip-template-popup.html\", []).run([\"$templateCache\", function ($templateCache) {\n $templateCache.put(\"uib/template/tooltip/tooltip-template-popup.html\", \"
    \\n\" + \"
    \\n\" + \"\");\n}]);\nangular.module(\"uib/template/popover/popover-html.html\", []).run([\"$templateCache\", function ($templateCache) {\n $templateCache.put(\"uib/template/popover/popover-html.html\", \"
    \\n\" + \"\\n\" + \"
    \\n\" + \"

    \\n\" + \"
    \\n\" + \"
    \\n\" + \"\");\n}]);\nangular.module(\"uib/template/popover/popover-template.html\", []).run([\"$templateCache\", function ($templateCache) {\n $templateCache.put(\"uib/template/popover/popover-template.html\", \"
    \\n\" + \"\\n\" + \"
    \\n\" + \"

    \\n\" + \"
    \\n\" + \"
    \\n\" + \"\");\n}]);\nangular.module(\"uib/template/popover/popover.html\", []).run([\"$templateCache\", function ($templateCache) {\n $templateCache.put(\"uib/template/popover/popover.html\", \"
    \\n\" + \"\\n\" + \"
    \\n\" + \"

    \\n\" + \"
    \\n\" + \"
    \\n\" + \"\");\n}]);\nangular.module('ui.bootstrap.tooltip').run(function () {\n !angular.$$csp().noInlineStyle && !angular.$$uibTooltipCss && angular.element(document).find('head').prepend('');\n angular.$$uibTooltipCss = true;\n});\nangular.module('ui.bootstrap.position').run(function () {\n !angular.$$csp().noInlineStyle && !angular.$$uibPositionCss && angular.element(document).find('head').prepend('');\n angular.$$uibPositionCss = true;\n});","import './styles/ui-popover.css';\nimport './ui-bootstrap-custom-tpls-2.5.0.js';\nexport default 'ui.bootstrap';","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","/**!\n * AngularJS file upload/drop directive and service with progress and abort\n * FileAPI Flash shim for old browsers not supporting FormData\n * @author Danial \n * @version 6.1.0\n */\n\n(function () {\n /** @namespace FileAPI.noContentTimeout */\n\n function patchXHR(fnName, newFn) {\n window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);\n }\n\n function redefineProp(xhr, prop, fn) {\n try {\n Object.defineProperty(xhr, prop, {get: fn});\n } catch (e) {/*ignore*/\n }\n }\n\n if (!window.FileAPI) {\n window.FileAPI = {};\n }\n\n FileAPI.shouldLoad = (window.XMLHttpRequest && !window.FormData) || FileAPI.forceLoad;\n if (FileAPI.shouldLoad) {\n var initializeUploadListener = function (xhr) {\n if (!xhr.__listeners) {\n if (!xhr.upload) xhr.upload = {};\n xhr.__listeners = [];\n var origAddEventListener = xhr.upload.addEventListener;\n xhr.upload.addEventListener = function (t, fn) {\n xhr.__listeners[t] = fn;\n if (origAddEventListener) origAddEventListener.apply(this, arguments);\n };\n }\n };\n\n patchXHR('open', function (orig) {\n return function (m, url, b) {\n initializeUploadListener(this);\n this.__url = url;\n try {\n orig.apply(this, [m, url, b]);\n } catch (e) {\n if (e.message.indexOf('Access is denied') > -1) {\n this.__origError = e;\n orig.apply(this, [m, '_fix_for_ie_crossdomain__', b]);\n }\n }\n };\n });\n\n patchXHR('getResponseHeader', function (orig) {\n return function (h) {\n return this.__fileApiXHR && this.__fileApiXHR.getResponseHeader ? this.__fileApiXHR.getResponseHeader(h) : (orig == null ? null : orig.apply(this, [h]));\n };\n });\n\n patchXHR('getAllResponseHeaders', function (orig) {\n return function () {\n return this.__fileApiXHR && this.__fileApiXHR.getAllResponseHeaders ? this.__fileApiXHR.getAllResponseHeaders() : (orig == null ? null : orig.apply(this));\n };\n });\n\n patchXHR('abort', function (orig) {\n return function () {\n return this.__fileApiXHR && this.__fileApiXHR.abort ? this.__fileApiXHR.abort() : (orig == null ? null : orig.apply(this));\n };\n });\n\n patchXHR('setRequestHeader', function (orig) {\n return function (header, value) {\n if (header === '__setXHR_') {\n initializeUploadListener(this);\n var val = value(this);\n // fix for angular < 1.2.0\n if (val instanceof Function) {\n val(this);\n }\n } else {\n this.__requestHeaders = this.__requestHeaders || {};\n this.__requestHeaders[header] = value;\n orig.apply(this, arguments);\n }\n };\n });\n\n patchXHR('send', function (orig) {\n return function () {\n var xhr = this;\n if (arguments[0] && arguments[0].__isFileAPIShim) {\n var formData = arguments[0];\n var config = {\n url: xhr.__url,\n jsonp: false, //removes the callback form param\n cache: true, //removes the ?fileapiXXX in the url\n complete: function (err, fileApiXHR) {\n xhr.__completed = true;\n if (!err && xhr.__listeners.load)\n xhr.__listeners.load({\n type: 'load',\n loaded: xhr.__loaded,\n total: xhr.__total,\n target: xhr,\n lengthComputable: true\n });\n if (!err && xhr.__listeners.loadend)\n xhr.__listeners.loadend({\n type: 'loadend',\n loaded: xhr.__loaded,\n total: xhr.__total,\n target: xhr,\n lengthComputable: true\n });\n if (err === 'abort' && xhr.__listeners.abort)\n xhr.__listeners.abort({\n type: 'abort',\n loaded: xhr.__loaded,\n total: xhr.__total,\n target: xhr,\n lengthComputable: true\n });\n if (fileApiXHR.status !== undefined) redefineProp(xhr, 'status', function () {\n return (fileApiXHR.status === 0 && err && err !== 'abort') ? 500 : fileApiXHR.status;\n });\n if (fileApiXHR.statusText !== undefined) redefineProp(xhr, 'statusText', function () {\n return fileApiXHR.statusText;\n });\n redefineProp(xhr, 'readyState', function () {\n return 4;\n });\n if (fileApiXHR.response !== undefined) redefineProp(xhr, 'response', function () {\n return fileApiXHR.response;\n });\n var resp = fileApiXHR.responseText || (err && fileApiXHR.status === 0 && err !== 'abort' ? err : undefined);\n redefineProp(xhr, 'responseText', function () {\n return resp;\n });\n redefineProp(xhr, 'response', function () {\n return resp;\n });\n if (err) redefineProp(xhr, 'err', function () {\n return err;\n });\n xhr.__fileApiXHR = fileApiXHR;\n if (xhr.onreadystatechange) xhr.onreadystatechange();\n if (xhr.onload) xhr.onload();\n },\n progress: function (e) {\n e.target = xhr;\n if (xhr.__listeners.progress) xhr.__listeners.progress(e);\n xhr.__total = e.total;\n xhr.__loaded = e.loaded;\n if (e.total === e.loaded) {\n // fix flash issue that doesn't call complete if there is no response text from the server\n var _this = this;\n setTimeout(function () {\n if (!xhr.__completed) {\n xhr.getAllResponseHeaders = function () {\n };\n _this.complete(null, {status: 204, statusText: 'No Content'});\n }\n }, FileAPI.noContentTimeout || 10000);\n }\n },\n headers: xhr.__requestHeaders\n };\n config.data = {};\n config.files = {};\n for (var i = 0; i < formData.data.length; i++) {\n var item = formData.data[i];\n if (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) {\n config.files[item.key] = item.val;\n } else {\n config.data[item.key] = item.val;\n }\n }\n\n setTimeout(function () {\n if (!FileAPI.hasFlash) {\n throw 'Adode Flash Player need to be installed. To check ahead use \"FileAPI.hasFlash\"';\n }\n xhr.__fileApiXHR = FileAPI.upload(config);\n }, 1);\n } else {\n if (this.__origError) {\n throw this.__origError;\n }\n orig.apply(xhr, arguments);\n }\n };\n });\n window.XMLHttpRequest.__isFileAPIShim = true;\n window.FormData = FormData = function () {\n return {\n append: function (key, val, name) {\n if (val.__isFileAPIBlobShim) {\n val = val.data[0];\n }\n this.data.push({\n key: key,\n val: val,\n name: name\n });\n },\n data: [],\n __isFileAPIShim: true\n };\n };\n\n window.Blob = Blob = function (b) {\n return {\n data: b,\n __isFileAPIBlobShim: true\n };\n };\n }\n\n})();\n\n(function () {\n /** @namespace FileAPI.forceLoad */\n /** @namespace window.FileAPI.jsUrl */\n /** @namespace window.FileAPI.jsPath */\n\n function isInputTypeFile(elem) {\n return elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';\n }\n\n function hasFlash() {\n try {\n var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');\n if (fo) return true;\n } catch (e) {\n if (navigator.mimeTypes['application/x-shockwave-flash'] !== undefined) return true;\n }\n return false;\n }\n\n function getOffset(obj) {\n var left = 0, top = 0;\n\n if (window.jQuery) {\n return jQuery(obj).offset();\n }\n\n if (obj.offsetParent) {\n do {\n left += (obj.offsetLeft - obj.scrollLeft);\n top += (obj.offsetTop - obj.scrollTop);\n obj = obj.offsetParent;\n } while (obj);\n }\n return {\n left: left,\n top: top\n };\n }\n\n if (FileAPI.shouldLoad) {\n\n //load FileAPI\n if (FileAPI.forceLoad) {\n FileAPI.html5 = false;\n }\n\n if (!FileAPI.upload) {\n var jsUrl, basePath, script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index, src;\n if (window.FileAPI.jsUrl) {\n jsUrl = window.FileAPI.jsUrl;\n } else if (window.FileAPI.jsPath) {\n basePath = window.FileAPI.jsPath;\n } else {\n for (i = 0; i < allScripts.length; i++) {\n src = allScripts[i].src;\n index = src.search(/\\/ng\\-file\\-upload[\\-a-zA-z0-9\\.]*\\.js/);\n if (index > -1) {\n basePath = src.substring(0, index + 1);\n break;\n }\n }\n }\n\n if (FileAPI.staticPath == null) FileAPI.staticPath = basePath;\n script.setAttribute('src', jsUrl || basePath + 'FileAPI.min.js');\n document.getElementsByTagName('head')[0].appendChild(script);\n\n FileAPI.hasFlash = hasFlash();\n }\n\n FileAPI.ngfFixIE = function (elem, createFileElemFn, bindAttr, changeFn) {\n if (!hasFlash()) {\n throw 'Adode Flash Player need to be installed. To check ahead use \"FileAPI.hasFlash\"';\n }\n var makeFlashInput = function () {\n if (elem.attr('disabled')) {\n elem.$$ngfRefElem.removeClass('js-fileapi-wrapper');\n } else {\n var fileElem = elem.$$ngfRefElem;\n if (!fileElem) {\n fileElem = elem.$$ngfRefElem = createFileElemFn();\n fileElem.addClass('js-fileapi-wrapper');\n if (!isInputTypeFile(elem)) {\n//\t\t\t\t\t\tif (fileElem.parent().css('position') === '' || fileElem.parent().css('position') === 'static') {\n//\t\t\t\t\t\t\tfileElem.parent().css('position', 'relative');\n//\t\t\t\t\t\t}\n//\t\t\t\t\t\telem.parent()[0].insertBefore(fileElem[0], elem[0]);\n//\t\t\t\t\t\telem.css('overflow', 'hidden');\n }\n setTimeout(function () {\n fileElem.bind('mouseenter', makeFlashInput);\n }, 10);\n fileElem.bind('change', function (evt) {\n fileApiChangeFn.apply(this, [evt]);\n changeFn.apply(this, [evt]);\n//\t\t\t\t\t\talert('change' + evt);\n });\n } else {\n bindAttr(elem.$$ngfRefElem);\n }\n if (!isInputTypeFile(elem)) {\n fileElem.css('position', 'absolute')\n .css('top', getOffset(elem[0]).top + 'px').css('left', getOffset(elem[0]).left + 'px')\n .css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')\n .css('filter', 'alpha(opacity=0)').css('display', elem.css('display'))\n .css('overflow', 'hidden').css('z-index', '900000')\n .css('visibility', 'visible');\n }\n }\n };\n\n elem.bind('mouseenter', makeFlashInput);\n\n var fileApiChangeFn = function (evt) {\n var files = FileAPI.getFiles(evt);\n //just a double check for #233\n for (var i = 0; i < files.length; i++) {\n if (files[i].size === undefined) files[i].size = 0;\n if (files[i].name === undefined) files[i].name = 'file';\n if (files[i].type === undefined) files[i].type = 'undefined';\n }\n if (!evt.target) {\n evt.target = {};\n }\n evt.target.files = files;\n // if evt.target.files is not writable use helper field\n if (evt.target.files !== files) {\n evt.__files_ = files;\n }\n (evt.__files_ || evt.target.files).item = function (i) {\n return (evt.__files_ || evt.target.files)[i] || null;\n };\n };\n };\n\n FileAPI.disableFileInput = function (elem, disable) {\n if (disable) {\n elem.removeClass('js-fileapi-wrapper');\n } else {\n elem.addClass('js-fileapi-wrapper');\n }\n };\n }\n})();\n\nif (!window.FileReader) {\n window.FileReader = function () {\n var _this = this, loadStarted = false;\n this.listeners = {};\n this.addEventListener = function (type, fn) {\n _this.listeners[type] = _this.listeners[type] || [];\n _this.listeners[type].push(fn);\n };\n this.removeEventListener = function (type, fn) {\n if (_this.listeners[type]) _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1);\n };\n this.dispatchEvent = function (evt) {\n var list = _this.listeners[evt.type];\n if (list) {\n for (var i = 0; i < list.length; i++) {\n list[i].call(_this, evt);\n }\n }\n };\n this.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null;\n\n var constructEvent = function (type, evt) {\n var e = {type: type, target: _this, loaded: evt.loaded, total: evt.total, error: evt.error};\n if (evt.result != null) e.target.result = evt.result;\n return e;\n };\n var listener = function (evt) {\n if (!loadStarted) {\n loadStarted = true;\n if (_this.onloadstart) _this.onloadstart(constructEvent('loadstart', evt));\n }\n var e;\n if (evt.type === 'load') {\n if (_this.onloadend) _this.onloadend(constructEvent('loadend', evt));\n e = constructEvent('load', evt);\n if (_this.onload) _this.onload(e);\n _this.dispatchEvent(e);\n } else if (evt.type === 'progress') {\n e = constructEvent('progress', evt);\n if (_this.onprogress) _this.onprogress(e);\n _this.dispatchEvent(e);\n } else {\n e = constructEvent('error', evt);\n if (_this.onerror) _this.onerror(e);\n _this.dispatchEvent(e);\n }\n };\n this.readAsArrayBuffer = function (file) {\n FileAPI.readAsBinaryString(file, listener);\n };\n this.readAsBinaryString = function (file) {\n FileAPI.readAsBinaryString(file, listener);\n };\n this.readAsDataURL = function (file) {\n FileAPI.readAsDataURL(file, listener);\n };\n this.readAsText = function (file) {\n FileAPI.readAsText(file, listener);\n };\n };\n}\n\n/**!\n * AngularJS file upload/drop directive and service with progress and abort\n * @author Danial \n * @version 6.1.0\n */\n\nif (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {\n window.XMLHttpRequest.prototype.setRequestHeader = (function (orig) {\n return function (header, value) {\n if (header === '__setXHR_') {\n var val = value(this);\n // fix for angular < 1.2.0\n if (val instanceof Function) {\n val(this);\n }\n } else {\n orig.apply(this, arguments);\n }\n };\n })(window.XMLHttpRequest.prototype.setRequestHeader);\n}\n\nvar ngFileUpload = angular.module('ngFileUpload', []);\n\nngFileUpload.version = '6.1.0';\nngFileUpload.defaults = {};\n\nngFileUpload.service('Upload', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {\n function sendHttp(config) {\n config.method = config.method || 'POST';\n config.headers = config.headers || {};\n\n var deferred = $q.defer();\n var promise = deferred.promise;\n\n config.headers.__setXHR_ = function () {\n return function (xhr) {\n if (!xhr) return;\n config.__XHR = xhr;\n if (config.xhrFn) config.xhrFn(xhr);\n xhr.upload.addEventListener('progress', function (e) {\n e.config = config;\n if (deferred.notify) {\n deferred.notify(e);\n } else if (promise.progressFunc) {\n $timeout(function () {\n promise.progressFunc(e);\n });\n }\n }, false);\n //fix for firefox not firing upload progress end, also IE8-9\n xhr.upload.addEventListener('load', function (e) {\n if (e.lengthComputable) {\n e.config = config;\n if (deferred.notify) {\n deferred.notify(e);\n } else if (promise.progressFunc) {\n $timeout(function () {\n promise.progressFunc(e);\n });\n }\n }\n }, false);\n };\n };\n\n $http(config).then(function (r) {\n deferred.resolve(r);\n }, function (e) {\n deferred.reject(e);\n }, function (n) {\n deferred.notify(n);\n });\n\n promise.success = function (fn) {\n promise.then(function (response) {\n fn(response.data, response.status, response.headers, config);\n });\n return promise;\n };\n\n promise.error = function (fn) {\n promise.then(null, function (response) {\n fn(response.data, response.status, response.headers, config);\n });\n return promise;\n };\n\n promise.progress = function (fn) {\n promise.progressFunc = fn;\n promise.then(null, null, function (update) {\n fn(update);\n });\n return promise;\n };\n promise.abort = function () {\n if (config.__XHR) {\n $timeout(function () {\n config.__XHR.abort();\n });\n }\n return promise;\n };\n promise.xhr = function (fn) {\n config.xhrFn = (function (origXhrFn) {\n return function () {\n if (origXhrFn) origXhrFn.apply(promise, arguments);\n fn.apply(promise, arguments);\n };\n })(config.xhrFn);\n return promise;\n };\n\n return promise;\n }\n\n this.upload = function (config) {\n function addFieldToFormData(formData, val, key) {\n if (val !== undefined) {\n if (angular.isDate(val)) {\n val = val.toISOString();\n }\n if (angular.isString(val)) {\n formData.append(key, val);\n } else if (config.sendFieldsAs === 'form') {\n if (angular.isObject(val)) {\n for (var k in val) {\n if (val.hasOwnProperty(k)) {\n addFieldToFormData(formData, val[k], key + '[' + k + ']');\n }\n }\n } else {\n formData.append(key, val);\n }\n } else {\n val = angular.isString(val) ? val : JSON.stringify(val);\n if (config.sendFieldsAs === 'json-blob') {\n formData.append(key, new Blob([val], {type: 'application/json'}));\n } else {\n formData.append(key, val);\n }\n }\n }\n }\n\n config.headers = config.headers || {};\n config.headers['Content-Type'] = undefined;\n config.transformRequest = config.transformRequest ?\n (angular.isArray(config.transformRequest) ?\n config.transformRequest : [config.transformRequest]) : [];\n config.transformRequest.push(function (data) {\n var formData = new FormData();\n var allFields = {};\n var key;\n for (key in config.fields) {\n if (config.fields.hasOwnProperty(key)) {\n allFields[key] = config.fields[key];\n }\n }\n if (data) allFields.data = data;\n for (key in allFields) {\n if (allFields.hasOwnProperty(key)) {\n var val = allFields[key];\n if (config.formDataAppender) {\n config.formDataAppender(formData, key, val);\n } else {\n addFieldToFormData(formData, val, key);\n }\n }\n }\n\n if (config.file != null) {\n var fileFormName = config.fileFormDataName || 'file';\n\n if (angular.isArray(config.file)) {\n var isFileFormNameString = angular.isString(fileFormName);\n for (var i = 0; i < config.file.length; i++) {\n formData.append(isFileFormNameString ? fileFormName : fileFormName[i], config.file[i],\n (config.fileName && config.fileName[i]) || config.file[i].name);\n }\n } else {\n formData.append(fileFormName, config.file, config.fileName || config.file.name);\n }\n }\n return formData;\n });\n\n return sendHttp(config);\n };\n\n this.http = function (config) {\n config.transformRequest = config.transformRequest || function (data) {\n if ((window.ArrayBuffer && data instanceof window.ArrayBuffer) || data instanceof Blob) {\n return data;\n }\n return $http.defaults.transformRequest[0](arguments);\n };\n return sendHttp(config);\n };\n\n this.dataUrl = function (file, callback, disallowObjectUrl) {\n if (window.FileReader && file &&\n (!window.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) &&\n (!window.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) {\n $timeout(function () {\n //prefer URL.createObjectURL for handling refrences to files of all sizes\n //since it doesn´t build a large string in memory\n var URL = window.URL || window.webkitURL;\n if (URL && URL.createObjectURL && !disallowObjectUrl) {\n callback(URL.createObjectURL(file));\n } else {\n var fileReader = new FileReader();\n fileReader.readAsDataURL(file);\n fileReader.onload = function (e) {\n $timeout(function () {\n callback(e.target.result);\n });\n };\n }\n });\n } else {\n callback(null);\n }\n };\n\n this.setDefaults = function(defaults) {\n ngFileUpload.defaults = defaults || {};\n };\n}\n\n]);\n\n(function () {\n ngFileUpload.getAttrWithDefaults = function(attr, name) {\n return attr[name] != null ? attr[name] :\n (ngFileUpload.defaults[name] == null ?\n ngFileUpload.defaults[name] : ngFileUpload.defaults[name].toString());\n };\n\n var getAttr = ngFileUpload.getAttrWithDefaults;\n\n ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile',\n function ($parse, $timeout, $compile) {\n return {\n restrict: 'AEC',\n require: '?ngModel',\n link: function (scope, elem, attr, ngModel) {\n linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile);\n }\n };\n }]);\n\n function linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile) {\n /** @namespace attr.ngfSelect */\n /** @namespace attr.ngfChange */\n /** @namespace attr.ngModel */\n /** @namespace attr.ngModelRejected */\n /** @namespace attr.ngfModel */\n /** @namespace attr.ngfMultiple */\n /** @namespace attr.ngfCapture */\n /** @namespace attr.ngfAccept */\n /** @namespace attr.ngfValidate */\n /** @namespace attr.ngfMaxSize */\n /** @namespace attr.ngfMinSize */\n /** @namespace attr.ngfResetOnClick */\n /** @namespace attr.ngfResetModelOnClick */\n /** @namespace attr.ngfKeep */\n /** @namespace attr.ngfKeepDistinct */\n\n if (elem.attr('__ngf_gen__')) {\n return;\n }\n\n scope.$on('$destroy', function () {\n if (elem.$$ngfRefElem) elem.$$ngfRefElem.remove();\n });\n\n var disabled = false;\n if (getAttr(attr, 'ngfSelect').search(/\\W+\\$files\\W+/) === -1) {\n scope.$watch(getAttr(attr, 'ngfSelect'), function (val) {\n disabled = val === false;\n });\n }\n function isInputTypeFile() {\n return elem[0].tagName.toLowerCase() === 'input' && attr.type && attr.type.toLowerCase() === 'file';\n }\n\n var isUpdating = false;\n\n function changeFn(evt) {\n if (!isUpdating) {\n isUpdating = true;\n try {\n var fileList = evt.__files_ || (evt.target && evt.target.files);\n var files = [], rejFiles = [];\n\n for (var i = 0; i < fileList.length; i++) {\n var file = fileList.item(i);\n if (validate(scope, $parse, attr, file, evt)) {\n files.push(file);\n } else {\n rejFiles.push(file);\n }\n }\n updateModel($parse, $timeout, scope, ngModel, attr,\n getAttr(attr, 'ngfChange') || getAttr(attr, 'ngfSelect'), files, rejFiles, evt);\n if (files.length === 0) evt.target.value = files;\n// if (evt.target && evt.target.getAttribute('__ngf_gen__')) {\n// angular.element(evt.target).remove();\n// }\n } finally {\n isUpdating = false;\n }\n }\n }\n\n function bindAttrToFileInput(fileElem) {\n if (getAttr(attr, 'ngfMultiple')) fileElem.attr('multiple', $parse(getAttr(attr, 'ngfMultiple'))(scope));\n if (getAttr(attr, 'ngfCapture')) fileElem.attr('capture', $parse(getAttr(attr, 'ngfCapture'))(scope));\n if (getAttr(attr, 'accept')) fileElem.attr('accept', getAttr(attr, 'accept'));\n for (var i = 0; i < elem[0].attributes.length; i++) {\n var attribute = elem[0].attributes[i];\n if ((isInputTypeFile() && attribute.name !== 'type') ||\n (attribute.name !== 'type' && attribute.name !== 'class' &&\n attribute.name !== 'id' && attribute.name !== 'style')) {\n if (attribute.value == null || attribute.value === '') {\n if (attribute.name === 'required') attribute.value = 'required';\n if (attribute.name === 'multiple') attribute.value = 'multiple';\n }\n fileElem.attr(attribute.name, attribute.value);\n }\n }\n }\n\n function createFileInput(evt, resetOnClick) {\n if (!resetOnClick && (evt || isInputTypeFile())) return elem.$$ngfRefElem || elem;\n if (elem.$$ngfProgramClick) return elem;\n\n var fileElem = angular.element('');\n bindAttrToFileInput(fileElem);\n\n if (isInputTypeFile()) {\n elem.replaceWith(fileElem);\n elem = fileElem;\n fileElem.attr('__ngf_gen__', true);\n $compile(elem)(scope);\n } else {\n fileElem.css('visibility', 'hidden').css('position', 'absolute').css('overflow', 'hidden')\n .css('width', '0px').css('height', '0px').css('border', 'none')\n .css('margin', '0px').css('padding', '0px').attr('tabindex', '-1');\n if (elem.$$ngfRefElem) {\n elem.$$ngfRefElem.remove();\n }\n elem.$$ngfRefElem = fileElem;\n document.body.appendChild(fileElem[0]);\n }\n\n return fileElem;\n }\n\n function resetModel(evt) {\n updateModel($parse, $timeout, scope, ngModel, attr,\n getAttr(attr, 'ngfChange') || getAttr(attr, 'ngfSelect'), [], [], evt, true);\n }\n\n var initialTouchStartY = 0;\n function clickHandler(evt) {\n if (elem.attr('disabled') || disabled) return false;\n\n if (evt != null) {\n var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches);\n if (evt.type === 'touchstart') {\n initialTouchStartY = touches ? touches[0].clientY : 0;\n return true; // don't block event default\n } else {\n evt.stopPropagation();\n evt.preventDefault();\n\n // prevent scroll from triggering event\n if (evt.type === 'touchend') {\n var currentLocation = touches ? touches[0].clientY : 0;\n if (Math.abs(currentLocation - initialTouchStartY) > 20) return false;\n }\n }\n }\n\n var resetOnClick = $parse(getAttr(attr, 'ngfResetOnClick'))(scope) !== false;\n var fileElem = createFileInput(evt, resetOnClick);\n\n function clickAndAssign(evt) {\n if (evt && !elem.$$ngfProgramClick) {\n elem.$$ngfProgramClick = true;\n fileElem[0].click();\n $timeout(function() {\n delete elem.$$ngfProgramClick;\n }, 500);\n }\n if ((isInputTypeFile() || !evt) && resetOnClick) {\n elem.bind('click touchstart touchend', clickHandler);\n }\n }\n\n if (fileElem) {\n if (!evt || resetOnClick) fileElem.bind('change', changeFn);\n if (evt && resetOnClick && $parse(getAttr(attr, 'ngfResetModelOnClick'))(scope) !== false) {\n resetModel(evt);\n }\n\n // fix for android native browser < 4.4\n if (shouldClickLater(navigator.userAgent)) {\n setTimeout(function () {\n clickAndAssign(evt);\n }, 0);\n } else {\n clickAndAssign(evt);\n }\n }\n\n return false;\n }\n\n if (window.FileAPI && window.FileAPI.ngfFixIE) {\n window.FileAPI.ngfFixIE(elem, createFileInput, bindAttrToFileInput, changeFn);\n } else {\n clickHandler();\n //if (!isInputTypeFile()) {\n // elem.bind('click touchend', clickHandler);\n //}\n }\n }\n\n function shouldClickLater(ua) {\n // android below 4.4\n var m = ua.match(/Android[^\\d]*(\\d+)\\.(\\d+)/);\n if (m && m.length > 2) {\n var v = ngFileUpload.defaults.androidFixMinorVersion || 4;\n return parseInt(m[1]) < 4 || (parseInt(m[1]) === v && parseInt(m[2]) < v);\n }\n\n // safari on windows\n return ua.indexOf('Chrome') === -1 && /.*Windows.*Safari.*/.test(ua);\n }\n\n ngFileUpload.validate = function (scope, $parse, attr, file, evt) {\n if (file == null) {\n return false;\n }\n function globStringToRegex(str) {\n if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {\n return str.substring(1, str.length - 1);\n }\n var split = str.split(','), result = '';\n if (split.length > 1) {\n for (var i = 0; i < split.length; i++) {\n result += '(' + globStringToRegex(split[i]) + ')';\n if (i < split.length - 1) {\n result += '|';\n }\n }\n } else {\n if (str.indexOf('.') === 0) {\n str = '*' + str;\n }\n result = '^' + str.replace(new RegExp('[.\\\\\\\\+*?\\\\[\\\\^\\\\]$(){}=!<>|:\\\\' + '-]', 'g'), '\\\\$&') + '$';\n result = result.replace(/\\\\\\*/g, '.*').replace(/\\\\\\?/g, '.');\n }\n return result;\n }\n\n var custom = $parse(getAttr(attr, 'ngfValidate'))(scope, {$file: file, $event: evt});\n if (custom != null && (custom === false || custom.length > 0)) {\n file.$error = custom ? custom : 'validate';\n return false;\n }\n var accept = $parse(getAttr(attr, 'ngfAccept'))(scope, {$file: file, $event: evt});\n var fileSizeMax = $parse(getAttr(attr, 'ngfMaxSize'))(scope, {$file: file, $event: evt}) || 9007199254740991;\n var fileSizeMin = $parse(getAttr(attr, 'ngfMinSize'))(scope, {$file: file, $event: evt}) || -1;\n if (accept != null && angular.isString(accept)) {\n var regexp = new RegExp(globStringToRegex(accept), 'gi');\n accept = (file.type != null && regexp.test(file.type.toLowerCase())) ||\n (file.name != null && regexp.test(file.name.toLowerCase()));\n if (!accept) {\n file.$error = 'accept';\n return false;\n }\n } else {\n if (accept === false) {\n file.$error = 'accept';\n return false;\n }\n }\n if (file.size == null) return true;\n if (file.size > fileSizeMax) {\n file.$error = 'maxSize';\n return false;\n }\n if (file.size < fileSizeMin) {\n file.$error = 'minSize';\n return false;\n }\n return true;\n };\n\n ngFileUpload.updateModel = function ($parse, $timeout, scope, ngModel, attr, fileChange,\n files, rejFiles, evt, noDelay) {\n function update() {\n var keep = $parse(getAttr(attr, 'ngfKeep'))(scope);\n if (keep === true) {\n var prevFiles = (ngModel.$modelValue || []).slice(0);\n if (!files || !files.length) {\n files = prevFiles;\n } else if ($parse(getAttr(attr, 'ngfKeepDistinct'))(scope) === true) {\n var len = prevFiles.length;\n for (var i = 0; i < files.length; i++) {\n for (var j = 0; j < len; j++) {\n if (files[i].name === prevFiles[j].name) break;\n }\n if (j === len) {\n prevFiles.push(files[i]);\n }\n }\n files = prevFiles;\n } else {\n files = prevFiles.concat(files);\n }\n }\n var file = files && files.length ? files[0] : null;\n if (ngModel) {\n var singleModel = !$parse(getAttr(attr, 'ngfMultiple'))(scope) && ! getAttr(attr, 'multiple') && !keep;\n $parse(getAttr(attr, 'ngModel')).assign(scope, singleModel ? file : files);\n $timeout(function () {\n if (ngModel) {\n ngModel.$setViewValue(singleModel ? file : (files != null && files.length === 0 ? null : files));\n }\n });\n }\n var ngfModel = getAttr(attr, 'ngfModel');\n if (ngfModel) {\n $parse(ngfModel).assign(scope, files);\n }\n\n if (getAttr(attr, 'ngModelRejected')) {\n $parse(getAttr(attr, 'ngModelRejected')).assign(scope, rejFiles);\n }\n if (fileChange) {\n $parse(fileChange)(scope, {\n $files: files,\n $file: file,\n $rejectedFiles: rejFiles,\n $event: evt\n });\n }\n }\n\n if (noDelay) {\n update();\n } else {\n $timeout(function () {\n update();\n });\n }\n };\n\n var validate = ngFileUpload.validate;\n var updateModel = ngFileUpload.updateModel;\n\n})();\n\n(function () {\n var validate = ngFileUpload.validate;\n var updateModel = ngFileUpload.updateModel;\n var getAttr = ngFileUpload.getAttrWithDefaults;\n\n ngFileUpload.directive('ngfDrop', ['$parse', '$timeout', '$location', function ($parse, $timeout, $location) {\n return {\n restrict: 'AEC',\n require: '?ngModel',\n link: function (scope, elem, attr, ngModel) {\n linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location);\n }\n };\n }]);\n\n ngFileUpload.directive('ngfNoFileDrop', function () {\n return function (scope, elem) {\n if (dropAvailable()) elem.css('display', 'none');\n };\n });\n\n ngFileUpload.directive('ngfDropAvailable', ['$parse', '$timeout', function ($parse, $timeout) {\n return function (scope, elem, attr) {\n if (dropAvailable()) {\n var fn = $parse(getAttr(attr, 'ngfDropAvailable'));\n $timeout(function () {\n fn(scope);\n if (fn.assign) {\n fn.assign(scope, true);\n }\n });\n }\n };\n }]);\n\n function linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location) {\n var available = dropAvailable();\n if (getAttr(attr, 'dropAvailable')) {\n $timeout(function () {\n if (scope[getAttr(attr, 'dropAvailable')]) {\n scope[getAttr(attr, 'dropAvailable')].value = available;\n } else {\n scope[getAttr(attr, 'dropAvailable')] = available;\n }\n });\n }\n if (!available) {\n if ($parse(getAttr(attr, 'ngfHideOnDropNotAvailable'))(scope) === true) {\n elem.css('display', 'none');\n }\n return;\n }\n\n var disabled = false;\n if (getAttr(attr, 'ngfDrop').search(/\\W+\\$files\\W+/) === -1) {\n scope.$watch(getAttr(attr, 'ngfDrop'), function(val) {\n disabled = val === false;\n });\n }\n\n var leaveTimeout = null;\n var stopPropagation = $parse(getAttr(attr, 'ngfStopPropagation'));\n var dragOverDelay = 1;\n var actualDragOverClass;\n\n elem[0].addEventListener('dragover', function (evt) {\n if (elem.attr('disabled') || disabled) return;\n evt.preventDefault();\n if (stopPropagation(scope)) evt.stopPropagation();\n // handling dragover events from the Chrome download bar\n if (navigator.userAgent.indexOf('Chrome') > -1) {\n var b = evt.dataTransfer.effectAllowed;\n evt.dataTransfer.dropEffect = ('move' === b || 'linkMove' === b) ? 'move' : 'copy';\n }\n $timeout.cancel(leaveTimeout);\n if (!scope.actualDragOverClass) {\n actualDragOverClass = calculateDragOverClass(scope, attr, evt);\n }\n elem.addClass(actualDragOverClass);\n }, false);\n elem[0].addEventListener('dragenter', function (evt) {\n if (elem.attr('disabled') || disabled) return;\n evt.preventDefault();\n if (stopPropagation(scope)) evt.stopPropagation();\n }, false);\n elem[0].addEventListener('dragleave', function () {\n if (elem.attr('disabled') || disabled) return;\n leaveTimeout = $timeout(function () {\n elem.removeClass(actualDragOverClass);\n actualDragOverClass = null;\n }, dragOverDelay || 1);\n }, false);\n elem[0].addEventListener('drop', function (evt) {\n if (elem.attr('disabled') || disabled) return;\n evt.preventDefault();\n if (stopPropagation(scope)) evt.stopPropagation();\n elem.removeClass(actualDragOverClass);\n actualDragOverClass = null;\n extractFiles(evt, function (files, rejFiles) {\n updateModel($parse, $timeout, scope, ngModel, attr,\n getAttr(attr, 'ngfChange') || getAttr(attr, 'ngfDrop'), files, rejFiles, evt);\n }, $parse(getAttr(attr, 'ngfAllowDir'))(scope) !== false,\n getAttr(attr, 'multiple') || $parse(getAttr(attr, 'ngfMultiple'))(scope));\n }, false);\n elem[0].addEventListener('paste', function (evt) {\n if (elem.attr('disabled') || disabled) return;\n extractFiles(evt, function (files, rejFiles) {\n updateModel($parse, $timeout, scope, ngModel, attr,\n getAttr(attr, 'ngfChange') || getAttr(attr, 'ngfDrop'), files, rejFiles, evt);\n }, false, getAttr(attr, 'multiple') || $parse(getAttr(attr, 'ngfMultiple'))(scope));\n }, false);\n\n function calculateDragOverClass(scope, attr, evt) {\n var accepted = true;\n var items = evt.dataTransfer.items;\n if (items != null) {\n for (var i = 0; i < items.length && accepted; i++) {\n accepted = accepted &&\n (items[i].kind === 'file' || items[i].kind === '') &&\n validate(scope, $parse, attr, items[i], evt);\n }\n }\n var clazz = $parse(getAttr(attr, 'ngfDragOverClass'))(scope, {$event: evt});\n if (clazz) {\n if (clazz.delay) dragOverDelay = clazz.delay;\n if (clazz.accept) clazz = accepted ? clazz.accept : clazz.reject;\n }\n return clazz || getAttr(attr, 'ngfDragOverClass') || 'dragover';\n }\n\n function extractFiles(evt, callback, allowDir, multiple) {\n var files = [], rejFiles = [], processing = 0;\n\n function addFile(file) {\n if (validate(scope, $parse, attr, file, evt)) {\n files.push(file);\n } else {\n rejFiles.push(file);\n }\n }\n\n function traverseFileTree(files, entry, path) {\n if (entry != null) {\n if (entry.isDirectory) {\n var filePath = (path || '') + entry.name;\n addFile({name: entry.name, type: 'directory', path: filePath});\n var dirReader = entry.createReader();\n var entries = [];\n processing++;\n var readEntries = function () {\n dirReader.readEntries(function (results) {\n try {\n if (!results.length) {\n for (var i = 0; i < entries.length; i++) {\n traverseFileTree(files, entries[i], (path ? path : '') + entry.name + '/');\n }\n processing--;\n } else {\n entries = entries.concat(Array.prototype.slice.call(results || [], 0));\n readEntries();\n }\n } catch (e) {\n processing--;\n console.error(e);\n }\n }, function () {\n processing--;\n });\n };\n readEntries();\n } else {\n processing++;\n entry.file(function (file) {\n try {\n processing--;\n file.path = (path ? path : '') + file.name;\n addFile(file);\n } catch (e) {\n processing--;\n console.error(e);\n }\n }, function () {\n processing--;\n });\n }\n }\n }\n\n if (evt.type === 'paste') {\n var clipboard = evt.clipboardData || evt.originalEvent.clipboardData;\n if (clipboard && clipboard.items) {\n for (var k = 0; k < clipboard.items.length; k++) {\n if (clipboard.items[k].type.indexOf('image') !== -1) {\n addFile(clipboard.items[k].getAsFile());\n }\n }\n callback(files, rejFiles);\n }\n } else {\n var items = evt.dataTransfer.items;\n\n if (items && items.length > 0 && $location.protocol() !== 'file') {\n for (var i = 0; i < items.length; i++) {\n if (items[i].webkitGetAsEntry && items[i].webkitGetAsEntry() && items[i].webkitGetAsEntry().isDirectory) {\n var entry = items[i].webkitGetAsEntry();\n if (entry.isDirectory && !allowDir) {\n continue;\n }\n if (entry != null) {\n traverseFileTree(files, entry);\n }\n } else {\n var f = items[i].getAsFile();\n if (f != null) addFile(f);\n }\n if (!multiple && files.length > 0) break;\n }\n } else {\n var fileList = evt.dataTransfer.files;\n if (fileList != null) {\n for (var j = 0; j < fileList.length; j++) {\n addFile(fileList.item(j));\n if (!multiple && files.length > 0) {\n break;\n }\n }\n }\n }\n var delays = 0;\n (function waitForProcess(delay) {\n $timeout(function () {\n if (!processing) {\n if (!multiple && files.length > 1) {\n i = 0;\n while (files[i].type === 'directory') i++;\n files = [files[i]];\n }\n callback(files, rejFiles);\n } else {\n if (delays++ * 10 < 20 * 1000) {\n waitForProcess(10);\n }\n }\n }, delay || 0);\n })();\n }\n }\n }\n\n function dropAvailable() {\n var div = document.createElement('div');\n return ('draggable' in div) && ('ondrop' in div);\n }\n\n})();\n\n(function () {\n\n function fileToSrc(Upload, scope, $parse, attr, name, defaultName, callback) {\n if (defaultName) {\n callback($parse(defaultName)(scope));\n }\n scope.$watch(name, function (file) {\n if (!angular.isString(file)) {\n if (window.FileReader && ngFileUpload.validate(scope, $parse, attr, file, null)) {\n Upload.dataUrl(file, function (url) {\n if (callback) {\n callback(url);\n } else {\n file.dataUrl = url || $parse(defaultName)(scope);\n }\n }, $parse(attr.ngfNoObjectUrl)(scope));\n }\n } else {\n callback(file);\n }\n });\n }\n\n /** @namespace attr.ngfSrc */\n /** @namespace attr.ngfDefaultSrc */\n /** @namespace attr.ngfNoObjectUrl */\n ngFileUpload.directive('ngfSrc', ['$parse', 'Upload', function ($parse, Upload) {\n return {\n restrict: 'AE',\n link: function (scope, elem, attr) {\n fileToSrc(Upload, scope, $parse, attr, attr.ngfSrc, attr.ngfDefaultSrc, function (url) {\n elem.attr('src', url);\n });\n }\n };\n }]);\n\n /** @namespace attr.ngfBackground */\n /** @namespace attr.ngfDefaultBackground */\n /** @namespace attr.ngfNoObjectUrl */\n ngFileUpload.directive('ngfBackground', ['$parse', 'Upload', function ($parse, Upload) {\n return {\n restrict: 'AE',\n link: function (scope, elem, attr) {\n fileToSrc(Upload, scope, $parse, attr, attr.ngfBackground, attr.ngfDefaultBackground, function (url) {\n elem.css('background-image', 'url(' + url + ')');\n });\n }\n };\n }]);\n\n /** @namespace attr.ngfDataUrl */\n /** @namespace attr.ngfDefaultDataUrl */\n /** @namespace attr.ngfNoObjectUrl */\n ngFileUpload.directive('ngfDataUrl', ['$parse', 'Upload', function ($parse, Upload) {\n return {\n restrict: 'AE',\n link: function (scope, elem, attr) {\n\n fileToSrc(Upload, scope, $parse, attr, attr.ngfDataUrl, attr.ngfDefaultDataUrl);\n }\n };\n }]);\n})();\n","require('./dist/ng-file-upload-all');\nmodule.exports = 'ngFileUpload';"],"names":[],"sourceRoot":""}