{"version":3,"sources":["webpack:///./ui/js/modules/fancybox.js","webpack:///./ui/js/vendor/angular-chosen.js","webpack:///./ui/js/vendor/angular-masonry.js","webpack:///./ui/js/vendor/angular-vertilize.js","webpack:///./ui/js/controllers/blogController.js","webpack:///./ui/js/controllers/faqsController.js","webpack:///./ui/js/controllers/insightsController.js","webpack:///./ui/js/controllers/productComparisonController.js","webpack:///./ui/js/controllers/productListController.js","webpack:///./ui/js/controllers/supportController.js","webpack:///./ui/js/controllers/videoListController.js","webpack:///./ui/js/controllers/index.js","webpack:///./ui/js/cordless/cordless.factory.js","webpack:///./ui/js/cordless/applicator-list/applicator-list.controller.js","webpack:///./ui/js/cordless/product-list/product-list.controller.js","webpack:///./ui/js/cordless/isotope-items-list/isotope-items-list.controller.js","webpack:///./ui/js/cordless/index.js","webpack:///./ui/js/cordless/applicator-list/position-tooltip.directive.js","webpack:///./ui/js/directives/categorySeo.js","webpack:///./ui/js/directives/filterExpand.js","webpack:///./ui/js/directives/gridSize.js","webpack:///./ui/js/directives/productList.js","webpack:///./ui/js/directives/productItem.js","webpack:///./ui/js/directives/scrollMagic.js","webpack:///./ui/js/directives/index.js","webpack:///./ui/js/directives/fancyBox.js","webpack:///./ui/js/directives/isotopeGrid.js","webpack:///./ui/js/directives/scrollBar.js","webpack:///./ui/js/filters/index.js","webpack:///./ui/js/filters/categoryFilter.js","webpack:///./ui/js/filters/productTabsCategoryFilter.js","webpack:///./ui/js/localisation/localisation.factory.js","webpack:///./ui/js/localisation/index.js","webpack:///./ui/js/routes/blog.js","webpack:///./ui/js/routes/faqList.js","webpack:///./ui/js/routes/insightsList.js","webpack:///./ui/js/routes/productList.js","webpack:///./ui/js/routes/supportArticlesList.js","webpack:///./ui/js/routes/videoList.js","webpack:///./ui/js/routes/index.js","webpack:///./ui/js/services/blogFactory.js","webpack:///./ui/js/services/categoryFactory.js","webpack:///./ui/js/services/faqsFactory.js","webpack:///./ui/js/services/insightsFactory.js","webpack:///./ui/js/services/loadingBar.js","webpack:///./ui/js/services/productComparisonFactory.js","webpack:///./ui/js/services/productListFactory.js","webpack:///./ui/js/services/storageFactory.js","webpack:///./ui/js/services/supportFactory.js","webpack:///./ui/js/services/videoListFactory.js","webpack:///./ui/js/services/index.js","webpack:///./ui/js/wtt/wtt-root/controller.js","webpack:///./ui/js/wtt/wtt-root/index.js","webpack:///./ui/js/wtt/wtt-intro/controller.js","webpack:///./ui/js/wtt/wtt-intro/index.js","webpack:///./ui/js/wtt/wtt-game/controller.js","webpack:///./ui/js/wtt/wtt-game/index.js","webpack:///./ui/js/wtt/wtt-submission/controller.js","webpack:///./ui/js/wtt/wtt-submission/index.js","webpack:///./ui/js/wtt/wtt-confirmation/index.js","webpack:///./ui/js/wtt/wtt-more/controller.js","webpack:///./ui/js/wtt/wtt-more/index.js","webpack:///./ui/js/wtt/wtt-form/index.js","webpack:///./ui/js/wtt/wtt-image-grid/controller.js","webpack:///./ui/js/wtt/wtt-image-grid/index.js","webpack:///./ui/js/wtt/wtt-dynamic-form-control/controller.js","webpack:///./ui/js/wtt/wtt-dynamic-form-control/index.js","webpack:///./ui/js/wtt/wtt.service.js","webpack:///./ui/js/wtt/index.js","webpack:///./ui/js/app.js","webpack:///./ui/js/directives/categorySeo.html","webpack:///./ui/js/wtt/wtt-root/template.html","webpack:///./ui/js/wtt/wtt-intro/template.html","webpack:///./ui/js/wtt/wtt-game/template.html","webpack:///./ui/js/wtt/wtt-submission/template.html","webpack:///./ui/js/wtt/wtt-confirmation/template.html","webpack:///./ui/js/wtt/wtt-more/template.html","webpack:///./ui/js/wtt/wtt-form/template.html","webpack:///./ui/js/wtt/wtt-image-grid/template.html","webpack:///./ui/js/wtt/wtt-dynamic-form-control/template.html"],"names":["$fancyboxLinks","$","$fancyboxVideoLinks","$inlineModals","self","initialise","length","applyFancyBox","applyFancyBoxVideo","applyFancyBoxInline","fancybox","width","height","padding","scrolling","addClass","autoSize","beforeShow","css","maxWidth","maxHeight","closeBtn","openEffect","closeEffect","margin","afterShow","$elem","helpers","media","modalId","attr","sessionKey","sessionStorage","getItem","beforeClose","setItem","e","type","aspectRatio","autoPlayVideo","hash","vars","hashes","window","location","href","slice","indexOf","split","i","push","undefined","playVideo","hasClass","click","Sys","WebForms","PageRequestManager","getInstance","add_endRequest","__indexOf","item","l","this","angular","module","directive","$timeout","CHOSEN_OPTION_WHITELIST","NG_OPTIONS_REGEXP","chosen","snakeCase","input","replace","$1","toLowerCase","value","key","_i","_len","isArray","isObject","hasOwnProperty","restrict","require","link","scope","element","ngModel","match","options","valuesExpr","ngOptions","$eval","$watch","newVal","oldVal","trigger","forEach","call","removeClass","message","empty","append","val","$viewValue","controller","$scope","$element","bricks","schedule","destroyed","timeout","preserveOrder","loadImages","scheduleMasonryOnce","args","arguments","found","filter","scheduleMasonry","apply","cancel","masonry","reload","appendBrick","id","_append","Object","keys","defaultLoaded","_layout","imagesLoaded","removeBrick","destroy","data","$emit","pre","attrs","ctrl","attrOptions","masonryOptions","extend","itemSelector","columnWidth","parseInt","reloadOnShow","prop","isVisible","wasVisible","$on","index","$id","on","$index","$window","_this","childrenHeights","allocateMe","updateMyHeight","getTallestHeight","Math","max","bind","$apply","parent","myIndex","clone","removeAttr","outerWidth","position","top","left","visibility","after","realHeight","myNewHeight","tallestHeight","BlogController","$state","$stateParams","$filter","blogFactory","setFilteredItems","getFilteredItems","filters","then","filteredItems","setStateParameters","pagination","categoryState","categories","get","x","stateParameters","pageid","category","searchtext","search","go","current","name","inherit","notify","itemsPerPage","searchQuery","filterOpen","toggleFilter","pagesize","loadMore","preventDefault","showLoadMore","getCategoryNamesForRoute","Array","getPinterestUrl","blogPost","domain","hostname","url","Url","image","Image","description","Title","encodeURIComponent","getBlogPosts","blogPosts","getCategories","allCategories","flatten","includes","CategoryDisplayName","getCategoriesFromNames","newValue","oldValue","debounce","pagedItems","setItemClass","setItemClassTwoColumn","startsWith","actual","expected","FaqsController","$sce","faqsFactory","getPagedItems","selectCategory","selectedCategory","getSelectedCategory","runSearch","getCategoryHref","InsightsController","insightsFactory","loadingBar","videos","filterLoaded","loading","getLoadMoreUrl","params","addLoadingBar","setPagedItems","getAllCategories","ProductComparisonController","productComparisonFactory","compareShow","getCompareSettings","compareSettings","removeAllComparisons","ComparedProducts","removeComparison","product","IsCompared","compareChange","AgilityID","compareShowToggle","ProductListController","productFilters","routeProxy","productListFactory","selectedFilters","getProxyFilters","filterFunctionalityOverrides","redirecting","Name","powersource","productcode","batteries","unknown1","unknown2","unknown3","GroupedAll","groupedAll","loaded","getClearfixClasses","classArray","showBatteryFilter","selectedPowerSource","RegExp","join","test","getCategoryTypes","categoryTypes","categoryType","pathname","categoryTypeSelected","selectedType","hasBatteries","initialised","getFilters","SupportController","supportFactory","VideoListController","videoListFactory","resetPagedItems","addOffsetClasses","classes","isAutoPlayable","$http","$q","applicators","getApplicators","deferred","defer","response","resolve","reject","promise","getApplicatorProducts","applicator","minRange","maxRange","getIsotopeItems","path","vm","applicatorGroups","showTooltip","tooltipActive","hideTooltip","getCssClass","DesktopWidth","productList","cordlessFactory","hideApplicatorProducts","sliderOptions","showTicks","floor","RangeMin","ceil","RangeMax","step","hideLimitLabels","onlyBindHandles","translate","RangeUnits","selectedApplicator","slider","minValue","min","maxValue","group","Applicators","j","activate","IsotopeItemsListController","isotopeItems","Products","configureModule","$stateProvider","$urlRouterProvider","state","abstract","views","controllerAs","templateUrl","otherwise","ApplicatorListController","ApplicatorProductListController","ApplicatorIsotopeItemsListController","factory","$link","siblings","pointPos","offset","windowHalfWidth","innerWidth","windowHalfHeight","innerHeight","config","CategorySeoController","$attrs","$location","$transclude","categoryFactory","originalDescriptionHtml","originalTitle","title","originalImageSrc","imageSrc","html","updateCategoryInformation","getCategorySeo","currentCategorySeo","categoryDescription","bannerImage","canonicalLink","protocol","host","slideDuration","delayInterval","slideToggleGroup","$toggle","always","forceOpen","$group","closest","startedOpened","toggleOptions","duration","slideStep","done","delay","childCount","children","setTimeout","slideToggle","now","tween","elem","pagedItemsResult","products","allProducts","navigator","userAgent","viewAll","categoryList","hideReviews","hideCompare","hideApplicationShot","showProductCount","showingCount","totalCount","agilityIds","ignoreUrl","getProducts","prototype","Category","sortBy","uniq","ProductItemController","agilityId","formatImageUrl","baseImageUrl","resizeWidth","getArray","items","$lng","logCompare","comparedAgilityIds","splice","showCompareBox","MaximumComparable","numberOfStars","filledStars","DocumentRatingValue","DocumentRatings","round","newComparedIds","p","appSettings","ScrollMagic","Controller","localOptions","triggerElement","scene","Scene","addTo","enter","end","leave","start","debugMode","addIndicators","bindToController","$keywords","$description","$canonical","hasOriginalSeoKeywords","hasOriginalSeoDescription","hasOriginalCanonicalLink","originalSeoTitle","document","originalSeoKeywords","originalSeoDescription","originalCanonicalLink","newSeoTitle","newSeoKeywords","newSeoDescription","newCanonicalLink","removeOrAddTag","$tag","hasOriginalTag","originalContent","newContent","defaultTag","remove","seoTitle","seoKeywords","seoDescription","transclude","template","attributes","ngHref","applyFancybox","$groups","find","checkLoaded","each","stopPropagation","$this","currentTarget","$notClicked","not","setGridWidth","colWidth","gridColWidth","girdWidth","colAmount","resize","layoutMode","fitWidth","isotope","isotopeReloadEvent","mCustomScrollbar","alwaysShowScrollbar","scrollMagic","selectedCategoryNames","n","currentCategoryNames","Categories","every","catName","KenticoLocalisationFactory","cultureCode","Storage","Promise","json","localisations","JSON","parse","getStorage","defaultCulture","res","stringify","setStorage","localisationFactory","$translateProvider","getElementById","preferredLanguage","useSanitizeValueStrategy","useLoaderCache","useLoader","$locationProvider","$cordlessList","$productList","$productCodeFilter","getRouteProxy","$videoList","$videoFilters","blogRoute","faqListRoute","insightsListRoute","productListRoute","supportArticlesListRoute","videoListRoute","err","loadSinglePage","searchText","searchIndex","storageFactory","categoryName","categorySeoList","sessionSeoList","getSessionItem","setSessionItem","FaqsFactory","getAllFaqsDefer","getAllCategoriesDefer","allFaqs","getAllFaqs","searchFaqs","faq","NodeParentId","NodeId","getAllInsightsDefer","allInsights","getInsights","insight","HasVideo","LoadingBar","cfpLoadingBar","complete","deffered","ProductListFactory","deferredCategoryTypes","filterProducts","fieldName","filterName","f","toUpperCase","some","pageUrl","proxyFilters","additionalFilters","getAdditionalFilters","groupedFilters","getGroupedFilters","overrides","post","filterParams","selected","searchCode","sessionList","productCode","selectedValue","ignoreAll","hiddenFilters","status","NumberOfBatteries","localStorage","getAllArticlesDefer","allArticles","getAllArticles","article","getVideosDefer","getVideos","culture","WTTRootController","$log","$rootScope","$translate","WTTService","wttService","visible","isReady","onReady","$initialData","initialData","setFormData","error","wttIntroController","formData","WTTGameController","tileCount","tileLimit","$event","target","form","$invalid","$setSubmitted","setSubmission","noop","termsToShow","termsToHide","WTTSubmissionController","WTTMoreController","questionIndex","answerIndex","answers","dynamicFormQuestions","isAnswered","setFinalStepData","bindings","onSubmit","onTermsClick","onTermsHideClick","WTTImageGridController","tileWidth","horizontal","tileHeight","vertical","dividers","generateDividers","tiles","generateTiles","xPos","x1","x2","y1","y2","y","yPos","xPercent","yPercent","widthPercent","heightPercent","onTileSelect","src","wttDynamicFormControl","question","answer","setQuestionAnswer","info","component","wttRoot","wttIntro","wttGame","wttSubmission","wttConfirmation","wttMore","wttForm","wttImageGrid","service","WebFont","load","custom","families","urls","main","$compileProvider","$httpProvider","debugInfoEnabled","process","useApplyAsync","html5Mode","hashPrefix","runModule","ControllersModule","DirectivesModule","FiltersModule","LocalisationModule","RoutesModule","ServicesModule","CordlessModule","WTTModule","run","constant","deferredBootstrapper","bootstrap","body","exports"],"mappings":"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","file":"36-e85da6dfbc0931a27046.js","sourcesContent":["import 'fancybox-core';\r\nimport 'fancybox-media';\r\n\r\n/* eslint-disable max-len */\r\nconst $fancyboxLinks = $('.fancybox-media, .reviewLink');\r\nconst $fancyboxVideoLinks = $(\r\n '.video-media, .js-video-thumbnail, a[href*=\"youtube.com/watch?\"], a[href*=\"youtube.com/v/?\"]',\r\n);\r\nconst $inlineModals = $('.js-modal-inline');\r\n/* eslint-enable max-len */\r\n\r\nconst self = {\r\n initialise: () => {\r\n if ($fancyboxLinks.length) {\r\n self.applyFancyBox(self.$fancyboxLinks);\r\n }\r\n\r\n if ($fancyboxVideoLinks.length) {\r\n self.applyFancyBoxVideo($fancyboxVideoLinks);\r\n }\r\n\r\n if ($inlineModals.length) {\r\n self.applyFancyBoxInline($inlineModals);\r\n }\r\n\r\n $('.productBtn').fancybox({\r\n width: '365',\r\n height: '275',\r\n padding: '20',\r\n scrolling: 'no',\r\n });\r\n\r\n // fancybox\r\n $('a[href*=\"youtube.com/watch?\"]').addClass('fancybox-media');\r\n $('a[href*=\"vimeo\"]').addClass('fancybox-media');\r\n\r\n self.applyFancyBox($('.fancybox-media'));\r\n\r\n $('.reviewLink').fancybox({\r\n width: '50%',\r\n autoSize: false,\r\n });\r\n\r\n // project centre share popup\r\n $('.projectTopBanner .shareButton').fancybox({\r\n beforeShow() {\r\n $('.fancybox-skin').css('backgroundColor', 'transparent');\r\n },\r\n maxWidth: 800,\r\n maxHeight: 800,\r\n width: '50%',\r\n height: '50%',\r\n closeBtn: true,\r\n openEffect: 'none',\r\n closeEffect: 'none',\r\n margin: 0,\r\n padding: 0,\r\n afterShow() {\r\n $('.fancybox-inner').css('overflow', 'inherit');\r\n },\r\n });\r\n },\r\n applyFancyBox: $elem => {\r\n if ($elem) {\r\n $elem.fancybox({\r\n closeBtn: true,\r\n helpers: {\r\n media: {},\r\n },\r\n });\r\n }\r\n },\r\n applyFancyBoxInline: $elem => {\r\n if (!$elem) {\r\n return;\r\n }\r\n\r\n const modalId = $elem.attr('id');\r\n const sessionKey = `modal-disabled-${modalId}`;\r\n\r\n try {\r\n const disableModel = sessionStorage.getItem(sessionKey, true);\r\n\r\n if (disableModel) {\r\n return;\r\n }\r\n\r\n $.fancybox(`#${modalId}`, {\r\n padding: 0,\r\n beforeClose: () => {\r\n try {\r\n sessionStorage.setItem(sessionKey, true);\r\n } catch (e) {\r\n // ignore\r\n }\r\n },\r\n });\r\n } catch (e) {\r\n // ignore\r\n }\r\n },\r\n applyFancyBoxVideo: $elem => {\r\n if ($elem) {\r\n $elem.fancybox({\r\n openEffect: 'none',\r\n closeEffect: 'none',\r\n type: 'iframe',\r\n closeBtn: true,\r\n width: 1920,\r\n height: 1080,\r\n aspectRatio: true,\r\n padding: 0,\r\n });\r\n }\r\n },\r\n /** Check if the query string contains playVideo, if so autoplay the video. */\r\n autoPlayVideo: $elem => {\r\n const vars = [];\r\n let hash;\r\n const hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');\r\n\r\n for (let i = 0; i < hashes.length; i += 1) {\r\n hash = hashes[i].split('=');\r\n vars.push(hash[0]);\r\n vars[hash[0]] = hash[1];\r\n }\r\n\r\n if (vars.playVideo !== undefined && $elem.hasClass('js-autoplayable')) {\r\n $elem.click();\r\n }\r\n },\r\n};\r\n\r\nself.initialise();\r\n\r\nif (window.Sys) {\r\n Sys.WebForms.PageRequestManager.getInstance().add_endRequest(self.initialise);\r\n}\r\n\r\nexport default self;\r\n","// Generated by CoffeeScript 1.6.2\r\n(function () {\r\n var __indexOf = [].indexOf || function (item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };\r\n\r\n angular.module('angular-chosen', []);\r\n\r\n angular.module('angular-chosen').directive('chosen', [\r\n '$timeout', function ($timeout) {\r\n var CHOSEN_OPTION_WHITELIST, NG_OPTIONS_REGEXP, chosen, isEmpty, snakeCase;\r\n\r\n NG_OPTIONS_REGEXP = /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w\\d]*)|(?:\\(\\s*([\\$\\w][\\$\\w\\d]*)\\s*,\\s*([\\$\\w][\\$\\w\\d]*)\\s*\\)))\\s+in\\s+(.*)$/;\r\n CHOSEN_OPTION_WHITELIST = ['noResultsText', 'allowSingleDeselect', 'disableSearchThreshold', 'disableSearch'];\r\n snakeCase = function (input) {\r\n return input.replace(/[A-Z]/g, function ($1) {\r\n return \"_\" + ($1.toLowerCase());\r\n });\r\n };\r\n isEmpty = function (value) {\r\n var key, _i, _len;\r\n\r\n if (angular.isArray(value)) {\r\n return value.length === 0;\r\n } else if (angular.isObject(value)) {\r\n for (_i = 0, _len = value.length; _i < _len; _i++) {\r\n key = value[_i];\r\n if (value.hasOwnProperty(key)) {\r\n return false;\r\n }\r\n }\r\n }\r\n return true;\r\n };\r\n return chosen = {\r\n restrict: 'A',\r\n require: '?ngModel',\r\n link: function (scope, element, attr, ngModel) {\r\n var disableWithMessage, match, options, startLoading, stopLoading, valuesExpr;\r\n\r\n /*\r\n * Start of edit to allow chosen list to update when options change\r\n * Originally from: https://github.com/iiome/angular-chosen\r\n */\r\n if (attr.ngOptions) {\r\n match = attr.ngOptions.match(NG_OPTIONS_REGEXP);\r\n valuesExpr = match[2];\r\n\r\n if (!valuesExpr)\r\n valuesExpr = match[7];\r\n\r\n var v = scope.$eval(valuesExpr);\r\n scope.$watch(valuesExpr, function (newVal, oldVal) {\r\n $timeout(function () {\r\n if (newVal !== oldVal) {\r\n element.trigger(\"liszt:updated\");\r\n }\r\n });\r\n });\r\n }\r\n /*\r\n * End of edit to allow chosen list to update when options change\r\n */\r\n\r\n options = scope.$eval(attr.chosen) || {};\r\n angular.forEach(attr, function (value, key) {\r\n if (__indexOf.call(CHOSEN_OPTION_WHITELIST, key) >= 0) {\r\n return options[snakeCase(key)] = scope.$eval(value);\r\n }\r\n });\r\n startLoading = function () {\r\n return element.addClass('loading').attr('disabled', true).trigger('liszt:updated');\r\n };\r\n stopLoading = function () {\r\n return element.removeClass('loading').attr('disabled', false).trigger('liszt:updated');\r\n };\r\n disableWithMessage = function (message) {\r\n return element.empty().append(\"\").attr('disabled', true).trigger('liszt:updated');\r\n };\r\n $timeout(function () {\r\n chosen = element.chosen(options);\r\n return element.val(ngModel == null ? '' : ngModel.$viewValue || '').trigger(\"liszt:updated\");\r\n });\r\n return chosen;\r\n ngModel.$render = function () {\r\n element.val(ngModel.$viewValue || '');\r\n return $timeout(function () {\r\n return element.trigger(\"liszt:updated\");\r\n });\r\n };\r\n if (attr.ngOptions) {\r\n match = attr.ngOptions.match(NG_OPTIONS_REGEXP);\r\n valuesExpr = match[7];\r\n if (angular.isUndefined(scope.$eval(valuesExpr))) {\r\n startLoading();\r\n }\r\n return scope.$watch(valuesExpr, function (newVal, oldVal) {\r\n if (newVal !== oldVal) {\r\n stopLoading();\r\n if (isEmpty(newVal)) {\r\n return disableWithMessage(options.no_results_text || 'No values available');\r\n }\r\n }\r\n });\r\n }\r\n }\r\n };\r\n }\r\n ]);\r\n\r\n}).call(this);\r\n","define(function (require) {\r\n require('angular');\r\n require('jquery');\r\n require('jquery-bridget');\r\n require('masonry-layout');\r\n\r\n /*!\r\n * angular-masonry 0.10.0\r\n * Pascal Hartig, weluse GmbH, http://weluse.de/\r\n * License: MIT\r\n */\r\n\r\n /*\r\n * https://github.com/passy/angular-masonry\r\n * NetC EDIT: The only thing different between this and the standard angular-masonry directive is I've added self.reload(); to scheduleMasonry\r\n * because items were sometimes incorrectly ordered after they'd been filtered. This appears to solve that.\r\n */\r\n (function () {\r\n 'use strict';\r\n angular.module('wu.masonry', []).controller('MasonryCtrl', [\r\n '$scope',\r\n '$element',\r\n '$timeout',\r\n function controller($scope, $element, $timeout) {\r\n var bricks = {};\r\n var schedule = [];\r\n var destroyed = false;\r\n var self = this;\r\n var timeout = null;\r\n this.preserveOrder = false;\r\n this.loadImages = true;\r\n this.scheduleMasonryOnce = function scheduleMasonryOnce() {\r\n var args = arguments;\r\n var found = schedule.filter(function filterFn(item) {\r\n return item[0] === args[0];\r\n }).length > 0;\r\n if (!found) {\r\n this.scheduleMasonry.apply(null, arguments);\r\n }\r\n };\r\n // Make sure it's only executed once within a reasonable time-frame in\r\n // case multiple elements are removed or added at once.\r\n this.scheduleMasonry = function scheduleMasonry() {\r\n if (timeout) {\r\n $timeout.cancel(timeout);\r\n }\r\n schedule.push([].slice.call(arguments));\r\n timeout = $timeout(function runMasonry() {\r\n if (destroyed) {\r\n return;\r\n }\r\n schedule.forEach(function scheduleForEach(args) {\r\n $element.masonry.apply($element, args);\r\n });\r\n\r\n self.reload();\r\n schedule = [];\r\n }, 30);\r\n };\r\n function defaultLoaded($element) {\r\n $element.addClass('loaded');\r\n }\r\n this.appendBrick = function appendBrick(element, id) {\r\n if (destroyed) {\r\n return;\r\n }\r\n function _append() {\r\n if (Object.keys(bricks).length === 0) {\r\n $element.masonry('resize');\r\n }\r\n if (bricks[id] === undefined) {\r\n // Keep track of added elements.\r\n bricks[id] = true;\r\n defaultLoaded(element);\r\n $element.masonry('appended', element, true);\r\n }\r\n }\r\n function _layout() {\r\n // I wanted to make this dynamic but ran into huuuge memory leaks\r\n // that I couldn't fix. If you know how to dynamically add a\r\n // callback so one could say \r\n // please submit a pull request!\r\n self.scheduleMasonryOnce('layout');\r\n }\r\n if (!self.loadImages) {\r\n _append();\r\n _layout();\r\n } else if (self.preserveOrder) {\r\n _append();\r\n element.imagesLoaded(_layout);\r\n } else {\r\n element.imagesLoaded(function imagesLoaded() {\r\n _append();\r\n _layout();\r\n });\r\n }\r\n };\r\n this.removeBrick = function removeBrick(id, element) {\r\n if (destroyed) {\r\n return;\r\n }\r\n delete bricks[id];\r\n $element.masonry('remove', element);\r\n this.scheduleMasonryOnce('layout');\r\n };\r\n this.destroy = function destroy() {\r\n destroyed = true;\r\n if ($element.data('masonry')) {\r\n // Gently uninitialize if still present\r\n $element.masonry('destroy');\r\n }\r\n $scope.$emit('masonry.destroyed');\r\n bricks = [];\r\n };\r\n this.reload = function reload() {\r\n $element.masonry();\r\n $scope.$emit('masonry.reloaded');\r\n };\r\n }\r\n ]).directive('masonry', function masonryDirective() {\r\n return {\r\n restrict: 'AE',\r\n controller: 'MasonryCtrl',\r\n link: {\r\n pre: function preLink(scope, element, attrs, ctrl) {\r\n var attrOptions = scope.$eval(attrs.masonry || attrs.masonryOptions);\r\n var options = angular.extend({\r\n itemSelector: attrs.itemSelector || '.masonry-brick',\r\n columnWidth: parseInt(attrs.columnWidth, 10) || attrs.columnWidth\r\n }, attrOptions || {});\r\n element.masonry(options);\r\n var loadImages = scope.$eval(attrs.loadImages);\r\n ctrl.loadImages = loadImages !== false;\r\n var preserveOrder = scope.$eval(attrs.preserveOrder);\r\n ctrl.preserveOrder = preserveOrder !== false && attrs.preserveOrder !== undefined;\r\n var reloadOnShow = scope.$eval(attrs.reloadOnShow);\r\n if (reloadOnShow !== false && attrs.reloadOnShow !== undefined) {\r\n scope.$watch(function () {\r\n return element.prop('offsetParent');\r\n }, function (isVisible, wasVisible) {\r\n if (isVisible && !wasVisible) {\r\n ctrl.reload();\r\n }\r\n });\r\n }\r\n scope.$emit('masonry.created', element);\r\n scope.$on('$destroy', ctrl.destroy);\r\n }\r\n }\r\n };\r\n }).directive('masonryBrick', function masonryBrickDirective() {\r\n return {\r\n restrict: 'AC',\r\n require: '^masonry',\r\n scope: true,\r\n link: {\r\n pre: function preLink(scope, element, attrs, ctrl) {\r\n var id = scope.$id, index;\r\n ctrl.appendBrick(element, id);\r\n element.on('$destroy', function () {\r\n ctrl.removeBrick(id, element);\r\n });\r\n scope.$on('masonry.reload', function () {\r\n ctrl.scheduleMasonryOnce('reloadItems');\r\n ctrl.scheduleMasonryOnce('layout');\r\n });\r\n scope.$watch('$index', function () {\r\n if (index !== undefined && index !== scope.$index) {\r\n ctrl.scheduleMasonryOnce('reloadItems');\r\n ctrl.scheduleMasonryOnce('layout');\r\n }\r\n index = scope.$index;\r\n });\r\n }\r\n }\r\n };\r\n });\r\n }());\r\n});\r\n","define(function (require) {\r\n 'use strict';\r\n\r\n var angular = require('angular');\r\n var $ = require('jquery');\r\n\r\n // Vertilize Container\r\n var VertilizeContainerDirective = function () {\r\n return {\r\n restrict: 'EA',\r\n controller: [\r\n '$scope', '$window',\r\n function ($scope, $window) {\r\n // Alias this\r\n var _this = this;\r\n\r\n // Array of children heights\r\n _this.childrenHeights = [];\r\n\r\n // API: Allocate child, return index for tracking.\r\n _this.allocateMe = function () {\r\n _this.childrenHeights.push(0);\r\n return (_this.childrenHeights.length - 1);\r\n };\r\n\r\n // API: Update a child's height\r\n _this.updateMyHeight = function (index, height) {\r\n _this.childrenHeights[index] = height;\r\n };\r\n\r\n // API: Get tallest height\r\n _this.getTallestHeight = function () {\r\n var height = 0;\r\n for (var i = 0; i < _this.childrenHeights.length; i = i + 1) {\r\n height = Math.max(height, _this.childrenHeights[i]);\r\n }\r\n return height;\r\n };\r\n\r\n // Add window resize to digest cycle\r\n angular.element($window).bind('resize', function () {\r\n return $scope.$apply();\r\n });\r\n }\r\n ]\r\n };\r\n };\r\n\r\n // Vertilize Item\r\n var VertilizeDirective = function () {\r\n return {\r\n restrict: 'EA',\r\n require: '^vertilizeContainer',\r\n link: function (scope, element, attrs, parent) {\r\n // My index allocation\r\n var myIndex = parent.allocateMe();\r\n\r\n // Get my real height by cloning so my height is not affected.\r\n var getMyRealHeight = function () {\r\n var clone = element.clone()\r\n .removeAttr('vertilize')\r\n .css({\r\n height: '',\r\n width: element.outerWidth(),\r\n position: 'fixed',\r\n top: 0,\r\n left: 0,\r\n visibility: 'hidden'\r\n });\r\n element.after(clone);\r\n var realHeight = clone.height();\r\n clone['remove']();\r\n return realHeight;\r\n };\r\n\r\n // Watch my height\r\n scope.$watch(getMyRealHeight, function (myNewHeight) {\r\n if (myNewHeight) {\r\n parent.updateMyHeight(myIndex, myNewHeight);\r\n }\r\n });\r\n\r\n // Watch for tallest height change\r\n scope.$watch(parent.getTallestHeight, function (tallestHeight) {\r\n if (tallestHeight) {\r\n element.css('height', tallestHeight);\r\n }\r\n });\r\n }\r\n };\r\n };\r\n\r\n /** Directives Module. */\r\n var module;\r\n\r\n try {\r\n module = angular.module('Ryobi.directives');\r\n } catch (e) {\r\n module = angular.module('Ryobi.directives', []);\r\n }\r\n\r\n module.directive('vertilizeContainer', VertilizeContainerDirective);\r\n module.directive('vertilize', VertilizeDirective);\r\n});\r\n","import debounce from 'lodash/debounce';\r\nimport filter from 'lodash/filter';\r\nimport flatten from 'lodash/flatten';\r\nimport get from 'lodash/get';\r\nimport includes from 'lodash/includes';\r\n\r\nconst BlogController = /* @ngInject */ (\r\n $scope,\r\n $state,\r\n $stateParams,\r\n $timeout,\r\n $filter,\r\n blogFactory,\r\n) => {\r\n // Specifies the number of items before the cycle repeats and we get to a big item again\r\n const itemCycle = 3;\r\n\r\n // Initialise the controller.\r\n initialise();\r\n\r\n function initialise() {\r\n /** Pagination options. */\r\n $scope.pagination = {\r\n pageid: $stateParams.pageid,\r\n itemsPerPage: 7,\r\n };\r\n\r\n /** Filter options. */\r\n $scope.filters = {\r\n searchQuery: $stateParams.search,\r\n };\r\n\r\n // States if the filter is showing or not\r\n $scope.filterOpen = false;\r\n\r\n // Toggles the filter open constiable\r\n $scope.toggleFilter = () => {\r\n $scope.filterOpen = !$scope.filterOpen;\r\n };\r\n\r\n // Keeping the search text outside of the filters because it's just used for the textbox.\r\n // The search query, which we're debouncing is used for the filtering\r\n $scope.searchtext = $scope.filters.searchQuery;\r\n\r\n $scope.pagination.pagesize = () => $scope.pagination.itemsPerPage * $scope.pagination.pageid;\r\n\r\n /** Load the next page. */\r\n $scope.loadMore = e => {\r\n if (e) e.preventDefault();\r\n\r\n // If there are still items to show then increment page count.\r\n if ($scope.showLoadMore()) {\r\n $scope.pagination.pageid += 1;\r\n }\r\n };\r\n\r\n /** Get an array of category names from objects, to be used in routing. */\r\n $scope.getCategoryNamesForRoute = categories => {\r\n if (typeof categories === 'object') {\r\n categories = get(categories, 'CategoryDisplayName');\r\n }\r\n\r\n if (typeof categories === 'string') {\r\n categories = new Array(categories);\r\n }\r\n\r\n return categories;\r\n };\r\n\r\n $scope.getPinterestUrl = blogPost => {\r\n const domain = `http://${location.hostname}`;\r\n const url = domain + blogPost.Url;\r\n const image = domain + blogPost.Image;\r\n const description = blogPost.Title;\r\n\r\n // eslint-disable-next-line max-len\r\n return `//www.pinterest.com/pin/create/button/?url=${encodeURIComponent(\r\n url,\r\n )}&media=${encodeURIComponent(image)}&description=${encodeURIComponent(description)}`;\r\n };\r\n\r\n // Get blog post items.\r\n blogFactory.getBlogPosts().then(data => {\r\n // Filter them based on the node alias path\r\n $scope.blogPosts = data;\r\n });\r\n\r\n // Get categories.\r\n blogFactory.getCategories().then(data => {\r\n $scope.allCategories = data;\r\n\r\n $scope.filters.categories = $stateParams.category\r\n ? getCategoriesFromNames($stateParams.category)\r\n : [];\r\n\r\n // Filter items on first load\r\n setFilteredItems();\r\n\r\n // Setting the watches after we have the categories so that they're\r\n // not fired again when we set the filtered categories above\r\n $scope.$watch(\r\n 'filters',\r\n (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n $scope.pagination.pageid = 1;\r\n setStateParameters();\r\n setFilteredItems();\r\n }\r\n },\r\n true,\r\n );\r\n\r\n $scope.$watch(\r\n 'pagination',\r\n (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n setStateParameters();\r\n setFilteredItems();\r\n }\r\n },\r\n true,\r\n );\r\n\r\n $scope.$watch(\r\n 'searchtext',\r\n debounce((newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n // Set the search query and because it's in the filter object,\r\n // the filters watch will fire\r\n $scope.pagination.pageid = 1;\r\n $scope.filters.searchQuery = newValue;\r\n $scope.$apply();\r\n }\r\n }, 500),\r\n );\r\n\r\n $scope.$watch('searchtext', (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n setStateParameters();\r\n }\r\n });\r\n });\r\n }\r\n\r\n function setFilteredItems() {\r\n blogFactory.getFilteredItems($scope.filters).then(data => {\r\n $scope.filteredItems = data;\r\n });\r\n }\r\n\r\n /**\r\n * Gets the categories by category name.\r\n * @private\r\n */\r\n function getCategoriesFromNames(categories) {\r\n if (typeof categories === 'string') {\r\n categories = new Array(categories);\r\n }\r\n\r\n // Get all categories from all parents\r\n const allCategories = flatten(get($scope.allCategories, 'Categories'));\r\n const categoryObjects = filter(allCategories, item =>\r\n includes(categories, item.CategoryDisplayName),\r\n );\r\n\r\n return categoryObjects;\r\n }\r\n\r\n $scope.pagedItems = () =>\r\n $filter('limitTo')($scope.filteredItems, $scope.pagination.pagesize(), 0);\r\n\r\n $scope.showLoadMore = () => {\r\n if ($scope.filteredItems && $scope.pagination.pagesize() < $scope.filteredItems.length) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n $scope.setItemClass = $index => {\r\n const mod = $index % itemCycle;\r\n switch (mod) {\r\n case 0:\r\n return 'full-tile';\r\n\r\n case 1:\r\n return 'left-tile';\r\n\r\n case 2:\r\n return 'right-tile';\r\n\r\n default:\r\n return null;\r\n }\r\n };\r\n\r\n $scope.setItemClassTwoColumn = $index => {\r\n const mod = $index % 2;\r\n switch (mod) {\r\n case 0:\r\n return 'left-tile';\r\n\r\n case 1:\r\n return 'right-tile';\r\n\r\n default:\r\n return null;\r\n }\r\n };\r\n\r\n $scope.startsWith = (actual, expected) => {\r\n const lowerStr = actual.toLowerCase();\r\n return lowerStr.indexOf(expected.toLowerCase()) === 0;\r\n };\r\n\r\n /**\r\n * Sets the state parameters based on the pagination and filter objects.\r\n * @private\r\n */\r\n function setStateParameters() {\r\n const pagination = $scope.pagination;\r\n const filters = $scope.filters;\r\n\r\n let categoryState =\r\n filters && filters.categories ? get(filters.categories, 'CategoryDisplayName') : null;\r\n\r\n if (categoryState) {\r\n categoryState = filter(categoryState, x => x);\r\n }\r\n\r\n if (categoryState != null && categoryState.length === 0) {\r\n categoryState = null;\r\n }\r\n\r\n const stateParameters = {\r\n pageid: pagination.pageid,\r\n };\r\n\r\n if (categoryState) {\r\n stateParameters.category = categoryState;\r\n }\r\n\r\n if ($scope.searchtext && $scope.searchtext.length) {\r\n stateParameters.search = $scope.searchtext;\r\n }\r\n\r\n $state.go($state.current.name, stateParameters, {\r\n location: 'replace',\r\n inherit: false,\r\n notify: false,\r\n });\r\n }\r\n};\r\n\r\nexport default BlogController;\r\n","import debounce from 'lodash/debounce';\r\n\r\nconst FaqsController = /* @ngInject */ (\r\n $scope,\r\n $state,\r\n $stateParams,\r\n $timeout,\r\n $filter,\r\n $sce,\r\n faqsFactory,\r\n) => {\r\n $scope.searchtext = faqsFactory.filters.searchQuery;\r\n\r\n initialise();\r\n\r\n function initialise() {\r\n $scope.allCategories = [];\r\n\r\n $scope.getPagedItems = () => faqsFactory.filteredItems;\r\n\r\n $scope.getCategories = () => faqsFactory.allCategories;\r\n\r\n $scope.selectCategory = (e, category) => {\r\n if (e) e.preventDefault();\r\n\r\n faqsFactory.filters.selectedCategory = category;\r\n faqsFactory.getFilteredItems();\r\n };\r\n\r\n $scope.getSelectedCategory = () => faqsFactory.filters.selectedCategory;\r\n\r\n $scope.runSearch = (e) => {\r\n if (e) e.preventDefault();\r\n faqsFactory.filters.searchQuery = $scope.searchtext;\r\n faqsFactory.getFilteredItems();\r\n };\r\n\r\n $scope.getCategoryHref = (category) => {\r\n const stateParameters = {};\r\n\r\n if (category) {\r\n stateParameters.category = category.Title;\r\n }\r\n\r\n return $state.href($state.current.name, stateParameters);\r\n };\r\n\r\n $scope.$watch('searchtext', debounce((newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n // Set the search query and because it's in the filter object, the filters watch will fire\r\n faqsFactory.filters.searchQuery = newValue;\r\n faqsFactory.getFilteredItems();\r\n }\r\n }, 500));\r\n }\r\n};\r\n\r\nexport default FaqsController;\r\n","import filter from 'lodash/filter';\r\nimport flatten from 'lodash/flatten';\r\nimport get from 'lodash/get';\r\nimport includes from 'lodash/includes';\r\n\r\nconst InsightsController = /* @ngInject */ (\r\n $scope,\r\n $state,\r\n $stateParams,\r\n $timeout,\r\n $filter,\r\n insightsFactory,\r\n loadingBar,\r\n) => {\r\n initialise();\r\n\r\n insightsFactory.setFilteredItems().then(() => {\r\n $scope.loading = false;\r\n });\r\n\r\n insightsFactory.getAllCategories().then(() => {\r\n $scope.filters.categories = $stateParams.category ?\r\n getCategoriesFromNames($stateParams.category) :\r\n [];\r\n });\r\n\r\n function initialise() {\r\n /** Filter options. */\r\n $scope.filters = {\r\n categories: [],\r\n };\r\n\r\n $scope.filterLoaded = false;\r\n\r\n $scope.loading = true;\r\n\r\n $scope.getPagedItems = () => insightsFactory.pagedItems;\r\n\r\n $scope.showLoadMore = () => {\r\n if ($scope.loading) { return false; }\r\n\r\n if ($scope.getPagedItems().length > 0 &&\r\n insightsFactory.pagesize() < insightsFactory.filteredItems.length) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n /** Load the next page. */\r\n $scope.loadMore = (e) => {\r\n if (e) e.preventDefault();\r\n\r\n // If there are still items to show then increment page count.\r\n if ($scope.showLoadMore()) { insightsFactory.pagination.pageid += 1; }\r\n };\r\n\r\n /** Gets the URL for the next page. */\r\n $scope.getLoadMoreUrl = () => {\r\n const params = {};\r\n params.pageid = insightsFactory.pagination.pageid + 1;\r\n\r\n if (insightsFactory.filters) {\r\n let categories = insightsFactory.filters.categories;\r\n\r\n if (typeof categories === 'object') {\r\n categories = get(categories, 'CategoryDisplayName');\r\n }\r\n\r\n if (typeof categories === 'string') {\r\n categories = new Array(categories);\r\n }\r\n\r\n // Filter out any null values\r\n categories = filter(categories, x => x);\r\n\r\n if (categories.length > 0) {\r\n params.category = categories;\r\n }\r\n }\r\n\r\n return $state.href('insightsList', params);\r\n };\r\n\r\n $scope.getCategories = () => {\r\n if (insightsFactory.allCategories.length > 0) {\r\n $scope.filterLoaded = true;\r\n }\r\n\r\n return insightsFactory.allCategories;\r\n };\r\n\r\n insightsFactory.pagination.pageid = $stateParams.pageid;\r\n\r\n $scope.$watch(() => insightsFactory.pagination,\r\n (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n // Add a loading bar to make it appear that something's happened\r\n loadingBar.addLoadingBar();\r\n\r\n insightsFactory.setPagedItems();\r\n setStateParameters();\r\n }\r\n }, true);\r\n\r\n $scope.$watch('filters', (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n // Add a loading bar to make it appear that something's happened\r\n loadingBar.addLoadingBar();\r\n\r\n insightsFactory.pagination.pageid = 1;\r\n\r\n insightsFactory.filters = newValue;\r\n\r\n insightsFactory.setFilteredItems();\r\n setStateParameters();\r\n }\r\n }, true);\r\n }\r\n\r\n /**\r\n * Sets the state parameters based on the pagination and filter objects.\r\n * @private\r\n */\r\n function setStateParameters() {\r\n const stateParameters = {\r\n pageid: insightsFactory.pagination.pageid,\r\n };\r\n\r\n const filters = insightsFactory.filters;\r\n\r\n if (filters) {\r\n let categoryState = (filters.categories) ?\r\n get(filters.categories, 'CategoryDisplayName') :\r\n null;\r\n if (categoryState) {\r\n categoryState = filter(categoryState, x => x);\r\n }\r\n\r\n if (categoryState != null && categoryState.length > 0) {\r\n stateParameters.category = categoryState;\r\n }\r\n\r\n if (filters.videos) {\r\n stateParameters.videos = true;\r\n }\r\n }\r\n\r\n $state.go($state.current.name, stateParameters, {\r\n location: 'replace',\r\n inherit: false,\r\n notify: false,\r\n });\r\n }\r\n\r\n /**\r\n * Gets the categories by category name.\r\n * @private\r\n */\r\n function getCategoriesFromNames(categories) {\r\n if (typeof categories === 'string') {\r\n categories = new Array(categories);\r\n }\r\n\r\n // Get all categories from all parents\r\n const allCategories = flatten(get(insightsFactory.allCategories, 'Categories'));\r\n const categoryObjects = filter(allCategories,\r\n item => includes(categories, item.CategoryDisplayName),\r\n );\r\n\r\n return categoryObjects;\r\n }\r\n};\r\n\r\nexport default InsightsController;\r\n","const ProductComparisonController = /* @ngInject */ (\r\n $scope,\r\n $state,\r\n $stateParams,\r\n $timeout,\r\n $filter,\r\n productComparisonFactory,\r\n) => {\r\n $scope.compareShow = false;\r\n\r\n $scope.getCompareSettings = () => productComparisonFactory.compareSettings;\r\n\r\n /**\r\n * Removed all comparisons for the user on the server, and resets them on the client accordingly\r\n */\r\n $scope.removeAllComparisons = (e) => {\r\n if (e) e.preventDefault();\r\n productComparisonFactory.compareSettings.ComparedProducts = [];\r\n\r\n productComparisonFactory.removeAllComparisons();\r\n };\r\n\r\n /**\r\n * Removes a product comparison and sets the value on the client accordingly\r\n */\r\n $scope.removeComparison = (e, product) => {\r\n if (e) e.preventDefault();\r\n\r\n product.IsCompared = false;\r\n\r\n productComparisonFactory.compareChange(product.AgilityID).then(() => {\r\n productComparisonFactory.getCompareSettings();\r\n });\r\n };\r\n\r\n $scope.compareShowToggle = () => {\r\n $scope.compareShow = !$scope.compareShow;\r\n };\r\n};\r\n\r\nexport default ProductComparisonController;\r\n","import filter from 'lodash/filter';\r\n\r\nconst ProductListController = /* @ngInject */ (\r\n $scope,\r\n $state,\r\n $stateParams,\r\n $timeout,\r\n $filter,\r\n $window,\r\n productFilters,\r\n routeProxy,\r\n productListFactory,\r\n productComparisonFactory,\r\n loadingBar,\r\n) => {\r\n initialise();\r\n\r\n function initialise() {\r\n $scope.productFilters = productFilters;\r\n $scope.filterLoaded = true;\r\n $scope.redirecting = false;\r\n\r\n $scope.loaded = () => productListFactory.loaded;\r\n\r\n /** Pagination options. */\r\n $scope.pagination = {\r\n pageid: $stateParams.pageid,\r\n itemsPerPage: 15,\r\n };\r\n\r\n // Shows the currently selected filters\r\n $scope.selectedFilters = {\r\n category: $stateParams.category,\r\n powersource: $stateParams.powersource,\r\n productcode: $stateParams.productcode,\r\n batteries: $stateParams.batteries,\r\n unknown1: $stateParams.unknown1,\r\n unknown2: $stateParams.unknown2,\r\n unknown3: $stateParams.unknown3,\r\n groupedAll: $stateParams.groupedAll,\r\n };\r\n\r\n $scope.showLoadMore = () => {\r\n if (productListFactory.filteredItems &&\r\n $scope.pagination.pagesize() < productListFactory.filteredItems.length) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n /** Load the next page. */\r\n $scope.loadMore = (e) => {\r\n if (e) e.preventDefault();\r\n\r\n // If there are still items to show then increment page count.\r\n if ($scope.showLoadMore()) {\r\n $scope.pagination.pageid += 1;\r\n }\r\n };\r\n\r\n /**\r\n * Returns the current page size\r\n */\r\n $scope.pagination.pagesize = () => (\r\n $scope.pagination.itemsPerPage * $scope.pagination.pageid\r\n );\r\n\r\n /**\r\n * Returns the products to be displayed on the current page\r\n */\r\n $scope.pagedItems = () => $filter('limitTo')(\r\n productListFactory.filteredItems,\r\n $scope.pagination.pagesize(),\r\n 0,\r\n );\r\n\r\n /**\r\n * Gets classes to conditionally display between each product list item\r\n */\r\n $scope.getClearfixClasses = (index) => {\r\n const classArray = [];\r\n\r\n if ((index + 1) % 5 === 0) {\r\n classArray.push('visible-lg clearfix');\r\n }\r\n\r\n if ((index + 1) % 4 === 0) {\r\n classArray.push('visible-md clearfix');\r\n }\r\n\r\n if ((index + 1) % 2 === 0) {\r\n classArray.push('visible-sm clearfix');\r\n }\r\n\r\n if ((index + 1) % 1 === 0) {\r\n classArray.push('visible-xs clearfix');\r\n }\r\n\r\n return classArray;\r\n };\r\n\r\n $scope.showBatteryFilter = () => {\r\n if (!$scope.selectedFilters) {\r\n return false;\r\n }\r\n\r\n if (!$scope.selectedFilters.powersource) {\r\n return false;\r\n }\r\n\r\n const selectedPowerSource = $scope.selectedFilters.powersource;\r\n const regex = new RegExp(\r\n ['36v', '18v', '12V', '14.4v', '7v', '4v'].join('|'),\r\n 'i',\r\n );\r\n\r\n if (regex.test(selectedPowerSource)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n /**\r\n * Gets a list of sibling categories\r\n */\r\n productListFactory.getCategoryTypes().then((data) => {\r\n $scope.categoryTypes = data;\r\n\r\n $scope.categoryType = filter(data, x => x.Url === $window.location.pathname);\r\n });\r\n\r\n $scope.categoryTypeSelected = () => {\r\n const selectedType = this.categoryType;\r\n\r\n if (selectedType && selectedType.Url !== '') {\r\n $window.location.href = selectedType.Url;\r\n }\r\n };\r\n\r\n $scope.hasBatteries = (batteries) => {\r\n const filters = angular.extend({}, $scope.selectedFilters);\r\n\r\n if (batteries) {\r\n filters.batteries = 'true';\r\n } else {\r\n filters.batteries = 'false';\r\n }\r\n\r\n if (productListFactory.filteredItems && productListFactory.filteredItems.length > 0) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n /**\r\n * Filters the products to be displayed on the page\r\n */\r\n const setFilteredItems = () => {\r\n if ($scope.redirecting) {\r\n return;\r\n }\r\n let filters;\r\n\r\n if (productListFactory.selectedFilters) {\r\n filters = productListFactory.selectedFilters;\r\n } else {\r\n filters = $scope.selectedFilters;\r\n }\r\n\r\n productListFactory.getFilteredItems(filters).then((data) => {\r\n productListFactory.loaded = true;\r\n\r\n $timeout(() => {\r\n productListFactory.filteredItems = data;\r\n });\r\n });\r\n };\r\n\r\n // Ensured calls are run only once\r\n if (!productListFactory.initialised) {\r\n productListFactory.initialised = true;\r\n setFilteredItems();\r\n }\r\n\r\n /**\r\n * The filters are stored on the product list controller against the filters,\r\n * this and the watch keeps them in sync\r\n */\r\n $scope.getFilters = () => productListFactory.selectedFilters;\r\n\r\n $scope.$watch('selectedFilters', (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n // Add a loading bar to make it appear that something's happened\r\n loadingBar.addLoadingBar();\r\n\r\n productListFactory.selectedFilters = newValue;\r\n\r\n setStateParameters();\r\n setFilteredItems();\r\n }\r\n }, true);\r\n\r\n $scope.$watch('pagination', (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n // Add a loading bar to make it appear that something's happened\r\n loadingBar.addLoadingBar();\r\n\r\n setStateParameters();\r\n setFilteredItems();\r\n }\r\n }, true);\r\n }\r\n\r\n /**\r\n * Sets the state parameters based on the pagination and filter objects.\r\n * @private\r\n */\r\n function setStateParameters() {\r\n const stateParameters = {\r\n pageid: $scope.pagination.pageid,\r\n };\r\n\r\n if (productListFactory.selectedFilters) {\r\n //\r\n if (productListFactory.selectedFilters.category) {\r\n //\r\n if (productListFactory.getProxyFilters().filterFunctionalityOverrides.indexOf('categories') === -1) {\r\n $window.location.href = productListFactory.selectedFilters.category.Url;\r\n $scope.redirecting = true;\r\n return;\r\n }\r\n\r\n stateParameters.category = productListFactory.selectedFilters.category.Name;\r\n }\r\n\r\n if (productListFactory.selectedFilters.powersource) {\r\n stateParameters.powersource = productListFactory.selectedFilters.powersource;\r\n }\r\n\r\n if (productListFactory.selectedFilters.productcode) {\r\n stateParameters.productcode = productListFactory.selectedFilters.productcode;\r\n }\r\n\r\n if (productListFactory.selectedFilters.batteries) {\r\n stateParameters.batteries = productListFactory.selectedFilters.batteries;\r\n }\r\n\r\n if (productListFactory.selectedFilters.unknown1) {\r\n stateParameters.unknown1 = productListFactory.selectedFilters.unknown1;\r\n }\r\n\r\n if (productListFactory.selectedFilters.unknown2) {\r\n stateParameters.unknown2 = productListFactory.selectedFilters.unknown2;\r\n }\r\n\r\n if (productListFactory.selectedFilters.unknown3) {\r\n stateParameters.unknown3 = productListFactory.selectedFilters.unknown3;\r\n }\r\n\r\n if (productListFactory.selectedFilters.GroupedAll) {\r\n stateParameters.groupedAll = productListFactory.selectedFilters.GroupedAll;\r\n }\r\n }\r\n\r\n $state.go($state.current.name, stateParameters, {\r\n location: 'replace',\r\n inherit: false,\r\n notify: false,\r\n });\r\n }\r\n};\r\n\r\nexport default ProductListController;\r\n","const SupportController = /* @ngInject */ (\r\n $scope,\r\n $state,\r\n $stateParams,\r\n $timeout,\r\n $filter,\r\n $sce,\r\n supportFactory,\r\n) => {\r\n initialise();\r\n\r\n function initialise() {\r\n $scope.allCategories = [];\r\n\r\n $scope.getPagedItems = () => supportFactory.filteredItems;\r\n\r\n $scope.getCategories = () => supportFactory.allCategories;\r\n\r\n $scope.selectCategory = (e, category) => {\r\n if (e) e.preventDefault();\r\n\r\n supportFactory.filters.selectedCategory = category;\r\n supportFactory.getFilteredItems();\r\n };\r\n\r\n $scope.getSelectedCategory = () => supportFactory.filters.selectedCategory;\r\n\r\n $scope.getCategoryHref = (category) => {\r\n const stateParameters = {\r\n category: category.Title,\r\n };\r\n\r\n return $state.href($state.current.name, stateParameters);\r\n };\r\n }\r\n};\r\n\r\nexport default SupportController;\r\n","import filter from 'lodash/filter';\r\nimport flatten from 'lodash/flatten';\r\nimport get from 'lodash/get';\r\nimport includes from 'lodash/includes';\r\n\r\nconst VideoListController = /* @ngInject */ (\r\n $scope,\r\n $state,\r\n $stateParams,\r\n $timeout,\r\n $filter,\r\n videoListFactory,\r\n loadingBar,\r\n) => {\r\n initialise();\r\n\r\n function initialise() {\r\n $scope.filterLoaded = false;\r\n\r\n /** Filter options. */\r\n $scope.filters = {};\r\n\r\n /**\r\n * Returns the current page size\r\n */\r\n $scope.pagesize = () => (\r\n videoListFactory.pagination.itemsPerPage * videoListFactory.pagination.pageid\r\n );\r\n\r\n $scope.getPagedItems = () => videoListFactory.pagedItems;\r\n\r\n $scope.showLoadMore = () => (\r\n videoListFactory.pagedItems &&\r\n $scope.pagesize() < videoListFactory.filteredItems.length\r\n );\r\n\r\n /** Load the next page. */\r\n $scope.loadMore = (e) => {\r\n if (e) e.preventDefault();\r\n\r\n // If there are still items to show then increment page count.\r\n if ($scope.showLoadMore()) {\r\n videoListFactory.pagination.pageid += 1;\r\n }\r\n };\r\n\r\n /** Returns offset classes to add to the video item.\r\n This will center the video if only a single item is present.\r\n */\r\n $scope.addOffsetClasses = () => {\r\n const classes = [];\r\n\r\n if (videoListFactory.pagedItems && videoListFactory.pagedItems.length === 1) {\r\n classes.push('col-md-offset-4');\r\n classes.push('col-sm-offset-3');\r\n classes.push('single-video');\r\n }\r\n\r\n return classes;\r\n };\r\n\r\n /** Returns the autoplayable class if there is only a single item on the page. */\r\n $scope.isAutoPlayable = () => {\r\n const classes = [];\r\n\r\n if (videoListFactory.pagedItems && videoListFactory.pagedItems.length === 1) {\r\n classes.push('js-autoplayable');\r\n }\r\n\r\n return classes;\r\n };\r\n\r\n /** Gets the URL for the next page. */\r\n $scope.getLoadMoreUrl = () => {\r\n const params = {};\r\n params.pageid = videoListFactory.pagination.pageid + 1;\r\n\r\n if (videoListFactory.filters) {\r\n let categories = videoListFactory.filters.categories;\r\n\r\n if (typeof categories === 'object') {\r\n categories = get(categories, 'CategoryDisplayName');\r\n }\r\n\r\n if (typeof categories === 'string') {\r\n categories = new Array(categories);\r\n }\r\n\r\n // Filter out any null values\r\n categories = filter(categories, x => x);\r\n\r\n if (categories.length > 0) { params.category = categories; }\r\n }\r\n\r\n return $state.href('videoList', params);\r\n };\r\n\r\n /**\r\n * Gets classes to conditionally display between each video list item\r\n */\r\n $scope.getClearfixClasses = (index) => {\r\n const classArray = [];\r\n\r\n if ((index + 1) % 3 === 0) {\r\n classArray.push('visible-md visible-lg clearfix');\r\n }\r\n\r\n if ((index + 1) % 2 === 0) {\r\n classArray.push('visible-sm clearfix');\r\n }\r\n\r\n if ((index + 1) % 1 === 0) {\r\n classArray.push('visible-xs clearfix');\r\n }\r\n\r\n return classArray;\r\n };\r\n\r\n $scope.$watch(() => videoListFactory.pagination,\r\n (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n $scope.pagination = newValue;\r\n\r\n resetPagedItems();\r\n setStateParameters();\r\n }\r\n }, true);\r\n\r\n // Setting the watches after we have the categories so that\r\n // they're not fired again when we set the filtered categories above\r\n $scope.$watch('filters', (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n videoListFactory.filters = newValue;\r\n\r\n videoListFactory.pagination.pageid = 1;\r\n resetPagedItems();\r\n setStateParameters();\r\n }\r\n }, true);\r\n\r\n videoListFactory.pagination.pageid = $stateParams.pageid;\r\n\r\n resetPagedItems();\r\n\r\n videoListFactory.getAllCategories().then((data) => {\r\n if (data.length > 0) {\r\n $scope.filterLoaded = true;\r\n }\r\n\r\n $scope.allCategories = data;\r\n $scope.filters.categories = $stateParams.category ?\r\n getCategoriesFromNames($stateParams.category) :\r\n [];\r\n });\r\n }\r\n\r\n /**\r\n * Gets the categories by category name.\r\n * @private\r\n */\r\n function getCategoriesFromNames(categories) {\r\n if (typeof categories === 'string') {\r\n categories = new Array(categories);\r\n }\r\n\r\n // Get all categories from all parents\r\n const allCategories = flatten(get($scope.allCategories, 'Categories'));\r\n const categoryObjects = filter(\r\n allCategories,\r\n item => includes(categories, item.CategoryDisplayName),\r\n );\r\n\r\n return categoryObjects;\r\n }\r\n\r\n function resetPagedItems() {\r\n // Add a loading bar to make it appear that something's happened\r\n loadingBar.addLoadingBar();\r\n\r\n videoListFactory.setFilteredItems().then((data) => {\r\n videoListFactory.pagedItems = $filter('limitTo')(data, $scope.pagesize(), 0);\r\n });\r\n }\r\n\r\n /**\r\n * Sets the state parameters based on the pagination and filter objects.\r\n * @private\r\n */\r\n function setStateParameters() {\r\n const stateParameters = {\r\n pageid: videoListFactory.pagination.pageid,\r\n };\r\n\r\n const filters = videoListFactory.filters;\r\n\r\n let categoryState = (filters && filters.categories) ?\r\n get(filters.categories, 'CategoryDisplayName') :\r\n null;\r\n\r\n if (categoryState) {\r\n categoryState = filter(categoryState, x => x);\r\n }\r\n\r\n if (categoryState != null && categoryState.length > 0) {\r\n stateParameters.category = categoryState;\r\n }\r\n\r\n $state.go($state.current.name, stateParameters, {\r\n location: 'replace',\r\n inherit: false,\r\n notify: false,\r\n });\r\n }\r\n};\r\n\r\nexport default VideoListController;\r\n","import BlogController from './blogController';\r\nimport FaqsController from './faqsController';\r\nimport InsightsController from './insightsController';\r\nimport ProductComparisonController from './productComparisonController';\r\nimport ProductListController from './productListController';\r\nimport SupportController from './supportController';\r\nimport VideoListController from './videoListController';\r\n\r\nconst module = angular.module('ryobi.controllers', [])\r\n .controller('BlogController', BlogController)\r\n .controller('FaqsController', FaqsController)\r\n .controller('InsightsController', InsightsController)\r\n .controller('ProductComparisonController', ProductComparisonController)\r\n .controller('ProductListController', ProductListController)\r\n .controller('SupportController', SupportController)\r\n .controller('VideoListController', VideoListController);\r\n\r\nexport default module;\r\n","export default /* @ngInject */ ($http, $q) => {\r\n const self = {\r\n getApplicators,\r\n getApplicatorProducts,\r\n getIsotopeItems,\r\n };\r\n\r\n let applicators;\r\n\r\n return self;\r\n\r\n function getApplicators() {\r\n if (applicators) {\r\n return applicators;\r\n }\r\n\r\n const deferred = $q.defer();\r\n\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/cordless/applicators', { params }).then(\r\n (response) => {\r\n deferred.resolve(response.data);\r\n applicators = response.data;\r\n return response;\r\n },\r\n (response) => {\r\n deferred.reject(response);\r\n return response;\r\n });\r\n\r\n return deferred.promise;\r\n }\r\n\r\n function getIsotopeItems() {\r\n const deferred = $q.defer();\r\n\r\n const params = {\r\n path: angular.element('.js-cordless').data('path'),\r\n };\r\n\r\n $http.get('/api/cordless/isotopeitems', { params }).then(\r\n (response) => {\r\n deferred.resolve(response.data);\r\n return response;\r\n },\r\n (response) => {\r\n deferred.reject(response);\r\n return response;\r\n });\r\n\r\n return deferred.promise;\r\n }\r\n\r\n function getApplicatorProducts(applicator, minRange, maxRange) {\r\n if (!applicator || applicator.length <= 0) {\r\n return null;\r\n }\r\n\r\n const deferred = $q.defer();\r\n\r\n\r\n const params = {\r\n applicator,\r\n minRange,\r\n maxRange,\r\n };\r\n\r\n $http.get('/api/cordless/products', { params }).then(\r\n (response) => {\r\n deferred.resolve(response.data);\r\n return response;\r\n },\r\n (response) => {\r\n deferred.reject(response);\r\n return response;\r\n });\r\n\r\n return deferred.promise;\r\n }\r\n};\r\n","export default /* @ngInject */ ($state, $window, applicators) => {\r\n const vm = this;\r\n vm.applicatorGroups = applicators;\r\n vm.showTooltip = showTooltip;\r\n vm.hideTooltip = hideTooltip;\r\n vm.getApplicatorProducts = getApplicatorProducts;\r\n vm.getCssClass = getCssClass;\r\n\r\n activate();\r\n\r\n /** Activate controller. */\r\n function activate() {\r\n }\r\n\r\n function showTooltip(applicator) {\r\n applicator.tooltipActive = true;\r\n }\r\n\r\n function hideTooltip(applicator) {\r\n applicator.tooltipActive = false;\r\n }\r\n\r\n function getApplicatorProducts(applicator, e) {\r\n if (e) {\r\n e.preventDefault();\r\n }\r\n\r\n applicator.tooltipActive = false;\r\n $state.go($state.current.name, {\r\n applicator: applicator.Title,\r\n });\r\n }\r\n\r\n function getCssClass(applicator) {\r\n const width = applicator.DesktopWidth;\r\n\r\n if (width === 60) {\r\n return 'cordless__inner-two-third';\r\n }\r\n\r\n if (width === 40) {\r\n return 'cordless__inner-forty-width';\r\n }\r\n\r\n return 'cordless__inner-third';\r\n }\r\n};\r\n","import debounce from 'lodash/debounce';\r\n\r\nexport default /* @ngInject */ (\r\n $scope,\r\n $state,\r\n $stateParams,\r\n applicators,\r\n productList,\r\n cordlessFactory,\r\n) => {\r\n if (!productList) {\r\n return;\r\n }\r\n\r\n const vm = this;\r\n vm.productList = productList;\r\n vm.hideApplicatorProducts = hideApplicatorProducts;\r\n vm.sliderOptions = {\r\n showTicks: true,\r\n floor: productList.RangeMin,\r\n ceil: productList.RangeMax,\r\n step: getRangeStep(),\r\n hideLimitLabels: true,\r\n onlyBindHandles: true,\r\n translate(value) {\r\n if (productList && productList.RangeUnits && productList.RangeUnits.length > 0) {\r\n return value + productList.RangeUnits;\r\n }\r\n\r\n return value;\r\n },\r\n };\r\n vm.applicators = [{ Title: '' }];\r\n vm.selectedApplicator = $stateParams.applicator || '';\r\n\r\n vm.slider = {\r\n minValue: $stateParams.min || vm.sliderOptions.floor,\r\n maxValue: $stateParams.max || vm.sliderOptions.ceil,\r\n };\r\n\r\n /**\r\n * Gets classes to conditionally display between each product list item\r\n */\r\n vm.getClearfixClasses = (index) => {\r\n const classArray = [];\r\n\r\n if ((index + 1) % 4 === 0) {\r\n classArray.push('visible-lg clearfix');\r\n }\r\n\r\n if ((index + 1) % 3 === 0) {\r\n classArray.push('visible-md clearfix');\r\n }\r\n\r\n if ((index + 1) % 2 === 0) {\r\n classArray.push('visible-sm clearfix');\r\n }\r\n\r\n if ((index + 1) % 1 === 0) { classArray.push('visible-xs clearfix'); }\r\n\r\n return classArray;\r\n };\r\n\r\n $scope.$watch('vm.selectedApplicator', (newVal, oldVal) => {\r\n if (newVal !== oldVal) {\r\n $state.go($state.current.name, {\r\n applicator: newVal,\r\n }, {\r\n inherit: false,\r\n notify: false, // Not notifying to prevent the list from reloading\r\n });\r\n\r\n cordlessFactory\r\n .getApplicatorProducts(vm.selectedApplicator, vm.slider.minValue, vm.slider.maxValue)\r\n .then((data) => { vm.productList = data; });\r\n }\r\n });\r\n\r\n $scope.$watch('vm.slider', debounce((newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n const params = {\r\n applicator: vm.selectedApplicator,\r\n };\r\n\r\n if (vm.slider.minValue > 0) {\r\n params.min = vm.slider.minValue;\r\n }\r\n\r\n if (vm.slider.maxValue > 0 && vm.slider.maxValue !== productList.RangeMax) {\r\n params.max = vm.slider.maxValue;\r\n }\r\n\r\n $state.go($state.current.name, params, {\r\n inherit: false,\r\n notify: false, // Not notifying to prevent the list from reloading\r\n });\r\n\r\n cordlessFactory\r\n .getApplicatorProducts(vm.selectedApplicator, vm.slider.minValue, vm.slider.maxValue)\r\n .then((data) => { vm.productList = data; });\r\n }\r\n }, 500), true);\r\n\r\n function getRangeStep() {\r\n const stepCount = productList.RangeMax - productList.RangeMin;\r\n return stepCount / 10;\r\n }\r\n\r\n function hideApplicatorProducts(e) {\r\n if (e) {\r\n e.preventDefault();\r\n }\r\n\r\n vm.productList = null;\r\n $state.go($state.current.name, {}, {\r\n inherit: false,\r\n notify: false,\r\n });\r\n }\r\n\r\n activate();\r\n\r\n function activate() {\r\n for (let i = 0; i < applicators.length; i += 1) {\r\n const group = applicators[i];\r\n\r\n if (group.Applicators) {\r\n for (let j = 0; j < group.Applicators.length; j += 1) {\r\n vm.applicators.push(group.Applicators[j]);\r\n }\r\n }\r\n }\r\n }\r\n};\r\n","export default class IsotopeItemsListController {\r\n /* @ngInject */\r\n constructor($state, $window, isotopeItems) {\r\n this.$state = $state;\r\n this.$window = $window;\r\n this.isotopeItems = isotopeItems;\r\n }\r\n getApplicatorProducts(applicator, e) {\r\n if (e) {\r\n e.preventDefault();\r\n }\r\n const { $state } = this;\r\n $state.go($state.current.name, {\r\n applicator: applicator.Products,\r\n });\r\n }\r\n}\r\n","/* eslint-disable max-len */\r\nimport cordlessFactory from './cordless.factory';\r\nimport ApplicatorListController from './applicator-list/applicator-list.controller';\r\nimport ApplicatorProductListController from './product-list/product-list.controller';\r\nimport ApplicatorIsotopeItemsListController from './isotope-items-list/isotope-items-list.controller';\r\nimport positionTooltipDirective from './applicator-list/position-tooltip.directive';\r\n/* eslint-enable max-len */\r\n\r\nconst module = angular.module('ryobi.cordless', ['ryobi.directives'])\r\n .controller('ApplicatorListController', ApplicatorListController)\r\n .controller('ApplicatorProductListController', ApplicatorProductListController)\r\n .controller('ApplicatorIsotopeItemsListController', ApplicatorIsotopeItemsListController)\r\n .factory('cordlessFactory', cordlessFactory)\r\n .directive('positionTooltip', positionTooltipDirective)\r\n .config(configureModule);\r\n\r\n/* @ngInject */\r\nfunction configureModule($stateProvider, $urlRouterProvider) {\r\n if (!angular.element('.js-cordless').length) {\r\n return;\r\n }\r\n\r\n $stateProvider\r\n .state('cordless', {\r\n abstract: true,\r\n })\r\n .state('cordless.list', {\r\n resolve: {\r\n /* eslint-disable no-shadow */\r\n applicators: /* @ngInject */ cordlessFactory => cordlessFactory.getApplicators(),\r\n isotopeItems: /* @ngInject */ cordlessFactory => cordlessFactory.getIsotopeItems(),\r\n productList: /* @ngInject */ ($stateParams, cordlessFactory) =>\r\n cordlessFactory.getApplicatorProducts(\r\n $stateParams.applicator,\r\n $stateParams.min,\r\n $stateParams.max,\r\n ),\r\n /* eslint-enable no-shadow */\r\n },\r\n url: '/{applicator}?{min:int}&{max:int}',\r\n views: {\r\n 'applicators@': {\r\n controller: 'ApplicatorListController',\r\n controllerAs: 'vm',\r\n templateUrl: '/sitefiles/src/ui/js/cordless/applicator-list/ApplicatorList.aspx',\r\n },\r\n 'isotopeItems@': {\r\n controller: 'ApplicatorIsotopeItemsListController',\r\n controllerAs: 'vm',\r\n templateUrl: '/sitefiles/src/ui/js/cordless/isotope-items-list/IsotopeItemsList.aspx',\r\n },\r\n 'products@': {\r\n controller: 'ApplicatorProductListController',\r\n controllerAs: 'vm',\r\n templateUrl: '/sitefiles/src/ui/js/cordless/product-list/ApplicatorProductList.aspx',\r\n },\r\n },\r\n });\r\n\r\n $urlRouterProvider.otherwise('/');\r\n}\r\n\r\nexport default module;\r\n","export default /* @ngInject */ ($timeout, $window) => {\r\n const self = {\r\n restrict: 'A',\r\n link,\r\n scope: {\r\n },\r\n };\r\n\r\n function link(scope, element) {\r\n const $link = element.siblings('.hex-btn');\r\n\r\n if ($link.length <= 0) {\r\n return;\r\n }\r\n\r\n $timeout(() => {\r\n const pointPos = $link.offset();\r\n\r\n const windowHalfWidth = $window.innerWidth / 2;\r\n const windowHalfHeight = $window.innerHeight / 2;\r\n\r\n if (pointPos.left > windowHalfWidth) {\r\n element.addClass('content-to-right');\r\n }\r\n\r\n if (pointPos.top > windowHalfHeight) {\r\n element.addClass('content-above');\r\n }\r\n });\r\n }\r\n\r\n return self;\r\n};\r\n","import template from './categorySeo.html';\r\n\r\n/* eslint-disable max-len */\r\nclass CategorySeoController {\r\n /* @ngInject */\r\n constructor($attrs, $location, $scope, $state, $stateParams, $timeout, $transclude, categoryFactory) {\r\n this.$location = $location;\r\n this.$state = $state;\r\n this.$stateParams = $stateParams;\r\n this.categoryFactory = categoryFactory;\r\n\r\n this.originalDescriptionHtml = '';\r\n this.originalTitle = $attrs.title;\r\n this.originalImageSrc = $attrs.imageSrc;\r\n\r\n // The original description is stored as child HTML, so tranclude it\r\n $transclude((clone) => {\r\n this.originalDescriptionHtml = angular.element('
').append(clone).html();\r\n });\r\n\r\n // When the state changes, find the new SEO category information\r\n $scope.$watch(() => $stateParams.category, (newVal, oldVal) => {\r\n if (newVal !== oldVal) {\r\n this.updateCategoryInformation();\r\n }\r\n });\r\n\r\n $timeout(() => {\r\n this.updateCategoryInformation();\r\n });\r\n }\r\n updateCategoryInformation() {\r\n const { $location, $state, $stateParams, categoryFactory } = this;\r\n categoryFactory.getCategorySeo($stateParams.category).then((data) => {\r\n if (!data) {\r\n data = {};\r\n }\r\n\r\n this.currentCategorySeo = data;\r\n\r\n // When we've updated the category SEO, update the description and image, or fallback to the original if not set\r\n if (!this.currentCategorySeo || !this.currentCategorySeo.description || this.currentCategorySeo.description.length <= 0) {\r\n this.categoryDescription = this.originalDescriptionHtml;\r\n } else {\r\n this.categoryDescription = this.currentCategorySeo.description;\r\n }\r\n\r\n if (!this.currentCategorySeo || !this.currentCategorySeo.bannerImage || this.currentCategorySeo.bannerImage.length <= 0) {\r\n this.imageSrc = this.originalImageSrc;\r\n } else {\r\n this.imageSrc = this.currentCategorySeo.bannerImage;\r\n }\r\n\r\n if ($stateParams.category && $stateParams.category.length > 0) {\r\n if (!this.currentCategorySeo || !this.currentCategorySeo.title || this.currentCategorySeo.title.length <= 0) {\r\n this.title = $stateParams.category;\r\n } else {\r\n this.title = this.currentCategorySeo.title;\r\n }\r\n } else {\r\n this.title = this.originalTitle;\r\n }\r\n\r\n this.currentCategorySeo.canonicalLink = `${$location.protocol()}://${$location.host()}${$state.href($state.current.name)}`;\r\n });\r\n }\r\n}\r\n\r\nexport default /* @ngInject */ () => {\r\n const directive = {\r\n bindToController: true,\r\n controller: CategorySeoController,\r\n controllerAs: 'vm',\r\n link,\r\n replace: true,\r\n restrict: 'A',\r\n transclude: true,\r\n scope: {},\r\n template,\r\n };\r\n\r\n return directive;\r\n\r\n function link(scope) {\r\n let $keywords = $('meta[name=keywords]');\r\n let $description = $('meta[name=description]');\r\n let $canonical = $(\"link[rel='canonical']\");\r\n\r\n const hasOriginalSeoKeywords = $keywords.length > 0;\r\n const hasOriginalSeoDescription = $description.length > 0;\r\n const hasOriginalCanonicalLink = $(\"link[rel='canonical']\").length > 0;\r\n\r\n // Initialise original values, so we can return to them if we're not given any new ones\r\n const originalSeoTitle = $(document).attr('title');\r\n const originalSeoKeywords = $keywords.attr('content');\r\n const originalSeoDescription = $description.attr('content');\r\n const originalCanonicalLink = $canonical.attr('href');\r\n\r\n // The category has chanced, so update the meta tags\r\n scope.$watch('vm.currentCategorySeo', (newValue) => {\r\n // Refresh the variables - they might have changed\r\n $keywords = $('meta[name=keywords]');\r\n $description = $('meta[name=description]');\r\n $canonical = $(\"link[rel='canonical']\");\r\n\r\n const currentCategorySeo = newValue;\r\n\r\n let newSeoTitle = originalSeoTitle;\r\n let newSeoKeywords = originalSeoKeywords;\r\n let newSeoDescription = originalSeoDescription;\r\n let newCanonicalLink = originalCanonicalLink;\r\n\r\n if (currentCategorySeo) {\r\n if (currentCategorySeo.seoTitle && currentCategorySeo.seoTitle.length > 0) {\r\n newSeoTitle = currentCategorySeo.seoTitle;\r\n }\r\n\r\n if (currentCategorySeo.seoKeywords && currentCategorySeo.seoKeywords.length > 0) {\r\n newSeoKeywords = currentCategorySeo.seoKeywords;\r\n }\r\n\r\n if (currentCategorySeo.seoDescription && currentCategorySeo.seoDescription.length > 0) {\r\n newSeoDescription = currentCategorySeo.seoDescription;\r\n }\r\n\r\n if (currentCategorySeo.canonicalLink && currentCategorySeo.canonicalLink.length > 0) {\r\n newCanonicalLink = currentCategorySeo.canonicalLink;\r\n }\r\n }\r\n\r\n // Remove tags if they're not required (maybe didn't have one to begin with), or add them if they now are\r\n removeOrAddTag($keywords, hasOriginalSeoKeywords, originalSeoKeywords, newSeoKeywords, ``);\r\n removeOrAddTag($description, hasOriginalSeoDescription, originalSeoDescription, newSeoDescription, ` `);\r\n removeOrAddTag($canonical, hasOriginalCanonicalLink, originalCanonicalLink, newCanonicalLink, ``);\r\n\r\n // Update the tag's content\r\n $(document).attr('title', newSeoTitle);\r\n $keywords.attr('content', newSeoKeywords);\r\n $description.attr('content', newSeoDescription);\r\n $canonical.attr('href', newCanonicalLink);\r\n\r\n function removeOrAddTag($tag, hasOriginalTag, originalContent, newContent, defaultTag) {\r\n // If there wasn't one already, and we're assigning the default, remove it again\r\n if (!hasOriginalTag && originalContent === newContent) {\r\n $tag.remove(// If we have new meta content, but the tag doesn't exist, add it\r\n );\r\n } else if ($tag.length <= 0 && originalContent !== newContent) {\r\n $('head').append(defaultTag);\r\n }\r\n }\r\n }, true);\r\n }\r\n};\r\n","/* eslint-disable max-len */\r\nconst slideDuration = 300;\r\nconst delayInterval = 100; // 100 Ms = 0.1s\r\n\r\nexport default /* @ngInject */ () => {\r\n const self = {\r\n link,\r\n restrict: 'A',\r\n scope: {\r\n filterLoaded: '=',\r\n },\r\n };\r\n\r\n return self;\r\n\r\n function link(scope, element) {\r\n const $parent = $(element);\r\n const $groups = $parent.find('.group > a');\r\n\r\n checkLoaded();\r\n\r\n // Load filter by default\r\n scope.$watch('filterLoaded', (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n checkLoaded();\r\n }\r\n }, true);\r\n\r\n function checkLoaded() {\r\n if (scope.filterLoaded === true) {\r\n $groups.each((i, item) => {\r\n const $this = $(item);\r\n const $group = $this.closest('.group');\r\n const $toggle = $group.children('.drop');\r\n if ($group.hasClass('start-open')) {\r\n slideToggleGroup($toggle, null, true);\r\n }\r\n });\r\n }\r\n }\r\n\r\n $groups.click((e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const $this = $(e.currentTarget);\r\n\r\n const $notClicked = $('.groups .group .drop:visible').siblings('a').not($this);\r\n\r\n const $clickedGroup = $this.parent('.group');\r\n const $toggle = $clickedGroup.children('.drop');\r\n if ($notClicked.length > 0) {\r\n const $notClickedToggle = $notClicked.siblings('.drop');\r\n slideToggleGroup($notClickedToggle, () => {\r\n slideToggleGroup($toggle);\r\n });\r\n } else {\r\n slideToggleGroup($toggle);\r\n }\r\n });\r\n }\r\n};\r\n\r\nfunction slideToggleGroup($toggle, always, forceOpen) {\r\n const $group = $toggle.closest('.group');\r\n let startedOpened = false;\r\n if ($group.hasClass('open')) {\r\n startedOpened = true;\r\n }\r\n\r\n if (forceOpen === true) {\r\n startedOpened = false;\r\n }\r\n\r\n const toggleOptions = {\r\n duration: slideDuration,\r\n step: slideStep,\r\n always,\r\n done() {\r\n if (!startedOpened) {\r\n $group.addClass('open');\r\n }\r\n },\r\n };\r\n\r\n let delay = 0;\r\n if (startedOpened) {\r\n const childCount = $toggle.children().length;\r\n delay = delayInterval * childCount;\r\n if (delay > 0) {\r\n delay += 200;\r\n } // Add some time at the end, so the animations finish before the JS scrolls up\r\n $group.removeClass('open');\r\n }\r\n\r\n setTimeout(() => {\r\n $toggle.slideToggle(toggleOptions);\r\n }, delay);\r\n}\r\n\r\n/** Sets the margin to slide the main content down when the filter slides */\r\nfunction slideStep(now, tween) {\r\n if (tween.prop === 'height') {\r\n const $elem = $(tween.elem);\r\n $elem.closest('.groups').css('margin-bottom', `${now}px`);\r\n }\r\n}\r\n","/* eslint-disable max-len */\r\nexport default /* @ngInject */ () => {\r\n const directive = {\r\n replace: true,\r\n controllerAs: 'vm',\r\n bindToController: true,\r\n restrict: 'A',\r\n link(scope, element, attrs) {\r\n function setGridWidth() {\r\n let colWidth = attrs.gridColWidth;\r\n\r\n if (!colWidth) {\r\n colWidth = 320;\r\n }\r\n\r\n const windowWidth = window.innerWidth;\r\n const colAmount = windowWidth / colWidth;\r\n let girdWidth;\r\n\r\n if (colAmount < 1) {\r\n girdWidth = Math.floor(1) * colWidth;\r\n } else {\r\n girdWidth = Math.floor(colAmount) * colWidth;\r\n }\r\n\r\n element.css({\r\n width: girdWidth,\r\n });\r\n }\r\n setGridWidth();\r\n $(window).resize(() => {\r\n setGridWidth();\r\n });\r\n },\r\n };\r\n\r\n return directive;\r\n};\r\n","/* eslint-disable max-len */\r\nimport sortBy from 'lodash/sortBy';\r\nimport uniq from 'lodash/uniq';\r\n\r\n/**\r\n * TODO: Make the main site product list use a version of this.\r\n * The different at the moment is this uses a load more button whilst the main list auto loads.\r\n */\r\n\r\nexport default /* @ngInject */ () => {\r\n const directive = {\r\n replace: true,\r\n controller: ProductListController,\r\n controllerAs: 'vm',\r\n bindToController: true,\r\n restrict: 'A',\r\n scope: {},\r\n templateUrl: '/sitefiles/src/ui/js/templates/ProductList.aspx',\r\n };\r\n\r\n return directive;\r\n};\r\n\r\n/* @ngInject */\r\nfunction ProductListController($attrs, $element, $filter, $scope, $window, productListFactory) {\r\n const vm = this;\r\n vm.pagedItemsResult = [];\r\n vm.pagedItems = pagedItems;\r\n vm.getClearfixClasses = getClearfixClasses;\r\n vm.pagination = {\r\n pageid: 1,\r\n itemsPerPage: 10,\r\n pagesize: getPageSize,\r\n };\r\n vm.loadMore = loadMore;\r\n vm.viewAll = viewAll;\r\n vm.showLoadMore = showLoadMore;\r\n vm.loaded = false;\r\n vm.categoryList = [];\r\n vm.selectedCategory = '';\r\n vm.hideReviews = $attrs.hideReviews === undefined ? false : $attrs.hideReviews === 'true';\r\n vm.hideCompare = $attrs.hideCompare === undefined ? false : $attrs.hideCompare === 'true';\r\n vm.hideApplicationShot = $attrs.hideApplicationShot === undefined ? false : $attrs.hideApplicationShot === 'true';\r\n vm.showProductCount = $attrs.showProductCount === undefined ? false : $attrs.showProductCount === 'true';\r\n vm.showingCount = getShowingCount;\r\n vm.totalCount = getProductCount;\r\n const agilityIds = $attrs.agilityIds.split(';');\r\n\r\n const filters = {\r\n agilityIds,\r\n ignoreUrl: true,\r\n };\r\n\r\n let allProducts = [];\r\n\r\n productListFactory.getProducts(filters).then((data) => {\r\n allProducts = data;\r\n vm.loaded = true;\r\n\r\n angular.forEach(allProducts, (value) => {\r\n Array.prototype.push.apply(vm.categoryList, value.Category);\r\n });\r\n\r\n vm.categoryList = sortBy(vm.categoryList, x => x);\r\n\r\n vm.categoryList = uniq(vm.categoryList, true);\r\n });\r\n\r\n function getShowingCount() {\r\n const products = $filter('ProductTabsCategory')(allProducts, vm.selectedCategory);\r\n const limitedProducts = $filter('limitTo')(products, vm.pagination.pagesize(), 0);\r\n return limitedProducts.length;\r\n }\r\n\r\n function getProductCount() {\r\n const products = $filter('ProductTabsCategory')(allProducts, vm.selectedCategory);\r\n return products.length;\r\n }\r\n\r\n /**\r\n * Returns the current page size\r\n */\r\n function getPageSize() {\r\n // If prerender exists in the user agent, then this is probably a request from google,\r\n // so show all products available rather than listing because it won't see the second page\r\n if (allProducts && $window.navigator.userAgent.match(/prerender/i)) {\r\n return allProducts.length;\r\n }\r\n\r\n return vm.pagination.itemsPerPage * vm.pagination.pageid;\r\n }\r\n\r\n function showLoadMore() {\r\n const products = $filter('ProductTabsCategory')(allProducts, vm.selectedCategory);\r\n if (products && vm.pagination.pagesize() < products.length) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns the products to be displayed on the current page\r\n */\r\n function pagedItems() {\r\n const products = $filter('ProductTabsCategory')(allProducts, vm.selectedCategory);\r\n return $filter('limitTo')(products, vm.pagination.pagesize(), 0);\r\n }\r\n\r\n function loadMore() {\r\n vm.pagination.pageid += 1;\r\n }\r\n\r\n function viewAll() {\r\n vm.pagination.pageid = vm.pagination.pagesize();\r\n }\r\n\r\n /**\r\n * Gets classes to conditionally display between each product list item\r\n */\r\n function getClearfixClasses(index) {\r\n const classArray = [];\r\n\r\n if ((index + 1) % 5 === 0) {\r\n classArray.push('visible-lg clearfix');\r\n }\r\n\r\n if ((index + 1) % 4 === 0) {\r\n classArray.push('visible-md clearfix');\r\n }\r\n\r\n if ((index + 1) % 2 === 0) {\r\n classArray.push('visible-sm clearfix');\r\n }\r\n\r\n if ((index + 1) % 1 === 0) {\r\n classArray.push('visible-xs clearfix');\r\n }\r\n\r\n return classArray;\r\n }\r\n}\r\n","/* eslint-disable max-len */\r\nimport get from 'lodash/get';\r\nimport includes from 'lodash/includes';\r\n\r\nexport default /* @ngInject */ () => {\r\n const directive = {\r\n replace: true,\r\n controller: ProductItemController,\r\n restrict: 'E',\r\n scope: {\r\n product: '=?',\r\n agilityId: '=?',\r\n hideCompare: '=?',\r\n hideReviews: '=?',\r\n hideApplicationShot: '=?',\r\n },\r\n templateUrl: '/sitefiles/src/ui/js/templates/ProductItem.aspx',\r\n };\r\n\r\n return directive;\r\n};\r\n\r\n/* @ngInject */\r\nfunction ProductItemController(\r\n $attrs,\r\n $element,\r\n $scope,\r\n productListFactory,\r\n productComparisonFactory,\r\n) {\r\n // If we haven't passed in a product object, use the agilityId if we've provided it instead\r\n if (!$scope.product) {\r\n $scope.product = null;\r\n\r\n const agilityId = parseInt($scope.agilityId, 10);\r\n if (agilityId > 0) {\r\n productListFactory.getProducts({ agilityIds: [agilityId] }).then(data => {\r\n if (data && data.length > 0) {\r\n $scope.product = data[0];\r\n }\r\n });\r\n }\r\n }\r\n\r\n $scope.formatImageUrl = (baseImageUrl, resizeWidth) => {\r\n if (baseImageUrl === undefined || baseImageUrl === null) {\r\n return baseImageUrl;\r\n }\r\n\r\n if (resizeWidth) {\r\n if (baseImageUrl.indexOf('?') > -1) {\r\n return `${baseImageUrl}&width=${resizeWidth}`;\r\n }\r\n\r\n return `${baseImageUrl}?width=${resizeWidth}`;\r\n }\r\n\r\n return baseImageUrl;\r\n };\r\n\r\n /**\r\n * Returns an array of a given size\r\n */\r\n $scope.getArray = items => new Array(items);\r\n\r\n /**\r\n * Refreshes the basic compare settings from the server\r\n */\r\n const refreshCompareSettings = () => {\r\n productComparisonFactory.getCompareSettings();\r\n };\r\n\r\n /**\r\n * Fired when the a compare checkbox is altered - the comparison is set/unset on the server,\r\n * the client is updated accordingly, and then the server updates for completeness\r\n */\r\n $scope.compareChange = (e, product) => {\r\n if (e) e.preventDefault();\r\n\r\n // Log a compare\r\n const $lng = $('#lng');\r\n if ($lng.length > 0) {\r\n productComparisonFactory.logCompare($lng.val());\r\n }\r\n\r\n if (!productComparisonFactory.compareSettings.ComparedProducts) {\r\n productComparisonFactory.compareSettings.ComparedProducts = [];\r\n }\r\n\r\n // Make an ajax call to unset it on the server for the user\r\n productComparisonFactory.compareChange(product.AgilityID).then(() => {\r\n const comparedAgilityIds = get(\r\n productComparisonFactory.compareSettings.ComparedProducts,\r\n 'AgilityID',\r\n );\r\n\r\n // Add/remove items from the array in the client (for speed) before we make an ajax call to the server to confirm the changes\r\n if (!product.IsCompared && includes(comparedAgilityIds, product.AgilityID)) {\r\n // If we're removing from the compare list, check if the item is in the list and remove it\r\n const index = comparedAgilityIds.indexOf(product.AgilityID);\r\n if (index > -1) {\r\n productComparisonFactory.compareSettings.ComparedProducts.splice(index, 1);\r\n }\r\n } else if (product.IsCompared && !includes(comparedAgilityIds, product.AgilityID)) {\r\n // If we're adding to the compare list, add the item\r\n productComparisonFactory.compareSettings.ComparedProducts.push(product);\r\n }\r\n\r\n // Then reset our local variables\r\n refreshCompareSettings();\r\n });\r\n };\r\n\r\n /**\r\n * Defines if the compare checkbox is visible or not\r\n */\r\n $scope.showCompareBox = product => {\r\n if (!productComparisonFactory.compareSettings) {\r\n return true;\r\n }\r\n\r\n if (!productComparisonFactory.compareSettings.ComparedProducts) {\r\n return true;\r\n }\r\n\r\n if (\r\n productComparisonFactory.compareSettings.ComparedProducts.length <\r\n productComparisonFactory.compareSettings.MaximumComparable\r\n ) {\r\n return true;\r\n }\r\n\r\n const comparedAgilityIds = get(\r\n productComparisonFactory.compareSettings.ComparedProducts,\r\n 'AgilityID',\r\n );\r\n if (includes(comparedAgilityIds, product.AgilityID)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n // Number of stars to show for each review\r\n $scope.numberOfStars = 5;\r\n\r\n /**\r\n * Gets the number of review stars to be populated for the chosen product\r\n */\r\n $scope.filledStars = product => {\r\n if (!product || product.DocumentRatingValue === 0 || product.DocumentRatings === 0) {\r\n return 0;\r\n }\r\n\r\n return Math.round(\r\n (product.DocumentRatingValue / product.DocumentRatings) * $scope.numberOfStars,\r\n );\r\n };\r\n\r\n $scope.$watch(\r\n () => getCompareSettingsWatch(),\r\n (newValue, oldValue) => {\r\n if (newValue !== oldValue) {\r\n const newComparedIds = get(newValue, 'AgilityID');\r\n\r\n productListFactory.products = productListFactory.products.forEach(p => {\r\n if (includes(newComparedIds, p.AgilityID)) {\r\n p.IsCompared = true;\r\n } else {\r\n p.IsCompared = false;\r\n }\r\n });\r\n }\r\n },\r\n );\r\n\r\n function getCompareSettingsWatch() {\r\n return productComparisonFactory.compareSettings\r\n ? productComparisonFactory.compareSettings.ComparedProducts\r\n : null;\r\n }\r\n}\r\n","/* eslint-disable max-len */\r\nexport default /* @ngInject */ (appSettings) => {\r\n const self = {\r\n link,\r\n restrict: 'A',\r\n scope: {\r\n controller: '=netcScrollMagic',\r\n options: '=?netcScrollMagicOptions',\r\n scene: '=?netcScrollMagicScene',\r\n\r\n // Events\r\n enter: '=?netcScrollMagicOnenter',\r\n end: '=?netcScrollMagicOnend',\r\n leave: '=?netcScrollMagicOnleave',\r\n start: '=?netcScrollMagicOnstart',\r\n },\r\n };\r\n\r\n return self;\r\n\r\n function link(scope, element) {\r\n require.ensure(['scrollmagic-core', 'scrollmagic-gsap'], () => {\r\n const ScrollMagic = require('scrollmagic-core');\r\n require('scrollmagic-gsap');\r\n\r\n // Ensure controller exists.\r\n if (scope.controller == null) {\r\n scope.controller = new ScrollMagic.Controller();\r\n }\r\n\r\n // Create scene and add to controller.\r\n const localOptions = scope.options;\r\n localOptions.triggerElement = element[0];\r\n scope.scene = new ScrollMagic.Scene(localOptions).addTo(scope.controller);\r\n\r\n // Add event handlers.\r\n if (scope.enter) scope.scene.on('enter', scope.enter);\r\n if (scope.end) scope.scene.on('end', scope.end);\r\n if (scope.leave) scope.scene.on('leave', scope.leave);\r\n if (scope.start) scope.scene.on('start', scope.start);\r\n\r\n // Add indicators in debug mode.\r\n if (appSettings.debugMode && scope.scene.addIndicators) scope.scene.addIndicators();\r\n });\r\n }\r\n};\r\n","import categorySeo from './categorySeo';\r\nimport fancyBox from './fancyBox';\r\nimport filterExpand from './filterExpand';\r\nimport gridSize from './gridSize';\r\nimport isotopeGrid from './isotopeGrid';\r\nimport productList from './productList';\r\nimport productItem from './productItem';\r\nimport scrollBar from './scrollBar';\r\nimport scrollMagic from './scrollMagic';\r\n\r\n\r\nconst module = angular.module('ryobi.directives', [])\r\n .directive('categorySeo', categorySeo)\r\n .directive('netcFancyBox', fancyBox)\r\n .directive('netcFilterExpand', filterExpand)\r\n .directive('gridSize', gridSize)\r\n .directive('isotopeGrid', isotopeGrid)\r\n .directive('productItem', productItem)\r\n .directive('productList', productList)\r\n .directive('scrollBar', scrollBar)\r\n .directive('netcScrollMagic', scrollMagic);\r\n\r\nexport default module;\r\n","/* eslint-disable max-len */\r\nimport fancybox from 'modules/fancybox'; // eslint-disable-line\r\n\r\nexport default /* @ngInject */ () => {\r\n const self = {\r\n link,\r\n restrict: 'A',\r\n scope: {\r\n applyFancybox: '=',\r\n },\r\n };\r\n\r\n function link(scope, element, attributes) {\r\n const href = attributes.ngHref || attributes.href;\r\n\r\n if (href && href.indexOf('youtube') > -1) {\r\n fancybox.applyFancyBoxVideo(element);\r\n\r\n // Check if the video needs to be auto-played once the template has rendered.\r\n setTimeout(() => {\r\n fancybox.autoPlayVideo(element);\r\n }, 0);\r\n }\r\n }\r\n\r\n return self;\r\n};\r\n","/* eslint-disable max-len */\r\nimport 'isotope-layout';\r\nimport 'isotope-packery';\r\n\r\n// Taken from https://github.com/diego-vieira/ng-isotope\r\n// The original didn't appear to $inject $timeout\r\n\r\nexport default /* @ngInject */ ($timeout) => {\r\n const directive = {\r\n replace: true,\r\n controllerAs: 'vm',\r\n restrict: 'A',\r\n scope: {\r\n items: '=isotopeGrid',\r\n },\r\n link(scope, element, attrs) {\r\n const options = {\r\n itemSelector: '.iso-grid--item',\r\n layoutMode: 'packery',\r\n masonry: {\r\n columnWidth: 320,\r\n fitWidth: true,\r\n },\r\n };\r\n\r\n element.isotope(options);\r\n\r\n scope.$watch('items', () => {\r\n $timeout(() => {\r\n element.isotope('reloadItems').isotope(options);\r\n });\r\n }, true);\r\n\r\n\r\n if (typeof attrs.isotopeReloadEvent !== 'undefined') {\r\n scope.$on(attrs.isotopeReloadEvent, () => {\r\n $timeout(() => {\r\n element.isotope('reloadItems').isotope(options);\r\n });\r\n });\r\n }\r\n },\r\n };\r\n\r\n return directive;\r\n};\r\n","/* eslint-disable max-len */\r\nimport 'jquery-mousewheel';\r\nimport 'malihu-custom-scrollbar-plugin';\r\n\r\nexport default /* @ngInject */ () => {\r\n const self = {\r\n restrict: 'A',\r\n link,\r\n scope: {},\r\n };\r\n\r\n function link(scope, element) {\r\n element.mCustomScrollbar({ alwaysShowScrollbar: 1 });\r\n }\r\n\r\n return self;\r\n};\r\n","import categoryFilter from './categoryFilter';\r\nimport productTabsCategoryFilter from './productTabsCategoryFilter';\r\n\r\nconst module = angular.module('ryobi.filters', [])\r\n .filter('Category', categoryFilter)\r\n .filter('ProductTabsCategory', productTabsCategoryFilter);\r\n\r\nexport default module;\r\n","import every from 'lodash/every';\r\nimport filter from 'lodash/filter';\r\nimport get from 'lodash/get';\r\nimport includes from 'lodash/includes';\r\n\r\nexport default /* @ngInject */ () => (items, categories) => {\r\n // If we've selected a category filter, then filter the list\r\n if (categories) {\r\n // Get the category names from the chosen categories\r\n let selectedCategoryNames = get(categories, 'CategoryDisplayName');\r\n\r\n // Filter out any null values\r\n selectedCategoryNames = filter(selectedCategoryNames, x => x);\r\n\r\n if (selectedCategoryNames.length > 0) {\r\n // Filter the items\r\n items = items.filter((n) => {\r\n const currentCategoryNames = n.Categories;\r\n\r\n // Returns true if all of the filters match an item\r\n return every(selectedCategoryNames, (catName) => {\r\n if (catName) {\r\n return includes(currentCategoryNames, catName);\r\n }\r\n\r\n return false;\r\n });\r\n });\r\n }\r\n }\r\n\r\n return items;\r\n};\r\n","import includes from 'lodash/includes';\r\n\r\nexport default /* @ngInject */ () => (items, selectedCategory) => {\r\n const filteredItems = [];\r\n\r\n // If we've selected a category filter, then filter the list\r\n if (selectedCategory) {\r\n angular.forEach(items, (value) => {\r\n if (includes(value.Category, selectedCategory)) {\r\n filteredItems.push(value);\r\n }\r\n });\r\n } else {\r\n return items;\r\n }\r\n\r\n return filteredItems;\r\n};\r\n","/** Kentico ngTranslate localisation factory. */\r\nconst KenticoLocalisationFactory = /* @ngInject */ $http => (options) => {\r\n const cultureCode = options.key;\r\n const key = `localisations-${cultureCode}`;\r\n\r\n return getStorage(key).then(\r\n localisations => localisations,\r\n () => {\r\n const params = {\r\n defaultCulture: 'en-US',\r\n };\r\n\r\n return $http.get(`/api/localisation/${cultureCode}`, { params }).then(\r\n (res) => {\r\n const localisations = res.data;\r\n return setStorage(key, localisations).then(\r\n () => localisations,\r\n () => localisations,\r\n );\r\n },\r\n () => Promise.reject(),\r\n );\r\n },\r\n );\r\n};\r\n\r\n/** Get value from storage. */\r\nfunction getStorage(key) {\r\n try {\r\n if (typeof Storage === 'undefined') {\r\n return Promise.reject();\r\n }\r\n\r\n if (!sessionStorage[key]) {\r\n return Promise.reject();\r\n }\r\n\r\n const json = sessionStorage[key];\r\n const localisations = JSON.parse(json);\r\n return Promise.resolve(localisations);\r\n } catch (e) {\r\n return Promise.reject();\r\n }\r\n}\r\n\r\n/** Set value in storage. */\r\nfunction setStorage(key, value) {\r\n try {\r\n if (typeof Storage === 'undefined') {\r\n return Promise.reject();\r\n }\r\n\r\n sessionStorage[key] = JSON.stringify(value);\r\n return Promise.resolve(value);\r\n } catch (e) {\r\n return Promise.reject();\r\n }\r\n}\r\n\r\nexport default KenticoLocalisationFactory;\r\n","import localisationFactory from './localisation.factory';\r\n\r\nexport default angular.module('ryobi.localisation', ['pascalprecht.translate'])\r\n .factory('localisationFactory', localisationFactory)\r\n .config(configureModule);\r\n\r\n/* @ngInject */\r\nfunction configureModule($translateProvider) {\r\n const defaultCulture = document.getElementById('lng').value;\r\n $translateProvider.preferredLanguage(defaultCulture);\r\n $translateProvider.useSanitizeValueStrategy('sanitizeParameters');\r\n $translateProvider.useLoaderCache(true);\r\n $translateProvider.useLoader('localisationFactory');\r\n}\r\n","export default /* @ngInject */ ($locationProvider, $stateProvider, $urlRouterProvider) => {\r\n const $blogPostList = $('.blog-list');\r\n\r\n if (!$blogPostList.length) {\r\n return;\r\n }\r\n\r\n $stateProvider.state('blog', {\r\n controller: 'BlogController',\r\n templateUrl: 'blog-list.html',\r\n url: '/{pageid:int}?{category:string}&{search:string}',\r\n });\r\n\r\n $urlRouterProvider.otherwise('/1');\r\n};\r\n","export default /* @ngInject */ ($locationProvider, $stateProvider, $urlRouterProvider) => {\r\n const $faqList = $('.faq-list');\r\n\r\n if (!$faqList.length) {\r\n return;\r\n }\r\n\r\n $stateProvider.state('faqList', {\r\n views: {\r\n 'faq-list': {\r\n templateUrl: 'faq-list.html',\r\n controller: 'FaqsController',\r\n },\r\n 'faq-filter': {\r\n templateUrl: 'faq-filter.html',\r\n controller: 'FaqsController',\r\n },\r\n },\r\n url: '/{category:string}?{search:string}',\r\n });\r\n\r\n $urlRouterProvider.otherwise('/');\r\n};\r\n","export default /* @ngInject */ ($locationProvider, $stateProvider, $urlRouterProvider) => {\r\n const $insightsList = $('.insights-list');\r\n\r\n if (!$insightsList.length) {\r\n return;\r\n }\r\n\r\n $stateProvider.state('insightsList', {\r\n views: {\r\n 'insights-list': {\r\n templateUrl: 'insights-list.html',\r\n controller: 'InsightsController',\r\n },\r\n 'insights-filter': {\r\n templateUrl: 'insights-filter.html',\r\n controller: 'InsightsController',\r\n },\r\n },\r\n url: '/{pageid:int}?{category:string}?{videos:bool}',\r\n });\r\n\r\n $urlRouterProvider.otherwise('/1');\r\n};\r\n","export default /* @ngInject */ ($locationProvider, $stateProvider, $urlRouterProvider) => {\r\n const $cordlessList = $('.cordless__product-display--content');\r\n const $productList = $('.js-product-list');\r\n const $productCodeFilter = $('.product-code-filter');\r\n\r\n if ($cordlessList.length) {\r\n return;\r\n }\r\n\r\n if (!$productList.length) {\r\n return;\r\n }\r\n\r\n if ($productCodeFilter.length) {\r\n $stateProvider.state('productList', {\r\n resolve: {\r\n productFilters: /* @ngInject */ productListFactory => productListFactory.getFilters(),\r\n routeProxy: /* @ngInject */ productListFactory => productListFactory.getRouteProxy(),\r\n },\r\n views: {\r\n 'product-list': {\r\n templateUrl: 'product-list.html',\r\n controller: 'ProductListController',\r\n },\r\n 'product-filter': {\r\n templateUrl: 'product-filter.html',\r\n controller: 'ProductListController',\r\n },\r\n 'product-code-filter': {\r\n templateUrl: 'product-code-filter.html',\r\n controller: 'ProductListController',\r\n },\r\n },\r\n // eslint-disable-next-line max-len\r\n url: '/{pageid:int}?{category:string}&{powersource:string}&{status:string}&{batteries:string}&{productcode:string}',\r\n });\r\n } else {\r\n $stateProvider.state('productList', {\r\n resolve: {\r\n productFilters: /* @ngInject */ productListFactory => productListFactory.getFilters(),\r\n routeProxy: /* @ngInject */ productListFactory => productListFactory.getRouteProxy(),\r\n },\r\n views: {\r\n 'product-list': {\r\n templateUrl: 'product-list.html',\r\n controller: 'ProductListController',\r\n },\r\n 'product-filter': {\r\n templateUrl: 'product-filter.html',\r\n controller: 'ProductListController',\r\n },\r\n },\r\n // eslint-disable-next-line max-len\r\n url: '/{pageid:int}?{category:string}&{powersource:string}&{status:string}&{batteries:string}&{productcode:string}&{groupedAll:string}&{unknown1:string}&{unknown2:string}&{unknown3:string}',\r\n });\r\n }\r\n\r\n $urlRouterProvider.otherwise('/1');\r\n};\r\n","export default /* @ngInject */ ($locationProvider, $stateProvider, $urlRouterProvider) => {\r\n const $supportArticlesList = $('.support-articles-list');\r\n\r\n if (!$supportArticlesList.length) {\r\n return;\r\n }\r\n\r\n $stateProvider.state('supportArticlesList', {\r\n views: {\r\n 'support-articles-list': {\r\n templateUrl: 'support-articles-list.html',\r\n controller: 'SupportController',\r\n },\r\n 'support-categories': {\r\n templateUrl: 'support-categories.html',\r\n controller: 'SupportController',\r\n },\r\n },\r\n url: '/{category:string}',\r\n });\r\n\r\n $urlRouterProvider.otherwise('/');\r\n};\r\n","export default /* @ngInject */ ($locationProvider, $stateProvider, $urlRouterProvider) => {\r\n const $videoList = $('.video-list');\r\n const $videoFilters = $('.video-filters');\r\n\r\n if (!$videoList.length) {\r\n return;\r\n }\r\n\r\n if ($videoFilters.length) {\r\n $stateProvider.state('videoList', {\r\n views: {\r\n 'video-list': {\r\n templateUrl: 'video-list.html',\r\n controller: 'VideoListController',\r\n },\r\n 'video-filter': {\r\n templateUrl: 'video-filter.html',\r\n controller: 'VideoListController',\r\n },\r\n },\r\n url: '/{pageid:int}?{category:string}',\r\n });\r\n\r\n $urlRouterProvider.otherwise('/1');\r\n } else {\r\n $stateProvider.state('videoList', {\r\n views: {\r\n 'video-list': {\r\n templateUrl: 'video-list.html',\r\n controller: 'VideoListController',\r\n },\r\n },\r\n url: '/{pageid:int}?{category:string}',\r\n });\r\n\r\n $urlRouterProvider.otherwise('/1');\r\n }\r\n};\r\n","import blogRoute from './blog';\r\nimport faqListRoute from './faqList';\r\nimport insightsListRoute from './insightsList';\r\nimport productListRoute from './productList';\r\nimport supportArticlesListRoute from './supportArticlesList';\r\nimport videoListRoute from './videoList';\r\n\r\nconst module = angular.module('ryobi.routes', [])\r\n .config(blogRoute)\r\n .config(faqListRoute)\r\n .config(insightsListRoute)\r\n .config(productListRoute)\r\n .config(supportArticlesListRoute)\r\n .config(videoListRoute);\r\n\r\nexport default module;\r\n","const blogFactory = /* @ngInject */ ($filter, $http, $q) => {\r\n const self = {};\r\n\r\n self.blogPosts = [];\r\n\r\n self.getBlogPosts = () => {\r\n const deferred = $q.defer();\r\n\r\n if (self.blogPosts.length) {\r\n deferred.resolve(self.blogPosts);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/blog/posts/', { params }).then(\r\n (res) => {\r\n self.blogPosts = res.data;\r\n deferred.resolve(res.data);\r\n },\r\n (err) => {\r\n deferred.reject(err);\r\n },\r\n );\r\n }\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.getCategories = () => {\r\n const deferred = $q.defer();\r\n\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/blog/categories/', { params }).then(\r\n (res) => {\r\n deferred.resolve(res.data);\r\n },\r\n (err) => {\r\n deferred.reject(err);\r\n },\r\n );\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.search = (searchQuery) => {\r\n if (!searchQuery || searchQuery.length <= 0) {\r\n return self.getBlogPosts();\r\n }\r\n\r\n const deferred = $q.defer();\r\n\r\n // Get query string parameters.\r\n const params = {\r\n url: location.pathname,\r\n loadSinglePage: true,\r\n searchText: searchQuery,\r\n searchIndex: 'BlogSearchIndex',\r\n };\r\n\r\n $http.get('/api/blog/search/', { params }).then(\r\n (res) => {\r\n deferred.resolve(res.data);\r\n },\r\n (err) => {\r\n deferred.reject(err);\r\n },\r\n );\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.getFilteredItems = (filters) => {\r\n const deferred = $q.defer();\r\n\r\n self.search(filters.searchQuery).then((data) => {\r\n let filteredItems = data;\r\n\r\n filteredItems = $filter('Category')(filteredItems, filters.categories, 0);\r\n\r\n deferred.resolve(filteredItems);\r\n });\r\n\r\n return deferred.promise;\r\n };\r\n\r\n return self;\r\n};\r\n\r\nexport default blogFactory;\r\n","const categoryFactory = /* @ngInject */ ($filter, $http, $q, storageFactory) => {\r\n const self = {\r\n getCategorySeo,\r\n };\r\n\r\n storageFactory.setSessionItem('categorySeoList', []);\r\n\r\n function getCategorySeo(categoryName) {\r\n const deferred = $q.defer();\r\n\r\n // If no category, return null\r\n if (!categoryName || categoryName.length <= 0) {\r\n deferred.resolve(null);\r\n return deferred.promise;\r\n }\r\n\r\n let categorySeoList;\r\n\r\n // If we have this item in session storage already, return it\r\n const sessionSeoList = storageFactory.getSessionItem('categorySeoList');\r\n\r\n if (sessionSeoList && sessionSeoList.length > 0) {\r\n categorySeoList = JSON.parse(sessionSeoList);\r\n\r\n if (categorySeoList !== null && categoryName in categorySeoList) {\r\n deferred.resolve(categorySeoList[categoryName]);\r\n return deferred.promise;\r\n }\r\n }\r\n\r\n const params = {\r\n categoryName,\r\n };\r\n\r\n $http.get('/api/productcategory/categoryseo/', { params }).then(\r\n (res) => {\r\n if (!categorySeoList) {\r\n categorySeoList = {};\r\n }\r\n\r\n // Store it back into the session\r\n categorySeoList[categoryName] = res.data;\r\n storageFactory.setSessionItem('categorySeoList', JSON.stringify(categorySeoList));\r\n\r\n deferred.resolve(res.data);\r\n },\r\n (err) => {\r\n deferred.reject(err);\r\n },\r\n );\r\n\r\n return deferred.promise;\r\n }\r\n\r\n return self;\r\n};\r\n\r\nexport default categoryFactory;\r\n","import filter from 'lodash/filter';\r\nimport find from 'lodash/find';\r\n\r\nconst FaqsFactory = /* @ngInject */ ($filter, $http, $state, $stateParams, $q, loadingBar) => {\r\n let getAllFaqsDefer;\r\n let getAllCategoriesDefer;\r\n\r\n let allFaqs = [];\r\n\r\n const self = {};\r\n self.allCategories = [];\r\n self.filteredItems = [];\r\n self.filters = {};\r\n\r\n /**\r\n * Filters the FAQs to be displayed on the page\r\n */\r\n self.getFilteredItems = () => {\r\n const deferred = $q.defer();\r\n\r\n getCategories()\r\n .then(() => {\r\n searchFaqs(self.filters.searchQuery)\r\n .then((data) => {\r\n // Add a loading bar to make it appear that something's happened\r\n loadingBar.addLoadingBar();\r\n\r\n let filteredItems = data.data;\r\n\r\n const filters = self.filters;\r\n\r\n // Get the selected category - if one isn't set, then it's null (show all)\r\n const selectedCategory = filters.selectedCategory;\r\n\r\n if (selectedCategory) {\r\n filteredItems = filter(filteredItems,\r\n faq => faq.NodeParentId === selectedCategory.NodeId,\r\n );\r\n }\r\n\r\n filters.selectedCategory = selectedCategory;\r\n\r\n setStateParameters();\r\n self.filteredItems = filteredItems;\r\n deferred.resolve(filteredItems);\r\n });\r\n });\r\n\r\n return deferred.promise;\r\n };\r\n\r\n function searchFaqs(searchQuery) {\r\n if (!searchQuery || searchQuery.length <= 0) {\r\n return getAllFaqs();\r\n }\r\n\r\n const deferred = $q.defer();\r\n\r\n // Get query string parameters.\r\n const params = {\r\n url: location.pathname,\r\n loadSinglePage: true,\r\n searchText: searchQuery,\r\n searchIndex: 'FaqSearchIndex',\r\n };\r\n\r\n $http.get('/api/faqs/search/', { params }).then(\r\n (data) => {\r\n deferred.resolve(data);\r\n },\r\n (data) => {\r\n deferred.reject(data);\r\n },\r\n );\r\n\r\n return deferred.promise;\r\n }\r\n\r\n function getAllFaqs() {\r\n if (getAllFaqsDefer) {\r\n return getAllFaqsDefer.promise;\r\n }\r\n\r\n getAllFaqsDefer = $q.defer();\r\n\r\n if (allFaqs.length) {\r\n getAllFaqsDefer.resolve(allFaqs);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/faqs/', { params }).then(\r\n (data) => {\r\n allFaqs = data;\r\n getAllFaqsDefer.resolve(data);\r\n },\r\n (data) => {\r\n getAllFaqsDefer.reject(data);\r\n },\r\n );\r\n }\r\n\r\n return getAllFaqsDefer.promise;\r\n }\r\n\r\n function getCategories() {\r\n if (getAllCategoriesDefer) {\r\n return getAllCategoriesDefer.promise;\r\n }\r\n\r\n getAllCategoriesDefer = $q.defer();\r\n\r\n if (self.allCategories.length) {\r\n getAllCategoriesDefer.resolve(self.allCategories);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/faqs/categories/', { params }).then(\r\n (data) => {\r\n self.allCategories = data;\r\n getAllCategoriesDefer.resolve(data);\r\n },\r\n (data) => {\r\n getAllCategoriesDefer.reject(data);\r\n },\r\n );\r\n }\r\n\r\n return getAllCategoriesDefer.promise;\r\n }\r\n\r\n /**\r\n * Sets the state parameters based on the pagination and filter objects.\r\n * @private\r\n */\r\n function setStateParameters() {\r\n const stateParameters = {};\r\n\r\n const filters = self.filters;\r\n if (filters) {\r\n if (filters.selectedCategory) {\r\n stateParameters.category = filters.selectedCategory.Title;\r\n }\r\n\r\n if (filters.searchQuery && filters.searchQuery.length) {\r\n stateParameters.search = filters.searchQuery;\r\n }\r\n }\r\n\r\n $state.go($state.current.name, stateParameters, {\r\n location: 'replace',\r\n inherit: false,\r\n notify: false,\r\n });\r\n }\r\n\r\n self.filters.searchQuery = $stateParams.search || null;\r\n\r\n // Initialisation: Save all categories\r\n getCategories().then((data) => {\r\n // If we have a category state selected, find that category object and store it\r\n self.filters.selectedCategory = find(\r\n data,\r\n category => category.Title === $stateParams.category,\r\n );\r\n\r\n // Then filter the list of all FAQs\r\n self.getFilteredItems();\r\n });\r\n\r\n return self;\r\n};\r\n\r\nexport default FaqsFactory;\r\n","import filter from 'lodash/filter';\r\n\r\nconst insightsFactory = /* @ngInject */ ($filter, $http, $q) => {\r\n let getAllInsightsDefer;\r\n let getAllCategoriesDefer;\r\n\r\n const self = {};\r\n\r\n /** Pagination options. */\r\n self.pagination = {\r\n pageid: 1,\r\n itemsPerPage: 8,\r\n };\r\n\r\n self.allInsights = [];\r\n self.allCategories = [];\r\n self.pagedItems = [];\r\n self.filteredItems = [];\r\n\r\n self.getInsights = () => {\r\n if (getAllInsightsDefer) {\r\n return getAllInsightsDefer.promise;\r\n }\r\n\r\n getAllInsightsDefer = $q.defer();\r\n\r\n if (self.allInsights.length) {\r\n getAllInsightsDefer.resolve(self.allInsights);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/insights/', { params }).then(\r\n (res) => {\r\n self.allInsights = res.data;\r\n getAllInsightsDefer.resolve(res.data);\r\n },\r\n (err) => {\r\n getAllInsightsDefer.reject(err);\r\n },\r\n );\r\n }\r\n\r\n return getAllInsightsDefer.promise;\r\n };\r\n\r\n self.setFilteredItems = () => {\r\n const defer = $q.defer();\r\n\r\n self.getInsights().then((data) => {\r\n self.filteredItems = [];\r\n self.setPagedItems();\r\n let filteredItems = data;\r\n\r\n const filters = self.filters;\r\n if (filters) {\r\n filteredItems = $filter('Category')(filteredItems, filters.categories, 0);\r\n\r\n if (filters.videos) {\r\n filteredItems = filter(filteredItems, insight => insight.HasVideo);\r\n }\r\n }\r\n\r\n self.filteredItems = filteredItems;\r\n self.setPagedItems();\r\n\r\n defer.resolve(self.filteredItems);\r\n });\r\n\r\n return defer.promise;\r\n };\r\n\r\n self.setPagedItems = () => {\r\n const defer = $q.defer();\r\n self.pagedItems = $filter('limitTo')(self.filteredItems, self.pagesize(), 0);\r\n defer.resolve(self.pagedItems);\r\n return defer.promise;\r\n };\r\n\r\n self.getAllCategories = () => {\r\n if (getAllCategoriesDefer) {\r\n return getAllCategoriesDefer.promise;\r\n }\r\n\r\n getAllCategoriesDefer = $q.defer();\r\n\r\n if (self.allCategories.length) {\r\n getAllCategoriesDefer.resolve(self.allCategories);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/insights/Categories/', { params }).then(\r\n (res) => {\r\n self.allCategories = res.data;\r\n getAllCategoriesDefer.resolve(res.data);\r\n },\r\n (err) => {\r\n getAllCategoriesDefer.reject(err);\r\n },\r\n );\r\n }\r\n\r\n return getAllCategoriesDefer.promise;\r\n };\r\n\r\n /**\r\n * Returns the current page size\r\n */\r\n self.pagesize = () => (\r\n self.pagination.itemsPerPage * self.pagination.pageid\r\n );\r\n\r\n return self;\r\n};\r\n\r\nexport default insightsFactory;\r\n","const LoadingBar = /* @ngInject */ (cfpLoadingBar) => {\r\n const self = {};\r\n\r\n self.addLoadingBar = () => {\r\n cfpLoadingBar.start();\r\n setTimeout(() => {\r\n cfpLoadingBar.complete();\r\n }, 500);\r\n };\r\n\r\n return self;\r\n};\r\n\r\nexport default LoadingBar;\r\n","const productComparisonFactory = /* @ngInject */ ($filter, $http, $q) => {\r\n const self = {};\r\n\r\n self.compareChange = (agilityId) => {\r\n const deferred = $q.defer();\r\n\r\n const params = {\r\n agilityId,\r\n };\r\n\r\n $http.get('/api/product/compareChange/', { params }).then(\r\n (data) => {\r\n deferred.resolve(data);\r\n },\r\n (data) => {\r\n deferred.reject(data);\r\n },\r\n );\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.removeAllComparisons = () => {\r\n const deferred = $q.defer();\r\n\r\n $http.get('/api/product/removeAllComparisons/').then(\r\n (res) => {\r\n deferred.resolve(res.data);\r\n },\r\n (err) => {\r\n deferred.reject(err);\r\n },\r\n );\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.getCompareSettings = () => {\r\n const deferred = $q.defer();\r\n\r\n $http.get('/api/product/compareSettings/').then(\r\n (res) => {\r\n self.compareSettings = res.data;\r\n deferred.resolve(res.data);\r\n },\r\n (err) => {\r\n deferred.reject(err);\r\n },\r\n );\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.logCompare = (cultureCode) => {\r\n const deffered = $q.defer();\r\n const params = {\r\n cultureCode,\r\n };\r\n\r\n $http.get('/api/analytics/logcompare/', { params }).then(\r\n () => {},\r\n (err) => {\r\n deffered.reject(err);\r\n },\r\n );\r\n\r\n return deffered.promise;\r\n };\r\n\r\n // Initialise\r\n self.getCompareSettings();\r\n\r\n return self;\r\n};\r\n\r\nexport default productComparisonFactory;\r\n","import filter from 'lodash/filter';\r\nimport some from 'lodash/some';\r\n\r\nconst ProductListFactory = /* @ngInject */ ($filter, $http, $q, storageFactory) => {\r\n const self = {};\r\n\r\n self.products = {};\r\n\r\n self.loaded = false;\r\n\r\n // Links to other categories\r\n self.categoryTypes = null;\r\n\r\n // A list of filtered products\r\n self.filteredItems = null;\r\n\r\n // The filters that have been chosen\r\n self.selectedFilters = null;\r\n\r\n // The filters to display\r\n let filters;\r\n\r\n self.getFilters = () => {\r\n const deferred = $q.defer();\r\n const pageUrl = self.getRouteProxy();\r\n const proxyFilters = self.getProxyFilters();\r\n const additionalFilters = self.getAdditionalFilters();\r\n const groupedFilters = self.getGroupedFilters();\r\n\r\n if (filters) {\r\n deferred.resolve(filters);\r\n return deferred.promise;\r\n }\r\n\r\n const params = {\r\n url: pageUrl,\r\n additionalFilters: [...additionalFilters],\r\n cultureCode: $('#lng').val(),\r\n ...proxyFilters.overrides,\r\n groupedFilters: [...groupedFilters],\r\n };\r\n\r\n $http.post('/api/productcategory/filters/', { ...params }).then(\r\n (res) => {\r\n filters = { ...res.data, ...proxyFilters };\r\n Object.keys(proxyFilters.overrides).forEach((key) => {\r\n filters[key] = proxyFilters.overrides[key];\r\n });\r\n filters.url = self.getRouteProxy();\r\n deferred.resolve(filters);\r\n },\r\n (err) => {\r\n deferred.reject(err);\r\n },\r\n );\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.getProducts = (filterParams) => {\r\n const deferred = $q.defer();\r\n let key = '';\r\n const proxyFilters = self.getProxyFilters();\r\n const groupedFilters = self.getGroupedFilters();\r\n\r\n // Set grouped filter stuff\r\n if (filterParams.GroupedAll) {\r\n for (let i = 0; i < groupedFilters.length; i += 1) {\r\n if (groupedFilters[i].agilityId === filterParams.GroupedAll) {\r\n groupedFilters[i].selected = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n let searchCode = '';\r\n if (filterParams) {\r\n searchCode = filterParams.productcode;\r\n }\r\n\r\n if (filterParams.category !== undefined && filterParams.category !== null) {\r\n key = `productList|${filterParams.category.Url}`;\r\n } else {\r\n key = 'productList|All';\r\n }\r\n\r\n const sessionList = storageFactory.getSessionItem(key);\r\n if (sessionList && sessionList.length > 0) {\r\n const productList = JSON.parse(sessionList);\r\n deferred.resolve(productList);\r\n } else if (self.products[key]) {\r\n deferred.resolve(self.products[key]);\r\n } else {\r\n const params = {\r\n url: self.getRouteProxy(filterParams.ignoreUrl),\r\n productCode: searchCode,\r\n agilityIds: filterParams.agilityIds,\r\n cultureCode: $('#lng').val(),\r\n ...proxyFilters.overrides,\r\n groupedFilters: [...groupedFilters],\r\n };\r\n\r\n params.additionalFilters = self.getAdditionalFilters();\r\n for (let i = 1; i <= 3; i += 1) {\r\n if (filterParams[`unknown${i}`]) {\r\n if (params.additionalFilters.length >= i - 1) {\r\n params.additionalFilters[i - 1].selectedValue = filterParams[`unknown${i}`];\r\n }\r\n }\r\n }\r\n\r\n if (filterParams.category !== undefined && filterParams.category !== null) {\r\n params.url = filterParams.category.Url;\r\n }\r\n\r\n $http.post('/api/productcategory/productspost/', params).then(\r\n (res) => {\r\n // storageFactory.setSessionItem(key, JSON.stringify(res.data));\r\n deferred.resolve(res.data);\r\n },\r\n (err) => {\r\n deferred.reject(err);\r\n },\r\n );\r\n }\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.getRouteProxy = (ignoreAll) => {\r\n const value = angular.element('.js-listing-proxy').val();\r\n\r\n if (ignoreAll === true) {\r\n return '/';\r\n }\r\n\r\n if (value !== null && value !== '' && value !== undefined) {\r\n return value;\r\n }\r\n\r\n return location.pathname;\r\n };\r\n\r\n self.getProxyFilters = () => {\r\n const value = angular.element('.js-listing-filters').val();\r\n\r\n if (value !== null && value !== '' && value !== undefined) {\r\n return JSON.parse(value);\r\n }\r\n\r\n return {\r\n filterFunctionalityOverrides: [],\r\n hiddenFilters: [],\r\n overrides: { },\r\n };\r\n };\r\n\r\n self.getGroupedFilters = () => {\r\n const value = angular.element('.js-listing-grouped-filters').val();\r\n\r\n if (value !== null && value !== '' && value !== undefined) {\r\n return JSON.parse(value);\r\n }\r\n\r\n return {};\r\n };\r\n\r\n let deferredCategoryTypes;\r\n\r\n self.getCategoryTypes = () => {\r\n if (deferredCategoryTypes) {\r\n return deferredCategoryTypes.promise;\r\n }\r\n\r\n deferredCategoryTypes = $q.defer();\r\n\r\n if (self.categoryTypes) {\r\n deferredCategoryTypes.resolve(self.categoryTypes);\r\n } else {\r\n const params = {\r\n url: self.getRouteProxy(),\r\n };\r\n\r\n $http.get('/api/productcategory/CategoryTypes/', { params }).then(\r\n (res) => {\r\n self.categoryTypes = res.data;\r\n deferredCategoryTypes.resolve(res.data);\r\n },\r\n (err) => {\r\n deferredCategoryTypes.reject(err);\r\n },\r\n );\r\n }\r\n\r\n return deferredCategoryTypes.promise;\r\n };\r\n\r\n self.getAdditionalFilters = () => {\r\n const value = angular.element('.js-listing-additional-filters').val();\r\n if (value !== null && value !== '' && value !== undefined) {\r\n return JSON.parse(value);\r\n }\r\n\r\n return {};\r\n };\r\n\r\n self.getFilteredItems = (filterParams) => {\r\n const deferred = $q.defer();\r\n\r\n self.getProducts(filterParams).then((data) => {\r\n let filteredItems = data;\r\n\r\n // Filter the items based on the selections\r\n if (filterParams) {\r\n // Filter any lists\r\n filteredItems = filterProducts(filteredItems, 'PowerSource', filterParams.powersource);\r\n filteredItems = filterProducts(filteredItems, 'Status', filterParams.status);\r\n\r\n // Filter by how many batteries a product has\r\n filteredItems = filter(filteredItems, (x) => {\r\n if (filterParams.batteries === 'true') {\r\n if (x.NumberOfBatteries > 0) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n if (filterParams.batteries === 'false') {\r\n if (x.NumberOfBatteries <= 0) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n }\r\n\r\n deferred.resolve(filteredItems);\r\n });\r\n\r\n return deferred.promise;\r\n };\r\n\r\n function filterProducts(items, fieldName, filterName) {\r\n if (filterName && filterName.length > 0) {\r\n const f = filterName.toUpperCase();\r\n\r\n items = filter(items, p => some(p[fieldName], (x) => {\r\n if (x.toUpperCase() === f) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }));\r\n }\r\n\r\n return items;\r\n }\r\n\r\n self.initialised = false;\r\n\r\n return self;\r\n};\r\n\r\nexport default ProductListFactory;\r\n","const storageFactory = /* @ngInject */ () => {\r\n const self = {\r\n getItem,\r\n getSessionItem,\r\n setItem,\r\n setSessionItem,\r\n };\r\n\r\n /** Get item from localstorage. */\r\n function getItem(key) {\r\n try {\r\n return localStorage.getItem(key);\r\n } catch (e) {\r\n return null;\r\n }\r\n }\r\n\r\n /** Set item in localstorage. */\r\n function setItem(key, data) {\r\n try {\r\n localStorage.setItem(key, data);\r\n return true;\r\n } catch (e) {\r\n return false;\r\n }\r\n }\r\n\r\n /** Get item from sessionstorage. */\r\n function getSessionItem(key) {\r\n try {\r\n return sessionStorage.getItem(key);\r\n } catch (e) {\r\n return null;\r\n }\r\n }\r\n\r\n /** Set item in sessionstorage. */\r\n function setSessionItem(key, data) {\r\n try {\r\n sessionStorage.setItem(key, data);\r\n return true;\r\n } catch (e) {\r\n return false;\r\n }\r\n }\r\n\r\n return self;\r\n};\r\n\r\nexport default storageFactory;\r\n","import filter from 'lodash/filter';\r\nimport find from 'lodash/find';\r\n\r\nconst supportFactory = /* @ngInject */ ($filter, $http, $state, $stateParams, $q, loadingBar) => {\r\n let getAllArticlesDefer;\r\n let getAllCategoriesDefer;\r\n\r\n let allArticles = [];\r\n\r\n const self = {};\r\n self.allCategories = [];\r\n self.filteredItems = [];\r\n\r\n self.filters = {};\r\n\r\n /**\r\n * Filters the articles to be displayed on the page\r\n */\r\n self.getFilteredItems = () => {\r\n const deferred = $q.defer();\r\n\r\n getCategories().then(() => {\r\n getAllArticles().then((data) => {\r\n // Add a loading bar to make it appear that something's happened\r\n loadingBar.addLoadingBar();\r\n\r\n let filteredItems = data;\r\n\r\n const filters = self.filters;\r\n\r\n // Get the selected category, using the first one if not set\r\n const selectedCategory = filters.selectedCategory || self.allCategories[0];\r\n\r\n if (selectedCategory) {\r\n filteredItems = filter(\r\n filteredItems,\r\n article => article.NodeParentId === selectedCategory.NodeId,\r\n );\r\n }\r\n\r\n filters.selectedCategory = selectedCategory;\r\n\r\n setStateParameters();\r\n self.filteredItems = filteredItems;\r\n deferred.resolve(filteredItems);\r\n });\r\n });\r\n\r\n return deferred.promise;\r\n };\r\n\r\n function getAllArticles() {\r\n if (getAllArticlesDefer) {\r\n return getAllArticlesDefer.promise;\r\n }\r\n\r\n getAllArticlesDefer = $q.defer();\r\n\r\n if (allArticles.length) {\r\n getAllArticlesDefer.resolve(allArticles);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/support/articles', { params }).then(\r\n (res) => {\r\n allArticles = res.data;\r\n getAllArticlesDefer.resolve(res.data);\r\n },\r\n (err) => {\r\n getAllArticlesDefer.reject(err);\r\n },\r\n );\r\n }\r\n\r\n return getAllArticlesDefer.promise;\r\n }\r\n\r\n function getCategories() {\r\n if (getAllCategoriesDefer) {\r\n return getAllCategoriesDefer.promise;\r\n }\r\n\r\n getAllCategoriesDefer = $q.defer();\r\n\r\n if (self.allCategories.length) {\r\n getAllCategoriesDefer.resolve(self.allCategories);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/support/categories/', { params }).then(\r\n (res) => {\r\n self.allCategories = res.data;\r\n getAllCategoriesDefer.resolve(res.data);\r\n },\r\n (err) => {\r\n getAllCategoriesDefer.reject(err);\r\n },\r\n );\r\n }\r\n\r\n return getAllCategoriesDefer.promise;\r\n }\r\n\r\n /**\r\n * Sets the state parameters based on the pagination and filter objects.\r\n * @private\r\n */\r\n function setStateParameters() {\r\n const stateParameters = {};\r\n\r\n const filters = self.filters;\r\n if (filters) {\r\n if (filters.selectedCategory) {\r\n stateParameters.category = filters.selectedCategory.Title;\r\n }\r\n }\r\n\r\n $state.go($state.current.name, stateParameters, {\r\n location: 'replace',\r\n inherit: false,\r\n notify: false,\r\n });\r\n }\r\n\r\n // Initialisation: Save all categories\r\n getCategories().then((data) => {\r\n // If we have a category state selected, find that category object and store it\r\n self.filters.selectedCategory = find(\r\n data,\r\n category => category.Title === $stateParams.category,\r\n );\r\n\r\n // Then filter the list of all articles\r\n self.getFilteredItems();\r\n });\r\n\r\n return self;\r\n};\r\n\r\nexport default supportFactory;\r\n","const videoListFactory = /* @ngInject */ ($filter, $http, $q) => {\r\n let getVideosDefer;\r\n let getAllCategoriesDefer;\r\n\r\n const self = {};\r\n\r\n /** Pagination options. */\r\n self.pagination = {\r\n pageid: 1,\r\n itemsPerPage: 6,\r\n };\r\n\r\n self.videos = [];\r\n self.filteredItems = [];\r\n\r\n self.getVideos = () => {\r\n if (getVideosDefer) {\r\n return getVideosDefer.promise;\r\n }\r\n\r\n getVideosDefer = $q.defer();\r\n\r\n if (self.videos.length) {\r\n getVideosDefer.resolve(self.videos);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n };\r\n\r\n $http.get('/api/video/', { params }).then(\r\n (res) => {\r\n self.videos = res.data;\r\n getVideosDefer.resolve(res.data);\r\n },\r\n (err) => {\r\n getVideosDefer.reject(err);\r\n },\r\n );\r\n }\r\n\r\n return getVideosDefer.promise;\r\n };\r\n\r\n /**\r\n * Filters the products to be displayed on the page\r\n */\r\n self.setFilteredItems = () => {\r\n const deferred = $q.defer();\r\n\r\n self.getVideos().then((data) => {\r\n let filteredItems = data;\r\n\r\n const filters = self.filters;\r\n\r\n if (filters) {\r\n filteredItems = $filter('Category')(filteredItems, filters.categories, 0);\r\n }\r\n\r\n self.filteredItems = filteredItems;\r\n deferred.resolve(filteredItems);\r\n });\r\n\r\n return deferred.promise;\r\n };\r\n\r\n self.getAllCategories = () => {\r\n if (getAllCategoriesDefer) {\r\n return getAllCategoriesDefer.promise;\r\n }\r\n\r\n getAllCategoriesDefer = $q.defer();\r\n\r\n if (self.allCategories) {\r\n getAllCategoriesDefer.resolve(self.allCategories);\r\n } else {\r\n const params = {\r\n url: location.pathname,\r\n culture: $('#lng').val(),\r\n };\r\n\r\n $http.get('/api/Video/Categories/', { params }).then(\r\n (data) => {\r\n self.allCategories = data;\r\n getAllCategoriesDefer.resolve(data);\r\n },\r\n (data) => {\r\n getAllCategoriesDefer.reject(data);\r\n },\r\n );\r\n }\r\n\r\n return getAllCategoriesDefer.promise;\r\n };\r\n\r\n return self;\r\n};\r\n\r\nexport default videoListFactory;\r\n","import blogFactory from './blogFactory';\r\nimport categoryFactory from './categoryFactory';\r\nimport faqsFactory from './faqsFactory';\r\nimport insightsFactory from './insightsFactory';\r\nimport loadingBar from './loadingBar';\r\nimport productComparisonFactory from './productComparisonFactory';\r\nimport productListFactory from './productListFactory';\r\nimport storageFactory from './storageFactory';\r\nimport supportFactory from './supportFactory';\r\nimport videoListFactory from './videoListFactory';\r\n\r\nconst module = angular.module('ryobi.services', [])\r\n .factory('blogFactory', blogFactory)\r\n .factory('categoryFactory', categoryFactory)\r\n .factory('faqsFactory', faqsFactory)\r\n .factory('insightsFactory', insightsFactory)\r\n .factory('loadingBar', loadingBar)\r\n .factory('productComparisonFactory', productComparisonFactory)\r\n .factory('productListFactory', productListFactory)\r\n .factory('storageFactory', storageFactory)\r\n .factory('supportFactory', supportFactory)\r\n .factory('videoListFactory', videoListFactory);\r\n\r\nexport default module;\r\n","export default class WTTRootController {\r\n /* @ngInject */\r\n constructor($log, $rootScope, $translate, WTTService) {\r\n this.$log = $log;\r\n this.wttService = WTTService;\r\n\r\n // Show content after translations have loaded.\r\n this.visible = $translate.isReady();\r\n $translate.onReady(() => {\r\n this.visible = true;\r\n });\r\n }\r\n $onInit() {\r\n const { $log, wttService } = this;\r\n\r\n try {\r\n const $initialData = angular.element('[id$=\"hdnWTTInitialData\"]');\r\n const initialData = JSON.parse($initialData.val());\r\n wttService.setFormData(initialData);\r\n } catch (err) {\r\n $log.error(err);\r\n }\r\n }\r\n}\r\n","import controller from './controller';\r\nimport template from './template.html';\r\n\r\nexport default {\r\n controller,\r\n template,\r\n};\r\n","/* eslint-disable no-useless-constructor */\r\nexport default class wttIntroController {\r\n /* @ngInject */\r\n constructor($state, WTTService) {\r\n // default\r\n this.wttService = WTTService;\r\n this.formData = this.wttService.formData;\r\n }\r\n}\r\n","import template from './template.html';\r\nimport controller from './controller';\r\n\r\nexport default {\r\n template,\r\n controller,\r\n};\r\n","export default class WTTGameController {\r\n /* @ngInject */\r\n constructor($state, WTTService) {\r\n this.$state = $state;\r\n this.wttService = WTTService;\r\n\r\n // Binding Content Editable Data to the scope\r\n this.formData = this.wttService.formData;\r\n }\r\n\r\n $onInit() {\r\n this.tileCount = 0;\r\n this.tileLimit = 3;\r\n }\r\n get showNavBar() {\r\n return (this.tileCount >= this.tileLimit);\r\n }\r\n onTileSelect($event) {\r\n if ((++this.tileCount) > this.tileLimit) { // eslint-disable-line\r\n return;\r\n }\r\n\r\n const $tile = angular.element($event.target);\r\n $tile.addClass('selected');\r\n }\r\n onSubmit($event, form, formData) {\r\n const { wttService, $state } = this;\r\n\r\n if ($event) {\r\n $event.preventDefault();\r\n }\r\n\r\n if (form.$invalid) {\r\n form.$setSubmitted();\r\n return;\r\n }\r\n\r\n wttService.setFormData(formData).then(\r\n () => wttService.setSubmission(formData).then(\r\n () => $state.go('wtt.more'),\r\n () => angular.noop,\r\n ),\r\n () => angular.noop,\r\n );\r\n }\r\n\r\n onTermsClick(val) {\r\n const termsToShow = angular.element(`.js-full-screen-popup[data-popup=\"wtt-terms-${val}\"]`);\r\n if (termsToShow.length) {\r\n angular.element('html').addClass('stop-scroll');\r\n angular.element('html').addClass('full-screen-popup-open');\r\n termsToShow.addClass('is-active');\r\n }\r\n }\r\n onTermsHideClick(val) {\r\n const termsToHide = angular.element(`.js-full-screen-popup[data-popup=\"wtt-terms-${val}\"]`);\r\n if (termsToHide.length) {\r\n angular.element('html').removeClass('stop-scroll');\r\n angular.element('html').removeClass('full-screen-popup-open');\r\n termsToHide.removeClass('is-active');\r\n }\r\n }\r\n}\r\n","import controller from './controller';\r\nimport template from './template.html';\r\n\r\nexport default {\r\n controller,\r\n template,\r\n};\r\n","export default class WTTSubmissionController {\r\n /* @ngInject */\r\n constructor($state, WTTService) {\r\n this.$state = $state;\r\n this.wttService = WTTService;\r\n this.formData = this.wttService.formData;\r\n }\r\n onSubmit($event, form, formData) {\r\n const { wttService, $state } = this;\r\n\r\n if ($event) {\r\n $event.preventDefault();\r\n }\r\n\r\n if (form.$invalid) {\r\n form.$setSubmitted();\r\n return;\r\n }\r\n\r\n wttService.setFormData(formData).then(\r\n () => wttService.setSubmission(formData).then(\r\n () => $state.go('wtt.more'),\r\n () => angular.noop,\r\n ),\r\n () => angular.noop,\r\n );\r\n }\r\n}\r\n","import controller from './controller';\r\nimport template from './template.html';\r\n\r\nexport default {\r\n controller,\r\n template,\r\n};\r\n","import template from './template.html';\r\n\r\nexport default {\r\n template,\r\n};\r\n","export default class WTTMoreController {\r\n /* @ngInject */\r\n constructor($state, WTTService) {\r\n this.$state = $state;\r\n this.wttService = WTTService;\r\n\r\n // Binding Content Editable Data to the scope\r\n this.formData = this.wttService.formData;\r\n }\r\n\r\n setQuestionAnswer($event) {\r\n const questionIndex = $event.questionIndex;\r\n const answerIndex = $event.answerIndex;\r\n\r\n const answers = this.formData.dynamicFormQuestions[questionIndex].answers;\r\n for (let i = 0; i < answers.length; i += 1) {\r\n if (i === answerIndex) {\r\n answers[i].isAnswered = true;\r\n } else {\r\n answers[i].isAnswered = false;\r\n }\r\n }\r\n }\r\n\r\n onSubmit() {\r\n this.wttService.setFormData(this.formData).then(\r\n () => this.wttService.setFinalStepData(this.formData.dynamicFormQuestions).then(\r\n () => this.$state.go('wtt.confirmation'),\r\n () => angular.noop,\r\n ),\r\n () => angular.noop,\r\n );\r\n }\r\n}\r\n","import controller from './controller';\r\nimport template from './template.html';\r\n\r\nexport default {\r\n template,\r\n controller,\r\n};\r\n","import template from './template.html';\r\n\r\nexport default {\r\n bindings: {\r\n onSubmit: '&',\r\n onTermsClick: '&',\r\n onTermsHideClick: '&',\r\n },\r\n template,\r\n};\r\n","/* eslint-disable no-useless-constructor */\r\nexport default class WTTImageGridController {\r\n /* @ngInject */\r\n constructor() {\r\n // default\r\n }\r\n get viewbox() {\r\n return `0 0 ${this.width} ${this.height}`;\r\n }\r\n $onChanges() {\r\n // Set tile dimensions - this are calculated as fractions of 1 for scaling.\r\n this.tileWidth = (1 / this.horizontal);\r\n this.tileHeight = (1 / this.vertical);\r\n\r\n // Create array of tiles.\r\n this.dividers = this.generateDividers();\r\n this.tiles = this.generateTiles();\r\n }\r\n generateDividers() {\r\n const dividers = [];\r\n\r\n // Vertical dividers.\r\n for (let x = 1; x < this.horizontal; x += 1) {\r\n const xPos = (x * this.tileWidth * 100);\r\n dividers.push({\r\n x1: `${xPos}%`,\r\n x2: `${xPos}%`,\r\n y1: '0%',\r\n y2: '100%',\r\n });\r\n }\r\n\r\n // Horizontal dividers.\r\n for (let y = 1; y < this.vertical; y += 1) {\r\n const yPos = (y * this.tileHeight * 100);\r\n dividers.push({\r\n x1: '0%',\r\n x2: '100%',\r\n y1: `${yPos}%`,\r\n y2: `${yPos}%`,\r\n });\r\n }\r\n\r\n return dividers;\r\n }\r\n generateTiles() {\r\n const tiles = [];\r\n\r\n for (let y = 0; y < this.vertical; y += 1) {\r\n for (let x = 0; x < this.horizontal; x += 1) {\r\n const xPos = (x * this.tileWidth);\r\n const yPos = (y * this.tileHeight);\r\n tiles.push({\r\n id: `${x}-${y}`,\r\n x: xPos,\r\n xPercent: `${xPos * 100}%`,\r\n y: yPos,\r\n yPercent: `${yPos * 100}%`,\r\n width: this.tileWidth,\r\n widthPercent: `${this.tileWidth * 100}%`,\r\n height: this.tileHeight,\r\n heightPercent: `${this.tileHeight * 100}%`,\r\n });\r\n }\r\n }\r\n\r\n return tiles;\r\n }\r\n}\r\n","import controller from './controller';\r\nimport template from './template.html';\r\n\r\nexport default {\r\n bindings: {\r\n onTileSelect: '&',\r\n width: '<',\r\n height: '<',\r\n horizontal: '<',\r\n vertical: '<',\r\n src: '<',\r\n },\r\n controller,\r\n template,\r\n};\r\n","/* eslint-disable no-useless-constructor */\r\nexport default class wttDynamicFormControl {\r\n /* @ngInject */\r\n constructor($state, WTTService) {\r\n // default\r\n this.wttService = WTTService;\r\n this.formData = this.wttService.formData;\r\n }\r\n}\r\n","import controller from './controller';\r\nimport template from './template.html';\r\n\r\nexport default {\r\n bindings: {\r\n question: '<',\r\n answer: '<',\r\n questionIndex: '<',\r\n answerIndex: '<',\r\n formData: '<',\r\n onSubmit: '&',\r\n setQuestionAnswer: '&',\r\n },\r\n controller,\r\n template,\r\n};\r\n","export default class WTTService {\r\n /* @ngInject */\r\n constructor($http, $log) {\r\n this.$http = $http;\r\n this.$log = $log;\r\n this.formData = {};\r\n }\r\n /** Set internal form data. */\r\n setFormData(formData) {\r\n this.formData = {\r\n ...this.formData,\r\n ...formData,\r\n };\r\n return Promise.resolve(this.formData);\r\n }\r\n /** Post submission form data. */\r\n setSubmission() {\r\n const { $http, $log } = this;\r\n\r\n return $http.post('/api/wtt/submissions', this.formData).then(\r\n (res) => {\r\n $log.info(res);\r\n return Promise.resolve(res);\r\n },\r\n (err) => {\r\n $log.error(err);\r\n return Promise.reject(err);\r\n },\r\n );\r\n }\r\n\r\n /** Post final step data. */\r\n setFinalStepData() {\r\n const { $http, $log } = this;\r\n\r\n return $http.post('/api/wtt/finalstep', this.formData.dynamicFormQuestions).then(\r\n (res) => {\r\n $log.info(res);\r\n return Promise.resolve(res);\r\n },\r\n (err) => {\r\n $log.error(err);\r\n return Promise.reject(err);\r\n },\r\n );\r\n }\r\n}\r\n","import 'angular';\r\nimport WebFont from 'webfontloader';\r\n\r\n// Routes.\r\nimport wttRoot from './wtt-root';\r\nimport wttIntro from './wtt-intro';\r\nimport wttGame from './wtt-game';\r\nimport wttSubmission from './wtt-submission';\r\nimport wttConfirmation from './wtt-confirmation';\r\nimport wttMore from './wtt-more';\r\n\r\n// Components.\r\nimport wttForm from './wtt-form';\r\nimport wttImageGrid from './wtt-image-grid';\r\nimport wttDynamicFormControl from './wtt-dynamic-form-control';\r\n\r\n// Service.\r\nimport WTTService from './wtt.service';\r\n\r\nexport default angular\r\n .module('ryobi.wtt', [])\r\n // Routes.\r\n .component('wttRoot', wttRoot)\r\n .component('wttIntro', wttIntro)\r\n .component('wttGame', wttGame)\r\n .component('wttSubmission', wttSubmission)\r\n .component('wttConfirmation', wttConfirmation)\r\n .component('wttMore', wttMore)\r\n // Components.\r\n .component('wttForm', wttForm)\r\n .component('wttImageGrid', wttImageGrid)\r\n .component('wttDynamicFormControl', wttDynamicFormControl)\r\n // Service.\r\n .service('WTTService', WTTService)\r\n // Configuration.\r\n .config(configureModule);\r\n\r\n/** Handle module initialisation. */\r\nfunction configureModule($stateProvider, $urlRouterProvider) {\r\n const $container = angular.element('#wtt');\r\n\r\n if (!$container.length) {\r\n return;\r\n }\r\n\r\n require.ensure(['fonts/rockout-rg/rockout-rg.css'], () => {\r\n WebFont.load({\r\n custom: {\r\n families: ['rockout-rg'],\r\n urls: [require('fonts/rockout-rg/rockout-rg.css')],\r\n },\r\n });\r\n });\r\n\r\n $stateProvider\r\n .state('wtt', {\r\n abstract: true,\r\n views: {\r\n main: {\r\n template: '',\r\n },\r\n },\r\n })\r\n .state('wtt.intro', {\r\n url: '/intro',\r\n views: {\r\n '': {\r\n template: '',\r\n },\r\n },\r\n })\r\n .state('wtt.game', {\r\n url: '/game',\r\n views: {\r\n '': {\r\n template: '',\r\n },\r\n },\r\n })\r\n .state('wtt.submission', {\r\n url: '/submission',\r\n views: {\r\n '': {\r\n template: '',\r\n },\r\n },\r\n })\r\n .state('wtt.more', {\r\n url: '/more',\r\n views: {\r\n '': {\r\n template: \"\",\r\n },\r\n },\r\n })\r\n .state('wtt.confirmation', {\r\n url: '/confirmation',\r\n views: {\r\n '': {\r\n template: '',\r\n },\r\n },\r\n });\r\n\r\n $urlRouterProvider.otherwise('/intro');\r\n}\r\n","// Load external libraries\r\nimport 'angular';\r\nimport 'angular-animate';\r\nimport 'angular-cookies';\r\nimport 'angular-loading-bar';\r\nimport 'angular-sanitize';\r\nimport 'angular-translate';\r\nimport 'angular-translate-handler-log';\r\nimport 'angular-translate-storage-cookie';\r\nimport 'angular-translate-storage-local';\r\nimport 'angular-ui-router';\r\nimport 'chosen';\r\nimport 'ng-infinite-scroll';\r\n\r\nimport deferredBootstrapper from 'angular-deferred-bootstrap';\r\n\r\n// Load local vendor libraries\r\nimport './vendor/angular-chosen';\r\nimport './vendor/angular-masonry';\r\nimport './vendor/angular-vertilize';\r\n\r\n// Load angular modules\r\nimport ControllersModule from './controllers';\r\nimport CordlessModule from './cordless';\r\nimport DirectivesModule from './directives';\r\nimport FiltersModule from './filters';\r\nimport LocalisationModule from './localisation';\r\nimport RoutesModule from './routes';\r\nimport ServicesModule from './services';\r\nimport WTTModule from './wtt';\r\n\r\nconst module = angular\r\n .module('ryobi', [\r\n 'ngAnimate',\r\n 'ngCookies',\r\n 'ngSanitize',\r\n 'angular-chosen',\r\n 'angular-loading-bar',\r\n 'infinite-scroll',\r\n 'pascalprecht.translate',\r\n 'ui.router',\r\n 'wu.masonry',\r\n ControllersModule.name,\r\n DirectivesModule.name,\r\n FiltersModule.name,\r\n LocalisationModule.name,\r\n RoutesModule.name,\r\n ServicesModule.name,\r\n CordlessModule.name,\r\n WTTModule.name,\r\n ])\r\n .config(configureModule)\r\n .run(runModule);\r\n\r\n// Set application settings.\r\nmodule.constant('appSettings', {\r\n debugMode: false,\r\n});\r\n\r\ndeferredBootstrapper.bootstrap({\r\n element: document.body,\r\n module: 'ryobi',\r\n resolve: {},\r\n});\r\n\r\n/**\r\n * Configure the module.\r\n * @ngInject\r\n */\r\nfunction configureModule($compileProvider, $httpProvider, $locationProvider) {\r\n $compileProvider.debugInfoEnabled(process.env.NODE_ENV !== 'production');\r\n $httpProvider.useApplyAsync(true);\r\n $locationProvider.html5Mode(false).hashPrefix('!');\r\n}\r\n\r\n/**\r\n * Run the module.\r\n * @ngInject\r\n */\r\nfunction runModule($rootScope) {\r\n // eslint-disable-next-line max-len\r\n if (process.env.NODE_ENV === 'development') {\r\n // Prevent errors being swallowed by ui-router in dev environments.\r\n $rootScope.$on(\r\n '$stateChangeError',\r\n (event, toState, toParams, fromState, fromParams, error) => {\r\n console.error('$stateChangeError', error); // eslint-disable-line no-console\r\n },\r\n );\r\n }\r\n}\r\n","module.exports = \"
0\\\"> {{vm.title}} 0\\\"/>
0, 'col-xs-12 text-align-center': vm.imageSrc.length === 0 }\\\">

{{vm.title}}

\";","module.exports = \" \";","module.exports = \"
0}\\\"> 0\\\"/> 0\\\" src={{image}} class=\\\"wtt-intro__landing-image wtt-intro__landing-image--{{$index}}\\\"/>

custom.wtt.intro.title

custom.wtt.intro.content

custom.wtt.intro.link
\";","module.exports = \"

custom.wtt.game.title

custom.wtt.game.content

\";","module.exports = \"

custom.wtt.submission.title

\";","module.exports = \"

custom.wtt.confirmation.title

custom.WTT.Tracking \";","module.exports = \"

custom.wtt.more.title

\";","module.exports = \"
\";","module.exports = \" \";","module.exports = \"
\";"],"sourceRoot":""}