{"version":3,"file":"default/js/main.js","sources":["webpack:///webpack/bootstrap","webpack:///./cartridges/app_lyonscg_mfra/cartridge/client/default/js/components/backtotop.js","webpack:///./cartridges/app_lyonscg_mfra/cartridge/client/default/js/components/clientSideValidation.js","webpack:///./cartridges/app_lyonscg_mfra/cartridge/client/default/js/components/footer.js","webpack:///./cartridges/app_lyonscg_mfra/cartridge/client/default/js/components/tooltips.js","webpack:///./cartridges/app_lyonscg_mfra/cartridge/client/default/js/config/zoomConfigs.js","webpack:///./cartridges/app_lyonscg_mfra/cartridge/client/default/js/util/utils.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/components/clientSideValidation.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/components/collapsibleItem.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/components/consentTracking.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/components/cookie.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/components/formValidation.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/components/keyboardAccessibility.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/components/spinner.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/product/base.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/product/detail.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/thirdParty/bootstrap.js","webpack:///./cartridges/app_storefront_base/cartridge/client/default/js/util.js","webpack:///./cartridges/int_googletags/cartridge/client/default/js/tagManager.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/cart/cart.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/checkout/adjustWarrantyPriceSpace.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/CrossBrowserTransparentVideo.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/FooterAnimate.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/MobileNavigation.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/Modal.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/accordionModule.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/carousels.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/envoymain.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/footer.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/menu.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/miniCart.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/search.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/select2-dropdownPosition.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/components/select2.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/config/slickConfigs.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/main.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/product/base.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/product/detail.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/product/productSetVariation.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/search/search.js","webpack:///./cartridges/org_arlo/cartridge/client/default/js/thirdParty/sfmcErrorHandler.js","webpack:///./node_modules/@babel/polyfill/lib/index.js","webpack:///./node_modules/@babel/polyfill/lib/noConflict.js","webpack:///./node_modules/bootstrap/js/src/alert.js","webpack:///./node_modules/bootstrap/js/src/carousel.js","webpack:///./node_modules/bootstrap/js/src/collapse.js","webpack:///./node_modules/bootstrap/js/src/modal.js","webpack:///./node_modules/bootstrap/js/src/scrollspy.js","webpack:///./node_modules/bootstrap/js/src/tab.js","webpack:///./node_modules/bootstrap/js/src/tooltip.js","webpack:///./node_modules/bootstrap/js/src/util.js","webpack:///./node_modules/core-js/es6/index.js","webpack:///./node_modules/core-js/fn/array/flat-map.js","webpack:///./node_modules/core-js/fn/array/includes.js","webpack:///./node_modules/core-js/fn/object/entries.js","webpack:///./node_modules/core-js/fn/object/get-own-property-descriptors.js","webpack:///./node_modules/core-js/fn/object/values.js","webpack:///./node_modules/core-js/fn/promise/finally.js","webpack:///./node_modules/core-js/fn/string/pad-end.js","webpack:///./node_modules/core-js/fn/string/pad-start.js","webpack:///./node_modules/core-js/fn/string/trim-end.js","webpack:///./node_modules/core-js/fn/string/trim-start.js","webpack:///./node_modules/core-js/fn/symbol/async-iterator.js","webpack:///./node_modules/core-js/library/fn/global.js","webpack:///./node_modules/core-js/library/modules/_a-function.js","webpack:///./node_modules/core-js/library/modules/_an-object.js","webpack:///./node_modules/core-js/library/modules/_core.js","webpack:///./node_modules/core-js/library/modules/_ctx.js","webpack:///./node_modules/core-js/library/modules/_descriptors.js","webpack:///./node_modules/core-js/library/modules/_dom-create.js","webpack:///./node_modules/core-js/library/modules/_export.js","webpack:///./node_modules/core-js/library/modules/_fails.js","webpack:///./node_modules/core-js/library/modules/_global.js","webpack:///./node_modules/core-js/library/modules/_has.js","webpack:///./node_modules/core-js/library/modules/_hide.js","webpack:///./node_modules/core-js/library/modules/_ie8-dom-define.js","webpack:///./node_modules/core-js/library/modules/_is-object.js","webpack:///./node_modules/core-js/library/modules/_object-dp.js","webpack:///./node_modules/core-js/library/modules/_property-desc.js","webpack:///./node_modules/core-js/library/modules/_to-primitive.js","webpack:///./node_modules/core-js/library/modules/es7.global.js","webpack:///./node_modules/core-js/modules/_a-function.js","webpack:///./node_modules/core-js/modules/_a-number-value.js","webpack:///./node_modules/core-js/modules/_add-to-unscopables.js","webpack:///./node_modules/core-js/modules/_advance-string-index.js","webpack:///./node_modules/core-js/modules/_an-instance.js","webpack:///./node_modules/core-js/modules/_an-object.js","webpack:///./node_modules/core-js/modules/_array-copy-within.js","webpack:///./node_modules/core-js/modules/_array-fill.js","webpack:///./node_modules/core-js/modules/_array-includes.js","webpack:///./node_modules/core-js/modules/_array-methods.js","webpack:///./node_modules/core-js/modules/_array-reduce.js","webpack:///./node_modules/core-js/modules/_array-species-constructor.js","webpack:///./node_modules/core-js/modules/_array-species-create.js","webpack:///./node_modules/core-js/modules/_bind.js","webpack:///./node_modules/core-js/modules/_classof.js","webpack:///./node_modules/core-js/modules/_cof.js","webpack:///./node_modules/core-js/modules/_collection-strong.js","webpack:///./node_modules/core-js/modules/_collection-weak.js","webpack:///./node_modules/core-js/modules/_collection.js","webpack:///./node_modules/core-js/modules/_core.js","webpack:///./node_modules/core-js/modules/_create-property.js","webpack:///./node_modules/core-js/modules/_ctx.js","webpack:///./node_modules/core-js/modules/_date-to-iso-string.js","webpack:///./node_modules/core-js/modules/_date-to-primitive.js","webpack:///./node_modules/core-js/modules/_defined.js","webpack:///./node_modules/core-js/modules/_descriptors.js","webpack:///./node_modules/core-js/modules/_dom-create.js","webpack:///./node_modules/core-js/modules/_enum-bug-keys.js","webpack:///./node_modules/core-js/modules/_enum-keys.js","webpack:///./node_modules/core-js/modules/_export.js","webpack:///./node_modules/core-js/modules/_fails-is-regexp.js","webpack:///./node_modules/core-js/modules/_fails.js","webpack:///./node_modules/core-js/modules/_fix-re-wks.js","webpack:///./node_modules/core-js/modules/_flags.js","webpack:///./node_modules/core-js/modules/_flatten-into-array.js","webpack:///./node_modules/core-js/modules/_for-of.js","webpack:///./node_modules/core-js/modules/_function-to-string.js","webpack:///./node_modules/core-js/modules/_global.js","webpack:///./node_modules/core-js/modules/_has.js","webpack:///./node_modules/core-js/modules/_hide.js","webpack:///./node_modules/core-js/modules/_html.js","webpack:///./node_modules/core-js/modules/_ie8-dom-define.js","webpack:///./node_modules/core-js/modules/_inherit-if-required.js","webpack:///./node_modules/core-js/modules/_invoke.js","webpack:///./node_modules/core-js/modules/_iobject.js","webpack:///./node_modules/core-js/modules/_is-array-iter.js","webpack:///./node_modules/core-js/modules/_is-array.js","webpack:///./node_modules/core-js/modules/_is-integer.js","webpack:///./node_modules/core-js/modules/_is-object.js","webpack:///./node_modules/core-js/modules/_is-regexp.js","webpack:///./node_modules/core-js/modules/_iter-call.js","webpack:///./node_modules/core-js/modules/_iter-create.js","webpack:///./node_modules/core-js/modules/_iter-define.js","webpack:///./node_modules/core-js/modules/_iter-detect.js","webpack:///./node_modules/core-js/modules/_iter-step.js","webpack:///./node_modules/core-js/modules/_iterators.js","webpack:///./node_modules/core-js/modules/_library.js","webpack:///./node_modules/core-js/modules/_math-expm1.js","webpack:///./node_modules/core-js/modules/_math-fround.js","webpack:///./node_modules/core-js/modules/_math-log1p.js","webpack:///./node_modules/core-js/modules/_math-sign.js","webpack:///./node_modules/core-js/modules/_meta.js","webpack:///./node_modules/core-js/modules/_microtask.js","webpack:///./node_modules/core-js/modules/_new-promise-capability.js","webpack:///./node_modules/core-js/modules/_object-assign.js","webpack:///./node_modules/core-js/modules/_object-create.js","webpack:///./node_modules/core-js/modules/_object-dp.js","webpack:///./node_modules/core-js/modules/_object-dps.js","webpack:///./node_modules/core-js/modules/_object-gopd.js","webpack:///./node_modules/core-js/modules/_object-gopn-ext.js","webpack:///./node_modules/core-js/modules/_object-gopn.js","webpack:///./node_modules/core-js/modules/_object-gops.js","webpack:///./node_modules/core-js/modules/_object-gpo.js","webpack:///./node_modules/core-js/modules/_object-keys-internal.js","webpack:///./node_modules/core-js/modules/_object-keys.js","webpack:///./node_modules/core-js/modules/_object-pie.js","webpack:///./node_modules/core-js/modules/_object-sap.js","webpack:///./node_modules/core-js/modules/_object-to-array.js","webpack:///./node_modules/core-js/modules/_own-keys.js","webpack:///./node_modules/core-js/modules/_parse-float.js","webpack:///./node_modules/core-js/modules/_parse-int.js","webpack:///./node_modules/core-js/modules/_perform.js","webpack:///./node_modules/core-js/modules/_promise-resolve.js","webpack:///./node_modules/core-js/modules/_property-desc.js","webpack:///./node_modules/core-js/modules/_redefine-all.js","webpack:///./node_modules/core-js/modules/_redefine.js","webpack:///./node_modules/core-js/modules/_regexp-exec-abstract.js","webpack:///./node_modules/core-js/modules/_regexp-exec.js","webpack:///./node_modules/core-js/modules/_same-value.js","webpack:///./node_modules/core-js/modules/_set-proto.js","webpack:///./node_modules/core-js/modules/_set-species.js","webpack:///./node_modules/core-js/modules/_set-to-string-tag.js","webpack:///./node_modules/core-js/modules/_shared-key.js","webpack:///./node_modules/core-js/modules/_shared.js","webpack:///./node_modules/core-js/modules/_species-constructor.js","webpack:///./node_modules/core-js/modules/_strict-method.js","webpack:///./node_modules/core-js/modules/_string-at.js","webpack:///./node_modules/core-js/modules/_string-context.js","webpack:///./node_modules/core-js/modules/_string-html.js","webpack:///./node_modules/core-js/modules/_string-pad.js","webpack:///./node_modules/core-js/modules/_string-repeat.js","webpack:///./node_modules/core-js/modules/_string-trim.js","webpack:///./node_modules/core-js/modules/_string-ws.js","webpack:///./node_modules/core-js/modules/_task.js","webpack:///./node_modules/core-js/modules/_to-absolute-index.js","webpack:///./node_modules/core-js/modules/_to-index.js","webpack:///./node_modules/core-js/modules/_to-integer.js","webpack:///./node_modules/core-js/modules/_to-iobject.js","webpack:///./node_modules/core-js/modules/_to-length.js","webpack:///./node_modules/core-js/modules/_to-object.js","webpack:///./node_modules/core-js/modules/_to-primitive.js","webpack:///./node_modules/core-js/modules/_typed-array.js","webpack:///./node_modules/core-js/modules/_typed-buffer.js","webpack:///./node_modules/core-js/modules/_typed.js","webpack:///./node_modules/core-js/modules/_uid.js","webpack:///./node_modules/core-js/modules/_user-agent.js","webpack:///./node_modules/core-js/modules/_validate-collection.js","webpack:///./node_modules/core-js/modules/_wks-define.js","webpack:///./node_modules/core-js/modules/_wks-ext.js","webpack:///./node_modules/core-js/modules/_wks.js","webpack:///./node_modules/core-js/modules/core.get-iterator-method.js","webpack:///./node_modules/core-js/modules/es6.array.copy-within.js","webpack:///./node_modules/core-js/modules/es6.array.every.js","webpack:///./node_modules/core-js/modules/es6.array.fill.js","webpack:///./node_modules/core-js/modules/es6.array.filter.js","webpack:///./node_modules/core-js/modules/es6.array.find-index.js","webpack:///./node_modules/core-js/modules/es6.array.find.js","webpack:///./node_modules/core-js/modules/es6.array.for-each.js","webpack:///./node_modules/core-js/modules/es6.array.from.js","webpack:///./node_modules/core-js/modules/es6.array.index-of.js","webpack:///./node_modules/core-js/modules/es6.array.is-array.js","webpack:///./node_modules/core-js/modules/es6.array.iterator.js","webpack:///./node_modules/core-js/modules/es6.array.join.js","webpack:///./node_modules/core-js/modules/es6.array.last-index-of.js","webpack:///./node_modules/core-js/modules/es6.array.map.js","webpack:///./node_modules/core-js/modules/es6.array.of.js","webpack:///./node_modules/core-js/modules/es6.array.reduce-right.js","webpack:///./node_modules/core-js/modules/es6.array.reduce.js","webpack:///./node_modules/core-js/modules/es6.array.slice.js","webpack:///./node_modules/core-js/modules/es6.array.some.js","webpack:///./node_modules/core-js/modules/es6.array.sort.js","webpack:///./node_modules/core-js/modules/es6.array.species.js","webpack:///./node_modules/core-js/modules/es6.date.now.js","webpack:///./node_modules/core-js/modules/es6.date.to-iso-string.js","webpack:///./node_modules/core-js/modules/es6.date.to-json.js","webpack:///./node_modules/core-js/modules/es6.date.to-primitive.js","webpack:///./node_modules/core-js/modules/es6.date.to-string.js","webpack:///./node_modules/core-js/modules/es6.function.bind.js","webpack:///./node_modules/core-js/modules/es6.function.has-instance.js","webpack:///./node_modules/core-js/modules/es6.function.name.js","webpack:///./node_modules/core-js/modules/es6.map.js","webpack:///./node_modules/core-js/modules/es6.math.acosh.js","webpack:///./node_modules/core-js/modules/es6.math.asinh.js","webpack:///./node_modules/core-js/modules/es6.math.atanh.js","webpack:///./node_modules/core-js/modules/es6.math.cbrt.js","webpack:///./node_modules/core-js/modules/es6.math.clz32.js","webpack:///./node_modules/core-js/modules/es6.math.cosh.js","webpack:///./node_modules/core-js/modules/es6.math.expm1.js","webpack:///./node_modules/core-js/modules/es6.math.fround.js","webpack:///./node_modules/core-js/modules/es6.math.hypot.js","webpack:///./node_modules/core-js/modules/es6.math.imul.js","webpack:///./node_modules/core-js/modules/es6.math.log10.js","webpack:///./node_modules/core-js/modules/es6.math.log1p.js","webpack:///./node_modules/core-js/modules/es6.math.log2.js","webpack:///./node_modules/core-js/modules/es6.math.sign.js","webpack:///./node_modules/core-js/modules/es6.math.sinh.js","webpack:///./node_modules/core-js/modules/es6.math.tanh.js","webpack:///./node_modules/core-js/modules/es6.math.trunc.js","webpack:///./node_modules/core-js/modules/es6.number.constructor.js","webpack:///./node_modules/core-js/modules/es6.number.epsilon.js","webpack:///./node_modules/core-js/modules/es6.number.is-finite.js","webpack:///./node_modules/core-js/modules/es6.number.is-integer.js","webpack:///./node_modules/core-js/modules/es6.number.is-nan.js","webpack:///./node_modules/core-js/modules/es6.number.is-safe-integer.js","webpack:///./node_modules/core-js/modules/es6.number.max-safe-integer.js","webpack:///./node_modules/core-js/modules/es6.number.min-safe-integer.js","webpack:///./node_modules/core-js/modules/es6.number.parse-float.js","webpack:///./node_modules/core-js/modules/es6.number.parse-int.js","webpack:///./node_modules/core-js/modules/es6.number.to-fixed.js","webpack:///./node_modules/core-js/modules/es6.number.to-precision.js","webpack:///./node_modules/core-js/modules/es6.object.assign.js","webpack:///./node_modules/core-js/modules/es6.object.create.js","webpack:///./node_modules/core-js/modules/es6.object.define-properties.js","webpack:///./node_modules/core-js/modules/es6.object.define-property.js","webpack:///./node_modules/core-js/modules/es6.object.freeze.js","webpack:///./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js","webpack:///./node_modules/core-js/modules/es6.object.get-own-property-names.js","webpack:///./node_modules/core-js/modules/es6.object.get-prototype-of.js","webpack:///./node_modules/core-js/modules/es6.object.is-extensible.js","webpack:///./node_modules/core-js/modules/es6.object.is-frozen.js","webpack:///./node_modules/core-js/modules/es6.object.is-sealed.js","webpack:///./node_modules/core-js/modules/es6.object.is.js","webpack:///./node_modules/core-js/modules/es6.object.keys.js","webpack:///./node_modules/core-js/modules/es6.object.prevent-extensions.js","webpack:///./node_modules/core-js/modules/es6.object.seal.js","webpack:///./node_modules/core-js/modules/es6.object.set-prototype-of.js","webpack:///./node_modules/core-js/modules/es6.object.to-string.js","webpack:///./node_modules/core-js/modules/es6.parse-float.js","webpack:///./node_modules/core-js/modules/es6.parse-int.js","webpack:///./node_modules/core-js/modules/es6.promise.js","webpack:///./node_modules/core-js/modules/es6.reflect.apply.js","webpack:///./node_modules/core-js/modules/es6.reflect.construct.js","webpack:///./node_modules/core-js/modules/es6.reflect.define-property.js","webpack:///./node_modules/core-js/modules/es6.reflect.delete-property.js","webpack:///./node_modules/core-js/modules/es6.reflect.enumerate.js","webpack:///./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js","webpack:///./node_modules/core-js/modules/es6.reflect.get-prototype-of.js","webpack:///./node_modules/core-js/modules/es6.reflect.get.js","webpack:///./node_modules/core-js/modules/es6.reflect.has.js","webpack:///./node_modules/core-js/modules/es6.reflect.is-extensible.js","webpack:///./node_modules/core-js/modules/es6.reflect.own-keys.js","webpack:///./node_modules/core-js/modules/es6.reflect.prevent-extensions.js","webpack:///./node_modules/core-js/modules/es6.reflect.set-prototype-of.js","webpack:///./node_modules/core-js/modules/es6.reflect.set.js","webpack:///./node_modules/core-js/modules/es6.regexp.constructor.js","webpack:///./node_modules/core-js/modules/es6.regexp.exec.js","webpack:///./node_modules/core-js/modules/es6.regexp.flags.js","webpack:///./node_modules/core-js/modules/es6.regexp.match.js","webpack:///./node_modules/core-js/modules/es6.regexp.replace.js","webpack:///./node_modules/core-js/modules/es6.regexp.search.js","webpack:///./node_modules/core-js/modules/es6.regexp.split.js","webpack:///./node_modules/core-js/modules/es6.regexp.to-string.js","webpack:///./node_modules/core-js/modules/es6.set.js","webpack:///./node_modules/core-js/modules/es6.string.anchor.js","webpack:///./node_modules/core-js/modules/es6.string.big.js","webpack:///./node_modules/core-js/modules/es6.string.blink.js","webpack:///./node_modules/core-js/modules/es6.string.bold.js","webpack:///./node_modules/core-js/modules/es6.string.code-point-at.js","webpack:///./node_modules/core-js/modules/es6.string.ends-with.js","webpack:///./node_modules/core-js/modules/es6.string.fixed.js","webpack:///./node_modules/core-js/modules/es6.string.fontcolor.js","webpack:///./node_modules/core-js/modules/es6.string.fontsize.js","webpack:///./node_modules/core-js/modules/es6.string.from-code-point.js","webpack:///./node_modules/core-js/modules/es6.string.includes.js","webpack:///./node_modules/core-js/modules/es6.string.italics.js","webpack:///./node_modules/core-js/modules/es6.string.iterator.js","webpack:///./node_modules/core-js/modules/es6.string.link.js","webpack:///./node_modules/core-js/modules/es6.string.raw.js","webpack:///./node_modules/core-js/modules/es6.string.repeat.js","webpack:///./node_modules/core-js/modules/es6.string.small.js","webpack:///./node_modules/core-js/modules/es6.string.starts-with.js","webpack:///./node_modules/core-js/modules/es6.string.strike.js","webpack:///./node_modules/core-js/modules/es6.string.sub.js","webpack:///./node_modules/core-js/modules/es6.string.sup.js","webpack:///./node_modules/core-js/modules/es6.string.trim.js","webpack:///./node_modules/core-js/modules/es6.symbol.js","webpack:///./node_modules/core-js/modules/es6.typed.array-buffer.js","webpack:///./node_modules/core-js/modules/es6.typed.data-view.js","webpack:///./node_modules/core-js/modules/es6.typed.float32-array.js","webpack:///./node_modules/core-js/modules/es6.typed.float64-array.js","webpack:///./node_modules/core-js/modules/es6.typed.int16-array.js","webpack:///./node_modules/core-js/modules/es6.typed.int32-array.js","webpack:///./node_modules/core-js/modules/es6.typed.int8-array.js","webpack:///./node_modules/core-js/modules/es6.typed.uint16-array.js","webpack:///./node_modules/core-js/modules/es6.typed.uint32-array.js","webpack:///./node_modules/core-js/modules/es6.typed.uint8-array.js","webpack:///./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js","webpack:///./node_modules/core-js/modules/es6.weak-map.js","webpack:///./node_modules/core-js/modules/es6.weak-set.js","webpack:///./node_modules/core-js/modules/es7.array.flat-map.js","webpack:///./node_modules/core-js/modules/es7.array.includes.js","webpack:///./node_modules/core-js/modules/es7.object.entries.js","webpack:///./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js","webpack:///./node_modules/core-js/modules/es7.object.values.js","webpack:///./node_modules/core-js/modules/es7.promise.finally.js","webpack:///./node_modules/core-js/modules/es7.string.pad-end.js","webpack:///./node_modules/core-js/modules/es7.string.pad-start.js","webpack:///./node_modules/core-js/modules/es7.string.trim-left.js","webpack:///./node_modules/core-js/modules/es7.string.trim-right.js","webpack:///./node_modules/core-js/modules/es7.symbol.async-iterator.js","webpack:///./node_modules/core-js/modules/web.dom.iterable.js","webpack:///./node_modules/core-js/modules/web.immediate.js","webpack:///./node_modules/core-js/modules/web.timers.js","webpack:///./node_modules/core-js/web/index.js","webpack:///./node_modules/ev-emitter/ev-emitter.js","webpack:///./node_modules/gsap/CSSPlugin.js","webpack:///./node_modules/gsap/dist/gsap.js","webpack:///./node_modules/gsap/gsap-core.js","webpack:///./node_modules/gsap/index.js","webpack:///./node_modules/imagesloaded/imagesloaded.js","webpack:///./node_modules/jquery/dist/jquery.js","webpack:///./node_modules/lodash/_Symbol.js","webpack:///./node_modules/lodash/_baseGetTag.js","webpack:///./node_modules/lodash/_baseTrim.js","webpack:///./node_modules/lodash/_freeGlobal.js","webpack:///./node_modules/lodash/_getRawTag.js","webpack:///./node_modules/lodash/_objectToString.js","webpack:///./node_modules/lodash/_root.js","webpack:///./node_modules/lodash/_trimmedEndIndex.js","webpack:///./node_modules/lodash/debounce.js","webpack:///./node_modules/lodash/isObject.js","webpack:///./node_modules/lodash/isObjectLike.js","webpack:///./node_modules/lodash/isSymbol.js","webpack:///./node_modules/lodash/lodash.js","webpack:///./node_modules/lodash/now.js","webpack:///./node_modules/lodash/toNumber.js","webpack:///../../src/utils/isBrowser.js","webpack:///../../src/utils/debounce.js","webpack:///../../src/utils/isFunction.js","webpack:///../../src/utils/getStyleComputedProperty.js","webpack:///../../src/utils/getParentNode.js","webpack:///../../src/utils/getScrollParent.js","webpack:///../../src/utils/getReferenceNode.js","webpack:///../../src/utils/isIE.js","webpack:///../../src/utils/getOffsetParent.js","webpack:///../../src/utils/isOffsetContainer.js","webpack:///../../src/utils/getRoot.js","webpack:///../../src/utils/findCommonOffsetParent.js","webpack:///../../src/utils/getScroll.js","webpack:///../../src/utils/includeScroll.js","webpack:///../../src/utils/getBordersSize.js","webpack:///../../src/utils/getWindowSizes.js","webpack:///../../src/utils/getClientRect.js","webpack:///../../src/utils/getBoundingClientRect.js","webpack:///../../src/utils/getOffsetRectRelativeToArbitraryNode.js","webpack:///../../src/utils/getViewportOffsetRectRelativeToArtbitraryNode.js","webpack:///../../src/utils/isFixed.js","webpack:///../../src/utils/getFixedPositionOffsetParent.js","webpack:///../../src/utils/getBoundaries.js","webpack:///../../src/utils/computeAutoPlacement.js","webpack:///../../src/utils/getReferenceOffsets.js","webpack:///../../src/utils/getOuterSizes.js","webpack:///../../src/utils/getOppositePlacement.js","webpack:///../../src/utils/getPopperOffsets.js","webpack:///../../src/utils/find.js","webpack:///../../src/utils/findIndex.js","webpack:///../../src/utils/runModifiers.js","webpack:///../../src/methods/update.js","webpack:///../../src/utils/isModifierEnabled.js","webpack:///../../src/utils/getSupportedPropertyName.js","webpack:///../../src/methods/destroy.js","webpack:///../../src/utils/getWindow.js","webpack:///../../src/utils/setupEventListeners.js","webpack:///../../src/methods/enableEventListeners.js","webpack:///../../src/utils/removeEventListeners.js","webpack:///../../src/methods/disableEventListeners.js","webpack:///../../src/utils/isNumeric.js","webpack:///../../src/utils/setStyles.js","webpack:///../../src/utils/setAttributes.js","webpack:///../../src/modifiers/applyStyle.js","webpack:///../../src/utils/getRoundedOffsets.js","webpack:///../../src/modifiers/computeStyle.js","webpack:///../../src/utils/isModifierRequired.js","webpack:///../../src/modifiers/arrow.js","webpack:///../../src/utils/getOppositeVariation.js","webpack:///../../src/methods/placements.js","webpack:///../../src/utils/clockwise.js","webpack:///../../src/modifiers/flip.js","webpack:///../../src/modifiers/keepTogether.js","webpack:///../../src/modifiers/offset.js","webpack:///../../src/modifiers/preventOverflow.js","webpack:///../../src/modifiers/shift.js","webpack:///../../src/modifiers/hide.js","webpack:///../../src/modifiers/inner.js","webpack:///../../src/modifiers/index.js","webpack:///../../src/methods/defaults.js","webpack:///../../src/index.js","webpack:///./node_modules/regenerator-runtime/runtime.js","webpack:///./node_modules/scrollmagic/scrollmagic/uncompressed/ScrollMagic.js","webpack:///./node_modules/slick-carousel/slick/slick.js","webpack:///./node_modules/svg4everybody/dist/svg4everybody.js","webpack:///(webpack)/buildin/amd-options.js","webpack:///(webpack)/buildin/global.js","webpack:///(webpack)/buildin/module.js"],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./cartridges/org_arlo/cartridge/client/default/js/main.js\");\n","'use strict';\n\nvar offsetTrigger = 300;\nvar scrollSpeed = 4000; // in px per sec\nvar hideBelow = 0; // min breakpoint in px\nvar hideAbove = Infinity; // max breakpoint in px (default is Infinity, a.k.a. no maximum)\nvar $backToTopButton = $('.back-to-top');\n\nvar backtotop = {\n isVisible: true,\n isScrolling: false,\n\n init: function () {\n /**\n * initialize back to top button and event handlers.\n **/\n\n // When the user scrolls down N px from the top of the document, show the button\n window.onscroll = function () {\n backtotop.testPosition();\n };\n\n // When the user clicks on the button, scroll back to the top of the document\n $backToTopButton.on('click', function () {\n backtotop.scroll();\n });\n\n // Initially hide the button on page load, before we test to sees if it should show.\n backtotop.hide();\n\n // Go ahead and see if we're already scrolled down far enough\n // to display the button after page loads.\n backtotop.testPosition();\n },\n show: function () {\n if (backtotop.isScrolling) {\n return;\n }\n if (!backtotop.isVisible) {\n $backToTopButton.fadeIn('fast').removeClass('active');\n backtotop.isVisible = true;\n }\n },\n hide: function () {\n if (backtotop.isScrolling) {\n return;\n }\n if (backtotop.isVisible) {\n $backToTopButton.fadeOut('fast');\n backtotop.isVisible = false;\n }\n },\n testPosition: function () {\n if (backtotop.isScrolling) {\n return;\n }\n var width = $(window).innerWidth();\n if (width >= hideBelow && width < hideAbove && ($(window).scrollTop() > offsetTrigger)) {\n backtotop.show();\n } else {\n backtotop.hide();\n }\n },\n reset: function () {\n $backToTopButton.removeClass('active');\n $backToTopButton.removeAttr('style');\n backtotop.hide();\n backtotop.isVisible = false;\n backtotop.isScrolling = false;\n },\n scroll: function () {\n if (backtotop.isScrolling) {\n return;\n }\n backtotop.show(); // just in case\n $backToTopButton.addClass('active');\n $backToTopButton.blur();\n backtotop.isScrolling = true;\n var distanceToTop = $backToTopButton.offset().top;\n var animationDuration = distanceToTop / (scrollSpeed / 1000);\n $('html, body')\n .stop(true, true)\n .animate({ scrollTop: 0 }, animationDuration, function () {\n backtotop.isScrolling = false;\n backtotop.reset();\n backtotop.testPosition();\n }\n );\n }\n};\n\nmodule.exports = function () {\n backtotop.init();\n};\n","'use strict';\n\nvar baseClientSideValidation = require('base/components/clientSideValidation');\n\nmodule.exports = $.extend(baseClientSideValidation, {\n /**\n * Clears the validation errors of an invalidated form element after a change occurs\n */\n clearErrorsOnChange: function () {\n $(':input, .form-control').on('change input', function () {\n if ($(this).hasClass('is-invalid')) {\n $(this).removeClass('is-invalid');\n $(this).closest('.invalid-feedback').remove();\n }\n });\n }\n});\n","'use strict';\n\nmodule.exports = function () {\n // back-to-top code enhanced, moved to backtotop.js\n};\n","'use strict';\n\n$(document).ready(function () {\n $(function () {\n $('[data-toggle=\"tooltip\"]').tooltip();\n });\n});\n","'use strict';\n\n/**\n * Default Zoom config\n */\nmodule.exports = {\n url: false,\n on: 'mouseover',\n duration: 120,\n target: false,\n touch: true,\n magnify: 1,\n callback: false,\n onZoomIn: false,\n onZoomOut: false\n};\n","'use strict';\n\nvar _ = require('lodash');\n\nvar utils = {\n /**\n * @desc Media breakpoints that are used throughout the Javascript\n */\n breakpoints: { // TODO: LFED Update with project breakpoints\n xs: 0,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1200\n },\n\n /**\n * @function\n * @description Returns either an object with all of the available breakpoints or a specific viewport based on the given size\n * @param {string=} size The viewport to return\n * @param {Object=} breakpoints A custom breakpoints object\n * @returns {Object|string} - breakpoints or specific viewport\n */\n getViewports: function (size, breakpoints) {\n var bps = breakpoints || this.breakpoints;\n\n if (size) {\n var viewport = bps[size];\n\n if (viewport) {\n return viewport;\n }\n\n window.console.error('Unexpected viewport size given in util.getViewports');\n throw new Error('Unexpected viewport size given in util.getViewports');\n } else {\n return breakpoints;\n }\n },\n\n /**\n * @function\n * @description Returns the current viewport name (ex: 'medium') or 'max' if the current window is larger than any defined viewport width\n * @returns {string} - current viewport name\n */\n getCurrentViewport: function () {\n var w = window.innerWidth;\n var viewports = utils.getViewports();\n var viewport = 'max';\n // Traverse the object from small up to desktop, and return the first match\n _.each(viewports, function (value, name) {\n if (w <= value) {\n viewport = name;\n }\n });\n return viewport;\n },\n\n /**\n * @function\n * @description appends the parameter with the given name and value to the given url and returns the changed url\n * @param {string} url the url to which the parameter will be added\n * @param {string} name the name of the parameter\n * @param {string} value the value of the parameter\n * @returns {string} - URL with parameter\n */\n appendParamToURL: function (url, name, value) {\n // quit if the param already exists\n if (url.indexOf(name + '=') !== -1) {\n return url;\n }\n var separator = url.indexOf('?') !== -1 ? '&' : '?';\n return url + separator + name + '=' + encodeURIComponent(value);\n },\n\n /**\n * @function\n * @description remove the parameter and its value from the given url and returns the changed url\n * @param {string} url the url from which the parameter will be removed\n * @param {string} name the name of parameter that will be removed from url\n * @returns {string} - URL without parameter\n */\n removeParamFromURL: function (url, name) {\n if (url.indexOf('?') === -1 || url.indexOf(name + '=') === -1) {\n return url;\n }\n var hash;\n var params;\n var domain = url.split('?')[0];\n var paramUrl = url.split('?')[1];\n var newParams = [];\n // if there is a hash at the end, store the hash\n if (paramUrl.indexOf('#') > -1) {\n hash = paramUrl.split('#')[1] || '';\n paramUrl = paramUrl.split('#')[0];\n }\n params = paramUrl.split('&');\n for (var i = 0; i < params.length; i++) {\n // put back param to newParams array if it is not the one to be removed\n if (params[i].split('=')[0] !== name) {\n newParams.push(params[i]);\n }\n }\n return domain + '?' + newParams.join('&') + (hash ? '#' + hash : '');\n },\n\n /**\n * appends params to a url\n * @param {string} url - Original url\n * @param {Object} params - Parameters to append\n * @returns {string} result url with appended parameters\n */\n appendToUrl: function (url, params) {\n var newUrl = url;\n newUrl += (newUrl.indexOf('?') !== -1 ? '&' : '?') + Object.keys(params).map(function (key) {\n return key + '=' + encodeURIComponent(params[key]);\n }).join('&');\n\n return newUrl;\n },\n\n /**\n * @function\n * @description extract the query string from URL\n * @param {string} url the url to extra query string from\n * @returns {string|Object} - Query String from URL\n **/\n getQueryString: function (url) {\n var qs;\n if (!_.isString(url)) {\n return null;\n }\n var a = document.createElement('a');\n a.href = url;\n if (a.search) {\n qs = a.search.substr(1); // remove the leading ?\n }\n return qs;\n },\n\n /**\n * @function\n * @description Checks to see if the given element is in the current viewport\n * @param {string} el - Element to check\n * @param {string} offsetToTop - Offset to give the top value\n * @returns {boolean} - Whether or not the element is in the viewport\n */\n elementInViewport: function (el, offsetToTop) {\n var top = el.offsetTop;\n var left = el.offsetLeft;\n var width = el.offsetWidth;\n var height = el.offsetHeight;\n\n while (el.offsetParent) {\n var offsetParent = el.offsetParent;\n top += offsetParent.offsetTop;\n left += offsetParent.offsetLeft;\n }\n\n if (typeof offsetToTop !== 'undefined') {\n top -= offsetToTop;\n }\n\n if (window.pageXOffset !== null) {\n return (\n top < (window.pageYOffset + window.innerHeight) &&\n left < (window.pageXOffset + window.innerWidth) &&\n (top + height) > window.pageYOffset &&\n (left + width) > window.pageXOffset\n );\n }\n\n if (document.compatMode === 'CSS1Compat') {\n return (\n top < (window.document.documentElement.scrollTop + window.document.documentElement.clientHeight) &&\n left < (window.document.documentElement.scrollLeft + window.document.documentElement.clientWidth) &&\n (top + height) > window.document.documentElement.scrollTop &&\n (left + width) > window.document.documentElement.scrollLeft\n );\n }\n\n return false;\n },\n\n /**\n * @function\n * @description Appends the parameter 'format=ajax' to a given path\n * @param {string} path the relative path\n * @returns {string} - URL with format param of ajax\n */\n ajaxUrl: function (path) {\n return this.appendParamToURL(path, 'format', 'ajax');\n },\n\n /**\n * @function\n * @description Converts the given relative URL to an absolute URL\n * @param {string} url - URL to convert\n * @returns {string} - Absolute URL\n */\n toAbsoluteUrl: function (url) {\n var absURL = url;\n if (url.indexOf('http') !== 0 && url.charAt(0) !== '/') {\n absURL = '/' + url;\n }\n return absURL;\n },\n\n /**\n * @function\n * @description Loads css dynamically from given urls\n * @param {Array} urls Array of urls from which css will be dynamically loaded.\n */\n loadDynamicCss: function (urls) {\n var i = urls.length;\n var len = urls.length;\n for (i = 0; i < len; i++) {\n this.loadedCssFiles.push(this.loadCssFile(urls[i]));\n }\n },\n\n /**\n * @function\n * @description Loads css file dynamically from given url\n * @param {string} url The url from which css file will be dynamically loaded.\n * @returns {jQuery} - CSS Link Element\n */\n loadCssFile: function (url) {\n return $('').appendTo($('head')).attr({\n type: 'text/css',\n rel: 'stylesheet'\n }).attr('href', url); // for i.e. <9, href must be added after link has been appended to head\n },\n // array to keep track of the dynamically loaded CSS files\n loadedCssFiles: [],\n\n /**\n * @function\n * @description Removes all css files which were dynamically loaded\n */\n clearDynamicCss: function () {\n var i = this.loadedCssFiles.length;\n while (i-- > 0) {\n $(this.loadedCssFiles[i]).remove();\n }\n this.loadedCssFiles = [];\n },\n\n /**\n * @function\n * @description Extracts all parameters from a given query string into an object\n * @param {string} qs The query string from which the parameters will be extracted\n * @returns {Object} - Object with params from the query string\n */\n getQueryStringParams: function (qs) {\n if (!qs || qs.length === 0) { return {}; }\n var params = {};\n var unescapedQS = decodeURIComponent(qs);\n // Use the String::replace method to iterate over each\n // name-value pair in the string.\n unescapedQS.replace(new RegExp('([^?=&]+)(=([^&]*))?', 'g'),\n function ($0, $1, $2, $3) {\n params[$1] = $3;\n }\n );\n return params;\n },\n\n /**\n * @function\n * @description Fills in the given form with the given address information\n * @param {Object} address - Address fields object\n * @param {Object} $form - Form jQuery object\n */\n fillAddressFields: function (address, $form) {\n var fields = Object.keys(address);\n for (var i = 0; i < fields.length; i++) {\n var field = fields[i];\n if (field !== 'ID' && field !== 'UUID' && field !== 'key') {\n // if the key in address object ends with 'Code', remove that suffix\n // keys that ends with 'Code' are postalCode, stateCode and countryCode\n $form.find('[name$=\"' + field.replace('Code', '') + '\"]').val(address[field]);\n // update the state fields\n if (field === 'countryCode') {\n $form.find('[name$=\"country\"]').trigger('change');\n // retrigger state selection after country has changed\n // this results in duplication of the state code, but is a necessary evil\n // for now because sometimes countryCode comes after stateCode\n $form.find('[name$=\"state\"]').val(address.stateCode);\n }\n }\n }\n },\n\n /**\n * @function\n * @description Binds the onclick-event to a delete button on a given container,\n * which opens a confirmation box with a given message\n * @param {string} container - The name of element to which the function will be bind\n * @param {string} message - The message the will be shown upon a click\n */\n setDeleteConfirmation: function (container, message) {\n $(container).on('click', '.delete', function () {\n return window.confirm(message); // eslint-disable-line\n });\n },\n\n /**\n * @function\n * @description Scrolls a browser window to a given x point\n * @param {string} xLocation - The x coordinate\n */\n scrollBrowser: function (xLocation) {\n $('html, body').animate({\n scrollTop: xLocation\n }, 500);\n },\n\n /**\n * @function\n * @desc Determines if the device that is being used is mobile\n * @returns {boolean} - Wether or not the browser is currently mobile\n */\n isMobile: function () {\n var mobileAgentHash = ['mobile', 'tablet', 'phone', 'ipad', 'ipod', 'android', 'blackberry', 'windows ce', 'opera mini', 'palm'];\n var idx = 0;\n var isMobile = false;\n var userAgent = (navigator.userAgent).toLowerCase();\n\n while (mobileAgentHash[idx] && !isMobile) {\n isMobile = (userAgent.indexOf(mobileAgentHash[idx]) >= 0);\n idx++;\n }\n return isMobile;\n },\n\n /**\n * @function\n * @description Executes a callback function when the user has stopped resizing the screen.\n * @param {function} callback - Callback function for the resize event\n * @return {function} - Callback function for the resize event\n */\n smartResize: function (callback) {\n var timeout;\n\n $(window).on('resize', function () {\n clearTimeout(timeout);\n timeout = setTimeout(callback, 100);\n }).resize();\n\n return callback;\n },\n\n /**\n * @function\n * @desc Generates a min-width matchMedia media query based on the given params\n * @param {string} size - Breakpoint to use for the media query\n * @param {Object} breakpoints - Override of the util breakpoints (optional)\n * @returns {boolean} - Wether or not the given media query matches\n */\n mediaBreakpointUp: function (size, breakpoints) {\n var breakpoint = this.getViewports(size, breakpoints);\n var mediaQuery = window.matchMedia('(min-width: ' + breakpoint + 'px)');\n return mediaQuery.matches;\n },\n\n /**\n * @function\n * @desc Generates a min-width matchMedia media query based on the given params\n * @param {string} size - Breakpoint to use for the media query\n * @param {Object} breakpoints - Override of the util breakpoints object (optional)\n * @returns {boolean} - Wether or not the given media query matches\n */\n mediaBreakpointDown: function (size, breakpoints) {\n var bps = typeof breakpoints !== 'undefined' ? breakpoints : this.breakpoints;\n var nextSize = this.getNextObjectKey(bps, size);\n\n if (typeof nextSize === 'string') {\n var breakpoint = this.getViewports(nextSize, breakpoints) - 1;\n var mediaQuery = window.matchMedia('(max-width: ' + breakpoint + 'px)');\n return mediaQuery.matches;\n }\n\n return true;\n },\n\n /**\n * @function\n * @desc Generates a min-width and max-width matchMedia media queries based on the given params\n * @param {string} sizeMin - Min breakpoint to use for the media query\n * @param {string} sizeMax - Max breakpoint to use for the media query\n * @param {Object} breakpoints - Override of the util breakpoints object (optional)\n * @returns {boolean} - Wether or not the given media query matches\n */\n mediaBreakpointBetween: function (sizeMin, sizeMax, breakpoints) {\n var min = this.mediaBreakpointUp(sizeMin, breakpoints);\n var max = this.mediaBreakpointDown(sizeMax, breakpoints);\n\n return min && max;\n },\n\n /**\n * @function\n * @desc Generates a min-width and max-width matchMedia media query based on the given params\n * @param {string} size - Breakpoint to use for the media query\n * @param {Object} breakpoints - Override of the util breakpoints object (optional)\n * @returns {boolean} - Wether or not the given media query matches\n */\n mediaBreakpointOnly: function (size, breakpoints) {\n return this.mediaBreakpointBetween(size, size, breakpoints);\n },\n\n /**\n * @function\n * @desc Retrieves the next key in the object or null if it doesn't exist\n * @param {Object} obj - Object to get the next key from\n * @param {string} key - Key to base the next key index on\n * @returns {string}|{null} - The next key of the given object or null if one doesn't exist\n */\n getNextObjectKey: function (obj, key) {\n var keys = Object.keys(obj);\n var nextIndex = keys.indexOf(key) + 1;\n\n if (keys.length > nextIndex) {\n return keys[nextIndex];\n }\n\n return null;\n },\n\n /**\n * @function\n * @desc Retrieves the util breakpoints object\n * @returns {Object} - All of the breakpoints\n */\n getBreakpoints: function () {\n return this.breakpoints;\n }\n};\n\nmodule.exports = utils;\n","'use strict';\n\n/**\n * Validate whole form. Requires `this` to be set to form object\n * @param {jQuery.event} event - Event to be canceled if form is invalid.\n * @returns {boolean} - Flag to indicate if form is valid\n */\nfunction validateForm(event) {\n var valid = true;\n if (this.checkValidity && !this.checkValidity()) {\n // safari\n valid = false;\n if (event) {\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n }\n $(this).find('input, select').each(function () {\n if (!this.validity.valid) {\n $(this).trigger('invalid', this.validity);\n }\n });\n }\n return valid;\n}\n\n/**\n * Remove all validation. Should be called every time before revalidating form\n * @param {element} form - Form to be cleared\n * @returns {void}\n */\nfunction clearForm(form) {\n $(form).find('.form-control.is-invalid').removeClass('is-invalid');\n}\n\nmodule.exports = {\n invalid: function () {\n $('form input, form select').on('invalid', function (e) {\n e.preventDefault();\n this.setCustomValidity('');\n if (!this.validity.valid) {\n var validationMessage = this.validationMessage;\n $(this).addClass('is-invalid');\n if (this.validity.patternMismatch && $(this).data('pattern-mismatch')) {\n validationMessage = $(this).data('pattern-mismatch');\n }\n if ((this.validity.rangeOverflow || this.validity.rangeUnderflow)\n && $(this).data('range-error')) {\n validationMessage = $(this).data('range-error');\n }\n if ((this.validity.tooLong || this.validity.tooShort)\n && $(this).data('range-error')) {\n validationMessage = $(this).data('range-error');\n }\n if (this.validity.valueMissing && $(this).data('missing-error')) {\n validationMessage = $(this).data('missing-error');\n }\n $(this).parents('.form-group').find('.invalid-feedback')\n .text(validationMessage);\n }\n });\n },\n\n submit: function () {\n $('form').on('submit', function (e) {\n return validateForm.call(this, e);\n });\n },\n\n buttonClick: function () {\n $('form button[type=\"submit\"], form input[type=\"submit\"]').on('click', function () {\n // clear all errors when trying to submit the form\n clearForm($(this).parents('form'));\n });\n },\n\n functions: {\n validateForm: function (form, event) {\n validateForm.call($(form), event || null);\n },\n clearForm: clearForm\n }\n};\n","'use strict';\nmodule.exports = function () {\n var sizes = ['xs', 'sm', 'md', 'lg', 'xl'];\n\n sizes.forEach(function (size) {\n var selector = '.collapsible-' + size + ' .title, .collapsible-' + size + '>.card-header';\n $('body').on('click', selector, function (e) {\n e.preventDefault();\n $(this).parents('.collapsible-' + size).toggleClass('active');\n });\n });\n};\n","'use strict';\n\n/**\n * Renders a modal window that will track the users consenting to accepting site tracking policy\n */\nfunction showConsentModal() {\n if (!$('.tracking-consent').data('caonline')) {\n return;\n }\n\n var urlContent = $('.tracking-consent').data('url');\n var urlAccept = $('.tracking-consent').data('accept');\n var urlReject = $('.tracking-consent').data('reject');\n var textYes = $('.tracking-consent').data('accepttext');\n var textNo = $('.tracking-consent').data('rejecttext');\n var textHeader = $('.tracking-consent').data('heading');\n\n var htmlString = ''\n + '
'\n + '
'\n + ''\n + '
'\n + '
'\n + textHeader\n + '
'\n + '
'\n + '
'\n + '
'\n + ''\n + ''\n + '
'\n + '
'\n + '
'\n + '
'\n + '
';\n $.spinner().start();\n $('body').append(htmlString);\n\n $.ajax({\n url: urlContent,\n type: 'get',\n dataType: 'html',\n success: function (response) {\n $('.modal-body').html(response);\n },\n error: function () {\n $('#consent-tracking').remove();\n }\n });\n\n $('#consent-tracking .button-wrapper button').click(function (e) {\n e.preventDefault();\n var url = $(this).data('url');\n $.ajax({\n url: url,\n type: 'get',\n dataType: 'json',\n success: function () {\n $('#consent-tracking .modal-body').remove();\n $('#consent-tracking').remove();\n $.spinner().stop();\n },\n error: function () {\n $('#consent-tracking .modal-body').remove();\n $('#consent-tracking').remove();\n $.spinner().stop();\n }\n });\n });\n}\n\nmodule.exports = function () {\n if ($('.consented').length === 0 && $('.tracking-consent').hasClass('api-true')) {\n showConsentModal();\n }\n\n if ($('.tracking-consent').hasClass('api-true')) {\n $('.tracking-consent').click(function () {\n showConsentModal();\n });\n }\n};\n","'use strict';\n\n/**\n * Get cookie value by cookie name from browser\n * @param {string} cookieName - name of the cookie\n * @returns {string} cookie value of the found cookie name\n */\nfunction getCookie(cookieName) {\n var name = cookieName + '=';\n var decodedCookie = decodeURIComponent(document.cookie);\n var cookieArray = decodedCookie.split(';');\n for (var i = 0; i < cookieArray.length; i++) {\n var cookieItem = cookieArray[i];\n while (cookieItem.charAt(0) === ' ') {\n cookieItem = cookieItem.substring(1);\n }\n if (cookieItem.indexOf(name) === 0) {\n return cookieItem.substring(name.length, cookieItem.length);\n }\n }\n return '';\n}\n\nmodule.exports = function () {\n if ($('.valid-cookie-warning').length > 0) {\n var previousSessionID = window.localStorage.getItem('previousSid');\n var currentSessionID = getCookie('sid');\n if (!previousSessionID && currentSessionID) {\n // When a user first time visit the home page,\n // set the previousSessionID to currentSessionID\n // and Show the cookie alert\n previousSessionID = currentSessionID;\n window.localStorage.setItem('previousSid', previousSessionID);\n $('.cookie-warning-messaging').show();\n } else if (previousSessionID && previousSessionID === currentSessionID) {\n // Hide the cookie alert if user is in the same session\n $('.cookie-warning-messaging').hide();\n } else {\n // Clear the previousSessionID from localStorage\n // when user session is changed or expired\n previousSessionID = '';\n window.localStorage.removeItem('previousSid');\n }\n }\n};\n","'use strict';\n\n/**\n * Remove all validation. Should be called every time before revalidating form\n * @param {element} form - Form to be cleared\n * @returns {void}\n */\nfunction clearFormErrors(form) {\n $(form).find('.form-control.is-invalid').removeClass('is-invalid');\n}\n\nmodule.exports = function (formElement, payload) {\n // clear form validation first\n clearFormErrors(formElement);\n $('.alert', formElement).remove();\n\n if (typeof payload === 'object' && payload.fields) {\n Object.keys(payload.fields).forEach(function (key) {\n if (payload.fields[key]) {\n var feedbackElement = $(formElement).find('[name=\"' + key + '\"]')\n .parent()\n .children('.invalid-feedback');\n\n if (feedbackElement.length > 0) {\n if (Array.isArray(payload[key])) {\n feedbackElement.html(payload.fields[key].join('
'));\n } else {\n feedbackElement.html(payload.fields[key]);\n }\n feedbackElement.siblings('.form-control').addClass('is-invalid');\n }\n }\n });\n }\n if (payload && payload.error) {\n var form = $(formElement).prop('tagName') === 'FORM'\n ? $(formElement)\n : $(formElement).parents('form');\n\n form.prepend('
'\n + payload.error.join('
') + '
');\n }\n};\n","'use strict';\n\nmodule.exports = function (selector, keyFunctions, preFunction) {\n $(selector).on('keydown', function (e) {\n var key = e.which;\n var supportedKeyCodes = [37, 38, 39, 40, 27];\n if (supportedKeyCodes.indexOf(key) >= 0) {\n e.preventDefault();\n }\n var returnedScope = preFunction.call(this);\n if (keyFunctions[key]) {\n keyFunctions[key].call(this, returnedScope);\n }\n });\n};\n","'use strict';\n\n/**\n * Show a spinner inside a given element\n * @param {element} $target - Element to block by the veil and spinner.\n * Pass body to block the whole page.\n */\nfunction addSpinner($target) {\n var $veil = $('
');\n $veil.append('
');\n if ($target.get(0).tagName === 'IMG') {\n $target.after($veil);\n $veil.css({ width: $target.width(), height: $target.height() });\n if ($target.parent().css('position') === 'static') {\n $target.parent().css('position', 'relative');\n }\n } else {\n $target.append($veil);\n if ($target.css('position') === 'static') {\n $target.parent().css('position', 'relative');\n $target.parent().addClass('veiled');\n }\n if ($target.get(0).tagName === 'BODY') {\n $veil.find('.spinner').css('position', 'fixed');\n }\n }\n $veil.click(function (e) {\n e.stopPropagation();\n });\n}\n\n/**\n * Remove existing spinner\n * @param {element} $veil - jQuery pointer to the veil element\n */\nfunction removeSpinner($veil) {\n if ($veil.parent().hasClass('veiled')) {\n $veil.parent().css('position', '');\n $veil.parent().removeClass('veiled');\n }\n $veil.off('click');\n $veil.remove();\n}\n\n// element level spinner:\n$.fn.spinner = function () {\n var $element = $(this);\n var Fn = function () {\n this.start = function () {\n if ($element.length) {\n addSpinner($element);\n }\n };\n this.stop = function () {\n if ($element.length) {\n var $veil = $('.veil');\n removeSpinner($veil);\n }\n };\n };\n return new Fn();\n};\n\n// page-level spinner:\n$.spinner = function () {\n var Fn = function () {\n this.start = function () {\n addSpinner($('body'));\n };\n this.stop = function () {\n removeSpinner($('.veil'));\n };\n };\n return new Fn();\n};\n","'use strict';\n\n/**\n * Retrieves the relevant pid value\n * @param {jquery} $el - DOM container for a given add to cart button\n * @return {string} - value to be used when adding product to cart\n */\nfunction getPidValue($el) {\n var pid;\n\n if ($('#quickViewModal').hasClass('show') && !$('.product-set').length) {\n pid = $($el).closest('.modal-content').find('.product-quickview').data('pid');\n } else if ($('.product-set-detail').length || $('.product-set').length) {\n pid = $($el).closest('.product-detail').find('.product-id').text();\n } else {\n pid = $('.product-detail:not(\".bundle-item\")').data('pid');\n }\n\n return pid;\n}\n\n/**\n * Retrieve contextual quantity selector\n * @param {jquery} $el - DOM container for the relevant quantity\n * @return {jquery} - quantity selector DOM container\n */\nfunction getQuantitySelector($el) {\n return $el && $('.set-items').length\n ? $($el).closest('.product-detail').find('.quantity-select')\n : $('.quantity-select');\n}\n\n/**\n * Retrieves the value associated with the Quantity pull-down menu\n * @param {jquery} $el - DOM container for the relevant quantity\n * @return {string} - value found in the quantity input\n */\nfunction getQuantitySelected($el) {\n return getQuantitySelector($el).val();\n}\n\n/**\n * Process the attribute values for an attribute that has image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction processSwatchValues(attr, $productContainer) {\n attr.values.forEach(function (attrValue) {\n var $attrValue = $productContainer.find('[data-attr=\"' + attr.id + '\"] [data-attr-value=\"' +\n attrValue.value + '\"]');\n var $swatchAnchor = $attrValue.parent();\n\n if (attrValue.selected) {\n $attrValue.addClass('selected');\n } else {\n $attrValue.removeClass('selected');\n }\n\n if (attrValue.url) {\n $swatchAnchor.attr('data-href', attrValue.url);\n } else {\n $swatchAnchor.removeAttr('data-href');\n }\n\n // Disable if not selectable\n $attrValue.removeClass('selectable unselectable');\n\n $attrValue.addClass(attrValue.selectable ? 'selectable' : 'unselectable');\n });\n}\n\n/**\n * Process attribute values associated with an attribute that does not have image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction processNonSwatchValues(attr, $productContainer) {\n var $attr = '[data-attr=\"' + attr.id + '\"]';\n var $defaultOption = $productContainer.find($attr + ' .select-' + attr.id);\n for (var i = 0, j = $defaultOption.length; i < j; i++) {\n $($defaultOption)[i].options[0].value = attr.resetUrl;\n }\n\n attr.values.forEach(function (attrValue) {\n var $attrValue = $productContainer\n .find($attr + ' [data-attr-value=\"' + attrValue.value + '\"]');\n $attrValue.attr('value', attrValue.url)\n .removeAttr('disabled');\n\n if (!attrValue.selectable) {\n $attrValue.attr('disabled', true);\n }\n });\n}\n\n/**\n * Routes the handling of attribute processing depending on whether the attribute has image\n * swatches or not\n *\n * @param {Object} attrs - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nfunction updateAttrs(attrs, $productContainer) {\n // Currently, the only attribute type that has image swatches is Color.\n var attrsWithSwatches = ['color'];\n\n attrs.forEach(function (attr) {\n if (attrsWithSwatches.indexOf(attr.id) > -1) {\n processSwatchValues(attr, $productContainer);\n } else {\n processNonSwatchValues(attr, $productContainer);\n }\n });\n}\n\n/**\n * Updates the availability status in the Product Detail Page\n *\n * @param {Object} response - Ajax response object after an\n * attribute value has been [de]selected\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nfunction updateAvailability(response, $productContainer) {\n var availabilityValue = '';\n var availabilityMessages = response.product.availability.messages;\n if (!response.product.readyToOrder) {\n availabilityValue = '
' + response.resources.info_selectforstock + '
';\n } else {\n availabilityMessages.forEach(function (message) {\n availabilityValue += '
' + message + '
';\n });\n }\n\n $($productContainer).trigger('product:updateAvailability', {\n product: response.product,\n $productContainer: $productContainer,\n message: availabilityValue,\n resources: response.resources\n });\n}\n\n/**\n * Generates html for promotions section\n *\n * @param {array} promotions - list of promotions\n * @return {string} - Compiled HTML\n */\nfunction getPromotionsHtml(promotions) {\n if (!promotions) {\n return '';\n }\n\n var html = '';\n\n promotions.forEach(function (promotion) {\n html += '
' + promotion.calloutMsg +\n '
';\n });\n\n return html;\n}\n\n/**\n * Generates html for product attributes section\n *\n * @param {array} attributes - list of attributes\n * @return {string} - Compiled HTML\n */\nfunction getAttributesHtml(attributes) {\n if (!attributes) {\n return '';\n }\n\n var html = '';\n\n attributes.forEach(function (attributeGroup) {\n if (attributeGroup.ID === 'mainAttributes') {\n attributeGroup.attributes.forEach(function (attribute) {\n html += '
' + attribute.label + ': '\n + attribute.value + '
';\n });\n }\n });\n\n return html;\n}\n\n/**\n * @typedef UpdatedOptionValue\n * @type Object\n * @property {string} id - Option value ID for look up\n * @property {string} url - Updated option value selection URL\n */\n\n/**\n * @typedef OptionSelectionResponse\n * @type Object\n * @property {string} priceHtml - Updated price HTML code\n * @property {Object} options - Updated Options\n * @property {string} options.id - Option ID\n * @property {UpdatedOptionValue[]} options.values - Option values\n */\n\n/**\n * Updates DOM using post-option selection Ajax response\n *\n * @param {OptionSelectionResponse} options - Ajax response options from selecting a product option\n * @param {jQuery} $productContainer - DOM element for current product\n */\nfunction updateOptions(options, $productContainer) {\n options.forEach(function (option) {\n var $optionEl = $productContainer.find('.product-option[data-option-id*=\"' + option.id\n + '\"]');\n option.values.forEach(function (value) {\n var valueEl = $optionEl.find('option[data-value-id*=\"' + value.id + '\"]');\n valueEl.val(value.url);\n });\n });\n}\n\n/**\n * Parses JSON from Ajax call made whenever an attribute value is [de]selected\n * @param {Object} response - response from Ajax call\n * @param {Object} response.product - Product object\n * @param {string} response.product.id - Product ID\n * @param {Object[]} response.product.variationAttributes - Product attributes\n * @param {Object[]} response.product.images - Product images\n * @param {boolean} response.product.hasRequiredAttrsSelected - Flag as to whether all required\n * attributes have been selected. Used partially to\n * determine whether the Add to Cart button can be enabled\n * @param {jQuery} $productContainer - DOM element for a given product.\n */\nfunction handleVariantResponse(response, $productContainer) {\n var isChoiceOfBonusProducts =\n $productContainer.parents('.choose-bonus-product-dialog').length > 0;\n var isVariant;\n if (response.product.variationAttributes) {\n updateAttrs(response.product.variationAttributes, $productContainer);\n isVariant = response.product.productType === 'variant';\n if (isChoiceOfBonusProducts && isVariant) {\n $productContainer.parent('.bonus-product-item')\n .data('pid', response.product.id);\n\n $productContainer.parent('.bonus-product-item')\n .data('ready-to-order', response.product.readyToOrder);\n } else {\n $productContainer.attr('data-pid', response.product.id);\n }\n }\n\n // Update primary images\n var primaryImageUrls = response.product.images;\n primaryImageUrls.pdp.forEach(function (imageUrl, idx) {\n $productContainer.find('.primary-images').find('img').eq(idx)\n .attr('src', imageUrl.url);\n });\n\n // Update pricing\n if (!isChoiceOfBonusProducts) {\n var $priceSelector = $('.prices .price', $productContainer).length\n ? $('.prices .price', $productContainer)\n : $('.prices .price');\n $priceSelector.replaceWith(response.product.price.html);\n }\n\n // Update promotions\n $('.promotions').empty().html(getPromotionsHtml(response.product.promotions));\n\n updateAvailability(response, $productContainer);\n\n if (isChoiceOfBonusProducts) {\n var $selectButton = $productContainer.find('.select-bonus-product');\n $selectButton.trigger('bonusproduct:updateSelectButton', {\n product: response.product, $productContainer: $productContainer\n });\n } else {\n // Enable \"Add to Cart\" button if all required attributes have been selected\n $('button.add-to-cart, button.add-to-cart-global, button.update-cart-product-global').trigger('product:updateAddToCart', {\n product: response.product, $productContainer: $productContainer\n }).trigger('product:statusUpdate', response.product);\n }\n\n // Update attributes\n $productContainer.find('.main-attributes').empty()\n .html(getAttributesHtml(response.product.attributes));\n}\n\n/**\n * @typespec UpdatedQuantity\n * @type Object\n * @property {boolean} selected - Whether the quantity has been selected\n * @property {string} value - The number of products to purchase\n * @property {string} url - Compiled URL that specifies variation attributes, product ID, options,\n * etc.\n */\n\n/**\n * Updates the quantity DOM elements post Ajax call\n * @param {UpdatedQuantity[]} quantities -\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction updateQuantities(quantities, $productContainer) {\n if (!($productContainer.parent('.bonus-product-item').length > 0)) {\n var optionsHtml = quantities.map(function (quantity) {\n var selected = quantity.selected ? ' selected ' : '';\n return '';\n }).join('');\n getQuantitySelector($productContainer).empty().html(optionsHtml);\n }\n}\n\n/**\n * updates the product view when a product attribute is selected or deselected or when\n * changing quantity\n * @param {string} selectedValueUrl - the Url for the selected variation value\n * @param {jQuery} $productContainer - DOM element for current product\n */\nfunction attributeSelect(selectedValueUrl, $productContainer) {\n if (selectedValueUrl) {\n $('body').trigger('product:beforeAttributeSelect',\n { url: selectedValueUrl, container: $productContainer });\n\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n success: function (data) {\n handleVariantResponse(data, $productContainer);\n updateOptions(data.product.options, $productContainer);\n updateQuantities(data.product.quantities, $productContainer);\n $('body').trigger('product:afterAttributeSelect',\n { data: data, container: $productContainer });\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n}\n\n/**\n * Retrieves url to use when adding a product to the cart\n *\n * @return {string} - The provided URL to use when adding a product to the cart\n */\nfunction getAddToCartUrl() {\n return $('.add-to-cart-url').val();\n}\n\n/**\n * Parses the html for a modal window\n * @param {string} html - representing the body and footer of the modal window\n *\n * @return {Object} - Object with properties body and footer.\n */\nfunction parseHtml(html) {\n var $html = $('
').append($.parseHTML(html));\n\n var body = $html.find('.choice-of-bonus-product');\n var footer = $html.find('.modal-footer').children();\n\n return { body: body, footer: footer };\n}\n\n/**\n * Retrieves url to use when adding a product to the cart\n *\n * @param {Object} data - data object used to fill in dynamic portions of the html\n */\nfunction chooseBonusProducts(data) {\n $('.modal-body').spinner().start();\n\n if ($('#chooseBonusProductModal').length !== 0) {\n $('#chooseBonusProductModal').remove();\n }\n var bonusUrl;\n if (data.bonusChoiceRuleBased) {\n bonusUrl = data.showProductsUrlRuleBased;\n } else {\n bonusUrl = data.showProductsUrlListBased;\n }\n\n var htmlString = ''\n + '
'\n + '
'\n + ''\n + '
'\n + '
'\n + ' ' + data.labels.selectprods + ''\n + ' '\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
';\n $('body').append(htmlString);\n $('.modal-body').spinner().start();\n\n $.ajax({\n url: bonusUrl,\n method: 'GET',\n dataType: 'html',\n success: function (html) {\n var parsedHtml = parseHtml(html);\n $('#chooseBonusProductModal .modal-body').empty();\n $('#chooseBonusProductModal .modal-body').html(parsedHtml.body);\n $('#chooseBonusProductModal .modal-footer').html(parsedHtml.footer);\n $('#chooseBonusProductModal').modal('show');\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n}\n\n/**\n * Updates the Mini-Cart quantity value after the customer has pressed the \"Add to Cart\" button\n * @param {string} response - ajax response from clicking the add to cart button\n */\nfunction handlePostCartAdd(response) {\n $('.minicart').trigger('count:update', response);\n var messageType = response.error ? 'alert-danger' : 'alert-success';\n // show add to cart toast\n if (response.newBonusDiscountLineItem\n && Object.keys(response.newBonusDiscountLineItem).length !== 0) {\n chooseBonusProducts(response.newBonusDiscountLineItem);\n } else {\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append(\n '
'\n );\n }\n\n $('.add-to-cart-messages').append(\n '
'\n + response.message\n + '
'\n );\n\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n }, 5000);\n }\n}\n\n/**\n * Retrieves the bundle product item ID's for the Controller to replace bundle master product\n * items with their selected variants\n *\n * @return {string[]} - List of selected bundle product item ID's\n */\nfunction getChildProducts() {\n var childProducts = [];\n $('.bundle-item').each(function () {\n childProducts.push({\n pid: $(this).find('.product-id').text(),\n quantity: parseInt($(this).find('label.quantity').data('quantity'), 10)\n });\n });\n\n return childProducts.length ? JSON.stringify(childProducts) : [];\n}\n\n/**\n * Retrieve product options\n *\n * @param {jQuery} $productContainer - DOM element for current product\n * @return {string} - Product options and their selected values\n */\nfunction getOptions($productContainer) {\n var options = $productContainer\n .find('.product-option')\n .map(function () {\n var $elOption = $(this).find('.options-select');\n var urlValue = $elOption.val();\n var selectedValueId = $elOption.find('option[value=\"' + urlValue + '\"]')\n .data('value-id');\n return {\n optionId: $(this).data('option-id'),\n selectedValueId: selectedValueId\n };\n }).toArray();\n\n return JSON.stringify(options);\n}\n\nmodule.exports = {\n attributeSelect: attributeSelect,\n methods: {\n editBonusProducts: function (data) {\n chooseBonusProducts(data);\n }\n },\n colorAttribute: function () {\n $(document).on('click', '[data-attr=\"color\"] a', function (e) {\n e.preventDefault();\n\n if ($(this).attr('disabled')) {\n return;\n }\n var $productContainer = $(this).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.product-detail');\n }\n\n attributeSelect(e.currentTarget.href, $productContainer);\n });\n },\n\n selectAttribute: function () {\n $(document).on('change', 'select[class*=\"select-\"], .options-select', function (e) {\n e.preventDefault();\n\n var $productContainer = $(this).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.product-detail');\n }\n attributeSelect(e.currentTarget.value, $productContainer);\n });\n },\n\n availability: function () {\n $(document).on('change', '.quantity-select', function (e) {\n e.preventDefault();\n\n var $productContainer = $(this).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.modal-content').find('.product-quickview');\n }\n\n if ($('.bundle-items', $productContainer).length === 0) {\n attributeSelect($(e.currentTarget).find('option:selected').data('url'),\n $productContainer);\n }\n });\n },\n\n addToCart: function () {\n $(document).on('click', 'button.add-to-cart, button.add-to-cart-global', function () {\n var addToCartUrl;\n var pid;\n var pidsObj;\n var setPids;\n\n $('body').trigger('product:beforeAddToCart', this);\n\n if ($('.set-items').length && $(this).hasClass('add-to-cart-global')) {\n setPids = [];\n\n $('.product-detail').each(function () {\n if (!$(this).hasClass('product-set-detail')) {\n setPids.push({\n pid: $(this).find('.product-id').text(),\n qty: $(this).find('.quantity-select').val(),\n options: getOptions($(this))\n });\n }\n });\n pidsObj = JSON.stringify(setPids);\n }\n\n pid = getPidValue($(this));\n\n var $productContainer = $(this).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.quick-view-dialog').find('.product-detail');\n }\n\n addToCartUrl = getAddToCartUrl();\n\n var form = {\n pid: pid,\n pidsObj: pidsObj,\n childProducts: getChildProducts(),\n quantity: getQuantitySelected($(this))\n };\n\n if (!$('.bundle-item').length) {\n form.options = getOptions($productContainer);\n }\n\n $(this).trigger('updateAddToCartFormData', form);\n if (addToCartUrl) {\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: function (data) {\n handlePostCartAdd(data);\n $('body').trigger('product:afterAddToCart', data);\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n });\n },\n selectBonusProduct: function () {\n $(document).on('click', '.select-bonus-product', function () {\n var $choiceOfBonusProduct = $(this).parents('.choice-of-bonus-product');\n var pid = $(this).data('pid');\n var maxPids = $('.choose-bonus-product-dialog').data('total-qty');\n var submittedQty = parseInt($(this).parents('.choice-of-bonus-product').find('.bonus-quantity-select').val(), 10);\n var totalQty = 0;\n $.each($('#chooseBonusProductModal .selected-bonus-products .selected-pid'), function () {\n totalQty += $(this).data('qty');\n });\n totalQty += submittedQty;\n var optionID = $(this).parents('.choice-of-bonus-product').find('.product-option').data('option-id');\n var valueId = $(this).parents('.choice-of-bonus-product').find('.options-select option:selected').data('valueId');\n if (totalQty <= maxPids) {\n var selectedBonusProductHtml = ''\n + '
'\n + '
'\n + $choiceOfBonusProduct.find('.product-name').html()\n + '
'\n + '
'\n + '
'\n ;\n $('#chooseBonusProductModal .selected-bonus-products').append(selectedBonusProductHtml);\n $('.pre-cart-products').html(totalQty);\n $('.selected-bonus-products .bonus-summary').removeClass('alert-danger');\n } else {\n $('.selected-bonus-products .bonus-summary').addClass('alert-danger');\n }\n });\n },\n removeBonusProduct: function () {\n $(document).on('click', '.selected-pid', function () {\n $(this).remove();\n var $selected = $('#chooseBonusProductModal .selected-bonus-products .selected-pid');\n var count = 0;\n if ($selected.length) {\n $selected.each(function () {\n count += parseInt($(this).data('qty'), 10);\n });\n }\n\n $('.pre-cart-products').html(count);\n $('.selected-bonus-products .bonus-summary').removeClass('alert-danger');\n });\n },\n enableBonusProductSelection: function () {\n $('body').on('bonusproduct:updateSelectButton', function (e, response) {\n $('button.select-bonus-product', response.$productContainer).attr('disabled',\n (!response.product.readyToOrder || !response.product.available));\n var pid = response.product.id;\n $('button.select-bonus-product').data('pid', pid);\n });\n },\n showMoreBonusProducts: function () {\n $(document).on('click', '.show-more-bonus-products', function () {\n var url = $(this).data('url');\n $('.modal-content').spinner().start();\n $.ajax({\n url: url,\n method: 'GET',\n success: function (html) {\n var parsedHtml = parseHtml(html);\n $('.modal-body').append(parsedHtml.body);\n $('.show-more-bonus-products:first').remove();\n $('.modal-content').spinner().stop();\n },\n error: function () {\n $('.modal-content').spinner().stop();\n }\n });\n });\n },\n addBonusProductsToCart: function () {\n $(document).on('click', '.add-bonus-products', function () {\n var $readyToOrderBonusProducts = $('.choose-bonus-product-dialog .selected-pid');\n var queryString = '?pids=';\n var url = $('.choose-bonus-product-dialog').data('addtocarturl');\n var pidsObject = {\n bonusProducts: []\n };\n\n $.each($readyToOrderBonusProducts, function () {\n var qtyOption =\n parseInt($(this)\n .data('qty'), 10);\n\n var option = null;\n if (qtyOption > 0) {\n if ($(this).data('optionid') && $(this).data('option-selected-value')) {\n option = {};\n option.optionId = $(this).data('optionid');\n option.productId = $(this).data('pid');\n option.selectedValueId = $(this).data('option-selected-value');\n }\n pidsObject.bonusProducts.push({\n pid: $(this).data('pid'),\n qty: qtyOption,\n options: [option]\n });\n pidsObject.totalQty = parseInt($('.pre-cart-products').html(), 10);\n }\n });\n queryString += JSON.stringify(pidsObject);\n queryString = queryString + '&uuid=' + $('.choose-bonus-product-dialog').data('uuid');\n queryString = queryString + '&pliuuid=' + $('.choose-bonus-product-dialog').data('pliuuid');\n $.spinner().start();\n $.ajax({\n url: url + queryString,\n method: 'POST',\n success: function (data) {\n $.spinner().stop();\n if (data.error) {\n $('.error-choice-of-bonus-products')\n .html(data.errorMessage);\n } else {\n $('.configure-bonus-product-attributes').html(data);\n $('.bonus-products-step2').removeClass('hidden-xl-down');\n $('#chooseBonusProductModal').modal('hide');\n\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append(\n '
'\n );\n }\n $('.minicart-quantity').html(data.totalQty);\n $('.add-to-cart-messages').append(\n '
'\n + data.msgSuccess + '
'\n );\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n if ($('.cart-page').length) {\n location.reload();\n }\n }, 3000);\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n });\n },\n\n getPidValue: getPidValue,\n getQuantitySelected: getQuantitySelected,\n getOptions: getOptions,\n getChildProducts: getChildProducts,\n handlePostCartAdd: handlePostCartAdd,\n handleVariantResponse: handleVariantResponse,\n updateOptions: updateOptions,\n updateQuantities: updateQuantities\n};\n","'use strict';\nvar base = require('./base');\n\nmodule.exports = {\n availability: base.availability,\n\n addToCart: base.addToCart,\n\n updateAttributesAndDetails: function () {\n $('body').on('product:statusUpdate', function (e, data) {\n var $productContainer = $('.product-detail[data-pid=\"' + data.id + '\"]');\n\n $productContainer.find('.description-and-detail .product-attributes')\n .empty()\n .html(data.attributesHtml);\n\n if (data.shortDescription) {\n $productContainer.find('.description-and-detail .description')\n .removeClass('hidden-xl-down');\n $productContainer.find('.description-and-detail .description .content')\n .empty()\n .html(data.shortDescription);\n } else {\n $productContainer.find('.description-and-detail .description')\n .addClass('hidden-xl-down');\n }\n\n if (data.longDescription) {\n $productContainer.find('.description-and-detail .details')\n .removeClass('hidden-xl-down');\n $productContainer.find('.description-and-detail .details .content')\n .empty()\n .html(data.longDescription);\n } else {\n $productContainer.find('.description-and-detail .details')\n .addClass('hidden-xl-down');\n }\n });\n },\n\n showSpinner: function () {\n $('body').on('product:beforeAddToCart product:beforeAttributeSelect', function () {\n $.spinner().start();\n });\n },\n updateAttribute: function () {\n $('body').on('product:afterAttributeSelect', function (e, response) {\n if ($('.product-detail>.bundle-items').length) {\n response.container.data('pid', response.data.product.id);\n response.container.find('.product-id').text(response.data.product.id);\n } else if ($('.product-set-detail').eq(0)) {\n response.container.data('pid', response.data.product.id);\n response.container.find('.product-id').text(response.data.product.id);\n } else {\n $('.product-id').text(response.data.product.id);\n $('.product-detail:not(\".bundle-item\")').data('pid', response.data.product.id);\n }\n });\n },\n updateAddToCart: function () {\n $('body').on('product:updateAddToCart', function (e, response) {\n // update local add to cart (for sets)\n $('button.add-to-cart', response.$productContainer).attr('disabled',\n (!response.product.readyToOrder || !response.product.available));\n\n var enable = $('.product-availability').toArray().every(function (item) {\n return $(item).data('available') && $(item).data('ready-to-order');\n });\n $('button.add-to-cart-global').attr('disabled', !enable);\n });\n },\n updateAvailability: function () {\n $('body').on('product:updateAvailability', function (e, response) {\n $('div.availability', response.$productContainer)\n .data('ready-to-order', response.product.readyToOrder)\n .data('available', response.product.available);\n\n $('.availability-msg', response.$productContainer)\n .empty().html(response.message);\n\n if ($('.global-availability').length) {\n var allAvailable = $('.product-availability').toArray()\n .every(function (item) { return $(item).data('available'); });\n\n var allReady = $('.product-availability').toArray()\n .every(function (item) { return $(item).data('ready-to-order'); });\n\n $('.global-availability')\n .data('ready-to-order', allReady)\n .data('available', allAvailable);\n\n $('.global-availability .availability-msg').empty()\n .html(allReady ? response.message : response.resources.info_selectforstock);\n }\n });\n },\n sizeChart: function () {\n var $sizeChart = $('.size-chart-collapsible');\n $('.size-chart a').on('click', function (e) {\n e.preventDefault();\n var url = $(this).attr('href');\n if ($sizeChart.is(':empty')) {\n $.ajax({\n url: url,\n type: 'get',\n dataType: 'json',\n success: function (data) {\n $sizeChart.append(data.content);\n }\n });\n }\n $sizeChart.toggleClass('active');\n });\n\n $('body').on('click touchstart', function (e) {\n if ($('.size-chart').has(e.target).length <= 0) {\n $sizeChart.removeClass('active');\n }\n });\n }\n};\n","require('bootstrap/js/src/util.js');\nrequire('bootstrap/js/src/alert.js');\n// require('bootstrap/js/src/button.js');\nrequire('bootstrap/js/src/carousel.js');\nrequire('bootstrap/js/src/collapse.js');\n// require('bootstrap/js/src/dropdown.js');\nrequire('bootstrap/js/src/modal.js');\nrequire('bootstrap/js/src/scrollspy.js');\nrequire('bootstrap/js/src/tab.js');\nrequire('bootstrap/js/src/tooltip.js');\n// require('bootstrap/js/src/popover.js');\n","'use strict';\n\nmodule.exports = function (include) {\n if (typeof include === 'function') {\n include();\n } else if (typeof include === 'object') {\n Object.keys(include).forEach(function (key) {\n if (typeof include[key] === 'function') {\n include[key]();\n }\n });\n }\n};\n","'use strict';\n\n/* global pageContext */\nvar dataLayer = window.dataLayer;\n\n/* global dataLayer */\n\n/**\n * Events are divided up by name space so only the\n * events that are needed are initialized.\n */\nvar events = {\n account: function () {},\n cart: function () {\n // Assign Product Obj when remove from cart click for modal confirmation\n $(document).on('click', '.hidden-md-down .remove-product', function () {\n var productObj = $.parseJSON($(this).attr('data-gtmdata'));\n var currency = $(this).attr('data-currency');\n // Send removeFromCart event when confirmation is complete\n $(document).on('click', '.cart-delete-confirmation-btn', function () {\n removeFromCart(productObj, getQuantityValue(productObj), currency);\n });\n });\n $('.cart-page .remove-btn.remove-product').on('click', function () {\n var productObj = $.parseJSON($(this).attr('data-gtmdata'));\n var currency = $(this).attr('data-currency');\n removeFromCart((productObj), getQuantityValue(productObj), currency);\n });\n },\n checkout: function () {\n $(document).on('click', '.shipping-summary .edit-button', function () {\n updateCheckoutStep(3);\n });\n $(document).on('click', '.submit-shipping', function () {\n updateCheckoutStep(4);\n });\n $(document).on('click', '.validate-shipping', function () {\n updateCheckoutStep(4);\n });\n\n $(document).on('click', '.submit-payment', function () {\n if ($('.submit-payment').css('display') === 'none') {\n updateCheckoutStep(4);\n } else {\n updateCheckoutStep(5);\n }\n });\n\n $(document).on('click', '.place-order', function () {\n updateCheckoutStep(5);\n });\n },\n compare: function () {},\n product: function () {\n $('.btn.add-to-cart').on('click', function () {\n addToCart($.parseJSON($(this).attr('data-gtmdata')), $('.quantity-select').val(), $(this).attr('data-currency'));\n });\n },\n search: function () {},\n storefront: function () {},\n wishlist: function () {},\n // events that should happen on every page\n all: function () {\n $('.pdp-link .link, .image-container a').on('click', function () {\n productClick($.parseJSON($(this).attr('data-gtmdata')));\n });\n $('.thumb-link').on('click', function () {\n productClick($.parseJSON($(this).attr('data-gtmdata')));\n });\n $('.has-sub-menu').on('click', function () {\n pushEvent('trackEvent', 'User Action', 'Header Click', $(this).html());\n });\n $('.primary-logo').on('click', function () {\n pushEvent('trackEvent', 'User Action', 'Header Click', 'Home Link');\n });\n $(document).on('click', '.remove-line-item button.remove-product', function () {\n var productObj = $.parseJSON($(this).attr('data-gtmdata'));\n var currency = $(this).attr('data-currency');\n $(document).on('click', '.cart-delete-confirmation-btn', function () {\n removeFromCart(productObj, getQuantityValue(productObj), currency);\n });\n });\n }\n};\n\n/**\n * Updates the current step in the checkout flow\n * @param {Integer} step the step number the flow is currently on\n */\nfunction updateCheckoutStep(step) {\n var obj = {\n event: 'checkout',\n ecommerce: {\n checkout: {\n actionField: {\n step: step\n }\n }\n }\n };\n dataLayer.push(obj);\n}\n\n/**\n * @param {Object} productObject The product data\n * @description gets the data for a product click\n * @TODO revisit the element event_info.label when Quickview is implemented\n */\nfunction productClick (productObject) {\n var obj = {\n event: 'productClick',\n event_info: {\n label: 'PDP'\n },\n ecommerce: {\n click: {\n actionField: {list: 'SearchResults'},\n products: []\n }\n }\n };\n obj.ecommerce.click.products.push(productObject);\n dataLayer.push(obj);\n}\n\n/**\n * @description Click event for add product to cart\n * @param {Object} productObject The product data\n * @param {String} quantity\n * @param {String} currency\n */\nfunction addToCart (productObject, quantity, currency) {\n var quantityObj = {'quantity': quantity},\n obj = {\n event: 'addToCart',\n ecommerce: {\n add: {\n products: []\n },\n currencyCode: currency\n }\n };\n obj.ecommerce.add.products.push($.extend(productObject,quantityObj));\n dataLayer.push(obj);\n}\n\n/**\n * @description Convenience method for getting quantity went removing\n * @param {Object} productObj productObj\n * @return {int} quantity value of quantity\n */\nfunction getQuantityValue(productObj) {\n var quantity = 1;\n $('select.quantity').each(function () {\n var datapid = $(this).attr('data-pid');\n if (datapid === productObj.id || datapid === productObj.childID) {\n quantity = $(this).val();\n }\n });\n return quantity;\n}\n\n/**\n *\n * @param {Object} productObject\n * @param {String|Number} quantity\n * @param {string} currency\n */\nfunction removeFromCart (productObject, quantity, currency) {\n var quantityObj = {'quantity': quantity},\n obj = {\n event: 'removeFromCart',\n ecommerce: {\n remove: {\n products: []\n },\n currencyCode: currency\n }\n };\n obj.ecommerce.remove.products.push($.extend(productObject,quantityObj));\n dataLayer.push(obj);\n}\n\n/**\n * @description Convenience method for creating a click event.\n * @param {String} event\n * @param {String} eventCategory\n * @param {String} eventAction\n * @param {String} eventLabel\n */\nfunction pushEvent (event, eventCategory, eventAction, eventLabel) {\n dataLayer.push({\n event: event,\n eventCategory: eventCategory,\n eventAction: eventAction,\n eventLabel: eventLabel\n });\n}\n\n/**\n*\n* @description Initialize the tag manager functionality\n* @param {string} nameSpace The current name space\n*/\nexports.init = function (nameSpace) {\n var ns = nameSpace || pageContext.ns;\n if (ns && events[ns]) {\n events[ns]();\n }\n events.all();\n};\n","'use strict';\n\nvar base = require('../product/base');\n\n/**\n * appends params to a url\n * @param {string} url - Original url\n * @param {Object} params - Parameters to append\n * @returns {string} result url with appended parameters\n */\nfunction appendToUrl(url, params) {\n var newUrl = url;\n newUrl += (newUrl.indexOf('?') !== -1 ? '&' : '?') + Object.keys(params).map(function (key) {\n return key + '=' + encodeURIComponent(params[key]);\n }).join('&');\n\n return newUrl;\n}\n\n/**\n * Checks whether the basket is valid. if invalid displays error message and disables\n * checkout button\n * @param {Object} data - AJAX response from the server\n */\nfunction validateBasket(data) {\n if (data.valid.error) {\n if (data.valid.message) {\n var errorHtml = '
' +\n '' + data.valid.message + '
';\n\n $('.cart-error').append(errorHtml);\n } else {\n $('.number-of-items').empty().append(data.resources.numberOfItems);\n $('.minicart-quantity').empty().append(data.numItems);\n $('.minicart .popover').empty();\n $('.minicart .popover').removeClass('show');\n }\n\n $('.checkout-btn').addClass('disabled');\n } else {\n $('.checkout-btn').removeClass('disabled');\n }\n}\n\n/**\n * re-renders the order totals and the number of items in the cart\n * @param {Object} data - AJAX response from the server\n */\nfunction updateCartTotals(data) {\n $('.number-of-items').empty().append(data.resources.numberOfItems);\n if ($('.checkout__steps-wrap').length) {\n if ($('.card-header-custom .small-text').length) {\n $('.card-header-custom .small-text').text(data.resources.numberOfItems);\n }\n }\n $('.shipping-cost').empty().append(data.totals.totalShippingCost);\n $('.tax-total').empty().append(data.totals.totalTax);\n if ($('.grand-total').length && $('.grand-total').hasClass('js-checkoutsummarytotal')) {\n $('.grand-total span.grand-total-sum').empty().append(data.totals.grandTotal);\n } else {\n $('.grand-total').empty().append(data.totals.grandTotal);\n }\n $('.sub-total').empty().append(data.totals.subTotal);\n $('.minicart-quantity').empty().append(data.numItems);\n\n if (data.totals.orderLevelDiscountTotal.value > 0) {\n $('.order-discount').removeClass('hide-order-discount');\n $('.order-discount-total').empty()\n .append('- ' + data.totals.orderLevelDiscountTotal.formatted);\n } else {\n $('.order-discount').addClass('hide-order-discount');\n }\n\n if (data.totals.shippingLevelDiscountTotal.value > 0) {\n $('.shipping-discount').removeClass('hide-shipping-discount');\n $('.shipping-discount-total').empty().append('- ' +\n data.totals.shippingLevelDiscountTotal.formatted);\n } else {\n $('.shipping-discount').addClass('hide-shipping-discount');\n }\n\n data.items.forEach(function (item) {\n $('.item-' + item.UUID).empty().append(item.renderedPromotions);\n if (item.isBonusProductLineItem === false) {\n if (item.priceTotal.nonAdjustedBasePrice) {\n $('.item-nonadjusted-' + item.UUID).empty().append(item.priceTotal.nonAdjustedBasePrice);\n $('.strike-through.non-adjusted-price.' + item.UUID).removeClass('non-adjusted-price');\n } else {\n $('.item-nonadjusted-' + item.UUID).empty();\n $('.strike-through.non-adjusted-price.' + item.UUID).addClass('non-adjusted-price');\n }\n $('.item-unit-' + item.UUID).empty().append(item.priceTotal.basePrice);\n $('.item-total-' + item.UUID).empty().append(item.priceTotal.renderedPrice);\n // Warranty Updates\n if ($('.uuid-' + item.UUID).find('.js-warrantytotalprice').length) {\n if ($('.uuid-' + item.UUID).find('.js-warrantytotalprice').hasClass('isbundleitem')) {\n $('.uuid-' + item.UUID).find('.js-warrantytotalprice').text($('.js-site-currencysymbol').val() + Number(item.warrantyData.warrantyUnitPrice).toFixed(2));\n } else {\n $('.uuid-' + item.UUID).find('.js-warrantytotalprice').text($('.js-site-currencysymbol').val() + Number(item.warrantyData.warrantyUnitPrice * item.quantity).toFixed(2));\n }\n }\n if ($('.checkout__steps-wrap').length) {\n if ($('.product-summary-block .product-line-item[data-product-line-item=' + item.UUID + ']').length) {\n if ($('.product-summary-block .product-line-item[data-product-line-item=' + item.UUID + ']').find('.js-warrantytotalprice').length) {\n if ($('.product-summary-block .product-line-item[data-product-line-item=' + item.UUID + ']').find('.js-warrantytotalprice').hasClass('isbundleitem')) {\n $('.product-summary-block .product-line-item[data-product-line-item=' + item.UUID + ']').find('.js-warrantytotalprice').text($('.js-site-currencysymbol').val() + Number(item.warrantyData.warrantyUnitPrice).toFixed(2));\n } else {\n $('.product-summary-block .product-line-item[data-product-line-item=' + item.UUID + ']').find('.js-warrantytotalprice').text($('.js-site-currencysymbol').val() + Number(item.warrantyData.warrantyUnitPrice * item.quantity).toFixed(2));\n }\n }\n $('.product-summary-block .product-line-item[data-product-line-item=' + item.UUID + ']').find('.line-item-pricing-info .qty-card-quantity-count').text(item.quantity);\n }\n }\n }\n });\n\n if (data) {\n var affirmSubtotal = data.totals && data.totals.subTotal.length > 0 ? data.totals.subTotal.replace(/[^\\d.]+/g, '') : 0;\n if ($('.js-affirm-cart-total').length > 0) {\n $('.js-affirm-cart-total').attr('data-amount', affirmSubtotal * 100);\n // Display the affirm section if total more than threshold\n if (Number(affirmSubtotal) >= Number($('.js-affirm-cart-mintotal').val())) {\n if (data.hasWarrantyItems) {\n $('.js-affirm-cart-total').addClass('d-none');\n } else {\n $('.js-affirm-cart-total').removeClass('d-none');\n }\n } else {\n $('.js-affirm-cart-total').addClass('d-none');\n }\n }\n if ($('.js-affirm-minicart-total').length > 0) {\n $('.js-affirm-minicart-total').attr('data-amount', affirmSubtotal * 100);\n // Display the affirm section if total more than threshold\n if (Number(affirmSubtotal) >= Number($('.js-affirm-minicart-mintotal').val())) {\n if (data.hasWarrantyItems) {\n $('.js-affirm-minicart-total').addClass('d-none');\n } else {\n $('.js-affirm-minicart-total').removeClass('d-none');\n }\n } else {\n $('.js-affirm-minicart-total').addClass('d-none');\n }\n }\n if ($('.js-affirm-checkout-mintotal').length > 0) {\n // reload the page if qty updated in checkout\n // reload needed as affirm totals needs to be updated and basket object\n location.reload();\n }\n if (typeof affirm !== 'undefined') { // eslint-disable-line\n affirm.ui.ready(function() { // eslint-disable-line\n affirm.ui.refresh(); // eslint-disable-line\n });\n }\n }\n}\n\n/**\n * re-renders the order totals and the number of items in the cart\n * @param {Object} message - Error message to display\n */\nfunction createErrorNotification(message) {\n if ($('.alert-danger').length < 1) {\n var errorHtml = '
' +\n '' + message + '
';\n\n $('.cart-error').append(errorHtml);\n }\n}\n\n/**\n * re-renders the approaching discount messages\n * @param {Object} approachingDiscounts - updated approaching discounts for the cart\n */\nfunction updateApproachingDiscounts(approachingDiscounts) {\n var html = '';\n $('.approaching-discounts').empty();\n if (approachingDiscounts.length > 0) {\n approachingDiscounts.forEach(function (item) {\n html += '
'\n + item.discountMsg + '
';\n });\n }\n $('.approaching-discounts').append(html);\n}\n\n/**\n * Updates the availability of a product line item\n * @param {Object} data - AJAX response from the server\n * @param {string} uuid - The uuid of the product line item to update\n */\nfunction updateAvailability(data, uuid) {\n var lineItem;\n var messages = '';\n\n for (var i = 0; i < data.items.length; i++) {\n if (data.items[i].UUID === uuid) {\n lineItem = data.items[i];\n break;\n }\n }\n\n if (lineItem) {\n $('.availability-' + lineItem.UUID).empty();\n }\n\n if (lineItem && lineItem.availability) {\n if (lineItem.availability.messages) {\n lineItem.availability.messages.forEach(function (message) {\n messages += '

' + message + '

';\n });\n }\n\n /* if (lineItem.availability.inStockDate) {\n messages += '

'\n + lineItem.availability.inStockDate\n + '

';\n }*/\n }\n\n if (lineItem) {\n $('.availability-' + lineItem.UUID).html(messages);\n }\n}\n\n/**\n * Finds an element in the array that matches search parameter\n * @param {array} array - array of items to search\n * @param {function} match - function that takes an element and returns a boolean indicating if the match is made\n * @returns {Object|null} - returns an element of the array that matched the query.\n */\nfunction findItem(array, match) {\n for (var i = 0, l = array.length; i < l; i++) {\n if (match.call(this, array[i])) {\n return array[i];\n }\n }\n return null;\n}\n\n/**\n * Updates details of a product line item\n * @param {Object} data - AJAX response from the server\n * @param {string} uuid - The uuid of the product line item to update\n */\nfunction updateProductDetails(data, uuid) {\n var lineItem = findItem(data.cartModel.items, function (item) {\n return item.UUID === uuid;\n });\n\n if (lineItem.variationAttributes) {\n var colorAttr = findItem(lineItem.variationAttributes, function (attr) {\n return attr.attributeId === 'color';\n });\n\n if (colorAttr) {\n var colorSelector = '.color-' + uuid;\n var newColor = 'Color: ' + colorAttr.displayValue;\n $(colorSelector).text(newColor);\n }\n\n var sizeAttr = findItem(lineItem.variationAttributes, function (attr) {\n return attr.attributeId === 'size';\n });\n\n if (sizeAttr) {\n var sizeSelector = '.size-' + uuid;\n var newSize = 'Size: ' + sizeAttr.displayValue;\n $(sizeSelector).text(newSize);\n }\n\n var cameraAttr = findItem(lineItem.variationAttributes, function (attr) {\n return attr.id === 'numbercameras';\n });\n\n if (cameraAttr) {\n var cameraSelector = '.numbercameras-' + uuid;\n var newNumber = 'Number of Cameras: ' + cameraAttr.displayValue;\n $(cameraSelector).text(newNumber);\n }\n\n var lightAttr = findItem(lineItem.variationAttributes, function (attr) {\n return attr.id === 'Number of Lights';\n });\n\n if (lightAttr) {\n var lightSelector = '.Lights-' + uuid;\n var newNumberLights = 'Number of Lights: ' + lightAttr.displayValue;\n $(lightSelector).text(newNumberLights);\n }\n\n var qCamAttr = findItem(lineItem.variationAttributes, function (attr) {\n return attr.id === 'Q.cameras';\n });\n\n if (qCamAttr) {\n var qCamSelector = 'p[class$=\"Q.cameras-' + uuid + '\"]';\n var newNumberCams = 'Select Camera: ' + qCamAttr.displayValue;\n $(qCamSelector).text(newNumberCams);\n }\n\n var imageSelector = '.card.product-info.uuid-' + uuid + ' .item-image > img';\n $(imageSelector).attr('src', lineItem.images.small[0].url);\n $(imageSelector).attr('alt', lineItem.images.small[0].alt);\n $(imageSelector).attr('title', lineItem.images.small[0].title);\n }\n\n var qtySelector = '.quantity[data-uuid=\"' + uuid + '\"]';\n $(qtySelector).val(lineItem.quantity);\n $(qtySelector).data('pid', data.newProductId);\n\n $('.remove-product[data-uuid=\"' + uuid + '\"]').data('pid', data.newProductId);\n\n var priceSelector = '.line-item-price-' + uuid + ' .sales .value';\n $(priceSelector).text(lineItem.price.sales.formatted);\n $(priceSelector).attr('content', lineItem.price.sales.decimalPrice);\n\n if (lineItem.price.list) {\n var listPriceSelector = '.line-item-price-' + uuid + ' .list .value';\n $(listPriceSelector).text(lineItem.price.list.formatted);\n $(listPriceSelector).attr('content', lineItem.price.list.decimalPrice);\n }\n\n $('.uuid-' + uuid + ' .line-item-name').html('' + lineItem.productName + '');\n}\n\n/**\n * Generates the modal window on the first call.\n *\n */\nfunction getModalHtmlElement() {\n if ($('#editProductModal').length !== 0) {\n $('#editProductModal').remove();\n }\n var htmlString = ''\n + '
'\n + '
'\n + ''\n + '
'\n + '
'\n + ' '\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
';\n $('body').append(htmlString);\n}\n\n/**\n * Parses the html for a modal window\n * @param {string} html - representing the body and footer of the modal window\n *\n * @return {Object} - Object with properties body and footer.\n */\nfunction parseHtml(html) {\n var $html = $('
').append($.parseHTML(html));\n\n var body = $html.find('.product-quickview');\n var footer = $html.find('.modal-footer').children();\n\n return { body: body, footer: footer };\n}\n\n/**\n * replaces the content in the modal window for product variation to be edited.\n * @param {string} editProductUrl - url to be used to retrieve a new product model\n */\nfunction fillModalElement(editProductUrl) {\n $('.modal-body').spinner().start();\n $.ajax({\n url: editProductUrl,\n method: 'GET',\n dataType: 'html',\n success: function (html) {\n var parsedHtml = parseHtml(html);\n\n $('#editProductModal .modal-body').empty();\n $('#editProductModal .modal-body').html(parsedHtml.body);\n $('#editProductModal .modal-footer').html(parsedHtml.footer);\n $('#editProductModal').modal('show');\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n}\n\n/**\n * replace content of modal\n * @param {string} actionUrl - url to be used to remove product\n * @param {string} productID - pid\n * @param {string} productName - product name\n * @param {string} uuid - uuid\n */\nfunction confirmDelete(actionUrl, productID, productName, uuid) {\n var $deleteConfirmBtn = $('.cart-delete-confirmation-btn');\n var $productToRemoveSpan = $('.product-to-remove');\n\n $deleteConfirmBtn.data('pid', productID);\n $deleteConfirmBtn.data('action', actionUrl);\n $deleteConfirmBtn.data('uuid', uuid);\n\n $productToRemoveSpan.empty().append(productName);\n}\n\n/**\n * Updates the Mini-Cart quantity value after the customer has pressed the \"Add to Cart\" button\n * @param {string} response - ajax response from clicking the add to cart button\n */\nfunction handlePostCartAdd(response) {\n $('.minicart').trigger('count:update', response);\n // var messageType = response.error ? 'alert-danger' : 'alert-success';\n // show add to cart toast\n if (response.newBonusDiscountLineItem\n && Object.keys(response.newBonusDiscountLineItem).length !== 0) {\n base.methods.editBonusProducts(response.newBonusDiscountLineItem);\n } else {\n /* if ($('.add-to-cart-messages').length === 0) {\n $('body').append(\n '
'\n );\n }\n\n $('.add-to-cart-messages').append(\n '
'\n + response.message\n + '
'\n );\n\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n }, 5000);\n */\n $('#flyout-cart').show();\n }\n}\n\n/**\n * Function to render a fresh Minicart HTML\n */\nfunction openNewMinicart() {\n var modalOverlay = document.querySelector('.modal-overlay');\n var miniCart = document.querySelector('.minicart_wrap');\n var body = document.querySelector('body');\n var url = $('.cart-link').attr('data-href');\n body.classList.add('no-scroll');\n $.get(url, function (data) {\n $('.minicart_wrap').empty();\n $('.minicart_wrap').parent().each(function () {\n if (!$(this).hasClass('mobile-header')) {\n $(this).children('.minicart_wrap').append(data);\n }\n });\n if (typeof affirm !== 'undefined') { // eslint-disable-line\n affirm.ui.ready(function() { // eslint-disable-line\n affirm.ui.refresh(); // eslint-disable-line\n });\n }\n $('.mob-byb-discount').css('width', $('.hybridbundle-line-item').width());\n modalOverlay.classList.add('active');\n miniCart.classList.add('active');\n body.classList.add('mini-cart-active');\n $.spinner().stop();\n });\n}\n\n/**\n * Generates the modal window on the first call.\n *\n */\nfunction getPaymentModalHtmlElement() {\n if ($('#spinnerModal').length !== 0) {\n $('#spinnerModal').remove();\n }\n // Only for mobile devices\n var htmlString = ''\n + '
'\n + '
'\n + ''\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
'\n + '
';\n $('body').append(htmlString);\n}\n\nmodule.exports = function () {\n $('body').on('click', '.remove-product', function (e) {\n e.preventDefault();\n\n var actionUrl = $(this).data('action');\n var productID = $(this).data('pid');\n var productName = $(this).data('name');\n var uuid = $(this).data('uuid');\n confirmDelete(actionUrl, productID, productName, uuid);\n });\n\n // Arlo 887:- Event to remove trailing and leading blank space\n $('body').on('focusout', '#couponCode', function () {\n var inputCouponCode = $(this).val();\n $(this).val(inputCouponCode.trim());\n });\n\n $('body').on('afterRemoveFromCart', function (e, data) {\n e.preventDefault();\n confirmDelete(data.actionUrl, data.productID, data.productName, data.uuid);\n });\n\n $('.optional-promo').click(function (e) {\n e.preventDefault();\n $('.promo-code-form').toggle();\n });\n\n $('body').on('click', '.cart-delete-confirmation-btn', function (e) {\n e.preventDefault();\n\n var productID = $(this).data('pid');\n var url = $(this).data('action');\n var uuid = $(this).data('uuid');\n var urlParams = {\n pid: productID,\n uuid: uuid\n };\n\n url = appendToUrl(url, urlParams);\n\n $('body > .modal-backdrop').remove();\n\n $.ajax({\n url: url,\n type: 'get',\n dataType: 'json',\n success: function (data) {\n var $removedProduct;\n $('.minicart_wrap__items').spinner().start();\n if (data.basket.items.length === 0 && $('#checkout-main').length < 1) {\n for (var s = 0, t = $('.product-line-item').length; s < t; s++) {\n if ($('.product-line-item')[s].getAttribute('data-product-line-item') === uuid) {\n $removedProduct = $('.product-line-item')[s];\n s = t;\n }\n }\n $removedProduct.remove();\n if (data.toBeDeletedUUIDs && data.toBeDeletedUUIDs.length > 0) {\n for (var k = 0; k < data.toBeDeletedUUIDs.length; k++) {\n $('.uuid-' + data.toBeDeletedUUIDs[k]).remove();\n }\n }\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n _etmc.trackCart([{ \"clear_cart\":true}]); // eslint-disable-line\n }\n $('.minicart_wrap').removeClass('active');\n location.reload();\n } else if ($('#checkout-main').length) {\n // reload the page in checkout to display correct line items and totals\n location.reload();\n } else {\n $('.product-line-item').spinner().start();\n var $numOfItems = $('.minicart_wrap__count');\n var $subTotal = $('.minicart_wrap__footer-totals-total');\n var $cartItems = $('.cart-count');\n for (var x = 0, y = $('.product-line-item').length; x < y; x++) {\n if ($('.product-line-item')[x].getAttribute('data-product-line-item') === uuid) {\n $removedProduct = $('.product-line-item')[x];\n x = y;\n }\n }\n $numOfItems.html(data.basket.resources.numberOfItems);\n $subTotal.html(data.basket.totals.subTotal);\n $cartItems.html(data.basket.numItems);\n $removedProduct.remove();\n if (data.toBeDeletedUUIDs && data.toBeDeletedUUIDs.length > 0) {\n for (var i = 0; i < data.toBeDeletedUUIDs.length; i++) {\n $('.uuid-' + data.toBeDeletedUUIDs[i]).remove();\n }\n }\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n var cart = {};\n cart = data.basket.trackCartDatalayer;\n _etmc.trackCart([{cart}]); // eslint-disable-line\n }\n $('.uuid-' + uuid).remove();\n if (!data.basket.hasBonusProduct) {\n $('.bonus-product').remove();\n }\n $('.coupons-and-promos').empty().append(data.basket.totals.discountsHtml);\n updateCartTotals(data.basket);\n if (!data.basket.paypalApplicable) {\n $('.paypal_button_div').addClass('d-none');\n } else {\n $('.paypal_button_div').removeClass('d-none');\n }\n updateApproachingDiscounts(data.basket.approachingDiscounts);\n $('body').trigger('setShippingMethodSelection', data.basket);\n validateBasket(data.basket);\n }\n $.spinner().stop();\n },\n error: function (err) {\n if (err.responseJSON.redirectUrl) {\n window.location.href = err.responseJSON.redirectUrl;\n } else {\n createErrorNotification(err.responseJSON.errorMessage);\n $.spinner().stop();\n }\n }\n });\n });\n var changeQtyCheck = false;\n $('body').on('change', '.quantity-form > .quantity', function (e) {\n e.stopImmediatePropagation();\n var preSelectQty = $(this).data('pre-select-qty');\n var quantity = $(this).val();\n var productID = $(this).data('pid');\n var url = $(this).data('action');\n var uuid = $(this).data('uuid');\n var minusBtn = $(this).siblings('.liq-minus');\n var minusBtnDisabled = minusBtn ? $(minusBtn).prop('disabled') : false;\n var headerCartCount = $('.cart-count');\n var numOfItems = $('.minicart_wrap__count');\n\n if (quantity === '1' && minusBtnDisabled === false) {\n $(minusBtn).attr('disabled', true).text('');\n } else if (quantity !== '1' && minusBtnDisabled) {\n $(minusBtn).removeAttr('disabled').text('-');\n }\n\n var urlParams = {\n pid: productID,\n quantity: quantity,\n uuid: uuid\n };\n if ($(this).hasClass('reduceqty')) {\n $(this).removeClass('reduceqty');\n urlParams.isqtyreduce = true;\n } else {\n urlParams.isqtyreduce = false;\n }\n\n // warranty updates\n if ($('.uuid-' + uuid).find('.js-itemwarranty-checkbox:checked').length) {\n urlParams.updatewarranty = true;\n var warrantyObjstr = $('.uuid-' + uuid).find('.js-itemwarranty-checkbox:checked').attr('data-warrantyobj');\n var warrantyObj = null;\n if (warrantyObjstr) {\n try {\n warrantyObj = JSON.parse(warrantyObjstr);\n } catch (e1) {\n console.error('warranty data corrupt');\n }\n urlParams.wpid = warrantyObj.warrantyPID;\n }\n }\n url = appendToUrl(url, urlParams);\n\n if ($('.cart.cart-page').length) {\n $('body').spinner().start();\n } else {\n $('.minicart_wrap').spinner().start();\n }\n\n $.ajax({\n url: url,\n type: 'get',\n context: this,\n dataType: 'json',\n success: function (data) {\n $('.quantity[data-uuid=\"' + uuid + '\"]').val(quantity);\n $('.coupons-and-promos').empty().append(data.totals.discountsHtml);\n updateCartTotals(data);\n // warranty updates\n if ($('.uuid-' + uuid).find('.js-itemwarranty-checkbox:checked').length) {\n var colorInterval = setInterval(function () {\n $('.uuid-' + uuid).find('.js-warrantytotalprice').toggleClass('warranty-bling');\n }, 500);\n setTimeout(function () {\n clearInterval(colorInterval);\n $('.uuid-' + uuid).find('.js-warrantytotalprice').removeClass('warranty-bling');\n }, 3000);\n }\n if (!data.paypalApplicable) {\n $('.paypal_button_div').addClass('d-none');\n } else {\n $('.paypal_button_div').removeClass('d-none');\n }\n updateApproachingDiscounts(data.approachingDiscounts);\n updateAvailability(data, uuid);\n validateBasket(data);\n $(this).data('pre-select-qty', quantity);\n if ($('#checkout-main').length || ($(this).parents('.product-info').hasClass('bonus-product-line-item') && $('.cart-page').length)) {\n // location.reload();\n if (window.location.pathname && !window.location.pathname.toLowerCase().includes('cart')) {\n changeQtyCheck = true;\n }\n }\n $.spinner().stop();\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n var cart = {};\n cart = data.trackCartDatalayer;\n _etmc.trackCart([{cart}]); // eslint-disable-line\n }\n if (headerCartCount && data && data.numItems) {\n $(headerCartCount).text(data.numItems);\n }\n if (numOfItems && data && data.resources && data.resources.numberOfItems) {\n $(numOfItems).html(data.resources.numberOfItems);\n }\n // Add new bonus products if any\n var cartItems = data.items;\n var latestItemsInCart = [];\n cartItems.forEach(function (item) {\n latestItemsInCart.push(item.UUID);\n if ($('.uuid-' + item.UUID).length < 1) {\n if (item.isBonusProductLineItem && item.isBonusProductLineItem === true) {\n $('.cart-products').append(`
\n
\n \"${item.images.small[0].alt}\"\n
\n
\n
Bonus Product
\n \n
\n
Quantity: ${item.quantity}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
`);\n }\n }\n });\n // Remove bonus items if any that are not part of updated basket items\n var itemsToDelete = [];\n $('.product-line-item.product-info').each(function () {\n if (latestItemsInCart.indexOf($(this).data('product-line-item')) < 0) {\n itemsToDelete.push($(this).data('product-line-item'));\n }\n });\n itemsToDelete.forEach(function (itemToDeleteuuid) {\n if (itemToDeleteuuid !== 'hybridbundle') {\n $('.uuid-' + itemToDeleteuuid).remove();\n }\n });\n },\n error: function (err) {\n if (err.responseJSON.redirectUrl) {\n window.location.href = err.responseJSON.redirectUrl;\n } else {\n createErrorNotification(err.responseJSON.errorMessage);\n $(this).val(parseInt(preSelectQty, 10));\n $.spinner().stop();\n }\n }\n });\n return false;\n });\n\n $('body').on('click', '.minicart_wrap__close', function () {\n if (changeQtyCheck === true) {\n location.reload();\n }\n });\n\n $('body').on('click', function (e) {\n if (!$(e.target).closest('.minicart_wrap').length) {\n if (changeQtyCheck === true) {\n location.reload();\n }\n }\n });\n\n $('.shippingMethods').change(function () {\n var url = $(this).attr('data-actionUrl');\n var urlParams = {\n methodID: $(this).find(':selected').attr('data-shipping-id')\n };\n // url = appendToUrl(url, urlParams);\n\n $('.totals').spinner().start();\n $.ajax({\n url: url,\n type: 'post',\n dataType: 'json',\n data: urlParams,\n success: function (data) {\n if (data.error) {\n window.location.href = data.redirectUrl;\n } else {\n $('.coupons-and-promos').empty().append(data.totals.discountsHtml);\n updateCartTotals(data);\n if (!data.paypalApplicable) {\n $('.paypal_button_div').addClass('d-none');\n } else {\n $('.paypal_button_div').removeClass('d-none');\n }\n updateApproachingDiscounts(data.approachingDiscounts);\n validateBasket(data);\n }\n $.spinner().stop();\n },\n error: function (err) {\n if (err.redirectUrl) {\n window.location.href = err.redirectUrl;\n } else {\n createErrorNotification(err.responseJSON.errorMessage);\n $.spinner().stop();\n }\n }\n });\n });\n\n $('.promo-code-form').submit(function (e) {\n e.preventDefault();\n $.spinner().start();\n $('.coupon-missing-error').hide();\n $('.coupon-error-message').empty();\n if (!$('.coupon-code-field').val()) {\n $('.promo-code-form .form-control').addClass('is-invalid');\n $('.coupon-missing-error').show();\n $.spinner().stop();\n return false;\n }\n var $form = $('.promo-code-form');\n $('.promo-code-form .form-control').removeClass('is-invalid');\n $('.coupon-error-message').empty();\n\n $.ajax({\n url: $form.attr('action'),\n type: 'GET',\n dataType: 'json',\n data: $form.serialize(),\n success: function (data) {\n if (data.error) {\n $('.promo-code-form .form-control').addClass('is-invalid');\n $('.coupon-error-message').empty().append(data.errorMessage);\n } else if (data.hasBonusProduct) {\n location.reload();\n } else {\n $('.coupons-and-promos').empty().append(data.totals.discountsHtml);\n updateCartTotals(data);\n updateApproachingDiscounts(data.approachingDiscounts);\n validateBasket(data);\n if (!data.paypalApplicable) {\n $('.paypal_button_div').addClass('d-none');\n }\n }\n $('.coupon-code-field').val('');\n $.spinner().stop();\n },\n error: function (err) {\n if (err.responseJSON.redirectUrl) {\n window.location.href = err.responseJSON.redirectUrl;\n } else {\n createErrorNotification(err.errorMessage);\n $.spinner().stop();\n }\n }\n });\n return false;\n });\n\n $('body').on('click', '.remove-coupon', function (e) {\n e.preventDefault();\n\n var couponCode = $(this).data('code');\n var uuid = $(this).data('uuid');\n var $deleteConfirmBtn = $('.delete-coupon-confirmation-btn');\n var $productToRemoveSpan = $('.coupon-to-remove');\n\n $deleteConfirmBtn.data('uuid', uuid);\n $deleteConfirmBtn.data('code', couponCode);\n\n $productToRemoveSpan.empty().append(couponCode);\n });\n\n $('body').on('click', '.delete-coupon-confirmation-btn', function (e) {\n e.preventDefault();\n\n var url = $(this).data('action');\n var uuid = $(this).data('uuid');\n var couponCode = $(this).data('code');\n var urlParams = {\n code: couponCode,\n uuid: uuid\n };\n\n url = appendToUrl(url, urlParams);\n\n $('body > .modal-backdrop').remove();\n\n $.spinner().start();\n $.ajax({\n url: url,\n type: 'get',\n dataType: 'json',\n success: function () {\n $('.coupon-uuid-' + uuid).remove();\n $.spinner().stop();\n // reload the page for bonus products\n location.reload();\n },\n error: function (err) {\n if (err.responseJSON.redirectUrl) {\n window.location.href = err.responseJSON.redirectUrl;\n } else {\n createErrorNotification(err.responseJSON.errorMessage);\n $.spinner().stop();\n }\n }\n });\n });\n $('body').on('click', '.cart-page .bonus-product-button', function () {\n $.spinner().start();\n $.ajax({\n url: $(this).data('url'),\n method: 'GET',\n dataType: 'json',\n success: function (data) {\n base.methods.editBonusProducts(data);\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n });\n $('body').on('click', '.cart-page .product-edit .edit, .cart-page .bundle-edit .edit', function (e) {\n e.preventDefault();\n\n var editProductUrl = $(this).attr('href');\n getModalHtmlElement();\n fillModalElement(editProductUrl);\n });\n\n $('body').on('product:updateAddToCart', function (e, response) {\n // update global add to cart (single products, bundles)\n var dialog = $(response.$productContainer)\n .closest('.quick-view-dialog');\n\n $('.update-cart-product-global', dialog).attr('disabled',\n !$('.global-availability', dialog).data('ready-to-order')\n || !$('.global-availability', dialog).data('available')\n );\n });\n\n $('body').on('product:updateAvailability', function (e, response) {\n // bundle individual products\n $('.product-availability', response.$productContainer)\n .data('ready-to-order', response.product.readyToOrder)\n .data('available', response.product.available)\n .find('.availability-msg')\n .empty()\n .html(response.message);\n\n\n var dialog = $(response.$productContainer)\n .closest('.quick-view-dialog');\n\n if ($('.product-availability', dialog).length) {\n // bundle all products\n var allAvailable = $('.product-availability', dialog).toArray()\n .every(function (item) { return $(item).data('available'); });\n\n var allReady = $('.product-availability', dialog).toArray()\n .every(function (item) { return $(item).data('ready-to-order'); });\n\n $('.global-availability', dialog)\n .data('ready-to-order', allReady)\n .data('available', allAvailable);\n\n $('.global-availability .availability-msg', dialog).empty()\n .html(allReady ? response.message : response.resources.info_selectforstock);\n } else {\n // single product\n $('.global-availability', dialog)\n .data('ready-to-order', response.product.readyToOrder)\n .data('available', response.product.available)\n .find('.availability-msg')\n .empty()\n .html(response.message);\n }\n });\n\n $('body').on('product:afterAttributeSelect', function (e, response) {\n if ($('.modal.show .product-quickview .bundle-items').length) {\n $('.modal.show').find(response.container).data('pid', response.data.product.id);\n $('.modal.show').find(response.container).find('.product-id').text(response.data.product.id);\n } else {\n $('.modal.show .product-quickview').data('pid', response.data.product.id);\n }\n\n base.updateMainImages(response.data.product);\n base.carouselInit();\n\n // Update product name\n response.container.find('.product-name').html(response.data.product.productName);\n });\n\n $('body').on('product:beforeAttributeSelect', function () {\n // Unslick the existing images to prepare them for direct js manipulation\n base.carouselUnslick();\n base.carouselUnslickBonus();\n });\n\n\n $('body').on('shown.bs.modal', '#editProductModal, #quickViewModal, #chooseBonusProductModal', function () {\n base.carouselInit();\n base.carouselInitBonus();\n });\n\n $('body').on('change', '.quantity-select', function () {\n var selectedQuantity = $(this).val();\n $('.modal.show .update-cart-url').data('selected-quantity', selectedQuantity);\n });\n\n $('body').on('click', '.update-cart-product-global', function (e) {\n e.preventDefault();\n\n var updateProductUrl = $(this).closest('.cart-and-ipay').find('.update-cart-url').val();\n var selectedQuantity = $(this).closest('.cart-and-ipay').find('.update-cart-url').data('selected-quantity');\n var uuid = $(this).closest('.cart-and-ipay').find('.update-cart-url').data('uuid');\n\n var form = {\n uuid: uuid,\n pid: base.getPidValue($(this)),\n quantity: selectedQuantity\n };\n\n $(this).parents('.card').spinner().start();\n if (updateProductUrl) {\n $.ajax({\n url: updateProductUrl,\n type: 'post',\n context: this,\n data: form,\n dataType: 'json',\n success: function (data) {\n $('#editProductModal').remove();\n $('.modal-backdrop').remove();\n $('body').removeClass('modal-open');\n\n $('.coupons-and-promos').empty().append(data.cartModel.totals.discountsHtml);\n updateCartTotals(data.cartModel);\n updateApproachingDiscounts(data.cartModel.approachingDiscounts);\n updateAvailability(data.cartModel, uuid);\n updateProductDetails(data, uuid);\n\n if (data.uuidToBeDeleted) {\n $('.uuid-' + data.uuidToBeDeleted).remove();\n }\n\n validateBasket(data.cartModel);\n\n $.spinner().stop();\n },\n error: function (err) {\n if (err.responseJSON.redirectUrl) {\n window.location.href = err.responseJSON.redirectUrl;\n } else {\n createErrorNotification(err.responseJSON.errorMessage);\n $.spinner().stop();\n }\n }\n });\n }\n });\n $(document).on('click', 'button.add-to-cart-recom', function (e) {\n e.preventDefault();\n var addToCartUrl = $(this).parent().find('.add-to-cart-url').val();\n $('body').trigger('product:beforeAddToCart', this);\n var form = {\n pid: $(this).attr('data-pid'),\n quantity: 1,\n options: []\n };\n\n $(this).trigger('updateAddToCartFormData', form);\n if (addToCartUrl) {\n $.spinner().start();\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: function (data) {\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n var cart = {};\n cart = data.cart.trackCartDatalayer;\n _etmc.trackCart([{cart}]); // eslint-disable-line\n }\n handlePostCartAdd(data);\n $('body').trigger('product:afterAddToCart', data);\n $.spinner().stop();\n\n var action = $('.page').attr('data-action');\n var maxPids = $('.choose-bonus-product-dialog').data('total-qty');\n if (action === 'Cart-Show') {\n if (maxPids === undefined) {\n window.location.reload();\n }\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n });\n\n $(document).on('click', 'button.add-to-cart-upsell', function (e) {\n e.preventDefault();\n var addToCartUrl = $(this).parent().find('.add-to-cart-url').val();\n $('body').trigger('product:beforeAddToCart', this);\n var $this = $(this);\n var isUpSellProduct = $(this).hasClass('add-to-cart-upsell');\n var form = {\n pid: $(this).attr('data-pid'),\n quantity: 1,\n options: [],\n isUpSellProduct: isUpSellProduct\n };\n\n $(this).trigger('updateAddToCartFormData', form);\n if (addToCartUrl) {\n $.spinner().start();\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: function (data) {\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n var cart = {};\n cart = data.cart.trackCartDatalayer;\n _etmc.trackCart([{cart}]); // eslint-disable-line\n }\n $('.flyout-cart__price .qty-flyout-total').text(data.cart.numItems);\n $('.flyout-cart__price .subtotal-flyout').text(data.cart.totals.subTotal);\n $this.text(data.message);\n $this.addClass('upsell-added');\n $('body').trigger('product:afterAddToCart', data);\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n });\n\n $(document).on('click', '.js-recs-add-to-cart', function (e) {\n e.preventDefault();\n var addToCartUrl = $(this).attr('data-add-to-cart-url');\n var form = {\n pid: $(this).attr('data-product-id'),\n quantity: 1,\n options: []\n };\n\n if (addToCartUrl) {\n $.spinner().start();\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: function (data) {\n if (!data.error) {\n window.location.reload();\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n });\n\n $('body').on('change', '.cart-products .quantity', function () {\n var preSelectQty = $(this).data('pre-select-qty');\n var quantity = $(this).val();\n var productID = $(this).data('pid');\n var url = $(this).data('action');\n var uuid = $(this).data('uuid');\n\n var urlParams = {\n pid: productID,\n quantity: quantity,\n uuid: uuid\n };\n url = appendToUrl(url, urlParams);\n $(this).parents('.product-info').spinner().start();\n $.ajax({\n url: url,\n type: 'get',\n context: this,\n dataType: 'json',\n success: function (data) {\n $('.quantity[data-uuid=\"' + uuid + '\"]').val(quantity);\n $('.coupons-and-promos').empty().append(data.totals.discountsHtml);\n updateCartTotals(data);\n // warranty updates\n if ($('.uuid-' + uuid).find('.js-itemwarranty-checkbox:checked').length) {\n var colorInterval = setInterval(function () {\n $('.uuid-' + uuid).find('.js-warrantytotalprice').toggleClass('warranty-bling');\n }, 500);\n setTimeout(function () {\n clearInterval(colorInterval);\n $('.uuid-' + uuid).find('.js-warrantytotalprice').removeClass('warranty-bling');\n }, 3000);\n }\n if (!data.paypalApplicable) {\n $('.paypal_button_div').addClass('d-none');\n } else {\n $('.paypal_button_div').removeClass('d-none');\n }\n updateApproachingDiscounts(data.approachingDiscounts);\n updateAvailability(data, uuid);\n validateBasket(data);\n $(this).data('pre-select-qty', quantity);\n $.spinner().stop();\n if ($('#checkout-main').length || ($(this).parents('.product-info').hasClass('bonus-product-line-item') && $('.cart-page').length)) {\n location.reload();\n }\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n var cart = {};\n cart = data.trackCartDatalayer;\n _etmc.trackCart([{cart}]); // eslint-disable-line\n }\n },\n error: function (err) {\n if (err.responseJSON.redirectUrl) {\n window.location.href = err.responseJSON.redirectUrl;\n } else {\n createErrorNotification(err.responseJSON.errorMessage);\n $(this).val(parseInt(preSelectQty, 10));\n $.spinner().stop();\n }\n }\n });\n });\n\n $('body').on('change', '.minicart_wrap .quantitytest', function (e) {\n e.preventDefault();\n var preSelectQty = $(this).data('pre-select-qty');\n var quantity = $(this).val();\n var productID = $(this).data('pid');\n var url = $(this).data('action');\n var uuid = $(this).data('uuid');\n\n var urlParams = {\n pid: productID,\n quantity: quantity,\n uuid: uuid\n };\n url = appendToUrl(url, urlParams);\n\n $(this).parents('.product-line-item').spinner().start();\n\n $.ajax({\n url: url,\n type: 'get',\n context: this,\n dataType: 'json',\n success: function (data) {\n var $numOfItems = $('.minicart_wrap__count');\n var $subTotal = $('.minicart_wrap__footer-totals-total');\n var $itemSubtotal = $('.item-total-' + uuid + ' span');\n var $cartItems = $('.cart-count');\n var currentDataPLIPrice = '';\n for (var i = 0, j = data.items.length; i < j; i++) {\n if (data.items[i].UUID === uuid) {\n currentDataPLIPrice = data.items[i].priceTotal.price;\n }\n }\n $numOfItems.html(data.resources.numberOfItems);\n $subTotal.html(data.totals.subTotal);\n $itemSubtotal.attr('content', currentDataPLIPrice);\n $itemSubtotal.html(currentDataPLIPrice);\n $cartItems.html(data.numItems);\n $.spinner().stop();\n },\n error: function (err) {\n if (err.responseJSON.redirectUrl) {\n window.location.href = err.responseJSON.redirectUrl;\n } else {\n createErrorNotification(err.responseJSON.errorMessage);\n $(this).val(parseInt(preSelectQty, 10));\n $.spinner().stop();\n }\n }\n });\n });\n\n/**\n * Click event for recommendations new smart button ( + )\n * @param {e} event - event of click\n * @param {addToCartUrl} string - string of add to cart path\n * @param {productID} string - string of ID of product to be added to cart\n * @param {quantity} string - string of qty added to cart (for these recommendations it will always be one\n * @param {isPDPLink} string - string of url to pdp. if this is a variation/master this is a link to the PDP to choose a variation\n * @param {urlParams} string - serialization of parameters to pass to add to cart url\n */\n $('body').on('click', '.cart-upsells-item .recs-add-to-cart', function (e) {\n e.preventDefault();\n var addToCartUrl = $(this).data('add-to-cart-url');\n var productID = $(this).data('product-id');\n var quantity = $(this).data('product-qty');\n var isPDPLink = '';\n var urlParams = {\n pid: productID,\n quantity: quantity\n };\n $(this).parents('.cart-upsells-item').spinner().start();\n if ($(this).data('pdp-link') !== 'undefined' && $(this).data('pdp-link') !== '' && typeof $(this).data('pdp-link') !== 'undefined') {\n isPDPLink = $(this).data('pdp-link');\n window.location.href = isPDPLink;\n } else {\n $.ajax({\n url: addToCartUrl,\n type: 'post',\n data: urlParams,\n dataType: 'json',\n success: function (response) {\n if (response.error === true) {\n createErrorNotification(response.message);\n $('html, body').animate({ scrollTop: $('#checkout-main').offset().top }, 1000);\n }\n $.spinner().stop();\n },\n error: function (response) {\n if (response.error === true) {\n createErrorNotification(response.message);\n $('html, body').animate({ scrollTop: $('#checkout-main').offset().top }, 1000);\n }\n },\n complete: function (response) {\n if (response.responseJSON.error === false) {\n window.location.reload();\n }\n }\n });\n }\n });\n\n $('body').on('click', '#continueShopping', function (e) {\n e.preventDefault();\n window.location.href = $(this).data('url');\n });\n\n $('.shippingMethods').select2({\n minimumResultsForSearch: -1\n });\n\n $('body').on('click', '.js-cart-hybridbundle-increaseqty', function (e) {\n e.stopImmediatePropagation();\n e.preventDefault();\n $(this).prop('disabled', true);\n // Check if the items are available in requested qty\n var canBeAdded = true;\n var hybridBundleQtyToAdd = Number($('.js-cart-hybridbundle-qty').val()) + 1;\n var singleQtyConfig = JSON.parse($('.js-cart-singleqty-hybridconfig').val());\n var itemKeys = Object.keys(singleQtyConfig);\n var message = '';\n for (var i = 0; i < itemKeys.length; i++) {\n var itemKey = itemKeys[i];\n var itemUUID = singleQtyConfig[itemKey].uuid;\n var qtyToAdd = singleQtyConfig[itemKey].qty * hybridBundleQtyToAdd;\n var maxQty = parseInt($('.js-hybrid-bundle-item[data-bundleitemuuid=' + itemUUID + ']').data('maxqty'), 10);\n if (qtyToAdd > maxQty) {\n canBeAdded = false;\n message += '
' + $('.js-hybrid-bundle-item[data-bundleitemuuid=' + itemUUID + ']').data('prodname');\n }\n }\n if (canBeAdded) {\n if ($(this).hasClass('is-minicart')) {\n $('.minicart_wrap').spinner().start();\n $.ajax({\n url: $(this).data('actionurl'),\n type: 'get'\n }).done(function (data) {\n if (data.success === true) {\n $('.minicart_wrap').empty();\n $('.minicart_wrap').spinner().start();\n openNewMinicart();\n }\n });\n } else {\n $('body').spinner().start();\n window.location.href = $(this).data('actionurl');\n }\n } else if (canBeAdded === false) {\n var errorHtml = '
' +\n '' + $('.js-hybrid-qtyerror-msgs').data('msg1') + ' ' + message + '
';\n $('.cart-error').html('');\n $('.cart-error').append(errorHtml);\n $('body').spinner().stop();\n $(this).prop('disabled', false);\n if ($('.js-minicart-block').length) {\n $('.js-minicart-block').animate({\n scrollTop: 0\n });\n }\n }\n });\n\n $('body').on('click', '.js-cart-hybridbundle-decreaseqty', function (e) {\n e.stopImmediatePropagation();\n e.preventDefault();\n $(this).prop('disabled', true);\n if ($(this).hasClass('is-minicart')) {\n $('.minicart_wrap').spinner().start();\n $.ajax({\n url: $(this).data('actionurl'),\n type: 'get'\n }).done(function (data) {\n if (data.success === true) {\n $('.minicart_wrap').empty();\n $('.minicart_wrap').spinner().start();\n openNewMinicart();\n }\n });\n } else {\n $('body').spinner().start();\n window.location.href = $(this).data('actionurl');\n }\n });\n\n // Add on subscription product add to cart\n $('.line-item-quantity input').each(function () {\n var pid = $(this).data('pid');\n if ($('.js-addon-input')) {\n $('.js-addon-input').each(function () {\n if ($(this).data('addonpid') === pid) {\n $(this).prop('checked', true);\n $(this).closest('.cart-addon_item').css({ 'pointer-events': 'none' });\n $(this).closest('.cart-addon_item').prop('disabled', true);\n $(this).prop('disabled', true);\n }\n });\n }\n });\n\n $('body').on('click', '.js-cartaddon-radio', function () {\n var addonInput = $(this).closest('.cart-addon_item').find('.js-addon-input');\n var pid = $(addonInput).data('addonpid');\n if (pid && $(addonInput).prop('checked') === true) {\n $(this).prop('disabled', true);\n $('body').spinner().start();\n var addToCartUrl = $('.js-cart-a2curl').val();\n var form = {\n pid: pid,\n childProducts: [],\n quantity: 1\n };\n if (addToCartUrl) {\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: function (data) {\n if (!data.error) {\n if ($('.js-cart-reloadurl').val()) {\n window.location.href = $('.js-cart-reloadurl').val();\n }\n }\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n }\n });\n\n $('body').on('click', '.js-applebutton', function () {\n setTimeout(function () {\n // Show Spinner Modal with content after payment popup has opened\n getPaymentModalHtmlElement();\n var spinnerModal = $('#spinnerModal');\n spinnerModal.find('.loder-img').spinner().start();\n spinnerModal.find('.spinner-body').append($('.spinner-content').html());\n spinnerModal.modal('show');\n $('body').spinner().start();\n }, 5000);\n });\n\n base.selectAttribute();\n base.colorAttribute();\n base.removeBonusProduct();\n base.selectBonusProduct();\n base.enableBonusProductSelection();\n base.showMoreBonusProducts();\n base.addBonusProductsToCart();\n base.carouselInit();\n\n // warranty updates\n $('body').on('change', '.js-itemwarranty-checkbox', function () {\n var warrantyObjstr = $(this).attr('data-warrantyobj');\n var warrantyObj = null;\n var headerCartCount = $('.cart-count');\n var $thisElement = $(this);\n var numOfItems = $('.minicart_wrap__count');\n if (warrantyObjstr) {\n try {\n warrantyObj = JSON.parse(warrantyObjstr);\n } catch (e) {\n console.error('warranty data corrupt');\n }\n var parentqty = $(this).closest('.product-line-item').find('.quantity-form input.quantity').val();\n var stopLoader = true;\n if (this.checked) {\n var addurl;\n // Add warranty to cart or increase qty\n if ($(this).closest('.minicart_wrap__container').length) {\n addurl = $('.js-addwarranty-minicart').val();\n } else {\n addurl = $('.js-addwarranty-cart').val();\n }\n if ($('.cart.cart-page').length) {\n $('body').spinner().start();\n } else {\n $('.minicart_wrap').spinner().start();\n }\n $.ajax({\n url: addurl,\n method: 'POST',\n data: {\n wpid: warrantyObj.warrantyPID,\n quantity: parentqty,\n parentpid: warrantyObj.parentpid,\n parentuuid: warrantyObj.parentuuid\n },\n success: function (data) {\n if (!data.error) {\n $('.coupons-and-promos').empty().append(data.totals.discountsHtml);\n updateCartTotals(data);\n if (!data.paypalApplicable) {\n $('.paypal_button_div').addClass('d-none');\n } else {\n $('.paypal_button_div').removeClass('d-none');\n }\n updateApproachingDiscounts(data.approachingDiscounts);\n validateBasket(data);\n if ($('#checkout-main').length || ($(this).parents('.product-info').hasClass('bonus-product-line-item') && $('.cart-page').length)) {\n // location.reload();\n if (window.location.pathname && !window.location.pathname.toLowerCase().includes('cart')) {\n changeQtyCheck = true;\n }\n }\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n var cart = {};\n cart = data.trackCartDatalayer;\n _etmc.trackCart([{cart}]); // eslint-disable-line\n }\n if (headerCartCount && data && data.numItems) {\n $(headerCartCount).text(data.numItems);\n }\n if (numOfItems && data && data.resources && data.resources.numberOfItems) {\n $(numOfItems).html(data.resources.numberOfItems);\n }\n // Add new bonus products if any\n var cartItems = data.items;\n var latestItemsInCart = [];\n cartItems.forEach(function (item) {\n latestItemsInCart.push(item.UUID);\n if ($('.uuid-' + item.UUID).length < 1) {\n if (item.isBonusProductLineItem && item.isBonusProductLineItem === true) {\n $('.cart-products').append(`
\n
\n \"${item.images.small[0].alt}\"\n
\n
\n
Bonus Product
\n \n
\n
Quantity: ${item.quantity}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
`);\n }\n }\n });\n // Remove bonus items if any that are not part of updated basket items\n var itemsToDelete = [];\n $('.product-line-item.product-info').each(function () {\n if (latestItemsInCart.indexOf($(this).data('product-line-item')) < 0) {\n itemsToDelete.push($(this).data('product-line-item'));\n }\n });\n itemsToDelete.forEach(function (itemToDeleteuuid) {\n if (itemToDeleteuuid !== 'hybridbundle') {\n $('.uuid-' + itemToDeleteuuid).remove();\n }\n });\n $thisElement.closest('.warranty-prod').find('.js-itemwarranty-checkbox').each(function () {\n $(this).attr('checked', true);\n });\n if ($('.checkout__steps-wrap').length) {\n location.reload();\n stopLoader = false;\n }\n }\n if (stopLoader) {\n $.spinner().stop();\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n } else {\n // remove warranty from cart or reduce quantity\n var removeurl;\n if ($(this).closest('.minicart_wrap__container').length) {\n removeurl = $('.js-removewarranty-minicart').val();\n } else {\n removeurl = $('.js-removewarranty-cart').val();\n }\n if ($('.cart.cart-page').length) {\n $('body').spinner().start();\n } else {\n $('.minicart_wrap').spinner().start();\n }\n $.ajax({\n url: removeurl,\n method: 'POST',\n data: {\n wpid: warrantyObj.warrantyPID,\n quantity: parentqty,\n parentpid: warrantyObj.parentpid,\n parentuuid: warrantyObj.parentuuid\n },\n success: function (data) {\n if (!data.error) {\n $('.coupons-and-promos').empty().append(data.totals.discountsHtml);\n updateCartTotals(data);\n if (!data.paypalApplicable) {\n $('.paypal_button_div').addClass('d-none');\n } else {\n $('.paypal_button_div').removeClass('d-none');\n }\n updateApproachingDiscounts(data.approachingDiscounts);\n validateBasket(data);\n if ($('#checkout-main').length || ($(this).parents('.product-info').hasClass('bonus-product-line-item') && $('.cart-page').length)) {\n // location.reload();\n if (window.location.pathname && !window.location.pathname.toLowerCase().includes('cart')) {\n changeQtyCheck = true;\n }\n }\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n var cart = {};\n cart = data.trackCartDatalayer;\n _etmc.trackCart([{cart}]); // eslint-disable-line\n }\n if (headerCartCount && data && data.numItems) {\n $(headerCartCount).text(data.numItems);\n }\n if (numOfItems && data && data.resources && data.resources.numberOfItems) {\n $(numOfItems).html(data.resources.numberOfItems);\n }\n // Add new bonus products if any\n var cartItems = data.items;\n var latestItemsInCart = [];\n cartItems.forEach(function (item) {\n latestItemsInCart.push(item.UUID);\n if ($('.uuid-' + item.UUID).length < 1) {\n if (item.isBonusProductLineItem && item.isBonusProductLineItem === true) {\n $('.cart-products').append(`
\n
\n \"${item.images.small[0].alt}\"\n
\n
\n
Bonus Product
\n \n
\n
Quantity: ${item.quantity}
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
`);\n }\n }\n });\n // Remove bonus items if any that are not part of updated basket items\n var itemsToDelete = [];\n $('.product-line-item.product-info').each(function () {\n if (latestItemsInCart.indexOf($(this).data('product-line-item')) < 0) {\n itemsToDelete.push($(this).data('product-line-item'));\n }\n });\n itemsToDelete.forEach(function (itemToDeleteuuid) {\n if (itemToDeleteuuid !== 'hybridbundle') {\n $('.uuid-' + itemToDeleteuuid).remove();\n }\n });\n $thisElement.closest('.warranty-prod').find('.js-itemwarranty-checkbox').each(function () {\n $(this).attr('checked', false);\n });\n if ($('.checkout__steps-wrap').length) {\n location.reload();\n stopLoader = false;\n }\n }\n if (stopLoader) {\n $.spinner().stop();\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n }\n });\n};\n","/**\n * Adjusts the margin-top of warranty total price elements within product items.\n * This function calculates the margin-top based on the heights of specific elements\n * within each product item and applies the calculated margin-top to the\n * '.js-warrantytotalprice' element.\n */\nfunction adjustWarrantyPriceSpace() {\n if ($('#checkout-main').length && $('.order-product-summary').length) {\n const productItems = document.querySelectorAll('.product-summary-block .product-line-item');\n\n productItems.forEach((item) => {\n try {\n const productAttributeHeight = $(item).find('.wrnty-attr-height').height() || 0;\n const productNameHeight = $(item).find('.wrnty-prod-height').height() || 0;\n const productItemPriceHeight = $(item).find('.line-item-unit-price').height() || 0;\n const productQuantityHeight = $(item).find('.line-item-pricing-info').height() || 0;\n\n const totalAttributeNameHeight = productAttributeHeight + productNameHeight;\n const totalPriceQuantityHeight = productItemPriceHeight + productQuantityHeight;\n const finalMarginTop = totalAttributeNameHeight - totalPriceQuantityHeight;\n\n $(item).find('.js-warrantytotalprice').css('margin-top', finalMarginTop);\n } catch (error) {\n console.error('Error processing product item:', item, error);\n }\n });\n }\n}\n\nexport { adjustWarrantyPriceSpace };\n","/**\n * Component: CrossBrowserTransparentVideo\n */\n\nexport default class CrossBrowserTransparentVideo {\n constructor() {\n this.$videos = $('.js-transparent-video');\n this.init();\n }\n\n supportsHEVCAlpha() {\n const navigator = window.navigator;\n const ua = navigator.userAgent.toLowerCase();\n const hasMediaCapabilities = !!(navigator.mediaCapabilities && navigator.mediaCapabilities.decodingInfo);\n const isSafari = ((ua.indexOf('safari') !== -1) && (!(ua.indexOf('chrome') !== -1) && (ua.indexOf('version/') !== -1)));\n return isSafari && hasMediaCapabilities;\n }\n\n isIE11() {\n return !!window.navigator.userAgent.match(/Trident\\/7\\./, []);\n }\n\n init() {\n this.$videos.each((idx, video) => {\n const sourceName = $(video).data('source');\n const sourceTag = document.createElement('source');\n\n if (!this.isIE11()) {\n sourceTag.src = this.supportsHEVCAlpha() ? `${sourceName}.mov` : `${sourceName}.webm`;\n }\n\n $(video).append(sourceTag);\n });\n }\n}\n","/**\n * Component: Footer\n */\nimport { gsap } from 'gsap/dist/gsap';\n\nexport default class Footer {\n constructor() {\n this.selectors = {\n root: '[data-footer]',\n panels: '[data-footer-panel]',\n panelHeadings: '[data-footer-panel-heading]',\n panelLists: '[data-footer-panel-list]'\n };\n\n this.rootElem = document.querySelector(this.selectors.root);\n if (!$(this.rootElem).length) return;\n this.panels = this.rootElem.querySelectorAll(this.selectors.panels);\n if (!$(this.panels).length) return;\n this.panelHeadings = this.rootElem.querySelectorAll(this.selectors.panelHeadings);\n if (!$(this.panelHeadings).length) return;\n\n this.init();\n }\n\n toggleAnimation(panelHeading) {\n // Save the current state of the clicked animation\n const selectedReversedState = panelHeading.animation.reversed();\n\n panelHeading.animation.reversed(!selectedReversedState);\n panelHeading.querySelector('button').setAttribute('aria-expanded', selectedReversedState);\n panelHeading.querySelector('button').classList.toggle('collapsed');\n }\n\n createAnimation(column) {\n const panelHeading = column.querySelector(this.selectors.panelHeadings);\n const panelList = column.querySelector(this.selectors.panelLists);\n\n gsap.set(panelList, { height: 'auto' });\n\n // Keep a reference to the animation on the column content itself\n const tween = gsap.from(panelList, {\n height: 0,\n duration: 0.25,\n ease: 'power3.inOut',\n reversed: true\n });\n\n panelHeading.animation = tween;\n }\n\n bindEvents() {\n this.panels.forEach((panel) => {\n this.createAnimation(panel);\n });\n\n this.panelHeadings.forEach((panelHeading) => {\n panelHeading.addEventListener('click', (e) => {\n e.stopImmediatePropagation();\n e.preventDefault();\n this.toggleAnimation(panelHeading);\n });\n });\n }\n\n init() {\n this.bindEvents();\n }\n}\n","/**\n * Component: MobileNavigation\n */\n\nexport default class MobileNavigation {\n constructor() {\n this.body = $('body');\n this.mobileNav = $('#mobileNavigation');\n this.toggleSecondLevelLinks = $('.toggle-second-level');\n this.toggleThirdLevelLinks = $('.toggle-third-level');\n this.secondLevelBackButtons = $('.mobile-navigation__back-button--second');\n this.thirdLevelBackButtons = $('.mobile-navigation__back-button--third');\n this.secondLevelContainer = $('.mobile-navigation__container--second-level');\n this.thirdLevelContainer = ('.mobile-navigation__container--third-level');\n this.secondLevelLists = $('.mobile-navigation__list--second-level');\n this.thirdLevelLists = ('.mobile-navigation__list--third-level');\n\n this.toggleSecondLevel = this.toggleSecondLevel.bind(this);\n this.toggleThirdLevel = this.toggleThirdLevel.bind(this);\n\n this.handleSecondLevelBackButton = this.handleSecondLevelBackButton.bind(this);\n this.handleThirdLevelBackButton = this.handleThirdLevelBackButton.bind(this);\n\n this.openInSameTab = this.openInSameTab.bind(this);\n\n this.init();\n }\n init() {\n $(document).on('click', '.mobile-navigation__list-item:not(.link-out)', this.toggleSecondLevel);\n $(document).on('click', '.mobile-navigation__list-item--second', this.toggleThirdLevel);\n $(document).on('click', '.mobile-navigation__back-button--second', this.handleSecondLevelBackButton);\n $(document).on('click', '.mobile-navigation__back-button--third', this.handleThirdLevelBackButton);\n $(document).on('click', '.mobile-navigation__product-category-link, .mobile-navigation__product-card .link, .tablet-link', this.openInSameTab);\n }\n\n toggleSecondLevel(event) {\n event.preventDefault();\n event.stopPropagation();\n const targetNode = $(event.target);\n const secondLevel = targetNode.closest('.toggle-second-level').next();\n\n $.each(this.toggleSecondLevelLinks, function () {\n jQuery(this).addClass('hide');\n });\n secondLevel.addClass('active');\n }\n\n toggleThirdLevel(event) {\n event.preventDefault();\n event.stopPropagation();\n const targetNode = $(event.target);\n const secondLevel = targetNode.closest('.mobile-navigation__container--second-level');\n const thirdLevel = targetNode.parent().next();\n\n $.each(this.toggleThirdLevelLinks, function () {\n $(this).addClass('hide');\n });\n\n $.each(this.secondLevelBackButtons, function () {\n $(this).addClass('hide');\n });\n\n secondLevel.removeClass('remove');\n thirdLevel.addClass('active');\n }\n\n\n handleSecondLevelBackButton(event) {\n event.preventDefault();\n event.stopPropagation();\n const targetNode = $(event.target);\n const secondLevel = targetNode.parent();\n\n $.each(this.toggleSecondLevelLinks, function () {\n $(this).removeClass('hide');\n });\n\n $.each(this.secondLevelBackButtons, function () {\n $(this).removeClass('hide');\n });\n\n secondLevel.removeClass('active');\n }\n\n handleThirdLevelBackButton(event) {\n event.preventDefault();\n event.stopPropagation();\n\n const targetNode = $(event.target);\n const thirdLevel = targetNode.parent();\n\n $.each(this.toggleThirdLevelLinks, function () {\n $(this).removeClass('hide');\n });\n\n $.each(this.toggleThirdLevelLinks, function () {\n $(this).removeClass('hide');\n });\n\n thirdLevel.removeClass('active');\n }\n\n openInSameTab(event) {\n event.preventDefault();\n event.stopPropagation();\n window.open($(event.currentTarget).attr('href'), '_self');\n }\n\n resetMobileNav() {\n $.each(this.toggleSecondLevelLinks, function () {\n jQuery(this).removeClass('hide');\n });\n $.each(this.secondLevelBackButtons, function () {\n $(this).addClass('hide');\n });\n $.each(this.thirdLevelBackButtons, function () {\n $(this).addClass('hide');\n });\n $.each(this.secondLevelContainer, function () {\n $(this).removeClass('active');\n });\n $.each(this.ThirdlevelContainer, function () {\n $(this).removeClass('active');\n });\n }\n}\n","/**\n * Component: Modal\n */\n\nexport default class Modal {\n constructor(id, config) {\n this.ns = 'modal';\n this.$self = jQuery('#' + id + '.' + this.ns);\n this.options = this.$self.data('options');\n this.$overlay = this.$self.find('.' + this.ns + '__overlay');\n this.$closeBtn = this.$self.find('.' + this.ns + '__close');\n\n this.closeElements = [];\n this.closeElements.push(this.$overlay); // Close the modal if overlay is clicked\n this.closeElements.push(this.$closeBtn);\n\n this.openModal = this.openModal.bind(this);\n this.closeModal = this.closeModal.bind(this);\n\n if (this.options) {\n // Bind click event to trigger modal selector\n this.$modalOpenElement = jQuery(this.options.triggerModalOpenSelector);\n // Set autoOpen if exists in options object\n this.autoOpen = this.options.autoOpen;\n this.autoOpenFlag = this.options.autoOpenFlag;\n }\n\n if (this.$self) {\n this.init(config);\n }\n }\n\n init(config) {\n this.setOpenHandlers();\n this.setCloseHandlers();\n this.setCloseButtonState(this.$closeBtn, config);\n this.setOptionalCallbacks(config);\n\n if (this.autoOpen && this.autoOpenFlag) {\n this.openOnInit();\n }\n\n $('body').on('click', '#headache-subscribe', function (e) {\n e.preventDefault();\n this.openModal();\n });\n }\n\n openOnInit() {\n // If localStorage key has NOT been set yet, open modal.\n if (!window.localStorage.getItem(this.autoOpenFlag)) {\n this.openModal();\n }\n }\n\n setOpenHandlers() {\n if (this.$modalOpenElement) {\n this.$modalOpenElement.on('click', () => {\n this.openModal();\n });\n }\n }\n\n openModal() {\n $('body').addClass('no-scroll');\n this.$self.addClass(this.ns + '--opened');\n\n if (this.openCallback) {\n this.openCallback();\n }\n }\n\n setCloseHandlers() {\n for (var i = 0; i < this.closeElements.length; i++) {\n var el = this.closeElements[i];\n if (el) {\n $(el).on('click', () => {\n this.closeModal();\n });\n }\n }\n\n $(document).on('keydown', (e) => {\n var key = e.key || e.keyCode;\n if (\n key === 'Escape'\n || key === 'Esc'\n || key === 27\n ) {\n this.closeModal();\n }\n });\n }\n\n closeModal() {\n $('body').removeClass('no-scroll');\n this.$self.removeClass(this.ns + '--opened');\n\n if (this.closeCallback) {\n this.closeCallback();\n }\n\n if (this.autoOpen && this.autoOpenFlag) {\n window.localStorage.setItem(this.autoOpenFlag, true);\n }\n }\n\n setCloseButtonState($closeBtn, config) {\n if (config) {\n this.showCloseButton = config.showCloseButton;\n\n if (this.showCloseButton === true) {\n $closeBtn.show();\n } else {\n $closeBtn.hide();\n }\n }\n }\n\n setOptionalCallbacks(config) {\n if (config) {\n var openCb = config.openCallback;\n var closeCb = config.closeCallback;\n if (typeof openCb === 'function') {\n this.openCallback = openCb;\n }\n\n if (typeof closeCb === 'function') {\n this.closeCallback = closeCb;\n }\n }\n }\n}\n","/**\n * Component: AccordionModule\n */\n\nexport default class AccordionModule {\n constructor() {\n this.$self = $('.js-accordion-module');\n this.$graphic = this.$self.find('.js-accordion-module-graphic');\n this.$items = this.$self.find('.js-accordion-module-item');\n\n this.init();\n }\n\n init() {\n this.$items.each((idx, item) => {\n $(item).on('click', () => {\n var allCollapsed = true;\n\n setTimeout(() => {\n this.$items.each(function (i, el) {\n if (!$(el).hasClass('collapsed')) {\n allCollapsed = false;\n return;\n }\n });\n if (allCollapsed) {\n this.$graphic.removeClass('opacity-0');\n } else {\n this.$graphic.addClass('opacity-0');\n }\n }, 300);\n });\n });\n }\n}\n","'use strict';\nvar slickConfigs = require('../config/slickConfigs');\n\n/**\n * Init globally reusable carousels\n */\n\nmodule.exports = {\n heroCarousels: function () {\n $('.hero-caro').not('.slick-initialized').slick(slickConfigs.hero);\n },\n productTileCarousels: function () {\n $('.product-tile-caro').not('.slick-initialized').slick(slickConfigs.productTiles);\n },\n pdpCarousels: function () {\n $('div.page-wrapper:not(.npi-pro):not(.npi-security) .product-overview__gallery-slides').not('.slick-initialized').slick(slickConfigs.pdp);\n }\n};\n","/**\n * Arlo SFCC Static\n * Main entry point.\n */\n\n/**\n * Global Modules\n */\nimport Modal from './Modal';\nconst { adjustWarrantyPriceSpace } = require('../checkout/adjustWarrantyPriceSpace');\n\nnew Modal('region-selector-content');// eslint-disable-line no-new\n\n /**\n * Handle Mobile Navigation\n */\nimport MobileNavigation from './MobileNavigation';\nconst mobile_nav = new MobileNavigation();// eslint-disable-line camelcase\n\n/**\n * Main Variables\n */\n\nvar body = document.querySelector('body');\n\n/**\n * HEADER FUNCTIONALITY\n */\nvar header = document.querySelector('.header');\nvar miniCartHeader = document.querySelector('.minicart-wrap__header');\nvar headerBanner = document.querySelector('.header__banner');\nvar headerContainer = document.querySelector('.header__container');\n\nif (headerBanner) {\n if (headerBanner.classList.contains('active')) {\n window.addEventListener('scroll', () => {\n if (window.scrollY > headerBanner.offsetHeight) {\n if (headerContainer && headerContainer.classList) {\n headerContainer.classList.add('fixed');\n }\n if (miniCartHeader && miniCartHeader.classList) {\n miniCartHeader.classList.add('scrolled');\n }\n } else {\n if (headerContainer && headerContainer.classList) {\n headerContainer.classList.remove('fixed');\n }\n if (miniCartHeader && miniCartHeader.classList) {\n miniCartHeader.classList.remove('scrolled');\n }\n }\n });\n } else {\n headerContainer.classList.add('fixed');\n }\n}\n\nvar hamburger = document.querySelector('.header__mobile-hamburger');\n\nif (hamburger) {\n hamburger.addEventListener('click', (e) => {\n e.preventDefault();\n if (hamburger.classList.contains('active')) {\n hamburger.classList.remove('active');\n body.classList.remove('no-scroll');\n headerContainer.classList.remove('menu-open');\n } else {\n hamburger.classList.add('active');\n body.classList.add('no-scroll');\n headerContainer.classList.add('menu-open');\n }\n setTimeout(() => { mobile_nav.resetMobileNav(); }, 500);\n }, false);\n\n window.addEventListener('resize', () => {\n if (window.innerWidth >= 1200) {\n hamburger.classList.remove('active');\n body.classList.remove('no-scroll');\n headerContainer.classList.remove('menu-open');\n }\n });\n}\n\n/**\n* CHECKOUT HEADER FUNCTIONALITY\n*/\nvar expandOrderSummaryButton = document.querySelector('[data-expand-summary]');\n\nif (expandOrderSummaryButton) {\n expandOrderSummaryButton.addEventListener('click', () => {\n jQuery('[data-order-summary-column]').slideToggle('slow');\n jQuery('[data-expand-arrow]').toggleClass('expanded');\n adjustWarrantyPriceSpace();\n });\n}\n\n/**\n * FOOTER FUNCTIONALITY\n */\nvar newsletterInput = document.querySelector('.footer__newsletter-form input');\nvar newsletterButton = document.querySelector('.footer__newsletter-form button');\nvar newsletterDesktopPlaceholder = document.querySelector('.footer__newsletter-placeholder');\n\nif (newsletterInput) {\n newsletterInput.addEventListener('input', () => {\n if (newsletterInput.value) {\n newsletterButton.disabled = false;\n newsletterDesktopPlaceholder.style.display = 'none';\n } else {\n newsletterButton.disabled = true;\n newsletterDesktopPlaceholder.style.display = '';\n }\n });\n}\n\n/**\n * MODAL/POPUP FUNCTIONALITY\n */\nvar modalOverlay = document.querySelector('.modal-overlay');\nvar searchIcon = document.querySelector('.item-search');\nvar searchBar = document.querySelector('.search-bar');\nvar cartIcon = document.querySelector('.item-cart');\nvar miniCart = document.querySelector('.minicart_wrap');\nvar searchBarClose = document.querySelector('.search-bar__close');\nvar miniCartClose = document.querySelector('.minicart__close');\n\n/**\n * Removes classes to remove modal overlays.\n */\nfunction closeOverlays() {\n body.classList.remove('no-scroll');\n modalOverlay.classList.remove('active');\n searchBar.classList.remove('active');\n miniCart.classList.remove('active');\n header.classList.remove('cart-open');\n headerBanner.classList.remove('cart-open');\n}\n\n/**\n * Search Icon click\n */\nif (searchIcon) {\n searchIcon.addEventListener('click', (e) => {\n e.preventDefault();\n body.classList.add('no-scroll');\n $('input.search-field').val('');\n $('input.search-field').html('');\n $('input.search-field').focus();\n modalOverlay.classList.add('active');\n searchBar.classList.add('active');\n $('.search-bar__results').html('');\n });\n}\n\n/**\n * Search Bar Close Click\n */\nif (searchBarClose) {\n searchBarClose.addEventListener('click', () => {\n closeOverlays();\n });\n}\n\n/**\n * Cart Icon click\n */\nif (cartIcon) {\n cartIcon.addEventListener('click', (e) => {\n if ($('body').width() < 744) {\n e.preventDefault();\n if ($('.page').attr('data-action') !== 'Cart-Show') {\n body.classList.add('no-scroll');\n modalOverlay.classList.add('active');\n miniCart.classList.add('active');\n header.classList.add('cart-open');\n headerBanner.classList.add('cart-open');\n }\n }\n });\n}\n\n/**\n * Mini Cart Close Click\n */\nif (miniCartClose) {\n miniCartClose.addEventListener('click', () => {\n closeOverlays();\n });\n}\n\n/**\n * Modal Overlay Click\n */\nif (miniCartClose) {\n modalOverlay.addEventListener('click', () => {\n closeOverlays();\n });\n}\n\n/**\n * Floating Labels for input fields\n */\nvar floatContainers = document.querySelectorAll('.form-float-container');\n\n// add active class\nvar handleFocus = (e) => {\n var target = e.target;\n target.parentNode.classList.add('active');\n target.setAttribute('placeholder', (target.getAttribute('data-placeholder') || ''));\n};\n\n// remove active class\nvar handleBlur = (e) => {\n var target = e.target;\n\n if (!target.value) {\n target.parentNode.classList.remove('active');\n }\n\n target.removeAttribute('placeholder');\n};\n\nvar bindEvents = (element) => {\n var floatField = element.querySelector('input') ? element.querySelector('input') : element.querySelector('textarea');\n floatField.addEventListener('focus', handleFocus);\n floatField.addEventListener('blur', handleBlur);\n};\n\nif (floatContainers.length > 0) {\n floatContainers.forEach((element) => {\n if (element.querySelector('select')) return;\n\n var inputElement = element.querySelector('input') ? element.querySelector('input') : element.querySelector('textarea');\n\n if (inputElement.value) {\n element.classList.add('active');\n }\n\n bindEvents(element);\n });\n}\n\n /**\n * Handle Navigation Dropdown\n */\n$('.toggle-nav-dropdown').on('mouseenter', function () {\n $('.navigation-dropdown').removeClass('show');\n var catId = $(this).data('cat-id');\n $(`.navigation-dropdown[data-cat-id=\"${catId}\"]`).addClass('show');\n document.querySelector('.modal-overlay').classList.add('active');\n});\n$('.header__nav-link:not(.toggle-nav-dropdown)').on('mouseenter', function () {\n $('.navigation-dropdown').removeClass('show');\n document.querySelector('.modal-overlay').classList.remove('active');\n});\n$('.navigation-dropdown').on('mouseleave', function () {\n $('.navigation-dropdown').removeClass('show');\n document.querySelector('.modal-overlay').classList.remove('active');\n});\n\n$('.header__container').on('mouseleave', function () {\n $('.navigation-dropdown').removeClass('show');\n document.querySelector('.modal-overlay').classList.remove('active');\n});\n\n$('body').on('click', '.flyout-cart__continue', function () {\n $('.modal__close').trigger('click');\n});\n\n$('body').on('click', '.mobile-navigation__product-card a', function (e) {\n e.preventDefault();\n window.location.href = $(this).attr('href');\n});\n","'use strict';\n\nvar SFMCErrorHandler = require('../thirdParty/sfmcErrorHandler');\n\n/**\n * @name findEmailSubscriptionError\n * @description find out the error msg for email\n * subscription based on error code and control\n * @param {string} errorcode input param\n * @param {string} errorcontrol input param\n * @returns {string} error message\n */\nfunction findEmailSubscriptionError(errorcode, errorcontrol) {\n var form = 'footer';\n var error = SFMCErrorHandler.getEmailSubscriptionError(errorcode, errorcontrol, form);\n return error;\n}\n\n$(document).ready(function () {\n $('#regionSelect').select2({\n minimumResultsForSearch: -1,\n dropdownPosition: 'below',\n width: '100%'\n });\n\n $('.footer__newsletter__result').hide();\n\n var newsletterInput = document.querySelector('.footer__newsletter-form input.sfmc-nl');\n var newsletterButton = document.querySelector('.footer__newsletter-form button.sfmc-nl-btn');\n var newsletterDesktopPlaceholder = document.querySelector('.footer__newsletter-placeholder');\n\n if (newsletterInput) {\n newsletterInput.addEventListener('input', () => {\n if (newsletterInput.value) {\n newsletterButton.disabled = false;\n newsletterDesktopPlaceholder.style.display = 'none';\n } else {\n newsletterButton.disabled = true;\n newsletterDesktopPlaceholder.style.display = '';\n }\n });\n }\n\n var pattern = /^\\w+([-+.'][^\\s]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/;\n $(newsletterButton).off('click').on('click', function () {\n var email = $(newsletterInput).val();\n if (!pattern.test(email)) {\n $('.footer__newsletter__result').hide();\n $('.footer__newsletter__result__invalid').show();\n }\n });\n\n var url = window.location.href.split('?')[0];\n var urlParams = new URLSearchParams(window.location.search);\n var signupSuccessUrl = $('#footer-email-signup-success');\n var signupErrorUrl = $('#footer-email-signup-error');\n var pageUrl = new URL(window.location).toString();\n // if an error occurs the hash that hooks up to the anchor is buried in the parameter string\n // this code moves the hash back to the end of the URL and reloads the page.\n var hash = '#above-footer';\n var hasNewsletter = urlParams.has('newsletter_signup');\n if (hasNewsletter === true) {\n if (!pageUrl.endsWith(hash)) {\n if (pageUrl.includes(hash)) {\n pageUrl = pageUrl.replace(hash, '') + hash;\n window.location.href = pageUrl;\n }\n }\n }\n if (signupSuccessUrl) {\n $(signupSuccessUrl).val(url + '?newsletter_signup=success' + hash);\n }\n\n if (signupErrorUrl) {\n $(signupErrorUrl).val(url + '?newsletter_signup=error' + hash);\n }\n\n var anyMsg = urlParams.get('newsletter_signup');\n if (anyMsg === 'success' || anyMsg === 'error') {\n $('.footer__newsletter__result').hide();\n if (anyMsg === 'success') {\n $('.footer__newsletter__result__success').show();\n } else {\n var errorcode = urlParams.has('errorcode') ? urlParams.get('errorcode') : null;\n var errorcontrol = urlParams.has('errorcontrol') ? urlParams.get('errorcontrol') : null;\n var errorMsg = findEmailSubscriptionError(errorcode, errorcontrol);\n $('.footer__newsletter__result__error').text(errorMsg).show();\n }\n }\n setTimeout(() => {\n if ($('.footer__panel-heading').length) {\n $('.footer__panel-heading button').eq(0).attr('aria-expanded', 'false');\n $('.footer__panel-heading button').eq(0).attr('class', 'collapsed');\n $('.footer__panel-heading').eq(0).click();\n }\n }, 2000);\n});\n","'use strict';\n\nvar keyboardAccessibility = require('base/components/keyboardAccessibility');\n\nvar clearSelection = function (element) {\n $(element).closest('.dropdown').children('.dropdown-menu').children('.top-category')\n .detach();\n $(element).closest('.dropdown.show').children('.nav-link').attr('aria-expanded', 'false');\n $(element).closest('.dropdown.show').removeClass('show');\n $(element).closest('li').detach();\n};\n\nmodule.exports = function () {\n var isDesktop = function (element) {\n return $(element).parents('.menu-toggleable-right').css('position') !== 'fixed';\n };\n\n $('.header-banner .close').on('click', function () {\n $('.header-banner').addClass('hide');\n });\n\n keyboardAccessibility('.main-menu .nav-link, .main-menu .dropdown-link',\n {\n 40: function (menuItem) { // down\n if (menuItem.hasClass('nav-item')) { // top level\n $('.navbar-nav .show').removeClass('show')\n .children('.dropdown-menu')\n .removeClass('show');\n menuItem.addClass('show').children('.dropdown-menu').addClass('show');\n $(this).attr('aria-expanded', 'true');\n menuItem.find('ul > li > a')\n .first()\n .focus();\n } else {\n menuItem.removeClass('show').children('.dropdown-menu').removeClass('show');\n $(this).attr('aria-expanded', 'false');\n menuItem.next().children().first().focus();\n }\n },\n 39: function (menuItem) { // right\n if (menuItem.hasClass('nav-item')) { // top level\n menuItem.removeClass('show').children('.dropdown-menu').removeClass('show');\n $(this).attr('aria-expanded', 'false');\n menuItem.next().children().first().focus();\n } else if (menuItem.hasClass('dropdown')) {\n menuItem.addClass('show').children('.dropdown-menu').addClass('show');\n $(this).attr('aria-expanded', 'true');\n menuItem.find('ul > li > a')\n .first()\n .focus();\n }\n },\n 38: function (menuItem) { // up\n if (menuItem.hasClass('nav-item')) { // top level\n menuItem.removeClass('show').children('.dropdown-menu').removeClass('show');\n $(this).attr('aria-expanded', 'false');\n } else if (menuItem.prev().length === 0) {\n menuItem.parent().parent().removeClass('show')\n .children('.nav-link')\n .attr('aria-expanded', 'false');\n menuItem.parent().parent().children().first()\n .focus();\n } else {\n menuItem.prev().children().first().focus();\n }\n },\n 37: function (menuItem) { // left\n if (menuItem.hasClass('nav-item')) { // top level\n menuItem.removeClass('show').children('.dropdown-menu').removeClass('show');\n $(this).attr('aria-expanded', 'false');\n menuItem.prev().children().first().focus();\n } else {\n menuItem.closest('.show').removeClass('show')\n .closest('li.show').removeClass('show')\n .children()\n .first()\n .focus()\n .attr('aria-expanded', 'false');\n }\n },\n 27: function (menuItem) { // escape\n var parentMenu = menuItem.hasClass('show')\n ? menuItem\n : menuItem.closest('li.show');\n parentMenu.children('.show').removeClass('show');\n parentMenu.removeClass('show').children('.nav-link')\n .attr('aria-expanded', 'false');\n parentMenu.children().first().focus();\n }\n },\n function () {\n return $(this).parent();\n }\n );\n\n $('.dropdown:not(.disabled) [data-toggle=\"dropdown\"]')\n .on('click', function (e) {\n var isCustomNav = $(this).hasClass('custom-nav-anchor');\n if (!isDesktop(this) && !isCustomNav) {\n $('.modal-background').show();\n // copy parent element into current UL\n var li = $('
  • ');\n var link = $(this).clone().removeClass('dropdown-toggle')\n .removeAttr('data-toggle')\n .removeAttr('aria-expanded')\n .attr('aria-haspopup', 'false');\n li.append(link);\n var closeMenu = $('
  • ');\n closeMenu.append($('.close-menu').first().clone());\n $(this).parent().children('.dropdown-menu')\n .prepend(li)\n .prepend(closeMenu);\n // copy navigation menu into view\n $(this).parent().addClass('show');\n $(this).attr('aria-expanded', 'true');\n e.preventDefault();\n } else if ($(this).attr('id') === 'compatibleDevicesDropdown') {\n $(this).siblings('.dropdown-menu-area').show();\n $(this).siblings('.dropdown-menu').addClass('show');\n $('body').addClass('overflow-x-hidden');\n $(this).attr('aria-expanded', 'true');\n\n $(this).closest('.dropdown').find('.dropdown-close').unbind('click');\n $(this).closest('.dropdown').find('.dropdown-close').on('click', function () {\n if ($(this).closest('.dropdown-menu-area').hasClass('show')) {\n $(this).closest('.dropdown').removeClass('show');\n $(this).closest('.dropdown').find('.dropdown-menu').removeClass('show');\n $(this).closest('.dropdown').find('.dropdown-toggle').attr('aria-expanded', 'false');\n $(this).closest('.dropdown-menu-area').hide();\n $('body').removeClass('overflow-x-hidden');\n }\n });\n }\n })\n .on('mouseenter', function () {\n if (isDesktop(this)) {\n var eventElement = this;\n $('.navbar-nav > li').each(function () {\n if (!$.contains(this, eventElement)) {\n $(this).find('.show').each(function () {\n clearSelection(this);\n });\n if ($(this).hasClass('show')) {\n $(this).removeClass('show');\n $(this).children('ul.dropdown-menu').removeClass('show');\n $(this).children('.nav-link').attr('aria-expanded', 'false');\n }\n }\n });\n // need to close all the dropdowns that are not direct parent of current dropdown\n $(this).parent().addClass('show');\n $(this).siblings('.dropdown-menu').addClass('show');\n $('body').addClass('overflow-x-hidden');\n $(this).attr('aria-expanded', 'true');\n }\n })\n .parent()\n .on('mouseleave', function () {\n if (isDesktop(this)) {\n $(this).removeClass('show');\n $(this).children('.dropdown-menu').removeClass('show');\n $('body').removeClass('overflow-x-hidden');\n $(this).children('.nav-link').attr('aria-expanded', 'false');\n }\n });\n\n $('.navbar').on('click', '.nav-toggle', function () {\n $(this).toggleClass('dropdown-carret');\n $(this).siblings('ul[role=menu]').toggleClass('d-none');\n });\n\n $('.navbar>.close-menu>.close-button').on('click', function (e) {\n e.preventDefault();\n $('.menu-toggleable-right').removeClass('in');\n $('.modal-background').hide();\n });\n\n $('.navbar-nav').on('click', '.back', function (e) {\n e.preventDefault();\n clearSelection(this);\n });\n\n $('.navbar-nav').on('click', '.close-button', function (e) {\n e.preventDefault();\n $('.navbar-nav').find('.top-category').detach();\n $('.navbar-nav').find('.nav-menu').detach();\n $('.navbar-nav').find('.show').removeClass('show');\n $('.menu-toggleable-right').removeClass('in');\n $('.modal-background').hide();\n });\n\n $('.navbar-toggler').click(function (e) {\n e.preventDefault();\n $('.main-menu').toggleClass('in');\n $('.modal-background').show();\n $('.dropdown-menu').remove();\n });\n\n keyboardAccessibility('.navbar-header .user',\n {\n 40: function ($popover) { // down\n if ($popover.children('a').first().is(':focus')) {\n $popover.children('a').first().next().focus();\n } else {\n $popover.children('a').first().focus();\n }\n },\n 38: function ($popover) { // up\n if ($popover.children('a').first().is(':focus')) {\n $(this).focus();\n $popover.removeClass('show');\n } else {\n $popover.children('a').first().focus();\n }\n },\n 27: function ($popover) { // escape\n $(this).focus();\n $popover.removeClass('show');\n },\n 9: function ($popover) { // tab\n $popover.removeClass('show');\n }\n },\n function () {\n var $popover = $('.user .popover');\n if (!($popover.hasClass('show'))) {\n $popover.addClass('show');\n }\n return $popover;\n }\n );\n\n\n $('.navbar-header .user').on('mouseenter focusin', function () {\n if ($('.navbar-header .user .popover').length > 0) {\n $('.navbar-header .user .popover').addClass('show');\n }\n });\n\n $('.navbar-header .user').on('mouseleave', function () {\n $('.navbar-header .user .popover').removeClass('show');\n });\n};\n","'use strict';\n\nvar cart = require('../cart/cart');\n\nmodule.exports = function () {\n cart();\n\n $('.minicart').on('count:update', function (event, count) {\n if (count && $.isNumeric(count.quantityTotal)) {\n $('.item-cart .cart-count').text(count.quantityTotal);\n if (count.quantityTotal > 0) {\n $('.header__utilities-item.item-cart.minicart').addClass('indicator');\n } else {\n $('.header__utilities-item.item-cart.minicart').removeClass('indicator');\n }\n }\n });\n\n try {\n $('.mob-byb-discount').css('width', $('.hybridbundle-line-item').width());\n $(window).on('resize', function () {\n var win = $(this);\n if (win.width() < 600 && $('.mob-byb-discount').length) {\n $('.mob-byb-discount').css('width', $('.hybridbundle-line-item').width());\n }\n });\n } catch (error) {\n console.log(error);\n }\n\n $('.minicart').on('mouseenter focusin touchstart', function () {\n if ($('.cart-page').length !== 0) {\n return;\n }\n if ($('.search:visible').length === 0) {\n return;\n }\n var url = $('.minicart').data('action-url');\n var count = parseInt($('.minicart .minicart-quantity').text(), 10);\n\n if (count !== 0 && $('.minicart .popover.show').length === 0) {\n $('.minicart .popover').addClass('show');\n // $('.minicart .popover').spinner().start();\n $.get(url, function (data) {\n $('.minicart .popover').empty();\n $('.minicart .popover').parent().each(function () {\n if (!$(this).hasClass('mobile-header')) {\n $(this).children('.minicart .popover').append(data);\n }\n });\n // $.spinner().stop();\n });\n }\n });\n $('body').on('touchstart click', function (e) {\n if ($('.minicart').has(e.target).length <= 0) {\n $('.minicart .popover').empty();\n $('.minicart .popover').removeClass('show');\n }\n });\n $('.minicart').on('mouseleave focusout', function (event) {\n if ((event.type === 'focusout' && $('.minicart').has(event.target).length > 0)\n || (event.type === 'mouseleave' && $(event.target).is('.minicart .quantity'))\n || $('body').hasClass('modal-open')) {\n event.stopPropagation();\n return;\n }\n $('.minicart .popover').empty();\n $('.minicart .popover').removeClass('show');\n });\n $('body').on('change', '.minicart .quantity', function () {\n if ($(this).parents('.bonus-product-line-item').length && $('.cart-page').length) {\n location.reload();\n }\n });\n\n/**\n * re-renders the order totals and the number of items in the cart\n * @param {Object} message - Error message to display\n */\n function createErrorNotification(message) {\n if ($('.alert-danger').length < 1) {\n var errorHtml = '
    ' +\n '' + message + '
    ';\n\n $('.cart-error').append(errorHtml);\n } else if ($('body').find('#checkout-main')) {\n var errorHtml2 = '
    ' +\n '' + message + '
    ';\n\n $('.cart-error').empty().append(errorHtml2);\n }\n }\n\n/**\n * Event Handlers for Quantity Controls\n */\n $('body').on('click', '.liq-minus', function () {\n var quantity = $(this).siblings('.quantity').val();\n if (quantity !== '1') {\n /* $('.liq-minus').removeAttr('disabled'); */\n this.parentNode.querySelector('input[type=number]').stepDown();\n var updatedQuantity = $(this).siblings('.quantity').val();\n if (updatedQuantity === '1') {\n $(this).attr('disabled', true).text('');\n }\n $(this).parent().find('input[type=number]').addClass('reduceqty');\n $(this).parent().find('input[type=number]').trigger('change');\n }\n });\n $('body').on('click', '.liq-plus', function () {\n var ATS = '10';\n if ($(this).siblings('.quantity').data('inventory') < 10) {\n ATS = $(this).siblings('.quantity').data('inventory').toString();\n }\n var quantity = $(this).siblings('.quantity').val();\n if (ATS === quantity) {\n var errmsg = 'You have reached the max quantity';\n createErrorNotification(errmsg);\n $('.js-minicart-block').animate({\n scrollTop: 0\n });\n } else {\n this.parentNode.querySelector('input[type=number]').stepUp();\n $(this).siblings('.liq-minus').removeAttr('disabled').text('-');\n $(this).parent().find('input[type=number]').trigger('change');\n }\n });\n\n/**\n * MODAL/POPUP FUNCTIONALITY\n */\n var modalOverlay = document.querySelector('.modal-overlay');\n var cartIcon = document.querySelector('.item-cart');\n var miniCart = document.querySelector('.minicart_wrap');\n var body = document.querySelector('body');\n var header = document.querySelector('.header');\n var headerBanner = document.querySelector('.header__banner');\n\n/**\n * Removes classes to remove modal overlays.\n */\n function closeOverlays() {\n $('#removeProductModal').find('button.close').click();\n body.classList.remove('no-scroll');\n body.classList.remove('mini-cart-active');\n if (modalOverlay) {\n modalOverlay.classList.remove('active');\n }\n if (miniCart) {\n miniCart.classList.remove('active');\n }\n }\n\n/**\n * Opens minicart.\n * @param {Object} e jquery event object\n */\n function openCart(e) {\n if ($('.page').attr('data-action') !== 'Cart-Show') {\n if ($('body .page[data-action=Cart-Show]').length < 1) {\n if ($('.minicart_wrap').children().length) {\n $('body').addClass('mini-cart-active');\n $('body').addClass('no-scroll');\n $('.modal-overlay').addClass('active');\n $('.minicart_wrap').addClass('active');\n } else {\n if (!$('.minicart_wrap').hasClass('express-checkout')) { // eslint-disable-line no-lonely-if\n var url = $('.cart-link').attr('data-href');\n $.get(url, function (data) {\n if (!data.error) {\n $('.minicart_wrap').empty();\n $('.minicart_wrap').parent().each(function () {\n if (!$(this).hasClass('mobile-header')) {\n $(this).children('.minicart_wrap').append(data);\n }\n });\n if (typeof affirm !== 'undefined') { // eslint-disable-line\n affirm.ui.ready(function () { // eslint-disable-line\n affirm.ui.refresh(); // eslint-disable-line\n });\n }\n modalOverlay.classList.add('active');\n miniCart.classList.add('active');\n body.classList.add('mini-cart-active');\n body.classList.add('no-scroll');\n header.classList.add('cart-open');\n if (headerBanner) {\n headerBanner.classList.add('cart-open');\n }\n $('.mob-byb-discount').css('width', $('.hybridbundle-line-item').width());\n } else if (data.error && data.message === 'Express Checkout') {\n $('.minicart_wrap').empty();\n body.classList.remove('no-scroll');\n miniCart.classList.add('express-checkout');\n if (e.type === 'touchstart') {\n window.location.href = $(e.target).closest('a').prop('href');\n }\n }\n });\n // $('.minicart_wrap').spinner().start();\n }\n }\n }\n }\n }\n\n/**\n * Cart Icon click\n */\n if (cartIcon) {\n if ($('body').width() < 1200) {\n cartIcon.addEventListener('touchstart', (e) => {\n e.preventDefault();\n openCart(e);\n });\n } else {\n cartIcon.addEventListener('mouseover', (e) => {\n e.preventDefault();\n openCart(e);\n });\n }\n }\n\n/**\n * Mini Cart Close Click\n */\n $('body').on('touchstart click', '.minicart_wrap__close, a.close-cart', function (e) {\n if (e.cancelable) {\n e.preventDefault();\n }\n closeOverlays();\n });\n $('body').on('mouseover', '.minicart_wrap__close, a.close-cart', function (e) {\n if (e.cancelable) {\n e.preventDefault();\n }\n closeOverlays();\n });\n $('body').on('click', '.minicart_wrap__close, a.close-cart', function (e) {\n if (e.cancelable) {\n e.preventDefault();\n }\n closeOverlays();\n });\n\n\n $('.page').children().not('.header').not('.minicart_wrap')\n .on('mouseenter mouseover', function () {\n closeOverlays();\n });\n\n $(document).on('click', 'body,html', function (e) {\n // eslint-disable-next-line no-console\n if ($('minicart_wrap').hasClass('active')) {\n var sideIconToggle = document.querySelector('.minicart_wrap');\n var itemCart = document.querySelector('.item-cart');\n var flyoutCart = document.querySelector('#flyout-cart');\n if (!sideIconToggle.contains(e.target) && !itemCart.contains(e.target) && (!flyoutCart || !flyoutCart.contains(e.target))) {\n e.preventDefault();\n closeOverlays();\n }\n }\n });\n\n/**\n* Mini Cart Close On Browser Tab Change\n*/\n document.addEventListener('visibilitychange', function () {\n if (document.visibilityState === 'hidden') {\n if ($('.minicart_wrap').hasClass('active')) {\n closeOverlays();\n }\n }\n });\n\n/**\n * Modal Overlay Click\n */\n if (modalOverlay) {\n modalOverlay.addEventListener('click', () => {\n closeOverlays();\n });\n }\n};\n","'use strict';\n\nvar debounce = require('lodash/debounce');\nvar minChars = 3;\n\n\n/**\n * Retrieves Suggestions element relative to scope\n *\n * @param {Object} scope - Search input field DOM element\n * @return {JQuery} - .search-bar__results element\n */\nfunction getSuggestionsWrapper() {\n return $('.search-bar__results');\n}\n\n/**\n * Determines whether DOM element is inside the .search-mobile class\n *\n * @param {Object} scope - DOM element, usually the input.search-field element\n * @return {boolean} - Whether DOM element is inside div.search-mobile\n */\nfunction isMobileSearch(scope) {\n return !!$(scope).closest('.search-mobile').length;\n}\n\n/**\n * Remove modal classes needed for mobile suggestions\n *\n */\nfunction clearModals() {\n $('body').removeClass('modal-open');\n $('.suggestions').removeClass('modal');\n}\n\n/**\n * Apply modal classes needed for mobile suggestions\n *\n * @param {Object} scope - Search input field DOM element\n */\nfunction applyModals(scope) {\n if (isMobileSearch(scope)) {\n $('body').addClass('modal-open');\n getSuggestionsWrapper(scope).find('.suggestions').addClass('modal');\n }\n}\n\n/**\n * Tear down Suggestions panel\n */\nfunction tearDownSuggestions() {\n $('input.search-field').val('');\n clearModals();\n $('.search-mobile .suggestions').unbind('scroll');\n $('.search-bar__results').empty();\n}\n\n/**\n * Toggle search field icon from search to close and vice-versa\n *\n * @param {string} action - Action to toggle to\n */\nfunction toggleSuggestionsIcon(action) {\n var mobileSearchIcon = '.search-mobile span.';\n var iconSearch = 'fa-search';\n var iconSearchClose = 'fa-close';\n\n if (action === 'close') {\n $(mobileSearchIcon + iconSearch).removeClass(iconSearch).addClass(iconSearchClose);\n } else {\n $(mobileSearchIcon + iconSearchClose).removeClass(iconSearchClose).addClass(iconSearch);\n }\n}\n\n/**\n * Determines whether the \"More Content Below\" icon should be displayed\n *\n * @param {Object} scope - DOM element, usually the input.search-field element\n */\nfunction handleMoreContentBelowIcon(scope) {\n if (($(scope).scrollTop() + $(scope).innerHeight()) >= $(scope)[0].scrollHeight) {\n $('.more-below').fadeOut();\n } else {\n $('.more-below').fadeIn();\n }\n}\n\n/**\n * Positions Suggestions panel on page\n *\n * @param {Object} scope - DOM element, usually the input.search-field element\n */\nfunction positionSuggestions(scope) {\n var outerHeight;\n var $scope;\n var $suggestions;\n var top;\n\n if (isMobileSearch(scope)) {\n $scope = $(scope);\n top = $scope.offset().top;\n outerHeight = $scope.outerHeight();\n $suggestions = getSuggestionsWrapper(scope).find('.suggestions');\n $suggestions.css('top', top + outerHeight);\n\n handleMoreContentBelowIcon(scope);\n\n // Unfortunately, we have to bind this dynamically, as the live scroll event was not\n // properly detecting dynamic suggestions element's scroll event\n $suggestions.scroll(function () {\n handleMoreContentBelowIcon(this);\n });\n }\n}\n\n/**\n * Process Ajax response for SearchServices-GetSuggestions\n *\n * @param {Object|string} response - Empty object literal if null response or string with rendered\n * suggestions template contents\n */\nfunction processResponse(response) {\n var $suggestionsWrapper = getSuggestionsWrapper(this).empty();\n\n $.spinner().stop();\n\n if (!(typeof (response) === 'object')) {\n $suggestionsWrapper.append(response).show();\n positionSuggestions(this);\n\n if (isMobileSearch(this)) {\n toggleSuggestionsIcon('close');\n applyModals(this);\n }\n } else {\n $suggestionsWrapper.hide();\n }\n}\n\n/**\n * Retrieve suggestions\n *\n * @param {Object} scope - Search field DOM element\n */\nfunction getSuggestions(scope) {\n if ($(scope).val().length >= minChars) {\n var endpoint = $('.search-bar__results').data('url');\n if (endpoint) {\n $.spinner().start();\n $.ajax({\n context: scope,\n url: endpoint + encodeURIComponent($(scope).val()),\n method: 'GET',\n success: processResponse,\n error: function () { $.spinner().stop(); }\n });\n }\n } else {\n toggleSuggestionsIcon('search');\n clearModals();\n getSuggestionsWrapper(scope).empty();\n }\n}\n\nmodule.exports = function () {\n // reinitializing select2 for sort if page load from back button\n $(document).ready(function () {\n var defaultSortValue;\n if (typeof $('#sel-sort .default').val() !== 'undefined') {\n defaultSortValue = $('#sel-sort .default').val();\n } else {\n defaultSortValue = $('#sel-sort').find('option:first-child').val();\n }\n if (performance.navigation.type === 2) {\n $('#sel-sort').val(defaultSortValue);\n $('#sel-sort').select2().trigger('change');\n $('#sel-sort').select2({\n minimumResultsForSearch: -1,\n width: 'resolve'\n });\n }\n });\n\n $(document).ready(function () {\n try {\n var breadcrumbHexColor = $('input[name=\"breadcrumbHexColor\"]').val();\n if (breadcrumbHexColor) {\n // Create a new style element\n var $style = $('');\n // Inject the new color for the pseudo-element using jQuery\n $style.text(`\n .breadcrumb-item::before {\n background-color: ${breadcrumbHexColor} !important;\n }\n `);\n // Append the style to the document head\n $('head').append($style);\n }\n } catch (e) {\n console.error('Error fetching or applying the color code');\n }\n });\n\n $('input.search-field').each(function () {\n /**\n * Use debounce to avoid making an Ajax call on every single key press by waiting a few\n * hundred milliseconds before making the request. Without debounce, the user sees the\n * browser blink with every key press.\n */\n var debounceSuggestions = debounce(getSuggestions, 300);\n\n $(this).on('keyup click', function (e) {\n debounceSuggestions(this, e);\n });\n });\n\n $('body').on('click', function (e) {\n if (!$('.suggestions').has(e.target).length && !$(e.target).hasClass('search-field')) {\n $('.suggestions').hide();\n }\n });\n\n $('body').on('click touchend', '.search-mobile span.fa-close', function () {\n $('.suggestions').hide();\n toggleSuggestionsIcon('search');\n tearDownSuggestions();\n });\n};\n","/* eslint-disable */\n;(function($) {\n\n var Defaults = $.fn.select2.amd.require('select2/defaults');\n\n $.extend(Defaults.defaults, {\n dropdownPosition: 'auto'\n });\n\n var AttachBody = $.fn.select2.amd.require('select2/dropdown/attachBody');\n\n var _positionDropdown = AttachBody.prototype._positionDropdown;\n\n AttachBody.prototype._positionDropdown = function() {\n\n var $window = $(window);\n\n var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');\n var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');\n\n var newDirection = null;\n\n var offset = this.$container.offset();\n\n offset.bottom = offset.top + this.$container.outerHeight(false);\n\n var container = {\n height: this.$container.outerHeight(false)\n };\n\n container.top = offset.top;\n container.bottom = offset.top + container.height;\n\n var dropdown = {\n height: this.$dropdown.outerHeight(false)\n };\n\n var viewport = {\n top: $window.scrollTop(),\n bottom: $window.scrollTop() + $window.height()\n };\n\n var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);\n var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);\n\n var css = {\n left: offset.left,\n top: container.bottom\n };\n\n // Determine what the parent element is to use for calciulating the offset\n var $offsetParent = this.$dropdownParent;\n\n // For statically positoned elements, we need to get the element\n // that is determining the offset\n if ($offsetParent.css('position') === 'static') {\n $offsetParent = $offsetParent.offsetParent();\n }\n\n var parentOffset = $offsetParent.offset();\n\n css.top -= parentOffset.top\n css.left -= parentOffset.left;\n\n var dropdownPositionOption = this.options.get('dropdownPosition');\n\n if (dropdownPositionOption === 'above' || dropdownPositionOption === 'below') {\n\n newDirection = dropdownPositionOption;\n\n } else {\n\n if (!isCurrentlyAbove && !isCurrentlyBelow) {\n newDirection = 'below';\n }\n\n if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {\n newDirection = 'above';\n } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {\n newDirection = 'below';\n }\n\n }\n\n if (newDirection == 'above' ||\n (isCurrentlyAbove && newDirection !== 'below')) {\n css.top = container.top - parentOffset.top - dropdown.height;\n }\n\n if (newDirection != null) {\n this.$dropdown\n .removeClass('select2-dropdown--below select2-dropdown--above')\n .addClass('select2-dropdown--' + newDirection);\n this.$container\n .removeClass('select2-container--below select2-container--above')\n .addClass('select2-container--' + newDirection);\n }\n\n this.$dropdownContainer.css(css);\n\n };\n\n})(window.jQuery);","/*! Select2 4.1.0-beta.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n/* eslint-disable */\n!function(n){\"function\"==typeof define&&define.amd?define([\"jquery\"],n):\"object\"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t=\"undefined\"!=typeof window?require(\"jquery\"):require(\"jquery\")(e)),n(t),t}:n(jQuery)}(function(u){var e=function(){if(u&&u.fn&&u.fn.select2&&u.fn.select2.amd)var e=u.fn.select2.amd;var t,n,i,h,s,o,f,g,m,v,y,_,r,a,b;function w(e,t){return r.call(e,t)}function l(e,t){var n,i,r,s,o,a,l,c,u,d,p,h=t&&t.split(\"/\"),f=y.map,g=f&&f[\"*\"]||{};if(e){for(o=(e=e.split(\"/\")).length-1,y.nodeIdCompat&&b.test(e[o])&&(e[o]=e[o].replace(b,\"\")),\".\"===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u\":\">\",'\"':\""\",\"'\":\"'\",\"/\":\"/\"};return\"string\"!=typeof e?e:String(e).replace(/[&<>\"'\\/\\\\]/g,function(e){return t[e]})},r.__cache={};var n=0;return r.GetUniqueElementId=function(e){var t=e.getAttribute(\"data-select2-id\");return null!=t||(t=e.id?\"select2-data-\"+e.id:\"select2-data-\"+(++n).toString()+\"-\"+r.generateChars(4),e.setAttribute(\"data-select2-id\",t)),t},r.StoreData=function(e,t,n){var i=r.GetUniqueElementId(e);r.__cache[i]||(r.__cache[i]={}),r.__cache[i][t]=n},r.GetData=function(e,t){var n=r.GetUniqueElementId(e);return t?r.__cache[n]&&null!=r.__cache[n][t]?r.__cache[n][t]:s(e).data(t):r.__cache[n]},r.RemoveData=function(e){var t=r.GetUniqueElementId(e);null!=r.__cache[t]&&delete r.__cache[t],e.removeAttribute(\"data-select2-id\")},r.copyNonInternalCssClasses=function(e,t){var n=e.getAttribute(\"class\").trim().split(/\\s+/);n=n.filter(function(e){return 0===e.indexOf(\"select2-\")});var i=t.getAttribute(\"class\").trim().split(/\\s+/);i=i.filter(function(e){return 0!==e.indexOf(\"select2-\")});var r=n.concat(i);e.setAttribute(\"class\",r.join(\" \"))},r}),e.define(\"select2/results\",[\"jquery\",\"./utils\"],function(h,f){function i(e,t,n){this.$element=e,this.data=n,this.options=t,i.__super__.constructor.call(this)}return f.Extend(i,f.Observable),i.prototype.render=function(){var e=h('
      ');return this.options.get(\"multiple\")&&e.attr(\"aria-multiselectable\",\"true\"),this.$results=e},i.prototype.clear=function(){this.$results.empty()},i.prototype.displayMessage=function(e){var t=this.options.get(\"escapeMarkup\");this.clear(),this.hideLoading();var n=h('
    • '),i=this.options.get(\"translations\").get(e.message);n.append(t(i(e.args))),n[0].className+=\" select2-results__message\",this.$results.append(n)},i.prototype.hideMessages=function(){this.$results.find(\".select2-results__message\").remove()},i.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n\",{class:\"select2-results__options select2-results__options--nested\"});p.append(l),o.append(a),o.append(p)}else this.template(e,t);return f.StoreData(t,\"data\",e),t},i.prototype.bind=function(t,e){var l=this,n=t.id+\"-results\";this.$results.attr(\"id\",n),t.on(\"results:all\",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on(\"results:append\",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on(\"query\",function(e){l.hideMessages(),l.showLoading(e)}),t.on(\"select\",function(){t.isOpen()&&(l.setClasses(),l.options.get(\"scrollAfterSelect\")&&l.highlightFirstItem())}),t.on(\"unselect\",function(){t.isOpen()&&(l.setClasses(),l.options.get(\"scrollAfterSelect\")&&l.highlightFirstItem())}),t.on(\"open\",function(){l.$results.attr(\"aria-expanded\",\"true\"),l.$results.attr(\"aria-hidden\",\"false\"),l.setClasses(),l.ensureHighlightVisible()}),t.on(\"close\",function(){l.$results.attr(\"aria-expanded\",\"false\"),l.$results.attr(\"aria-hidden\",\"true\"),l.$results.removeAttr(\"aria-activedescendant\")}),t.on(\"results:toggle\",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger(\"mouseup\")}),t.on(\"results:select\",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],\"data\");e.hasClass(\"select2-results__option--selected\")?l.trigger(\"close\",{}):l.trigger(\"select\",{data:t})}}),t.on(\"results:previous\",function(){var e=l.getHighlightedResults(),t=l.$results.find(\".select2-results__option--selectable\"),n=t.index(e);if(!(n<=0)){var i=n-1;0===e.length&&(i=0);var r=t.eq(i);r.trigger(\"mouseenter\");var s=l.$results.offset().top,o=r.offset().top,a=l.$results.scrollTop()+(o-s);0===i?l.$results.scrollTop(0):o-s<0&&l.$results.scrollTop(a)}}),t.on(\"results:next\",function(){var e=l.getHighlightedResults(),t=l.$results.find(\".select2-results__option--selectable\"),n=t.index(e)+1;if(!(n>=t.length)){var i=t.eq(n);i.trigger(\"mouseenter\");var r=l.$results.offset().top+l.$results.outerHeight(!1),s=i.offset().top+i.outerHeight(!1),o=l.$results.scrollTop()+s-r;0===n?l.$results.scrollTop(0):rthis.$results.outerHeight()||s<0)&&this.$results.scrollTop(r)}},i.prototype.template=function(e,t){var n=this.options.get(\"templateResult\"),i=this.options.get(\"escapeMarkup\"),r=n(e,t);null==r?t.style.display=\"none\":\"string\"==typeof r?t.innerHTML=i(r):h(t).append(r)},i}),e.define(\"select2/keys\",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define(\"select2/selection/base\",[\"jquery\",\"../utils\",\"../keys\"],function(n,i,r){function s(e,t){this.$element=e,this.options=t,s.__super__.constructor.call(this)}return i.Extend(s,i.Observable),s.prototype.render=function(){var e=n('');return this._tabindex=0,null!=i.GetData(this.$element[0],\"old-tabindex\")?this._tabindex=i.GetData(this.$element[0],\"old-tabindex\"):null!=this.$element.attr(\"tabindex\")&&(this._tabindex=this.$element.attr(\"tabindex\")),e.attr(\"title\",this.$element.attr(\"title\")),e.attr(\"tabindex\",this._tabindex),e.attr(\"aria-disabled\",\"false\"),this.$selection=e},s.prototype.bind=function(e,t){var n=this,i=e.id+\"-results\";this.container=e,this.$selection.on(\"focus\",function(e){n.trigger(\"focus\",e)}),this.$selection.on(\"blur\",function(e){n._handleBlur(e)}),this.$selection.on(\"keydown\",function(e){n.trigger(\"keypress\",e),e.which===r.SPACE&&e.preventDefault()}),e.on(\"results:focus\",function(e){n.$selection.attr(\"aria-activedescendant\",e.data._resultId)}),e.on(\"selection:update\",function(e){n.update(e.data)}),e.on(\"open\",function(){n.$selection.attr(\"aria-expanded\",\"true\"),n.$selection.attr(\"aria-owns\",i),n._attachCloseHandler(e)}),e.on(\"close\",function(){n.$selection.attr(\"aria-expanded\",\"false\"),n.$selection.removeAttr(\"aria-activedescendant\"),n.$selection.removeAttr(\"aria-owns\"),n.$selection.trigger(\"focus\"),n._detachCloseHandler(e)}),e.on(\"enable\",function(){n.$selection.attr(\"tabindex\",n._tabindex),n.$selection.attr(\"aria-disabled\",\"false\")}),e.on(\"disable\",function(){n.$selection.attr(\"tabindex\",\"-1\"),n.$selection.attr(\"aria-disabled\",\"true\")})},s.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger(\"blur\",e)},1)},s.prototype._attachCloseHandler=function(e){n(document.body).on(\"mousedown.select2.\"+e.id,function(e){var t=n(e.target).closest(\".select2\");n(\".select2.select2-container--open\").each(function(){this!=t[0]&&i.GetData(this,\"element\").select2(\"close\")})})},s.prototype._detachCloseHandler=function(e){n(document.body).off(\"mousedown.select2.\"+e.id)},s.prototype.position=function(e,t){t.find(\".selection\").append(e)},s.prototype.destroy=function(){this._detachCloseHandler(this.container)},s.prototype.update=function(e){throw new Error(\"The `update` method must be defined in child classes.\")},s.prototype.isEnabled=function(){return!this.isDisabled()},s.prototype.isDisabled=function(){return this.options.get(\"disabled\")},s}),e.define(\"select2/selection/single\",[\"jquery\",\"./base\",\"../utils\",\"../keys\"],function(e,t,n,i){function r(){r.__super__.constructor.apply(this,arguments)}return n.Extend(r,t),r.prototype.render=function(){var e=r.__super__.render.call(this);return e[0].classList.add(\"select2-selection--single\"),e.html(''),e},r.prototype.bind=function(t,e){var n=this;r.__super__.bind.apply(this,arguments);var i=t.id+\"-container\";this.$selection.find(\".select2-selection__rendered\").attr(\"id\",i).attr(\"role\",\"textbox\").attr(\"aria-readonly\",\"true\"),this.$selection.attr(\"aria-labelledby\",i),this.$selection.on(\"mousedown\",function(e){1===e.which&&n.trigger(\"toggle\",{originalEvent:e})}),this.$selection.on(\"focus\",function(e){}),this.$selection.on(\"blur\",function(e){}),t.on(\"focus\",function(e){t.isOpen()||n.$selection.trigger(\"focus\")})},r.prototype.clear=function(){var e=this.$selection.find(\".select2-selection__rendered\");e.empty(),e.removeAttr(\"title\")},r.prototype.display=function(e,t){var n=this.options.get(\"templateSelection\");return this.options.get(\"escapeMarkup\")(n(e,t))},r.prototype.selectionContainer=function(){return e(\"\")},r.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(\".select2-selection__rendered\"),i=this.display(t,n);n.empty().append(i);var r=t.title||t.text;r?n.attr(\"title\",r):n.removeAttr(\"title\")}else this.clear()},r}),e.define(\"select2/selection/multiple\",[\"jquery\",\"./base\",\"../utils\"],function(r,e,d){function s(e,t){s.__super__.constructor.apply(this,arguments)}return d.Extend(s,e),s.prototype.render=function(){var e=s.__super__.render.call(this);return e[0].classList.add(\"select2-selection--multiple\"),e.html('
        '),e},s.prototype.bind=function(e,t){var i=this;s.__super__.bind.apply(this,arguments);var n=e.id+\"-container\";this.$selection.find(\".select2-selection__rendered\").attr(\"id\",n),this.$selection.on(\"click\",function(e){i.trigger(\"toggle\",{originalEvent:e})}),this.$selection.on(\"click\",\".select2-selection__choice__remove\",function(e){if(!i.isDisabled()){var t=r(this).parent(),n=d.GetData(t[0],\"data\");i.trigger(\"unselect\",{originalEvent:e,data:n})}}),this.$selection.on(\"keydown\",\".select2-selection__choice__remove\",function(e){i.isDisabled()||e.stopPropagation()})},s.prototype.clear=function(){var e=this.$selection.find(\".select2-selection__rendered\");e.empty(),e.removeAttr(\"title\")},s.prototype.display=function(e,t){var n=this.options.get(\"templateSelection\");return this.options.get(\"escapeMarkup\")(n(e,t))},s.prototype.selectionContainer=function(){return r('
      • ')},s.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=this.$selection.find(\".select2-selection__rendered\").attr(\"id\")+\"-choice-\",i=0;i×');r.attr(\"title\",i()),r.attr(\"aria-label\",i()),r.attr(\"aria-describedby\",n),a.StoreData(r[0],\"data\",t),this.$selection.prepend(r)}},e}),e.define(\"select2/selection/search\",[\"jquery\",\"../utils\",\"../keys\"],function(i,l,c){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=i('');this.$searchContainer=t,this.$search=t.find(\"input\"),this.$search.prop(\"autocomplete\",this.options.get(\"autocomplete\"));var n=e.call(this);return this._transferTabIndex(),n.append(this.$searchContainer),n},e.prototype.bind=function(e,t,n){var i=this,r=t.id+\"-results\",s=t.id+\"-container\";e.call(this,t,n),i.$search.attr(\"aria-describedby\",s),t.on(\"open\",function(){i.$search.attr(\"aria-controls\",r),i.$search.trigger(\"focus\")}),t.on(\"close\",function(){i.$search.val(\"\"),i.resizeSearch(),i.$search.removeAttr(\"aria-controls\"),i.$search.removeAttr(\"aria-activedescendant\"),i.$search.trigger(\"focus\")}),t.on(\"enable\",function(){i.$search.prop(\"disabled\",!1),i._transferTabIndex()}),t.on(\"disable\",function(){i.$search.prop(\"disabled\",!0)}),t.on(\"focus\",function(e){i.$search.trigger(\"focus\")}),t.on(\"results:focus\",function(e){e.data._resultId?i.$search.attr(\"aria-activedescendant\",e.data._resultId):i.$search.removeAttr(\"aria-activedescendant\")}),this.$selection.on(\"focusin\",\".select2-search--inline\",function(e){i.trigger(\"focus\",e)}),this.$selection.on(\"focusout\",\".select2-search--inline\",function(e){i._handleBlur(e)}),this.$selection.on(\"keydown\",\".select2-search--inline\",function(e){if(e.stopPropagation(),i.trigger(\"keypress\",e),i._keyUpPrevented=e.isDefaultPrevented(),e.which===c.BACKSPACE&&\"\"===i.$search.val()){var t=i.$selection.find(\".select2-selection__choice\").last();if(0this.maximumInputLength?this.trigger(\"results:message\",{message:\"inputTooLong\",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define(\"select2/data/maximumSelectionLength\",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get(\"maximumSelectionLength\"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on(\"select\",function(){i._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var i=this;this._checkIfMaximumSelected(function(){e.call(i,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var i=this;this.current(function(e){var t=null!=e?e.length:0;0=i.maximumSelectionLength?i.trigger(\"results:message\",{message:\"maximumSelected\",args:{maximum:i.maximumSelectionLength}}):n&&n()})},e}),e.define(\"select2/dropdown\",[\"jquery\",\"./utils\"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr(\"dir\",this.options.get(\"dir\")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define(\"select2/dropdown/search\",[\"jquery\"],function(s){function e(){}return e.prototype.render=function(e){var t=e.call(this),n=s('');return this.$searchContainer=n,this.$search=n.find(\"input\"),this.$search.prop(\"autocomplete\",this.options.get(\"autocomplete\")),t.prepend(n),t},e.prototype.bind=function(e,t,n){var i=this,r=t.id+\"-results\";e.call(this,t,n),this.$search.on(\"keydown\",function(e){i.trigger(\"keypress\",e),i._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on(\"input\",function(e){s(this).off(\"keyup\")}),this.$search.on(\"keyup input\",function(e){i.handleSearch(e)}),t.on(\"open\",function(){i.$search.attr(\"tabindex\",0),i.$search.attr(\"aria-controls\",r),i.$search.trigger(\"focus\"),window.setTimeout(function(){i.$search.trigger(\"focus\")},0)}),t.on(\"close\",function(){i.$search.attr(\"tabindex\",-1),i.$search.removeAttr(\"aria-controls\"),i.$search.removeAttr(\"aria-activedescendant\"),i.$search.val(\"\"),i.$search.trigger(\"blur\")}),t.on(\"focus\",function(){t.isOpen()||i.$search.trigger(\"focus\")}),t.on(\"results:all\",function(e){null!=e.query.term&&\"\"!==e.query.term||(i.showSearch(e)?i.$searchContainer[0].classList.remove(\"select2-search--hide\"):i.$searchContainer[0].classList.add(\"select2-search--hide\"))}),t.on(\"results:focus\",function(e){e.data._resultId?i.$search.attr(\"aria-activedescendant\",e.data._resultId):i.$search.removeAttr(\"aria-activedescendant\")})},e.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger(\"query\",{term:t})}this._keyUpPrevented=!1},e.prototype.showSearch=function(e,t){return!0},e}),e.define(\"select2/dropdown/hidePlaceholder\",[],function(){function e(e,t,n,i){this.placeholder=this.normalizePlaceholder(n.get(\"placeholder\")),e.call(this,t,n,i)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return\"string\"==typeof t&&(t={id:\"\",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),i=t.length-1;0<=i;i--){var r=t[i];this.placeholder.id===r.id&&n.splice(i,1)}return n},e}),e.define(\"select2/dropdown/infiniteScroll\",[\"jquery\"],function(n){function e(e,t,n,i){this.lastParams={},e.call(this,t,n,i),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on(\"query\",function(e){i.lastParams=e,i.loading=!0}),t.on(\"query:append\",function(e){i.lastParams=e,i.loading=!0}),this.$results.on(\"scroll\",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+50&&this.loadMore()}},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger(\"query:append\",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n('
      • '),t=this.options.get(\"translations\").get(\"loadingMore\");return e.html(t(this.lastParams)),e},e}),e.define(\"select2/dropdown/attachBody\",[\"jquery\",\"../utils\"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get(\"dropdownParent\")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on(\"open\",function(){i._showDropdown(),i._attachPositioningHandler(t),i._bindContainerResultHandlers(t)}),t.on(\"close\",function(){i._hideDropdown(),i._detachPositioningHandler(t)}),this.$dropdownContainer.on(\"mousedown\",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr(\"class\",n.attr(\"class\")),t[0].classList.remove(\"select2\"),t[0].classList.add(\"select2-container--open\"),t.css({position:\"absolute\",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(\"\"),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on(\"results:all\",function(){n._positionDropdown(),n._resizeDropdown()}),t.on(\"results:append\",function(){n._positionDropdown(),n._resizeDropdown()}),t.on(\"results:message\",function(){n._positionDropdown(),n._resizeDropdown()}),t.on(\"select\",function(){n._positionDropdown(),n._resizeDropdown()}),t.on(\"unselect\",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0}},e.prototype._attachPositioningHandler=function(e,t){var n=this,i=\"scroll.select2.\"+t.id,r=\"resize.select2.\"+t.id,s=\"orientationchange.select2.\"+t.id,o=this.$container.parents().filter(a.hasScroll);o.each(function(){a.StoreData(this,\"select2-scroll-position\",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),o.on(i,function(e){var t=a.GetData(this,\"select2-scroll-position\");f(this).scrollTop(t.y)}),f(window).on(i+\" \"+r+\" \"+s,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n=\"scroll.select2.\"+t.id,i=\"resize.select2.\"+t.id,r=\"orientationchange.select2.\"+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+\" \"+i+\" \"+r)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown[0].classList.contains(\"select2-dropdown--above\"),n=this.$dropdown[0].classList.contains(\"select2-dropdown--below\"),i=null,r=this.$container.offset();r.bottom=r.top+this.$container.outerHeight(!1);var s={height:this.$container.outerHeight(!1)};s.top=r.top,s.bottom=r.top+s.height;var o=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ar.bottom+o,d={left:r.left,top:s.bottom},p=this.$dropdownParent;\"static\"===p.css(\"position\")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(i=\"below\"),u||!c||t?!c&&u&&t&&(i=\"below\"):i=\"above\",(\"above\"==i||t&&\"below\"!==i)&&(d.top=s.top-h.top-o),null!=i&&(this.$dropdown[0].classList.remove(\"select2-dropdown--below\"),this.$dropdown[0].classList.remove(\"select2-dropdown--above\"),this.$dropdown[0].classList.add(\"select2-dropdown--\"+i),this.$container[0].classList.remove(\"select2-container--below\"),this.$container[0].classList.remove(\"select2-container--above\"),this.$container[0].classList.add(\"select2-container--\"+i)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+\"px\"};this.options.get(\"dropdownAutoWidth\")&&(e.minWidth=e.width,e.position=\"relative\",e.width=\"auto\"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define(\"select2/dropdown/minimumResultsForSearch\",[],function(){function e(e,t,n,i){this.minimumResultsForSearch=n.get(\"minimumResultsForSearch\"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,i)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,i=0;i');return e.attr(\"dir\",this.options.get(\"dir\")),this.$container=e,this.$container[0].classList.add(\"select2-container--\"+this.options.get(\"theme\")),u.StoreData(e[0],\"element\",this.$element),e},d}),e.define(\"jquery-mousewheel\",[\"jquery\"],function(e){return e}),e.define(\"jquery.select2\",[\"jquery\",\"jquery-mousewheel\",\"./select2/core\",\"./select2/defaults\",\"./select2/utils\"],function(r,e,s,t,o){if(null==r.fn.select2){var a=[\"open\",\"close\",\"destroy\"];r.fn.select2=function(t){if(\"object\"==typeof(t=t||{}))return this.each(function(){var e=r.extend(!0,{},t);new s(r(this),e)}),this;if(\"string\"!=typeof t)throw new Error(\"Invalid arguments for Select2: \"+t);var n,i=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=o.GetData(this,\"select2\");null==e&&window.console&&console.error&&console.error(\"The select2('\"+t+\"') method was called on an element that is not using Select2.\"),n=e[t].apply(e,i)}),-1 1200) {\n $('.campaign-hero__content, .feature-overview-slider').css('padding-left', logo);\n }\n\n if ($('#industry-banner, .hub-banner-copy').length && $(window).width() > 1200) {\n $('.ind-banner-copy, .hub-banner-copy').css('left', logo + 74);\n $('.ind-banner-overlap').css('right', logo);\n }\n\n if ($('.industry-safe-secure').length && $(window).width() > 1200) {\n $('.industry-safe-secure').css('padding-left', logo - 8);\n }\n\n if ($('.wrnty-banner-text').length && $(window).width() > 1200) {\n $('.wrnty-banner-text').css('padding-left', logo + 10);\n }\n\n if ($('.bussiness-security-breadcrumb').length && $(window).width() > 1200) {\n $('.bussiness-security-breadcrumb').css('padding-left', logo + 10);\n }\n }\n }\n\n resizeContent();\n\n $(window).resize(function () {\n resizeContent();\n });\n\n $('body').on('click', '.cookie-warning-messaging button.close', function (e) {\n e.preventDefault();\n window.localStorage.setItem('cookie_accept', true);\n $('.cookie-warning-messaging').hide();\n });\n\n $('body').on('click', '.cookie-link', function (e) {\n e.preventDefault();\n window.localStorage.setItem('cookie_accept', true);\n $('.cookie-warning-messaging').hide();\n window.location.href = $(this).attr('href');\n });\n\n $('body').click(function () {\n setTimeout(function () {\n var statecode = $('#shippingStatedefault').val() || $('#state').val();\n var stateval = $('#shippingStatedefault option[value=' + statecode + ']').html() || $('#state option[value=' + statecode + ']').html();\n $('#select2-shippingStatedefault-container, #select2-state-container').attr('title', stateval);\n $('#select2-shippingStatedefault-container, #select2-state-container').html(stateval);\n }, 500);\n });\n\n new FooterAnimate(); // eslint-disable-line no-new\n\n const ATSPriceTwoline = document.getElementsByClassName('ATS-price-twoLine');\n if (ATSPriceTwoline.length > 0) {\n for (let i = 0; i < ATSPriceTwoline.length; i++) {\n const ATSPriceEle = ATSPriceTwoline[i];\n const PriceText = ATSPriceEle.innerText;\n const splitText = PriceText.replace('mo.', 'mo.\\n');\n ATSPriceEle.innerText = splitText;\n }\n }\n\n window.addEventListener('load', function () {\n if (typeof (OneTrust) !== 'undefined') { // eslint-disable-line no-undef\n OneTrust.OnConsentChanged(function () { // eslint-disable-line\n if (typeof (OnetrustActiveGroups) !== 'undefined' && OnetrustActiveGroups.length) { // eslint-disable-line no-undef\n if ($('.js-account-dashboardpage').length > 0) {\n if ($('.js-account-dashboardpage').val() === 'getConsentDone') {\n return false;\n }\n }\n var selectedCookiPrefs = OnetrustActiveGroups; // eslint-disable-line no-undef\n if (selectedCookiPrefs.length > 0) {\n if (selectedCookiPrefs.charAt(0) === ',') {\n selectedCookiPrefs = selectedCookiPrefs.substring(1);\n }\n if (selectedCookiPrefs.charAt(selectedCookiPrefs.length - 1) === ',') {\n selectedCookiPrefs = selectedCookiPrefs.substring(0, selectedCookiPrefs.length - 1);\n }\n if ($('.js-updatecookieprefs-url').length) {\n var url = $('.js-updatecookieprefs-url').val();\n $.ajax({\n url: url,\n type: 'post',\n data: {\n selectprefs: selectedCookiPrefs\n },\n success: function () {\n // Left blank on intention\n }\n });\n }\n }\n }\n });\n }\n });\n\n window.onscroll = function () {\n if (window.scrollY > 100) {\n $('.custom-select').select2('close');\n }\n };\n\n var $headerBanner = $('.js-header-banner');\n if ($headerBanner.length) {\n var quoteIndex = -1;\n // eslint-disable-next-line require-jsdoc, no-inner-declarations\n function showNextQuote() {\n ++quoteIndex;\n $headerBanner.eq(quoteIndex % $headerBanner.length)\n .fadeIn(1500)\n .delay(5000)\n .fadeOut(1500, showNextQuote);\n }\n showNextQuote();\n }\n});\n\nrequire('base/thirdParty/bootstrap');\nrequire('base/components/spinner');\nrequire('svg4everybody');\nrequire('slick-carousel');\nrequire('gsap');\nrequire('./components/select2');\nrequire('./components/select2-dropdownPosition');\n\n","'use strict';\n\nvar base = require('base/product/base');\nvar slickConfigs = require('../config/slickConfigs');\nvar zoomConfigs = require('lyonscg/config/zoomConfigs');\nvar imagesloaded = require('imagesloaded');\nvar utils = require('lyonscg/util/utils');\nvar productSetVariation = require('./productSetVariation');\nvar colorSelected;\n/**\n * Disable PDP Zoom\n */\nfunction disableZoom() {\n $('.slide-link').trigger('zoom.destroy');\n}\n\n/**\n * Generates html for product attributes section\n *\n * @param {array} attributes - list of attributes\n * @return {string} - Compiled HTML\n */\nfunction getAttributesHtml(attributes) {\n if (!attributes) {\n return '';\n }\n\n var html = '';\n\n attributes.forEach(function (attributeGroup) {\n if (attributeGroup.ID === 'mainAttributes') {\n attributeGroup.attributes.forEach(function (attribute) {\n html += '
        ' + attribute.label + ': '\n + attribute.value + '
        ';\n });\n }\n });\n\n return html;\n}\n\n/**\n * Generates html for promotions section\n *\n * @param {array} promotions - list of promotions\n * @return {string} - Compiled HTML\n */\nfunction getPromotionsHtml(promotions) {\n if (!promotions) {\n return '';\n }\n\n var html = '';\n\n promotions.forEach(function (promotion) {\n html += '
        ' + promotion.calloutMsg +\n '
        ';\n });\n\n return html;\n}\n\n\n/**\n * Updates the availability status in the Product Detail Page\n *\n * @param {Object} response - Ajax response object after an\n * attribute value has been [de]selected\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nfunction updateAvailability(response, $productContainer) {\n var availabilityValue = '';\n var availabilityMessages = response.product.availability\n ? response.product.availability.messages : [];\n if (!response.product.readyToOrder) {\n availabilityValue = '
        ' + response.resources.info_selectforstock + '
        ';\n } else {\n availabilityMessages.forEach(function (message) {\n availabilityValue += '
        ' + message + '
        ';\n });\n }\n\n $($productContainer).trigger('product:updateAvailability', {\n product: response.product,\n $productContainer: $productContainer,\n message: availabilityValue,\n resources: response.resources\n });\n}\n\n/**\n * Process attribute values associated with an attribute that does not have image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction processNonSwatchValues(attr, $productContainer) {\n var $attr = '[data-attr=\"' + attr.id + '\"]';\n var $defaultOption = $productContainer.find($attr + ' .select-' + attr.id);\n for (var i = 0, j = $defaultOption.length; i < j; i++) {\n $($defaultOption)[i].options[0].value = attr.resetUrl;\n }\n var colorName = colorSelected;\n var price = null;\n attr.values.forEach(function (attrValue) {\n var $attrValue = $productContainer\n .find($attr + ' [data-attr-value=\"' + attrValue.value + '\"]');\n $attrValue.attr('value', attrValue.url)\n .removeAttr('disabled');\n\n if (!attrValue.selectable) {\n $attrValue.attr('disabled', true);\n }\n });\n\n var $allCardWrappers = $('.product-overview__bundle-columns');\n\n var $cardWrapper = $allCardWrappers.filter(function () {\n return $(this).data('attr-id') === attr.attributeId;\n });\n\n var url = '';\n var value = '';\n var selected;\n var selectable;\n var title;\n var list;\n var atrIndex = 0; // eslint-disable-line no-unused-vars\n $cardWrapper.html('');\n attr.values.forEach(function (attrValue) {\n url = attrValue.url;\n value = attrValue.value;\n selected = attrValue.selected;\n title = attrValue.displayValue;\n selectable = attrValue.selectable;\n for (var a = 0, b = attr.variants.length; a < b; a++) {\n if (colorName === attr.variants[a].color && (value === attr.variants[a].size || value === attr.variants[a].videoQuality)) {\n price = attr.variants[a].price;\n }\n }\n if (price && price.list) {\n list = price.list.formatted;\n } else {\n list = null;\n }\n var $card = `\n
        \n
        \n ${title}\n
        \n
        `;\n if (list === null) {\n $card = `\n
        \n
        \n ${title}\n
        \n
        `;\n }\n if (selectable === true) {\n $cardWrapper.append($card);\n }\n atrIndex++;\n });\n\n var $cards = $cardWrapper.find('.product-overview__bundle-card');\n\n $cards.on('click', (event) => {\n event.preventDefault();\n $(this).removeClass('active');\n const targetNode = event.currentTarget;\n var textContent = targetNode.children[0].dataset.value;\n targetNode.classList.add('active');\n $('.product-overview__attributes .custom-select-pdp option[value=\"' + textContent + '\"]').prop('selected', true);\n var $selectionEl = $cardWrapper.parent().siblings('.product-overview__attributes .custom-select-pdp');\n $selectionEl.trigger('change');\n });\n}\n\n/**\n * Process the attribute values for an attribute that has image swatches\n *\n * @param {Object} attr - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {Object[]} attr.values - Array of attribute value objects\n * @param {string} attr.values.value - Attribute coded value\n * @param {string} attr.values.url - URL to de/select an attribute value of the product\n * @param {boolean} attr.values.isSelectable - Flag as to whether an attribute value can be\n * selected. If there is no variant that corresponds to a specific combination of attribute\n * values, an attribute may be disabled in the Product Detail Page\n * @param {jQuery} $productContainer - DOM container for a given product\n */\nfunction processSwatchValues(attr, $productContainer) {\n attr.values.forEach(function (attrValue) {\n var $attrValue = $productContainer.find('[data-attr=\"' + attr.id + '\"] [data-attr-value=\"' +\n attrValue.value + '\"]');\n var $swatchAnchor = $attrValue.parent().not('.plp-swatch');\n\n if (attrValue.selected) {\n $attrValue.addClass('selected');\n colorSelected = attrValue.value;\n } else {\n $attrValue.removeClass('selected');\n }\n\n if (attrValue.url) {\n $swatchAnchor.attr('data-href', attrValue.url);\n } else {\n $swatchAnchor.removeAttr('data-href');\n }\n\n // Disable if not selectable\n $attrValue.removeClass('selectable unselectable');\n\n $attrValue.addClass(attrValue.selectable ? 'selectable' : 'unselectable');\n });\n}\n\n/**\n * Routes the handling of attribute processing depending on whether the attribute has image\n * swatches or not\n *\n * @param {Object} attrs - Attribute\n * @param {string} attr.id - Attribute ID\n * @param {jQuery} $productContainer - DOM element for a given product\n */\nfunction updateAttrs(attrs, $productContainer) {\n // Currently, the only attribute type that has image swatches is Color.\n var attrsWithSwatches = ['color'];\n\n attrs.forEach(function (attr) {\n if (attrsWithSwatches.indexOf(attr.id) > -1) {\n processSwatchValues(attr, $productContainer);\n } else {\n processNonSwatchValues(attr, $productContainer);\n }\n });\n}\n\n/**\n * Parses JSON from Ajax call made whenever an attribute value is [de]selected\n * @param {Object} response - response from Ajax call\n * @param {Object} response.product - Product object\n * @param {string} response.product.id - Product ID\n * @param {Object[]} response.product.variationAttributes - Product attributes\n * @param {Object[]} response.product.images - Product images\n * @param {boolean} response.product.hasRequiredAttrsSelected - Flag as to whether all required\n * attributes have been selected. Used partially to\n * determine whether the Add to Cart button can be enabled\n * @param {jQuery} $productContainer - DOM element for a given product.\n */\nfunction handleVariantResponse(response, $productContainer) {\n var isChoiceOfBonusProducts =\n $productContainer.parents('.choose-bonus-product-dialog').length > 0;\n var isVariant;\n if (response.product.variationAttributes) {\n updateAttrs(response.product.variationAttributes, $productContainer);\n isVariant = response.product.productType === 'variant';\n if (isChoiceOfBonusProducts && isVariant) {\n $productContainer.parent('.bonus-product-item')\n .data('pid', response.product.id);\n\n $productContainer.parent('.bonus-product-item')\n .data('ready-to-order', response.product.readyToOrder);\n } else {\n $productContainer.attr('data-pid', response.product.id);\n }\n }\n\n // Update primary images\n var primaryImageUrls = response.product.images;\n primaryImageUrls.pdp.forEach(function (imageUrl, idx) {\n $productContainer.find('.primary-images').find('img').eq(idx)\n .attr('src', imageUrl.url);\n });\n\n // Update pricing if not a set, for set there is a different script\n if (response.product.productType !== 'set') {\n if (!isChoiceOfBonusProducts) {\n var $priceSelector = $('.prices .price', $productContainer).length\n ? $('.prices .price', $productContainer)\n : $('.prices .price');\n $priceSelector.replaceWith(response.product.price.html);\n }\n }\n\n // Update promotions\n $('.promotions').empty().html(getPromotionsHtml(response.product.promotions));\n\n updateAvailability(response, $productContainer);\n\n if (isChoiceOfBonusProducts) {\n var $selectButton = $productContainer.find('.select-bonus-product');\n $selectButton.trigger('bonusproduct:updateSelectButton', {\n product: response.product, $productContainer: $productContainer\n });\n } else {\n // Enable \"Add to Cart\" button if all required attributes have been selected\n $('button.add-to-cart, button.add-to-cart-global, button.update-cart-product-global').trigger('product:updateAddToCart', {\n product: response.product, $productContainer: $productContainer\n }).trigger('product:statusUpdate', response.product);\n }\n\n // Update attributes\n $productContainer.find('.main-attributes').empty()\n .html(getAttributesHtml(response.product.attributes));\n}\n\n/**\n * Init PDP Zoom\n */\nfunction initZoom() {\n disableZoom();\n\n var isDesktop = utils.mediaBreakpointUp('lg');\n var $activeSlide = $('.product-carousel .slick-active');\n var $image = $activeSlide.find('.slide-link.zoom-hires');\n var url = $image.attr('href');\n\n if ($image.length > 0 && url && url !== 'null' && isDesktop) {\n // Start spinner while zoom image loads\n $activeSlide.spinner().start();\n\n var config = {\n url: url,\n callback: function () {\n // Stop spinner when zoom image loaded\n $activeSlide.spinner().stop();\n }\n };\n config = $.extend({}, zoomConfigs, config);\n\n $image.zoom(config);\n }\n}\n\n/**\n * Init the product carousel using a predefined slick configuration\n */\nfunction carouselInit() {\n var $carousel = $('.product-carousel');\n\n if ($carousel.length) {\n imagesloaded($carousel).on('done', function () {\n if ($carousel.hasClass('slick-initialized')) {\n $carousel.off('init', initZoom);\n $carousel.off('afterChange', initZoom);\n }\n $carousel.on('init', initZoom);\n $carousel.on('afterChange', initZoom);\n $carousel.not('.slick-initialized').slick(slickConfigs.pdp);\n });\n }\n}\n\n/**\n * Init the price spider\n */\nfunction initPricespider() {\n window.onload = function () {\n if (typeof window.PriceSpider !== 'undefined' && typeof window.PriceSpider.rebind === 'function') {\n window.PriceSpider.rebind();\n }\n };\n}\n\n/**\n * Deconstruct (unslick) the carousel, removing classes and handlers added on slick initialize.\n */\nfunction carouselUnslick() {\n var $carousel = $('.product-carousel');\n\n if ($carousel.length && $carousel.hasClass('slick-initialized')) {\n $carousel.off('init', initZoom);\n $carousel.off('afterChange', initZoom);\n $carousel.slick('unslick');\n }\n}\n\n/**\n * Init the product carousel using a predefined slick configuration for bonus item\n */\nfunction carouselInitBonus() {\n var $carouselBonus = $('.bonus-product-item');\n if ($carouselBonus.length) {\n $carouselBonus.each(function () {\n var $carouselBonusDiv = $(this).find('.product-carousel');\n if ($carouselBonusDiv.length) {\n imagesloaded($carouselBonusDiv).on('done', function () {\n $carouselBonusDiv.on('init', initZoom);\n $carouselBonusDiv.on('afterChange', initZoom);\n $carouselBonusDiv.not('.slick-initialized').slick(slickConfigs.pdp);\n });\n }\n });\n }\n}\n\n/**\n * Deconstruct (unslick) the carousel, removing classes and handlers added on slick initialize.\n */\nfunction carouselUnslickBonus() {\n var $carouselBonus = $('.bonus-product-item');\n if ($carouselBonus.length) {\n $carouselBonus.each(function () {\n var $carouselBonusDiv = $(this).find('.product-carousel');\n if ($carouselBonusDiv.length && $carouselBonusDiv.hasClass('slick-initialized')) {\n $carouselBonusDiv.off('init', initZoom);\n $carouselBonusDiv.off('afterChange', initZoom);\n $carouselBonusDiv.slick('unslick');\n }\n });\n }\n}\n/**\n * @param {json} product - Product json\n * @param {boolean} plp - is plp tile\n * @returns {string} htmlString - carousel slides\n */\nfunction updateMainImages(product, plp) {\n var images = product.images;\n var htmlString = '';\n var video = '';\n\n if (plp) {\n var htmlSlider = '' +\n '' +\n '' +\n '' +\n ' 1 ? 'tile-image-original' : ' ') + '\"' +\n 'src=\"' + (product.selectedProductUrl || images.large[0].url) + '\" class=\"slide-img\" alt=\"' + images.large[0].alt + '\" title=\"' + images.large[0].title + '\" data-media itemprop=\"image\"/>';\n\n htmlString += htmlSlider;\n } else {\n if (product.cdnVideo !== null && (product.productType === 'master' || product.productType === 'variant')) {\n video = '';\n htmlString += video;\n }\n images.pdp.forEach(function (image, idx) {\n var htmlSlide = '';\n htmlString += htmlSlide;\n });\n images.carouselLifestyle.forEach(function (image, idx) {\n var htmlSlide = '';\n htmlString += htmlSlide;\n });\n } /* else {\n if (product.cdnVideo !== null && (product.productType === 'master' || product.productType === 'variant')) {\n video = '';\n htmlString += video;\n }\n images.pdp.forEach(function (image, idx) {\n var htmlSlide = '';\n htmlString += htmlSlide;\n });\n } */\n return htmlString;\n}\n\n/**\n * @param {json} product - Product json\n * @returns {string} htmlString - carousel slides\n */\nfunction updateThumbnailImages(product) {\n var images = product.images;\n var htmlString = '';\n images.carouselVideoThumbnail.forEach(function (image) {\n var htmlSlide = '';\n htmlString += htmlSlide;\n });\n images.carouselThumbnail.forEach(function (image) {\n var htmlSlide = '';\n htmlString += htmlSlide;\n });\n images.carouselLifestyleThumbnail.forEach(function (image) {\n var htmlSlide = '';\n htmlString += htmlSlide;\n });\n return htmlString;\n}\n\n/**\n*@param {Object} response - response from Ajax call\n*@param {jQuery} $productContainer - DOM element for a given product.\n */\nfunction updateBundlePrice(response, $productContainer) {\n var $priceSelector = $('.product-bundle .prices .price', $productContainer).length\n ? $('.product-bundle .prices .price', $productContainer)\n : $('.product-bundle .prices .price');\n $priceSelector.replaceWith(response.product.price.html);\n}\n\n/**\n * Updates the full price of a product set on PLP when a color swatch is selected\n *\n * @param {jQuery} $priceEl - The price element to update\n * @param {string} price - The price text to set\n * @param {boolean} discount - Whether the price has a discount\n * @param {string} productType - The type of a product on a tile\n * @returns {void}\n */\nfunction updatePlpFullPrice($priceEl, price, discount, productType) {\n var $fullPriceContainer = productType === 'set'\n ? $priceEl.find('.js-set-price-plp_full')\n : $priceEl.find('.js-product-price-plp_full');\n\n if ($fullPriceContainer.length > 1) {\n $fullPriceContainer.eq(1).detach();\n $fullPriceContainer = $($fullPriceContainer[0]);\n }\n\n if (discount) {\n $fullPriceContainer.addClass('strike-through list');\n } else {\n $fullPriceContainer.removeClass('strike-through list');\n }\n\n if (productType === 'set') {\n $fullPriceContainer.contents().last().replaceWith(price);\n } else {\n $fullPriceContainer.contents().eq(1).replaceWith(price);\n }\n}\n\n/**\n * Updates the discount price of a product set on PLP when a color swatch is selected\n *\n * @param {jQuery} $priceEl - The price element to update\n * @param {string} priceTxt - The price text to set\n * @param {string|null} promo - The promo discount price\n * @param {string} productType - The type of a product on a tile\n * @returns {void}\n */\nfunction updatePlpDiscountPrice($priceEl, priceTxt, promo, productType) {\n var $salePrice = $priceEl.find('.js-set-price-sales__plp-wrapper_sales-price');\n var $outerSpanSalePrice = $('').addClass(`${promo ? 'starting strike-through list price-mid-val' : 'sales red-color'} js-set-price-sales__plp-wrapper_sales-price`);\n var $innerSpanSalePrice = $('')\n .addClass('value large-text')\n .attr('itemprop', 'price')\n .attr('content', priceTxt)\n .text(priceTxt);\n\n var $innerSpanPromoPrice = $('')\n .addClass('value large-text')\n .attr('itemprop', 'price')\n .attr('content', promo)\n .text(promo);\n\n var $fullPriceEl = productType === 'set'\n ? $priceEl.find('.js-set-price-plp_full')\n : $priceEl.find('.js-product-price-plp_full');\n\n $salePrice.remove();\n $outerSpanSalePrice.append($innerSpanSalePrice);\n $outerSpanSalePrice.insertAfter($fullPriceEl);\n\n if (promo) {\n $priceEl.find('.js-set-price-sales__plp-wrapper_promo-discount').remove();\n\n var $promoOuterSpan = $('').addClass('sales white-color bold700 js-set-price-sales__plp-wrapper_promo-discount');\n\n $promoOuterSpan.append($innerSpanPromoPrice);\n $promoOuterSpan.insertAfter($outerSpanSalePrice);\n }\n}\n\n/**\n * Re-renders the save amount percent text\n *\n * @param {jQuery} $priceEl - The price DOM container\n * @param {string} saveAmount - The text of the save amount percent\n */\nfunction updateDiscountPercent($priceEl, saveAmount) {\n var $saveAmountEl = $priceEl.find('.js-save-amount');\n\n if ($saveAmountEl.length) {\n $saveAmountEl.removeClass('d-none');\n $saveAmountEl.text(saveAmount);\n } else {\n var $newSaveAmount = $('', {\n class: 'js-save-amount red-color text-danger value large-text',\n text: saveAmount\n });\n\n $priceEl.append($newSaveAmount);\n }\n}\n\n/**\n* @param {Object} response - response from Ajax call\n* @param {jQuery|null} $hitColorElOnPlp - DOM element of a color swatch on PLP or null if the method is executed not on PLP\n */\nfunction updatePrice(response, $hitColorElOnPlp) {\n if (!$hitColorElOnPlp) {\n return;\n }\n\n var $priceEl = $hitColorElOnPlp.closest('.js-product-category__list-item').find('.js-set-price-plp');\n var productType = response.product.productType;\n var fullPriceTxt;\n var discountPriceTxt;\n var promoDiscountPriceTxt;\n var saveAmount;\n\n if (productType === 'set') {\n fullPriceTxt = response.product.price.availableProductsSetPrice.formattedFull;\n discountPriceTxt = response.product.price.availableProductsSetPrice.formattedDisc;\n promoDiscountPriceTxt = response.product.price.availableProductsSetPrice.formattedPromoDisc;\n saveAmount = response.product.price.availableProductsSetPrice.formattedSavePercent;\n } else {\n fullPriceTxt = response.product.price.list && response.product.price.list.formatted;\n discountPriceTxt = response.product.price.sales && response.product.price.sales.formatted;\n promoDiscountPriceTxt = response.product.price.promo && response.product.price.promo.formatted;\n saveAmount = response.product.price.productDiscountPercentage;\n }\n\n if (fullPriceTxt && discountPriceTxt && promoDiscountPriceTxt) {\n updatePlpFullPrice($priceEl, fullPriceTxt, true, productType);\n updatePlpDiscountPrice($priceEl, discountPriceTxt, promoDiscountPriceTxt, productType);\n } else if ((fullPriceTxt && discountPriceTxt) || (discountPriceTxt && promoDiscountPriceTxt)) {\n var higherPrice = fullPriceTxt || discountPriceTxt;\n var lowerPrice = promoDiscountPriceTxt || discountPriceTxt;\n\n updatePlpFullPrice($priceEl, higherPrice, true, productType);\n updatePlpDiscountPrice($priceEl, lowerPrice, null, productType);\n $priceEl.find('.js-set-price-sales__plp-wrapper_promo-discount').remove();\n } else if (fullPriceTxt || discountPriceTxt) {\n var price = fullPriceTxt || discountPriceTxt;\n\n updatePlpFullPrice($priceEl, price, false, productType);\n $priceEl.find('.js-set-price-sales__plp-wrapper_sales-price').remove();\n $priceEl.find('.js-set-price-sales__plp-wrapper_promo-discount').remove();\n }\n\n if (saveAmount) {\n updateDiscountPercent($priceEl, saveAmount);\n } else {\n $priceEl.find('.js-save-amount').remove();\n }\n}\n\n/**\n * updates the product view when a product attribute is selected or deselected or when\n * changing quantity\n * @param {string} selectedValueUrl - the Url for the selected variation value\n * @param {jQuery} $productContainer - DOM element for current product\n * @param {jQuery} $hitColorEl - The hit color swatch element\n */\nfunction attributeSelect(selectedValueUrl, $productContainer, $hitColorEl) {\n if (selectedValueUrl) {\n $('body').trigger('product:beforeAttributeSelect',\n { url: selectedValueUrl, container: $productContainer });\n\n $.ajax({\n url: selectedValueUrl,\n method: 'GET',\n success: function (data) {\n if (\n ($productContainer.hasClass('product-grid') && $productContainer.find('.product-category__list-item').length) ||\n $productContainer.hasClass('slick-slide')\n ) {\n var updateMainImagesHTML = updateMainImages(data.product, true);\n\n var pid = data.product.masterProductID || data.product.id;\n var listItem = $hitColorEl.closest('.product-category__list-item[id=\"' + pid + '\"]');\n\n if (listItem && listItem.length) {\n var title = data.product.displayName || data.product.productName;\n var subtitle = data.product.productHeadingDescStr || data.product.shortDescription;\n var navUrl = data.product.productNavigationUrl || data.product.selectedProductUrl;\n\n listItem.find('picture').empty().html(updateMainImagesHTML);\n listItem.find('.image-container a.plp-main-image').attr('href', navUrl);\n listItem.find('.product-category__cta-section a').attr('href', navUrl);\n listItem.find('.js-search-tile-product-name h4').attr('title', title).text(title).addClass('product-heading-title');\n listItem.find('.js-plp-tile__item-attributes_text').html(subtitle).addClass('product-heading-description');\n }\n\n listItem.find('.variant-section .variant-border').removeClass('light');\n let selectedColor = data.product.selectedColor || '';\n\n if (data.product.variationAttributes) {\n let colorObject = data.product.variationAttributes.filter((variationAttribute) => {\n return variationAttribute.attributeId === 'color';\n });\n\n if (colorObject.length) {\n let color = colorObject[0].values.filter((value) => {\n return value.selected;\n });\n if (color.length) {\n selectedColor = color[0].id;\n }\n }\n }\n\n listItem.find('.variant-section .' + selectedColor).addClass('light');\n\n var productId = data.product.masterProduct ? data.product.masterProductID : data.product.id;\n listItem.attr('id', productId);\n\n updatePrice(data, $hitColorEl);\n\n return;\n }\n\n updatePrice(data, $productContainer);\n handleVariantResponse(data, $productContainer);\n\n base.updateOptions(data.product.options, $productContainer);\n base.updateQuantities(data.product.quantities, $productContainer);\n\n if ($('.select-attr.custom-select').children('option:first-child').is(':selected')) {\n $('.cart-and-ipay').hide();\n } else {\n $('.cart-and-ipay').show();\n }\n\n if ($('.js-affirm-pdp-promo').length > 0) {\n if (data.product.availability.isPreorder === true || data.product.availability.isBackorder === true) {\n if ($('.js-affirm-pdp-preorder-filter').length > 0 && $('.js-affirm-pdp-preorder-filter').val() === 'true') {\n $('.js-affirm-pdp-promo').addClass('d-none');\n } else {\n $('.js-affirm-pdp-promo').removeClass('d-none');\n }\n } else {\n $('.js-affirm-pdp-promo').removeClass('d-none');\n $('.js-pdp-affirmprice').removeClass('d-none');\n }\n\n if (!data.product.isAffirmThresholdReached) {\n $('.js-affirm-pdp-promo').addClass('d-none');\n } else if (data.product.isAffirmThresholdReached) {\n $('.js-affirm-pdp-promo').removeClass('d-none');\n $('.js-pdp-affirmprice').removeClass('d-none');\n }\n var affirmSubtotal = 0;\n if (data.product) {\n affirmSubtotal = 0;\n if (data.product.price && data.product.price.sales) {\n affirmSubtotal = data.product.price.sales.value;\n }\n }\n if ($('.js-pdp-affirmprice').length > 0) {\n $('.js-pdp-affirmprice').attr('data-amount', affirmSubtotal * 100);\n }\n if (typeof affirm !== 'undefined') { // eslint-disable-line\n affirm.ui.ready(function() { // eslint-disable-line\n affirm.ui.refresh(); // eslint-disable-line\n });\n }\n }\n\n if (data.product.hideCTAAndAffirm === false) {\n $('.product-nav__right').removeClass('hide-cta-and-affirm');\n $('.js-pdp-a2c-buttons .cart-and-ipay').removeClass('hide-cta-and-affirm');\n } else if (data.product.hideCTAAndAffirm === true) {\n $('.product-nav__right').addClass('hide-cta-and-affirm');\n $('.js-pdp-a2c-buttons .cart-and-ipay').addClass('hide-cta-and-affirm');\n }\n $('body').trigger('product:afterAttributeSelect',\n { data: data, container: $productContainer });\n $.spinner().stop();\n // Change price spider skus after variant select in non-ecom websites\n if ($('button.add-to-cart, button.add-to-cart-global, button.update-cart-product-global').length === 0) {\n $('.price-spider').each(function () {\n if (data.product.hideFindARetailer !== null && !data.product.hideFindARetailer) {\n $(this).replaceWith('
        Find A Retailer
        ');\n $('.price-spider').html('');\n $('.price-spider').removeClass('ps-nsosellers');\n $('.price-spider').removeClass('d-none');\n $('.price-spider').removeClass('disable').addClass('ps-widget');\n $('.price-spider').attr('ps-sku', data.product.id);\n if (window.PriceSpider) {\n window.PriceSpider.rebind();\n }\n } else {\n $(this).replaceWith('
        Find A Retailer
        ');\n }\n });\n }\n // Update non-ecom retailers when available\n if ($('.js-non-ecom-retailerbody').length > 0) {\n if (data.product.nonecomretailers !== null) {\n $('.js-non-ecom-retailerbody .modal-body .row').html(decodeURIComponent(data.product.nonecomretailers));\n }\n }\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n}\n\n/**\n * Function to get variant specific up-sell recommendations\n * @param {string} productID ID of the product added to cart\n */\nfunction generateUpsellData(productID) {\n var recommURL = $('.flyout-cart__recommendation').data('url') + productID;\n $('.flyout-cart__modal').spinner().start();\n $('.flyout-cart__recommendation').empty();\n $('.flyout-cart__recommendation').load(recommURL, function () {\n var config = {\n centerMode: false,\n variableWidth: true,\n infinite: false,\n draggable: true,\n arrows: true,\n dots: false,\n slidesToScroll: 1,\n slidesToShow: 4.1,\n rows: 0,\n responsive: [\n {\n breakpoint: 1181,\n settings: {\n slidesToShow: 2,\n arrows: false,\n dots: true\n }\n },\n {\n breakpoint: 415,\n settings: {\n slidesToShow: 2,\n arrows: false,\n dots: true\n }\n }\n ]\n };\n var theme = $(this).data('slick-slider-theme') === 'light' ? 'light' : 'dark';\n $(this).addClass(theme);\n if ($('.flyout-cart__recommendation-slider').length > 0) {\n $('.no-rec').each(function () {\n $(this).removeClass('no-rec');\n });\n $('.flyout-cart__recommendation-slider').not('.slick-initialized').slick(config);\n }\n $.spinner().stop();\n $('#flyout-cart').addClass('modal--opened');\n });\n}\n\nvar exportBase = $.extend({}, base, {\n carouselInit: carouselInit,\n carouselInitBonus: carouselInitBonus,\n carouselUnslick: carouselUnslick,\n carouselUnslickBonus: carouselUnslickBonus,\n updateMainImages: updateMainImages,\n updateThumbnailImages: updateThumbnailImages,\n processNonSwatchValues: processNonSwatchValues,\n selectAttribute: function () {\n $(document).on('change', 'select[class*=\"select-\"], .options-select', function (e) {\n e.preventDefault();\n\n var $productContainer = $(this).closest('.set-item');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.product-detail');\n }\n if ($(this).attr('id') || $(this).attr('id') === 'sel-sort' || $(this).attr('id') === 'selector-1' || $(this).attr('id') === 'selector-2' || $(this).attr('id') === 'selector-3') {\n // Do nothing\n } else {\n attributeSelect(e.currentTarget.value, $productContainer);\n }\n });\n $(document).ready(function () {\n initPricespider();\n });\n },\n colorAttribute: function () {\n $(document).on('click', '[data-attr=\"color\"] a', function (e) {\n e.preventDefault();\n\n var $hitColorEl = $(this);\n\n if ($hitColorEl.attr('disabled')) {\n return;\n }\n\n if ($hitColorEl.hasClass('js-color-attribute__product-set')) {\n var itemData = $hitColorEl.parent().data('obj');\n var id = itemData.id;\n var url = $hitColorEl.closest('.js-variant-section').data('url-product-show');\n\n productSetVariation.methods.renderVariantsOnPdp(id, url);\n productSetVariation.methods.updateColorSwatch($hitColorEl);\n productSetVariation.methods.updateBasketInformation($hitColorEl);\n productSetVariation.methods.updateProductNames($hitColorEl.data('display-names'));\n\n return;\n }\n\n var $productContainer = $hitColorEl.closest('.set-item');\n\n if (!$productContainer.length) {\n $productContainer = $hitColorEl.closest('.slick-slide');\n }\n\n if (!$productContainer.length) {\n $productContainer = $hitColorEl.closest('.product-category__list');\n }\n\n if (!$productContainer.length) {\n $productContainer = $hitColorEl.closest('.product-detail');\n }\n\n attributeSelect($hitColorEl.attr('data-href'), $productContainer, $hitColorEl);\n });\n },\n availability: function () {\n $(document).on('change', '.quantity-select', function (e) {\n e.preventDefault();\n var $productContainer = $(this).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.modal-content').find('.product-quickview');\n }\n if ($('.bundle-items', $productContainer).length !== 0) {\n $.ajax({\n url: $(e.currentTarget).find('option:selected').data('url'),\n method: 'GET',\n success: function (data) {\n updateBundlePrice(data, $productContainer);\n $.spinner.stop();\n },\n error: function () {\n $.spinner.stop();\n }\n });\n } else {\n attributeSelect($(e.currentTarget).find('option:selected').data('url'),\n $productContainer);\n }\n });\n },\n addToCart: function () {\n $(document).on('click', 'button.add-to-cart, button.add-to-cart-global', function () {\n var addToCartUrl;\n var pid;\n var pidsObj;\n var setPids;\n var that = this;\n\n $('body').trigger('product:beforeAddToCart', this);\n\n if ($('.js-product-set-detail').data('is-product-set') && $(this).hasClass('add-to-cart-global')) {\n setPids = [];\n\n $('.js-set-item').each(function () {\n var $productCont = $(this);\n if (!$productCont.hasClass('product-set-detail') && $productCont.data('available')) {\n setPids.push({\n pid: $productCont.data('pid'),\n qty: $productCont.data('qty') || 1,\n options: base.getOptions($productCont)\n });\n }\n });\n\n pidsObj = JSON.stringify(setPids);\n pid = $(this).data('pid');\n } else {\n pid = base.getPidValue($(this));\n }\n\n var $productContainer = $(this).closest('.product-detail');\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.quick-view-dialog').find('.product-detail');\n }\n var subsriptionProductID = $productContainer.find('input[name=\"subscriptionProduct\"]:checked').val();\n\n addToCartUrl = $('.add-to-cart-url').val();\n\n var form = {\n pid: pid,\n pidsObj: pidsObj,\n childProducts: base.getChildProducts(),\n quantity: base.getQuantitySelected($(this)),\n subsriptionProductID: subsriptionProductID\n };\n\n if (!$('.bundle-item').length) {\n form.options = base.getOptions($productContainer);\n }\n\n $(this).trigger('updateAddToCartFormData', form);\n /* replacement fields from response */\n var topName = '';\n var bottomName = '';\n var kitName = '';\n var imageURL = '';\n var imageAlt = '';\n var pricing = '';\n var itemQty = '';\n var subTotal = '';\n var avail = '';\n if (addToCartUrl) {\n $.ajax({\n url: addToCartUrl,\n method: 'POST',\n data: form,\n success: function (data) {\n $(that).blur();\n if (typeof _etmc !== 'undefined'){ // eslint-disable-line\n var cart = {};\n cart = data.cart.trackCartDatalayer;\n _etmc.trackCart([{cart}]); // eslint-disable-line\n }\n\n var isProductSet = data.productAdded.isProductSet;\n\n // base.handlePostCartAdd(data);\n $('.minicart').trigger('count:update', data);\n var messageType = data.error ? 'alert-danger' : 'alert-success';\n // show add to cart toast\n if (data.newBonusDiscountLineItem\n && Object.keys(data.newBonusDiscountLineItem).length !== 0) {\n base.methods.editBonusProducts(data.newBonusDiscountLineItem);\n } else {\n var hasUpsell = document.querySelector('.flyout-cart__recommendation');\n\n if (($('.add-to-cart-messages').length === 0 && !hasUpsell) || isProductSet) {\n $('body').append(\n '
        '\n );\n }\n\n if (!!data.atsBundleRemoved && data.atsBundleRemoved === true) {\n $('.js-ats-bundle-removed').removeClass('d-none');\n $('.js-ats-bundle-removed').addClass('d-block');\n $('#atsRemovedModal').modal('show');\n } else {\n $('.add-to-cart-messages').append(\n '
        '\n + data.message\n + '
        '\n );\n setTimeout(function () {\n $('.add-to-basket-alert').remove();\n }, 5000);\n }\n var productID = data.productAdded.pid;\n if (!data.error) {\n if (!isProductSet && $('#flyout-cart').length && hasUpsell) {\n $('body').addClass('no-scroll');\n generateUpsellData(productID);\n }\n for (var i = 0, j = data.cart.items.length; i < j; i++) {\n if (data.cart.items[i].id === productID) {\n var productAdded = data.cart.items[i];\n avail = (productAdded.availability.isPreorder || productAdded.availability.isBackorder) ? productAdded.availability.inStockDate : '';\n topName = productAdded.topLine !== null ? productAdded.topLine : productAdded.productName;\n bottomName = productAdded.bottomLine !== null ? productAdded.bottomLine : '';\n if (productAdded.variationAttributes !== null) {\n kitName = (typeof productAdded.variationAttributes[1] !== 'undefined') ? productAdded.variationAttributes[1].displayValue : '';\n if (productAdded.variationAttributes[0] !== null) {\n if (typeof productAdded.variationAttributes[1] !== 'undefined') {\n kitName += ' - ';\n }\n kitName += (typeof productAdded.variationAttributes[0] !== 'undefined') ? productAdded.variationAttributes[0].displayValue : '';\n }\n }\n imageURL = productAdded.images.pdpLrgDesktop[0].url;\n imageAlt = productAdded.images.pdpLrgDesktop[0].alt;\n if (productAdded.price.list) {\n var discountPrice = productAdded.price.sales.formatted;\n pricing = productAdded.price.list.formatted;\n $('.flyout-cart__product-price del').show();\n $('.flyout-cart__product-price del>span.list').addClass('strike-through');\n $('.flyout-cart__product-price del').css('text-decoration', 'line-through');\n $('.flyout-cart__product-price .value').html(pricing);\n $('.reg-flyout-price').html(discountPrice);\n } else {\n pricing = productAdded.price.sales.formatted;\n $('.flyout-cart__product-price del>span.list').removeClass('strike-through');\n $('.flyout-cart__product-price del').css('text-decoration', 'none');\n $('.flyout-cart__product-price .list').html(pricing);\n $('.reg-flyout-price').html('');\n }\n pricing = productAdded.price.sales.formatted;\n itemQty = data.quantityTotal;\n subTotal = data.cart.totals.grandTotal;\n if (avail !== '') {\n $('.flyout-cart__product-shipping').show();\n $('.ships-on-date').html(avail);\n } else {\n $('.flyout-cart__product-shipping').hide();\n }\n $('.flyout-cart__product-name').html(topName);\n $('.flyout-cart__product-attributes').html(bottomName);\n $('.flyout-cart__product-addon').html(kitName);\n $('.flyout-cart__product-image').attr('src', imageURL);\n $('.flyout-cart__product-image').attr('alt', imageAlt);\n $('.qty-flyout-total').html(itemQty);\n $('.subtotal-flyout').html(subTotal);\n if (data.atsBundleRemoved === true) {\n $('.minicart_wrap').removeClass('express-checkout');\n $('.js-ats-bundle-removed').removeClass('d-none');\n $('.js-ats-bundle-removed').addClass('d-block');\n }\n }\n }\n } else {\n if ($('.add-to-cart-messages').length === 0) {\n $('body').append(\n '
        '\n );\n } else {\n $('.add-to-cart-messages').html('');\n }\n $('.add-to-cart-messages').append(\n '
        '\n + data.message\n + '
        '\n );\n }\n }\n $('.minicart_wrap').children().remove();\n $('body').trigger('product:afterAddToCart', data);\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n });\n }\n});\n\nmodule.exports = exportBase;\n","'use strict';\n/* global PriceSpider */\nvar detailBase = require('base/product/detail');\nvar formValidation = require('base/components/formValidation');\nvar orgBase = require('org/product/base');\n\n/**\n * Selects the variation buttons elements on the storefront\n *\n * @param {string} variationId - The ID of the variation which buttons should be selected\n * @param {boolean} active - Whether the button should be active\n * @returns {jQuery|undefined} The jQuery object wrapping the DOM elements of the button\n */\nfunction selectVariationBtn(variationId, active) {\n var $variationBtns;\n\n if (active) {\n $variationBtns = $('.product-overview__bundle-card.active');\n } else {\n $variationBtns = $('.product-overview__bundle-card');\n }\n\n if (!variationId) {\n return $variationBtns;\n }\n\n var $specificVariationBtns = [];\n\n $variationBtns.each(function () {\n var $btn = $(this);\n\n if ($btn.parent().data('attr-id') === variationId) {\n $specificVariationBtns.push($btn);\n }\n });\n\n return $specificVariationBtns;\n}\n\ndetailBase.availability = orgBase.availability;\n\ndetailBase.addToCart = orgBase.addToCart;\n\ndetailBase.showSpinner = function () {\n $('body').on('product:beforeAddToCart product:beforeAttributeSelect', function () {\n // $.spinner().start(); removing spinner per Arlo team\n });\n};\n\ndetailBase.updateAddToCart = function () {\n $('body').on('product:updateAddToCart', function (e, response) {\n var enableAddToCart = response.product.readyToOrder && response.product.available;\n\n // update local add to cart (for sets)\n $('button.add-to-cart', response.$productContainer).attr('disabled', !enableAddToCart);\n $('button.add-to-cart', response.$productContainer).attr('data-pid', response.product.id);\n $('button#btn-open-notify', response.$productContainer).attr('data-pid', response.product.id);\n\n // update display for back in stock based on availability\n $('.cart-and-ipay', response.$productContainer).toggleClass('d-none', !enableAddToCart);\n $('.back-in-stock-btn', response.$productContainer).toggleClass('d-none', enableAddToCart || response.product.productType === 'master' || response.product.productType === 'bundle');\n\n // update gtm with new product data\n $('button.add-to-cart').attr('data-gtmdata', response.product.gtmDataObj);\n $('button#btn-open-notify').attr('data-gtmdata', response.product.gtmDataObj);\n\n var enable = $('.product-availability').toArray().every(function (item) {\n return $(item).data('available') && $(item).data('ready-to-order');\n });\n $('button.add-to-cart-global').attr('disabled', !enable);\n // price spider button\n $('.price-spider').each(function () {\n if (response.product.hideFindARetailer !== null && !response.product.hideFindARetailer) {\n $(this).replaceWith('
        Find A Retailer
        ');\n $('.pdp-cta-actions').addClass('d-none');\n $('.price-spider').html('');\n $('.price-spider').removeClass('ps-nsosellers');\n $('.price-spider').removeClass('d-none');\n $('.price-spider').removeClass('disable').addClass('ps-widget');\n $('.price-spider').attr('ps-sku', response.product.id);\n if (typeof window.PriceSpider !== 'undefined' && typeof window.PriceSpider.rebind === 'function') {\n PriceSpider.rebind();\n }\n } else {\n $('.pdp-cta-actions').removeClass('d-none');\n $(this).replaceWith('
        Find A Retailer
        ');\n }\n });\n if (!enableAddToCart) {\n $('.price-spider').addClass('notifyme');\n }\n });\n};\n\ndetailBase.updateAvailability = function () {\n $('body').on('product:updateAvailability', function (e, response) {\n $('div.availability', response.$productContainer)\n .data('ready-to-order', response.product.readyToOrder)\n .data('available', response.product.available);\n\n $('.availability-msg', response.$productContainer)\n .empty().html(response.message);\n if (response.product.availability && response.product.availability.messages.length > 1) {\n $('.availability-msg').parents('.availability-messages').addClass('w-100');\n } else {\n $('.availability-msg').parents('.availability-messages').removeClass('w-100');\n }\n if ($('.global-availability').length) {\n var allAvailable = $('.product-availability').toArray()\n .every(function (item) {\n return $(item).data('available');\n });\n\n var allReady = $('.product-availability').toArray()\n .every(function (item) {\n return $(item).data('ready-to-order');\n });\n\n $('.global-availability')\n .data('ready-to-order', allReady)\n .data('available', allAvailable);\n\n $('.global-availability .availability-msg').empty()\n .html(allReady ? response.message : response.resources.info_selectforstock);\n }\n });\n};\n\ndetailBase.toggleOne = function () {\n $('body').on('click', '.product-bundle-detail .bundle-item .description , .product-bundle-detail .bundle-item .details', function () {\n if ($(this).siblings().hasClass('active')) {\n $(this).siblings().removeClass('active');\n }\n });\n};\n\ndetailBase.backInStock = function () {\n $('body').on('submit', '.back-in-stock-form', function (e) {\n e.preventDefault();\n var form = $(this);\n var url = form.attr('action');\n form.spinner().start();\n $.ajax({\n url: url,\n type: 'post',\n dataType: 'json',\n data: form.serialize(),\n success: function (data) {\n form.spinner().stop();\n if (!data.success) {\n formValidation(form, data);\n } else {\n $('.back-in-stock-body').empty().append('

        ' + data.receivedMsgBody + '

        ');\n $('.send-email-btn').empty();\n }\n },\n error: function () {\n form.spinner().stop();\n }\n });\n return false;\n });\n};\n\ndetailBase.updateProduct = function () {\n $('body').on('product:afterAttributeSelect', function (e, response) {\n // If colors are unselected reset dropdown\n var isColorSelected = false;\n var isSizeSelected = false;\n var witbHTML = '';\n var optionalColor = $('input[name$=\"variationColorName\"]').val();\n var colorExist = $('input[name$=\"colorExist\"]').val();\n // eslint-disable-next-line\n var $techspecsList = $('.product-overview__features-list');\n\n if (optionalColor) {\n if (colorExist) {\n for (var xx = 0, yx = response.data.product.variationAttributes[0].values.length; xx < yx; xx++) {\n if (response.data.product.variationAttributes[0].values[xx].selected) {\n isColorSelected = true;\n }\n }\n if (response.data.product.variationAttributes.length > 1) {\n for (var ix = 0, jx = response.data.product.variationAttributes[1].values.length; ix < jx; ix++) {\n if (response.data.product.variationAttributes[1].values[ix].selected) {\n isSizeSelected = true;\n }\n }\n }\n\n if (!isColorSelected) {\n $('.custom-select-pdp').children('option:first-child').prop('selected', true);\n $('.custom-select-pdp').trigger('change.select2');\n $('.custom-select-pdp').attr('disabled', true);\n }\n\n if (isColorSelected && !isSizeSelected) {\n // Select the first kit\n var $variationBtnsSize = selectVariationBtn('size', false);\n var $variationBtnSizeActive = selectVariationBtn('size', true);\n\n if ($variationBtnsSize.length > 0 && $variationBtnSizeActive.length <= 0) {\n $('.product-overview__bundle-card').eq(0).trigger('click');\n }\n }\n } else {\n for (var a = 0, b = response.data.product.variationAttributes[0].values.length; a < b; a++) {\n if (response.data.product.variationAttributes[0].values[a].selected) {\n isSizeSelected = true;\n }\n }\n if (!isSizeSelected) {\n $('.custom-select-pdp').children('option:first-child').prop('selected', true);\n $('.custom-select-pdp').trigger('change.select2');\n }\n }\n } else {\n for (var x = 0, y = response.data.product.variationAttributes[0].values.length; x < y; x++) {\n if (response.data.product.variationAttributes[0].values[x].selected) {\n isColorSelected = true;\n }\n }\n if (response.data.product.variationAttributes.length > 1) {\n for (var i = 0, j = response.data.product.variationAttributes[1].values.length; i < j; i++) {\n if (response.data.product.variationAttributes[1].values[i].selected) {\n isSizeSelected = true;\n }\n }\n }\n\n if (!isColorSelected) {\n $('.custom-select-pdp').children('option:first-child').prop('selected', true);\n $('.custom-select-pdp').trigger('change.select2');\n $('.custom-select-pdp').attr('disabled', true);\n }\n if (isColorSelected && !isSizeSelected) {\n $('.custom-select-pdp').children('option:first-child').prop('selected', true);\n $('.custom-select-pdp').trigger('change.select2');\n }\n }\n\n // Update product name\n var stickyHeaderName = response.data.product.topLine || response.data.product.displayName || response.data.product.productName;\n\n response.container.find('.product-name').html(response.data.product.displayName ? response.data.product.displayName : response.data.product.productName);\n response.container.find('.product-nav__product-name h5').html(stickyHeaderName);\n response.container.find('.product-overview__product-name h1').html(response.data.product.topName ? response.data.product.topName : response.data.product.displayName);\n response.container.find('.product-overview__product-name .product-type').html(response.data.product.bottomName ? response.data.product.bottomName : '');\n response.container.find('.product-overview__description').html(response.data.product.shortDescription);\n $('.product-overview__gallery-slides').slick('unslick');\n $('.product-overview__gallery-thumbnail').slick('unslick');\n $('.product-overview__gallery-slides').empty();\n $('.product-overview__gallery-thumbnail').empty();\n $('.product-overview__gallery-slides').html(orgBase.updateMainImages(response.data.product));\n $('.product-overview__gallery-thumbnail').html(orgBase.updateThumbnailImages(response.data.product));\n var thumbnailSlidesToShow = $('.product-overview__gallery-slide.thumbnail-slide').length;\n $('.product-overview__gallery-thumbnail').slick({\n asNavFor: '[data-product-media-slider]',\n centerMode: false,\n slidesToShow: thumbnailSlidesToShow,\n infinite: true,\n vertical: true,\n draggable: false,\n arrows: false,\n dots: false,\n focusOnSelect: true,\n slidesToScroll: 1,\n rows: 0\n });\n $('.product-overview__gallery-slides').slick({\n asNavFor: '[data-product-thumbnail-slider]',\n centerMode: false,\n variableWidth: false,\n infinite: true,\n draggable: false,\n arrows: true,\n dots: true,\n slidesToScroll: 1,\n slidesToShow: 1,\n rows: 0,\n responsive: [\n {\n breakpoint: 480,\n settings: {\n arrows: false,\n dots: true\n }\n }\n ]\n });\n\n // change tech specs\n var techSpecsCount = response.data.product.techspecs.length;\n var $techSpecsString = '';\n var counter = 0;\n var techspec;\n var q;\n var w;\n // eslint-disable-next-line\n $techspecsList.html('');\n for (q = 0, w = response.data.product.techspecs.length; q < w; q++) {\n techspec = response.data.product.techspecs[q];\n if (q % 4 === 0) {\n if (counter === 0) {\n counter++;\n }\n $techSpecsString += '
          ';\n }\n $techSpecsString += '
        • ' + techspec + '
        • ';\n if (counter % 4 === 0 || counter === techSpecsCount) {\n $techSpecsString += '
        ';\n }\n counter++;\n }\n // eslint-disable-next-line\n $techspecsList.html($techSpecsString);\n // response.container.find('.product-overview__features-list').html($techspecsList);\n // end change tech specs\n // Update back in stock HTML\n if (!response.data.product.available && response.data.product.backinstockbtn && response.data.product.backinstockmodal) {\n response.container.find('.back-in-stock-btn').html(response.data.product.backinstockbtn);\n response.container.find('.back-in-stock-modal').html(response.data.product.backinstockmodal);\n }\n // eslint-disable-next-line\n var headerSelectKitBtn = $('#master_select_kit_btn');\n // eslint-disable-next-line\n if (headerSelectKitBtn && response.data.product.variationAttributes != null) {\n if (response.data.product.readyToOrder) {\n // eslint-disable-next-line\n $(headerSelectKitBtn).hide();\n } else {\n // eslint-disable-next-line\n $(headerSelectKitBtn).show();\n }\n }\n\n // add whats in the box\n $.ajax({\n url: response.container.find('#whats-in-the-box').attr('data-url') + '?pid=' + response.data.product.id,\n type: 'get',\n success: function (data) {\n witbHTML = data;\n },\n error: function () {\n witbHTML = response.container.find('#whats-in-the-box').html();\n },\n complete: function () {\n response.container.find('#whats-in-the-box').html(witbHTML);\n }\n });\n\n // end whats in the box\n\n $('#prdID').html(response.data.product.id ? 'Item No. ' + response.data.product.id : '');\n });\n};\n\ndetailBase.updateAttributesAndDetails = function () {\n $('body').on('product:statusUpdate', function (e, data) {\n var messages = '';\n var $productContainer = $('.product-detail[data-pid=\"' + data.id + '\"]');\n\n $productContainer.find('.description-and-detail .product-attributes')\n .empty()\n .html(data.attributesHtml);\n\n if (data.shortDescription) {\n $productContainer.find('.description-and-detail .description')\n .removeClass('hidden-xl-down');\n $productContainer.find('.description-and-detail .description .content')\n .empty()\n .html(data.shortDescription);\n } else {\n $productContainer.find('.description-and-detail .description')\n .addClass('hidden-xl-down');\n }\n\n if (data.longDescription) {\n $productContainer.find('.description-and-detail .details')\n .removeClass('hidden-xl-down');\n $productContainer.find('.description-and-detail .details .content')\n .empty()\n .html(data.longDescription);\n } else {\n $productContainer.find('.description-and-detail .details')\n .addClass('hidden-xl-down');\n }\n\n if (data.availability) {\n $('.add-to-cart span').html(data.availability.buttonlabel);\n }\n\n $('.preorder-backorder-date').empty();\n if (data.availability) {\n if (data.availability.messages && data.availability.inStockDate) {\n data.availability.messages.forEach(function (message) {\n messages += '' + message + '';\n });\n }\n }\n\n if (data.price.productDiscountPercentage) {\n $('.js-save-amount').removeClass('d-none');\n $('.js-save-amount').html(data.price.productDiscountPercentage);\n } else {\n $('.js-save-amount').addClass('d-none');\n }\n $('.preorder-backorder-date').html(messages);\n });\n};\n\ndetailBase.updateVideoonPDP = function () {\n $(document).on('click', '.js-trigger-video-modal', function (e) {\n e.preventDefault();\n $('body').addClass('modal-static');\n $('body').addClass('noscroll');\n var iframe = $(this).parent('.product-overview__gallery-slide').find('.iFrame-text').val();\n $('.video-modal-content').append(iframe);\n $('.close-video-modal').removeClass('d-none');\n $('.overlay').addClass('modal-open');\n var id = $(this).attr('data-youtube-id');\n var youTubeAttrs = '?rel=0&mute=1&autoplay=1';\n var src = '//www.youtube.com/embed/' + id + youTubeAttrs;\n $('.video-modal-content').find('.youtube').attr('src', src);\n });\n\n $('body').on('click', '.close-video-modal, .modal-static', function (e) {\n e.preventDefault();\n $('body').removeClass('noscroll');\n $('body').removeClass('modal-static');\n $('.video-modal-content').html('');\n $('.overlay').removeClass('modal-open');\n $('.close-video-modal').addClass('d-none');\n });\n $('body').keyup(function (e) {\n if (e.keyCode === 27) {\n $('body').removeClass('noscroll');\n $('body').removeClass('modal-static');\n $('.video-modal-content').html('');\n $('.overlay').removeClass('modal-open');\n $('.close-video-modal').addClass('d-none');\n }\n });\n};\n\ndetailBase.selectAttributeSync = function () {\n $(document).on('change', 'select[class*=\"select-\"]', function () {\n var selectedOption = $(this).find(':selected').data('attr-value');\n var selectedColor = $('.color-value.swatch-circle.selected').data('attr-value');\n var otherSelect = $('select[class*=\"select-\"]').not($(this)).not('.quantity-select').find('option[data-attr-value=\"' + selectedOption + '\"]')\n .parent();\n $(otherSelect).find(':selected').prop('selected', false);\n $(otherSelect).find('option[data-attr-value=\"' + selectedOption + '\"]').prop('selected', true);\n $(otherSelect).trigger('change.select2');\n if ($(this).children('option:first-child').is(':selected') && $('.color-value.swatch-circle').hasClass('selected')) {\n $('.custom-select-variation, .custom-select-dropdown-bluegray, .custom-select-pdp').removeAttr('disabled');\n } else {\n $('.color-value.swatch-circle').removeClass('selected');\n $('.color-value.swatch-circle[data-attr-value=' + selectedColor + ']').addClass('selected');\n }\n });\n};\n\ndetailBase.selectDropdownInit = function () {\n $('.custom-select-pdp').select2({\n dropdownCssClass: 'bluegray',\n minimumResultsForSearch: -1\n });\n $('.custom-select-variation').select2({\n dropdownCssClass: 'select-dropdown-pdp',\n minimumResultsForSearch: -1\n });\n var colorExist = $('input[name$=\"colorExist\"]').val();\n if (colorExist) {\n if (!$('.custom-select-pdp').children('option:first-child').is(':selected') || $('.color-value.swatch-circle').hasClass('selected')) {\n $('.custom-select-variation, .custom-select-dropdown-bluegray, .custom-select-pdp').removeAttr('disabled');\n } else {\n $('.custom-select-variation, .custom-select-dropdown-bluegray, .custom-select-pdp').attr('disabled', true);\n }\n } else {\n $('.custom-select-variation, .custom-select-dropdown-bluegray, .custom-select-pdp').removeAttr('disabled');\n }\n};\n\ndetailBase.toolTipEvent = function () {\n var menu = $('.dropdown-menu-area');\n if ($(window).width() < 1199) {\n $(document).on('click', '.dropdown-opener', function () {\n if (menu) {\n $(menu).toggleClass('show');\n }\n if ($(menu).hasClass('show')) {\n $('section.product-overview').css('overflow', 'visible');\n } else {\n $('section.product-overview').css('overflow', 'hidden');\n }\n });\n } else {\n $(document).on('mouseenter', '.dropdown-opener', function () {\n if (menu) {\n $(menu).show();\n }\n });\n $(document).on('mouseleave', '.dropdown-tooltip', function () {\n if (menu) {\n $(menu).hide();\n }\n });\n }\n};\n\n// show Banner Icon Play when DOM is loaded\ndetailBase.showBannerIconPlay = function () {\n $('.video-banner-icon-play').show();\n};\n\n// show attributes when DOM is loaded\ndetailBase.showAttributes = function () {\n $('.product-overview__attributes').show();\n detailBase.selectDropdownInit();\n};\n\ndetailBase.showCarousel = function () {\n if ($('body').find('video#pdp-featured-video').length > 0) {\n $('video#pdp-featured-video').on('canplay', function () {\n $('.product-overview__gallery').css('visibility', 'visible');\n });\n } else {\n $('.product-overview__gallery').css('visibility', 'visible');\n }\n};\n\ndetailBase.customEvents = function () {\n $(document).on('click', '.js-customize-cta', function (e) {\n e.preventDefault();\n window.location.href = $(this).attr('href');\n });\n};\n\ndetailBase.includedProdyct = function () {\n $(document).on('click', '.js-bundle-list-btn', function () {\n var hiddenProducts = $('.product-overview__set-item:nth-child(n+4)');\n hiddenProducts.addClass('show');\n $(this).addClass('d-none');\n $('.js-hide-list-btn').removeClass('d-none');\n });\n\n $(document).on('click', '.js-hide-list-btn', function () {\n var hiddenProducts = $('.product-overview__set-item.show');\n hiddenProducts.removeClass('show');\n $(this).addClass('d-none');\n $('.js-bundle-list-btn').removeClass('d-none');\n });\n};\n\ndetailBase.sliceText = function () {\n const $container = $('.js-read-more-container');\n const $text = $container.find('.js-has-read-more-button');\n\n if (!$text.length) {\n return;\n }\n\n const shortTextLength = +($text.data('short-text-length')) || 25;\n const $readMoreBtn = $container.find('.js-read-more-btn');\n const $readLessBtn = $container.find('.js-read-less-btn');\n\n const fullText = $text.html().trim();\n\n const fullTextWordLength = fullText.split(' ').length;\n\n /**\n * Returns a shortened version of the text with HTML markup.\n *\n * @function getShortenedText\n * @param {string} text - The full text content (including HTML markup).\n * @param {number} maxLength - The maximum number of words to show in the short text before truncation.\n * @returns {string} The shortened version of the text with HTML markup.\n */\n function getShortenedText(text, maxLength) {\n const words = text.split(' ');\n if (words.length > maxLength) {\n return words.slice(0, maxLength).join(' ') + '...';\n }\n return text;\n }\n\n const shortText = getShortenedText(fullText, shortTextLength);\n\n if (fullTextWordLength) {\n $container.removeClass('hide-content');\n }\n\n if (fullTextWordLength > shortTextLength) {\n $text.html(shortText);\n $readMoreBtn.removeClass('d-none');\n }\n\n $(document).on('click', '.js-read-more-btn', function () {\n $text.html(fullText).addClass('active');\n $(this).addClass('d-none');\n $readLessBtn.removeClass('d-none');\n });\n\n $(document).on('click', '.js-read-less-btn', function () {\n $text.html(shortText).removeClass('active');\n $(this).addClass('d-none');\n $readMoreBtn.removeClass('d-none');\n });\n};\n\nmodule.exports = $.extend(detailBase, exports);\n","'use strict';\n\n/**\n * @namespace productSetVariation\n * @memberof org_arlo\n * Manages the change of a product variant by color on PDP for a product set\n */\n\nvar updateDom = require('../search/search').updateDom;\n\nmodule.exports = {\n methods: {\n /**\n * Updates the appearance of the color swatches when selected\n *\n * @param {jQuery} $element - The selected swatch element\n * @returns {void}\n */\n updateColorSwatch: function ($element) {\n var productId = $element.find('span').data('color-swatch-product-id');\n var $allSwatches = $('span[data-color-swatch-product-id]');\n\n $allSwatches.each(function () {\n var $swatch = $(this);\n\n if ($swatch.data('color-swatch-product-id') === productId) {\n $swatch.addClass('selected');\n } else {\n $swatch.removeClass('selected');\n }\n });\n },\n /**\n * Rerenders a product set on PDP if a color variant is selected\n *\n * @param {string} pid The id of a product.\n * @param {string} url The url to call to receive the rendering template\n * @returns {void}\n */\n renderVariantsOnPdp: function (pid, url) {\n var $productDetails = $('.js-no-gutters');\n\n $productDetails.spinner().start();\n $.ajax({\n url: url,\n method: 'GET',\n data: {\n pid: pid,\n rerenderSetVariant: true\n },\n success: function (data) {\n var sliceText = require('./detail').sliceText;\n var slickConfigs = require('../config/slickConfigs');\n var $results = $(data);\n\n [\n '.js-product-id',\n '.product-overview__gallery-slides',\n '.js-affirm-message-container',\n '.js-individual-products__wrapper',\n '.js-product-overview__description',\n '.js-product-overview__prices',\n '.js-product-set-total-wrap',\n '.js-cart-and-ipay',\n '.js-promo-message',\n '.js-product-recommendations',\n '.js-product-faq',\n '.js-disclaimers'\n ].forEach(function (selector) {\n updateDom($results, selector);\n });\n\n sliceText();\n $('.product-tile-caro').not('.slick-initialized').slick(slickConfigs.productTiles);\n $('.js-product-nav').find('.js-save-amount-text').addClass('d-none');\n\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n },\n /**\n * Updates the information for of the add-to-cart button\n *\n * @param {jQuery} $element - The selected swatch element\n * @returns {void}\n */\n updateBasketInformation: function ($element) {\n var productId = $element.parent().data('obj').id;\n $('.js-btn__add-to-cart-global_bundle-pdp').attr('data-pid', productId);\n },\n /**\n * Updates the displayed product names\n *\n * @param {Object} data - the object containing names for different parts of the page\n * @returns {void}\n */\n updateProductNames: function (data) {\n $('.js-product-main-name').text(data.mainName);\n $('.js-product-sticky-bar-name').text(data.stickyBarName);\n }\n }\n};\n","'use strict';\n\n/**\n * Update DOM elements with Ajax results\n *\n * @param {Object} $results - jQuery DOM element\n * @param {string} selector - DOM element to look up in the $results\n * @param {string} selectorClasses - Pass throguh classes to update the selector\n * @return {undefined}\n */\nfunction updateDom($results, selector, selectorClasses) {\n if ($results) {\n var $updates = $results.find(selector);\n $(selector).empty().html($updates.html());\n }\n\n if (selectorClasses != null) {\n $(selector).attr('class', selectorClasses);\n }\n}\n\n/**\n * Parse query string\n *\n * @param {string} query - permalink\n * @return {Object} - return object with page size\n */\nfunction parseQueryString(query) {\n var vars = query.split('&');\n var queryString = {};\n for (var i = 0; i < vars.length; i++) {\n var pair = vars[i].split('=');\n var key = decodeURIComponent(pair[0]);\n var value = decodeURIComponent(pair[1]);\n\n if (typeof queryString[key] === 'undefined') {\n queryString[key] = decodeURIComponent(value);\n } else if (typeof queryString[key] === 'string') {\n var arr = [queryString[key], decodeURIComponent(value)];\n queryString[key] = arr;\n } else {\n queryString[key].push(decodeURIComponent(value));\n }\n }\n return queryString;\n}\n\n/**\n * Keep refinement panes expanded/collapsed after Ajax refresh\n *\n * @param {Object} $results - jQuery DOM element\n * @return {undefined}\n */\nfunction handleRefinements($results) {\n $('.refinement.active').each(function () {\n $(this).removeClass('active');\n\n $results\n .find('.' + $(this)[0].className.replace(/ /g, '.'))\n .addClass('active');\n });\n\n updateDom($results, '.refinements');\n}\n\n/**\n * Check classes on .grid-header\n *\n * @param {Object} $results - jQuery DOM element\n * @return {undefined}\n */\nfunction handleGridHeader($results) {\n updateDom($results, '.grid-header', $results.find('.grid-header').attr('class'));\n}\n\n/**\n * Parse Ajax results and updated select DOM elements\n *\n * @param {string} response - Ajax response HTML code\n * @return {undefined}\n */\nfunction parseResults(response) {\n var $results = $(response);\n var specialHandlers = {\n '.refinements': handleRefinements,\n '.grid-header': handleGridHeader\n };\n\n // Update DOM elements that do not require special handling\n [\n '.cat-top-container',\n '.header-bar',\n '.header.page-title',\n '.product-grid',\n '.show-more',\n '.filter-bar',\n '.nav-result-count',\n '.js-category-pills'\n ].forEach(function (selector) {\n updateDom($results, selector);\n });\n\n Object.keys(specialHandlers).forEach(function (selector) {\n specialHandlers[selector]($results);\n });\n}\n\n/**\n * This function retrieves another page of content to display in the content search grid\n * @param {JQuery} $element - the jquery element that has the click event attached\n * @param {JQuery} $target - the jquery element that will receive the response\n * @return {undefined}\n */\nfunction getContent($element, $target) {\n var showMoreUrl = $element.data('url');\n $.spinner().start();\n $.ajax({\n url: showMoreUrl,\n method: 'GET',\n success: function (response) {\n $target.append(response);\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n}\n\n/**\n * Update sort option URLs from Ajax response\n *\n * @param {string} response - Ajax response HTML code\n * @return {undefined}\n */\nfunction updateSortOptions(response) {\n var $tempDom = $('
        ').append($(response));\n var sortOptions = $tempDom.find('.grid-footer').data('sort-options').options;\n sortOptions.forEach(function (option) {\n $('option.' + option.id).val(option.url);\n });\n}\n\n/**\n * Update current and canonical URL\n *\n * @param {string} response - Ajax response HTML code\n * @return {undefined}\n */\nfunction updateUrls(response) {\n var $permaLinkUrls = $('.permalink', response);\n\n if ($permaLinkUrls.length > 0) {\n $permaLinkUrls.each(function () {\n var $permaLinkUrl = $(this);\n var permalink = $permaLinkUrl.val();\n\n var parsedUrl = parseQueryString(permalink);\n\n if (!$.isEmptyObject(parsedUrl)) {\n $(\"link[rel^='canonical']\", $permaLinkUrl.closest('head')).attr('href', permalink);\n history.pushState(null, null, permalink);\n }\n });\n }\n}\n\n/**\n * Toggle Filter Bar\n *\n */\nfunction toggleFilterBar() {\n var $parent = $('.js-search-results');\n var $btn = $('.js-nav-cta');\n var $refinementBar = $parent.find('.js-refinement-filter');\n var $refinementFilterResult = $('.b-refinement-filter__result');\n\n $btn.toggleClass('b-nav-cta--active');\n $refinementBar.toggleClass('b-refinement-filter--active');\n\n if ($(window).width() < 975) {\n $('body').toggleClass('no-body-scroll');\n } else if ($btn.hasClass('b-nav-cta--scrollable') && $btn.hasClass('b-nav-cta--active') && $refinementFilterResult.length > 0) {\n var offsetTop = $refinementFilterResult.offset().top;\n var scrollTopPosition = offsetTop - 160;\n\n $('html, body').animate({\n scrollTop: scrollTopPosition\n }, 500);\n }\n}\n\n\n/**\n * Hide Filter Bar\n *\n */\nfunction hideFilterBar() {\n var $parent = $('.js-search-results');\n var $btn = $('.js-nav-cta');\n var $refinementBar = $parent.find('.js-refinement-filter');\n\n $btn.removeClass('b-nav-cta--active');\n $refinementBar.removeClass('b-refinement-filter--active');\n $('body').removeClass('no-body-scroll');\n}\n\nmodule.exports = {\n filter: function () {\n // Display refinements bar when Filter button clicked\n $('.container').on('click', 'button.js-filter-results', toggleFilterBar);\n if ($(window).width() > 975) {\n toggleFilterBar();\n }\n },\n\n scroll: function () {\n var ScrollMagic = require('scrollmagic');\n\n if (ScrollMagic) {\n var headerHeight = $('header').height();\n var controller = new ScrollMagic.Controller();\n\n new ScrollMagic.Scene({\n triggerElement: '.js-refinement-filter',\n triggerHook: 0,\n offset: -headerHeight,\n reverse: true\n }).setClassToggle('.js-nav-cta', 'b-nav-cta--scrollable').addTo(controller);\n }\n },\n\n readMore: function () {\n var readMore = 'Read More';\n var readLess = 'Read Less';\n\n $(document).on('click', '.js-read-more-btn', function () {\n var isCollapsed = $(this).data('is-collapsed');\n var $wrapper = $('.js-read-more-wrapper');\n var $container = $('.js-read-more-container');\n $wrapper.toggleClass('category-hero__text--collapsed');\n $wrapper.height(!isCollapsed ? $container.outerHeight() + 5 : 40);\n $(this).html(isCollapsed ? readMore : readLess);\n $(this).data('is-collapsed', !isCollapsed);\n });\n\n $(document).on('click', '.js-read-more-arrow', function () {\n var container = $(this).closest('.js-read-more-container');\n container.toggleClass('hide-content');\n });\n },\n\n closeRefinments: function () {\n // Refinements close button\n $('.container').on('click', '.refinement-bar button.close', hideFilterBar);\n },\n\n resize: function () {\n // Close refinement bar and hide modal background if user resizes browser\n $(window).resize(hideFilterBar);\n },\n\n sort: function () {\n // Handle sort order menu selection\n $('.container').on('change click', '[name=sort-order], .js-sort-order-option', function (e) {\n e.preventDefault();\n\n var url = this.value;\n var $preservedPageSizeEl = $('.js-saved-page-size');\n var preservedPageSize = $preservedPageSizeEl.length && $preservedPageSizeEl.text().trim();\n $preservedPageSizeEl.remove();\n var originalPageSize;\n\n if (preservedPageSize) {\n var szParam = url.match(/sz=(\\d+)/) ? url.match(/sz=(\\d+)/)[0] : '';\n originalPageSize = szParam && szParam.match(/\\d+/) ? szParam.match(/\\d+/)[0] : null;\n url = url.replace(/(sz=)\\d+/, `$1${preservedPageSize}`);\n }\n\n $.spinner().start();\n $(this).trigger('search:sort', this.value);\n var $prevSelected = $('.js-sort-order-option[selected=\"selected\"]');\n $prevSelected.removeAttr('selected');\n $prevSelected.children('.checkmark').addClass('d-none');\n $(this).attr('selected', 'selected');\n $(this).children('.checkmark').removeClass('d-none');\n $.ajax({\n url: url,\n data: {\n selectedUrl: this.value,\n originalSz: originalPageSize\n },\n method: 'GET',\n success: function (response) {\n $('.product-grid').empty().html(response);\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n });\n },\n\n showMore: function () {\n // Show more products\n $('.container').on('click', '.show-more button', function (e) {\n e.stopPropagation();\n var showMoreUrl = $(this).data('url');\n\n e.preventDefault();\n\n $.spinner().start();\n $(this).trigger('search:showMore', e);\n $.ajax({\n url: showMoreUrl,\n data: { selectedUrl: showMoreUrl },\n method: 'GET',\n success: function (response) {\n $('.grid-footer').replaceWith(response);\n updateSortOptions(response);\n updateUrls(response);\n $.spinner().stop();\n },\n error: function () {\n $.spinner().stop();\n }\n });\n });\n },\n\n applyFilter: function () {\n // Handle refinement value selection and reset click\n $('.container').on(\n 'click',\n '.refinements li button:not(\".js-sort-order-option\"), .refinement-bar a.reset, .filter-value a, .swatch-filter a, .js-category-pill',\n function (e) {\n e.preventDefault();\n e.stopPropagation();\n\n $.spinner().start();\n $(this).trigger('search:filter', e);\n var url = $(this).data('href');\n $.ajax({\n url: url,\n data: {\n page: $('.grid-footer').data('page-number'),\n selectedUrl: e.currentTarget.href\n },\n method: 'GET',\n success: function (response) {\n parseResults(response);\n var headerHeight = $('header').height();\n var contententBlock = $('.js-refinement-filter');\n $(window).scrollTop(contententBlock.offset().top - headerHeight);\n $.spinner().stop();\n $('body .custom-select-dropdown').select2({\n minimumResultsForSearch: -1,\n dropdownPosition: 'below',\n width: 'resolve'\n });\n if ($('.refinements').children().length < 1) {\n $('.reset').click();\n }\n window.history.pushState({}, '', url);\n },\n error: function () {\n $.spinner().stop();\n }\n });\n }\n );\n },\n\n showContentTab: function () {\n // Display content results from the search\n $('body').on('click', '.content-search', function () {\n $(this).addClass('active');\n $('#content-search-results-pane').addClass('active');\n $('.product-search').removeClass('active');\n $('#product-search-results').removeClass('active');\n if ($('#content-search-results').html() === '') {\n getContent($(this), $('#content-search-results'));\n }\n $('#content-search-results').show();\n });\n\n // Display the next page of content results from the search\n $('.container').on('click', '.show-more-content button', function () {\n getContent($(this), $('#content-search-results .result-count'));\n $('.show-more-content').remove();\n });\n },\n\n showProductTab: function () {\n // Display content results from the search\n $('.container').on('click', '.product-search', function () {\n $(this).addClass('active');\n $('.content-search').removeClass('active');\n $('#content-search-results-pane').removeClass('active');\n $('#content-search-results').hide();\n $('.product-search').addClass('active');\n $('#product-search-results').addClass('active');\n });\n },\n\n resetFilters: function () {\n // Display content results from the search\n $('.page[data-action=Search-Show]').on('click', '.refinement-bar .reset.btn', function () {\n $.spinner().start();\n window.location.href = $(this).data('href');\n });\n },\n\n colorAttribute: function () {\n $(document).on('click', '.color-swatches a:not(.swatch-ellipsis)', function (e) {\n e.preventDefault();\n\n var swatchImg = $(e.currentTarget).data('swatchimg');\n var swatchUrl = $(e.currentTarget).attr('href');\n var $productContainer = $(this).closest('.set-item'); // Need to check and see what classes a product set tile has if any?\n\n if (!$productContainer.length) {\n $productContainer = $(this).closest('.grid-tile');\n }\n\n var currentImg = $($productContainer).find('.tile-image').attr('src');\n\n if ($(this).attr('disabled') || currentImg === swatchImg) {\n return;\n }\n\n $($productContainer).find('.tile-image').attr('src', swatchImg);\n $($productContainer).find('.pdp-link a').attr('href', swatchUrl);\n $($productContainer).find('.image-container > a:not(.quickview)').attr('href', swatchUrl);\n $($productContainer).find('.swatch-ellipsis').attr('href', swatchUrl);\n });\n },\n\n pressShowMore: function () {\n // Display the next page of content results from the search\n $('.container').on('click', 'button#press-load-more', function (e) {\n e.preventDefault();\n getContent($(this), $('.press-list__articles'));\n $('.show-more-content').remove();\n });\n },\n\n contentResultsShowMore: function () {\n // Display the next page of content results from the search\n $('.container').on('click', 'button.content-page-load-more', function () {\n getContent($(this), $('#content-search-results .search-page-results'));\n $(this).remove();\n });\n },\n updateDom: updateDom,\n\n initBacktoTop: function () {\n $('body').on('click', '[data-back-top-button]', function (event) {\n event.preventDefault();\n $('html, body').animate({ scrollTop: 0 }, 500);\n return false;\n });\n }\n};\n","'use strict';\n/**\n * @name getEmailSubscriptionError\n * @description find out the error msg for email\n * subscription based on error code and control\n * @param {string} errorcode input param\n * @param {string} errorcontrol input param\n * @param {string} form input param\n * @returns {string} error message\n */\nfunction getEmailSubscriptionError(errorcode, errorcontrol, form) {\n var strError = '';\n switch (errorcode) {\n case '1': case '6': case '7': case '9':\n strError = 'An error has occurred while attempting to save your subscriber information.';\n break;\n\n case '2':\n strError = 'The list provided does not exist.';\n break;\n\n case '3':\n strError = 'Information was not provided for a mandatory field.';\n break;\n\n case '4':\n strError = 'Invalid information was provided';\n break;\n\n case '5':\n if (form === 'footer') {\n strError = 'The list provided does not exist.';\n break;\n } else {\n strError = 'The list provided does not exist.';\n break;\n }\n\n case '8':\n if (form === 'footer') {\n strError = 'You have already subscribed to this list.';\n break;\n } else {\n strError = 'You have already subscribed to this list, only first time subscribers are eligible for this promotion.';\n break;\n }\n case '10':\n strError = 'An error has occurred while attempting to save subscriber information.';\n break;\n\n case '12':\n strError = 'The email address is already unsubscribed.';\n break;\n\n case '13' :\n strError = 'Check that the list ID or MID specified in your code is correct.';\n break;\n\n case '14' :\n strError = 'Subscriber key is not enabled.';\n break;\n\n default:\n strError = 'Oops! something went wrong. Please try again.';\n }\n if (form === 'modal') {\n window.localStorage.removeItem('arlPromoOverlayModal');\n }\n return strError;\n}\n\nmodule.exports = {\n getEmailSubscriptionError: getEmailSubscriptionError\n};\n","\"use strict\";\n\nrequire(\"./noConflict\");\n\nvar _global = _interopRequireDefault(require(\"core-js/library/fn/global\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\nif (_global[\"default\"]._babelPolyfill && typeof console !== \"undefined\" && console.warn) {\n console.warn(\"@babel/polyfill is loaded more than once on this page. This is probably not desirable/intended \" + \"and may have consequences if different versions of the polyfills are applied sequentially. \" + \"If you do need to load the polyfill more than once, use @babel/polyfill/noConflict \" + \"instead to bypass the warning.\");\n}\n\n_global[\"default\"]._babelPolyfill = true;","\"use strict\";\n\nrequire(\"core-js/es6\");\n\nrequire(\"core-js/fn/array/includes\");\n\nrequire(\"core-js/fn/array/flat-map\");\n\nrequire(\"core-js/fn/string/pad-start\");\n\nrequire(\"core-js/fn/string/pad-end\");\n\nrequire(\"core-js/fn/string/trim-start\");\n\nrequire(\"core-js/fn/string/trim-end\");\n\nrequire(\"core-js/fn/symbol/async-iterator\");\n\nrequire(\"core-js/fn/object/get-own-property-descriptors\");\n\nrequire(\"core-js/fn/object/values\");\n\nrequire(\"core-js/fn/object/entries\");\n\nrequire(\"core-js/fn/promise/finally\");\n\nrequire(\"core-js/web\");\n\nrequire(\"regenerator-runtime/runtime\");","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Selector = {\n DISMISS : '[data-dismiss=\"alert\"]'\n}\n\nconst Event = {\n CLOSE : `close${EVENT_KEY}`,\n CLOSED : `closed${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n ALERT : 'alert',\n FADE : 'fade',\n SHOW : 'show'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${ClassName.ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(Event.CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(ClassName.SHOW)\n\n if (!$(element).hasClass(ClassName.FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(Event.CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n Event.CLICK_DATA_API,\n Selector.DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval : 5000,\n keyboard : true,\n slide : false,\n pause : 'hover',\n wrap : true,\n touch : true\n}\n\nconst DefaultType = {\n interval : '(number|boolean)',\n keyboard : 'boolean',\n slide : '(boolean|string)',\n pause : '(string|boolean)',\n wrap : 'boolean',\n touch : 'boolean'\n}\n\nconst Direction = {\n NEXT : 'next',\n PREV : 'prev',\n LEFT : 'left',\n RIGHT : 'right'\n}\n\nconst Event = {\n SLIDE : `slide${EVENT_KEY}`,\n SLID : `slid${EVENT_KEY}`,\n KEYDOWN : `keydown${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`,\n TOUCHSTART : `touchstart${EVENT_KEY}`,\n TOUCHMOVE : `touchmove${EVENT_KEY}`,\n TOUCHEND : `touchend${EVENT_KEY}`,\n POINTERDOWN : `pointerdown${EVENT_KEY}`,\n POINTERUP : `pointerup${EVENT_KEY}`,\n DRAG_START : `dragstart${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n CAROUSEL : 'carousel',\n ACTIVE : 'active',\n SLIDE : 'slide',\n RIGHT : 'carousel-item-right',\n LEFT : 'carousel-item-left',\n NEXT : 'carousel-item-next',\n PREV : 'carousel-item-prev',\n ITEM : 'carousel-item',\n POINTER_EVENT : 'pointer-event'\n}\n\nconst Selector = {\n ACTIVE : '.active',\n ACTIVE_ITEM : '.active.carousel-item',\n ITEM : '.carousel-item',\n ITEM_IMG : '.carousel-item img',\n NEXT_PREV : '.carousel-item-next, .carousel-item-prev',\n INDICATORS : '.carousel-indicators',\n DATA_SLIDE : '[data-slide], [data-slide-to]',\n DATA_RIDE : '[data-ride=\"carousel\"]'\n}\n\nconst PointerType = {\n TOUCH : 'touch',\n PEN : 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(Selector.INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(Direction.NEXT)\n }\n }\n\n nextWhenVisible() {\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(Direction.PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(Selector.NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(Event.SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex\n ? Direction.NEXT\n : Direction.PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element)\n .on(Event.KEYDOWN, (event) => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(Event.MOUSEENTER, (event) => this.pause(event))\n .on(Event.MOUSELEAVE, (event) => this.cycle(event))\n }\n\n this._addTouchEventListeners()\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = (event) => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = (event) => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = (event) => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(Selector.ITEM_IMG)).on(Event.DRAG_START, (e) => e.preventDefault())\n if (this._pointerEvent) {\n $(this._element).on(Event.POINTERDOWN, (event) => start(event))\n $(this._element).on(Event.POINTERUP, (event) => end(event))\n\n this._element.classList.add(ClassName.POINTER_EVENT)\n } else {\n $(this._element).on(Event.TOUCHSTART, (event) => start(event))\n $(this._element).on(Event.TOUCHMOVE, (event) => move(event))\n $(this._element).on(Event.TOUCHEND, (event) => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode\n ? [].slice.call(element.parentNode.querySelectorAll(Selector.ITEM))\n : []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === Direction.NEXT\n const isPrevDirection = direction === Direction.PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === Direction.PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1\n ? this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(Selector.ACTIVE_ITEM))\n const slideEvent = $.Event(Event.SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector.ACTIVE))\n $(indicators)\n .removeClass(ClassName.ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(ClassName.ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === Direction.NEXT) {\n directionalClassName = ClassName.LEFT\n orderClassName = ClassName.NEXT\n eventDirectionName = Direction.LEFT\n } else {\n directionalClassName = ClassName.RIGHT\n orderClassName = ClassName.PREV\n eventDirectionName = Direction.RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(Event.SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(ClassName.SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)\n if (nextElementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = nextElementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(ClassName.ACTIVE)\n\n $(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(ClassName.ACTIVE)\n $(nextElement).addClass(ClassName.ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n data[action]()\n } else if (_config.interval) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(Event.LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(Selector.DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle : true,\n parent : ''\n}\n\nconst DefaultType = {\n toggle : 'boolean',\n parent : '(string|element)'\n}\n\nconst Event = {\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n SHOW : 'show',\n COLLAPSE : 'collapse',\n COLLAPSING : 'collapsing',\n COLLAPSED : 'collapsed'\n}\n\nconst Dimension = {\n WIDTH : 'width',\n HEIGHT : 'height'\n}\n\nconst Selector = {\n ACTIVES : '.show, .collapsing',\n DATA_TOGGLE : '[data-toggle=\"collapse\"]'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter((foundElem) => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(ClassName.SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(Selector.ACTIVES))\n .filter((elem) => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(ClassName.COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(Event.SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(ClassName.COLLAPSE)\n .addClass(ClassName.COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(ClassName.COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .addClass(ClassName.SHOW)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(Event.SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n const startEvent = $.Event(Event.HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(ClassName.COLLAPSING)\n .removeClass(ClassName.COLLAPSE)\n .removeClass(ClassName.SHOW)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(ClassName.SHOW)) {\n $(trigger).addClass(ClassName.COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .trigger(Event.HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(Dimension.WIDTH)\n return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector =\n `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n\n const children = [].slice.call(parent.querySelectorAll(selector))\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(ClassName.SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(ClassName.COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$this.data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (!data && _config.toggle && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop : true,\n keyboard : true,\n focus : true,\n show : true\n}\n\nconst DefaultType = {\n backdrop : '(boolean|string)',\n keyboard : 'boolean',\n focus : 'boolean',\n show : 'boolean'\n}\n\nconst Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n RESIZE : `resize${EVENT_KEY}`,\n CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,\n KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,\n MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,\n MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n SCROLLBAR_MEASURER : 'modal-scrollbar-measure',\n BACKDROP : 'modal-backdrop',\n OPEN : 'modal-open',\n FADE : 'fade',\n SHOW : 'show'\n}\n\nconst Selector = {\n DIALOG : '.modal-dialog',\n DATA_TOGGLE : '[data-toggle=\"modal\"]',\n DATA_DISMISS : '[data-dismiss=\"modal\"]',\n FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',\n STICKY_CONTENT : '.sticky-top'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(Selector.DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(ClassName.FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(Event.SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n Event.CLICK_DISMISS,\n Selector.DATA_DISMISS,\n (event) => this.hide(event)\n )\n\n $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {\n $(this._element).one(Event.MOUSEUP_DISMISS, (event) => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(Event.HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(ClassName.FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(Event.FOCUSIN)\n\n $(this._element).removeClass(ClassName.SHOW)\n\n $(this._element).off(Event.CLICK_DISMISS)\n $(this._dialog).off(Event.MOUSEDOWN_DISMISS)\n\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, (event) => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach((htmlElement) => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `Event.CLICK_DATA_API` event that should remain\n */\n $(document).off(Event.FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(ClassName.FADE)\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.scrollTop = 0\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(ClassName.SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(Event.SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(Event.FOCUSIN) // Guard against infinite focus loop\n .on(Event.FOCUSIN, (event) => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown && this._config.keyboard) {\n $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {\n if (event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(Event.KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(Event.RESIZE, (event) => this.handleUpdate(event))\n } else {\n $(window).off(Event.RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(ClassName.OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(Event.HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(ClassName.FADE)\n ? ClassName.FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = ClassName.BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(Event.CLICK_DISMISS, (event) => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n if (event.target !== event.currentTarget) {\n return\n }\n if (this._config.backdrop === 'static') {\n this._element.focus()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(ClassName.SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(ClassName.SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(ClassName.FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing =\n this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = rect.left + rect.right < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(Selector.STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(ClassName.OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${Selector.STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = ClassName.SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY)\n ? 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(Event.SHOW, (showEvent) => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(Event.HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.2.1): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.2.1'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset : 10,\n method : 'auto',\n target : ''\n}\n\nconst DefaultType = {\n offset : 'number',\n method : 'string',\n target : '(string|element)'\n}\n\nconst Event = {\n ACTIVATE : `activate${EVENT_KEY}`,\n SCROLL : `scroll${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`\n}\n\nconst ClassName = {\n DROPDOWN_ITEM : 'dropdown-item',\n DROPDOWN_MENU : 'dropdown-menu',\n ACTIVE : 'active'\n}\n\nconst Selector = {\n DATA_SPY : '[data-spy=\"scroll\"]',\n ACTIVE : '.active',\n NAV_LIST_GROUP : '.nav, .list-group',\n NAV_LINKS : '.nav-link',\n NAV_ITEMS : '.nav-item',\n LIST_ITEMS : '.list-group-item',\n DROPDOWN : '.dropdown',\n DROPDOWN_ITEMS : '.dropdown-item',\n DROPDOWN_TOGGLE : '.dropdown-toggle'\n}\n\nconst OffsetMethod = {\n OFFSET : 'offset',\n POSITION : 'position'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +\n `${this._config.target} ${Selector.LIST_ITEMS},` +\n `${this._config.target} ${Selector.DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window\n ? OffsetMethod.OFFSET : OffsetMethod.POSITION\n\n const offsetMethod = this._config.method === 'auto'\n ? autoMethod : this._config.method\n\n const offsetBase = offsetMethod === OffsetMethod.POSITION\n ? this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map((element) => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n return null\n })\n .filter((item) => item)\n .sort((a, b) => a[0] - b[0])\n .forEach((item) => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (typeof config.target !== 'string') {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window\n ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window\n ? window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset +\n scrollHeight -\n this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n const offsetLength = this._offsets.length\n for (let i = offsetLength; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map((selector) => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {\n $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)\n $link.addClass(ClassName.ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(ClassName.ACTIVE)\n // Set triggered links parents as active\n // With both