{"version":3,"sources":["../../dev/j/product-home-v10.js"],"names":["detectInitScreen","window","getComputedStyle","document","body","getPropertyValue","setStickyHeight","screenSize","stickyHeight","sysReqOsVer","version","ua","navigator","userAgent","toLowerCase","supportedVersions","detect","avastGlobals","os","isWindows","i","length","name","indexOf","Abdata","cache","options","pricelistApi","web","RootPath","pricelistApiB","vatLocales","init","this","$","extend","cacheDelimiter","xhrPool","abortAll","each","idx","jqXHR","abort","getPriceData","createCacheId","parameters","elem","el","data","p","collectAjaxParams","_","abtype","internalId","campaign","maintenance","computers","lic","appendix","priceData","params","ajaxParams","priceLink","cacheId","paramQuery","match","multiyear","avast","locale","campaignMarker","apiHash","installments","provider","selectFromCache","trigger","ajax","type","url","dataType","context","beforeSend","push","success","parseData","error","textStatus","errorThrown","internalid","additional2","delim","abDataInstance","re","RegExp","updateCache","products","cId","replace","maintenanceLimits","computersLimits","priceInNumber","price","priceFormatted","realPriceInNumber","stripDecimals","realPrice","precision","realPriceFormatted","totalPrice","getTotalPrice","$this","key","prices","min","parseInt","parseFloat","quant","_price","_quant","_vat","vat","link","foreignId","flatDiscount","discount","discountType","minQuantity","maxQuantity","priceFormat","currency","currencySymbol","thousandSeparator","decimalSeparator","number","regex","toString","Number","getDataByInternalId","props","cacheData","test","id","index","priceList","JSON","parse","dataset","pricelist","console","log","Actionbox","defaults","abProductsSelector","overlaySelector","abBoxSelector","autoLoadData","installmentTemplate","customCurrency","currencySwitch","opts","build","on","proxy","loopBoxes","countTimeout","abEl","find","first","updateInputs","updateInputsData","handleKeyPress","preRender","pullData","append","resetInputs","boxClass","box","closest","valEl","valContent","text","isEmpty","trim","priceEqual","addClass","parent","removeClass","get","fn","abdata","evt","msg","nextBox","root","fillData","filter","boxInternalId","boxInternalIdObj","buildInternalId","internalIdToObj","currentMaintenance","nextMaintenance","removeData","formatedData","pcs","mainInternalId","priceDivider","pricing","val","formatPrice","installmentPrice","realPriceTotal","priceyTypo","typoPrice","typoPriceParts","split","markupPrice","join","customId","renderData","renderValue","decSep","thSep","formatedPrice","number_format","numberOfDecimals","symbol","cssSelector","attr","findClass","has","html","yrs","current","currentTarget","siblings","newVal","pcsString","pad","btn","clearTimeout","updateInternalIds","num","size","s","newId","idObj","_idObj","map","prop","idParts","renewal","prodEl","prefix","c","lastIndexOf","allowedValues","max","limits","values","len","counting","setTimeout","speed","maxSpeed","speedup","inputId","input","increase","hasClass","originalEvent","preventDefault","countIndex","call","off","updateCount","count","triggerMsg","_clearTimeout","message","updatePrice","Array","prototype","fun","TypeError","t","Object","res","thisArg","arguments","searchElement","fromIndex","undefined","Math","abs","Infinity","create","obj","F","ready","ab","actionbox","apply","abconfig","osVer","hide","show","e","sysreq","sh","outerHeight","h","height","css","min-height","animate","fadeOut","fadeIn"],"mappings":"AA4mCA,QAASA,oBAER,MADYC,QAAuB,iBAAIA,OAAOC,iBAAiBC,SAASC,KAAK,UAAUC,iBAAiB,WAAa,GAGtH,QAASC,mBACR,GAAIC,GAAaP,mBACbQ,EAAe,EAOnB,OANkB,UAAdD,IACHC,EAAe,GAEE,UAAdD,IACHC,EAAe,GAETA,EA8BR,QAASC,eACR,GAEIC,GAFAC,EAAKC,UAAUC,UAAUC,cACzBC,GAAqB,KAAM,QAAS,IAAK,IAAK,MAE9CC,EAASC,aAAaD,MAE1B,IAAqB,gBAAXA,IAAuBA,EAAOE,GAAGC,UAC1C,IAAI,GAAIC,GAAI,EAAGL,EAAkBM,OAASD,EAAGA,IACzCJ,EAAOE,GAAGR,UAAYK,EAAkBK,KAC1CV,EAAUM,EAAOE,GAAGI,KAAO,IAAMN,EAAOE,GAAGR,QAK9C,SAAGC,EAAGY,QAAQ,UAAY,IAInBb,EAhqCR,GAAIc,SACHC,SACAC,SACCC,aAAcV,aAAaW,IAAIC,SAAW,qCAC1CC,cAAeb,aAAaW,IAAIC,SAAW,4BAE3CE,eAQDC,KAAM,SAASN,GAkBd,MAjBAO,MAAKP,QAAUQ,EAAEC,UAAWF,KAAKP,QAASA,GAC1CO,KAAKR,SACLQ,KAAKG,eAAiB,IAGE,mBAAdF,GAAEG,UACXH,EAAEG,WAEFH,EAAEG,QAAQC,SAAW,WACnBJ,EAAEK,KAAKN,KAAM,SAASO,EAAKC,GAC3BA,EAAMC,YAKTT,KAAKU,eAEEV,MAQRW,cAAe,SAASC,GACvB,GAAIC,GAAOb,KAAKP,QAAQqB,GACvBC,EAAOF,EAAOA,EAAKE,OAAS,KAC5BC,EAAI,GAA6BhB,KAAKiB,kBAAkBF,GACxDG,EAAIlB,KAAKG,cAST,OANiB,cAAba,EAAEG,OACKH,EAAEI,WAAa,IAAMJ,EAAEK,SAAWH,EAAIF,EAAEM,YAAcJ,EAEtDF,EAAEI,WAAa,IAAMJ,EAAEK,SAAWH,EAAIF,EAAEM,YAAcJ,EAAIF,EAAEO,UAAYL,EAAIF,EAAEQ,IAAMN,EAAIF,EAAES,UAUvGf,aAAc,SAASI,GACtB,GAKCY,GALGb,EAAOC,GAAMd,KAAKP,QAAQqB,GAC7BC,EAAOF,EAAOA,EAAKE,OAAS,KAC5BY,EAAS3B,KAAK4B,WAAa5B,KAAKiB,kBAAkBF,GAClDc,EAA+B,cAAlBF,EAAOR,OAA0BnB,KAAKP,QAAQC,aAAeM,KAAKP,QAAQI,cACvFiC,EAAU9B,KAAKW,cAAcgB,GAE7BI,EAAY,aAAkBJ,EAAOP,WAAWY,MAAM,eACnD,eAAkBL,EAAOP,WACzB,gBAAkBO,EAAOM,UACzB,UAAkBN,EAAOJ,UACzB,WAAkBW,MAAMC,OACxB,mBAAqBR,EAAOS,eAC5B,mBACeT,EAAOU,OAEtBV,GAAOW,eACTP,GAAc,iBAAmBJ,EAAOW,cAEtCX,EAAON,WACTU,GAAc,aAAeJ,EAAON,UAElCM,EAAOY,WACTR,GAAc,aAAeJ,EAAOY,UAOlCvC,KAAKR,MAAMsC,IAsBbJ,EAAY1B,KAAKwC,gBAAgBV,GACjC7B,EAAEY,GAAM4B,QAAQ,iBAAkBf,EAAY,YAAc,UAAWA,KAtBxEzB,EAAEyC,MACDC,KAAM,MACNC,IAAKf,EAAYE,EACjBc,SAAU,OACVC,QAAS9C,KACT+C,WAAY,SAASvC,GAEpBP,EAAEG,QAAQ4C,KAAKxC,IAEhByC,QAAS,SAASlC,GACjBf,KAAKkD,UAAUpB,EAASf,GACxBW,EAAY1B,KAAKwC,gBAAgBV,GACjC7B,EAAEY,GAAM4B,QAAQ,iBAAkBf,EAAY,YAAc,UAAWA,KAExEyB,MAAO,SAAS3C,EAAO4C,EAAYC,GAChB,UAAfD,GACFnD,EAAEY,GAAM4B,QAAQ,iBAAkB,aAAcW,EAAYC,QAejEpC,kBAAmB,SAASF,GAC3B,GAAIY,KAmBJ,OAjBGZ,KACFY,GACCR,OAAwC,gBAAhBJ,GAAKI,QAAuBJ,EAAKI,OAAO7B,QAAQ,aAAe,EAAK,YAAc,GAC1G8B,WAAgBL,EAAKuC,YAAc,GACnCjC,SAAgBN,EAAKM,UAAY,GACjCC,YAAgBP,EAAKO,aAAe,KACpCC,UAAgBR,EAAKQ,WAAa,IAClCC,IAAgBT,EAAKS,KAAO,IAC5BC,SAAgB,GAChBQ,UAAgBlB,EAAKkB,WAAa,WAClCM,SAAgBxB,EAAKwB,UAAY,KACjCD,aAAgBvB,EAAKuB,cAAgB,KACrCiB,YAAgBxC,EAAKwC,aAAe,KACpClB,QAAYtB,EAAKsB,SAAW,KAC5BD,eAAmBrB,EAAKqB,gBAAkB,QAGrCT,GAQRuB,UAAW,SAASpB,EAASf,GAE5B,GAAIyC,GAAQxD,KAAKG,eAChBsD,EAAiBzD,KACjB0D,EAAK,GAAIC,QAAO3D,KAAKG,eAAiB,QAAUH,KAAKG,eAStD,IAFAsD,EAAeG,YAAY9B,MAExBf,IAASA,EAAK8C,SAEhB5D,EAAEK,KAAKS,EAAM,WACZ,GAAI+C,GAAMhC,EAAQiC,QAAQL,EAAIF,EAAQxD,KAAKsB,YAAckC,EAEzDxD,MAAKgE,mBAAqB,GAAG,GAAG,IAChChE,KAAKiE,iBAAmB,EAAG,EAAG,EAAG,IACjCjE,KAAKkE,cAAgB,GAAKlE,KAAKmE,MAC/BnE,KAAKmE,MAAQnE,KAAKoE,eAClBpE,KAAKqE,kBAAoB,GAAKZ,EAAea,cAActE,KAAKuE,UAAWvE,KAAKwE,WAChFxE,KAAKuE,UAAYvE,KAAKyE,mBACtBzE,KAAK0E,WAAajB,EAAekB,cAAc3E,KAAKoB,YAEpDqC,EAAeG,YAAYE,EAAK9D,YAE3B,IAAIe,EAAK8C,UAAqC,IAAzB9C,EAAK8C,SAASzE,OAEzCa,EAAEK,KAAKS,EAAK8C,SAAU,WAErB,GAAInC,MACAyC,KACAI,KACAK,EAAQ3E,EAAED,MAAM,GAChB8D,EAAMhC,EAAQiC,QAAQL,EAAIF,EAAQoB,EAAMtD,YAAckC,EAE1D,KAAK,GAAIqB,KAAOD,GAAME,OACrBX,EAAMnB,MACL+B,IAAOC,SAASH,EAAK,IACrBV,MAAUc,WAAWL,EAAME,OAAOD,MAEjCN,EAAUvB,MACX+B,IAAOC,SAASH,EAAK,IACrBV,MAAUc,WAAWL,EAAME,OAAOD,KAIpCnD,GAAUyC,MAAQ,SAASe,GAK1B,IAAK,GAFJC,GAFGC,EAASJ,SAASE,EAAO,IAC5BG,EAAQtE,EAAKuE,KAAO7B,EAAehE,QAAQK,WAAWoC,MAAMC,QAAWpB,EAAKuE,IAAM,EAG1EnG,EAAI,EAAGgF,EAAM/E,OAASD,EAAGA,IAC9BiG,GAAUjB,EAAMhF,GAAG4F,MACrBI,EAAUhB,EAAMhF,GAAGgF,MAGrB,OAAOgB,GAASC,EAASC,GAE1B3D,EAAU6C,UAAY,SAASW,GAK7B,IAAK,GAFLC,GAFGC,EAASJ,SAASE,EAAO,IAC5BG,EAAQtE,EAAKuE,KAAO7B,EAAehE,QAAQK,WAAWoC,MAAMC,QAAWpB,EAAKuE,IAAM,EAGzEnG,EAAI,EAAGoF,EAAUnF,OAASD,EAAGA,IACnCiG,GAAUb,EAAUpF,GAAG4F,MACzBI,EAASZ,EAAUpF,GAAGgF,MAGxB,OAAOgB,GAASC,EAASC,GAE1B3D,EAAU6D,KAAO,SAASL,GACzB,MAAOnE,GAAKwE,KAAKxB,QAAQ,QAASa,EAAMY,WAAWzB,QAAQ,UAAWmB,IAGvExD,EAAU+D,aAAe1E,EAAK2E,SAC9BhE,EAAUiE,aAAe5E,EAAK4E,aAC9BjE,EAAUkE,YAAc7E,EAAK6E,YAC7BlE,EAAUmE,YAAc9E,EAAK8E,YAC7BnE,EAAUJ,YAAcsD,EAAMtD,YAC9BI,EAAUsC,mBAAqB,GAAG,GAAG,IACrCtC,EAAUoE,YAAc/E,EAAK+E,YAC7BpE,EAAUqE,SAAWhF,EAAKiF,eAC1BtE,EAAUuE,kBAAoBlF,EAAKkF,kBACnCvE,EAAUwE,iBAAmBnF,EAAKmF,iBAClCxE,EAAU8C,UAAYzD,EAAKyD,UAC3B9C,EAAUoE,YAAc/E,EAAK+E,YAE7BrC,EAAeG,YAAYE,EAAKpC,SAE3B,CAENzB,EAAEY,MAAM4B,QAAQ,iBADN,cAWV6B,cAAe,SAAS6B,EAAQ3B,GACjC,GACC4B,GAAQ,GAAIzC,QAAO,sBAA6Ca,EAAY,MAM7E,OAJIA,KACH2B,EAASA,EAAOE,WAAWrE,MAAMoE,GAAO,IAGlCE,OAAOH,IAQfvC,YAAa,SAAS9B,EAASf,GAC9Bf,KAAKR,MAAMsC,GAAWf,GAQvByB,gBAAkB,SAASV,GAC1B,MAAO9B,MAAKR,MAAMsC,IASnByE,oBAAuB,SAASnF,EAAYoF,GAC3C,GAAIhH,GAAQQ,KAAKR,MAChBmC,EAAS1B,EAAEC,WAAYkB,WAAYA,GAAaoF,GAChD5E,EAAa5B,KAAKiB,kBAAkBU,GACpCG,EAAU9B,KAAKW,cAAciB,GAC7B6E,EAAYzG,KAAKwC,gBAAgBV,GACjC4B,EAAK,GAAIC,QAAO,IAAMvC,GACtBL,IAED,IAAGyF,EACCC,GACF1F,EAAKiC,KAAKyD,OAGX,KAAI,GAAI5B,KAAOrF,GAEXkE,EAAGgD,KAAK7B,IACV9D,EAAKiC,KAAKxD,EAAMqF,GAKnB,OAAO9D,IASR4D,cAAe,SAASgC,GACvB,GAAIxC,GAAQ,IAgBZ,OAdAlE,GAAE,oBAAoBK,KAAK,SAASsG,GACnC,GAAIC,EAEJ,KACCA,EAAYC,KAAKC,MAAM/G,KAAKgH,QAAQC,WACnC,MAAM9D,GACP+D,QAAQC,IAAIhE,GAGT0D,GAAaA,EAAUF,KAC1BxC,EAAQ0C,EAAUF,GAAIlC,sBAIjBN,IAYLiD,WACHC,UACGC,mBAAuB,oBACvBC,gBAAuB,WACvBC,cAAuB,OACvBC,cAAuB,EACvBnF,aAAuB,EACvBoF,oBAAuB,0CACvBC,eAAuB,GACvBC,eAAuB,IAO1B7H,KAAM,SAAS8H,EAAMhH,GACnBb,KAAKP,QAAUQ,EAAEC,UAAUF,KAAKqH,SAASQ,GACzC7H,KAAK8H,MAAMjH,GAGXZ,EAAE/B,UAAU6J,GAAG,gBAAiB9H,EAAE+H,MAAMhI,KAAKiI,UAAWjI,QAM1D8H,MAAO,SAASjH,GAEfb,KAAKkI,aAAe,GAGpBlI,KAAK8C,QAAU7C,EAAEY,GAGjBb,KAAKmI,KAAOnI,KAAK8C,QAAQ/B,KAAK,cAAgBf,KAAK8C,QAAU9C,KAAK8C,QAAQsF,KAAK,qBAAqBC,QAGpGrI,KAAKmI,KAAKC,KAAK,QAAQL,GAAG,qBAAsB9H,EAAE+H,MAAMhI,KAAKsI,aAActI,OAC3EA,KAAKmI,KAAKC,KAAK,QAAQL,GAAG,mBAAoB9H,EAAE+H,MAAMhI,KAAKuI,iBAAkBvI,OAG7EC,EAAE/B,UAAU6J,GAAG,mBAAoB9H,EAAE+H,MAAMhI,KAAKwI,eAAgBxI,OAGhEA,KAAKyI,YAGFzI,KAAKP,QAAQgI,cACfzH,KAAK0I,YAMPD,UAAY,WAEXzI,KAAKmI,KAAKQ,OAAO,qCACjB3I,KAAK4I,aACL,IAAIC,GAAW7I,KAAKP,QAAQ+H,aAG5BxH,MAAKmI,KAAKC,KAAK,gBAAgB9H,KAAK,WACnC,GAAIsE,GAAQ3E,EAAED,MACb8I,EAAMlE,EAAMmE,QAAQF,GACpBG,EAASpE,EAAMwD,KAAK,UACpBa,EAAaD,EAAME,OACnBC,GAAWlJ,EAAEmJ,KAAKH,GAClBI,EAAcpJ,EAAE6I,GAAKV,KAAK,mBAAmBc,SAAWD,EAAe,EAAI,GAEzEE,GAAWE,IACbzE,EAAM0E,SAAS,aAQlBZ,SAAU,WAGT1I,KAAKmI,KAAKmB,SAAS,YACnBtJ,KAAKmI,KAAKC,KAAK,gBAAgBkB,SAAS,YACxCtJ,KAAKmI,KAAKoB,OAAO,OAAOnB,KAAK,eAAeoB,YAAY,UAGrDvJ,EAAEc,KAAKf,KAAKmI,KAAKsB,IAAI,GAAI,UAC3BzJ,KAAKmI,KAAKpH,KAAK,UAAUL,eAGC,kBAAhBT,GAAEyJ,GAAGC,QACd3J,KAAKmI,KAAKwB,QAAQ7I,GAAKd,KAAKmI,QAU/BF,UAAW,SAAS2B,EAAKC,EAAK9I,GAE7B,GACC+I,EAED,IAAG/I,GAAQA,EAAKO,YAAa,CAC5B,GAAIyI,GAAO/J,IAEXA,MAAKgK,SAASJ,EAAKC,EAAK9I,GAIxBf,KAAKmI,KAAKpH,KAAK,cAAeiE,SAASjE,EAAKO,YAAa,IAAM,IAE/DwI,EAAU9J,KAAKmI,KAAKC,KAAK,qBAAqB6B,OAAO,WACpD,GAAIC,GAAgBjK,EAAED,MAAMe,KAAK,cAG7BoJ,GAFiBJ,EAAKK,gBAAgBF,GAAgB5I,YAAa0D,SAASjE,EAAKO,YAAa,IAAM,KAEjFyI,EAAKM,gBAAgBH,IACxCI,EAAqBH,EAAiB7I,YACtCiJ,EAAkBvF,SAASjE,EAAKO,YAAa,IAAM,EAGvD,OAAO0D,UAASsF,EAAoB,MAAQC,IAG1CtK,EAAEc,KAAKf,KAAKmI,KAAKsB,IAAI,GAAI,WAAaK,EAAQ1K,OAAS,EAEvDY,KAAK0I,WAILzI,EAAE/B,UAAUuE,QAAQ,wBAAyB,6BAEhDzC,KAAKmI,KAAKqC,WAAW,iBAWvBR,SAAU,SAASJ,EAAKC,EAAK9I,GAC5B,GAKC+B,GALG2H,KACHC,EAAM1K,KAAKmI,KAAKC,KAAK,cACrBuC,EAAiB3K,KAAKmI,KAAKpH,KAAK,cAChCgJ,EAAO/J,KAGP4K,EAAe5K,KAAKP,QAAQ6C,aAAetC,KAAKP,QAAQ6C,aAAyC,YAAzBtC,KAAKP,QAAQoL,SAAyB9J,GAAQA,EAAKO,YAAeP,EAAKO,YAAc,EAC7J0E,EAAiBjF,EAAKiF,eAAiBjF,EAAKiF,eAAiBjF,EAAKgF,QAEnE,IAAIhF,EAAK,CAELA,EAAK6E,aACJZ,SAAS0F,EAAII,MAAO,KAAO9F,SAASjE,EAAK6E,YAAa,KACxD8E,EAAII,IAAI/J,EAAK6E,aAGZ7E,EAAK8E,aACJb,SAAS0F,EAAII,MAAO,KAAO9F,SAASjE,EAAK8E,YAAa,KACxD6E,EAAII,IAAI/J,EAAK8E,YAOf,IAAIX,GAAQwF,EAAII,KAehB,IAZAL,EAAalF,KAA6B,kBAAdxE,GAAKwE,KAAuBxE,EAAKwE,KAAKL,GAASnE,EAAKwE,KAChFkF,EAAalG,UAAuC,kBAAnBxD,GAAKwD,UAA4BxD,EAAKwD,UAAUW,GAASnE,EAAKwD,UAC/FkG,EAAatG,MAA+B,kBAAfpD,GAAKoD,MAAwBpD,EAAKoD,MAAMe,GAASnE,EAAKoD,MACnFsG,EAAa/E,SAAW3E,EAAK2E,SAGJ,kBAAf3E,GAAKoD,QACdsG,EAAatG,MAAQnE,KAAK+K,YAAYN,EAAatG,MAAOpD,EAAK+E,YAAa/E,EAAKgF,SAAUhF,EAAKyD,UAAWzD,EAAKmF,iBAAkBnF,EAAKkF,mBACvIwE,EAAalG,UAAYvE,KAAK+K,YAAYN,EAAalG,UAAWxD,EAAK+E,YAAa/E,EAAKgF,SAAUhF,EAAKyD,UAAWzD,EAAKmF,iBAAkBnF,EAAKkF,oBAI7IjG,KAAKP,QAAQ6C,aAAa,CAC5B,GAAI0I,GAAmBhL,KAAK+K,YAAahK,EAAKsD,kBAAoBrE,KAAKP,QAAQ6C,aAAgBvB,EAAK+E,YAAaE,EAAgBjF,EAAKyD,UAAWzD,EAAKmF,iBAAkBnF,EAAKkF,kBAC7KwE,GAAaQ,eAAiBR,EAAalG,UAC3CkG,EAAalG,UAAYvE,KAAKP,QAAQiI,oBAAoB3D,QAAQ,KAAM/D,KAAKP,QAAQ6C,cAAgB0I,EAGtG,GAAGhL,KAAKP,QAAQyL,WAAW,CAC1B,GAAIC,GAAYnL,KAAK+K,YAAahK,EAAKsD,kBAAoBuG,EAAgB7J,EAAK+E,YAAaE,EAAgBjF,EAAKyD,UAAWzD,EAAKmF,iBAAkBnF,EAAKkF,kBACzJkF,GAAYA,EAAUpH,QAAQ,SAAU,GAExC,IAAIqH,GAAiBD,EAAUE,MAAMtK,EAAKmF,kBACtCoF,IAGJA,GAAYtI,KAAK,gCAEwB,IAAtCmI,EAAU7L,QAAQ0G,IACnBsF,EAAYtI,KAAK,0BAA4BgD,EAAiB,WAGhEsF,EAAYtI,KAAK,yBAA2BoI,EAAe,GAAGrH,QAAQiC,EAAgB,IAAM,WAGzFoF,EAAe,IACjBE,EAAYtI,KAAK,yBAA2BjC,EAAKmF,iBAAmBkF,EAAe,GAAGrH,QAAQiC,EAAgB,IAAM,WAG5E,IAAtCmF,EAAU7L,QAAQ0G,IACnBsF,EAAYtI,KAAK,0BAA4BgD,EAAiB,WAGhEsF,EAAYtI,KAAK,WAEjByH,EAAaQ,eAAiBR,EAAalG,UAC3CkG,EAAalG,UAAY+G,EAAYC,KAAK,IAGf,YAAzBvL,KAAKP,QAAQoL,UACfJ,EAAalF,KAAOkF,EAAalF,KAAKxB,QAAQ,oBAAqB,aAAe/D,KAAKP,QAAQ+L,SAAW,MAIxGzK,EAAKkD,kBAAoBjE,KAAKmI,KAAKpH,KAAK,qBAC1Cf,KAAKmI,KAAKpH,KAAK,mBAAoBA,EAAKkD,iBAEtClD,EAAKiD,oBAAsBhE,KAAKmI,KAAKpH,KAAK,uBAC5Cf,KAAKmI,KAAKpH,KAAK,qBAAsBA,EAAKiD,mBAExCjD,EAAK6E,aACP5F,KAAKmI,KAAKpH,KAAK,eAAgBA,EAAK6E,aAElC7E,EAAK8E,aACP7F,KAAKmI,KAAKpH,KAAK,eAAgBA,EAAK8E,aAGlC9E,EAAKO,aAAeqJ,IACL3K,KAAKoK,gBAAiBO,GAAiBrJ,YAAa0D,SAASjE,EAAKO,YAAa,MAEhGwB,EAAU9C,KAAKmI,KAAKC,KAAK,qBAAqB6B,OAAO,WACnD,GAAIC,GAAgBjK,EAAED,MAAMe,KAAK,cAChCoJ,EAAmBJ,EAAKM,gBAAgBH,GACxCI,EAAqBH,EAAiB7I,YACtCiJ,EAAkBvF,SAASjE,EAAKO,YAAa,GAE9C,OAAO0D,UAASsF,EAAoB,MAAQC,KAI5CzH,GACF9C,KAAKyL,WAAW3I,EAAS2H,KAS5BgB,WAAY,SAAS3I,EAAS2H,GAE5BzK,KAAK0L,YAAY,iBAAkB5I,EAAS2H,EAAalG,WACzDvE,KAAK0L,YAAY,iCAAkC5I,EAAS2H,EAAalG,WACzEvE,KAAK0L,YAAY,YAAa5I,EAAS2H,EAAaQ,gBACpDjL,KAAK0L,YAAY,eAAgB5I,EAAU2H,EAAqB,SAAIA,EAAatG,MAAQ,IACzFnE,KAAK0L,YAAY,QAAS5I,EAAS2H,EAAa/E,UAChD1F,KAAK0L,YAAY,UAAW5I,EAAS2H,EAAalF,KAAM,QACxDvF,KAAK0L,YAAY,QAAS5I,EAAS2H,EAAalF,KAAM,QACtDvF,KAAKmI,KAAKqB,YAAY,YACtBxJ,KAAKmI,KAAKC,KAAK,gBAAgBoB,YAAY,YAC3CxJ,KAAKmI,KAAKC,KAAK,eAAekB,SAAS,WAazCyB,YAAa,SAAS5G,EAAO2B,EAAaC,EAAUvB,EAAWmH,EAAQC,GACtE,GAAIC,EAWJ,IATgC,kBAAtB5L,KAAI6L,gBACbD,EAAgB5L,IAAI6L,cAAc3H,GAE7B4H,iBAAkBvH,EAClB0B,iBAAkByF,EAClB1F,kBAAmB2F,EACnBI,OAAQ,MAGXH,EACF,MAAO/F,GAAY/B,QAAQ,KAAKgC,GAAUhC,QAAQ,KAAK8H,IAUzDH,YAAa,SAASO,EAAanJ,EAASgI,EAAKoB,GAChD,GAAIrL,GAAO,EAAgBZ,EAAE6C,GAASsF,KAAK6D,GAAe,EACvDnB,IACFjK,EAAK2I,YAAY,UAEb0C,GAAiB,UAATA,EACXrL,EAAKqL,KAAKA,EAAMpB,GACNoB,GAAiB,UAATA,GAClBrL,EAAK2I,YAAYxJ,KAAKmM,UAAUtL,EAAM,UAAU0K,KAAK,KACrD1K,EAAKyI,SAASwB,IAEXjK,EAAKuL,IAAI,UAAUhN,OAAS,EAC9ByB,EAAKuH,KAAK,UAAUiE,KAAKvB,GAEzBjK,EAAKwL,KAAKvB,IAIZjK,EAAKyI,SAAS,WAOhBf,iBAAkB,SAASqB,GAC1B,GAAIc,GAAM1K,KAAKmI,KAAKC,KAAK,cACxBkE,EAAMtM,KAAKmI,KAAKC,KAAK,gBACrBmE,EAAWtM,EAAE2J,EAAI4C,eAAeC,SAAS,WAAWrE,KAAK,cAAchJ,OAAS,EAAKsL,EAAM4B,EAC3FI,EAAS1H,SAASuH,EAAQzB,MAAO,IAEjC6B,EAAY3M,KAAK4M,IAAIlC,EAAII,MAAO,GAChC+B,EAAM5M,EAAE2J,EAAI4C,cAGe,YAAzBK,EAAI9L,KAAK,cAKZ+L,aAAa9M,KAAKkI,cAGfqE,IAAYD,GACXtH,SAAS0H,EAAQ,KAAO,KAE1BA,EAAS1H,SAAS0H,EAAQ,IAAM,IAOlC1M,KAAKmI,KAAKpH,KAAK,YAAa2J,EAAII,QAGhB,YAAblB,EAAIjH,MAAoC,aAAbiH,EAAIjH,MAAqD,aAA9BkK,EAAI9L,KAAK,oBACjE8L,EAAIrC,WAAW,iBACfxK,KAAK+M,mBAAmBrC,IAAKiC,IAC7B3M,KAAK0I,cAUPkE,IAAK,SAASI,EAAKC,GAElB,IADA,GAAIC,GAAIF,EAAI,GACLE,EAAE9N,OAAS6N,GAAMC,EAAI,IAAMA,CAClC,OAAOA,IAMRH,kBAAmB,SAASvG,GAC3B,GAAIuD,GAAO/J,MAMiC,aAA7BA,KAAKmI,KAAKpH,KAAK,UAA4Bf,KAAKmI,KAAKoB,SAAWvJ,KAAKmI,MAE5EC,KAAK,qBAAqB9H,KAAK,WACtC,GAAIsE,GAAQ3E,EAAED,MACVmN,EAAQpD,EAAKK,gBAAgBxF,EAAM7D,KAAK,cAAeyF,EAC3D5B,GAAM7D,KAAK,aAAcoM,MAW3B/C,gBAAiB,SAASzD,EAAIH,GAC7B,GACC4G,GAAQpN,KAAKqK,gBAAgB1D,GAC7B0G,IAMD,OALG7G,IACFvG,EAAEC,OAAOmN,EAAQD,EAAO5G,GAEjBvG,EAAEqN,IAAID,EAAQ,SAASE,GAAM,MAAOA,KAAQhC,KAAK,MAW1DlB,gBAAiB,SAASjJ,GACzB,GAAIgM,MACHI,EAAUpM,EAAWiK,MAAM,IAS5B,OANA+B,GAAM/N,KAAOmO,EAAQ,GACrBJ,EAAM3O,QAAU+O,EAAQ,GACxBJ,EAAM1C,IAAM8C,EAAQ,GACpBJ,EAAM9L,YAAckM,EAAQ,GAC5BJ,EAAMK,QAAUD,EAAQ,GAEjBJ,GAMRxE,YAAa,WACZ,GAAI8B,GAAM1K,KAAKmI,KAAKC,KAAK,cACxBkE,EAAMtM,KAAKmI,KAAKC,KAAK,gBACrBsF,EAAS1N,KAAKmI,IAEfuC,GAAII,IAAI,GACRwB,EAAIxB,IAAI,GAGR4C,EAAO3M,KAAK,YAAa,GACzB2M,EAAO3M,KAAK,cAAe,IACxB2M,EAAO3M,KAAK,uBACd2M,EAAO3M,KAAK,aAAc2M,EAAO3M,KAAK,uBAIvCf,KAAKmI,KAAKC,KAAK,iBAAiBoB,YAAY,aAS7C2C,UAAW,SAASrL,EAAI6M,GAIvB,MAHc1N,GAAEa,GAAIoL,KAAK,SAASb,MAAM,KAAKpB,OAAO,SAAS2D,GAC5D,MAAoC,KAA7BA,EAAEC,YAAYF,EAAQ,MAY/BG,cAAe,SAAS/I,EAAKgJ,EAAKC,GACjC,GAAIC,MACHC,KAAOnJ,IAAOgJ,IAAOA,EAAMhJ,EAAM,CAElC,KAAIiJ,GAAUE,EACb,IAAI,GAAI/O,GAAI,EAAG+O,EAAM/O,EAAGA,IACvB8O,EAAOjL,KAAK+B,EAAM5F,OAGnB8O,GAASD,CAEV,OAAOC,IAOR3F,aAAc,SAASsB,GAiDtB,QAASuE,GAASzE,GACjBA,IACAK,EAAK7B,aAAekG,WAAW,WAAWD,EAASzE,IAAO2E,GAC1DA,EAASA,EAAQC,EAAYD,EAAQE,EAAUD,EAnDhD,GAAIzB,GAAM5M,EAAE2J,EAAI4C,eACZ6B,EAAQ,IACRE,EAAU,GACVD,EAAW,GACXvE,EAAO/J,KACPwO,EAAU3B,EAAI9D,QAAQ,WAAWX,KAAK,SAAS8D,KAAK,MACpDuC,EAAQzO,KAAKmI,KAAKC,KAAK,IAAMoG,GAC7BE,EAAY7B,EAAI8B,SAAS,QAAW,GAAK,EAGzC5J,EAAMC,SAAShF,KAAKmI,KAAKpH,KAAK,gBAAiB,IAClDgN,EAAM/I,SAAShF,KAAKmI,KAAKpH,KAAK,gBAAiB,IAC/CiN,EAAsB,cAAZQ,EAA2BxO,KAAKmI,KAAKpH,KAAK,oBAAsBf,KAAKmI,KAAKpH,KAAK,sBAEzFkN,EAASjO,KAAK8N,cAAc/I,EAAKgJ,EAAKC,EAGpC/N,GAAE2J,EAAI4C,eAAemC,SAAS,cAIc,kBAArC/E,GAAIgF,cAAcC,gBAC3BjF,EAAIgF,cAAcC,iBAGhBZ,GACFK,EAAW,IACXtO,KAAK8O,WAAab,EAAO3O,QAAqB,cAAZkP,EAA2BxJ,SAASyJ,EAAM3D,MAAO,IAAkC,GAA5B9F,SAASyJ,EAAM3D,MAAO,MAE/G9K,KAAK8O,WAA0B,cAAZN,EAA2BxJ,SAASyJ,EAAM3D,MAAO,IAAkC,GAA5B9F,SAASyJ,EAAM3D,MAAO,IAI/D,aAA9B+B,EAAI9L,KAAK,mBACX8L,EAAI9E,GAAG,oBAAqB,SAAS6B,GACpCkD,aAAa/C,EAAK7B,cAClB6B,EAAKxB,iBAAiBwG,KAAKhF,EAAMH,GACjCiD,EAAImC,IAAI,qBACRnC,EAAIrC,WAAW,mBAEjBqC,EAAI9L,KAAK,gBAAiB,aAG3BoN,EAAS,WACRpE,EAAKkF,YAAYhB,EAAQlE,EAAK+E,WAAYN,EAASE,EAAU3J,EAAKgJ,OAiBpEkB,YAAa,SAAShB,EAAQa,EAAYN,EAASE,EAAU3J,EAAKgJ,GACjE,GAAIlE,EAEJ,IAAGoE,EACEa,EAAaJ,GAAa,GAAQI,EAAaJ,EAAYT,EAAO7O,OACrEY,KAAK8O,WAAaA,EAAaJ,GAE/B7E,EAAsB,IAAfiF,EAAoB,EAAI,EACpB,IAARjF,IACF7J,KAAK8O,WAAab,EAAO7O,OAAS,GAEvB,IAARyK,IACH7J,KAAK8O,WAAa,IAGpB9O,KAAKmI,KAAKC,KAAK,IAAMoG,GAAS1D,IAAiB,cAAZ0D,EAA2BP,EAAOjO,KAAK8O,YAAcb,EAAOjO,KAAK8O,YAAc,QAE5G,CACN,GAAIL,GAAQzO,KAAKmI,KAAKC,KAAK,IAAMoG,GAC7BU,EAAQlK,SAASyJ,EAAM3D,MAAO,IAAM4D,CAErCQ,GAAQ,GACVT,EAAM3D,IAAIoE,GAERA,EAAQnB,IACVlE,EAAM,GAEJqF,GAASnK,IACX8E,EAAM,GAQLA,GACF7J,KAAKmP,WAAW,mBAAoBtF,IAGtCuF,cAAe,WACdtC,aAAa9M,KAAKkI,eAOnBiH,WAAY,SAAUxM,EAAMkH,GAC3B5J,EAAE/B,UAAUuE,QAAQE,IAAQ0M,QAASxF,MAMrCyF,YAAa,WACb,GAAIzH,GAAO7H,KAAKP,WACU,mBAAhBQ,GAAEyJ,GAAGC,SACd9B,EAAK/G,GAAKd,KAAKmI,KACfnI,KAAKmI,KAAKwB,OAAO9B,KASf0H,OAAMC,UAAUvF,SAEnBsF,MAAMC,UAAUvF,OAAS,SAASwF,GAEnC,OAAa,KAATzP,MAA4B,OAATA,KACrB,KAAM,IAAI0P,UAEZ,IAAIC,GAAIC,OAAO5P,MACXkO,EAAMyB,EAAEvQ,SAAW,CACvB,IAAmB,kBAARqQ,GACT,KAAM,IAAIC,UAIZ,KAAK,GAFDG,MACAC,EAAUC,UAAU3Q,QAAU,EAAI2Q,UAAU,OAAK,GAC5C5Q,EAAI,EAAGA,EAAI+O,EAAK/O,IAEvB,GAAIA,IAAKwQ,GACT,CACD,GAAI7E,GAAM6E,EAAExQ,EAERsQ,GAAIV,KAAKe,EAAShF,EAAK3L,EAAGwQ,IAC5BE,EAAI7M,KAAK8H,GAIZ,MAAO+E,KAKHN,MAAMC,UAAUlQ,UACpBiQ,MAAMC,UAAUlQ,QAAU,SAAU0Q,EAAeC,GACjD,GAAKjQ,OAASkQ,WAAsB,OAATlQ,KAC5B,KAAM,IAAI0P,WAAW,gCAGpB,IAAItQ,GAASY,KAAKZ,SAAW,CAe7B,KAbA6Q,GAAaA,GAAa,EAEtBE,KAAKC,IAAIH,KAAeI,WAC7BJ,EAAY,GAGPA,EAAY,IACjBA,GAAa7Q,GACG,IACd6Q,EAAY,GAIPA,EAAY7Q,EAAQ6Q,IAC3B,GAAIjQ,KAAKiQ,KAAeD,EACtB,MAAOC,EAIR,QAAQ,IAKkB,kBAAlBL,QAAOU,SACjBV,OAAOU,OAAS,SAAUC,GACzB,QAASC,MAET,MADAA,GAAEhB,UAAYe,EACP,GAAIC,KAKbvQ,EAAE/B,UAAUuS,MAAM,WAGjBxQ,EAAEyJ,GAAGgH,GAAKzQ,EAAEyJ,GAAGiH,UAAY,SAASlR,GACnC,GAAIO,KAAKZ,OAAS,EAAG,CACpB,GAAGgI,UAAU3H,IAAYQ,EAAED,MAAMe,KAAK,aAGrC,WADAd,GAAED,MAAMe,KAAK,aAAatB,GAASmR,MAAM3Q,EAAED,MAAMe,KAAK,aAGvD,IAAsB,gBAAZtB,KAAyBA,EAClC,MAAOO,MAAKM,KAAK,WAChB,GAAIqQ,GAAYf,OAAOU,OAAOlJ,UAC9BuJ,GAAU5Q,KAAKN,EAASO,MAExBC,EAAEc,KAAKf,KAAM,YAAa2Q,OAO9B1Q,EAAEyJ,GAAGC,OAAS,SAASlK,GACtB,GAAIO,KAAKZ,OAAS,EACjB,MAAOY,MAAKM,KAAK,WAChB,GAAIqJ,GAASiG,OAAOU,OAAO/Q,OAC3BoK,GAAO5J,KAAKN,GAEZQ,EAAEc,KAAKf,KAAM,SAAU2J,KAU1B,IAAIkH,KAEU,WAAX1O,SACF0O,EAASvO,aAAe,GAGtBrC,EAAE,wBAAwBb,OAAS,IACrCyR,EAAS3F,YAAa,GAGpBjL,EAAE,iDAAiDb,OAAS,IAC9DyR,EAAS3F,YAAa,EACtB2F,EAAShG,QAAU,UACnBgG,EAASrF,SAAW,WAKrBvL,EAAE,wBAAwB0Q,UAAUE,GAGpC5Q,EAAE,wBAAwB0Q,UAAUE,KAwBrC5Q,EAAE/B,UAAUuS,MAAM,WACjB,GAAIK,GAAQtS,aAERsS,KACH7Q,EAAE,sBAAsB8Q,OACxB9Q,EAAE,0BAA0B+Q,QAG7B/Q,EAAE,uBAAuB8H,GAAG,QAAS,SAASkJ,GAC7CA,EAAEpC,gBACF,IAAIqC,GAASjR,EAAE,WACXkR,EAAKD,EAAOE,cACZC,EAAIF,EAAKlR,EAAE,sBAAsBmR,cAAgBnR,EAAE,0BAA0BqR,QAEjFJ,GAAOK,KAAKC,aAAgBL,EAAK,OACjCD,EAAOO,SAASD,aAAeH,GAAI,KACnCpR,EAAE,sBAAsByR,QAAQ,IAAK,WACpCzR,EAAE,0BAA0B0R,OAAO,SAIlCb,GACF7Q,EAAE,0BAA0BiJ,KAAK4H","file":"product-home-v10.js","sourcesContent":["/**\n * Pricing API request.\n *\n * @version 0.10.1\n * @author Ales Gabriel\n * @requires jquery\n * @copyright Avast Software s.r.o\n */\n\nvar Abdata = {\n\tcache : {},\n\toptions: {\n\t\tpricelistApi: avastGlobals.web.RootPath + 'api/v2/pricing/business-pricelist?',\n\t\tpricelistApiB: avastGlobals.web.RootPath + 'api/v2/pricing/pricelist?',\n\t\t// These regions has prices with VAT\n\t\tvatLocales: {}\n\t},\n\n\t/**\n\t * init Merge options with defaults, build ajax pool and start ajax\n\t * @param {Object} options Options\n\t * @return {Object} Abdata instance\n\t */\n\tinit: function(options){\n\t\tthis.options = $.extend({}, this.options, options);\n\t\tthis.cache = {};\n\t\tthis.cacheDelimiter = ',';\n\n\t\t// Ajax pool\n\t\tif(typeof $.xhrPool === 'undefined'){\n\t\t\t$.xhrPool = [];\n\n\t\t\t$.xhrPool.abortAll = function() {\n\t\t\t $.each(this, function(idx, jqXHR) {\n\t\t\t\t\tjqXHR.abort();\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\t\t// initial price data\n\t\tthis.getPriceData();\n\n\t\treturn this;\n\t},\n\n\t/**\n\t * createCacheId Generate cacheId\n\t * @param {Object} parameters InternalId and other data\n\t * @return {String} Cache key\n\t */\n\tcreateCacheId: function(parameters){\n\t\tvar elem = this.options.el,\n\t\t\tdata = elem ? elem.data() : null,\n\t\t\tp = (parameters) ? parameters : this.collectAjaxParams(data),\n\t\t\t_ = this.cacheDelimiter,\n\t\t\tcacheId;\n\n\t\t\tif (p.abtype === 'multiyear') {\n\t\t\t\tcacheId = p.internalId + '-' + p.campaign + _ + p.maintenance + _;\n\t\t\t} else {\n\t\t\t\tcacheId = p.internalId + '-' + p.campaign + _ + p.maintenance + _ + p.computers + _ + p.lic + _ + p.appendix;\n\t\t\t}\n\n\t\t\treturn cacheId;\n\t},\n\n\t/**\n\t * getPriceData Collect parameters and send AJAX request or read from cache.\n\t */\n\t// TODO: How about accept additional parameter here, which point to the element from which to collect AJAX params?\n\tgetPriceData: function(el){\n\t\tvar elem = el || this.options.el,\n\t\t\tdata = elem ? elem.data() : null,\n\t\t\tparams = this.ajaxParams = this.collectAjaxParams(data),\n\t\t\tpriceLink = (params.abtype === 'multiyear') ? this.options.pricelistApi : this.options.pricelistApiB, // TODO : Update condition and path according to v2 API\n\t\t\tcacheId = this.createCacheId(params),\n\t\t\tpriceData,\n\t\t\tparamQuery ='productId=' + params.internalId.match(/[^-]*-[^-]*/) +\n\t\t\t\t\t\t'&internalId=' + params.internalId +\n\t\t\t\t\t\t'&maintenance=' + params.multiyear +\n\t\t\t\t\t\t'&seats=' + params.computers +\n\t\t\t\t\t\t'&locale=' + avast.locale +\n\t\t\t\t\t\t'&campaignMarker=' + params.campaignMarker +\n\t\t\t\t\t\t'&platform=web' +\n\t\t\t\t\t\t'&h=' + params.apiHash;\n\n\t\tif (params.installments) {\n\t\t\t paramQuery += '&installments=' + params.installments;\n\t\t}\n\t\tif (params.campaign) {\n\t\t\t paramQuery += '&campaign=' + params.campaign;\n\t\t}\n\t\tif (params.provider) {\n\t\t\t paramQuery += '&provider=' + params.provider;\n\t\t}\n\n\t\t// make ajax call\n\t\t//console.log(\"cacheId: %s\", cacheId);\n\t\t//console.log(\"cache: %o\", this.cache);\n\n\t\tif(!this.cache[cacheId]){\n\t\t\t$.ajax({\n\t\t\t\ttype: \"GET\",\n\t\t\t\turl: priceLink + paramQuery,\n\t\t\t\tdataType: \"json\",\n\t\t\t\tcontext: this,\n\t\t\t\tbeforeSend: function(jqXHR){\n\t\t\t\t\t//$.xhrPool.abortAll(); // Kill all pending requests\n\t\t\t\t\t$.xhrPool.push(jqXHR);\n\t\t\t\t},\n\t\t\t\tsuccess: function(data){\n\t\t\t\t\tthis.parseData(cacheId, data);\n\t\t\t\t\tpriceData = this.selectFromCache(cacheId);\n\t\t\t\t\t$(elem).trigger('data.ab.avast', [priceData ? 'data sent' : 'no data', priceData]);\n\t\t\t\t},\n\t\t\t\terror: function(jqXHR, textStatus, errorThrown){\n\t\t\t\t\tif(textStatus !== \"abort\"){\n\t\t\t\t\t\t$(elem).trigger('data.ab.avast', ['ajax error', textStatus, errorThrown]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t priceData = this.selectFromCache(cacheId);\n\t\t $(elem).trigger('data.ab.avast', [priceData ? 'data sent' : 'no data', priceData]);\n\t\t}\n\t},\n\n\t/**\n\t * collectAjaxParams Read jQuery.data from element\n\t * data {Object} parameters for AJAX request\n\t * @return {Object} Ajax parameters\n\t */\n\tcollectAjaxParams: function(data){\n\t\tvar params = {};\n\n\t\tif(data){\n\t\t\tparams = {\n\t\t\t\tabtype : (typeof data.abtype === 'string' && data.abtype.indexOf('business') > -1) ? 'multiyear' : '', // Can be solved only with different XML structure?\n\t\t\t\tinternalId : data.internalid || '',\n\t\t\t\tcampaign : data.campaign || '',\n\t\t\t\tmaintenance : data.maintenance || '12', // Maintenance should be skipped if multiyear is called\n\t\t\t\tcomputers : data.computers || '1',\n\t\t\t\tlic : data.lic || '1',\n\t\t\t\tappendix : '', // TODO: This polute cacheId with hypen on the end\n\t\t\t\tmultiyear : data.multiyear || '12,24,36',\n\t\t\t\tprovider : data.provider || null,\n\t\t\t\tinstallments: data.installments || null,\n\t\t\t\tadditional2 : data.additional2 || null,\n\t\t\t\tapiHash : data.apiHash || null,\n\t\t\t\tcampaignMarker : data.campaignMarker || 'WDS'\n\t\t\t};\n\t\t}\n\t\treturn params;\n\t},\n\n\t/**\n\t * parseData Convert data from AJAX response to object\n\t * @param {String} cacheId Cache key\n\t * @param {Object} data JSON data\n\t */\n\tparseData: function(cacheId, data){\n\t\t// parsing should create\n\t\tvar delim = this.cacheDelimiter,\n\t\t\tabDataInstance = this,\n\t\t\tre = new RegExp(this.cacheDelimiter + '(.+?)' + this.cacheDelimiter);\n\n\t\t/*\n\t\t * Update cache with new cacheId, put empty object as value.\n\t\t * If request is correct, it will be replaced with approp data.\n\t\t * Creating cacheId - even from incorrect ID - prevents calling AJAX requests repeatedly.\n\t\t */\n\t\tabDataInstance.updateCache(cacheId, {});\n\n\t\tif(data && !data.products) {\n\t\t\t// HOME\n\t\t\t$.each(data, function() {\n\t\t\t\tvar cId = cacheId.replace(re, delim + this.maintenance + delim);\n\n\t\t\t\tthis.maintenanceLimits = [12,24,36];\n\t\t\t\tthis.computersLimits = [1, 3, 5, 10];\n\t\t\t\tthis.priceInNumber = '' + this.price;\n\t\t\t\tthis.price = this.priceFormatted;\n\t\t\t\tthis.realPriceInNumber = '' + abDataInstance.stripDecimals(this.realPrice, this.precision);\n\t\t\t\tthis.realPrice = this.realPriceFormatted;\n\t\t\t\tthis.totalPrice = abDataInstance.getTotalPrice(this.internalId);\n\n\t\t\t\tabDataInstance.updateCache(cId, this);\n\t\t\t});\n\t\t} else if (data.products && data.products.length !== 0) {\n\t\t\t// BUSINESS\n\t\t\t$.each(data.products, function() {\n\t\t\t\t// Update cacheId\n\t\t\t\tvar priceData = {};\n\t\t\t\tvar price = [];\n\t\t\t\tvar realPrice = [];\n\t\t\t\tvar $this = $(this)[0];\n\t\t\t\tvar cId = cacheId.replace(re, delim + $this.maintenance + delim);\n\n\t\t\t\tfor (var key in $this.prices) {\n\t\t\t\t\tprice.push({\n\t\t\t\t\t\t'min': parseInt(key, 10),\n\t\t\t\t\t\t'price' : parseFloat($this.prices[key])\n\t\t\t\t\t });\n\t\t\t\t\t realPrice.push({\n\t\t\t\t\t\t'min': parseInt(key, 10),\n\t\t\t\t\t\t'price' : parseFloat($this.prices[key])\n\t\t\t\t\t });\n\t\t\t\t}\n\n\t\t\t\tpriceData.price = function(quant){\n\t\t\t\t\tvar _quant = parseInt(quant, 10),\n\t\t\t\t\t\t_vat = (data.vat && abDataInstance.options.vatLocales[avast.locale]) ? data.vat : 1,\n\t\t\t\t\t\t_price;\n\n\t\t\t\t\tfor (var i = 0; price.length > i; i++){\n\t\t\t\t\t\tif(_quant >= price[i].min){\n\t\t\t\t\t\t\t_price = price[i].price;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn _price * _quant * _vat;\n\t\t\t\t};\n\t\t\t\tpriceData.realPrice = function(quant){\n\t\t\t\t\tvar _quant = parseInt(quant, 10),\n\t\t\t\t\t\t_vat = (data.vat && abDataInstance.options.vatLocales[avast.locale]) ? data.vat : 1,\n\t\t\t\t\t\t_price;\n\n\t\t\t\t\t for (var i = 0; realPrice.length > i; i++){\n\t\t\t\t\t\tif(_quant >= realPrice[i].min){\n\t\t\t\t\t\t\t_price = realPrice[i].price;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn _price * _quant * _vat;\n\t\t\t\t};\n\t\t\t\tpriceData.link = function(quant){\n\t\t\t\t\treturn data.link.replace('{PID}', $this.foreignId).replace('{QUANT}', quant);\n\t\t\t\t};\n\t\t\t\t//priceData.discount = $this.attr('real-discount');\n\t\t\t\tpriceData.flatDiscount = data.discount; // Flat discount not related to number of devices\n\t\t\t\tpriceData.discountType = data.discountType;\n\t\t\t\tpriceData.minQuantity = data.minQuantity;\n\t\t\t\tpriceData.maxQuantity = data.maxQuantity;\n\t\t\t\tpriceData.maintenance = $this.maintenance;\n\t\t\t\tpriceData.maintenanceLimits = [12,24,36];\n\t\t\t\tpriceData.priceFormat = data.priceFormat;\n\t\t\t\tpriceData.currency = data.currencySymbol;\n\t\t\t\tpriceData.thousandSeparator = data.thousandSeparator;\n\t\t\t\tpriceData.decimalSeparator = data.decimalSeparator;\n\t\t\t\tpriceData.precision = data.precision;\n\t\t\t\tpriceData.priceFormat = data.priceFormat;\n\n\t\t\t\tabDataInstance.updateCache(cId, priceData);\n\t\t\t});\n\t\t} else {\n\t\t\tvar msg = 'no data';\n\t\t\t$(elem).trigger('data.ab.avast', [msg]);\n\t\t}\n\t},\n\n\t/**\n\t * stripDecimals Remove additional decimals over precision limit\n\t * @param {number} number A number to be stripped\n\t * @param {integer} precision Number of decimals in returned float\n\t * @return {number} Stripped number\n\t */\n stripDecimals: function(number, precision){\n\t\tvar decimalSeparator = '\\\\.',\n\t\t\tregex = new RegExp(\"^-?\\\\d+(?:\" + decimalSeparator + \"\\\\d{0,\" + precision + \"})?\");\n\n\t\tif (precision) {\n\t\t\tnumber = number.toString().match(regex)[0];\n\t\t}\n\n\t\treturn Number(number);\n\t},\n\n\t/**\n\t * updateCache Store data in cache to specific key\n\t * @param {String} cacheId Cache key\n\t * @param {Object} data Price data\n\t */\n\tupdateCache: function(cacheId, data){\n\t\tthis.cache[cacheId] = data;\n\t},\n\n\t/**\n\t * Get price data from cache\n\t * @param {String} cacheId Unique identifier. Look to createCacheId method from what is created.\n\t * @return {Object} Price data\n\t */\n\tselectFromCache : function(cacheId){\n\t\treturn this.cache[cacheId];\n\t},\n\n\t/**\n\t * getDataByInternalId Select all matched entries in cache. Match can be partial.\n\t * @param {String} internalId Internal ID of product\n\t * @param {Object} props Additional properties which can modify cache ID identificator (campaign, maintenance, pcs, etc.)\n\t * @return {Array} Price objects\n\t */\n\tgetDataByInternalId : function(internalId, props){\n\t\tvar cache = this.cache,\n\t\t\tparams = $.extend({}, {internalId: internalId}, props),\n\t\t\tajaxParams = this.collectAjaxParams(params),\n\t\t\tcacheId = this.createCacheId(ajaxParams),\n\t\t\tcacheData = this.selectFromCache(cacheId),\n\t\t\tre = new RegExp('^' + internalId),\n\t\t\tdata = [];\n\n\t\tif(props) {\n\t\t\tif(cacheData){\n\t\t\t\tdata.push(cacheData);\n\t\t\t}\n\t\t} else {\n\t\t\tfor(var key in cache){\n\t\t\t\t// console.log('Match: %s', re.test(key))\n\t\t\t\tif(re.test(key)) {\n\t\t\t\t\tdata.push(cache[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn data;\n\t},\n\t/**\n\t * getTotalPrice Collect prices from data attributes.\n\t * @description Method assumes there is a `data-pricelist` attribute in the markup\n\t * with prices without installment divider. Pricelist should expose all seats prices for maintenance variant.\n\t * @param {string} id InternalId\n\t * @return {string} Price\n\t */\n\tgetTotalPrice: function(id) {\n\t\tvar price = null;\n\n\t\t$('[data-pricelist]').each(function(index) {\n\t\t\tvar priceList;\n\n\t\t\ttry {\n\t\t\t\tpriceList = JSON.parse(this.dataset.pricelist);\n\t\t\t} catch(error) {\n\t\t\t\tconsole.log(error);\n\t\t\t}\n\n\t\t\tif (priceList && priceList[id]) {\n\t\t\t\tprice = priceList[id].realPriceFormatted;\n\t\t\t}\n\t\t});\n\n\t\treturn price;\n\t}\n};\n\n/**\n * Actionbox object: Product Actionbox with prerendered prices.\n *\n * @version 0.1.5\n * @author Ales Gabriel\n * @copyright Avast Software s.r.o ©2014\n */\n\nvar Actionbox = {\n\tdefaults: {\n\t abProductsSelector : '[data-internalid]', // Context element selector\n\t overlaySelector : '#overlay', // Dim page with this element.\n\t abBoxSelector : '.box', // boxes class\n\t autoLoadData : false, // Request AJAX price data with first render. It will rewrite prices, links which are set in html\n\t installments : 0,\n\t installmentTemplate : '#p× de ',\n\t customCurrency : '',\n\t currencySwitch : ''\n\t},\n\t/**\n\t * Init plugin and register global listeners\n\t * @param {Object} opts Config options\n\t * @param {DOM Node} elem Element where plugin is initiated\n\t */\n\tinit: function(opts, elem){\n\t\t this.options = $.extend({},this.defaults,opts);\n\t\t this.build(elem);\n\n\t\t // Register default events\n\t\t $(document).on('data.ab.avast', $.proxy(this.loopBoxes, this));\n\t},\n\t/**\n\t * Register UI events, open and call for price data\n\t * @param {Event} evt Event called for popup\n\t */\n\tbuild: function(elem){\n\t\t// Count timeout\n\t\tthis.countTimeout = '';\n\n\t\t// If custom template replace default popup with different element\n\t\tthis.context = $(elem);\n\t\t// abEl can be in elements on which actionbox is initialized, but must have data-internalid set.\n\t\t// Or can be any first-child with data-internalid set.\n\t\tthis.abEl = this.context.data('internalid') ? this.context : this.context.find('[data-internalid]').first();\n\n\t\t// Register button events\n\t\tthis.abEl.find('.add').on('mousedown.ab.avast', $.proxy(this.updateInputs, this));\n\t\tthis.abEl.find('.add').on('mouseup.ab.avast', $.proxy(this.updateInputsData, this));\n\n\t\t// Register close events\n\t\t$(document).on('keydown.ab.avast', $.proxy(this.handleKeyPress, this));\n\n\t\t// Prerender\n\t\tthis.preRender();\n\n\t\t// Only if it is autoLoadData ask for data during with build. Otherwise wait for user interaction.\n\t\tif(this.options.autoLoadData){\n\t\t\tthis.pullData();\n\t\t}\n\t},\n\t/**\n\t * Correct display, reset inputs.\n\t */\n\tpreRender : function() {\n\t\t// Prerender\n\t\tthis.abEl.append('
');\n\t\tthis.resetInputs();\n\t\tvar boxClass = this.options.abBoxSelector;\n\n\t\t// Hide Regular price label if price missing or price is same as price.\n\t\tthis.abEl.find('.no-discount').each(function(){\n\t\t\tvar $this = $(this),\n\t\t\t\tbox = $this.closest(boxClass),\n\t\t\t\tvalEl = $this.find('.value'),\n\t\t\t\tvalContent = valEl.text(),\n\t\t\t\tisEmpty = !$.trim(valContent),\n\t\t\t\tpriceEqual = ($(box).find('a.button > span').text() === valContent ) ? 1 : 0;\n\n\t\t\tif(isEmpty || priceEqual) {\n\t\t\t\t$this.addClass('hidden');\n\t\t\t}\n\t\t});\n\t},\n\t/**\n\t * pullData Ask for data\n\t * @return {[type]} [description]\n\t */\n\tpullData: function(){\n\t\t// DOM changes - Add spinner\n\t\t// TODO: move to own function\n\t\tthis.abEl.addClass('spinning');\n\t\tthis.abEl.find('.box .button').addClass('spinning');\n\t\tthis.abEl.parent('div').find('.ab-overlay').removeClass('hidden');\n\n\t\t// Ask for data.\n\t\tif($.data(this.abEl.get(0), 'abdata')){\n\t\t\tthis.abEl.data('abdata').getPriceData();\n\t\t} else {\n\t\t\t// If no instance of abdata on element, revoke abdata plugin initialization.\n\t\t\tif(typeof $.fn.abdata === 'function'){\n\t\t\t\tthis.abEl.abdata({el : this.abEl});\n\t\t\t}\n\t\t}\n\t},\n\t/**\n\t * loopBoxes Incrementaly loop boxes, create specific cacheId and call for price data update.\n\t * @param {Event} evt Internal data.ab.avast event\n\t * @param {String} msg Message from event\n\t * @param {Object} data Prices, links, formats etc.\n\t */\n\tloopBoxes: function(evt, msg, data){\n\n\t\tvar nextInternalId,\n\t\t\tnextBox;\n\n\t\tif(data && data.maintenance) {\n\t\t\tvar root = this;\n\t\t\t// load prices, links etc. to current box\n\t\t\tthis.fillData(evt, msg, data);\n\t\t\t// TODO: Try harder to indentify next box.\n\t\t\t// This doesn't work if some maintanence box is missing ... check siblings in DOM or something like this\n\t\t\t// Prepare next maintenance\n\t\t\tthis.abEl.data('maintenance', parseInt(data.maintenance, 10) + 12);\n\n\t\t\tnextBox = this.abEl.find('[data-internalid]').filter(function(){\n\t\t\t\tvar boxInternalId = $(this).data('internalid');\n\t\t\t\tvar nextInternalId = root.buildInternalId(boxInternalId, {maintenance: parseInt(data.maintenance, 10) + 12});\n\n\t\t\t\tvar boxInternalIdObj = root.internalIdToObj(boxInternalId);\n\t\t\t\tvar currentMaintenance = boxInternalIdObj.maintenance;\n\t\t\t\tvar nextMaintenance = parseInt(data.maintenance, 10) + 12;\n\n\t\t\t\t// return $(this).data('internalid') === nextInternalId;\n\t\t\t\treturn parseInt(currentMaintenance, 10) === nextMaintenance;\n\t\t\t});\n\n\t\t\tif($.data(this.abEl.get(0), 'abdata') && nextBox.length > 0){\n\t\t\t // Ask for data only if next box exists\n\t\t\t this.pullData();\n\t\t\t} else {\n\t\t\t // Publish price update is finished\n\n\t\t\t $(document).trigger('priceUpdate.ab.avast', ['actionbox prices updated']);\n\t\t\t}\n\t\t\tthis.abEl.removeData('maintenance');\n\t\t}\n\t},\n\n\t/**\n\t * fillData Update DOM with data\n\t * @param {Event} evt Internal data.ab.avast event\n\t * @param {String} msg Message from event\n\t * @param {Object} data Prices, links, formats etc.\n\t */\n\t// TODO: Last param should be last.\n\tfillData: function(evt, msg, data) {\n\t\tvar formatedData = {},\n\t\t\tpcs = this.abEl.find('#computers'),\n\t\t\tmainInternalId = this.abEl.data('internalid'),\n\t\t\troot = this,\n\t\t\titemInternalId,\n\t\t\tcontext,\n\t\t\tpriceDivider = this.options.installments ? this.options.installments : (this.options.pricing === 'monthly' && data && data.maintenance) ? data.maintenance : 1,\n\t\t\tcurrencySymbol = data.currencySymbol ? data.currencySymbol : data.currency;\n\n\t\tif (data){\n\t\t\t// Reduce input values to min/max if set.\n\t\t\tif(data.minQuantity){\n\t\t\t\tif(parseInt(pcs.val(), 10) <= parseInt(data.minQuantity, 10)) {\n\t\t\t\t\tpcs.val(data.minQuantity);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(data.maxQuantity){\n\t\t\t\tif(parseInt(pcs.val(), 10) >= parseInt(data.maxQuantity, 10)){\n\t\t\t\t\tpcs.val(data.maxQuantity);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// TODO: Where to triger validation message HAS_PRICE = 1\n\n\t\t\t// Computers quantity in input\n\t\t\tvar quant = pcs.val();\n\n\t\t\t// Prices\n\t\t\tformatedData.link = (typeof data.link === 'function') ? data.link(quant) : data.link;\n\t\t\tformatedData.realPrice = (typeof data.realPrice === 'function') ? data.realPrice(quant) : data.realPrice;\n\t\t\tformatedData.price = (typeof data.price === 'function') ? data.price(quant) : data.price;\n\t\t\tformatedData.discount = data.discount;\n\n\t\t\t// Formating prices\n\t\t\tif(typeof data.price === 'function'){\n\t\t\t\tformatedData.price = this.formatPrice(formatedData.price, data.priceFormat, data.currency, data.precision, data.decimalSeparator, data.thousandSeparator);\n\t\t\t\tformatedData.realPrice = this.formatPrice(formatedData.realPrice, data.priceFormat, data.currency, data.precision, data.decimalSeparator, data.thousandSeparator);\n\t\t\t}\n\n\t\t\t// Formating installments prices\n\t\t\tif(this.options.installments){\n\t\t\t\tvar installmentPrice = this.formatPrice((data.realPriceInNumber / this.options.installments) , data.priceFormat, currencySymbol, data.precision, data.decimalSeparator, data.thousandSeparator);\n\t\t\t\tformatedData.realPriceTotal = formatedData.realPrice;\n\t\t\t\tformatedData.realPrice = this.options.installmentTemplate.replace('#p', this.options.installments) + installmentPrice;\n\t\t\t}\n\n\t\t\tif(this.options.priceyTypo){\n\t\t\t\tvar typoPrice = this.formatPrice((data.realPriceInNumber / priceDivider) , data.priceFormat, currencySymbol, data.precision, data.decimalSeparator, data.thousandSeparator);\n\t\t\t\ttypoPrice = typoPrice.replace(' ', '');\n\n\t\t\t\tvar typoPriceParts = typoPrice.split(data.decimalSeparator);\n\t\t\t\tvar markupPrice = [];\n\n\t\t\t\t// Open price wrapper\n\t\t\t\tmarkupPrice.push('');\n\t\t\t\t// Paste currency before price\n\t\t\t\tif(typoPrice.indexOf(currencySymbol) === 0){\n\t\t\t\t\t markupPrice.push('' + currencySymbol + '');\n\t\t\t\t}\n\t\t\t\t// Paste price\n\t\t\t\tmarkupPrice.push('' + typoPriceParts[0].replace(currencySymbol, '') + '');\n\n\t\t\t\t// Decimal price if any\n\t\t\t\tif(typoPriceParts[1]){\n\t\t\t\t\tmarkupPrice.push('' + data.decimalSeparator + typoPriceParts[1].replace(currencySymbol, '') + '');\n\t\t\t\t}\n\t\t\t\t// Paste currency symbol after price\n\t\t\t\tif(typoPrice.indexOf(currencySymbol) !== 0){\n\t\t\t\t\t markupPrice.push('' + currencySymbol + '');\n\t\t\t\t}\n\t\t\t\t// Close price wrapper\n\t\t\t\tmarkupPrice.push('');\n\n\t\t\t\tformatedData.realPriceTotal = formatedData.realPrice;\n\t\t\t\tformatedData.realPrice = markupPrice.join('');\n\t\t\t}\n\n\t\t\tif(this.options.pricing === 'monthly'){\n\t\t\t\tformatedData.link = formatedData.link.replace(/\\/CustomID.(.*)\\//, '/CustomID.' + this.options.customId + '/');\n\t\t\t}\n\n\t\t\t// Set only data values, leave DOM data attributes without change.\n\t\t\tif(data.computersLimits && !this.abEl.data('computers-limits')){\n\t\t\t\tthis.abEl.data('computers-limits', data.computersLimits);\n\t\t\t}\n\t\t\tif(data.maintenanceLimits && !this.abEl.data('maintenance-limits')){\n\t\t\t\tthis.abEl.data('maintenance-limits', data.maintenanceLimits);\n\t\t\t}\n\t\t\tif(data.minQuantity){\n\t\t\t\tthis.abEl.data('min-quantity', data.minQuantity);\n\t\t\t}\n\t\t\tif(data.maxQuantity){\n\t\t\t\tthis.abEl.data('max-quantity', data.maxQuantity);\n\t\t\t}\n\n\t\t\tif(data.maintenance && mainInternalId){\n\t\t\t\titemInternalId = this.buildInternalId( mainInternalId, {maintenance: parseInt(data.maintenance, 10)});\n\t\t\t\t// Get context element by comparing maintenance in internalId for each box and data.maintenance\n\t\t\t\tcontext = this.abEl.find('[data-internalid]').filter(function(){\n\t\t\t\t\t\tvar boxInternalId = $(this).data('internalid'),\n\t\t\t\t\t\t\tboxInternalIdObj = root.internalIdToObj(boxInternalId),\n\t\t\t\t\t\t\tcurrentMaintenance = boxInternalIdObj.maintenance,\n\t\t\t\t\t\t\tnextMaintenance = parseInt(data.maintenance, 10);\n\n\t\t\t\t\t\treturn parseInt(currentMaintenance, 10) === nextMaintenance;\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\tif(context){\n\t\t\t\tthis.renderData(context, formatedData);\n\t\t\t}\n\t\t}\n\t},\n\t/**\n\t * renderData Update DOM with changes\n\t * @param {DOMElement} context Ancestor element\n\t * @param {Object} formatedData Data to render\n\t */\n\trenderData: function(context, formatedData){\n\t\t\t// Render prices and link values\n\t\t\tthis.renderValue('.button > span', context, formatedData.realPrice);\n\t\t\tthis.renderValue('.discounted > span:first-child', context, formatedData.realPrice);\n\t\t\tthis.renderValue('.discount', context, formatedData.realPriceTotal);\n\t\t\tthis.renderValue('.no-discount', context, (formatedData.discount) ? formatedData.price : '');\n\t\t\tthis.renderValue('.save', context, formatedData.discount);\n\t\t\tthis.renderValue('.button', context, formatedData.link, 'href');\n\t\t\tthis.renderValue('.cart', context, formatedData.link, 'href');\n\t\t\tthis.abEl.removeClass('spinning');\n\t\t\tthis.abEl.find('.box .button').removeClass('spinning');\n\t\t\tthis.abEl.find('.ab-overlay').addClass('hidden');\n\t},\n\t//WUT\n\t/**\n\t * formatPrice Format price with currency, correct precision, decimal thousand separator and currency\n\t * @param {[type]} price [description]\n\t * @param {[type]} priceFormat [description]\n\t * @param {[type]} currency [description]\n\t * @param {[type]} precision [description]\n\t * @param {[type]} decSep [description]\n\t * @param {[type]} thSep [description]\n\t * @return {String} Price with correct format with currency\n\t */\n\tformatPrice: function(price, priceFormat, currency, precision, decSep, thSep){\n\t\tvar formatedPrice;\n\n\t\tif(typeof $().number_format === 'function') {\n\t\t\tformatedPrice = $().number_format(price,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnumberOfDecimals: precision,\n\t\t\t\t\t\t\t\tdecimalSeparator: decSep,\n\t\t\t\t\t\t\t\tthousandSeparator: thSep,\n\t\t\t\t\t\t\t\tsymbol: \"\"\n\t\t\t\t\t\t\t});\n\t\t}\n\t\tif(formatedPrice){\n\t\t\treturn priceFormat.replace(\"#c\",currency).replace(\"#p\",formatedPrice);\n\t\t}\n\t},\n\t/**\n\t * renderValue Output specific value to DOM. If Element has child with css class \".value\", value will be rendered in this child.\n\t * @param {[type]} cssSelector Element selector\n\t * @param {DOMElement} context Search for cssSelector in specified context\n\t * @param {String} val Value\n\t * @param {String} attr Load value to element attribute\n\t */\n\trenderValue: function(cssSelector, context, val, attr){\n\t\tvar elem = (cssSelector) ? $(context).find(cssSelector) : '';\n\t\tif(val){\n\t\t\telem.removeClass('hidden');\n\t\t\t// Update attributes\n\t\t\tif (attr && attr !== 'class') {\n\t\t\t\telem.attr(attr, val);\n\t\t\t} else if (attr && attr === 'class'){\n\t\t\t\telem.removeClass(this.findClass(elem, 'avast-').join(''));\n\t\t\t\telem.addClass(val);\n\t\t\t} else {\n\t\t\t\tif(elem.has('.value').length > 0){\n\t\t\t\t\telem.find('.value').html(val);\n\t\t\t\t} else {\n\t\t\t\t\telem.html(val);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\telem.addClass('hidden');\n\t\t}\n\t},\n\t/**\n\t * [updateInputsData description]\n\t * @param {Event} evt Mouse event when encrease, decrease pcs or maintenance\n\t */\n\tupdateInputsData: function(evt) {\n\t\tvar pcs = this.abEl.find('#computers'),\n\t\t\tyrs = this.abEl.find('#maintenance'),\n\t\t\tcurrent = ($(evt.currentTarget).siblings('.amount').find('#computers').length > 0) ? pcs : yrs,\n\t\t\tnewVal = parseInt(current.val(), 10), // TODO: value based on minQuantity, maxQuantity\n\t\t\tnewIndex,\n\t\t\tpcsString = this.pad(pcs.val(), 3),\n\t\t\tbtn = $(evt.currentTarget);\n\n\t\t// Break if custom behavior\n\t\tif(btn.data('behavior') === 'custom'){\n\t\t\treturn;\n\t\t}\n\n\t\t// Stop event input updates.\n\t\tclearTimeout(this.countTimeout);\n\n\n\t\tif(current === yrs){\n\t\t\tif(parseInt(newVal, 10) >= 12){\n\t\t\t\t// Convert months to years\n\t\t\t\tnewVal = parseInt(newVal, 10) / 12;\n\t\t\t} else {\n\t\t\t\t// Months are not currently in use.\n\t\t\t}\n\t\t}\n\n\t\t// Update data with value from input\n\t\tthis.abEl.data('computers', pcs.val());\n\n\t\t// Inputs and data config done. Call for prices.\n\t\tif(evt.type === 'mouseup' || (evt.type === 'mouseout' && btn.data('flag-outbound') === 'mouseout')){\n\t\t\tbtn.removeData('flag-outbound');\n\t\t\tthis.updateInternalIds({pcs: pcsString});\n\t\t\tthis.pullData();\n\t\t}\n\t},\n\t//WUT\n\t/**\n\t * pad Leading zeros\n\t * @param {Number} num Number to which add leading zeros\n\t * @param {Number} size From what size prepend zeros\n\t * @return {String} [description]\n\t */\n\tpad: function(num, size) {\n\t\tvar s = num+\"\";\n\t\twhile (s.length < size) s = \"0\" + s;\n\t\treturn s;\n\t},\n\t/**\n\t * updateInternalIds Loop elements with data-internalid attribute and update its internalId.\n\t * @param {Objec} props Properties to be updated ( Available props: name | version | pcs | maintenance | renewal )\n\t */\n\tupdateInternalIds: function(props){\n\t\tvar root = this;\n\n\t\t/**\n\t\t * There must be internalId updated for home.\n\t\t * But mustn't be updated for business.\n\t\t */\n\t\tvar context = (this.abEl.data('abtype') !== 'business') ? this.abEl.parent() : this.abEl;\n\n\t\tcontext.find('[data-internalid]').each(function(){\n\t\t\tvar $this = $(this);\n\t\t\tvar newId = root.buildInternalId($this.data('internalid'), props);\n\t\t\t$this.data('internalid', newId);\n\t\t});\n\t},\n\n\t//WUT\n\t/**\n\t * buildInternalId Build new internal ID by merge former internalid and props from parameter\n\t * @param {String} id Internal ID to update\n\t * @param {Object} props Properties to be updated ( Available props: name | version | pcs | maintenance | renewal )\n\t * @return {String} New Internal ID\n\t */\n\tbuildInternalId: function(id, props){\n\t\tvar newId,\n\t\t\tidObj = this.internalIdToObj(id),\n\t\t\t_idObj = {};\n\t\tif(props){\n\t\t\t$.extend(_idObj, idObj, props);\n\t\t}\n\t\tnewId = $.map(_idObj, function(prop){return prop;}).join('-');\n\n\t\treturn newId;\n\t},\n\n\t//WUT\n\t/**\n\t * internalIdToObj description\n\t * @param {String} internalId Internal ID (eg. ISE-08-001-12-MR).\n\t * @return {Object} Internal ID converted to object\n\t */\n\tinternalIdToObj: function(internalId){\n\t\tvar idObj = {},\n\t\t\tidParts = internalId.split('-');\n\n\t\t// TODO: This one only works for new internalId strings format (eg. ISE-08-001-12-MR).\n\t\tidObj.name = idParts[0];\n\t\tidObj.version = idParts[1];\n\t\tidObj.pcs = idParts[2];\n\t\tidObj.maintenance = idParts[3];\n\t\tidObj.renewal = idParts[4];\n\n\t\treturn idObj;\n\t},\n\n\t/**\n\t * resetInputs Set elements data to default values PCs: 1, Maintenance: 12\n\t */\n\tresetInputs: function(){\n\t\tvar pcs = this.abEl.find('#computers'),\n\t\t\tyrs = this.abEl.find('#maintenance'),\n\t\t\tprodEl = this.abEl;\n\n\t\tpcs.val(1);\n\t\tyrs.val(1);\n\n\t\t// Change data\n\t\tprodEl.data('computers', 1);\n\t\tprodEl.data('maintenance', 12);\n\t\tif(prodEl.data('internalid-default')){\n\t\t\tprodEl.data('internalid', prodEl.data('internalid-default'));\n\t\t}\n\n\t\t// Enable disabled buttons\n\t\tthis.abEl.find('.add.disabled').removeClass('disabled');\n\t},\n\t//WUT\n\t/**\n\t * findClass Find class by prefix\n\t * @param {DOMElement} el In Element\n\t * @param {String} prefix Search for prefix\n\t * @return {Boolean}\n\t */\n\tfindClass: function(el, prefix) {\n\t\tvar classes = $(el).attr(\"class\").split(\" \").filter(function(c) {\n\t\t\treturn c.lastIndexOf(prefix, 0) === 0;\n\t\t});\n\t\treturn classes;\n\t},\n\t//WUT\n\t/**\n\t * allowedValues Return allowed values in selector. Limits higher importance over min, max\n\t * @param {Number} min Minimal value\n\t * @param {Number} max Maximal value\n\t * @param {Array} limits Ordering has holes - send exact values in Array\n\t * @return {Array}\n\t */\n\tallowedValues: function(min, max, limits){\n\t\tvar values = [],\n\t\t\tlen = (min && max) ? max - min + 1 : false;\n\n\t\tif(!limits && len){\n\t\t\tfor(var i = 0; len > i; i++){\n\t\t\t\tvalues.push(min + i);\n\t\t\t}\n\t\t} else {\n\t\t\tvalues = limits;\n\t\t}\n\t\treturn values;\n\t},\n\n\t/**\n\t * updateInputs Button click handler. Manage increase/decrease on inputs and update data attributes\n\t * @param {Event} evt Mouse event\n\t */\n\tupdateInputs: function(evt){\n\t\tvar btn = $(evt.currentTarget),\n\t\t\t\t speed = 300, // Initial speed of counting\n\t\t\t\t speedup = 0.5, // next loop will be shorter then previous about this amount\n\t\t\t\t maxSpeed = 50, // max speed in which counting is repeated (in miliseconds)\n\t\t\t\t root = this,\n\t\t\t\t inputId = btn.closest('.select').find('input').attr('id'),\n\t\t\t\t input = this.abEl.find('#' + inputId),\n\t\t\t\t increase = (btn.hasClass('plus')) ? 1 : -1;\n\n\n\t\tvar min = parseInt(this.abEl.data('min-quantity'), 10),\n\t\t\tmax = parseInt(this.abEl.data('max-quantity'), 10),\n\t\t\tlimits = (inputId === 'computers') ? this.abEl.data('computers-limits') : this.abEl.data('maintenance-limits'),\n\t\t\t// Create array from min max, or limits.\n\t\t\tvalues = this.allowedValues(min, max, limits);\n\n\t\t// Break if custom behavior\n\t\tif($(evt.currentTarget).hasClass('disabled')){\n\t\t\treturn;\n\t\t}\n\n\t\tif(typeof evt.originalEvent.preventDefault === \"function\"){\n\t\t\tevt.originalEvent.preventDefault(); // Disable Chrome set cursor to text while dragging\n\t\t}\n\n\t\tif(values) {\n\t\t\tmaxSpeed = 150; // Slowdown max speed if values are limited.\n\t\t\tthis.countIndex = values.indexOf((inputId === 'computers') ? parseInt(input.val(), 10) : parseInt(input.val(), 10) * 12);\n\t\t} else {\n\t\t\tthis.countIndex = (inputId === 'computers') ? parseInt(input.val(), 10) : parseInt(input.val(), 10) * 12;\n\t\t}\n\n\t\t// bind/unbind mouseout event on each attempt\n\t\tif (btn.data('flag-outbound') !== 'mouseout'){\n\t\t\t\tbtn.on('mouseout.ab.avast', function(evt){\n\t\t\t\t\tclearTimeout(root.countTimeout);\n\t\t\t\t\troot.updateInputsData.call(root, evt);\n\t\t\t\t\tbtn.off('mouseout.ab.avast');\n\t\t\t\t\tbtn.removeData('flag-outbound');\n\t\t\t\t});\n\t\t\tbtn.data('flag-outbound', 'mouseout');\n\t\t}\n\n\t\tcounting(function(){\n\t\t\troot.updateCount(values, root.countIndex, inputId, increase, min, max);\n\t\t});\n\n\t\t// Update speed of incrementing\n\t\tfunction counting(fn){\n\t\t\tfn();\n\t\t\troot.countTimeout = setTimeout(function(){counting(fn);}, speed);\n\t\t\tspeed = (speed > maxSpeed) ? speed * speedup : maxSpeed;\n\t\t}\n\t},\n\t/**\n\t * updateCount Make changes to DOM data attributes and input values on each counting step\n\t * @param {Array} values Array of allowed values, which can be dispalyed in selector\n\t * @param {Integer} countIndex Index of allowed value, which have to be displayed\n\t * @param {String} inputId Identify which selector should be updated\n\t * @param {Integer} increase 1|-1\n\t */\n\tupdateCount: function(values, countIndex, inputId, increase, min, max){\n\t\tvar msg;\n\t\t// Counting in virtual steps\n\t\tif(values){\n\t\t\tif((countIndex + increase) >= 0 && (countIndex + increase) < values.length){\n\t\t\t\tthis.countIndex = countIndex + increase;\n\t\t\t} else {\n\t\t\t\tmsg = (countIndex === 0) ? 4 : 3;\n\t\t\t\tif(msg === 4) {\n\t\t\t\t\tthis.countIndex = values.length - 1;\n\t\t\t\t}\n\t\t\t\tif (msg === 3) {\n\t\t\t\t\tthis.countIndex = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.abEl.find('#' + inputId).val((inputId === 'computers') ? values[this.countIndex] : values[this.countIndex] / 12);\n\t\t// Plain increment\n\t\t} else {\n\t\t\tvar input = this.abEl.find('#' + inputId);\n\t\t\tvar count = parseInt(input.val(), 10) + increase;\n\t\t\t// TODO: check why stops working if counting under zero !!\n\t\t\tif(count > 0){\n\t\t\t\tinput.val(count);\n\t\t\t}\n\t\t\tif(count > max ) {\n\t\t\t\tmsg = 3;\n\t\t\t}\n\t\t\tif(count <= min ) {\n\t\t\t\tmsg = 4;\n\t\t\t}\n\t\t}\n\t\t// Triger validation message here TOO_MANY = 3, TOO_SMALL = 4. and decide what to do\n\t\t// TODO: Can be performance expensive to trigger event here.\n\t\t// On the other hand this is the right place to publish message, that limit was reached, buttons can be disabled and so.\n\t\t// Other solution could be set min, max variables besides limits and check it only when user release mouse\n\t\t// But it should looks wierd to count in different steps until limit is reached and then follow with incrementing by 1.\n\t\tif(msg){\n\t\t\tthis.triggerMsg('validation.avast', msg);\n\t\t}\n\t},\n\t_clearTimeout: function(){\n\t\tclearTimeout(this.countTimeout);\n\t},\n\t/**\n\t * triggerMsg Publish event on document\n\t * @param {String} type Event type\n\t * @param {String} msg Event message\n\t */\n\ttriggerMsg: function (type, msg){\n\t\t$(document).trigger(type, [{message: msg}]);\n\t},\n\t/**\n\t * updatePrice Facade code for $('#abox-home-boxes').ab('updatePrice');\n\t * @return {[type]} [description]\n\t */\n\t updatePrice: function (){\n\t\tvar opts = this.options || {};\n\t\tif(typeof $.fn.abdata === 'function'){\n\t\t\topts.el = this.abEl;\n\t\t\tthis.abEl.abdata(opts);\n\t\t}\n\t\t// TODO !!! or use this.pullData();\n\t}\n};\n\n///////////////////////////////////////////////////////////////////\n\n// Array.prototype.filter polyfill\nif (!Array.prototype.filter)\n{\n Array.prototype.filter = function(fun /*, thisArg */) {\n\n\tif (this === void 0 || this === null)\n\t throw new TypeError();\n\n\tvar t = Object(this);\n\tvar len = t.length >>> 0;\n\tif (typeof fun !== \"function\")\n\t throw new TypeError();\n\n\tvar res = [];\n\tvar thisArg = arguments.length >= 2 ? arguments[1] : void 0;\n\tfor (var i = 0; i < len; i++)\n\t{\n\t if (i in t)\n\t {\n\t\tvar val = t[i];\n\n\t\tif (fun.call(thisArg, val, i, t))\n\t\t res.push(val);\n\t }\n\t}\n\n\treturn res;\n };\n}\n\n// Array.prototype.indexOf polyfill\nif (!Array.prototype.indexOf) {\n\tArray.prototype.indexOf = function (searchElement, fromIndex) {\n\t if ( this === undefined || this === null ) {\n\t\tthrow new TypeError( '\"this\" is null or not defined' );\n\t }\n\n\t var length = this.length >>> 0; // Hack to convert object.length to a UInt32\n\n\t fromIndex = +fromIndex || 0;\n\n\t if (Math.abs(fromIndex) === Infinity) {\n\t\tfromIndex = 0;\n\t }\n\n\t if (fromIndex < 0) {\n\t\tfromIndex += length;\n\t\tif (fromIndex < 0) {\n\t\t fromIndex = 0;\n\t\t}\n\t }\n\n\t for (;fromIndex < length; fromIndex++) {\n\t\tif (this[fromIndex] === searchElement) {\n\t\t return fromIndex;\n\t\t}\n\t }\n\n\t return -1;\n\t};\n}\n\n// Object create\nif (typeof Object.create !== 'function') {\n\tObject.create = function (obj) {\n\t\tfunction F(){}\n\t\tF.prototype = obj;\n\t\treturn new F();\n\t};\n}\n\n// Init Abdata and actionbox jQuery plugins\n$(document).ready(function() {\n\n\t// Enable popup actionboxes\n\t$.fn.ab = $.fn.actionbox = function(options){\n\t\tif (this.length > 0) {\n\t\t\tif(Actionbox[options] && $(this).data('actionbox')){\n\t\t\t\t// TODO: support legacy code $('#abox-home-boxes').ab('updatePrice');\n\t\t\t\t$(this).data('actionbox')[options].apply($(this).data('actionbox'));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(typeof options === 'object' || !options){\n\t\t\t\treturn this.each(function(){\n\t\t\t\t\tvar actionbox = Object.create(Actionbox);\n\t\t\t\t\tactionbox.init(options, this);\n\n\t\t\t\t\t$.data(this, 'actionbox', actionbox);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\n\t// Load price data plugin\n\t$.fn.abdata = function(options){\n\t\tif (this.length > 0) {\n\t\t\treturn this.each(function(){\n\t\t\t\tvar abdata = Object.create(Abdata);\n\t\t\t\tabdata.init(options);\n\n\t\t\t\t$.data(this, 'abdata', abdata);\n\t\t\t});\n\t\t}\n\t};\n\n\n\t// Init actionbox\n\t// Call directly on actionbox wrapper -> $('#abox-home-boxes-v10').actionbox() and find #main internally.\n\t// Actually do not rely on #main, but look for the first element with data-internalid attribute set.\n\t// Sken not only childs but also root element itself for data-internalid attribute.\n\tvar abconfig = {};\n\n\tif(locale === 'pt-br'){\n\t\tabconfig.installments = 3;\n\t}\n\n\tif($('#abox-home-color-v10').length > 0){\n\t\tabconfig.priceyTypo = true;\n\t}\n\n\tif($('#abox-home-color-v10 [data-pricing=\"monthly\"]').length > 0){\n\t\tabconfig.priceyTypo = true;\n\t\tabconfig.pricing = 'monthly';\n\t\tabconfig.customId = 'PPMONTH';\n\t}\n\n\t// Init actionboxes\n\t// Standard actionbox\n\t$('#abox-home-boxes-v10').actionbox(abconfig);\n\n\t// actionbox 2015\n\t$('#abox-home-color-v10').actionbox(abconfig);\n});\n\n/**\n * PRODUCT HOME COMMON\n */\n\n // Top height\nfunction detectInitScreen(){\n\tvar scrn = (window.getComputedStyle) ? window.getComputedStyle(document.body,':after').getPropertyValue('content') : '';\n\treturn scrn;\n}\nfunction setStickyHeight() {\n\tvar screenSize = detectInitScreen();\n\tvar stickyHeight = 72;\n\tif (screenSize == 'mobile'){\n\t\tstickyHeight = 0;\n\t}\n\tif (screenSize == 'tablet') {\n\t\tstickyHeight = 0;\n\t}\n\treturn stickyHeight;\n}\n\n$(document).ready(function() {\n\tvar osVer = sysReqOsVer();\n\n\tif(!osVer){\n\t\t$('#sysreq .supported').hide();\n\t\t$('#sysreq .not-supported').show();\n\t}\n\t// toggle sysreq\n\t$('.sysreq-toggle-link').on('click', function(e){\n\t\te.preventDefault();\n\t\tvar sysreq = $('#sysreq');\n\t\tvar sh = sysreq.outerHeight();\n\t\tvar h = sh - $('#sysreq .supported').outerHeight() + $('#sysreq .not-supported').height();\n\n\t\tsysreq.css({'min-height' : sh + 'px'});\n\t\tsysreq.animate({'min-height' : h}, 200);\n\t\t$('#sysreq .supported').fadeOut(300, function(){\n\t\t\t$('#sysreq .not-supported').fadeIn(300);\n\t\t});\n\t});\n\n\tif(osVer){\n\t\t$('#sysreq .sysreq-os-ver').text(osVer);\n\t}\n});\n\n\nfunction sysReqOsVer(){\n\tvar ua = navigator.userAgent.toLowerCase();\n\tvar supportedVersions = ['XP', 'Vista', '7', '8', '10'];\n\tvar version;\n\tvar detect = avastGlobals.detect;\n\n\tif(typeof detect === 'object' && detect.os.isWindows){\n\t\tfor(var i = 0; supportedVersions.length > i; i++){\n\t\t\tif(detect.os.version === supportedVersions[i]){\n\t\t\t\tversion = detect.os.name + ' ' + detect.os.version;\n\t\t\t}\n\t\t}\n\t}\n\n\tif(ua.indexOf(' arm;') > -1){\n\t\treturn false;\n\t}\n\n\treturn version;\n}\n"]}