PageSourceSearch

https://www.blueshieldca.com/etc.clientlibs/bsca/clientlibs/clientlib-base.lc-1790220572243-lc.min.js

js blueshieldca.com collected 2026-09-24 08:45:20 UTC 374,017 bytes, 9,023 lines download raw bytes

1/*******************************************************************************
2 * Copyright 2019 Adobe
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 ******************************************************************************/
16
17/**
18 * Element.matches()
19 * https://developer.mozilla.org/enUS/docs/Web/API/Element/matches#Polyfill
20 */
21if (!Element.prototype.matches) {
22    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
23}
24
25// eslint-disable-next-line valid-jsdoc
26/**
27 * Element.closest()
28 * https://developer.mozilla.org/enUS/docs/Web/API/Element/closest#Polyfill
29 */
30if (!Element.prototype.closest) {
31    Element.prototype.closest = function(s) {
32        "use strict";
33        var el = this;
34        if (!document.documentElement.contains(el)) {
35            return null;
36        }
37        do {
38            if (el.matches(s)) {
39                return el;
40            }
41            el = el.parentElement || el.parentNode;
42        } while (el !== null && el.nodeType === 1);
43        return null;
44    };
45}
46
47/*******************************************************************************
48 * Copyright 2019 Adobe
49 *
50 * Licensed under the Apache License, Version 2.0 (the "License");
51 * you may not use this file except in compliance with the License.
52 * You may obtain a copy of the License at
53 *
54 *     http://www.apache.org/licenses/LICENSE-2.0
55 *
56 * Unless required by applicable law or agreed to in writing, software
57 * distributed under the License is distributed on an "AS IS" BASIS,
58 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
59 * See the License for the specific language governing permissions and
60 * limitations under the License.
61 ******************************************************************************/
62(function() {
63    "use strict";
64
65    var containerUtils = window.CQ && window.CQ.CoreComponents && window.CQ.CoreComponents.container && window.CQ.CoreComponents.container.utils ? window.CQ.CoreComponents.container.utils : undefined;
66    if (!containerUtils) {
67        // eslint-disable-next-line no-console
68        console.warn("Accordion: container utilities at window.CQ.CoreComponents.container.utils are not available. This can lead to missing features. Ensure the core.wcm.components.commons.site.container client library is included on the page.");
69    }
70    var dataLayerEnabled;
71    var dataLayer;
72    var dataLayerName;
73    var delay = 100;
74
75    var NS = "cmp";
76    var IS = "accordion";
77
78    var keyCodes = {
79        ENTER: 13,
80        SPACE: 32,
81        END: 35,
82        HOME: 36,
83        ARROW_LEFT: 37,
84        ARROW_UP: 38,
85        ARROW_RIGHT: 39,
86        ARROW_DOWN: 40
87    };
88
89    var selectors = {
90        self: "[data-" + NS + '-is="' + IS + '"]'
91    };
92
93    var cssClasses = {
94        button: {
95            disabled: "cmp-accordion__button--disabled",
96            expanded: "cmp-accordion__button--expanded"
97        },
98        panel: {
99            hidden: "cmp-accordion__panel--hidden",
100            expanded: "cmp-accordion__panel--expanded"
101        }
102    };
103
104    var dataAttributes = {
105        item: {
106            expanded: "data-cmp-expanded"
107        }
108    };
109
110    var properties = {
111        /**
112         * Determines whether a single accordion item is forced to be expanded at a time.
113         * Expanding one item will collapse all others.
114         *
115         * @memberof Accordion
116         * @type {Boolean}
117         * @default false
118         */
119        "singleExpansion": {
120            "default": false,
121            "transform": function(value) {
122                return !(value === null || typeof value === "undefined");
123            }
124        }
125    };
126
127    /**
128     * Accordion Configuration.
129     *
130     * @typedef {Object} AccordionConfig Represents an Accordion configuration
131     * @property {HTMLElement} element The HTMLElement representing the Accordion
132     * @property {Object} options The Accordion options
133     */
134
135    /**
136     * Accordion.
137     *
138     * @class Accordion
139     * @classdesc An interactive Accordion component for toggling panels of related content
140     * @param {AccordionConfig} config The Accordion configuration
141     */
142    function Accordion(config) {
143        var that = this;
144
145        if (config && config.element) {
146            init(config);
147        }
148
149        /**
150         * Initializes the Accordion.
151         *
152         * @private
153         * @param {AccordionConfig} config The Accordion configuration
154         */
155        function init(config) {
156            that._config = config;
157
158            // prevents multiple initialization
159            config.element.removeAttribute("data-" + NS + "-is");
160
161            setupProperties(config.options);
162            cacheElements(config.element);
163
164            if (that._elements["item"]) {
165                // ensures multiple element types are arrays.
166                that._elements["item"] = Array.isArray(that._elements["item"]) ? that._elements["item"] : [that._elements["item"]];
167                that._elements["button"] = Array.isArray(that._elements["button"]) ? that._elements["button"] : [that._elements["button"]];
168                that._elements["panel"] = Array.isArray(that._elements["panel"]) ? that._elements["panel"] : [that._elements["panel"]];
169
170                if (that._properties.singleExpansion) {
171                    var expandedItems = getExpandedItems();
172                    // multiple expanded items annotated, display the last item open.
173                    if (expandedItems.length > 1) {
174                        toggle(expandedItems.length - 1);
175                    }
176                }
177
178                refreshItems();
179                bindEvents();
180                scrollToDeepLinkIdInAccordion();
181            }
182            if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
183                /*
184                 * Editor message handling:
185                 * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
186                 * - check that the message data panel container type is correct and that the id (path) matches this specific Accordion component
187                 * - if so, route the "navigate" operation to enact a navigation of the Accordion based on index data
188                 */
189                window.CQ.CoreComponents.MESSAGE_CHANNEL = window.CQ.CoreComponents.MESSAGE_CHANNEL || new window.Granite.author.MessageChannel("cqauthor", window);
190                window.CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage("cmp.panelcontainer", function(message) {
191                    if (message.data && message.data.type === "cmp-accordion" && message.data.id === that._elements.self.dataset["cmpPanelcontainerId"]) {
192                        if (message.data.operation === "navigate") {
193                            // switch to single expansion mode when navigating in edit mode.
194                            var singleExpansion = that._properties.singleExpansion;
195                            that._properties.singleExpansion = true;
196                            toggle(message.data.index);
197
198                            // revert to the configured state.
199                            that._properties.singleExpansion = singleExpansion;
200                        }
201                    }
202                });
203            }
204        }
205
206        /**
207         * Displays the panel containing the element that corresponds to the deep link in the URI fragment
208         * and scrolls the browser to this element.
209         */
210        function scrollToDeepLinkIdInAccordion() {
211            if (containerUtils) {
212                var deepLinkItemIdx = containerUtils.getDeepLinkItemIdx(that, "item", "item");
213                if (deepLinkItemIdx > -1) {
214                    var deepLinkItem = that._elements["item"][deepLinkItemIdx];
215                    if (deepLinkItem && !deepLinkItem.hasAttribute(dataAttributes.item.expanded)) {
216                        // if single expansion: close all accordion items
217                        if (that._properties.singleExpansion) {
218                            for (var j = 0; j < that._elements["item"].length; j++) {
219                                if (that._elements["item"][j].hasAttribute(dataAttributes.item.expanded)) {
220                                    setItemExpanded(that._elements["item"][j], false, true);
221                                }
222                            }
223                        }
224                        // expand the accordion item containing the deep link
225                        setItemExpanded(deepLinkItem, true, true);
226                    }
227                    var hashId = window.location.hash.substring(1);
228                    if (hashId) {
229                        var hashItem = document.querySelector("[id='" + hashId + "']");
230                        if (hashItem) {
231                            hashItem.scrollIntoView();
232                        }
233                    }
234                }
235            }
236        }
237
238        /**
239         * Caches the Accordion elements as defined via the {@code data-accordion-hook="ELEMENT_NAME"} markup API.
240         *
241         * @private
242         * @param {HTMLElement} wrapper The Accordion wrapper element
243         */
244        function cacheElements(wrapper) {
245            that._elements = {};
246            that._elements.self = wrapper;
247            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
248
249            for (var i = 0; i < hooks.length; i++) {
250                var hook = hooks[i];
251                if (hook.closest("." + NS + "-" + IS) === that._elements.self) { // only process own accordion elements
252                    var capitalized = IS;
253                    capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
254                    var key = hook.dataset[NS + "Hook" + capitalized];
255                    if (that._elements[key]) {
256                        if (!Array.isArray(that._elements[key])) {
257                            var tmp = that._elements[key];
258                            that._elements[key] = [tmp];
259                        }
260                        that._elements[key].push(hook);
261                    } else {
262                        that._elements[key] = hook;
263                    }
264                }
265            }
266        }
267
268        /**
269         * Sets up properties for the Accordion based on the passed options.
270         *
271         * @private
272         * @param {Object} options The Accordion options
273         */
274        function setupProperties(options) {
275            that._properties = {};
276
277            for (var key in properties) {
278                if (Object.prototype.hasOwnProperty.call(properties, key)) {
279                    var property = properties[key];
280                    var value = null;
281
282                    if (options && options[key] != null) {
283                        value = options[key];
284
285                        // transform the provided option
286                        if (property && typeof property.transform === "function") {
287                            value = property.transform(value);
288                        }
289                    }
290
291                    if (value === null) {
292                        // value still null, take the property default
293                        value = properties[key]["default"];
294                    }
295
296                    that._properties[key] = value;
297                }
298            }
299        }
300
301        /**
302         * Binds Accordion event handling.
303         *
304         * @private
305         */
306        function bindEvents() {
307            window.addEventListener("hashchange", scrollToDeepLinkIdInAccordion, false);
308            var buttons = that._elements["button"];
309            if (buttons) {
310                for (var i = 0; i < buttons.length; i++) {
311                    (function(index) {
312                        buttons[i].addEventListener("click", function(event) {
313                            toggle(index);
314                            focusButton(index);
315                        });
316                        buttons[i].addEventListener("keydown", function(event) {
317                            onButtonKeyDown(event, index);
318                        });
319                    })(i);
320                }
321            }
322        }
323
324        /**
325         * Handles button keydown events.
326         *
327         * @private
328         * @param {Object} event The keydown event
329         * @param {Number} index The index of the button triggering the event
330         */
331        function onButtonKeyDown(event, index) {
332            var lastIndex = that._elements["button"].length - 1;
333
334            switch (event.keyCode) {
335                case keyCodes.ARROW_LEFT:
336                case keyCodes.ARROW_UP:
337                    event.preventDefault();
338                    if (index > 0) {
339                        focusButton(index - 1);
340                    }
341                    break;
342                case keyCodes.ARROW_RIGHT:
343                case keyCodes.ARROW_DOWN:
344                    event.preventDefault();
345                    if (index < lastIndex) {
346                        focusButton(index + 1);
347                    }
348                    break;
349                case keyCodes.HOME:
350                    event.preventDefault();
351                    focusButton(0);
352                    break;
353                case keyCodes.END:
354                    event.preventDefault();
355                    focusButton(lastIndex);
356                    break;
357                case keyCodes.ENTER:
358                case keyCodes.SPACE:
359                    event.preventDefault();
360                    toggle(index);
361                    focusButton(index);
362                    break;
363                default:
364                    return;
365            }
366        }
367
368        /**
369         * General handler for toggle of an item.
370         *
371         * @private
372         * @param {Number} index The index of the item to toggle
373         */
374        function toggle(index) {
375            var item = that._elements["item"][index];
376            if (item) {
377                if (that._properties.singleExpansion) {
378                    // ensure only a single item is expanded if single expansion is enabled.
379                    for (var i = 0; i < that._elements["item"].length; i++) {
380                        if (that._elements["item"][i] !== item) {
381                            var expanded = getItemExpanded(that._elements["item"][i]);
382                            if (expanded) {
383                                setItemExpanded(that._elements["item"][i], false);
384                            }
385                        }
386                    }
387                }
388                setItemExpanded(item, !getItemExpanded(item));
389
390                if (dataLayerEnabled) {
391                    var accordionId = that._elements.self.id;
392                    var expandedItems = getExpandedItems()
393                        .map(function(item) {
394                            return getDataLayerId(item);
395                        });
396
397                    var uploadPayload = { component: {} };
398                    uploadPayload.component[accordionId] = { shownItems: expandedItems };
399
400                    var removePayload = { component: {} };
401                    removePayload.component[accordionId] = { shownItems: undefined };
402
403                    dataLayer.push(removePayload);
404                    dataLayer.push(uploadPayload);
405                }
406            }
407        }
408
409        /**
410         * Sets an item's expanded state based on the provided flag and refreshes its internals.
411         *
412         * @private
413         * @param {HTMLElement} item The item to mark as expanded, or not expanded
414         * @param {Boolean} expanded true to mark the item expanded, false otherwise
415         * @param {Boolean} keepHash true to keep the hash in the URL, false to update it
416         */
417        function setItemExpanded(item, expanded, keepHash) {
418            if (expanded) {
419                item.setAttribute(dataAttributes.item.expanded, "");
420                var index = that._elements["item"].indexOf(item);
421                if (!keepHash && containerUtils) {
422                    containerUtils.updateUrlHash(that, "item", index);
423                }
424                if (dataLayerEnabled) {
425                    dataLayer.push({
426                        event: "cmp:show",
427                        eventInfo: {
428                            path: "component." + getDataLayerId(item)
429                        }
430                    });
431                }
432
433            } else {
434                item.removeAttribute(dataAttributes.item.expanded);
435                if (!keepHash && containerUtils) {
436                    containerUtils.removeUrlHash();
437                }
438                if (dataLayerEnabled) {
439                    dataLayer.push({
440                        event: "cmp:hide",
441                        eventInfo: {
442                            path: "component." + getDataLayerId(item)
443                        }
444                    });
445                }
446            }
447            refreshItem(item);
448        }
449
450        /**
451         * Gets an item's expanded state.
452         *
453         * @private
454         * @param {HTMLElement} item The item for checking its expanded state
455         * @returns {Boolean} true if the item is expanded, false otherwise
456         */
457        function getItemExpanded(item) {
458            return item && item.dataset && item.dataset["cmpExpanded"] !== undefined;
459        }
460
461        /**
462         * Refreshes an item based on its expanded state.
463         *
464         * @private
465         * @param {HTMLElement} item The item to refresh
466         */
467        function refreshItem(item) {
468            var expanded = getItemExpanded(item);
469            if (expanded) {
470                expandItem(item);
471            } else {
472                collapseItem(item);
473            }
474        }
475
476        /**
477         * Refreshes all items based on their expanded state.
478         *
479         * @private
480         */
481        function refreshItems() {
482            for (var i = 0; i < that._elements["item"].length; i++) {
483                refreshItem(that._elements["item"][i]);
484            }
485        }
486
487        /**
488         * Returns all expanded items.
489         *
490         * @private
491         * @returns {HTMLElement[]} The expanded items
492         */
493        function getExpandedItems() {
494            var expandedItems = [];
495
496            for (var i = 0; i < that._elements["item"].length; i++) {
497                var item = that._elements["item"][i];
498                var expanded = getItemExpanded(item);
499                if (expanded) {
500                    expandedItems.push(item);
501                }
502            }
503
504            return expandedItems;
505        }
506
507        /**
508         * Annotates the item and its internals with
509         * the necessary style and accessibility attributes to indicate it is expanded.
510         *
511         * @private
512         * @param {HTMLElement} item The item to annotate as expanded
513         */
514        function expandItem(item) {
515            var index = that._elements["item"].indexOf(item);
516            if (index > -1) {
517                var button = that._elements["button"][index];
518                var panel = that._elements["panel"][index];
519                button.classList.add(cssClasses.button.expanded);
520                // used to fix some known screen readers issues in reading the correct state of the 'aria-expanded' attribute
521                // e.g. https://bugs.webkit.org/show_bug.cgi?id=210934
522                setTimeout(function() {
523                    button.setAttribute("aria-expanded", true);
524                }, delay);
525                panel.classList.add(cssClasses.panel.expanded);
526                panel.classList.remove(cssClasses.panel.hidden);
527                panel.setAttribute("aria-hidden", false);
528            }
529        }
530
531        /**
532         * Annotates the item and its internals with
533         * the necessary style and accessibility attributes to indicate it is not expanded.
534         *
535         * @private
536         * @param {HTMLElement} item The item to annotate as not expanded
537         */
538        function collapseItem(item) {
539            var index = that._elements["item"].indexOf(item);
540            if (index > -1) {
541                var button = that._elements["button"][index];
542                var panel = that._elements["panel"][index];
543                button.classList.remove(cssClasses.button.expanded);
544                // used to fix some known screen readers issues in reading the correct state of the 'aria-expanded' attribute
545                // e.g. https://bugs.webkit.org/show_bug.cgi?id=210934
546                setTimeout(function() {
547                    button.setAttribute("aria-expanded", false);
548                }, delay);
549                panel.classList.add(cssClasses.panel.hidden);
550                panel.classList.remove(cssClasses.panel.expanded);
551                panel.setAttribute("aria-hidden", true);
552            }
553        }
554
555        /**
556         * Focuses the button at the provided index.
557         *
558         * @private
559         * @param {Number} index The index of the button to focus
560         */
561        function focusButton(index) {
562            var button = that._elements["button"][index];
563            button.focus();
564        }
565    }
566
567    /**
568     * Reads options data from the Accordion wrapper element, defined via {@code data-cmp-*} data attributes.
569     *
570     * @private
571     * @param {HTMLElement} element The Accordion element to read options data from
572     * @returns {Object} The options read from the component data attributes
573     */
574    function readData(element) {
575        var data = element.dataset;
576        var options = [];
577        var capitalized = IS;
578        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
579        var reserved = ["is", "hook" + capitalized];
580
581        for (var key in data) {
582            if (Object.prototype.hasOwnProperty.call(data, key)) {
583                var value = data[key];
584
585                if (key.indexOf(NS) === 0) {
586                    key = key.slice(NS.length);
587                    key = key.charAt(0).toLowerCase() + key.substring(1);
588
589                    if (reserved.indexOf(key) === -1) {
590                        options[key] = value;
591                    }
592                }
593            }
594        }
595
596        return options;
597    }
598
599    /**
600     * Parses the dataLayer string and returns the ID
601     *
602     * @private
603     * @param {HTMLElement} item the accordion item
604     * @returns {String} dataLayerId or undefined
605     */
606    function getDataLayerId(item) {
607        if (item) {
608            if (item.dataset.cmpDataLayer) {
609                return Object.keys(JSON.parse(item.dataset.cmpDataLayer))[0];
610            } else {
611                return item.id;
612            }
613        }
614        return null;
615    }
616
617    /**
618     * Document ready handler and DOM mutation observers. Initializes Accordion components as necessary.
619     *
620     * @private
621     */
622    function onDocumentReady() {
623        dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
624        if (dataLayerEnabled) {
625            dataLayerName = document.body.getAttribute("data-cmp-data-layer-name") || "adobeDataLayer";
626            dataLayer = window[dataLayerName] = window[dataLayerName] || [];
627        }
628
629        var elements = document.querySelectorAll(selectors.self);
630        for (var i = 0; i < elements.length; i++) {
631            new Accordion({ element: elements[i], options: readData(elements[i]) });
632        }
633
634        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
635        var body = document.querySelector("body");
636        var observer = new MutationObserver(function(mutations) {
637            mutations.forEach(function(mutation) {
638                // needed for IE
639                var nodesArray = [].slice.call(mutation.addedNodes);
640                if (nodesArray.length > 0) {
641                    nodesArray.forEach(function(addedNode) {
642                        if (addedNode.querySelectorAll) {
643                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
644                            elementsArray.forEach(function(element) {
645                                new Accordion({ element: element, options: readData(element) });
646                            });
647                        }
648                    });
649                }
650            });
651        });
652
653        observer.observe(body, {
654            subtree: true,
655            childList: true,
656            characterData: true
657        });
658    }
659
660    if (document.readyState !== "loading") {
661        onDocumentReady();
662    } else {
663        document.addEventListener("DOMContentLoaded", onDocumentReady);
664    }
665
666    if (containerUtils) {
667        window.addEventListener("load", containerUtils.scrollToAnchor, false);
668    }
669
670}());
671
672/*******************************************************************************
673 * Copyright 2018 Adobe
674 *
675 * Licensed under the Apache License, Version 2.0 (the "License");
676 * you may not use this file except in compliance with the License.
677 * You may obtain a copy of the License at
678 *
679 *     http://www.apache.org/licenses/LICENSE2.0
680 *
681 * Unless required by applicable law or agreed to in writing, software
682 * distributed under the License is distributed on an "AS IS" BASIS,
683 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
684 * See the License for the specific language governing permissions and
685 * limitations under the License.
686 ******************************************************************************/
687
688/**
689 * Element.matches()
690 * https://developer.mozilla.org/enUS/docs/Web/API/Element/matches#Polyfill
691 */
692if (!Element.prototype.matches) {
693    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
694}
695
696// eslint-disable-next-line valid-jsdoc
697/**
698 * Element.closest()
699 * https://developer.mozilla.org/enUS/docs/Web/API/Element/closest#Polyfill
700 */
701if (!Element.prototype.closest) {
702    Element.prototype.closest = function(s) {
703        "use strict";
704        var el = this;
705        if (!document.documentElement.contains(el)) {
706            return null;
707        }
708        do {
709            if (el.matches(s)) {
710                return el;
711            }
712            el = el.parentElement || el.parentNode;
713        } while (el !== null && el.nodeType === 1);
714        return null;
715    };
716}
717
718/*******************************************************************************
719 * Copyright 2018 Adobe
720 *
721 * Licensed under the Apache License, Version 2.0 (the "License");
722 * you may not use this file except in compliance with the License.
723 * You may obtain a copy of the License at
724 *
725 *     http://www.apache.org/licenses/LICENSE-2.0
726 *
727 * Unless required by applicable law or agreed to in writing, software
728 * distributed under the License is distributed on an "AS IS" BASIS,
729 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
730 * See the License for the specific language governing permissions and
731 * limitations under the License.
732 ******************************************************************************/
733/* global
734    CQ
735 */
736(function() {
737    "use strict";
738
739    var containerUtils = window.CQ && window.CQ.CoreComponents && window.CQ.CoreComponents.container && window.CQ.CoreComponents.container.utils ? window.CQ.CoreComponents.container.utils : undefined;
740    if (!containerUtils) {
741        // eslint-disable-next-line no-console
742        console.warn("Tabs: container utilities at window.CQ.CoreComponents.container.utils are not available. This can lead to missing features. Ensure the core.wcm.components.commons.site.container client library is included on the page.");
743    }
744    var dataLayerEnabled;
745    var dataLayer;
746    var dataLayerName;
747
748    var NS = "cmp";
749    var IS = "tabs";
750
751    var keyCodes = {
752        END: 35,
753        HOME: 36,
754        ARROW_LEFT: 37,
755        ARROW_UP: 38,
756        ARROW_RIGHT: 39,
757        ARROW_DOWN: 40
758    };
759
760    var selectors = {
761        self: "[data-" + NS + '-is="' + IS + '"]',
762        active: {
763            tab: "cmp-tabs__tab--active",
764            tabpanel: "cmp-tabs__tabpanel--active"
765        }
766    };
767
768    /**
769     * Tabs Configuration
770     *
771     * @typedef {Object} TabsConfig Represents a Tabs configuration
772     * @property {HTMLElement} element The HTMLElement representing the Tabs
773     * @property {Object} options The Tabs options
774     */
775
776    /**
777     * Tabs
778     *
779     * @class Tabs
780     * @classdesc An interactive Tabs component for navigating a list of tabs
781     * @param {TabsConfig} config The Tabs configuration
782     */
783    function Tabs(config) {
784        var that = this;
785
786        if (config && config.element) {
787            init(config);
788        }
789
790        /**
791         * Initializes the Tabs
792         *
793         * @private
794         * @param {TabsConfig} config The Tabs configuration
795         */
796        function init(config) {
797            that._config = config;
798
799            // prevents multiple initialization
800            config.element.removeAttribute("data-" + NS + "-is");
801
802            cacheElements(config.element);
803            that._active = getActiveIndex(that._elements["tab"]);
804
805            if (that._elements.tabpanel) {
806                refreshActive();
807                bindEvents();
808                scrollToDeepLinkIdInTabs();
809            }
810
811            if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
812                /*
813                 * Editor message handling:
814                 * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
815                 * - check that the message data panel container type is correct and that the id (path) matches this specific Tabs component
816                 * - if so, route the "navigate" operation to enact a navigation of the Tabs based on index data
817                 */
818                CQ.CoreComponents.MESSAGE_CHANNEL = CQ.CoreComponents.MESSAGE_CHANNEL || new window.Granite.author.MessageChannel("cqauthor", window);
819                CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage("cmp.panelcontainer", function(message) {
820                    if (message.data && message.data.type === "cmp-tabs" && message.data.id === that._elements.self.dataset["cmpPanelcontainerId"]) {
821                        if (message.data.operation === "navigate") {
822                            navigate(message.data.index);
823                        }
824                    }
825                });
826            }
827        }
828
829        /**
830         * Displays the panel containing the element that corresponds to the deep link in the URI fragment
831         * and scrolls the browser to this element.
832         */
833        function scrollToDeepLinkIdInTabs() {
834            if (containerUtils) {
835                var deepLinkItemIdx = containerUtils.getDeepLinkItemIdx(that, "tab", "tabpanel");
836                if (deepLinkItemIdx > -1) {
837                    var deepLinkItem = that._elements["tab"][deepLinkItemIdx];
838                    if (deepLinkItem && that._elements["tab"][that._active].id !== deepLinkItem.id) {
839                        navigateAndFocusTab(deepLinkItemIdx, true);
840                    }
841                    var hashId = window.location.hash.substring(1);
842                    if (hashId) {
843                        var hashItem = document.querySelector("[id='" + hashId + "']");
844                        if (hashItem) {
845                            hashItem.scrollIntoView();
846                        }
847                    }
848                }
849            }
850        }
851
852        /**
853         * Returns the index of the active tab, if no tab is active returns 0
854         *
855         * @param {Array} tabs Tab elements
856         * @returns {Number} Index of the active tab, 0 if none is active
857         */
858        function getActiveIndex(tabs) {
859            if (tabs) {
860                for (var i = 0; i < tabs.length; i++) {
861                    if (tabs[i].classList.contains(selectors.active.tab)) {
862                        return i;
863                    }
864                }
865            }
866            return 0;
867        }
868
869        /**
870         * Caches the Tabs elements as defined via the {@code data-tabs-hook="ELEMENT_NAME"} markup API
871         *
872         * @private
873         * @param {HTMLElement} wrapper The Tabs wrapper element
874         */
875        function cacheElements(wrapper) {
876            that._elements = {};
877            that._elements.self = wrapper;
878            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
879
880            for (var i = 0; i < hooks.length; i++) {
881                var hook = hooks[i];
882                if (hook.closest("." + NS + "-" + IS) === that._elements.self) { // only process own tab elements
883                    var capitalized = IS;
884                    capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
885                    var key = hook.dataset[NS + "Hook" + capitalized];
886                    if (that._elements[key]) {
887                        if (!Array.isArray(that._elements[key])) {
888                            var tmp = that._elements[key];
889                            that._elements[key] = [tmp];
890                        }
891                        that._elements[key].push(hook);
892                    } else {
893                        that._elements[key] = hook;
894                    }
895                }
896            }
897        }
898
899        /**
900         * Binds Tabs event handling
901         *
902         * @private
903         */
904        function bindEvents() {
905            window.addEventListener("hashchange", scrollToDeepLinkIdInTabs, false);
906            var tabs = that._elements["tab"];
907            if (tabs) {
908                for (var i = 0; i < tabs.length; i++) {
909                    (function(index) {
910                        tabs[i].addEventListener("click", function(event) {
911                            navigateAndFocusTab(index);
912                        });
913                        tabs[i].addEventListener("keydown", function(event) {
914                            onKeyDown(event);
915                        });
916                    })(i);
917                }
918            }
919        }
920
921        /**
922         * Handles tab keydown events
923         *
924         * @private
925         * @param {Object} event The keydown event
926         */
927        function onKeyDown(event) {
928            var index = that._active;
929            var lastIndex = that._elements["tab"].length - 1;
930
931            switch (event.keyCode) {
932                case keyCodes.ARROW_LEFT:
933                case keyCodes.ARROW_UP:
934                    event.preventDefault();
935                    if (index > 0) {
936                        navigateAndFocusTab(index - 1);
937                    }
938                    break;
939                case keyCodes.ARROW_RIGHT:
940                case keyCodes.ARROW_DOWN:
941                    event.preventDefault();
942                    if (index < lastIndex) {
943                        navigateAndFocusTab(index + 1);
944                    }
945                    break;
946                case keyCodes.HOME:
947                    event.preventDefault();
948                    navigateAndFocusTab(0);
949                    break;
950                case keyCodes.END:
951                    event.preventDefault();
952                    navigateAndFocusTab(lastIndex);
953                    break;
954                default:
955                    return;
956            }
957        }
958
959        /**
960         * Refreshes the tab markup based on the current {@code Tabs#_active} index
961         *
962         * @private
963         */
964        function refreshActive() {
965            var tabpanels = that._elements["tabpanel"];
966            var tabs = that._elements["tab"];
967
968            if (tabpanels) {
969                if (Array.isArray(tabpanels)) {
970                    for (var i = 0; i < tabpanels.length; i++) {
971                        if (i === parseInt(that._active)) {
972                            tabpanels[i].classList.add(selectors.active.tabpanel);
973                            tabpanels[i].removeAttribute("aria-hidden");
974                            tabs[i].classList.add(selectors.active.tab);
975                            tabs[i].setAttribute("aria-selected", true);
976                            tabs[i].setAttribute("tabindex", "0");
977                        } else {
978                            tabpanels[i].classList.remove(selectors.active.tabpanel);
979                            tabpanels[i].setAttribute("aria-hidden", true);
980                            tabs[i].classList.remove(selectors.active.tab);
981                            tabs[i].setAttribute("aria-selected", false);
982                            tabs[i].setAttribute("tabindex", "-1");
983                        }
984                    }
985                } else {
986                    // only one tab
987                    tabpanels.classList.add(selectors.active.tabpanel);
988                    tabs.classList.add(selectors.active.tab);
989                }
990            }
991        }
992
993        /**
994         * Focuses the element and prevents scrolling the element into view
995         *
996         * @param {HTMLElement} element Element to focus
997         */
998        function focusWithoutScroll(element) {
999            var x = window.scrollX || window.pageXOffset;
1000            var y = window.scrollY || window.pageYOffset;
1001            element.focus();
1002            window.scrollTo(x, y);
1003        }
1004
1005        /**
1006         * Navigates to the tab at the provided index
1007         *
1008         * @private
1009         * @param {Number} index The index of the tab to navigate to
1010         */
1011        function navigate(index) {
1012            that._active = index;
1013            refreshActive();
1014        }
1015
1016        /**
1017         * Navigates to the item at the provided index and ensures the active tab gains focus
1018         *
1019         * @private
1020         * @param {Number} index The index of the item to navigate to
1021         * @param {Boolean} keepHash true to keep the hash in the URL, false to update it
1022         */
1023        function navigateAndFocusTab(index, keepHash) {
1024            var exActive = that._active;
1025            if (!keepHash && containerUtils) {
1026                containerUtils.updateUrlHash(that, "tab", index);
1027            }
1028            navigate(index);
1029            focusWithoutScroll(that._elements["tab"][index]);
1030
1031            if (dataLayerEnabled) {
1032
1033                var activeItem = getDataLayerId(that._elements.tabpanel[index]);
1034                var exActiveItem = getDataLayerId(that._elements.tabpanel[exActive]);
1035
1036                dataLayer.push({
1037                    event: "cmp:show",
1038                    eventInfo: {
1039                        path: "component." + activeItem
1040                    }
1041                });
1042
1043                dataLayer.push({
1044                    event: "cmp:hide",
1045                    eventInfo: {
1046                        path: "component." + exActiveItem
1047                    }
1048                });
1049
1050                var tabsId = that._elements.self.id;
1051                var uploadPayload = { component: {} };
1052                uploadPayload.component[tabsId] = { shownItems: [activeItem] };
1053
1054                var removePayload = { component: {} };
1055                removePayload.component[tabsId] = { shownItems: undefined };
1056
1057                dataLayer.push(removePayload);
1058                dataLayer.push(uploadPayload);
1059            }
1060        }
1061    }
1062
1063    /**
1064     * Reads options data from the Tabs wrapper element, defined via {@code data-cmp-*} data attributes
1065     *
1066     * @private
1067     * @param {HTMLElement} element The Tabs element to read options data from
1068     * @returns {Object} The options read from the component data attributes
1069     */
1070    function readData(element) {
1071        var data = element.dataset;
1072        var options = [];
1073        var capitalized = IS;
1074        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
1075        var reserved = ["is", "hook" + capitalized];
1076
1077        for (var key in data) {
1078            if (Object.prototype.hasOwnProperty.call(data, key)) {
1079                var value = data[key];
1080
1081                if (key.indexOf(NS) === 0) {
1082                    key = key.slice(NS.length);
1083                    key = key.charAt(0).toLowerCase() + key.substring(1);
1084
1085                    if (reserved.indexOf(key) === -1) {
1086                        options[key] = value;
1087                    }
1088                }
1089            }
1090        }
1091
1092        return options;
1093    }
1094
1095    /**
1096     * Parses the dataLayer string and returns the ID
1097     *
1098     * @private
1099     * @param {HTMLElement} item the accordion item
1100     * @returns {String} dataLayerId or undefined
1101     */
1102    function getDataLayerId(item) {
1103        if (item) {
1104            if (item.dataset.cmpDataLayer) {
1105                return Object.keys(JSON.parse(item.dataset.cmpDataLayer))[0];
1106            } else {
1107                return item.id;
1108            }
1109        }
1110        return null;
1111    }
1112
1113    /**
1114     * Document ready handler and DOM mutation observers. Initializes Tabs components as necessary.
1115     *
1116     * @private
1117     */
1118    function onDocumentReady() {
1119        dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
1120        if (dataLayerEnabled) {
1121            dataLayerName = document.body.getAttribute("data-cmp-data-layer-name") || "adobeDataLayer";
1122            dataLayer = window[dataLayerName] = window[dataLayerName] || [];
1123        }
1124
1125        var elements = document.querySelectorAll(selectors.self);
1126        for (var i = 0; i < elements.length; i++) {
1127            new Tabs({ element: elements[i], options: readData(elements[i]) });
1128        }
1129
1130        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
1131        var body = document.querySelector("body");
1132        var observer = new MutationObserver(function(mutations) {
1133            mutations.forEach(function(mutation) {
1134                // needed for IE
1135                var nodesArray = [].slice.call(mutation.addedNodes);
1136                if (nodesArray.length > 0) {
1137                    nodesArray.forEach(function(addedNode) {
1138                        if (addedNode.querySelectorAll) {
1139                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
1140                            elementsArray.forEach(function(element) {
1141                                new Tabs({ element: element, options: readData(element) });
1142                            });
1143                        }
1144                    });
1145                }
1146            });
1147        });
1148
1149        observer.observe(body, {
1150            subtree: true,
1151            childList: true,
1152            characterData: true
1153        });
1154    }
1155
1156    if (document.readyState !== "loading") {
1157        onDocumentReady();
1158    } else {
1159        document.addEventListener("DOMContentLoaded", onDocumentReady);
1160    }
1161
1162    if (containerUtils) {
1163        window.addEventListener("load", containerUtils.scrollToAnchor, false);
1164    }
1165
1166}());
1167
1168/*******************************************************************************
1169 * Copyright 2022 Adobe
1170 *
1171 * Licensed under the Apache License, Version 2.0 (the "License");
1172 * you may not use this file except in compliance with the License.
1173 * You may obtain a copy of the License at
1174 *
1175 *     http://www.apache.org/licenses/LICENSE-2.0
1176 *
1177 * Unless required by applicable law or agreed to in writing, software
1178 * distributed under the License is distributed on an "AS IS" BASIS,
1179 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1180 * See the License for the specific language governing permissions and
1181 * limitations under the License.
1182 ******************************************************************************/
1183(function(document) {
1184    "use strict";
1185
1186    window.CMP = window.CMP || {};
1187    window.CMP.utils = (function() {
1188        var NS = "cmp";
1189
1190        /**
1191         * Reads options data from the Component wrapper element, defined via {@code data-cmp-*} data attributes
1192         *
1193         * @param {HTMLElement} element The component element to read options data from
1194         * @param {String} is The component identifier
1195         * @returns {String[]} The options read from the component data attributes
1196         */
1197        var readData = function(element, is) {
1198            var data = element.dataset;
1199            var options = [];
1200            var capitalized = is;
1201            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
1202            var reserved = ["is", "hook" + capitalized];
1203
1204            for (var key in data) {
1205                if (Object.prototype.hasOwnProperty.call(data, key)) {
1206                    var value = data[key];
1207
1208                    if (key.indexOf(NS) === 0) {
1209                        key = key.slice(NS.length);
1210                        key = key.charAt(0).toLowerCase() + key.substring(1);
1211
1212                        if (reserved.indexOf(key) === -1) {
1213                            options[key] = value;
1214                        }
1215                    }
1216                }
1217            }
1218            return options;
1219        };
1220
1221        /**
1222         * Set up the final properties of a component by evaluating the transform function or fall back to the default value on demand
1223         * @param {String[]} options the options to transform
1224         * @param {Object} properties object of properties of property functions
1225         * @returns {Object} transformed properties
1226         */
1227        var setupProperties = function(options, properties) {
1228            var transformedProperties = {};
1229
1230            for (var key in properties) {
1231                if (Object.prototype.hasOwnProperty.call(properties, key)) {
1232                    var property = properties[key];
1233                    if (options && options[key] != null) {
1234                        if (property && typeof property.transform === "function") {
1235                            transformedProperties[key] = property.transform(options[key]);
1236                        } else {
1237                            transformedProperties[key] = options[key];
1238                        }
1239                    } else {
1240                        transformedProperties[key] = properties[key]["default"];
1241                    }
1242                }
1243            }
1244            return transformedProperties;
1245        };
1246
1247
1248        return {
1249            readData: readData,
1250            setupProperties: setupProperties
1251        };
1252    }());
1253}(window.document));
1254
1255/*******************************************************************************
1256 * Copyright 2018 Adobe
1257 *
1258 * Licensed under the Apache License, Version 2.0 (the "License");
1259 * you may not use this file except in compliance with the License.
1260 * You may obtain a copy of the License at
1261 *
1262 *     http://www.apache.org/licenses/LICENSE-2.0
1263 *
1264 * Unless required by applicable law or agreed to in writing, software
1265 * distributed under the License is distributed on an "AS IS" BASIS,
1266 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1267 * See the License for the specific language governing permissions and
1268 * limitations under the License.
1269 ******************************************************************************/
1270(function() {
1271    "use strict";
1272
1273    var containerUtils = window.CQ && window.CQ.CoreComponents && window.CQ.CoreComponents.container && window.CQ.CoreComponents.container.utils ? window.CQ.CoreComponents.container.utils : undefined;
1274    if (!containerUtils) {
1275        // eslint-disable-next-line no-console
1276        console.warn("Tabs: container utilities at window.CQ.CoreComponents.container.utils are not available. This can lead to missing features. Ensure the core.wcm.components.commons.site.container client library is included on the page.");
1277    }
1278    var dataLayerEnabled;
1279    var dataLayer;
1280    var dataLayerName;
1281
1282    var NS = "cmp";
1283    var IS = "carousel";
1284
1285    var keyCodes = {
1286        SPACE: 32,
1287        END: 35,
1288        HOME: 36,
1289        ARROW_LEFT: 37,
1290        ARROW_UP: 38,
1291        ARROW_RIGHT: 39,
1292        ARROW_DOWN: 40
1293    };
1294
1295    var selectors = {
1296        self: "[data-" + NS + '-is="' + IS + '"]'
1297    };
1298
1299    var properties = {
1300        /**
1301         * Determines whether the Carousel will automatically transition between slides
1302         *
1303         * @memberof Carousel
1304         * @type {Boolean}
1305         * @default false
1306         */
1307        "autoplay": {
1308            "default": false,
1309            "transform": function(value) {
1310                return !(value === null || typeof value === "undefined");
1311            }
1312        },
1313        /**
1314         * Duration (in milliseconds) before automatically transitioning to the next slide
1315         *
1316         * @memberof Carousel
1317         * @type {Number}
1318         * @default 5000
1319         */
1320        "delay": {
1321            "default": 5000,
1322            "transform": function(value) {
1323                value = parseFloat(value);
1324                return !isNaN(value) ? value : null;
1325            }
1326        },
1327        /**
1328         * Determines whether automatic pause on hovering the carousel is disabled
1329         *
1330         * @memberof Carousel
1331         * @type {Boolean}
1332         * @default false
1333         */
1334        "autopauseDisabled": {
1335            "default": false,
1336            "transform": function(value) {
1337                return !(value === null || typeof value === "undefined");
1338            }
1339        }
1340    };
1341
1342    /**
1343     * Carousel Configuration
1344     *
1345     * @typedef {Object} CarouselConfig Represents a Carousel configuration
1346     * @property {HTMLElement} element The HTMLElement representing the Carousel
1347     * @property {*[]} options The Carousel options
1348     */
1349
1350    /**
1351     * Carousel
1352     *
1353     * @class Carousel
1354     * @classdesc An interactive Carousel component for navigating a list of generic items
1355     * @param {CarouselConfig} config The Carousel configuration
1356     */
1357    function Carousel(config) {
1358        var that = this;
1359
1360        if (config && config.element) {
1361            init(config);
1362        }
1363
1364        /**
1365         * Initializes the Carousel
1366         *
1367         * @private
1368         * @param {CarouselConfig} config The Carousel configuration
1369         */
1370        function init(config) {
1371            that._config = config;
1372
1373            // prevents multiple initialization
1374            config.element.removeAttribute("data-" + NS + "-is");
1375
1376            setupProperties(config.options);
1377            cacheElements(config.element);
1378
1379            that._active = 0;
1380            that._paused = false;
1381
1382            if (that._elements.item) {
1383                initializeActive();
1384                bindEvents();
1385                resetAutoplayInterval();
1386                refreshPlayPauseActions();
1387                scrollToDeepLinkIdInCarousel();
1388            }
1389
1390            // TODO: This section is only relevant in edit mode and should move to the editor clientLib
1391            if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
1392                /*
1393                 * Editor message handling:
1394                 * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
1395                 * - check that the message data panel container type is correct and that the id (path) matches this specific Carousel component
1396                 * - if so, route the "navigate" operation to enact a navigation of the Carousel based on index data
1397                 */
1398                window.CQ = window.CQ || {};
1399                window.CQ.CoreComponents = window.CQ.CoreComponents || {};
1400                window.CQ.CoreComponents.MESSAGE_CHANNEL = window.CQ.CoreComponents.MESSAGE_CHANNEL || new window.Granite.author.MessageChannel("cqauthor", window);
1401                window.CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage("cmp.panelcontainer", function(message) {
1402                    if (message.data && message.data.type === "cmp-carousel" && message.data.id === that._elements.self.dataset["cmpPanelcontainerId"]) {
1403                        if (message.data.operation === "navigate") {
1404                            navigate(message.data.index);
1405                        }
1406                    }
1407                });
1408            }
1409        }
1410
1411        /**
1412         * Displays the slide containing the element that corresponds to the deep link in the URI fragment
1413         * and scrolls the browser to this element.
1414         */
1415        function scrollToDeepLinkIdInCarousel() {
1416            if (containerUtils) {
1417                var deepLinkItemIdx = containerUtils.getDeepLinkItemIdx(that, "item", "item");
1418                if (deepLinkItemIdx > -1) {
1419                    var deepLinkItem = that._elements["item"][deepLinkItemIdx];
1420                    if (deepLinkItem && that._elements["item"][that._active].id !== deepLinkItem.id) {
1421                        navigateAndFocusIndicator(deepLinkItemIdx, true);
1422                        // pause the carousel auto-rotation
1423                        pause();
1424                    }
1425                    var hashId = window.location.hash.substring(1);
1426                    if (hashId) {
1427                        var hashItem = document.querySelector("[id='" + hashId + "']");
1428                        if (hashItem) {
1429                            hashItem.scrollIntoView();
1430                        }
1431                    }
1432                }
1433            }
1434        }
1435
1436        /**
1437         * Caches the Carousel elements as defined via the {@code data-carousel-hook="ELEMENT_NAME"} markup API
1438         *
1439         * @private
1440         * @param {HTMLElement} wrapper The Carousel wrapper element
1441         */
1442        function cacheElements(wrapper) {
1443            that._elements = {};
1444            that._elements.self = wrapper;
1445            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
1446
1447            for (var i = 0; i < hooks.length; i++) {
1448                var hook = hooks[i];
1449                var capitalized = IS;
1450                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
1451                var key = hook.dataset[NS + "Hook" + capitalized];
1452                if (that._elements[key]) {
1453                    if (!Array.isArray(that._elements[key])) {
1454                        var tmp = that._elements[key];
1455                        that._elements[key] = [tmp];
1456                    }
1457                    that._elements[key].push(hook);
1458                } else {
1459                    that._elements[key] = hook;
1460                }
1461            }
1462        }
1463
1464        /**
1465         * Sets up properties for the Carousel based on the passed options.
1466         *
1467         * @private
1468         * @param {Object} options The Carousel options
1469         */
1470        function setupProperties(options) {
1471            that._properties = {};
1472
1473            for (var key in properties) {
1474                if (Object.prototype.hasOwnProperty.call(properties, key)) {
1475                    var property = properties[key];
1476                    var value = null;
1477
1478                    if (options && options[key] != null) {
1479                        value = options[key];
1480
1481                        // transform the provided option
1482                        if (property && typeof property.transform === "function") {
1483                            value = property.transform(value);
1484                        }
1485                    }
1486
1487                    if (value === null) {
1488                        // value still null, take the property default
1489                        value = properties[key]["default"];
1490                    }
1491
1492                    that._properties[key] = value;
1493                }
1494            }
1495        }
1496
1497        /**
1498         * Binds Carousel event handling
1499         *
1500         * @private
1501         */
1502        function bindEvents() {
1503            window.addEventListener("hashchange", scrollToDeepLinkIdInCarousel, false);
1504            if (that._elements["previous"]) {
1505                that._elements["previous"].addEventListener("click", function() {
1506                    var index = getPreviousIndex();
1507                    navigate(index);
1508                    if (dataLayerEnabled) {
1509                        dataLayer.push({
1510                            event: "cmp:show",
1511                            eventInfo: {
1512                                path: "component." + getDataLayerId(that._elements.item[index])
1513                            }
1514                        });
1515                    }
1516                });
1517            }
1518
1519            if (that._elements["next"]) {
1520                that._elements["next"].addEventListener("click", function() {
1521                    var index = getNextIndex();
1522                    navigate(index);
1523                    if (dataLayerEnabled) {
1524                        dataLayer.push({
1525                            event: "cmp:show",
1526                            eventInfo: {
1527                                path: "component." + getDataLayerId(that._elements.item[index])
1528                            }
1529                        });
1530                    }
1531                });
1532            }
1533
1534            var indicators = that._elements["indicator"];
1535            if (indicators) {
1536                for (var i = 0; i < indicators.length; i++) {
1537                    (function(index) {
1538                        indicators[i].addEventListener("click", function(event) {
1539                            navigateAndFocusIndicator(index);
1540                            // pause the carousel auto-rotation
1541                            pause();
1542                        });
1543                    })(i);
1544                }
1545            }
1546
1547            if (that._elements["pause"]) {
1548                if (that._properties.autoplay) {
1549                    that._elements["pause"].addEventListener("click", onPauseClick);
1550                }
1551            }
1552
1553            if (that._elements["play"]) {
1554                if (that._properties.autoplay) {
1555                    that._elements["play"].addEventListener("click", onPlayClick);
1556                }
1557            }
1558
1559            that._elements.self.addEventListener("keydown", onKeyDown);
1560
1561            if (!that._properties.autopauseDisabled) {
1562                that._elements.self.addEventListener("mouseenter", onMouseEnter);
1563                that._elements.self.addEventListener("mouseleave", onMouseLeave);
1564            }
1565
1566            // for accessibility we pause animation when a element get focused
1567            var items = that._elements["item"];
1568            if (items) {
1569                for (var j = 0; j < items.length; j++) {
1570                    items[j].addEventListener("focusin", onMouseEnter);
1571                    items[j].addEventListener("focusout", onMouseLeave);
1572                }
1573            }
1574        }
1575
1576        /**
1577         * Handles carousel keydown events
1578         *
1579         * @private
1580         * @param {Object} event The keydown event
1581         */
1582        function onKeyDown(event) {
1583            var index = that._active;
1584            var lastIndex = that._elements["indicator"].length - 1;
1585
1586            switch (event.keyCode) {
1587                case keyCodes.ARROW_LEFT:
1588                case keyCodes.ARROW_UP:
1589                    event.preventDefault();
1590                    if (index > 0) {
1591                        navigateAndFocusIndicator(index - 1);
1592                    }
1593                    break;
1594                case keyCodes.ARROW_RIGHT:
1595                case keyCodes.ARROW_DOWN:
1596                    event.preventDefault();
1597                    if (index < lastIndex) {
1598                        navigateAndFocusIndicator(index + 1);
1599                    }
1600                    break;
1601                case keyCodes.HOME:
1602                    event.preventDefault();
1603                    navigateAndFocusIndicator(0);
1604                    break;
1605                case keyCodes.END:
1606                    event.preventDefault();
1607                    navigateAndFocusIndicator(lastIndex);
1608                    break;
1609                case keyCodes.SPACE:
1610                    if (that._properties.autoplay && (event.target !== that._elements["previous"] && event.target !== that._elements["next"])) {
1611                        event.preventDefault();
1612                        if (!that._paused) {
1613                            pause();
1614                        } else {
1615                            play();
1616                        }
1617                    }
1618                    if (event.target === that._elements["pause"]) {
1619                        that._elements["play"].focus();
1620                    }
1621                    if (event.target === that._elements["play"]) {
1622                        that._elements["pause"].focus();
1623                    }
1624                    break;
1625                default:
1626                    return;
1627            }
1628        }
1629
1630        /**
1631         * Handles carousel mouseenter events
1632         *
1633         * @private
1634         * @param {Object} event The mouseenter event
1635         */
1636        function onMouseEnter(event) {
1637            clearAutoplayInterval();
1638        }
1639
1640        /**
1641         * Handles carousel mouseleave events
1642         *
1643         * @private
1644         * @param {Object} event The mouseleave event
1645         */
1646        function onMouseLeave(event) {
1647            resetAutoplayInterval();
1648        }
1649
1650        /**
1651         * Handles pause element click events
1652         *
1653         * @private
1654         * @param {Object} event The click event
1655         */
1656        function onPauseClick(event) {
1657            pause();
1658            that._elements["play"].focus();
1659        }
1660
1661        /**
1662         * Handles play element click events
1663         *
1664         * @private
1665         * @param {Object} event The click event
1666         */
1667        function onPlayClick() {
1668            play();
1669            that._elements["pause"].focus();
1670        }
1671
1672        /**
1673         * Pauses the playing of the Carousel. Sets {@code Carousel#_paused} marker.
1674         * Only relevant when autoplay is enabled
1675         *
1676         * @private
1677         */
1678        function pause() {
1679            that._paused = true;
1680            clearAutoplayInterval();
1681            refreshPlayPauseActions();
1682        }
1683
1684        /**
1685         * Enables the playing of the Carousel. Sets {@code Carousel#_paused} marker.
1686         * Only relevant when autoplay is enabled
1687         *
1688         * @private
1689         */
1690        function play() {
1691            that._paused = false;
1692
1693            // If the Carousel is hovered, don't begin auto transitioning until the next mouse leave event
1694            var hovered = false;
1695            if (that._elements.self.parentElement) {
1696                hovered = that._elements.self.parentElement.querySelector(":hover") === that._elements.self;
1697            }
1698            if (that._properties.autopauseDisabled || !hovered) {
1699                resetAutoplayInterval();
1700            }
1701
1702            refreshPlayPauseActions();
1703        }
1704
1705        /**
1706         * Refreshes the play/pause action markup based on the {@code Carousel#_paused} state
1707         *
1708         * @private
1709         */
1710        function refreshPlayPauseActions() {
1711            setActionDisabled(that._elements["pause"], that._paused);
1712            setActionDisabled(that._elements["play"], !that._paused);
1713        }
1714
1715        /**
1716         * Initialize {@code Carousel#_active} based on the active item of the carousel.
1717         */
1718        function initializeActive() {
1719            var items = that._elements["item"];
1720            if (items && Array.isArray(items)) {
1721                for (var i = 0; i < items.length; i++) {
1722                    if (items[i].classList.contains("cmp-carousel__item--active")) {
1723                        that._active = i;
1724                        break;
1725                    }
1726                }
1727            }
1728        }
1729
1730        /**
1731         * Refreshes the item markup based on the current {@code Carousel#_active} index
1732         *
1733         * @private
1734         */
1735        function refreshActive() {
1736            var items = that._elements["item"];
1737            var indicators = that._elements["indicator"];
1738
1739            if (items) {
1740                if (Array.isArray(items)) {
1741                    for (var i = 0; i < items.length; i++) {
1742                        if (i === parseInt(that._active)) {
1743                            items[i].classList.add("cmp-carousel__item--active");
1744                            items[i].removeAttribute("aria-hidden");
1745                            indicators[i].classList.add("cmp-carousel__indicator--active");
1746                            indicators[i].setAttribute("aria-selected", true);
1747                            indicators[i].setAttribute("tabindex", "0");
1748                        } else {
1749                            items[i].classList.remove("cmp-carousel__item--active");
1750                            items[i].setAttribute("aria-hidden", true);
1751                            indicators[i].classList.remove("cmp-carousel__indicator--active");
1752                            indicators[i].setAttribute("aria-selected", false);
1753                            indicators[i].setAttribute("tabindex", "-1");
1754                        }
1755                    }
1756                } else {
1757                    // only one item
1758                    items.classList.add("cmp-carousel__item--active");
1759                    indicators.classList.add("cmp-carousel__indicator--active");
1760                }
1761            }
1762        }
1763
1764        /**
1765         * Focuses the element and prevents scrolling the element into view
1766         *
1767         * @param {HTMLElement} element Element to focus
1768         */
1769        function focusWithoutScroll(element) {
1770            var x = window.scrollX || window.pageXOffset;
1771            var y = window.scrollY || window.pageYOffset;
1772            element.focus();
1773            window.scrollTo(x, y);
1774        }
1775
1776        /**
1777         * Retrieves the next active index, with looping
1778         *
1779         * @private
1780         * @returns {Number} Index of the next carousel item
1781         */
1782        function getNextIndex() {
1783            return that._active === (that._elements["item"].length - 1) ? 0 : that._active + 1;
1784        }
1785
1786        /**
1787         * Retrieves the previous active index, with looping
1788         *
1789         * @private
1790         * @returns {Number} Index of the previous carousel item
1791         */
1792        function getPreviousIndex() {
1793            return that._active === 0 ? (that._elements["item"].length - 1) : that._active - 1;
1794        }
1795
1796        /**
1797         * Navigates to the item at the provided index
1798         *
1799         * @private
1800         * @param {Number} index The index of the item to navigate to
1801         * @param {Boolean} keepHash true to keep the hash in the URL, false to update it
1802         */
1803        function navigate(index, keepHash) {
1804            if (index < 0 || index > (that._elements["item"].length - 1)) {
1805                return;
1806            }
1807
1808            that._active = index;
1809            refreshActive();
1810
1811            if (!keepHash && containerUtils) {
1812                containerUtils.updateUrlHash(that, "item", index);
1813            }
1814
1815            if (dataLayerEnabled) {
1816                var carouselId = that._elements.self.id;
1817                var activeItem = getDataLayerId(that._elements.item[index]);
1818                var updatePayload = { component: {} };
1819                updatePayload.component[carouselId] = { shownItems: [activeItem] };
1820
1821                var removePayload = { component: {} };
1822                removePayload.component[carouselId] = { shownItems: undefined };
1823
1824                dataLayer.push(removePayload);
1825                dataLayer.push(updatePayload);
1826            }
1827
1828            // reset the autoplay transition interval following navigation, if not already hovering the carousel
1829            if (that._elements.self.parentElement) {
1830                if (that._elements.self.parentElement.querySelector(":hover") !== that._elements.self) {
1831                    resetAutoplayInterval();
1832                }
1833            }
1834        }
1835
1836        /**
1837         * Navigates to the item at the provided index and ensures the active indicator gains focus
1838         *
1839         * @private
1840         * @param {Number} index The index of the item to navigate to
1841         * @param {Boolean} keepHash true to keep the hash in the URL, false to update it
1842         */
1843        function navigateAndFocusIndicator(index, keepHash) {
1844            navigate(index, keepHash);
1845            focusWithoutScroll(that._elements["indicator"][index]);
1846
1847            if (dataLayerEnabled) {
1848                dataLayer.push({
1849                    event: "cmp:show",
1850                    eventInfo: {
1851                        path: "component." + getDataLayerId(that._elements.item[index])
1852                    }
1853                });
1854            }
1855        }
1856
1857        /**
1858         * Starts/resets automatic slide transition interval
1859         *
1860         * @private
1861         */
1862        function resetAutoplayInterval() {
1863            if (that._paused || !that._properties.autoplay) {
1864                return;
1865            }
1866            clearAutoplayInterval();
1867            that._autoplayIntervalId = window.setInterval(function() {
1868                if (document.visibilityState && document.hidden) {
1869                    return;
1870                }
1871                var indicators = that._elements["indicators"];
1872                if (indicators !== document.activeElement && indicators.contains(document.activeElement)) {
1873                    // if an indicator has focus, ensure we switch focus following navigation
1874                    navigateAndFocusIndicator(getNextIndex(), true);
1875                } else {
1876                    navigate(getNextIndex(), true);
1877                }
1878            }, that._properties.delay);
1879        }
1880
1881        /**
1882         * Clears/pauses automatic slide transition interval
1883         *
1884         * @private
1885         */
1886        function clearAutoplayInterval() {
1887            window.clearInterval(that._autoplayIntervalId);
1888            that._autoplayIntervalId = null;
1889        }
1890
1891        /**
1892         * Sets the disabled state for an action and toggles the appropriate CSS classes
1893         *
1894         * @private
1895         * @param {HTMLElement} action Action to disable
1896         * @param {Boolean} [disable] {@code true} to disable, {@code false} to enable
1897         */
1898        function setActionDisabled(action, disable) {
1899            if (!action) {
1900                return;
1901            }
1902            if (disable !== false) {
1903                action.disabled = true;
1904                action.classList.add("cmp-carousel__action--disabled");
1905            } else {
1906                action.disabled = false;
1907                action.classList.remove("cmp-carousel__action--disabled");
1908            }
1909        }
1910    }
1911
1912    /**
1913     * Parses the dataLayer string and returns the ID
1914     *
1915     * @private
1916     * @param {HTMLElement} item the accordion item
1917     * @returns {String} dataLayerId or undefined
1918     */
1919    function getDataLayerId(item) {
1920        if (item) {
1921            if (item.dataset.cmpDataLayer) {
1922                return Object.keys(JSON.parse(item.dataset.cmpDataLayer))[0];
1923            } else {
1924                return item.id;
1925            }
1926        }
1927        return null;
1928    }
1929
1930    /**
1931     * Document ready handler and DOM mutation observers. Initializes Carousel components as necessary.
1932     *
1933     * @private
1934     */
1935    function onDocumentReady() {
1936        dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
1937        if (dataLayerEnabled) {
1938            dataLayerName = document.body.getAttribute("data-cmp-data-layer-name") || "adobeDataLayer";
1939            dataLayer = window[dataLayerName] = window[dataLayerName] || [];
1940        }
1941
1942        var elements = document.querySelectorAll(selectors.self);
1943        for (var i = 0; i < elements.length; i++) {
1944            new Carousel({ element: elements[i], options: CMP.utils.readData(elements[i], IS) });
1945        }
1946
1947        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
1948        var body = document.querySelector("body");
1949        var observer = new MutationObserver(function(mutations) {
1950            mutations.forEach(function(mutation) {
1951                // needed for IE
1952                var nodesArray = [].slice.call(mutation.addedNodes);
1953                if (nodesArray.length > 0) {
1954                    nodesArray.forEach(function(addedNode) {
1955                        if (addedNode.querySelectorAll) {
1956                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
1957                            elementsArray.forEach(function(element) {
1958                                new Carousel({ element: element, options: CMP.utils.readData(element, IS) });
1959                            });
1960                        }
1961                    });
1962                }
1963            });
1964        });
1965
1966        observer.observe(body, {
1967            subtree: true,
1968            childList: true,
1969            characterData: true
1970        });
1971    }
1972
1973    var documentReady = document.readyState !== "loading" ? Promise.resolve() : new Promise(function(resolve) {
1974        document.addEventListener("DOMContentLoaded", resolve);
1975    });
1976    Promise.all([documentReady]).then(onDocumentReady);
1977
1978    if (containerUtils) {
1979        window.addEventListener("load", containerUtils.scrollToAnchor, false);
1980    }
1981
1982}());
1983
1984/*******************************************************************************
1985 * Copyright 2017 Adobe
1986 *
1987 * Licensed under the Apache License, Version 2.0 (the "License");
1988 * you may not use this file except in compliance with the License.
1989 * You may obtain a copy of the License at
1990 *
1991 *     http://www.apache.org/licenses/LICENSE-2.0
1992 *
1993 * Unless required by applicable law or agreed to in writing, software
1994 * distributed under the License is distributed on an "AS IS" BASIS,
1995 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1996 * See the License for the specific language governing permissions and
1997 * limitations under the License.
1998 ******************************************************************************/
1999if (window.Element && !Element.prototype.closest) {
2000    // eslint valid-jsdoc: "off"
2001    Element.prototype.closest =
2002        function(s) {
2003            "use strict";
2004            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
2005            var el      = this;
2006            var i;
2007            do {
2008                i = matches.length;
2009                while (--i >= 0 && matches.item(i) !== el) {
2010                    // continue
2011                }
2012            } while ((i < 0) && (el = el.parentElement));
2013            return el;
2014        };
2015}
2016
2017if (window.Element && !Element.prototype.matches) {
2018    Element.prototype.matches =
2019        Element.prototype.matchesSelector ||
2020        Element.prototype.mozMatchesSelector ||
2021        Element.prototype.msMatchesSelector ||
2022        Element.prototype.oMatchesSelector ||
2023        Element.prototype.webkitMatchesSelector ||
2024        function(s) {
2025            "use strict";
2026            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
2027            var i       = matches.length;
2028            while (--i >= 0 && matches.item(i) !== this) {
2029                // continue
2030            }
2031            return i > -1;
2032        };
2033}
2034
2035if (!Object.assign) {
2036    Object.assign = function(target, varArgs) { // .length of function is 2
2037        "use strict";
2038        if (target === null) {
2039            throw new TypeError("Cannot convert undefined or null to object");
2040        }
2041
2042        var to = Object(target);
2043
2044        for (var index = 1; index < arguments.length; index++) {
2045            var nextSource = arguments[index];
2046
2047            if (nextSource !== null) {
2048                for (var nextKey in nextSource) {
2049                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
2050                        to[nextKey] = nextSource[nextKey];
2051                    }
2052                }
2053            }
2054        }
2055        return to;
2056    };
2057}
2058
2059(function(arr) {
2060    "use strict";
2061    arr.forEach(function(item) {
2062        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
2063            return;
2064        }
2065        Object.defineProperty(item, "remove", {
2066            configurable: true,
2067            enumerable: true,
2068            writable: true,
2069            value: function remove() {
2070                this.parentNode.removeChild(this);
2071            }
2072        });
2073    });
2074})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
2075
2076/*******************************************************************************
2077 * Copyright 2022 Adobe
2078 *
2079 * Licensed under the Apache License, Version 2.0 (the "License");
2080 * you may not use this file except in compliance with the License.
2081 * You may obtain a copy of the License at
2082 *
2083 *     http://www.apache.org/licenses/LICENSE-2.0
2084 *
2085 * Unless required by applicable law or agreed to in writing, software
2086 * distributed under the License is distributed on an "AS IS" BASIS,
2087 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2088 * See the License for the specific language governing permissions and
2089 * limitations under the License.
2090 ******************************************************************************/
2091(function(document) {
2092    "use strict";
2093
2094    window.CMP = window.CMP || {};
2095    window.CMP.utils = (function() {
2096        var NS = "cmp";
2097
2098        /**
2099         * Reads options data from the Component wrapper element, defined via {@code data-cmp-*} data attributes
2100         *
2101         * @param {HTMLElement} element The component element to read options data from
2102         * @param {String} is The component identifier
2103         * @returns {String[]} The options read from the component data attributes
2104         */
2105        var readData = function(element, is) {
2106            var data = element.dataset;
2107            var options = [];
2108            var capitalized = is;
2109            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
2110            var reserved = ["is", "hook" + capitalized];
2111
2112            for (var key in data) {
2113                if (Object.prototype.hasOwnProperty.call(data, key)) {
2114                    var value = data[key];
2115
2116                    if (key.indexOf(NS) === 0) {
2117                        key = key.slice(NS.length);
2118                        key = key.charAt(0).toLowerCase() + key.substring(1);
2119
2120                        if (reserved.indexOf(key) === -1) {
2121                            options[key] = value;
2122                        }
2123                    }
2124                }
2125            }
2126            return options;
2127        };
2128
2129        /**
2130         * Set up the final properties of a component by evaluating the transform function or fall back to the default value on demand
2131         * @param {String[]} options the options to transform
2132         * @param {Object} properties object of properties of property functions
2133         * @returns {Object} transformed properties
2134         */
2135        var setupProperties = function(options, properties) {
2136            var transformedProperties = {};
2137
2138            for (var key in properties) {
2139                if (Object.prototype.hasOwnProperty.call(properties, key)) {
2140                    var property = properties[key];
2141                    if (options && options[key] != null) {
2142                        if (property && typeof property.transform === "function") {
2143                            transformedProperties[key] = property.transform(options[key]);
2144                        } else {
2145                            transformedProperties[key] = options[key];
2146                        }
2147                    } else {
2148                        transformedProperties[key] = properties[key]["default"];
2149                    }
2150                }
2151            }
2152            return transformedProperties;
2153        };
2154
2155
2156        return {
2157            readData: readData,
2158            setupProperties: setupProperties
2159        };
2160    }());
2161}(window.document));
2162
2163/*******************************************************************************
2164 * Copyright 2022 Adobe
2165 *
2166 * Licensed under the Apache License, Version 2.0 (the "License");
2167 * you may not use this file except in compliance with the License.
2168 * You may obtain a copy of the License at
2169 *
2170 *     http://www.apache.org/licenses/LICENSE-2.0
2171 *
2172 * Unless required by applicable law or agreed to in writing, software
2173 * distributed under the License is distributed on an "AS IS" BASIS,
2174 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2175 * See the License for the specific language governing permissions and
2176 * limitations under the License.
2177 ******************************************************************************/
2178(function(document) {
2179    "use strict";
2180
2181    window.CMP = window.CMP || {};
2182    window.CMP.image = window.CMP.image || {};
2183    window.CMP.image.dynamicMedia = (function() {
2184        var autoSmartCrops = {};
2185        var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
2186        var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
2187        var SRC_URI_DPR_OFF = "dpr=off";
2188        var SRC_URI_DPR_ON = "dpr=on,{dpr}";
2189        var dpr = window.devicePixelRatio || 1;
2190        var config = {
2191            minWidth: 20
2192        };
2193
2194        /**
2195         * get auto smart crops from dm
2196         * @param {String} src the src uri
2197         * @returns {{}} the smart crop json object
2198         */
2199        var getAutoSmartCrops = function(src) {
2200            var request = new XMLHttpRequest();
2201            var url = src.split(SRC_URI_TEMPLATE_WIDTH_VAR)[0] + "?req=set,json";
2202            request.open("GET", url, false);
2203            request.onload = function() {
2204                if (request.status >= 200 && request.status < 400) {
2205                    // success status
2206                    var responseText = request.responseText;
2207                    var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
2208                    var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
2209                    var resPayload = rePayload.exec(responseText);
2210                    var payload;
2211                    if (resPayload) {
2212                        var payloadStr = resPayload[2];
2213                        if (rePayloadJSON.test(payloadStr)) {
2214                            payload = JSON.parse(payloadStr);
2215                        }
2216
2217                    }
2218                    // check "relation" - only in case of smartcrop preset
2219                    if (payload && payload.set.relation && payload.set.relation.length > 0) {
2220                        for (var i = 0; i < payload.set.relation.length; i++) {
2221                            autoSmartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
2222                                ":" + payload.set.relation[i].userdata.SmartCropDef;
2223                        }
2224                    }
2225                } else {
2226                    // error status
2227                }
2228            };
2229            request.send();
2230            return autoSmartCrops;
2231        };
2232
2233        /**
2234         * Build and return the srcset value based on the available auto smart crops
2235         * @param {String} src the src uri
2236         * @param {Object} smartCrops the smart crops object
2237         * @returns {String} the srcset
2238         */
2239        var getSrcSet = function(src, smartCrops) {
2240            var srcset;
2241            var keys = Object.keys(smartCrops);
2242            if (keys.length > 0) {
2243                srcset = [];
2244                for (var key in autoSmartCrops) {
2245                    srcset.push(src.replace(SRC_URI_TEMPLATE_WIDTH_VAR, smartCrops[key]) + " " + key + "w");
2246                }
2247            }
2248            return  srcset.join(",");
2249        };
2250
2251        /**
2252         * Get the optimal width based on the available sizes
2253         * @param {[Number]} sizes the available sizes
2254         * @param {Number} width the element width
2255         * @returns {String} the optimal width
2256         */
2257        function getOptimalWidth(sizes, width) {
2258            var len = sizes.length;
2259            var key = 0;
2260
2261            while ((key < len - 1) && (sizes[key] < width)) {
2262                key++;
2263            }
2264
2265            return sizes[key] !== undefined ? sizes[key].toString() : width;
2266        }
2267
2268        /**
2269         * Get the width of an element or parent element if the width is smaller than the minimum width
2270         * @param {HTMLElement} component the image component
2271         * @param {HTMLElement | Node} parent the parent element
2272         * @returns {Number} the width of the element
2273         */
2274        var getWidth = function(component, parent) {
2275            var width = component.offsetWidth;
2276            while (width < config.minWidth && parent && !component._autoWidth) {
2277                width =  parent.offsetWidth;
2278                parent = parent.parentNode;
2279            }
2280            return width;
2281        };
2282
2283        /**
2284         * Set the src and srcset attribute for a Dynamic Media Image which auto smart crops enabled.
2285         * @param {HTMLElement} component the image component
2286         * @param {{}} properties the component properties
2287         */
2288        var setDMAttributes = function(component, properties) {
2289            // for v3 we first have to turn the dpr on
2290            var src = properties.src.replace(SRC_URI_DPR_OFF, SRC_URI_DPR_ON);
2291            src = src.replace(SRC_URI_TEMPLATE_DPR_VAR, dpr);
2292            var smartCrops = {};
2293            var width;
2294            if (properties["smartcroprendition"] === "SmartCrop:Auto") {
2295                smartCrops = getAutoSmartCrops(src);
2296            }
2297            var hasWidths = (properties.widths && properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
2298            if (hasWidths) {
2299                var image = component.querySelector("img");
2300                var elemWidth = getWidth(component, component.parentNode);
2301                if (properties["smartcroprendition"] === "SmartCrop:Auto") {
2302                    image.setAttribute("srcset", CMP.image.dynamicMedia.getSrcSet(src, smartCrops));
2303                    width = getOptimalWidth(Object.keys(smartCrops, elemWidth));
2304                    image.setAttribute("src", CMP.image.dynamicMedia.getSrc(src, smartCrops[width]));
2305                } else {
2306                    width = getOptimalWidth(properties.widths, elemWidth);
2307                    image.setAttribute("src", CMP.image.dynamicMedia.getSrc(src, width));
2308                }
2309            }
2310        };
2311
2312        /**
2313         * Get the src attribute based on the optimal width
2314         * @param {String} src the src uri
2315         * @param {String} width the element width
2316         * @returns {String} the final src attribute
2317         */
2318        var getSrc = function(src, width) {
2319            if (src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR) > -1) {
2320                src = src.replace(SRC_URI_TEMPLATE_WIDTH_VAR, width);
2321            }
2322            return src;
2323        };
2324
2325
2326        return {
2327            getAutoSmartCrops: getAutoSmartCrops,
2328            getSrcSet: getSrcSet,
2329            getSrc: getSrc,
2330            setDMAttributes: setDMAttributes,
2331            getWidth: getWidth
2332        };
2333    }());
2334    document.dispatchEvent(new CustomEvent("core.wcm.components.commons.site.image.dynamic-media.loaded"));
2335}(window.document));
2336
2337/*******************************************************************************
2338 * Copyright 2016 Adobe
2339 *
2340 * Licensed under the Apache License, Version 2.0 (the "License");
2341 * you may not use this file except in compliance with the License.
2342 * You may obtain a copy of the License at
2343 *
2344 *     http://www.apache.org/licenses/LICENSE-2.0
2345 *
2346 * Unless required by applicable law or agreed to in writing, software
2347 * distributed under the License is distributed on an "AS IS" BASIS,
2348 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2349 * See the License for the specific language governing permissions and
2350 * limitations under the License.
2351 ******************************************************************************/
2352(function() {
2353    "use strict";
2354
2355    var NS = "cmp";
2356    var IS = "image";
2357
2358    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
2359    var LAZY_THRESHOLD_DEFAULT = 0;
2360    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
2361    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
2362    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
2363
2364    var selectors = {
2365        self: "[data-" + NS + '-is="' + IS + '"]',
2366        image: '[data-cmp-hook-image="image"]',
2367        map: '[data-cmp-hook-image="map"]',
2368        area: '[data-cmp-hook-image="area"]'
2369    };
2370
2371    var lazyLoader = {
2372        "cssClass": "cmp-image__image--is-loading",
2373        "style": {
2374            "height": 0,
2375            "padding-bottom": "" // will be replaced with % ratio
2376        }
2377    };
2378
2379    var properties = {
2380        /**
2381         * An array of alternative image widths (in pixels).
2382         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
2383         *
2384         * @memberof Image
2385         * @type {Number[]}
2386         * @default []
2387         */
2388        "widths": {
2389            "default": [],
2390            "transform": function(value) {
2391                var widths = [];
2392                value.split(",").forEach(function(item) {
2393                    item = parseFloat(item);
2394                    if (!isNaN(item)) {
2395                        widths.push(item);
2396                    }
2397                });
2398                return widths;
2399            }
2400        },
2401        /**
2402         * Indicates whether the image should be rendered lazily.
2403         *
2404         * @memberof Image
2405         * @type {Boolean}
2406         * @default false
2407         */
2408        "lazy": {
2409            "default": false,
2410            "transform": function(value) {
2411                return !(value === null || typeof value === "undefined");
2412            }
2413        },
2414        /**
2415         * Indicates image is DynamicMedia image.
2416         *
2417         * @memberof Image
2418         * @type {Boolean}
2419         * @default false
2420         */
2421        "dmimage": {
2422            "default": false,
2423            "transform": function(value) {
2424                return !(value === null || typeof value === "undefined");
2425            }
2426        },
2427        /**
2428         * The lazy threshold.
2429         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
2430         * to load.
2431         *
2432         * @memberof Image
2433         * @type {Number}
2434         * @default 0
2435         */
2436        "lazythreshold": {
2437            "default": 0,
2438            "transform": function(value) {
2439                var val =  parseInt(value);
2440                if (isNaN(val)) {
2441                    return LAZY_THRESHOLD_DEFAULT;
2442                }
2443                return val;
2444            }
2445        },
2446        /**
2447         * The image source.
2448         *
2449         * Can be a simple image source, or a URI template representation that
2450         * can be variable expanded - useful for building an image configuration with an alternative width.
2451         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
2452         *
2453         * @memberof Image
2454         * @type {String}
2455         */
2456        "src": {
2457            "transform": function(value) {
2458                return decodeURIComponent(value);
2459            }
2460        }
2461    };
2462
2463    var devicePixelRatio = window.devicePixelRatio || 1;
2464
2465    function Image(config) {
2466        var that = this;
2467
2468        var smartCrops = {};
2469
2470        var useAssetDelivery = false;
2471        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
2472
2473        function init(config) {
2474            // prevents multiple initialization
2475            config.element.removeAttribute("data-" + NS + "-is");
2476
2477            // check if asset delivery is used
2478            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
2479                useAssetDelivery = true;
2480                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
2481            }
2482
2483            that._properties = CMP.utils.setupProperties(config.options, properties);
2484            cacheElements(config.element);
2485            // check image is DM asset; if true try to make req=set
2486            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
2487                smartCrops = CMP.image.dynamicMedia.getAutoSmartCrops(config.options.src);
2488            }
2489
2490            if (!that._elements.noscript) {
2491                return;
2492            }
2493
2494            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
2495
2496            unwrapNoScript();
2497
2498            if (that._properties.lazy) {
2499                addLazyLoader();
2500            }
2501
2502            if (that._elements.map) {
2503                that._elements.image.addEventListener("load", onLoad);
2504            }
2505
2506            window.addEventListener("resize", onWindowResize);
2507            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
2508                document.addEventListener(name, that.update);
2509            });
2510
2511            that._elements.image.addEventListener("cmp-image-redraw", that.update);
2512
2513            that._interSectionObserver = new IntersectionObserver(function(entries, interSectionObserver) {
2514                entries.forEach(function(entry) {
2515                    if (entry.intersectionRatio > 0) {
2516                        that.update();
2517                    }
2518                });
2519            });
2520            that._interSectionObserver.observe(that._elements.self);
2521
2522            that.update();
2523        }
2524
2525        function loadImage() {
2526            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
2527            var replacement;
2528            if (Object.keys(smartCrops).length > 0) {
2529                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
2530                replacement = smartCrops[optimalWidth];
2531            } else {
2532                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
2533            }
2534            if (useAssetDelivery) {
2535                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
2536            }
2537            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
2538            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
2539
2540            var imgSrcAttribute = that._elements.image.getAttribute("src");
2541
2542            if (url !== imgSrcAttribute) {
2543                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
2544                    that._elements.image.setAttribute("src", url);
2545                } else {
2546                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
2547                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
2548                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
2549                    if (isImageRefSame && urlTemplateParts.length > 1) {
2550                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
2551                    }
2552                    if (isImageRefSame) {
2553                        that._elements.image.setAttribute("src", url);
2554                        if (!hasWidths) {
2555                            window.removeEventListener("scroll", that.update);
2556                        }
2557                    }
2558                }
2559            }
2560            if (that._lazyLoaderShowing) {
2561                that._elements.image.addEventListener("load", removeLazyLoader);
2562            }
2563            that._interSectionObserver.unobserve(that._elements.self);
2564        }
2565
2566        function getOptimalWidth(widths, useDevicePixelRatio) {
2567            var container = that._elements.self;
2568            var containerWidth = container.clientWidth;
2569            while (containerWidth === 0 && container.parentNode) {
2570                container = container.parentNode;
2571                containerWidth = container.clientWidth;
2572            }
2573
2574            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
2575            var optimalWidth = containerWidth * dpr;
2576            var len = widths.length;
2577            var key = 0;
2578
2579            while ((key < len - 1) && (widths[key] < optimalWidth)) {
2580                key++;
2581            }
2582
2583            return widths[key].toString();
2584        }
2585
2586        function addLazyLoader() {
2587            var width = that._elements.image.getAttribute("width");
2588            var height = that._elements.image.getAttribute("height");
2589
2590            if (width && height) {
2591                var ratio = (height / width) * 100;
2592                var styles = lazyLoader.style;
2593
2594                styles["padding-bottom"] = ratio + "%";
2595
2596                for (var s in styles) {
2597                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
2598                        that._elements.image.style[s] = styles[s];
2599                    }
2600                }
2601            }
2602            that._elements.image.setAttribute("src", EMPTY_PIXEL);
2603            that._elements.image.classList.add(lazyLoader.cssClass);
2604            that._lazyLoaderShowing = true;
2605        }
2606
2607        function unwrapNoScript() {
2608            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
2609            var parser = new DOMParser();
2610
2611            // temporary document avoids requesting the image before removing its src
2612            var temporaryDocument = parser.parseFromString(markup, "text/html");
2613            var imageElement = temporaryDocument.querySelector(selectors.image);
2614            imageElement.removeAttribute("src");
2615            that._elements.container.insertBefore(imageElement, that._elements.noscript);
2616
2617            var mapElement = temporaryDocument.querySelector(selectors.map);
2618            if (mapElement) {
2619                that._elements.container.insertBefore(mapElement, that._elements.noscript);
2620            }
2621
2622            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
2623            if (that._elements.container.matches(selectors.image)) {
2624                that._elements.image = that._elements.container;
2625            } else {
2626                that._elements.image = that._elements.container.querySelector(selectors.image);
2627            }
2628
2629            that._elements.map = that._elements.container.querySelector(selectors.map);
2630            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
2631        }
2632
2633        function removeLazyLoader() {
2634            that._elements.image.classList.remove(lazyLoader.cssClass);
2635            for (var property in lazyLoader.style) {
2636                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
2637                    that._elements.image.style[property] = "";
2638                }
2639            }
2640            that._elements.image.removeEventListener("load", removeLazyLoader);
2641            that._lazyLoaderShowing = false;
2642        }
2643
2644        function isLazyVisible() {
2645            if (that._elements.container.offsetParent === null) {
2646                return false;
2647            }
2648
2649            var wt = window.pageYOffset;
2650            var wb = wt + document.documentElement.clientHeight;
2651            var et = that._elements.container.getBoundingClientRect().top + wt;
2652            var eb = et + that._elements.container.clientHeight;
2653
2654            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
2655        }
2656
2657        function resizeAreas() {
2658            if (that._elements.areas && that._elements.areas.length > 0) {
2659                for (var i = 0; i < that._elements.areas.length; i++) {
2660                    var width = that._elements.image.width;
2661                    var height = that._elements.image.height;
2662
2663                    if (width && height) {
2664                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
2665                        if (relcoords) {
2666                            var relativeCoordinates = relcoords.split(",");
2667                            var coordinates = new Array(relativeCoordinates.length);
2668
2669                            for (var j = 0; j < coordinates.length; j++) {
2670                                if (j % 2 === 0) {
2671                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
2672                                } else {
2673                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
2674                                }
2675                            }
2676
2677                            that._elements.areas[i].coords = coordinates;
2678                        }
2679                    }
2680                }
2681            }
2682        }
2683
2684        function cacheElements(wrapper) {
2685            that._elements = {};
2686            that._elements.self = wrapper;
2687            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
2688
2689            for (var i = 0; i < hooks.length; i++) {
2690                var hook = hooks[i];
2691                var capitalized = IS;
2692                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
2693                var key = hook.dataset[NS + "Hook" + capitalized];
2694                that._elements[key] = hook;
2695            }
2696        }
2697
2698        function onWindowResize() {
2699            that.update();
2700            resizeAreas();
2701        }
2702
2703        function onLoad() {
2704            resizeAreas();
2705        }
2706
2707        that.update = function() {
2708            if (that._properties.lazy) {
2709                if (isLazyVisible()) {
2710                    loadImage();
2711                }
2712            } else {
2713                loadImage();
2714            }
2715        };
2716
2717        if (config && config.element) {
2718            init(config);
2719        }
2720    }
2721
2722    function onDocumentReady() {
2723        var elements = document.querySelectorAll(selectors.self);
2724        for (var i = 0; i < elements.length; i++) {
2725            new Image({ element: elements[i], options: CMP.utils.readData(elements[i], IS) });
2726        }
2727
2728        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
2729        var body             = document.querySelector("body");
2730        var observer         = new MutationObserver(function(mutations) {
2731            mutations.forEach(function(mutation) {
2732                // needed for IE
2733                var nodesArray = [].slice.call(mutation.addedNodes);
2734                if (nodesArray.length > 0) {
2735                    nodesArray.forEach(function(addedNode) {
2736                        if (addedNode.querySelectorAll) {
2737                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
2738                            elementsArray.forEach(function(element) {
2739                                new Image({ element: element, options: CMP.utils.readData(element, IS) });
2740                            });
2741                        }
2742                    });
2743                }
2744            });
2745        });
2746
2747        observer.observe(body, {
2748            subtree: true,
2749            childList: true,
2750            characterData: true
2751        });
2752    }
2753
2754    var documentReady = document.readyState !== "loading" ? Promise.resolve() : new Promise(function(resolve) {
2755        document.addEventListener("DOMContentLoaded", resolve);
2756    });
2757
2758    Promise.all([documentReady]).then(onDocumentReady);
2759    /*
2760        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
2761        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
2762     */
2763    function decodeNoscript(text) {
2764        text = text.replace(/&(amp;)*lt;/g, "<");
2765        text = text.replace(/&(amp;)*gt;/g, ">");
2766        return text;
2767    }
2768
2769})();
2770
2771/*******************************************************************************
2772 * Copyright 2017 Adobe
2773 *
2774 * Licensed under the Apache License, Version 2.0 (the "License");
2775 * you may not use this file except in compliance with the License.
2776 * You may obtain a copy of the License at
2777 *
2778 *     http://www.apache.org/licenses/LICENSE-2.0
2779 *
2780 * Unless required by applicable law or agreed to in writing, software
2781 * distributed under the License is distributed on an "AS IS" BASIS,
2782 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2783 * See the License for the specific language governing permissions and
2784 * limitations under the License.
2785 ******************************************************************************/
2786if (window.Element && !Element.prototype.closest) {
2787    // eslint valid-jsdoc: "off"
2788    Element.prototype.closest =
2789        function(s) {
2790            "use strict";
2791            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
2792            var el      = this;
2793            var i;
2794            do {
2795                i = matches.length;
2796                while (--i >= 0 && matches.item(i) !== el) {
2797                    // continue
2798                }
2799            } while ((i < 0) && (el = el.parentElement));
2800            return el;
2801        };
2802}
2803
2804if (window.Element && !Element.prototype.matches) {
2805    Element.prototype.matches =
2806        Element.prototype.matchesSelector ||
2807        Element.prototype.mozMatchesSelector ||
2808        Element.prototype.msMatchesSelector ||
2809        Element.prototype.oMatchesSelector ||
2810        Element.prototype.webkitMatchesSelector ||
2811        function(s) {
2812            "use strict";
2813            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
2814            var i       = matches.length;
2815            while (--i >= 0 && matches.item(i) !== this) {
2816                // continue
2817            }
2818            return i > -1;
2819        };
2820}
2821
2822if (!Object.assign) {
2823    Object.assign = function(target, varArgs) { // .length of function is 2
2824        "use strict";
2825        if (target === null) {
2826            throw new TypeError("Cannot convert undefined or null to object");
2827        }
2828
2829        var to = Object(target);
2830
2831        for (var index = 1; index < arguments.length; index++) {
2832            var nextSource = arguments[index];
2833
2834            if (nextSource !== null) {
2835                for (var nextKey in nextSource) {
2836                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
2837                        to[nextKey] = nextSource[nextKey];
2838                    }
2839                }
2840            }
2841        }
2842        return to;
2843    };
2844}
2845
2846(function(arr) {
2847    "use strict";
2848    arr.forEach(function(item) {
2849        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
2850            return;
2851        }
2852        Object.defineProperty(item, "remove", {
2853            configurable: true,
2854            enumerable: true,
2855            writable: true,
2856            value: function remove() {
2857                this.parentNode.removeChild(this);
2858            }
2859        });
2860    });
2861})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
2862
2863/*******************************************************************************
2864 * Copyright 2016 Adobe
2865 *
2866 * Licensed under the Apache License, Version 2.0 (the "License");
2867 * you may not use this file except in compliance with the License.
2868 * You may obtain a copy of the License at
2869 *
2870 *     http://www.apache.org/licenses/LICENSE-2.0
2871 *
2872 * Unless required by applicable law or agreed to in writing, software
2873 * distributed under the License is distributed on an "AS IS" BASIS,
2874 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2875 * See the License for the specific language governing permissions and
2876 * limitations under the License.
2877 ******************************************************************************/
2878(function() {
2879    "use strict";
2880
2881    var NS = "cmp";
2882    var IS = "image";
2883
2884    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
2885    var LAZY_THRESHOLD_DEFAULT = 0;
2886    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
2887    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
2888    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
2889
2890    var selectors = {
2891        self: "[data-" + NS + '-is="' + IS + '"]',
2892        image: '[data-cmp-hook-image="image"]',
2893        map: '[data-cmp-hook-image="map"]',
2894        area: '[data-cmp-hook-image="area"]'
2895    };
2896
2897    var lazyLoader = {
2898        "cssClass": "cmp-image__image--is-loading",
2899        "style": {
2900            "height": 0,
2901            "padding-bottom": "" // will be replaced with % ratio
2902        }
2903    };
2904
2905    var properties = {
2906        /**
2907         * An array of alternative image widths (in pixels).
2908         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
2909         *
2910         * @memberof Image
2911         * @type {Number[]}
2912         * @default []
2913         */
2914        "widths": {
2915            "default": [],
2916            "transform": function(value) {
2917                var widths = [];
2918                value.split(",").forEach(function(item) {
2919                    item = parseFloat(item);
2920                    if (!isNaN(item)) {
2921                        widths.push(item);
2922                    }
2923                });
2924                return widths;
2925            }
2926        },
2927        /**
2928         * Indicates whether the image should be rendered lazily.
2929         *
2930         * @memberof Image
2931         * @type {Boolean}
2932         * @default false
2933         */
2934        "lazy": {
2935            "default": false,
2936            "transform": function(value) {
2937                return !(value === null || typeof value === "undefined");
2938            }
2939        },
2940        /**
2941         * Indicates image is DynamicMedia image.
2942         *
2943         * @memberof Image
2944         * @type {Boolean}
2945         * @default false
2946         */
2947        "dmimage": {
2948            "default": false,
2949            "transform": function(value) {
2950                return !(value === null || typeof value === "undefined");
2951            }
2952        },
2953        /**
2954         * The lazy threshold.
2955         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
2956         * to load.
2957         *
2958         * @memberof Image
2959         * @type {Number}
2960         * @default 0
2961         */
2962        "lazythreshold": {
2963            "default": 0,
2964            "transform": function(value) {
2965                var val =  parseInt(value);
2966                if (isNaN(val)) {
2967                    return LAZY_THRESHOLD_DEFAULT;
2968                }
2969                return val;
2970            }
2971        },
2972        /**
2973         * The image source.
2974         *
2975         * Can be a simple image source, or a URI template representation that
2976         * can be variable expanded - useful for building an image configuration with an alternative width.
2977         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
2978         *
2979         * @memberof Image
2980         * @type {String}
2981         */
2982        "src": {
2983            "transform": function(value) {
2984                return decodeURIComponent(value);
2985            }
2986        }
2987    };
2988
2989    var devicePixelRatio = window.devicePixelRatio || 1;
2990
2991    function readData(element) {
2992        var data = element.dataset;
2993        var options = [];
2994        var capitalized = IS;
2995        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
2996        var reserved = ["is", "hook" + capitalized];
2997
2998        for (var key in data) {
2999            if (Object.prototype.hasOwnProperty.call(data, key)) {
3000                var value = data[key];
3001
3002                if (key.indexOf(NS) === 0) {
3003                    key = key.slice(NS.length);
3004                    key = key.charAt(0).toLowerCase() + key.substring(1);
3005
3006                    if (reserved.indexOf(key) === -1) {
3007                        options[key] = value;
3008                    }
3009                }
3010            }
3011        }
3012        return options;
3013    }
3014
3015    function Image(config) {
3016        var that = this;
3017
3018        var smartCrops = {};
3019
3020        var useAssetDelivery = false;
3021        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
3022
3023        function init(config) {
3024            // prevents multiple initialization
3025            config.element.removeAttribute("data-" + NS + "-is");
3026
3027            // check if asset delivery is used
3028            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
3029                useAssetDelivery = true;
3030                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
3031            }
3032
3033            setupProperties(config.options);
3034            cacheElements(config.element);
3035            // check image is DM asset; if true try to make req=set
3036            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
3037                var request = new XMLHttpRequest();
3038                var urlTemplatePart = decodeURIComponent(config.options.src).split(srcUriTemplateWidthVar)[0];
3039                var url = urlTemplatePart + (urlTemplatePart.indexOf("?") < 0 ? "?" : "") + "req=set,json";
3040
3041                request.open("GET", url, false);
3042                request.onload = function() {
3043                    if (request.status >= 200 && request.status < 400) {
3044                        // success status
3045                        var responseText = request.responseText;
3046                        var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
3047                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
3048                        var resPayload = rePayload.exec(responseText);
3049                        var payload;
3050                        if (resPayload) {
3051                            var payloadStr = resPayload[2];
3052                            if (rePayloadJSON.test(payloadStr)) {
3053                                payload = JSON.parse(payloadStr);
3054                            }
3055
3056                        }
3057                        // check "relation" - only in case of smartcrop preset
3058                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
3059                            for (var i = 0; i < payload.set.relation.length; i++) {
3060                                smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
3061                                    ":" + payload.set.relation[i].userdata.SmartCropDef;
3062                            }
3063                        }
3064                    } else {
3065                        // error status
3066                    }
3067                };
3068                request.send();
3069            }
3070
3071            if (!that._elements.noscript) {
3072                return;
3073            }
3074
3075            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
3076
3077            unwrapNoScript();
3078
3079            if (that._properties.lazy) {
3080                addLazyLoader();
3081            }
3082
3083            if (that._elements.map) {
3084                that._elements.image.addEventListener("load", onLoad);
3085            }
3086
3087            window.addEventListener("resize", onWindowResize);
3088            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
3089                document.addEventListener(name, that.update);
3090            });
3091
3092            that._elements.image.addEventListener("cmp-image-redraw", that.update);
3093            that.update();
3094        }
3095
3096        function loadImage() {
3097            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
3098            var replacement;
3099            if (Object.keys(smartCrops).length > 0) {
3100                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
3101                replacement = smartCrops[optimalWidth];
3102            } else {
3103                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
3104            }
3105            if (useAssetDelivery) {
3106                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
3107            }
3108            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
3109            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
3110
3111            var imgSrcAttribute = that._elements.image.getAttribute("src");
3112
3113            if (url !== imgSrcAttribute) {
3114                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
3115                    that._elements.image.setAttribute("src", url);
3116                } else {
3117                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
3118                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
3119                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
3120                    if (isImageRefSame && urlTemplateParts.length > 1) {
3121                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
3122                    }
3123                    if (isImageRefSame) {
3124                        that._elements.image.setAttribute("src", url);
3125                        if (!hasWidths) {
3126                            window.removeEventListener("scroll", that.update);
3127                        }
3128                    }
3129                }
3130            }
3131            if (that._lazyLoaderShowing) {
3132                that._elements.image.addEventListener("load", removeLazyLoader);
3133            }
3134        }
3135
3136        function getOptimalWidth(widths, useDevicePixelRatio) {
3137            var container = that._elements.self;
3138            var containerWidth = container.clientWidth;
3139            while (containerWidth === 0 && container.parentNode) {
3140                container = container.parentNode;
3141                containerWidth = container.clientWidth;
3142            }
3143
3144            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
3145            var optimalWidth = containerWidth * dpr;
3146            var len = widths.length;
3147            var key = 0;
3148
3149            while ((key < len - 1) && (widths[key] < optimalWidth)) {
3150                key++;
3151            }
3152
3153            return widths[key].toString();
3154        }
3155
3156        function addLazyLoader() {
3157            var width = that._elements.image.getAttribute("width");
3158            var height = that._elements.image.getAttribute("height");
3159
3160            if (width && height) {
3161                var ratio = (height / width) * 100;
3162                var styles = lazyLoader.style;
3163
3164                styles["padding-bottom"] = ratio + "%";
3165
3166                for (var s in styles) {
3167                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
3168                        that._elements.image.style[s] = styles[s];
3169                    }
3170                }
3171            }
3172            that._elements.image.setAttribute("src", EMPTY_PIXEL);
3173            that._elements.image.classList.add(lazyLoader.cssClass);
3174            that._lazyLoaderShowing = true;
3175        }
3176
3177        function unwrapNoScript() {
3178            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
3179            var parser = new DOMParser();
3180
3181            // temporary document avoids requesting the image before removing its src
3182            var temporaryDocument = parser.parseFromString(markup, "text/html");
3183            var imageElement = temporaryDocument.querySelector(selectors.image);
3184            imageElement.removeAttribute("src");
3185            that._elements.container.insertBefore(imageElement, that._elements.noscript);
3186
3187            var mapElement = temporaryDocument.querySelector(selectors.map);
3188            if (mapElement) {
3189                that._elements.container.insertBefore(mapElement, that._elements.noscript);
3190            }
3191
3192            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
3193            if (that._elements.container.matches(selectors.image)) {
3194                that._elements.image = that._elements.container;
3195            } else {
3196                that._elements.image = that._elements.container.querySelector(selectors.image);
3197            }
3198
3199            that._elements.map = that._elements.container.querySelector(selectors.map);
3200            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
3201        }
3202
3203        function removeLazyLoader() {
3204            that._elements.image.classList.remove(lazyLoader.cssClass);
3205            for (var property in lazyLoader.style) {
3206                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
3207                    that._elements.image.style[property] = "";
3208                }
3209            }
3210            that._elements.image.removeEventListener("load", removeLazyLoader);
3211            that._lazyLoaderShowing = false;
3212        }
3213
3214        function isLazyVisible() {
3215            if (that._elements.container.offsetParent === null) {
3216                return false;
3217            }
3218
3219            var wt = window.pageYOffset;
3220            var wb = wt + document.documentElement.clientHeight;
3221            var et = that._elements.container.getBoundingClientRect().top + wt;
3222            var eb = et + that._elements.container.clientHeight;
3223
3224            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
3225        }
3226
3227        function resizeAreas() {
3228            if (that._elements.areas && that._elements.areas.length > 0) {
3229                for (var i = 0; i < that._elements.areas.length; i++) {
3230                    var width = that._elements.image.width;
3231                    var height = that._elements.image.height;
3232
3233                    if (width && height) {
3234                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
3235                        if (relcoords) {
3236                            var relativeCoordinates = relcoords.split(",");
3237                            var coordinates = new Array(relativeCoordinates.length);
3238
3239                            for (var j = 0; j < coordinates.length; j++) {
3240                                if (j % 2 === 0) {
3241                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
3242                                } else {
3243                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
3244                                }
3245                            }
3246
3247                            that._elements.areas[i].coords = coordinates;
3248                        }
3249                    }
3250                }
3251            }
3252        }
3253
3254        function cacheElements(wrapper) {
3255            that._elements = {};
3256            that._elements.self = wrapper;
3257            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
3258
3259            for (var i = 0; i < hooks.length; i++) {
3260                var hook = hooks[i];
3261                var capitalized = IS;
3262                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
3263                var key = hook.dataset[NS + "Hook" + capitalized];
3264                that._elements[key] = hook;
3265            }
3266        }
3267
3268        function setupProperties(options) {
3269            that._properties = {};
3270
3271            for (var key in properties) {
3272                if (Object.prototype.hasOwnProperty.call(properties, key)) {
3273                    var property = properties[key];
3274                    if (options && options[key] != null) {
3275                        if (property && typeof property.transform === "function") {
3276                            that._properties[key] = property.transform(options[key]);
3277                        } else {
3278                            that._properties[key] = options[key];
3279                        }
3280                    } else {
3281                        that._properties[key] = properties[key]["default"];
3282                    }
3283                }
3284            }
3285        }
3286
3287        function onWindowResize() {
3288            that.update();
3289            resizeAreas();
3290        }
3291
3292        function onLoad() {
3293            resizeAreas();
3294        }
3295
3296        that.update = function() {
3297            if (that._properties.lazy) {
3298                if (isLazyVisible()) {
3299                    loadImage();
3300                }
3301            } else {
3302                loadImage();
3303            }
3304        };
3305
3306        if (config && config.element) {
3307            init(config);
3308        }
3309    }
3310
3311    function onDocumentReady() {
3312        var elements = document.querySelectorAll(selectors.self);
3313        for (var i = 0; i < elements.length; i++) {
3314            new Image({ element: elements[i], options: readData(elements[i]) });
3315        }
3316
3317        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
3318        var body             = document.querySelector("body");
3319        var observer         = new MutationObserver(function(mutations) {
3320            mutations.forEach(function(mutation) {
3321                // needed for IE
3322                var nodesArray = [].slice.call(mutation.addedNodes);
3323                if (nodesArray.length > 0) {
3324                    nodesArray.forEach(function(addedNode) {
3325                        if (addedNode.querySelectorAll) {
3326                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
3327                            elementsArray.forEach(function(element) {
3328                                new Image({ element: element, options: readData(element) });
3329                            });
3330                        }
3331                    });
3332                }
3333            });
3334        });
3335
3336        observer.observe(body, {
3337            subtree: true,
3338            childList: true,
3339            characterData: true
3340        });
3341    }
3342
3343    if (document.readyState !== "loading") {
3344        onDocumentReady();
3345    } else {
3346        document.addEventListener("DOMContentLoaded", onDocumentReady);
3347    }
3348
3349    /*
3350        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
3351        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
3352     */
3353    function decodeNoscript(text) {
3354        text = text.replace(/&(amp;)*lt;/g, "<");
3355        text = text.replace(/&(amp;)*gt;/g, ">");
3356        return text;
3357    }
3358
3359})();
3360
3361/*******************************************************************************
3362 * Copyright 2017 Adobe
3363 *
3364 * Licensed under the Apache License, Version 2.0 (the "License");
3365 * you may not use this file except in compliance with the License.
3366 * You may obtain a copy of the License at
3367 *
3368 *     http://www.apache.org/licenses/LICENSE-2.0
3369 *
3370 * Unless required by applicable law or agreed to in writing, software
3371 * distributed under the License is distributed on an "AS IS" BASIS,
3372 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3373 * See the License for the specific language governing permissions and
3374 * limitations under the License.
3375 ******************************************************************************/
3376if (window.Element && !Element.prototype.closest) {
3377    // eslint valid-jsdoc: "off"
3378    Element.prototype.closest =
3379        function(s) {
3380            "use strict";
3381            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
3382            var el      = this;
3383            var i;
3384            do {
3385                i = matches.length;
3386                while (--i >= 0 && matches.item(i) !== el) {
3387                    // continue
3388                }
3389            } while ((i < 0) && (el = el.parentElement));
3390            return el;
3391        };
3392}
3393
3394if (window.Element && !Element.prototype.matches) {
3395    Element.prototype.matches =
3396        Element.prototype.matchesSelector ||
3397        Element.prototype.mozMatchesSelector ||
3398        Element.prototype.msMatchesSelector ||
3399        Element.prototype.oMatchesSelector ||
3400        Element.prototype.webkitMatchesSelector ||
3401        function(s) {
3402            "use strict";
3403            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
3404            var i       = matches.length;
3405            while (--i >= 0 && matches.item(i) !== this) {
3406                // continue
3407            }
3408            return i > -1;
3409        };
3410}
3411
3412if (!Object.assign) {
3413    Object.assign = function(target, varArgs) { // .length of function is 2
3414        "use strict";
3415        if (target === null) {
3416            throw new TypeError("Cannot convert undefined or null to object");
3417        }
3418
3419        var to = Object(target);
3420
3421        for (var index = 1; index < arguments.length; index++) {
3422            var nextSource = arguments[index];
3423
3424            if (nextSource !== null) {
3425                for (var nextKey in nextSource) {
3426                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
3427                        to[nextKey] = nextSource[nextKey];
3428                    }
3429                }
3430            }
3431        }
3432        return to;
3433    };
3434}
3435
3436(function(arr) {
3437    "use strict";
3438    arr.forEach(function(item) {
3439        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
3440            return;
3441        }
3442        Object.defineProperty(item, "remove", {
3443            configurable: true,
3444            enumerable: true,
3445            writable: true,
3446            value: function remove() {
3447                this.parentNode.removeChild(this);
3448            }
3449        });
3450    });
3451})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
3452
3453/*******************************************************************************
3454 * Copyright 2016 Adobe
3455 *
3456 * Licensed under the Apache License, Version 2.0 (the "License");
3457 * you may not use this file except in compliance with the License.
3458 * You may obtain a copy of the License at
3459 *
3460 *     http://www.apache.org/licenses/LICENSE-2.0
3461 *
3462 * Unless required by applicable law or agreed to in writing, software
3463 * distributed under the License is distributed on an "AS IS" BASIS,
3464 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3465 * See the License for the specific language governing permissions and
3466 * limitations under the License.
3467 ******************************************************************************/
3468(function() {
3469    "use strict";
3470
3471    var NS = "cmp";
3472    var IS = "image";
3473
3474    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
3475    var LAZY_THRESHOLD_DEFAULT = 0;
3476    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
3477    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
3478    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
3479
3480    var selectors = {
3481        self: "[data-" + NS + '-is="' + IS + '"]',
3482        image: '[data-cmp-hook-image="image"]',
3483        map: '[data-cmp-hook-image="map"]',
3484        area: '[data-cmp-hook-image="area"]'
3485    };
3486
3487    var lazyLoader = {
3488        "cssClass": "cmp-image__image--is-loading",
3489        "style": {
3490            "height": 0,
3491            "padding-bottom": "" // will be replaced with % ratio
3492        }
3493    };
3494
3495    var properties = {
3496        /**
3497         * An array of alternative image widths (in pixels).
3498         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
3499         *
3500         * @memberof Image
3501         * @type {Number[]}
3502         * @default []
3503         */
3504        "widths": {
3505            "default": [],
3506            "transform": function(value) {
3507                var widths = [];
3508                value.split(",").forEach(function(item) {
3509                    item = parseFloat(item);
3510                    if (!isNaN(item)) {
3511                        widths.push(item);
3512                    }
3513                });
3514                return widths;
3515            }
3516        },
3517        /**
3518         * Indicates whether the image should be rendered lazily.
3519         *
3520         * @memberof Image
3521         * @type {Boolean}
3522         * @default false
3523         */
3524        "lazy": {
3525            "default": false,
3526            "transform": function(value) {
3527                return !(value === null || typeof value === "undefined");
3528            }
3529        },
3530        /**
3531         * Indicates image is DynamicMedia image.
3532         *
3533         * @memberof Image
3534         * @type {Boolean}
3535         * @default false
3536         */
3537        "dmimage": {
3538            "default": false,
3539            "transform": function(value) {
3540                return !(value === null || typeof value === "undefined");
3541            }
3542        },
3543        /**
3544         * The lazy threshold.
3545         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
3546         * to load.
3547         *
3548         * @memberof Image
3549         * @type {Number}
3550         * @default 0
3551         */
3552        "lazythreshold": {
3553            "default": 0,
3554            "transform": function(value) {
3555                var val =  parseInt(value);
3556                if (isNaN(val)) {
3557                    return LAZY_THRESHOLD_DEFAULT;
3558                }
3559                return val;
3560            }
3561        },
3562        /**
3563         * The image source.
3564         *
3565         * Can be a simple image source, or a URI template representation that
3566         * can be variable expanded - useful for building an image configuration with an alternative width.
3567         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
3568         *
3569         * @memberof Image
3570         * @type {String}
3571         */
3572        "src": {
3573            "transform": function(value) {
3574                return decodeURIComponent(value);
3575            }
3576        }
3577    };
3578
3579    var devicePixelRatio = window.devicePixelRatio || 1;
3580
3581    function readData(element) {
3582        var data = element.dataset;
3583        var options = [];
3584        var capitalized = IS;
3585        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
3586        var reserved = ["is", "hook" + capitalized];
3587
3588        for (var key in data) {
3589            if (Object.prototype.hasOwnProperty.call(data, key)) {
3590                var value = data[key];
3591
3592                if (key.indexOf(NS) === 0) {
3593                    key = key.slice(NS.length);
3594                    key = key.charAt(0).toLowerCase() + key.substring(1);
3595
3596                    if (reserved.indexOf(key) === -1) {
3597                        options[key] = value;
3598                    }
3599                }
3600            }
3601        }
3602        return options;
3603    }
3604
3605    function Image(config) {
3606        var that = this;
3607
3608        var smartCrops = {};
3609
3610        var useAssetDelivery = false;
3611        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
3612
3613        function init(config) {
3614            // prevents multiple initialization
3615            config.element.removeAttribute("data-" + NS + "-is");
3616
3617            // check if asset delivery is used
3618            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
3619                useAssetDelivery = true;
3620                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
3621            }
3622
3623            setupProperties(config.options);
3624            cacheElements(config.element);
3625            // check image is DM asset; if true try to make req=set
3626            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
3627                var request = new XMLHttpRequest();
3628                var urlTemplatePart = decodeURIComponent(config.options.src).split(srcUriTemplateWidthVar)[0];
3629                var url = urlTemplatePart + (urlTemplatePart.indexOf("?") < 0 ? "?" : "") + "req=set,json";
3630
3631                request.open("GET", url, false);
3632                request.onload = function() {
3633                    if (request.status >= 200 && request.status < 400) {
3634                        // success status
3635                        var responseText = request.responseText;
3636                        var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
3637                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
3638                        var resPayload = rePayload.exec(responseText);
3639                        var payload;
3640                        if (resPayload) {
3641                            var payloadStr = resPayload[2];
3642                            if (rePayloadJSON.test(payloadStr)) {
3643                                payload = JSON.parse(payloadStr);
3644                            }
3645
3646                        }
3647                        // check "relation" - only in case of smartcrop preset
3648                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
3649                            for (var i = 0; i < payload.set.relation.length; i++) {
3650                                smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
3651                                    ":" + payload.set.relation[i].userdata.SmartCropDef;
3652                            }
3653                        }
3654                    } else {
3655                        // error status
3656                    }
3657                };
3658                request.send();
3659            }
3660
3661            if (!that._elements.noscript) {
3662                return;
3663            }
3664
3665            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
3666
3667            unwrapNoScript();
3668
3669            if (that._properties.lazy) {
3670                addLazyLoader();
3671            }
3672
3673            if (that._elements.map) {
3674                that._elements.image.addEventListener("load", onLoad);
3675            }
3676
3677            window.addEventListener("resize", onWindowResize);
3678            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
3679                document.addEventListener(name, that.update);
3680            });
3681
3682            that._elements.image.addEventListener("cmp-image-redraw", that.update);
3683            that.update();
3684        }
3685
3686        function loadImage() {
3687            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
3688            var replacement;
3689            if (Object.keys(smartCrops).length > 0) {
3690                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
3691                replacement = smartCrops[optimalWidth];
3692            } else {
3693                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
3694            }
3695            if (useAssetDelivery) {
3696                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
3697            }
3698            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
3699            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
3700
3701            var imgSrcAttribute = that._elements.image.getAttribute("src");
3702
3703            if (url !== imgSrcAttribute) {
3704                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
3705                    that._elements.image.setAttribute("src", url);
3706                } else {
3707                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
3708                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
3709                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
3710                    if (isImageRefSame && urlTemplateParts.length > 1) {
3711                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
3712                    }
3713                    if (isImageRefSame) {
3714                        that._elements.image.setAttribute("src", url);
3715                        if (!hasWidths) {
3716                            window.removeEventListener("scroll", that.update);
3717                        }
3718                    }
3719                }
3720            }
3721            if (that._lazyLoaderShowing) {
3722                that._elements.image.addEventListener("load", removeLazyLoader);
3723            }
3724        }
3725
3726        function getOptimalWidth(widths, useDevicePixelRatio) {
3727            var container = that._elements.self;
3728            var containerWidth = container.clientWidth;
3729            while (containerWidth === 0 && container.parentNode) {
3730                container = container.parentNode;
3731                containerWidth = container.clientWidth;
3732            }
3733
3734            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
3735            var optimalWidth = containerWidth * dpr;
3736            var len = widths.length;
3737            var key = 0;
3738
3739            while ((key < len - 1) && (widths[key] < optimalWidth)) {
3740                key++;
3741            }
3742
3743            return widths[key].toString();
3744        }
3745
3746        function addLazyLoader() {
3747            var width = that._elements.image.getAttribute("width");
3748            var height = that._elements.image.getAttribute("height");
3749
3750            if (width && height) {
3751                var ratio = (height / width) * 100;
3752                var styles = lazyLoader.style;
3753
3754                styles["padding-bottom"] = ratio + "%";
3755
3756                for (var s in styles) {
3757                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
3758                        that._elements.image.style[s] = styles[s];
3759                    }
3760                }
3761            }
3762            that._elements.image.setAttribute("src", EMPTY_PIXEL);
3763            that._elements.image.classList.add(lazyLoader.cssClass);
3764            that._lazyLoaderShowing = true;
3765        }
3766
3767        function unwrapNoScript() {
3768            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
3769            var parser = new DOMParser();
3770
3771            // temporary document avoids requesting the image before removing its src
3772            var temporaryDocument = parser.parseFromString(markup, "text/html");
3773            var imageElement = temporaryDocument.querySelector(selectors.image);
3774            imageElement.removeAttribute("src");
3775            that._elements.container.insertBefore(imageElement, that._elements.noscript);
3776
3777            var mapElement = temporaryDocument.querySelector(selectors.map);
3778            if (mapElement) {
3779                that._elements.container.insertBefore(mapElement, that._elements.noscript);
3780            }
3781
3782            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
3783            if (that._elements.container.matches(selectors.image)) {
3784                that._elements.image = that._elements.container;
3785            } else {
3786                that._elements.image = that._elements.container.querySelector(selectors.image);
3787            }
3788
3789            that._elements.map = that._elements.container.querySelector(selectors.map);
3790            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
3791        }
3792
3793        function removeLazyLoader() {
3794            that._elements.image.classList.remove(lazyLoader.cssClass);
3795            for (var property in lazyLoader.style) {
3796                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
3797                    that._elements.image.style[property] = "";
3798                }
3799            }
3800            that._elements.image.removeEventListener("load", removeLazyLoader);
3801            that._lazyLoaderShowing = false;
3802        }
3803
3804        function isLazyVisible() {
3805            if (that._elements.container.offsetParent === null) {
3806                return false;
3807            }
3808
3809            var wt = window.pageYOffset;
3810            var wb = wt + document.documentElement.clientHeight;
3811            var et = that._elements.container.getBoundingClientRect().top + wt;
3812            var eb = et + that._elements.container.clientHeight;
3813
3814            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
3815        }
3816
3817        function resizeAreas() {
3818            if (that._elements.areas && that._elements.areas.length > 0) {
3819                for (var i = 0; i < that._elements.areas.length; i++) {
3820                    var width = that._elements.image.width;
3821                    var height = that._elements.image.height;
3822
3823                    if (width && height) {
3824                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
3825                        if (relcoords) {
3826                            var relativeCoordinates = relcoords.split(",");
3827                            var coordinates = new Array(relativeCoordinates.length);
3828
3829                            for (var j = 0; j < coordinates.length; j++) {
3830                                if (j % 2 === 0) {
3831                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
3832                                } else {
3833                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
3834                                }
3835                            }
3836
3837                            that._elements.areas[i].coords = coordinates;
3838                        }
3839                    }
3840                }
3841            }
3842        }
3843
3844        function cacheElements(wrapper) {
3845            that._elements = {};
3846            that._elements.self = wrapper;
3847            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
3848
3849            for (var i = 0; i < hooks.length; i++) {
3850                var hook = hooks[i];
3851                var capitalized = IS;
3852                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
3853                var key = hook.dataset[NS + "Hook" + capitalized];
3854                that._elements[key] = hook;
3855            }
3856        }
3857
3858        function setupProperties(options) {
3859            that._properties = {};
3860
3861            for (var key in properties) {
3862                if (Object.prototype.hasOwnProperty.call(properties, key)) {
3863                    var property = properties[key];
3864                    if (options && options[key] != null) {
3865                        if (property && typeof property.transform === "function") {
3866                            that._properties[key] = property.transform(options[key]);
3867                        } else {
3868                            that._properties[key] = options[key];
3869                        }
3870                    } else {
3871                        that._properties[key] = properties[key]["default"];
3872                    }
3873                }
3874            }
3875        }
3876
3877        function onWindowResize() {
3878            that.update();
3879            resizeAreas();
3880        }
3881
3882        function onLoad() {
3883            resizeAreas();
3884        }
3885
3886        that.update = function() {
3887            if (that._properties.lazy) {
3888                if (isLazyVisible()) {
3889                    loadImage();
3890                }
3891            } else {
3892                loadImage();
3893            }
3894        };
3895
3896        if (config && config.element) {
3897            init(config);
3898        }
3899    }
3900
3901    function onDocumentReady() {
3902        var elements = document.querySelectorAll(selectors.self);
3903        for (var i = 0; i < elements.length; i++) {
3904            new Image({ element: elements[i], options: readData(elements[i]) });
3905        }
3906
3907        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
3908        var body             = document.querySelector("body");
3909        var observer         = new MutationObserver(function(mutations) {
3910            mutations.forEach(function(mutation) {
3911                // needed for IE
3912                var nodesArray = [].slice.call(mutation.addedNodes);
3913                if (nodesArray.length > 0) {
3914                    nodesArray.forEach(function(addedNode) {
3915                        if (addedNode.querySelectorAll) {
3916                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
3917                            elementsArray.forEach(function(element) {
3918                                new Image({ element: element, options: readData(element) });
3919                            });
3920                        }
3921                    });
3922                }
3923            });
3924        });
3925
3926        observer.observe(body, {
3927            subtree: true,
3928            childList: true,
3929            characterData: true
3930        });
3931    }
3932
3933    if (document.readyState !== "loading") {
3934        onDocumentReady();
3935    } else {
3936        document.addEventListener("DOMContentLoaded", onDocumentReady);
3937    }
3938
3939    /*
3940        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
3941        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
3942     */
3943    function decodeNoscript(text) {
3944        text = text.replace(/&(amp;)*lt;/g, "<");
3945        text = text.replace(/&(amp;)*gt;/g, ">");
3946        return text;
3947    }
3948
3949})();
3950
3951/*******************************************************************************
3952 * Copyright 2017 Adobe
3953 *
3954 * Licensed under the Apache License, Version 2.0 (the "License");
3955 * you may not use this file except in compliance with the License.
3956 * You may obtain a copy of the License at
3957 *
3958 *     http://www.apache.org/licenses/LICENSE-2.0
3959 *
3960 * Unless required by applicable law or agreed to in writing, software
3961 * distributed under the License is distributed on an "AS IS" BASIS,
3962 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3963 * See the License for the specific language governing permissions and
3964 * limitations under the License.
3965 ******************************************************************************/
3966if (window.Element && !Element.prototype.closest) {
3967    // eslint valid-jsdoc: "off"
3968    Element.prototype.closest =
3969        function(s) {
3970            "use strict";
3971            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
3972            var el      = this;
3973            var i;
3974            do {
3975                i = matches.length;
3976                while (--i >= 0 && matches.item(i) !== el) {
3977                    // continue
3978                }
3979            } while ((i < 0) && (el = el.parentElement));
3980            return el;
3981        };
3982}
3983
3984if (window.Element && !Element.prototype.matches) {
3985    Element.prototype.matches =
3986        Element.prototype.matchesSelector ||
3987        Element.prototype.mozMatchesSelector ||
3988        Element.prototype.msMatchesSelector ||
3989        Element.prototype.oMatchesSelector ||
3990        Element.prototype.webkitMatchesSelector ||
3991        function(s) {
3992            "use strict";
3993            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
3994            var i       = matches.length;
3995            while (--i >= 0 && matches.item(i) !== this) {
3996                // continue
3997            }
3998            return i > -1;
3999        };
4000}
4001
4002if (!Object.assign) {
4003    Object.assign = function(target, varArgs) { // .length of function is 2
4004        "use strict";
4005        if (target === null) {
4006            throw new TypeError("Cannot convert undefined or null to object");
4007        }
4008
4009        var to = Object(target);
4010
4011        for (var index = 1; index < arguments.length; index++) {
4012            var nextSource = arguments[index];
4013
4014            if (nextSource !== null) {
4015                for (var nextKey in nextSource) {
4016                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
4017                        to[nextKey] = nextSource[nextKey];
4018                    }
4019                }
4020            }
4021        }
4022        return to;
4023    };
4024}
4025
4026(function(arr) {
4027    "use strict";
4028    arr.forEach(function(item) {
4029        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
4030            return;
4031        }
4032        Object.defineProperty(item, "remove", {
4033            configurable: true,
4034            enumerable: true,
4035            writable: true,
4036            value: function remove() {
4037                this.parentNode.removeChild(this);
4038            }
4039        });
4040    });
4041})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
4042
4043/*******************************************************************************
4044 * Copyright 2016 Adobe
4045 *
4046 * Licensed under the Apache License, Version 2.0 (the "License");
4047 * you may not use this file except in compliance with the License.
4048 * You may obtain a copy of the License at
4049 *
4050 *     http://www.apache.org/licenses/LICENSE-2.0
4051 *
4052 * Unless required by applicable law or agreed to in writing, software
4053 * distributed under the License is distributed on an "AS IS" BASIS,
4054 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4055 * See the License for the specific language governing permissions and
4056 * limitations under the License.
4057 ******************************************************************************/
4058(function() {
4059    "use strict";
4060
4061    var NS = "cmp";
4062    var IS = "image";
4063
4064    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
4065    var LAZY_THRESHOLD_DEFAULT = 0;
4066    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
4067    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
4068    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
4069
4070    var selectors = {
4071        self: "[data-" + NS + '-is="' + IS + '"]',
4072        image: '[data-cmp-hook-image="image"]',
4073        map: '[data-cmp-hook-image="map"]',
4074        area: '[data-cmp-hook-image="area"]'
4075    };
4076
4077    var lazyLoader = {
4078        "cssClass": "cmp-image__image--is-loading",
4079        "style": {
4080            "height": 0,
4081            "padding-bottom": "" // will be replaced with % ratio
4082        }
4083    };
4084
4085    var properties = {
4086        /**
4087         * An array of alternative image widths (in pixels).
4088         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
4089         *
4090         * @memberof Image
4091         * @type {Number[]}
4092         * @default []
4093         */
4094        "widths": {
4095            "default": [],
4096            "transform": function(value) {
4097                var widths = [];
4098                value.split(",").forEach(function(item) {
4099                    item = parseFloat(item);
4100                    if (!isNaN(item)) {
4101                        widths.push(item);
4102                    }
4103                });
4104                return widths;
4105            }
4106        },
4107        /**
4108         * Indicates whether the image should be rendered lazily.
4109         *
4110         * @memberof Image
4111         * @type {Boolean}
4112         * @default false
4113         */
4114        "lazy": {
4115            "default": false,
4116            "transform": function(value) {
4117                return !(value === null || typeof value === "undefined");
4118            }
4119        },
4120        /**
4121         * Indicates image is DynamicMedia image.
4122         *
4123         * @memberof Image
4124         * @type {Boolean}
4125         * @default false
4126         */
4127        "dmimage": {
4128            "default": false,
4129            "transform": function(value) {
4130                return !(value === null || typeof value === "undefined");
4131            }
4132        },
4133        /**
4134         * The lazy threshold.
4135         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
4136         * to load.
4137         *
4138         * @memberof Image
4139         * @type {Number}
4140         * @default 0
4141         */
4142        "lazythreshold": {
4143            "default": 0,
4144            "transform": function(value) {
4145                var val =  parseInt(value);
4146                if (isNaN(val)) {
4147                    return LAZY_THRESHOLD_DEFAULT;
4148                }
4149                return val;
4150            }
4151        },
4152        /**
4153         * The image source.
4154         *
4155         * Can be a simple image source, or a URI template representation that
4156         * can be variable expanded - useful for building an image configuration with an alternative width.
4157         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
4158         *
4159         * @memberof Image
4160         * @type {String}
4161         */
4162        "src": {
4163            "transform": function(value) {
4164                return decodeURIComponent(value);
4165            }
4166        }
4167    };
4168
4169    var devicePixelRatio = window.devicePixelRatio || 1;
4170
4171    function readData(element) {
4172        var data = element.dataset;
4173        var options = [];
4174        var capitalized = IS;
4175        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
4176        var reserved = ["is", "hook" + capitalized];
4177
4178        for (var key in data) {
4179            if (Object.prototype.hasOwnProperty.call(data, key)) {
4180                var value = data[key];
4181
4182                if (key.indexOf(NS) === 0) {
4183                    key = key.slice(NS.length);
4184                    key = key.charAt(0).toLowerCase() + key.substring(1);
4185
4186                    if (reserved.indexOf(key) === -1) {
4187                        options[key] = value;
4188                    }
4189                }
4190            }
4191        }
4192        return options;
4193    }
4194
4195    function Image(config) {
4196        var that = this;
4197
4198        var smartCrops = {};
4199
4200        var useAssetDelivery = false;
4201        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
4202
4203        function init(config) {
4204            // prevents multiple initialization
4205            config.element.removeAttribute("data-" + NS + "-is");
4206
4207            // check if asset delivery is used
4208            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
4209                useAssetDelivery = true;
4210                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
4211            }
4212
4213            setupProperties(config.options);
4214            cacheElements(config.element);
4215            // check image is DM asset; if true try to make req=set
4216            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
4217                var request = new XMLHttpRequest();
4218                var urlTemplatePart = decodeURIComponent(config.options.src).split(srcUriTemplateWidthVar)[0];
4219                var url = urlTemplatePart + (urlTemplatePart.indexOf("?") < 0 ? "?" : "") + "req=set,json";
4220
4221                request.open("GET", url, false);
4222                request.onload = function() {
4223                    if (request.status >= 200 && request.status < 400) {
4224                        // success status
4225                        var responseText = request.responseText;
4226                        var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
4227                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
4228                        var resPayload = rePayload.exec(responseText);
4229                        var payload;
4230                        if (resPayload) {
4231                            var payloadStr = resPayload[2];
4232                            if (rePayloadJSON.test(payloadStr)) {
4233                                payload = JSON.parse(payloadStr);
4234                            }
4235
4236                        }
4237                        // check "relation" - only in case of smartcrop preset
4238                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
4239                            for (var i = 0; i < payload.set.relation.length; i++) {
4240                                smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
4241                                    ":" + payload.set.relation[i].userdata.SmartCropDef;
4242                            }
4243                        }
4244                    } else {
4245                        // error status
4246                    }
4247                };
4248                request.send();
4249            }
4250
4251            if (!that._elements.noscript) {
4252                return;
4253            }
4254
4255            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
4256
4257            unwrapNoScript();
4258
4259            if (that._properties.lazy) {
4260                addLazyLoader();
4261            }
4262
4263            if (that._elements.map) {
4264                that._elements.image.addEventListener("load", onLoad);
4265            }
4266
4267            window.addEventListener("resize", onWindowResize);
4268            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
4269                document.addEventListener(name, that.update);
4270            });
4271
4272            that._elements.image.addEventListener("cmp-image-redraw", that.update);
4273            that.update();
4274        }
4275
4276        function loadImage() {
4277            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
4278            var replacement;
4279            if (Object.keys(smartCrops).length > 0) {
4280                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
4281                replacement = smartCrops[optimalWidth];
4282            } else {
4283                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
4284            }
4285            if (useAssetDelivery) {
4286                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
4287            }
4288            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
4289            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
4290
4291            var imgSrcAttribute = that._elements.image.getAttribute("src");
4292
4293            if (url !== imgSrcAttribute) {
4294                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
4295                    that._elements.image.setAttribute("src", url);
4296                } else {
4297                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
4298                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
4299                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
4300                    if (isImageRefSame && urlTemplateParts.length > 1) {
4301                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
4302                    }
4303                    if (isImageRefSame) {
4304                        that._elements.image.setAttribute("src", url);
4305                        if (!hasWidths) {
4306                            window.removeEventListener("scroll", that.update);
4307                        }
4308                    }
4309                }
4310            }
4311            if (that._lazyLoaderShowing) {
4312                that._elements.image.addEventListener("load", removeLazyLoader);
4313            }
4314        }
4315
4316        function getOptimalWidth(widths, useDevicePixelRatio) {
4317            var container = that._elements.self;
4318            var containerWidth = container.clientWidth;
4319            while (containerWidth === 0 && container.parentNode) {
4320                container = container.parentNode;
4321                containerWidth = container.clientWidth;
4322            }
4323
4324            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
4325            var optimalWidth = containerWidth * dpr;
4326            var len = widths.length;
4327            var key = 0;
4328
4329            while ((key < len - 1) && (widths[key] < optimalWidth)) {
4330                key++;
4331            }
4332
4333            return widths[key].toString();
4334        }
4335
4336        function addLazyLoader() {
4337            var width = that._elements.image.getAttribute("width");
4338            var height = that._elements.image.getAttribute("height");
4339
4340            if (width && height) {
4341                var ratio = (height / width) * 100;
4342                var styles = lazyLoader.style;
4343
4344                styles["padding-bottom"] = ratio + "%";
4345
4346                for (var s in styles) {
4347                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
4348                        that._elements.image.style[s] = styles[s];
4349                    }
4350                }
4351            }
4352            that._elements.image.setAttribute("src", EMPTY_PIXEL);
4353            that._elements.image.classList.add(lazyLoader.cssClass);
4354            that._lazyLoaderShowing = true;
4355        }
4356
4357        function unwrapNoScript() {
4358            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
4359            var parser = new DOMParser();
4360
4361            // temporary document avoids requesting the image before removing its src
4362            var temporaryDocument = parser.parseFromString(markup, "text/html");
4363            var imageElement = temporaryDocument.querySelector(selectors.image);
4364            imageElement.removeAttribute("src");
4365            that._elements.container.insertBefore(imageElement, that._elements.noscript);
4366
4367            var mapElement = temporaryDocument.querySelector(selectors.map);
4368            if (mapElement) {
4369                that._elements.container.insertBefore(mapElement, that._elements.noscript);
4370            }
4371
4372            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
4373            if (that._elements.container.matches(selectors.image)) {
4374                that._elements.image = that._elements.container;
4375            } else {
4376                that._elements.image = that._elements.container.querySelector(selectors.image);
4377            }
4378
4379            that._elements.map = that._elements.container.querySelector(selectors.map);
4380            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
4381        }
4382
4383        function removeLazyLoader() {
4384            that._elements.image.classList.remove(lazyLoader.cssClass);
4385            for (var property in lazyLoader.style) {
4386                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
4387                    that._elements.image.style[property] = "";
4388                }
4389            }
4390            that._elements.image.removeEventListener("load", removeLazyLoader);
4391            that._lazyLoaderShowing = false;
4392        }
4393
4394        function isLazyVisible() {
4395            if (that._elements.container.offsetParent === null) {
4396                return false;
4397            }
4398
4399            var wt = window.pageYOffset;
4400            var wb = wt + document.documentElement.clientHeight;
4401            var et = that._elements.container.getBoundingClientRect().top + wt;
4402            var eb = et + that._elements.container.clientHeight;
4403
4404            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
4405        }
4406
4407        function resizeAreas() {
4408            if (that._elements.areas && that._elements.areas.length > 0) {
4409                for (var i = 0; i < that._elements.areas.length; i++) {
4410                    var width = that._elements.image.width;
4411                    var height = that._elements.image.height;
4412
4413                    if (width && height) {
4414                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
4415                        if (relcoords) {
4416                            var relativeCoordinates = relcoords.split(",");
4417                            var coordinates = new Array(relativeCoordinates.length);
4418
4419                            for (var j = 0; j < coordinates.length; j++) {
4420                                if (j % 2 === 0) {
4421                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
4422                                } else {
4423                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
4424                                }
4425                            }
4426
4427                            that._elements.areas[i].coords = coordinates;
4428                        }
4429                    }
4430                }
4431            }
4432        }
4433
4434        function cacheElements(wrapper) {
4435            that._elements = {};
4436            that._elements.self = wrapper;
4437            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
4438
4439            for (var i = 0; i < hooks.length; i++) {
4440                var hook = hooks[i];
4441                var capitalized = IS;
4442                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
4443                var key = hook.dataset[NS + "Hook" + capitalized];
4444                that._elements[key] = hook;
4445            }
4446        }
4447
4448        function setupProperties(options) {
4449            that._properties = {};
4450
4451            for (var key in properties) {
4452                if (Object.prototype.hasOwnProperty.call(properties, key)) {
4453                    var property = properties[key];
4454                    if (options && options[key] != null) {
4455                        if (property && typeof property.transform === "function") {
4456                            that._properties[key] = property.transform(options[key]);
4457                        } else {
4458                            that._properties[key] = options[key];
4459                        }
4460                    } else {
4461                        that._properties[key] = properties[key]["default"];
4462                    }
4463                }
4464            }
4465        }
4466
4467        function onWindowResize() {
4468            that.update();
4469            resizeAreas();
4470        }
4471
4472        function onLoad() {
4473            resizeAreas();
4474        }
4475
4476        that.update = function() {
4477            if (that._properties.lazy) {
4478                if (isLazyVisible()) {
4479                    loadImage();
4480                }
4481            } else {
4482                loadImage();
4483            }
4484        };
4485
4486        if (config && config.element) {
4487            init(config);
4488        }
4489    }
4490
4491    function onDocumentReady() {
4492        var elements = document.querySelectorAll(selectors.self);
4493        for (var i = 0; i < elements.length; i++) {
4494            new Image({ element: elements[i], options: readData(elements[i]) });
4495        }
4496
4497        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
4498        var body             = document.querySelector("body");
4499        var observer         = new MutationObserver(function(mutations) {
4500            mutations.forEach(function(mutation) {
4501                // needed for IE
4502                var nodesArray = [].slice.call(mutation.addedNodes);
4503                if (nodesArray.length > 0) {
4504                    nodesArray.forEach(function(addedNode) {
4505                        if (addedNode.querySelectorAll) {
4506                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
4507                            elementsArray.forEach(function(element) {
4508                                new Image({ element: element, options: readData(element) });
4509                            });
4510                        }
4511                    });
4512                }
4513            });
4514        });
4515
4516        observer.observe(body, {
4517            subtree: true,
4518            childList: true,
4519            characterData: true
4520        });
4521    }
4522
4523    if (document.readyState !== "loading") {
4524        onDocumentReady();
4525    } else {
4526        document.addEventListener("DOMContentLoaded", onDocumentReady);
4527    }
4528
4529    /*
4530        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
4531        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
4532     */
4533    function decodeNoscript(text) {
4534        text = text.replace(/&(amp;)*lt;/g, "<");
4535        text = text.replace(/&(amp;)*gt;/g, ">");
4536        return text;
4537    }
4538
4539})();
4540
4541/*******************************************************************************
4542 * Copyright 2017 Adobe
4543 *
4544 * Licensed under the Apache License, Version 2.0 (the "License");
4545 * you may not use this file except in compliance with the License.
4546 * You may obtain a copy of the License at
4547 *
4548 *     http://www.apache.org/licenses/LICENSE-2.0
4549 *
4550 * Unless required by applicable law or agreed to in writing, software
4551 * distributed under the License is distributed on an "AS IS" BASIS,
4552 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4553 * See the License for the specific language governing permissions and
4554 * limitations under the License.
4555 ******************************************************************************/
4556if (window.Element && !Element.prototype.closest) {
4557    // eslint valid-jsdoc: "off"
4558    Element.prototype.closest =
4559        function(s) {
4560            "use strict";
4561            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
4562            var el      = this;
4563            var i;
4564            do {
4565                i = matches.length;
4566                while (--i >= 0 && matches.item(i) !== el) {
4567                    // continue
4568                }
4569            } while ((i < 0) && (el = el.parentElement));
4570            return el;
4571        };
4572}
4573
4574if (window.Element && !Element.prototype.matches) {
4575    Element.prototype.matches =
4576        Element.prototype.matchesSelector ||
4577        Element.prototype.mozMatchesSelector ||
4578        Element.prototype.msMatchesSelector ||
4579        Element.prototype.oMatchesSelector ||
4580        Element.prototype.webkitMatchesSelector ||
4581        function(s) {
4582            "use strict";
4583            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
4584            var i       = matches.length;
4585            while (--i >= 0 && matches.item(i) !== this) {
4586                // continue
4587            }
4588            return i > -1;
4589        };
4590}
4591
4592if (!Object.assign) {
4593    Object.assign = function(target, varArgs) { // .length of function is 2
4594        "use strict";
4595        if (target === null) {
4596            throw new TypeError("Cannot convert undefined or null to object");
4597        }
4598
4599        var to = Object(target);
4600
4601        for (var index = 1; index < arguments.length; index++) {
4602            var nextSource = arguments[index];
4603
4604            if (nextSource !== null) {
4605                for (var nextKey in nextSource) {
4606                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
4607                        to[nextKey] = nextSource[nextKey];
4608                    }
4609                }
4610            }
4611        }
4612        return to;
4613    };
4614}
4615
4616(function(arr) {
4617    "use strict";
4618    arr.forEach(function(item) {
4619        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
4620            return;
4621        }
4622        Object.defineProperty(item, "remove", {
4623            configurable: true,
4624            enumerable: true,
4625            writable: true,
4626            value: function remove() {
4627                this.parentNode.removeChild(this);
4628            }
4629        });
4630    });
4631})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
4632
4633/*******************************************************************************
4634 * Copyright 2016 Adobe
4635 *
4636 * Licensed under the Apache License, Version 2.0 (the "License");
4637 * you may not use this file except in compliance with the License.
4638 * You may obtain a copy of the License at
4639 *
4640 *     http://www.apache.org/licenses/LICENSE-2.0
4641 *
4642 * Unless required by applicable law or agreed to in writing, software
4643 * distributed under the License is distributed on an "AS IS" BASIS,
4644 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4645 * See the License for the specific language governing permissions and
4646 * limitations under the License.
4647 ******************************************************************************/
4648(function() {
4649    "use strict";
4650
4651    var NS = "cmp";
4652    var IS = "image";
4653
4654    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
4655    var LAZY_THRESHOLD_DEFAULT = 0;
4656    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
4657    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
4658    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
4659
4660    var selectors = {
4661        self: "[data-" + NS + '-is="' + IS + '"]',
4662        image: '[data-cmp-hook-image="image"]',
4663        map: '[data-cmp-hook-image="map"]',
4664        area: '[data-cmp-hook-image="area"]'
4665    };
4666
4667    var lazyLoader = {
4668        "cssClass": "cmp-image__image--is-loading",
4669        "style": {
4670            "height": 0,
4671            "padding-bottom": "" // will be replaced with % ratio
4672        }
4673    };
4674
4675    var properties = {
4676        /**
4677         * An array of alternative image widths (in pixels).
4678         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
4679         *
4680         * @memberof Image
4681         * @type {Number[]}
4682         * @default []
4683         */
4684        "widths": {
4685            "default": [],
4686            "transform": function(value) {
4687                var widths = [];
4688                value.split(",").forEach(function(item) {
4689                    item = parseFloat(item);
4690                    if (!isNaN(item)) {
4691                        widths.push(item);
4692                    }
4693                });
4694                return widths;
4695            }
4696        },
4697        /**
4698         * Indicates whether the image should be rendered lazily.
4699         *
4700         * @memberof Image
4701         * @type {Boolean}
4702         * @default false
4703         */
4704        "lazy": {
4705            "default": false,
4706            "transform": function(value) {
4707                return !(value === null || typeof value === "undefined");
4708            }
4709        },
4710        /**
4711         * Indicates image is DynamicMedia image.
4712         *
4713         * @memberof Image
4714         * @type {Boolean}
4715         * @default false
4716         */
4717        "dmimage": {
4718            "default": false,
4719            "transform": function(value) {
4720                return !(value === null || typeof value === "undefined");
4721            }
4722        },
4723        /**
4724         * The lazy threshold.
4725         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
4726         * to load.
4727         *
4728         * @memberof Image
4729         * @type {Number}
4730         * @default 0
4731         */
4732        "lazythreshold": {
4733            "default": 0,
4734            "transform": function(value) {
4735                var val =  parseInt(value);
4736                if (isNaN(val)) {
4737                    return LAZY_THRESHOLD_DEFAULT;
4738                }
4739                return val;
4740            }
4741        },
4742        /**
4743         * The image source.
4744         *
4745         * Can be a simple image source, or a URI template representation that
4746         * can be variable expanded - useful for building an image configuration with an alternative width.
4747         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
4748         *
4749         * @memberof Image
4750         * @type {String}
4751         */
4752        "src": {
4753            "transform": function(value) {
4754                return decodeURIComponent(value);
4755            }
4756        }
4757    };
4758
4759    var devicePixelRatio = window.devicePixelRatio || 1;
4760
4761    function readData(element) {
4762        var data = element.dataset;
4763        var options = [];
4764        var capitalized = IS;
4765        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
4766        var reserved = ["is", "hook" + capitalized];
4767
4768        for (var key in data) {
4769            if (Object.prototype.hasOwnProperty.call(data, key)) {
4770                var value = data[key];
4771
4772                if (key.indexOf(NS) === 0) {
4773                    key = key.slice(NS.length);
4774                    key = key.charAt(0).toLowerCase() + key.substring(1);
4775
4776                    if (reserved.indexOf(key) === -1) {
4777                        options[key] = value;
4778                    }
4779                }
4780            }
4781        }
4782        return options;
4783    }
4784
4785    function Image(config) {
4786        var that = this;
4787
4788        var smartCrops = {};
4789
4790        var useAssetDelivery = false;
4791        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
4792
4793        function init(config) {
4794            // prevents multiple initialization
4795            config.element.removeAttribute("data-" + NS + "-is");
4796
4797            // check if asset delivery is used
4798            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
4799                useAssetDelivery = true;
4800                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
4801            }
4802
4803            setupProperties(config.options);
4804            cacheElements(config.element);
4805            // check image is DM asset; if true try to make req=set
4806            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
4807                var request = new XMLHttpRequest();
4808                var urlTemplatePart = decodeURIComponent(config.options.src).split(srcUriTemplateWidthVar)[0];
4809                var url = urlTemplatePart + (urlTemplatePart.indexOf("?") < 0 ? "?" : "") + "req=set,json";
4810
4811                request.open("GET", url, false);
4812                request.onload = function() {
4813                    if (request.status >= 200 && request.status < 400) {
4814                        // success status
4815                        var responseText = request.responseText;
4816                        var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
4817                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
4818                        var resPayload = rePayload.exec(responseText);
4819                        var payload;
4820                        if (resPayload) {
4821                            var payloadStr = resPayload[2];
4822                            if (rePayloadJSON.test(payloadStr)) {
4823                                payload = JSON.parse(payloadStr);
4824                            }
4825
4826                        }
4827                        // check "relation" - only in case of smartcrop preset
4828                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
4829                            for (var i = 0; i < payload.set.relation.length; i++) {
4830                                smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
4831                                    ":" + payload.set.relation[i].userdata.SmartCropDef;
4832                            }
4833                        }
4834                    } else {
4835                        // error status
4836                    }
4837                };
4838                request.send();
4839            }
4840
4841            if (!that._elements.noscript) {
4842                return;
4843            }
4844
4845            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
4846
4847            unwrapNoScript();
4848
4849            if (that._properties.lazy) {
4850                addLazyLoader();
4851            }
4852
4853            if (that._elements.map) {
4854                that._elements.image.addEventListener("load", onLoad);
4855            }
4856
4857            window.addEventListener("resize", onWindowResize);
4858            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
4859                document.addEventListener(name, that.update);
4860            });
4861
4862            that._elements.image.addEventListener("cmp-image-redraw", that.update);
4863            that.update();
4864        }
4865
4866        function loadImage() {
4867            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
4868            var replacement;
4869            if (Object.keys(smartCrops).length > 0) {
4870                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
4871                replacement = smartCrops[optimalWidth];
4872            } else {
4873                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
4874            }
4875            if (useAssetDelivery) {
4876                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
4877            }
4878            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
4879            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
4880
4881            var imgSrcAttribute = that._elements.image.getAttribute("src");
4882
4883            if (url !== imgSrcAttribute) {
4884                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
4885                    that._elements.image.setAttribute("src", url);
4886                } else {
4887                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
4888                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
4889                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
4890                    if (isImageRefSame && urlTemplateParts.length > 1) {
4891                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
4892                    }
4893                    if (isImageRefSame) {
4894                        that._elements.image.setAttribute("src", url);
4895                        if (!hasWidths) {
4896                            window.removeEventListener("scroll", that.update);
4897                        }
4898                    }
4899                }
4900            }
4901            if (that._lazyLoaderShowing) {
4902                that._elements.image.addEventListener("load", removeLazyLoader);
4903            }
4904        }
4905
4906        function getOptimalWidth(widths, useDevicePixelRatio) {
4907            var container = that._elements.self;
4908            var containerWidth = container.clientWidth;
4909            while (containerWidth === 0 && container.parentNode) {
4910                container = container.parentNode;
4911                containerWidth = container.clientWidth;
4912            }
4913
4914            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
4915            var optimalWidth = containerWidth * dpr;
4916            var len = widths.length;
4917            var key = 0;
4918
4919            while ((key < len - 1) && (widths[key] < optimalWidth)) {
4920                key++;
4921            }
4922
4923            return widths[key].toString();
4924        }
4925
4926        function addLazyLoader() {
4927            var width = that._elements.image.getAttribute("width");
4928            var height = that._elements.image.getAttribute("height");
4929
4930            if (width && height) {
4931                var ratio = (height / width) * 100;
4932                var styles = lazyLoader.style;
4933
4934                styles["padding-bottom"] = ratio + "%";
4935
4936                for (var s in styles) {
4937                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
4938                        that._elements.image.style[s] = styles[s];
4939                    }
4940                }
4941            }
4942            that._elements.image.setAttribute("src", EMPTY_PIXEL);
4943            that._elements.image.classList.add(lazyLoader.cssClass);
4944            that._lazyLoaderShowing = true;
4945        }
4946
4947        function unwrapNoScript() {
4948            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
4949            var parser = new DOMParser();
4950
4951            // temporary document avoids requesting the image before removing its src
4952            var temporaryDocument = parser.parseFromString(markup, "text/html");
4953            var imageElement = temporaryDocument.querySelector(selectors.image);
4954            imageElement.removeAttribute("src");
4955            that._elements.container.insertBefore(imageElement, that._elements.noscript);
4956
4957            var mapElement = temporaryDocument.querySelector(selectors.map);
4958            if (mapElement) {
4959                that._elements.container.insertBefore(mapElement, that._elements.noscript);
4960            }
4961
4962            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
4963            if (that._elements.container.matches(selectors.image)) {
4964                that._elements.image = that._elements.container;
4965            } else {
4966                that._elements.image = that._elements.container.querySelector(selectors.image);
4967            }
4968
4969            that._elements.map = that._elements.container.querySelector(selectors.map);
4970            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
4971        }
4972
4973        function removeLazyLoader() {
4974            that._elements.image.classList.remove(lazyLoader.cssClass);
4975            for (var property in lazyLoader.style) {
4976                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
4977                    that._elements.image.style[property] = "";
4978                }
4979            }
4980            that._elements.image.removeEventListener("load", removeLazyLoader);
4981            that._lazyLoaderShowing = false;
4982        }
4983
4984        function isLazyVisible() {
4985            if (that._elements.container.offsetParent === null) {
4986                return false;
4987            }
4988
4989            var wt = window.pageYOffset;
4990            var wb = wt + document.documentElement.clientHeight;
4991            var et = that._elements.container.getBoundingClientRect().top + wt;
4992            var eb = et + that._elements.container.clientHeight;
4993
4994            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
4995        }
4996
4997        function resizeAreas() {
4998            if (that._elements.areas && that._elements.areas.length > 0) {
4999                for (var i = 0; i < that._elements.areas.length; i++) {
5000                    var width = that._elements.image.width;
5001                    var height = that._elements.image.height;
5002
5003                    if (width && height) {
5004                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
5005                        if (relcoords) {
5006                            var relativeCoordinates = relcoords.split(",");
5007                            var coordinates = new Array(relativeCoordinates.length);
5008
5009                            for (var j = 0; j < coordinates.length; j++) {
5010                                if (j % 2 === 0) {
5011                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
5012                                } else {
5013                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
5014                                }
5015                            }
5016
5017                            that._elements.areas[i].coords = coordinates;
5018                        }
5019                    }
5020                }
5021            }
5022        }
5023
5024        function cacheElements(wrapper) {
5025            that._elements = {};
5026            that._elements.self = wrapper;
5027            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
5028
5029            for (var i = 0; i < hooks.length; i++) {
5030                var hook = hooks[i];
5031                var capitalized = IS;
5032                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
5033                var key = hook.dataset[NS + "Hook" + capitalized];
5034                that._elements[key] = hook;
5035            }
5036        }
5037
5038        function setupProperties(options) {
5039            that._properties = {};
5040
5041            for (var key in properties) {
5042                if (Object.prototype.hasOwnProperty.call(properties, key)) {
5043                    var property = properties[key];
5044                    if (options && options[key] != null) {
5045                        if (property && typeof property.transform === "function") {
5046                            that._properties[key] = property.transform(options[key]);
5047                        } else {
5048                            that._properties[key] = options[key];
5049                        }
5050                    } else {
5051                        that._properties[key] = properties[key]["default"];
5052                    }
5053                }
5054            }
5055        }
5056
5057        function onWindowResize() {
5058            that.update();
5059            resizeAreas();
5060        }
5061
5062        function onLoad() {
5063            resizeAreas();
5064        }
5065
5066        that.update = function() {
5067            if (that._properties.lazy) {
5068                if (isLazyVisible()) {
5069                    loadImage();
5070                }
5071            } else {
5072                loadImage();
5073            }
5074        };
5075
5076        if (config && config.element) {
5077            init(config);
5078        }
5079    }
5080
5081    function onDocumentReady() {
5082        var elements = document.querySelectorAll(selectors.self);
5083        for (var i = 0; i < elements.length; i++) {
5084            new Image({ element: elements[i], options: readData(elements[i]) });
5085        }
5086
5087        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
5088        var body             = document.querySelector("body");
5089        var observer         = new MutationObserver(function(mutations) {
5090            mutations.forEach(function(mutation) {
5091                // needed for IE
5092                var nodesArray = [].slice.call(mutation.addedNodes);
5093                if (nodesArray.length > 0) {
5094                    nodesArray.forEach(function(addedNode) {
5095                        if (addedNode.querySelectorAll) {
5096                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
5097                            elementsArray.forEach(function(element) {
5098                                new Image({ element: element, options: readData(element) });
5099                            });
5100                        }
5101                    });
5102                }
5103            });
5104        });
5105
5106        observer.observe(body, {
5107            subtree: true,
5108            childList: true,
5109            characterData: true
5110        });
5111    }
5112
5113    if (document.readyState !== "loading") {
5114        onDocumentReady();
5115    } else {
5116        document.addEventListener("DOMContentLoaded", onDocumentReady);
5117    }
5118
5119    /*
5120        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
5121        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
5122     */
5123    function decodeNoscript(text) {
5124        text = text.replace(/&(amp;)*lt;/g, "<");
5125        text = text.replace(/&(amp;)*gt;/g, ">");
5126        return text;
5127    }
5128
5129})();
5130
5131/*******************************************************************************
5132 * Copyright 2017 Adobe
5133 *
5134 * Licensed under the Apache License, Version 2.0 (the "License");
5135 * you may not use this file except in compliance with the License.
5136 * You may obtain a copy of the License at
5137 *
5138 *     http://www.apache.org/licenses/LICENSE-2.0
5139 *
5140 * Unless required by applicable law or agreed to in writing, software
5141 * distributed under the License is distributed on an "AS IS" BASIS,
5142 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5143 * See the License for the specific language governing permissions and
5144 * limitations under the License.
5145 ******************************************************************************/
5146if (window.Element && !Element.prototype.closest) {
5147    // eslint valid-jsdoc: "off"
5148    Element.prototype.closest =
5149        function(s) {
5150            "use strict";
5151            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
5152            var el      = this;
5153            var i;
5154            do {
5155                i = matches.length;
5156                while (--i >= 0 && matches.item(i) !== el) {
5157                    // continue
5158                }
5159            } while ((i < 0) && (el = el.parentElement));
5160            return el;
5161        };
5162}
5163
5164if (window.Element && !Element.prototype.matches) {
5165    Element.prototype.matches =
5166        Element.prototype.matchesSelector ||
5167        Element.prototype.mozMatchesSelector ||
5168        Element.prototype.msMatchesSelector ||
5169        Element.prototype.oMatchesSelector ||
5170        Element.prototype.webkitMatchesSelector ||
5171        function(s) {
5172            "use strict";
5173            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
5174            var i       = matches.length;
5175            while (--i >= 0 && matches.item(i) !== this) {
5176                // continue
5177            }
5178            return i > -1;
5179        };
5180}
5181
5182if (!Object.assign) {
5183    Object.assign = function(target, varArgs) { // .length of function is 2
5184        "use strict";
5185        if (target === null) {
5186            throw new TypeError("Cannot convert undefined or null to object");
5187        }
5188
5189        var to = Object(target);
5190
5191        for (var index = 1; index < arguments.length; index++) {
5192            var nextSource = arguments[index];
5193
5194            if (nextSource !== null) {
5195                for (var nextKey in nextSource) {
5196                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
5197                        to[nextKey] = nextSource[nextKey];
5198                    }
5199                }
5200            }
5201        }
5202        return to;
5203    };
5204}
5205
5206(function(arr) {
5207    "use strict";
5208    arr.forEach(function(item) {
5209        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
5210            return;
5211        }
5212        Object.defineProperty(item, "remove", {
5213            configurable: true,
5214            enumerable: true,
5215            writable: true,
5216            value: function remove() {
5217                this.parentNode.removeChild(this);
5218            }
5219        });
5220    });
5221})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
5222
5223/*******************************************************************************
5224 * Copyright 2016 Adobe
5225 *
5226 * Licensed under the Apache License, Version 2.0 (the "License");
5227 * you may not use this file except in compliance with the License.
5228 * You may obtain a copy of the License at
5229 *
5230 *     http://www.apache.org/licenses/LICENSE-2.0
5231 *
5232 * Unless required by applicable law or agreed to in writing, software
5233 * distributed under the License is distributed on an "AS IS" BASIS,
5234 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5235 * See the License for the specific language governing permissions and
5236 * limitations under the License.
5237 ******************************************************************************/
5238(function() {
5239    "use strict";
5240
5241    var NS = "cmp";
5242    var IS = "image";
5243
5244    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
5245    var LAZY_THRESHOLD_DEFAULT = 0;
5246    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
5247    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
5248    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
5249
5250    var selectors = {
5251        self: "[data-" + NS + '-is="' + IS + '"]',
5252        image: '[data-cmp-hook-image="image"]',
5253        map: '[data-cmp-hook-image="map"]',
5254        area: '[data-cmp-hook-image="area"]'
5255    };
5256
5257    var lazyLoader = {
5258        "cssClass": "cmp-image__image--is-loading",
5259        "style": {
5260            "height": 0,
5261            "padding-bottom": "" // will be replaced with % ratio
5262        }
5263    };
5264
5265    var properties = {
5266        /**
5267         * An array of alternative image widths (in pixels).
5268         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
5269         *
5270         * @memberof Image
5271         * @type {Number[]}
5272         * @default []
5273         */
5274        "widths": {
5275            "default": [],
5276            "transform": function(value) {
5277                var widths = [];
5278                value.split(",").forEach(function(item) {
5279                    item = parseFloat(item);
5280                    if (!isNaN(item)) {
5281                        widths.push(item);
5282                    }
5283                });
5284                return widths;
5285            }
5286        },
5287        /**
5288         * Indicates whether the image should be rendered lazily.
5289         *
5290         * @memberof Image
5291         * @type {Boolean}
5292         * @default false
5293         */
5294        "lazy": {
5295            "default": false,
5296            "transform": function(value) {
5297                return !(value === null || typeof value === "undefined");
5298            }
5299        },
5300        /**
5301         * Indicates image is DynamicMedia image.
5302         *
5303         * @memberof Image
5304         * @type {Boolean}
5305         * @default false
5306         */
5307        "dmimage": {
5308            "default": false,
5309            "transform": function(value) {
5310                return !(value === null || typeof value === "undefined");
5311            }
5312        },
5313        /**
5314         * The lazy threshold.
5315         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
5316         * to load.
5317         *
5318         * @memberof Image
5319         * @type {Number}
5320         * @default 0
5321         */
5322        "lazythreshold": {
5323            "default": 0,
5324            "transform": function(value) {
5325                var val =  parseInt(value);
5326                if (isNaN(val)) {
5327                    return LAZY_THRESHOLD_DEFAULT;
5328                }
5329                return val;
5330            }
5331        },
5332        /**
5333         * The image source.
5334         *
5335         * Can be a simple image source, or a URI template representation that
5336         * can be variable expanded - useful for building an image configuration with an alternative width.
5337         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
5338         *
5339         * @memberof Image
5340         * @type {String}
5341         */
5342        "src": {
5343            "transform": function(value) {
5344                return decodeURIComponent(value);
5345            }
5346        }
5347    };
5348
5349    var devicePixelRatio = window.devicePixelRatio || 1;
5350
5351    function readData(element) {
5352        var data = element.dataset;
5353        var options = [];
5354        var capitalized = IS;
5355        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
5356        var reserved = ["is", "hook" + capitalized];
5357
5358        for (var key in data) {
5359            if (Object.prototype.hasOwnProperty.call(data, key)) {
5360                var value = data[key];
5361
5362                if (key.indexOf(NS) === 0) {
5363                    key = key.slice(NS.length);
5364                    key = key.charAt(0).toLowerCase() + key.substring(1);
5365
5366                    if (reserved.indexOf(key) === -1) {
5367                        options[key] = value;
5368                    }
5369                }
5370            }
5371        }
5372        return options;
5373    }
5374
5375    function Image(config) {
5376        var that = this;
5377
5378        var smartCrops = {};
5379
5380        var useAssetDelivery = false;
5381        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
5382
5383        function init(config) {
5384            // prevents multiple initialization
5385            config.element.removeAttribute("data-" + NS + "-is");
5386
5387            // check if asset delivery is used
5388            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
5389                useAssetDelivery = true;
5390                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
5391            }
5392
5393            setupProperties(config.options);
5394            cacheElements(config.element);
5395            // check image is DM asset; if true try to make req=set
5396            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
5397                var request = new XMLHttpRequest();
5398                var urlTemplatePart = decodeURIComponent(config.options.src).split(srcUriTemplateWidthVar)[0];
5399                var url = urlTemplatePart + (urlTemplatePart.indexOf("?") < 0 ? "?" : "") + "req=set,json";
5400
5401                request.open("GET", url, false);
5402                request.onload = function() {
5403                    if (request.status >= 200 && request.status < 400) {
5404                        // success status
5405                        var responseText = request.responseText;
5406                        var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
5407                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
5408                        var resPayload = rePayload.exec(responseText);
5409                        var payload;
5410                        if (resPayload) {
5411                            var payloadStr = resPayload[2];
5412                            if (rePayloadJSON.test(payloadStr)) {
5413                                payload = JSON.parse(payloadStr);
5414                            }
5415
5416                        }
5417                        // check "relation" - only in case of smartcrop preset
5418                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
5419                            for (var i = 0; i < payload.set.relation.length; i++) {
5420                                smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
5421                                    ":" + payload.set.relation[i].userdata.SmartCropDef;
5422                            }
5423                        }
5424                    } else {
5425                        // error status
5426                    }
5427                };
5428                request.send();
5429            }
5430
5431            if (!that._elements.noscript) {
5432                return;
5433            }
5434
5435            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
5436
5437            unwrapNoScript();
5438
5439            if (that._properties.lazy) {
5440                addLazyLoader();
5441            }
5442
5443            if (that._elements.map) {
5444                that._elements.image.addEventListener("load", onLoad);
5445            }
5446
5447            window.addEventListener("resize", onWindowResize);
5448            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
5449                document.addEventListener(name, that.update);
5450            });
5451
5452            that._elements.image.addEventListener("cmp-image-redraw", that.update);
5453            that.update();
5454        }
5455
5456        function loadImage() {
5457            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
5458            var replacement;
5459            if (Object.keys(smartCrops).length > 0) {
5460                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
5461                replacement = smartCrops[optimalWidth];
5462            } else {
5463                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
5464            }
5465            if (useAssetDelivery) {
5466                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
5467            }
5468            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
5469            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
5470
5471            var imgSrcAttribute = that._elements.image.getAttribute("src");
5472
5473            if (url !== imgSrcAttribute) {
5474                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
5475                    that._elements.image.setAttribute("src", url);
5476                } else {
5477                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
5478                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
5479                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
5480                    if (isImageRefSame && urlTemplateParts.length > 1) {
5481                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
5482                    }
5483                    if (isImageRefSame) {
5484                        that._elements.image.setAttribute("src", url);
5485                        if (!hasWidths) {
5486                            window.removeEventListener("scroll", that.update);
5487                        }
5488                    }
5489                }
5490            }
5491            if (that._lazyLoaderShowing) {
5492                that._elements.image.addEventListener("load", removeLazyLoader);
5493            }
5494        }
5495
5496        function getOptimalWidth(widths, useDevicePixelRatio) {
5497            var container = that._elements.self;
5498            var containerWidth = container.clientWidth;
5499            while (containerWidth === 0 && container.parentNode) {
5500                container = container.parentNode;
5501                containerWidth = container.clientWidth;
5502            }
5503
5504            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
5505            var optimalWidth = containerWidth * dpr;
5506            var len = widths.length;
5507            var key = 0;
5508
5509            while ((key < len - 1) && (widths[key] < optimalWidth)) {
5510                key++;
5511            }
5512
5513            return widths[key].toString();
5514        }
5515
5516        function addLazyLoader() {
5517            var width = that._elements.image.getAttribute("width");
5518            var height = that._elements.image.getAttribute("height");
5519
5520            if (width && height) {
5521                var ratio = (height / width) * 100;
5522                var styles = lazyLoader.style;
5523
5524                styles["padding-bottom"] = ratio + "%";
5525
5526                for (var s in styles) {
5527                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
5528                        that._elements.image.style[s] = styles[s];
5529                    }
5530                }
5531            }
5532            that._elements.image.setAttribute("src", EMPTY_PIXEL);
5533            that._elements.image.classList.add(lazyLoader.cssClass);
5534            that._lazyLoaderShowing = true;
5535        }
5536
5537        function unwrapNoScript() {
5538            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
5539            var parser = new DOMParser();
5540
5541            // temporary document avoids requesting the image before removing its src
5542            var temporaryDocument = parser.parseFromString(markup, "text/html");
5543            var imageElement = temporaryDocument.querySelector(selectors.image);
5544            imageElement.removeAttribute("src");
5545            that._elements.container.insertBefore(imageElement, that._elements.noscript);
5546
5547            var mapElement = temporaryDocument.querySelector(selectors.map);
5548            if (mapElement) {
5549                that._elements.container.insertBefore(mapElement, that._elements.noscript);
5550            }
5551
5552            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
5553            if (that._elements.container.matches(selectors.image)) {
5554                that._elements.image = that._elements.container;
5555            } else {
5556                that._elements.image = that._elements.container.querySelector(selectors.image);
5557            }
5558
5559            that._elements.map = that._elements.container.querySelector(selectors.map);
5560            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
5561        }
5562
5563        function removeLazyLoader() {
5564            that._elements.image.classList.remove(lazyLoader.cssClass);
5565            for (var property in lazyLoader.style) {
5566                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
5567                    that._elements.image.style[property] = "";
5568                }
5569            }
5570            that._elements.image.removeEventListener("load", removeLazyLoader);
5571            that._lazyLoaderShowing = false;
5572        }
5573
5574        function isLazyVisible() {
5575            if (that._elements.container.offsetParent === null) {
5576                return false;
5577            }
5578
5579            var wt = window.pageYOffset;
5580            var wb = wt + document.documentElement.clientHeight;
5581            var et = that._elements.container.getBoundingClientRect().top + wt;
5582            var eb = et + that._elements.container.clientHeight;
5583
5584            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
5585        }
5586
5587        function resizeAreas() {
5588            if (that._elements.areas && that._elements.areas.length > 0) {
5589                for (var i = 0; i < that._elements.areas.length; i++) {
5590                    var width = that._elements.image.width;
5591                    var height = that._elements.image.height;
5592
5593                    if (width && height) {
5594                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
5595                        if (relcoords) {
5596                            var relativeCoordinates = relcoords.split(",");
5597                            var coordinates = new Array(relativeCoordinates.length);
5598
5599                            for (var j = 0; j < coordinates.length; j++) {
5600                                if (j % 2 === 0) {
5601                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
5602                                } else {
5603                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
5604                                }
5605                            }
5606
5607                            that._elements.areas[i].coords = coordinates;
5608                        }
5609                    }
5610                }
5611            }
5612        }
5613
5614        function cacheElements(wrapper) {
5615            that._elements = {};
5616            that._elements.self = wrapper;
5617            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
5618
5619            for (var i = 0; i < hooks.length; i++) {
5620                var hook = hooks[i];
5621                var capitalized = IS;
5622                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
5623                var key = hook.dataset[NS + "Hook" + capitalized];
5624                that._elements[key] = hook;
5625            }
5626        }
5627
5628        function setupProperties(options) {
5629            that._properties = {};
5630
5631            for (var key in properties) {
5632                if (Object.prototype.hasOwnProperty.call(properties, key)) {
5633                    var property = properties[key];
5634                    if (options && options[key] != null) {
5635                        if (property && typeof property.transform === "function") {
5636                            that._properties[key] = property.transform(options[key]);
5637                        } else {
5638                            that._properties[key] = options[key];
5639                        }
5640                    } else {
5641                        that._properties[key] = properties[key]["default"];
5642                    }
5643                }
5644            }
5645        }
5646
5647        function onWindowResize() {
5648            that.update();
5649            resizeAreas();
5650        }
5651
5652        function onLoad() {
5653            resizeAreas();
5654        }
5655
5656        that.update = function() {
5657            if (that._properties.lazy) {
5658                if (isLazyVisible()) {
5659                    loadImage();
5660                }
5661            } else {
5662                loadImage();
5663            }
5664        };
5665
5666        if (config && config.element) {
5667            init(config);
5668        }
5669    }
5670
5671    function onDocumentReady() {
5672        var elements = document.querySelectorAll(selectors.self);
5673        for (var i = 0; i < elements.length; i++) {
5674            new Image({ element: elements[i], options: readData(elements[i]) });
5675        }
5676
5677        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
5678        var body             = document.querySelector("body");
5679        var observer         = new MutationObserver(function(mutations) {
5680            mutations.forEach(function(mutation) {
5681                // needed for IE
5682                var nodesArray = [].slice.call(mutation.addedNodes);
5683                if (nodesArray.length > 0) {
5684                    nodesArray.forEach(function(addedNode) {
5685                        if (addedNode.querySelectorAll) {
5686                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
5687                            elementsArray.forEach(function(element) {
5688                                new Image({ element: element, options: readData(element) });
5689                            });
5690                        }
5691                    });
5692                }
5693            });
5694        });
5695
5696        observer.observe(body, {
5697            subtree: true,
5698            childList: true,
5699            characterData: true
5700        });
5701    }
5702
5703    if (document.readyState !== "loading") {
5704        onDocumentReady();
5705    } else {
5706        document.addEventListener("DOMContentLoaded", onDocumentReady);
5707    }
5708
5709    /*
5710        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
5711        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
5712     */
5713    function decodeNoscript(text) {
5714        text = text.replace(/&(amp;)*lt;/g, "<");
5715        text = text.replace(/&(amp;)*gt;/g, ">");
5716        return text;
5717    }
5718
5719})();
5720
5721/*******************************************************************************
5722 * Copyright 2017 Adobe
5723 *
5724 * Licensed under the Apache License, Version 2.0 (the "License");
5725 * you may not use this file except in compliance with the License.
5726 * You may obtain a copy of the License at
5727 *
5728 *     http://www.apache.org/licenses/LICENSE-2.0
5729 *
5730 * Unless required by applicable law or agreed to in writing, software
5731 * distributed under the License is distributed on an "AS IS" BASIS,
5732 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5733 * See the License for the specific language governing permissions and
5734 * limitations under the License.
5735 ******************************************************************************/
5736if (window.Element && !Element.prototype.closest) {
5737    // eslint valid-jsdoc: "off"
5738    Element.prototype.closest =
5739        function(s) {
5740            "use strict";
5741            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
5742            var el      = this;
5743            var i;
5744            do {
5745                i = matches.length;
5746                while (--i >= 0 && matches.item(i) !== el) {
5747                    // continue
5748                }
5749            } while ((i < 0) && (el = el.parentElement));
5750            return el;
5751        };
5752}
5753
5754if (window.Element && !Element.prototype.matches) {
5755    Element.prototype.matches =
5756        Element.prototype.matchesSelector ||
5757        Element.prototype.mozMatchesSelector ||
5758        Element.prototype.msMatchesSelector ||
5759        Element.prototype.oMatchesSelector ||
5760        Element.prototype.webkitMatchesSelector ||
5761        function(s) {
5762            "use strict";
5763            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
5764            var i       = matches.length;
5765            while (--i >= 0 && matches.item(i) !== this) {
5766                // continue
5767            }
5768            return i > -1;
5769        };
5770}
5771
5772if (!Object.assign) {
5773    Object.assign = function(target, varArgs) { // .length of function is 2
5774        "use strict";
5775        if (target === null) {
5776            throw new TypeError("Cannot convert undefined or null to object");
5777        }
5778
5779        var to = Object(target);
5780
5781        for (var index = 1; index < arguments.length; index++) {
5782            var nextSource = arguments[index];
5783
5784            if (nextSource !== null) {
5785                for (var nextKey in nextSource) {
5786                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
5787                        to[nextKey] = nextSource[nextKey];
5788                    }
5789                }
5790            }
5791        }
5792        return to;
5793    };
5794}
5795
5796(function(arr) {
5797    "use strict";
5798    arr.forEach(function(item) {
5799        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
5800            return;
5801        }
5802        Object.defineProperty(item, "remove", {
5803            configurable: true,
5804            enumerable: true,
5805            writable: true,
5806            value: function remove() {
5807                this.parentNode.removeChild(this);
5808            }
5809        });
5810    });
5811})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
5812
5813/*******************************************************************************
5814 * Copyright 2016 Adobe
5815 *
5816 * Licensed under the Apache License, Version 2.0 (the "License");
5817 * you may not use this file except in compliance with the License.
5818 * You may obtain a copy of the License at
5819 *
5820 *     http://www.apache.org/licenses/LICENSE-2.0
5821 *
5822 * Unless required by applicable law or agreed to in writing, software
5823 * distributed under the License is distributed on an "AS IS" BASIS,
5824 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5825 * See the License for the specific language governing permissions and
5826 * limitations under the License.
5827 ******************************************************************************/
5828(function() {
5829    "use strict";
5830
5831    var NS = "cmp";
5832    var IS = "image";
5833    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
5834    var LAZY_THRESHOLD_DEFAULT = 0;
5835    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
5836    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
5837    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
5838
5839    var selectors = {
5840//        self: "[data-" + NS + '-is="' + IS + '"]',
5841        self: '[data-test-primary="image"]',
5842        image: '[data-cmp-hook-image="image"]',
5843        map: '[data-cmp-hook-image="map"]',
5844        area: '[data-cmp-hook-image="area"]'
5845    };
5846
5847    var lazyLoader = {
5848        "cssClass": "cmp-image__image--is-loading",
5849        "style": {
5850            "height": 0,
5851            "padding-bottom": "" // will be replaced with % ratio
5852        }
5853    };
5854
5855    var properties = {
5856        /**
5857         * An array of alternative image widths (in pixels).
5858         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
5859         *
5860         * @memberof Image
5861         * @type {Number[]}
5862         * @default []
5863         */
5864        "widths": {
5865            "default": [],
5866            "transform": function(value) {
5867                var widths = [];
5868                value.split(",").forEach(function(item) {
5869                    item = parseFloat(item);
5870                    if (!isNaN(item)) {
5871                        widths.push(item);
5872                    }
5873                });
5874                return widths;
5875            }
5876        },
5877        /**
5878         * Indicates whether the image should be rendered lazily.
5879         *
5880         * @memberof Image
5881         * @type {Boolean}
5882         * @default false
5883         */
5884        "lazy": {
5885            "default": false,
5886            "transform": function(value) {
5887                return !(value === null || typeof value === "undefined");
5888            }
5889        },
5890        /**
5891         * Indicates image is DynamicMedia image.
5892         *
5893         * @memberof Image
5894         * @type {Boolean}
5895         * @default false
5896         */
5897        "dmimage": {
5898            "default": false,
5899            "transform": function(value) {
5900                return !(value === null || typeof value === "undefined");
5901            }
5902        },
5903        /**
5904         * The lazy threshold.
5905         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
5906         * to load.
5907         *
5908         * @memberof Image
5909         * @type {Number}
5910         * @default 0
5911         */
5912        "lazythreshold": {
5913            "default": 0,
5914            "transform": function(value) {
5915                var val =  parseInt(value);
5916                if (isNaN(val)) {
5917                    return LAZY_THRESHOLD_DEFAULT;
5918                }
5919                return val;
5920            }
5921        },
5922        /**
5923         * The image source.
5924         *
5925         * Can be a simple image source, or a URI template representation that
5926         * can be variable expanded - useful for building an image configuration with an alternative width.
5927         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
5928         *
5929         * @memberof Image
5930         * @type {String}
5931         */
5932        "src": {
5933            "transform": function(value) {
5934                return decodeURIComponent(value);
5935            }
5936        }
5937    };
5938
5939    var devicePixelRatio = window.devicePixelRatio || 1;
5940
5941    function readData(element) {
5942        var data = element.dataset;
5943        var options = [];
5944        var capitalized = IS;
5945        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
5946        var reserved = ["is", "hook" + capitalized];
5947
5948        for (var key in data) {
5949            if (Object.prototype.hasOwnProperty.call(data, key)) {
5950                var value = data[key];
5951
5952                if (key.indexOf(NS) === 0) {
5953                    key = key.slice(NS.length);
5954                    key = key.charAt(0).toLowerCase() + key.substring(1);
5955
5956                    if (reserved.indexOf(key) === -1) {
5957                        options[key] = value;
5958                    }
5959                }
5960            }
5961        }
5962        return options;
5963    }
5964
5965    function Image(config) {
5966        var that = this;
5967
5968        var smartCrops = {};
5969
5970        var useAssetDelivery = false;
5971        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
5972
5973        function init(config) {
5974            // prevents multiple initialization
5975            config.element.removeAttribute("data-" + NS + "-is");
5976
5977            // check if asset delivery is used
5978            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
5979                useAssetDelivery = true;
5980                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
5981            }
5982
5983            setupProperties(config.options);
5984            cacheElements(config.element);
5985            // check image is DM asset; if true try to make req=set
5986            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
5987                var request = new XMLHttpRequest();
5988                var urlTemplatePart = decodeURIComponent(config.options.src).split(srcUriTemplateWidthVar)[0];
5989                var url = urlTemplatePart + (urlTemplatePart.indexOf("?") < 0 ? "?" : "") + "req=set,json";
5990                request.open("GET", url, false);
5991                request.onload = function() {
5992                    if (request.status >= 200 && request.status < 400) {
5993                        // success status
5994                        var responseText = request.responseText;
5995                        var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
5996                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
5997                        var resPayload = rePayload.exec(responseText);
5998                        var payload;
5999                        if (resPayload) {
6000                            var payloadStr = resPayload[2];
6001                            if (rePayloadJSON.test(payloadStr)) {
6002                                payload = JSON.parse(payloadStr);
6003                            }
6004
6005                        }
6006                        // check "relation" - only in case of smartcrop preset
6007                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
6008                            for (var i = 0; i < payload.set.relation.length; i++) {
6009                                smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
6010                                    ":" + payload.set.relation[i].userdata.SmartCropDef;
6011                            }
6012                        }
6013                    } else {
6014                        // error status
6015                    }
6016                };
6017                request.send();
6018            }
6019
6020            if (!that._elements.noscript) {
6021                return;
6022            }
6023
6024            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
6025
6026            unwrapNoScript();
6027
6028            if (that._properties.lazy) {
6029                addLazyLoader();
6030            }
6031
6032            if (that._elements.map) {
6033                that._elements.image.addEventListener("load", onLoad);
6034            }
6035
6036            window.addEventListener("resize", onWindowResize);
6037            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
6038                document.addEventListener(name, that.update);
6039            });
6040
6041            that._elements.image.addEventListener("cmp-image-redraw", that.update);
6042            that.update();
6043        }
6044
6045        function loadImage() {
6046            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
6047            var replacement;
6048            if (Object.keys(smartCrops).length > 0) {
6049                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
6050                replacement = smartCrops[optimalWidth];
6051            } else {
6052                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
6053            }
6054            if (useAssetDelivery) {
6055                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
6056            }
6057            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
6058            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
6059
6060            var imgSrcAttribute = that._elements.image.getAttribute("src");
6061
6062            if (url !== imgSrcAttribute) {
6063                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
6064                    that._elements.image.setAttribute("src", url);
6065                } else {
6066                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
6067                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
6068                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
6069                    if (isImageRefSame && urlTemplateParts.length > 1) {
6070                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
6071                    }
6072                    if (isImageRefSame) {
6073                        that._elements.image.setAttribute("src", url);
6074                        if (!hasWidths) {
6075                            window.removeEventListener("scroll", that.update);
6076                        }
6077                    }
6078                }
6079            }
6080            if (that._lazyLoaderShowing) {
6081                that._elements.image.addEventListener("load", removeLazyLoader);
6082            }
6083        }
6084
6085        function getOptimalWidth(widths, useDevicePixelRatio) {
6086            var container = that._elements.self;
6087            var containerWidth = container.clientWidth;
6088            while (containerWidth === 0 && container.parentNode) {
6089                container = container.parentNode;
6090                containerWidth = container.clientWidth;
6091            }
6092
6093            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
6094            var optimalWidth = containerWidth * dpr;
6095            var len = widths.length;
6096            var key = 0;
6097
6098            while ((key < len - 1) && (widths[key] < optimalWidth)) {
6099                key++;
6100            }
6101
6102            return widths[key].toString();
6103        }
6104
6105        function addLazyLoader() {
6106            var width = that._elements.image.getAttribute("width");
6107            var height = that._elements.image.getAttribute("height");
6108
6109            if (width && height) {
6110                var ratio = (height / width) * 100;
6111                var styles = lazyLoader.style;
6112
6113                styles["padding-bottom"] = ratio + "%";
6114
6115                for (var s in styles) {
6116                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
6117                        that._elements.image.style[s] = styles[s];
6118                    }
6119                }
6120            }
6121            that._elements.image.setAttribute("src", EMPTY_PIXEL);
6122            that._elements.image.classList.add(lazyLoader.cssClass);
6123            that._lazyLoaderShowing = true;
6124        }
6125
6126        function unwrapNoScript() {
6127            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
6128            var parser = new DOMParser();
6129
6130            // temporary document avoids requesting the image before removing its src
6131            var temporaryDocument = parser.parseFromString(markup, "text/html");
6132            var imageElement = temporaryDocument.querySelector(selectors.image);
6133            imageElement.removeAttribute("src");
6134            that._elements.container.insertBefore(imageElement, that._elements.noscript);
6135
6136            var mapElement = temporaryDocument.querySelector(selectors.map);
6137            if (mapElement) {
6138                that._elements.container.insertBefore(mapElement, that._elements.noscript);
6139            }
6140
6141            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
6142            if (that._elements.container.matches(selectors.image)) {
6143                that._elements.image = that._elements.container;
6144            } else {
6145                that._elements.image = that._elements.container.querySelector(selectors.image);
6146            }
6147
6148            that._elements.map = that._elements.container.querySelector(selectors.map);
6149            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
6150        }
6151
6152        function removeLazyLoader() {
6153            that._elements.image.classList.remove(lazyLoader.cssClass);
6154            for (var property in lazyLoader.style) {
6155                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
6156                    that._elements.image.style[property] = "";
6157                }
6158            }
6159            that._elements.image.removeEventListener("load", removeLazyLoader);
6160            that._lazyLoaderShowing = false;
6161        }
6162
6163        function isLazyVisible() {
6164            if (that._elements.container.offsetParent === null) {
6165                return false;
6166            }
6167
6168            var wt = window.pageYOffset;
6169            var wb = wt + document.documentElement.clientHeight;
6170            var et = that._elements.container.getBoundingClientRect().top + wt;
6171            var eb = et + that._elements.container.clientHeight;
6172
6173            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
6174        }
6175
6176        function resizeAreas() {
6177            if (that._elements.areas && that._elements.areas.length > 0) {
6178                for (var i = 0; i < that._elements.areas.length; i++) {
6179                    var width = that._elements.image.width;
6180                    var height = that._elements.image.height;
6181
6182                    if (width && height) {
6183                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
6184                        if (relcoords) {
6185                            var relativeCoordinates = relcoords.split(",");
6186                            var coordinates = new Array(relativeCoordinates.length);
6187
6188                            for (var j = 0; j < coordinates.length; j++) {
6189                                if (j % 2 === 0) {
6190                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
6191                                } else {
6192                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
6193                                }
6194                            }
6195
6196                            that._elements.areas[i].coords = coordinates;
6197                        }
6198                    }
6199                }
6200            }
6201        }
6202
6203        function cacheElements(wrapper) {
6204            that._elements = {};
6205            that._elements.self = wrapper;
6206            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
6207
6208            for (var i = 0; i < hooks.length; i++) {
6209                var hook = hooks[i];
6210                var capitalized = IS;
6211                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
6212                var key = hook.dataset[NS + "Hook" + capitalized];
6213                that._elements[key] = hook;
6214            }
6215        }
6216
6217        function setupProperties(options) {
6218            that._properties = {};
6219
6220            for (var key in properties) {
6221                if (Object.prototype.hasOwnProperty.call(properties, key)) {
6222                    var property = properties[key];
6223                    if (options && options[key] != null) {
6224                        if (property && typeof property.transform === "function") {
6225                            that._properties[key] = property.transform(options[key]);
6226                        } else {
6227                            that._properties[key] = options[key];
6228                        }
6229                    } else {
6230                        that._properties[key] = properties[key]["default"];
6231                    }
6232                }
6233            }
6234        }
6235
6236        function onWindowResize() {
6237            that.update();
6238            resizeAreas();
6239        }
6240
6241        function onLoad() {
6242            resizeAreas();
6243        }
6244
6245        that.update = function() {
6246            if (that._properties.lazy) {
6247                if (isLazyVisible()) {
6248                    loadImage();
6249                }
6250            } else {
6251                loadImage();
6252            }
6253        };
6254
6255        if (config && config.element) {
6256            init(config);
6257        }
6258    }
6259
6260    function onDocumentReady() {
6261        var elements = document.querySelectorAll(selectors.self);
6262        for (var i = 0; i < elements.length; i++) {
6263            new Image({ element: elements[i], options: readData(elements[i]) });
6264        }
6265
6266        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
6267        var body             = document.querySelector("body");
6268        var observer         = new MutationObserver(function(mutations) {
6269            mutations.forEach(function(mutation) {
6270
6271                // needed for IE
6272                var nodesArray = [].slice.call(mutation.addedNodes);
6273                if (nodesArray.length > 0) {
6274                    nodesArray.forEach(function(addedNode) {
6275                        if (addedNode.querySelectorAll) {
6276                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
6277                            elementsArray.forEach(function(element) {
6278                                new Image({ element: element, options: readData(element) });
6279                            });
6280                        }
6281                    });
6282                }
6283            });
6284        });
6285
6286        observer.observe(body, {
6287            subtree: true,
6288            childList: true,
6289            characterData: true
6290        });
6291    }
6292
6293    if (document.readyState !== "loading") {
6294        onDocumentReady();
6295    } else {
6296        document.addEventListener("DOMContentLoaded", onDocumentReady);
6297    }
6298
6299    /*
6300        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
6301        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
6302     */
6303    function decodeNoscript(text) {
6304        text = text.replace(/&(amp;)*lt;/g, "<");
6305        text = text.replace(/&(amp;)*gt;/g, ">");
6306        return text;
6307    }
6308
6309})();
6310
6311/*******************************************************************************
6312 * Copyright 2017 Adobe
6313 *
6314 * Licensed under the Apache License, Version 2.0 (the "License");
6315 * you may not use this file except in compliance with the License.
6316 * You may obtain a copy of the License at
6317 *
6318 *     http://www.apache.org/licenses/LICENSE-2.0
6319 *
6320 * Unless required by applicable law or agreed to in writing, software
6321 * distributed under the License is distributed on an "AS IS" BASIS,
6322 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6323 * See the License for the specific language governing permissions and
6324 * limitations under the License.
6325 ******************************************************************************/
6326if (window.Element && !Element.prototype.closest) {
6327    // eslint valid-jsdoc: "off"
6328    Element.prototype.closest =
6329        function(s) {
6330            "use strict";
6331            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
6332            var el      = this;
6333            var i;
6334            do {
6335                i = matches.length;
6336                while (--i >= 0 && matches.item(i) !== el) {
6337                    // continue
6338                }
6339            } while ((i < 0) && (el = el.parentElement));
6340            return el;
6341        };
6342}
6343
6344if (window.Element && !Element.prototype.matches) {
6345    Element.prototype.matches =
6346        Element.prototype.matchesSelector ||
6347        Element.prototype.mozMatchesSelector ||
6348        Element.prototype.msMatchesSelector ||
6349        Element.prototype.oMatchesSelector ||
6350        Element.prototype.webkitMatchesSelector ||
6351        function(s) {
6352            "use strict";
6353            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
6354            var i       = matches.length;
6355            while (--i >= 0 && matches.item(i) !== this) {
6356                // continue
6357            }
6358            return i > -1;
6359        };
6360}
6361
6362if (!Object.assign) {
6363    Object.assign = function(target, varArgs) { // .length of function is 2
6364        "use strict";
6365        if (target === null) {
6366            throw new TypeError("Cannot convert undefined or null to object");
6367        }
6368
6369        var to = Object(target);
6370
6371        for (var index = 1; index < arguments.length; index++) {
6372            var nextSource = arguments[index];
6373
6374            if (nextSource !== null) {
6375                for (var nextKey in nextSource) {
6376                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
6377                        to[nextKey] = nextSource[nextKey];
6378                    }
6379                }
6380            }
6381        }
6382        return to;
6383    };
6384}
6385
6386(function(arr) {
6387    "use strict";
6388    arr.forEach(function(item) {
6389        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
6390            return;
6391        }
6392        Object.defineProperty(item, "remove", {
6393            configurable: true,
6394            enumerable: true,
6395            writable: true,
6396            value: function remove() {
6397                this.parentNode.removeChild(this);
6398            }
6399        });
6400    });
6401})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
6402
6403/*******************************************************************************
6404 * Copyright 2016 Adobe
6405 *
6406 * Licensed under the Apache License, Version 2.0 (the "License");
6407 * you may not use this file except in compliance with the License.
6408 * You may obtain a copy of the License at
6409 *
6410 *     http://www.apache.org/licenses/LICENSE-2.0
6411 *
6412 * Unless required by applicable law or agreed to in writing, software
6413 * distributed under the License is distributed on an "AS IS" BASIS,
6414 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6415 * See the License for the specific language governing permissions and
6416 * limitations under the License.
6417 ******************************************************************************/
6418(function() {
6419    "use strict";
6420
6421    var NS = "cmp";
6422    var IS = "image";
6423    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
6424    var LAZY_THRESHOLD_DEFAULT = 0;
6425    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
6426    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
6427    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
6428
6429    var selectors = {
6430//        self: "[data-" + NS + '-is="' + IS + '"]',
6431        self: '[data-test-primary="image"]',
6432        image: '[data-cmp-hook-image="image"]',
6433        map: '[data-cmp-hook-image="map"]',
6434        area: '[data-cmp-hook-image="area"]'
6435    };
6436
6437    var lazyLoader = {
6438        "cssClass": "cmp-image__image--is-loading",
6439        "style": {
6440            "height": 0,
6441            "padding-bottom": "" // will be replaced with % ratio
6442        }
6443    };
6444
6445    var properties = {
6446        /**
6447         * An array of alternative image widths (in pixels).
6448         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
6449         *
6450         * @memberof Image
6451         * @type {Number[]}
6452         * @default []
6453         */
6454        "widths": {
6455            "default": [],
6456            "transform": function(value) {
6457                var widths = [];
6458                value.split(",").forEach(function(item) {
6459                    item = parseFloat(item);
6460                    if (!isNaN(item)) {
6461                        widths.push(item);
6462                    }
6463                });
6464                return widths;
6465            }
6466        },
6467        /**
6468         * Indicates whether the image should be rendered lazily.
6469         *
6470         * @memberof Image
6471         * @type {Boolean}
6472         * @default false
6473         */
6474        "lazy": {
6475            "default": false,
6476            "transform": function(value) {
6477                return !(value === null || typeof value === "undefined");
6478            }
6479        },
6480        /**
6481         * Indicates image is DynamicMedia image.
6482         *
6483         * @memberof Image
6484         * @type {Boolean}
6485         * @default false
6486         */
6487        "dmimage": {
6488            "default": false,
6489            "transform": function(value) {
6490                return !(value === null || typeof value === "undefined");
6491            }
6492        },
6493        /**
6494         * The lazy threshold.
6495         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
6496         * to load.
6497         *
6498         * @memberof Image
6499         * @type {Number}
6500         * @default 0
6501         */
6502        "lazythreshold": {
6503            "default": 0,
6504            "transform": function(value) {
6505                var val =  parseInt(value);
6506                if (isNaN(val)) {
6507                    return LAZY_THRESHOLD_DEFAULT;
6508                }
6509                return val;
6510            }
6511        },
6512        /**
6513         * The image source.
6514         *
6515         * Can be a simple image source, or a URI template representation that
6516         * can be variable expanded - useful for building an image configuration with an alternative width.
6517         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
6518         *
6519         * @memberof Image
6520         * @type {String}
6521         */
6522        "src": {
6523            "transform": function(value) {
6524                return decodeURIComponent(value);
6525            }
6526        }
6527    };
6528
6529    var devicePixelRatio = window.devicePixelRatio || 1;
6530
6531    function readData(element) {
6532        var data = element.dataset;
6533        var options = [];
6534        var capitalized = IS;
6535        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
6536        var reserved = ["is", "hook" + capitalized];
6537
6538        for (var key in data) {
6539            if (Object.prototype.hasOwnProperty.call(data, key)) {
6540                var value = data[key];
6541
6542                if (key.indexOf(NS) === 0) {
6543                    key = key.slice(NS.length);
6544                    key = key.charAt(0).toLowerCase() + key.substring(1);
6545
6546                    if (reserved.indexOf(key) === -1) {
6547                        options[key] = value;
6548                    }
6549                }
6550            }
6551        }
6552        return options;
6553    }
6554
6555    function Image(config) {
6556        var that = this;
6557
6558        var smartCrops = {};
6559
6560        var useAssetDelivery = false;
6561        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
6562
6563        function init(config) {
6564            // prevents multiple initialization
6565            config.element.removeAttribute("data-" + NS + "-is");
6566
6567            // check if asset delivery is used
6568            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
6569                useAssetDelivery = true;
6570                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
6571            }
6572
6573            setupProperties(config.options);
6574            cacheElements(config.element);
6575            // check image is DM asset; if true try to make req=set
6576            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
6577                var request = new XMLHttpRequest();
6578                var urlTemplatePart = decodeURIComponent(config.options.src).split(srcUriTemplateWidthVar)[0];
6579                var url = urlTemplatePart + (urlTemplatePart.indexOf("?") < 0 ? "?" : "") + "req=set,json";
6580                request.open("GET", url, false);
6581                request.onload = function() {
6582                    if (request.status >= 200 && request.status < 400) {
6583                        // success status
6584                        var responseText = request.responseText;
6585                        var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
6586                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
6587                        var resPayload = rePayload.exec(responseText);
6588                        var payload;
6589                        if (resPayload) {
6590                            var payloadStr = resPayload[2];
6591                            if (rePayloadJSON.test(payloadStr)) {
6592                                payload = JSON.parse(payloadStr);
6593                            }
6594
6595                        }
6596                        // check "relation" - only in case of smartcrop preset
6597                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
6598                            for (var i = 0; i < payload.set.relation.length; i++) {
6599                                smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
6600                                    ":" + payload.set.relation[i].userdata.SmartCropDef;
6601                            }
6602                        }
6603                    } else {
6604                        // error status
6605                    }
6606                };
6607                request.send();
6608            }
6609
6610            if (!that._elements.noscript) {
6611                return;
6612            }
6613
6614            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
6615
6616            unwrapNoScript();
6617
6618            if (that._properties.lazy) {
6619                addLazyLoader();
6620            }
6621
6622            if (that._elements.map) {
6623                that._elements.image.addEventListener("load", onLoad);
6624            }
6625
6626            window.addEventListener("resize", onWindowResize);
6627            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
6628                document.addEventListener(name, that.update);
6629            });
6630
6631            that._elements.image.addEventListener("cmp-image-redraw", that.update);
6632            that.update();
6633        }
6634
6635        function loadImage() {
6636            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
6637            var replacement;
6638            if (Object.keys(smartCrops).length > 0) {
6639                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
6640                replacement = smartCrops[optimalWidth];
6641            } else {
6642                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
6643            }
6644            if (useAssetDelivery) {
6645                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
6646            }
6647            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
6648            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
6649
6650            var imgSrcAttribute = that._elements.image.getAttribute("src");
6651
6652            if (url !== imgSrcAttribute) {
6653                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
6654                    that._elements.image.setAttribute("src", url);
6655                } else {
6656                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
6657                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
6658                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
6659                    if (isImageRefSame && urlTemplateParts.length > 1) {
6660                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
6661                    }
6662                    if (isImageRefSame) {
6663                        that._elements.image.setAttribute("src", url);
6664                        if (!hasWidths) {
6665                            window.removeEventListener("scroll", that.update);
6666                        }
6667                    }
6668                }
6669            }
6670            if (that._lazyLoaderShowing) {
6671                that._elements.image.addEventListener("load", removeLazyLoader);
6672            }
6673        }
6674
6675        function getOptimalWidth(widths, useDevicePixelRatio) {
6676            var container = that._elements.self;
6677            var containerWidth = container.clientWidth;
6678            while (containerWidth === 0 && container.parentNode) {
6679                container = container.parentNode;
6680                containerWidth = container.clientWidth;
6681            }
6682
6683            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
6684            var optimalWidth = containerWidth * dpr;
6685            var len = widths.length;
6686            var key = 0;
6687
6688            while ((key < len - 1) && (widths[key] < optimalWidth)) {
6689                key++;
6690            }
6691
6692            return widths[key].toString();
6693        }
6694
6695        function addLazyLoader() {
6696            var width = that._elements.image.getAttribute("width");
6697            var height = that._elements.image.getAttribute("height");
6698
6699            if (width && height) {
6700                var ratio = (height / width) * 100;
6701                var styles = lazyLoader.style;
6702
6703                styles["padding-bottom"] = ratio + "%";
6704
6705                for (var s in styles) {
6706                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
6707                        that._elements.image.style[s] = styles[s];
6708                    }
6709                }
6710            }
6711            that._elements.image.setAttribute("src", EMPTY_PIXEL);
6712            that._elements.image.classList.add(lazyLoader.cssClass);
6713            that._lazyLoaderShowing = true;
6714        }
6715
6716        function unwrapNoScript() {
6717            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
6718            var parser = new DOMParser();
6719
6720            // temporary document avoids requesting the image before removing its src
6721            var temporaryDocument = parser.parseFromString(markup, "text/html");
6722            var imageElement = temporaryDocument.querySelector(selectors.image);
6723            imageElement.removeAttribute("src");
6724            that._elements.container.insertBefore(imageElement, that._elements.noscript);
6725
6726            var mapElement = temporaryDocument.querySelector(selectors.map);
6727            if (mapElement) {
6728                that._elements.container.insertBefore(mapElement, that._elements.noscript);
6729            }
6730
6731            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
6732            if (that._elements.container.matches(selectors.image)) {
6733                that._elements.image = that._elements.container;
6734            } else {
6735                that._elements.image = that._elements.container.querySelector(selectors.image);
6736            }
6737
6738            that._elements.map = that._elements.container.querySelector(selectors.map);
6739            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
6740        }
6741
6742        function removeLazyLoader() {
6743            that._elements.image.classList.remove(lazyLoader.cssClass);
6744            for (var property in lazyLoader.style) {
6745                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
6746                    that._elements.image.style[property] = "";
6747                }
6748            }
6749            that._elements.image.removeEventListener("load", removeLazyLoader);
6750            that._lazyLoaderShowing = false;
6751        }
6752
6753        function isLazyVisible() {
6754            if (that._elements.container.offsetParent === null) {
6755                return false;
6756            }
6757
6758            var wt = window.pageYOffset;
6759            var wb = wt + document.documentElement.clientHeight;
6760            var et = that._elements.container.getBoundingClientRect().top + wt;
6761            var eb = et + that._elements.container.clientHeight;
6762
6763            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
6764        }
6765
6766        function resizeAreas() {
6767            if (that._elements.areas && that._elements.areas.length > 0) {
6768                for (var i = 0; i < that._elements.areas.length; i++) {
6769                    var width = that._elements.image.width;
6770                    var height = that._elements.image.height;
6771
6772                    if (width && height) {
6773                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
6774                        if (relcoords) {
6775                            var relativeCoordinates = relcoords.split(",");
6776                            var coordinates = new Array(relativeCoordinates.length);
6777
6778                            for (var j = 0; j < coordinates.length; j++) {
6779                                if (j % 2 === 0) {
6780                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
6781                                } else {
6782                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
6783                                }
6784                            }
6785
6786                            that._elements.areas[i].coords = coordinates;
6787                        }
6788                    }
6789                }
6790            }
6791        }
6792
6793        function cacheElements(wrapper) {
6794            that._elements = {};
6795            that._elements.self = wrapper;
6796            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
6797
6798            for (var i = 0; i < hooks.length; i++) {
6799                var hook = hooks[i];
6800                var capitalized = IS;
6801                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
6802                var key = hook.dataset[NS + "Hook" + capitalized];
6803                that._elements[key] = hook;
6804            }
6805        }
6806
6807        function setupProperties(options) {
6808            that._properties = {};
6809
6810            for (var key in properties) {
6811                if (Object.prototype.hasOwnProperty.call(properties, key)) {
6812                    var property = properties[key];
6813                    if (options && options[key] != null) {
6814                        if (property && typeof property.transform === "function") {
6815                            that._properties[key] = property.transform(options[key]);
6816                        } else {
6817                            that._properties[key] = options[key];
6818                        }
6819                    } else {
6820                        that._properties[key] = properties[key]["default"];
6821                    }
6822                }
6823            }
6824        }
6825
6826        function onWindowResize() {
6827            that.update();
6828            resizeAreas();
6829        }
6830
6831        function onLoad() {
6832            resizeAreas();
6833        }
6834
6835        that.update = function() {
6836            if (that._properties.lazy) {
6837                if (isLazyVisible()) {
6838                    loadImage();
6839                }
6840            } else {
6841                loadImage();
6842            }
6843        };
6844
6845        if (config && config.element) {
6846            init(config);
6847        }
6848    }
6849
6850    function onDocumentReady() {
6851        var elements = document.querySelectorAll(selectors.self);
6852        for (var i = 0; i < elements.length; i++) {
6853            new Image({ element: elements[i], options: readData(elements[i]) });
6854        }
6855
6856        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
6857        var body             = document.querySelector("body");
6858        var observer         = new MutationObserver(function(mutations) {
6859            mutations.forEach(function(mutation) {
6860
6861                // needed for IE
6862                var nodesArray = [].slice.call(mutation.addedNodes);
6863                if (nodesArray.length > 0) {
6864                    nodesArray.forEach(function(addedNode) {
6865                        if (addedNode.querySelectorAll) {
6866                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
6867                            elementsArray.forEach(function(element) {
6868                                new Image({ element: element, options: readData(element) });
6869                            });
6870                        }
6871                    });
6872                }
6873            });
6874        });
6875
6876        observer.observe(body, {
6877            subtree: true,
6878            childList: true,
6879            characterData: true
6880        });
6881    }
6882
6883    if (document.readyState !== "loading") {
6884        onDocumentReady();
6885    } else {
6886        document.addEventListener("DOMContentLoaded", onDocumentReady);
6887    }
6888
6889    /*
6890        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
6891        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
6892     */
6893    function decodeNoscript(text) {
6894        text = text.replace(/&(amp;)*lt;/g, "<");
6895        text = text.replace(/&(amp;)*gt;/g, ">");
6896        return text;
6897    }
6898
6899})();
6900
6901/*******************************************************************************
6902 * Copyright 2017 Adobe
6903 *
6904 * Licensed under the Apache License, Version 2.0 (the "License");
6905 * you may not use this file except in compliance with the License.
6906 * You may obtain a copy of the License at
6907 *
6908 *     http://www.apache.org/licenses/LICENSE-2.0
6909 *
6910 * Unless required by applicable law or agreed to in writing, software
6911 * distributed under the License is distributed on an "AS IS" BASIS,
6912 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6913 * See the License for the specific language governing permissions and
6914 * limitations under the License.
6915 ******************************************************************************/
6916if (window.Element && !Element.prototype.closest) {
6917    // eslint valid-jsdoc: "off"
6918    Element.prototype.closest =
6919        function(s) {
6920            "use strict";
6921            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
6922            var el      = this;
6923            var i;
6924            do {
6925                i = matches.length;
6926                while (--i >= 0 && matches.item(i) !== el) {
6927                    // continue
6928                }
6929            } while ((i < 0) && (el = el.parentElement));
6930            return el;
6931        };
6932}
6933
6934if (window.Element && !Element.prototype.matches) {
6935    Element.prototype.matches =
6936        Element.prototype.matchesSelector ||
6937        Element.prototype.mozMatchesSelector ||
6938        Element.prototype.msMatchesSelector ||
6939        Element.prototype.oMatchesSelector ||
6940        Element.prototype.webkitMatchesSelector ||
6941        function(s) {
6942            "use strict";
6943            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
6944            var i       = matches.length;
6945            while (--i >= 0 && matches.item(i) !== this) {
6946                // continue
6947            }
6948            return i > -1;
6949        };
6950}
6951
6952if (!Object.assign) {
6953    Object.assign = function(target, varArgs) { // .length of function is 2
6954        "use strict";
6955        if (target === null) {
6956            throw new TypeError("Cannot convert undefined or null to object");
6957        }
6958
6959        var to = Object(target);
6960
6961        for (var index = 1; index < arguments.length; index++) {
6962            var nextSource = arguments[index];
6963
6964            if (nextSource !== null) {
6965                for (var nextKey in nextSource) {
6966                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
6967                        to[nextKey] = nextSource[nextKey];
6968                    }
6969                }
6970            }
6971        }
6972        return to;
6973    };
6974}
6975
6976(function(arr) {
6977    "use strict";
6978    arr.forEach(function(item) {
6979        if (Object.prototype.hasOwnProperty.call(item, "remove")) {
6980            return;
6981        }
6982        Object.defineProperty(item, "remove", {
6983            configurable: true,
6984            enumerable: true,
6985            writable: true,
6986            value: function remove() {
6987                this.parentNode.removeChild(this);
6988            }
6989        });
6990    });
6991})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
6992
6993/*******************************************************************************
6994 * Copyright 2016 Adobe
6995 *
6996 * Licensed under the Apache License, Version 2.0 (the "License");
6997 * you may not use this file except in compliance with the License.
6998 * You may obtain a copy of the License at
6999 *
7000 *     http://www.apache.org/licenses/LICENSE-2.0
7001 *
7002 * Unless required by applicable law or agreed to in writing, software
7003 * distributed under the License is distributed on an "AS IS" BASIS,
7004 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7005 * See the License for the specific language governing permissions and
7006 * limitations under the License.
7007 ******************************************************************************/
7008(function() {
7009    "use strict";
7010
7011    var NS = "cmp";
7012    var IS = "image";
7013
7014    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
7015    var LAZY_THRESHOLD_DEFAULT = 0;
7016    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
7017    var SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY = "width={width}";
7018    var SRC_URI_TEMPLATE_DPR_VAR = "{dpr}";
7019
7020    var selectors = {
7021        self: "[data-" + NS + '-is="' + IS + '"]',
7022        image: '[data-cmp-hook-image="image"]',
7023        map: '[data-cmp-hook-image="map"]',
7024        area: '[data-cmp-hook-image="area"]'
7025    };
7026
7027    var lazyLoader = {
7028        "cssClass": "cmp-image__image--is-loading",
7029        "style": {
7030            "height": 0,
7031            "padding-bottom": "" // will be replaced with % ratio
7032        }
7033    };
7034
7035    var properties = {
7036        /**
7037         * An array of alternative image widths (in pixels).
7038         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
7039         *
7040         * @memberof Image
7041         * @type {Number[]}
7042         * @default []
7043         */
7044        "widths": {
7045            "default": [],
7046            "transform": function(value) {
7047                var widths = [];
7048                value.split(",").forEach(function(item) {
7049                    item = parseFloat(item);
7050                    if (!isNaN(item)) {
7051                        widths.push(item);
7052                    }
7053                });
7054                return widths;
7055            }
7056        },
7057        /**
7058         * Indicates whether the image should be rendered lazily.
7059         *
7060         * @memberof Image
7061         * @type {Boolean}
7062         * @default false
7063         */
7064        "lazy": {
7065            "default": false,
7066            "transform": function(value) {
7067                return !(value === null || typeof value === "undefined");
7068            }
7069        },
7070        /**
7071         * Indicates image is DynamicMedia image.
7072         *
7073         * @memberof Image
7074         * @type {Boolean}
7075         * @default false
7076         */
7077        "dmimage": {
7078            "default": false,
7079            "transform": function(value) {
7080                return !(value === null || typeof value === "undefined");
7081            }
7082        },
7083        /**
7084         * The lazy threshold.
7085         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
7086         * to load.
7087         *
7088         * @memberof Image
7089         * @type {Number}
7090         * @default 0
7091         */
7092        "lazythreshold": {
7093            "default": 0,
7094            "transform": function(value) {
7095                var val =  parseInt(value);
7096                if (isNaN(val)) {
7097                    return LAZY_THRESHOLD_DEFAULT;
7098                }
7099                return val;
7100            }
7101        },
7102        /**
7103         * The image source.
7104         *
7105         * Can be a simple image source, or a URI template representation that
7106         * can be variable expanded - useful for building an image configuration with an alternative width.
7107         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
7108         *
7109         * @memberof Image
7110         * @type {String}
7111         */
7112        "src": {
7113            "transform": function(value) {
7114                return decodeURIComponent(value);
7115            }
7116        }
7117    };
7118
7119    var devicePixelRatio = window.devicePixelRatio || 1;
7120
7121    function readData(element) {
7122        var data = element.dataset;
7123        var options = [];
7124        var capitalized = IS;
7125        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
7126        var reserved = ["is", "hook" + capitalized];
7127
7128        for (var key in data) {
7129            if (Object.prototype.hasOwnProperty.call(data, key)) {
7130                var value = data[key];
7131
7132                if (key.indexOf(NS) === 0) {
7133                    key = key.slice(NS.length);
7134                    key = key.charAt(0).toLowerCase() + key.substring(1);
7135
7136                    if (reserved.indexOf(key) === -1) {
7137                        options[key] = value;
7138                    }
7139                }
7140            }
7141        }
7142        return options;
7143    }
7144
7145    function Image(config) {
7146        var that = this;
7147
7148        var smartCrops = {};
7149
7150        var useAssetDelivery = false;
7151        var srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR;
7152
7153        function init(config) {
7154            // prevents multiple initialization
7155            config.element.removeAttribute("data-" + NS + "-is");
7156
7157            // check if asset delivery is used
7158            if (config.options.src && config.options.src.indexOf(SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY) >= 0) {
7159                useAssetDelivery = true;
7160                srcUriTemplateWidthVar = SRC_URI_TEMPLATE_WIDTH_VAR_ASSET_DELIVERY;
7161            }
7162
7163            setupProperties(config.options);
7164            cacheElements(config.element);
7165            // check image is DM asset; if true try to make req=set
7166            if (config.options.src && Object.prototype.hasOwnProperty.call(config.options, "dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
7167                var request = new XMLHttpRequest();
7168                var urlTemplatePart = decodeURIComponent(config.options.src).split(srcUriTemplateWidthVar)[0];
7169                var url = urlTemplatePart + (urlTemplatePart.indexOf("?") < 0 ? "?" : "") + "req=set,json";
7170
7171                request.open("GET", url, false);
7172                request.onload = function() {
7173                    if (request.status >= 200 && request.status < 400) {
7174                        // success status
7175                        var responseText = request.responseText;
7176                        var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
7177                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
7178                        var resPayload = rePayload.exec(responseText);
7179                        var payload;
7180                        if (resPayload) {
7181                            var payloadStr = resPayload[2];
7182                            if (rePayloadJSON.test(payloadStr)) {
7183                                payload = JSON.parse(payloadStr);
7184                            }
7185
7186                        }
7187                        // check "relation" - only in case of smartcrop preset
7188                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
7189                            for (var i = 0; i < payload.set.relation.length; i++) {
7190                                smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] =
7191                                    ":" + payload.set.relation[i].userdata.SmartCropDef;
7192                            }
7193                        }
7194                    } else {
7195                        // error status
7196                    }
7197                };
7198                request.send();
7199            }
7200
7201            if (!that._elements.noscript) {
7202                return;
7203            }
7204
7205            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
7206
7207            unwrapNoScript();
7208
7209            if (that._properties.lazy) {
7210                addLazyLoader();
7211            }
7212
7213            if (that._elements.map) {
7214                that._elements.image.addEventListener("load", onLoad);
7215            }
7216
7217            window.addEventListener("resize", onWindowResize);
7218            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
7219                document.addEventListener(name, that.update);
7220            });
7221
7222            that._elements.image.addEventListener("cmp-image-redraw", that.update);
7223            that.update();
7224        }
7225
7226        function loadImage() {
7227            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
7228            var replacement;
7229            if (Object.keys(smartCrops).length > 0) {
7230                var optimalWidth = getOptimalWidth(Object.keys(smartCrops), false);
7231                replacement = smartCrops[optimalWidth];
7232            } else {
7233                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths, true) : "";
7234            }
7235            if (useAssetDelivery) {
7236                replacement = replacement !== "" ? ("width=" + replacement.substring(1)) : "";
7237            }
7238            var url = that._properties.src.replace(srcUriTemplateWidthVar, replacement);
7239            url = url.replace(SRC_URI_TEMPLATE_DPR_VAR, devicePixelRatio);
7240
7241            var imgSrcAttribute = that._elements.image.getAttribute("src");
7242
7243            if (url !== imgSrcAttribute) {
7244                if (imgSrcAttribute === null || imgSrcAttribute === EMPTY_PIXEL) {
7245                    that._elements.image.setAttribute("src", url);
7246                } else {
7247                    var urlTemplateParts = that._properties.src.split(srcUriTemplateWidthVar);
7248                    // check if image src was dynamically swapped meanwhile (e.g. by Target)
7249                    var isImageRefSame = imgSrcAttribute.startsWith(urlTemplateParts[0]);
7250                    if (isImageRefSame && urlTemplateParts.length > 1) {
7251                        isImageRefSame = imgSrcAttribute.endsWith(urlTemplateParts[urlTemplateParts.length - 1]);
7252                    }
7253                    if (isImageRefSame) {
7254                        that._elements.image.setAttribute("src", url);
7255                        if (!hasWidths) {
7256                            window.removeEventListener("scroll", that.update);
7257                        }
7258                    }
7259                }
7260            }
7261            if (that._lazyLoaderShowing) {
7262                that._elements.image.addEventListener("load", removeLazyLoader);
7263            }
7264        }
7265
7266        function getOptimalWidth(widths, useDevicePixelRatio) {
7267            var container = that._elements.self;
7268            var containerWidth = container.clientWidth;
7269            while (containerWidth === 0 && container.parentNode) {
7270                container = container.parentNode;
7271                containerWidth = container.clientWidth;
7272            }
7273
7274            var dpr = useDevicePixelRatio ? devicePixelRatio : 1;
7275            var optimalWidth = containerWidth * dpr;
7276            var len = widths.length;
7277            var key = 0;
7278
7279            while ((key < len - 1) && (widths[key] < optimalWidth)) {
7280                key++;
7281            }
7282
7283            return widths[key].toString();
7284        }
7285
7286        function addLazyLoader() {
7287            var width = that._elements.image.getAttribute("width");
7288            var height = that._elements.image.getAttribute("height");
7289
7290            if (width && height) {
7291                var ratio = (height / width) * 100;
7292                var styles = lazyLoader.style;
7293
7294                styles["padding-bottom"] = ratio + "%";
7295
7296                for (var s in styles) {
7297                    if (Object.prototype.hasOwnProperty.call(styles, s)) {
7298                        that._elements.image.style[s] = styles[s];
7299                    }
7300                }
7301            }
7302            that._elements.image.setAttribute("src", EMPTY_PIXEL);
7303            that._elements.image.classList.add(lazyLoader.cssClass);
7304            that._lazyLoaderShowing = true;
7305        }
7306
7307        function unwrapNoScript() {
7308            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
7309            var parser = new DOMParser();
7310
7311            // temporary document avoids requesting the image before removing its src
7312            var temporaryDocument = parser.parseFromString(markup, "text/html");
7313            var imageElement = temporaryDocument.querySelector(selectors.image);
7314            imageElement.removeAttribute("src");
7315            that._elements.container.insertBefore(imageElement, that._elements.noscript);
7316
7317            var mapElement = temporaryDocument.querySelector(selectors.map);
7318            if (mapElement) {
7319                that._elements.container.insertBefore(mapElement, that._elements.noscript);
7320            }
7321
7322            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
7323            if (that._elements.container.matches(selectors.image)) {
7324                that._elements.image = that._elements.container;
7325            } else {
7326                that._elements.image = that._elements.container.querySelector(selectors.image);
7327            }
7328
7329            that._elements.map = that._elements.container.querySelector(selectors.map);
7330            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
7331        }
7332
7333        function removeLazyLoader() {
7334            that._elements.image.classList.remove(lazyLoader.cssClass);
7335            for (var property in lazyLoader.style) {
7336                if (Object.prototype.hasOwnProperty.call(lazyLoader.style, property)) {
7337                    that._elements.image.style[property] = "";
7338                }
7339            }
7340            that._elements.image.removeEventListener("load", removeLazyLoader);
7341            that._lazyLoaderShowing = false;
7342        }
7343
7344        function isLazyVisible() {
7345            if (that._elements.container.offsetParent === null) {
7346                return false;
7347            }
7348
7349            var wt = window.pageYOffset;
7350            var wb = wt + document.documentElement.clientHeight;
7351            var et = that._elements.container.getBoundingClientRect().top + wt;
7352            var eb = et + that._elements.container.clientHeight;
7353
7354            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
7355        }
7356
7357        function resizeAreas() {
7358            if (that._elements.areas && that._elements.areas.length > 0) {
7359                for (var i = 0; i < that._elements.areas.length; i++) {
7360                    var width = that._elements.image.width;
7361                    var height = that._elements.image.height;
7362
7363                    if (width && height) {
7364                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
7365                        if (relcoords) {
7366                            var relativeCoordinates = relcoords.split(",");
7367                            var coordinates = new Array(relativeCoordinates.length);
7368
7369                            for (var j = 0; j < coordinates.length; j++) {
7370                                if (j % 2 === 0) {
7371                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
7372                                } else {
7373                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
7374                                }
7375                            }
7376
7377                            that._elements.areas[i].coords = coordinates;
7378                        }
7379                    }
7380                }
7381            }
7382        }
7383
7384        function cacheElements(wrapper) {
7385            that._elements = {};
7386            that._elements.self = wrapper;
7387            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
7388
7389            for (var i = 0; i < hooks.length; i++) {
7390                var hook = hooks[i];
7391                var capitalized = IS;
7392                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
7393                var key = hook.dataset[NS + "Hook" + capitalized];
7394                that._elements[key] = hook;
7395            }
7396        }
7397
7398        function setupProperties(options) {
7399            that._properties = {};
7400
7401            for (var key in properties) {
7402                if (Object.prototype.hasOwnProperty.call(properties, key)) {
7403                    var property = properties[key];
7404                    if (options && options[key] != null) {
7405                        if (property && typeof property.transform === "function") {
7406                            that._properties[key] = property.transform(options[key]);
7407                        } else {
7408                            that._properties[key] = options[key];
7409                        }
7410                    } else {
7411                        that._properties[key] = properties[key]["default"];
7412                    }
7413                }
7414            }
7415        }
7416
7417        function onWindowResize() {
7418            that.update();
7419            resizeAreas();
7420        }
7421
7422        function onLoad() {
7423            resizeAreas();
7424        }
7425
7426        that.update = function() {
7427            if (that._properties.lazy) {
7428                if (isLazyVisible()) {
7429                    loadImage();
7430                }
7431            } else {
7432                loadImage();
7433            }
7434        };
7435
7436        if (config && config.element) {
7437            init(config);
7438        }
7439    }
7440
7441    function onDocumentReady() {
7442        var elements = document.querySelectorAll(selectors.self);
7443        for (var i = 0; i < elements.length; i++) {
7444            new Image({ element: elements[i], options: readData(elements[i]) });
7445        }
7446
7447        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
7448        var body             = document.querySelector("body");
7449        var observer         = new MutationObserver(function(mutations) {
7450            mutations.forEach(function(mutation) {
7451                // needed for IE
7452                var nodesArray = [].slice.call(mutation.addedNodes);
7453                if (nodesArray.length > 0) {
7454                    nodesArray.forEach(function(addedNode) {
7455                        if (addedNode.querySelectorAll) {
7456                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
7457                            elementsArray.forEach(function(element) {
7458                                new Image({ element: element, options: readData(element) });
7459                            });
7460                        }
7461                    });
7462                }
7463            });
7464        });
7465
7466        observer.observe(body, {
7467            subtree: true,
7468            childList: true,
7469            characterData: true
7470        });
7471    }
7472
7473    if (document.readyState !== "loading") {
7474        onDocumentReady();
7475    } else {
7476        document.addEventListener("DOMContentLoaded", onDocumentReady);
7477    }
7478
7479    /*
7480        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
7481        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
7482     */
7483    function decodeNoscript(text) {
7484        text = text.replace(/&(amp;)*lt;/g, "<");
7485        text = text.replace(/&(amp;)*gt;/g, ">");
7486        return text;
7487    }
7488
7489})();
7490
7491/*******************************************************************************
7492 * Copyright 2022 Adobe
7493 *
7494 * Licensed under the Apache License, Version 2.0 (the "License");
7495 * you may not use this file except in compliance with the License.
7496 * You may obtain a copy of the License at
7497 *
7498 *     http://www.apache.org/licenses/LICENSE-2.0
7499 *
7500 * Unless required by applicable law or agreed to in writing, software
7501 * distributed under the License is distributed on an "AS IS" BASIS,
7502 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7503 * See the License for the specific language governing permissions and
7504 * limitations under the License.
7505 ******************************************************************************/
7506(function() {
7507    "use strict";
7508
7509    var NS = "cmp";
7510    var IS = "search";
7511
7512    var DELAY = 300; // time before fetching new results when the user is typing a search string
7513    var LOADING_DISPLAY_DELAY = 300; // minimum time during which the loading indicator is displayed
7514    var PARAM_RESULTS_OFFSET = "resultsOffset";
7515
7516    var keyCodes = {
7517        TAB: 9,
7518        ENTER: 13,
7519        ESCAPE: 27,
7520        ARROW_UP: 38,
7521        ARROW_DOWN: 40
7522    };
7523
7524    var selectors = {
7525        self: "[data-" + NS + '-is="' + IS + '"]',
7526        item: {
7527            self: "[data-" + NS + "-hook-" + IS + '="item"]',
7528            title: "[data-" + NS + "-hook-" + IS + '="itemTitle"]',
7529            focused: "." + NS + "-search__item--is-focused"
7530        }
7531    };
7532
7533    var properties = {
7534        /**
7535         * The minimum required length of the search term before results are fetched.
7536         *
7537         * @memberof Search
7538         * @type {Number}
7539         * @default 3
7540         */
7541        minLength: {
7542            "default": 3,
7543            transform: function(value) {
7544                value = parseFloat(value);
7545                return isNaN(value) ? null : value;
7546            }
7547        },
7548        /**
7549         * The maximal number of results fetched by a search request.
7550         *
7551         * @memberof Search
7552         * @type {Number}
7553         * @default 10
7554         */
7555        resultsSize: {
7556            "default": 10,
7557            transform: function(value) {
7558                value = parseFloat(value);
7559                return isNaN(value) ? null : value;
7560            }
7561        }
7562    };
7563
7564    var idCount = 0;
7565
7566    function readData(element) {
7567        var data = element.dataset;
7568        var options = [];
7569        var capitalized = IS;
7570        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
7571        var reserved = ["is", "hook" + capitalized];
7572
7573        for (var key in data) {
7574            if (Object.prototype.hasOwnProperty.call(data, key)) {
7575                var value = data[key];
7576
7577                if (key.indexOf(NS) === 0) {
7578                    key = key.slice(NS.length);
7579                    key = key.charAt(0).toLowerCase() + key.substring(1);
7580
7581                    if (reserved.indexOf(key) === -1) {
7582                        options[key] = value;
7583                    }
7584                }
7585            }
7586        }
7587
7588        return options;
7589    }
7590
7591    function toggleShow(element, show) {
7592        if (element) {
7593            if (show !== false) {
7594                element.style.display = "block";
7595                element.setAttribute("aria-hidden", false);
7596            } else {
7597                element.style.display = "none";
7598                element.setAttribute("aria-hidden", true);
7599            }
7600        }
7601    }
7602
7603    function serialize(form) {
7604        var query = [];
7605        if (form && form.elements) {
7606            for (var i = 0; i < form.elements.length; i++) {
7607                var node = form.elements[i];
7608                if (!node.disabled && node.name) {
7609                    var param = [node.name, encodeURIComponent(node.value)];
7610                    query.push(param.join("="));
7611                }
7612            }
7613        }
7614        return query.join("&");
7615    }
7616
7617    function mark(node, regex) {
7618        if (!node || !regex) {
7619            return;
7620        }
7621
7622        // text nodes
7623        if (node.nodeType === 3) {
7624            var nodeValue = node.nodeValue;
7625            var match = regex.exec(nodeValue);
7626
7627            if (nodeValue && match) {
7628                var element = document.createElement("mark");
7629                element.className = NS + "-search__item-mark";
7630                element.appendChild(document.createTextNode(match[0]));
7631
7632                var after = node.splitText(match.index);
7633                after.nodeValue = after.nodeValue.substring(match[0].length);
7634                node.parentNode.insertBefore(element, after);
7635            }
7636        } else if (node.hasChildNodes()) {
7637            for (var i = 0; i < node.childNodes.length; i++) {
7638                // recurse
7639                mark(node.childNodes[i], regex);
7640            }
7641        }
7642    }
7643
7644    function localizeMessage(searchElementId, message, values = []) {
7645        const i18nMessages = JSON.parse(document.querySelector("#" + searchElementId).getAttribute("data-i18n-messages"));
7646        let translation = i18nMessages[message];
7647        // Insert values
7648        if (values.length > 0) {
7649            translation = translation.replace(/{(\d+)}/g, function(match, index) {
7650                return typeof values[index] !== "undefined" ? values[index] : match;
7651            });
7652        }
7653        return translation;
7654    }
7655
7656    // useful for Accessibility, helping users with low vision and users with cognitive disabilities to identify the change in results
7657    function updateSearchResultsStatusMessageElement(searchElementId, totalResults) {
7658        var searchResultsStatusMessage = document.querySelector("#" + searchElementId + "> .cmp_search__info");
7659        searchResultsStatusMessage.style.visibility = "visible";
7660        var searchResultsFoundMessage = localizeMessage(searchElementId, totalResults === 1 ? "{0} result" : "{0} results", [totalResults]);
7661        var searchResultsNotFoundMessage = localizeMessage(searchElementId, "No results");
7662        searchResultsStatusMessage.innerText = totalResults > 0 ? searchResultsFoundMessage : searchResultsNotFoundMessage;
7663    }
7664
7665    function Search(config) {
7666        if (config.element) {
7667            // prevents multiple initialization
7668            config.element.removeAttribute("data-" + NS + "-is");
7669        }
7670
7671        this._cacheElements(config.element);
7672        this._setupProperties(config.options);
7673
7674        this._action = this._elements.form.getAttribute("action");
7675        this._resultsOffset = 0;
7676        this._hasMoreResults = true;
7677
7678        this._elements.input.addEventListener("input", this._onInput.bind(this));
7679        this._elements.input.addEventListener("focus", this._onInput.bind(this));
7680        this._elements.input.addEventListener("keydown", this._onKeydown.bind(this));
7681        this._elements.clear.addEventListener("click", this._onClearClick.bind(this));
7682        document.addEventListener("click", this._onDocumentClick.bind(this));
7683        this._elements.results.addEventListener("scroll", this._onScroll.bind(this));
7684
7685        this._makeAccessible();
7686    }
7687
7688    Search.prototype._displayResults = function() {
7689        if (this._elements.input.value.length === 0) {
7690            toggleShow(this._elements.clear, false);
7691            this._cancelResults();
7692        } else if (this._elements.input.value.length < this._properties.minLength) {
7693            toggleShow(this._elements.clear, true);
7694        } else {
7695            this._updateResults();
7696            toggleShow(this._elements.clear, true);
7697        }
7698    };
7699
7700    Search.prototype._onScroll = function(event) {
7701        // fetch new results when the results to be scrolled down are less than the visible results
7702        if (this._elements.results.scrollTop + 2 * this._elements.results.clientHeight >= this._elements.results.scrollHeight) {
7703            this._resultsOffset += this._properties.resultsSize;
7704            this._displayResults();
7705        }
7706    };
7707
7708    Search.prototype._onInput = function(event) {
7709        var self = this;
7710        self._cancelResults();
7711        // start searching when the search term reaches the minimum length
7712        this._timeout = setTimeout(function() {
7713            self._displayResults();
7714        }, DELAY);
7715    };
7716
7717    Search.prototype._onKeydown = function(event) {
7718        var self = this;
7719
7720        switch (event.keyCode) {
7721            case keyCodes.TAB:
7722                if (self._resultsOpen()) {
7723                    toggleShow(self._elements.results, false);
7724                    self._elements.input.setAttribute("aria-expanded", "false");
7725                    this._hideSearchResultsStatusMessage();
7726                }
7727                break;
7728            case keyCodes.ENTER:
7729                event.preventDefault();
7730                if (self._resultsOpen()) {
7731                    var focused = self._elements.results.querySelector(selectors.item.focused);
7732                    if (focused) {
7733                        focused.click();
7734                    }
7735                }
7736                break;
7737            case keyCodes.ESCAPE:
7738                self._cancelResults();
7739                break;
7740            case keyCodes.ARROW_UP:
7741                if (self._resultsOpen()) {
7742                    event.preventDefault();
7743                    self._stepResultFocus(true);
7744                }
7745                break;
7746            case keyCodes.ARROW_DOWN:
7747                if (self._resultsOpen()) {
7748                    event.preventDefault();
7749                    self._stepResultFocus();
7750                } else {
7751                    // test the input and if necessary fetch and display the results
7752                    self._onInput();
7753                }
7754                break;
7755            default:
7756                return;
7757        }
7758    };
7759
7760    Search.prototype._onClearClick = function(event) {
7761        event.preventDefault();
7762        this._elements.input.value = "";
7763        toggleShow(this._elements.clear, false);
7764        toggleShow(this._elements.results, false);
7765        this._elements.input.setAttribute("aria-expanded", "false");
7766        this._hideSearchResultsStatusMessage();
7767    };
7768
7769    Search.prototype._onDocumentClick = function(event) {
7770        var inputContainsTarget =  this._elements.input.contains(event.target);
7771        var resultsContainTarget = this._elements.results.contains(event.target);
7772
7773        if (!(inputContainsTarget || resultsContainTarget)) {
7774            toggleShow(this._elements.results, false);
7775            this._elements.input.setAttribute("aria-expanded", "false");
7776            this._hideSearchResultsStatusMessage();
7777        }
7778    };
7779
7780    Search.prototype._resultsOpen = function() {
7781        return this._elements.results.style.display !== "none";
7782    };
7783
7784    Search.prototype._makeAccessible = function() {
7785        var id = NS + "-search-results-" + idCount;
7786        this._elements.input.setAttribute("aria-owns", id);
7787        this._elements.results.id = id;
7788        idCount++;
7789    };
7790
7791    Search.prototype._generateItems = function(data, results) {
7792        var self = this;
7793
7794        data.forEach(function(item) {
7795            var el = document.createElement("span");
7796            el.innerHTML = self._elements.itemTemplate.innerHTML;
7797            el.querySelectorAll(selectors.item.title)[0].appendChild(document.createTextNode(item.title));
7798            el.querySelectorAll(selectors.item.self)[0].setAttribute("href", self._safeHref(item.url));
7799            results.innerHTML += el.innerHTML;
7800        });
7801    };
7802
7803    Search.prototype._safeHref = function(href) {
7804        var a = document.createElement("a");
7805        a.href = href;
7806        return a.pathname;
7807    };
7808
7809    Search.prototype._markResults = function() {
7810        var nodeList = this._elements.results.querySelectorAll(selectors.item.self);
7811        var escapedTerm = this._elements.input.value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
7812        var regex = new RegExp("(" + escapedTerm + ")", "gi");
7813
7814        for (var i = this._resultsOffset - 1; i < nodeList.length; ++i) {
7815            var result = nodeList[i];
7816            mark(result, regex);
7817        }
7818    };
7819
7820    Search.prototype._stepResultFocus = function(reverse) {
7821        var results = this._elements.results.querySelectorAll(selectors.item.self);
7822        var focused = this._elements.results.querySelector(selectors.item.focused);
7823        var newFocused;
7824        var index = Array.prototype.indexOf.call(results, focused);
7825        var focusedCssClass = NS + "-search__item--is-focused";
7826
7827        if (results.length > 0) {
7828
7829            if (!reverse) {
7830                // highlight the next result
7831                if (index < 0) {
7832                    results[0].classList.add(focusedCssClass);
7833                    results[0].setAttribute("aria-selected", "true");
7834                } else if (index + 1 < results.length) {
7835                    results[index].classList.remove(focusedCssClass);
7836                    results[index].setAttribute("aria-selected", "false");
7837                    results[index + 1].classList.add(focusedCssClass);
7838                    results[index + 1].setAttribute("aria-selected", "true");
7839                }
7840
7841                // if the last visible result is partially hidden, scroll up until it's completely visible
7842                newFocused = this._elements.results.querySelector(selectors.item.focused);
7843                if (newFocused) {
7844                    var bottomHiddenHeight = newFocused.offsetTop + newFocused.offsetHeight - this._elements.results.scrollTop - this._elements.results.clientHeight;
7845                    if (bottomHiddenHeight > 0) {
7846                        this._elements.results.scrollTop += bottomHiddenHeight;
7847                    } else {
7848                        this._onScroll();
7849                    }
7850                }
7851
7852            } else {
7853                // highlight the previous result
7854                if (index >= 1) {
7855                    results[index].classList.remove(focusedCssClass);
7856                    results[index].setAttribute("aria-selected", "false");
7857                    results[index - 1].classList.add(focusedCssClass);
7858                    results[index - 1].setAttribute("aria-selected", "true");
7859                }
7860
7861                // if the first visible result is partially hidden, scroll down until it's completely visible
7862                newFocused = this._elements.results.querySelector(selectors.item.focused);
7863                if (newFocused) {
7864                    var topHiddenHeight = this._elements.results.scrollTop - newFocused.offsetTop;
7865                    if (topHiddenHeight > 0) {
7866                        this._elements.results.scrollTop -= topHiddenHeight;
7867                    }
7868                }
7869            }
7870        }
7871    };
7872
7873    Search.prototype._updateResults = function() {
7874        var self = this;
7875        if (self._hasMoreResults) {
7876            var request = new XMLHttpRequest();
7877            var url = self._action + "?" + serialize(self._elements.form) + "&" + PARAM_RESULTS_OFFSET + "=" + self._resultsOffset;
7878
7879            request.open("GET", url, true);
7880            request.onload = function() {
7881                // when the results are loaded: hide the loading indicator and display the search icon after a minimum period
7882                setTimeout(function() {
7883                    toggleShow(self._elements.loadingIndicator, false);
7884                    toggleShow(self._elements.icon, true);
7885                }, LOADING_DISPLAY_DELAY);
7886                if (request.status >= 200 && request.status < 400) {
7887                    // success status
7888                    var data = JSON.parse(request.responseText);
7889                    updateSearchResultsStatusMessageElement(self._elements.self.id, data.length);
7890                    if (data.length > 0) {
7891                        self._generateItems(data, self._elements.results);
7892                        self._markResults();
7893                        toggleShow(self._elements.results, true);
7894                        self._elements.input.setAttribute("aria-expanded", "true");
7895                    } else {
7896                        self._hasMoreResults = false;
7897                    }
7898                    // the total number of results is not a multiple of the fetched results:
7899                    // -> we reached the end of the query
7900                    if (self._elements.results.querySelectorAll(selectors.item.self).length % self._properties.resultsSize > 0) {
7901                        self._hasMoreResults = false;
7902                    }
7903                } else {
7904                    // error status
7905                }
7906            };
7907            // when the results are loading: display the loading indicator and hide the search icon
7908            toggleShow(self._elements.loadingIndicator, true);
7909            toggleShow(self._elements.icon, false);
7910            request.send();
7911        }
7912    };
7913
7914    Search.prototype._cancelResults = function() {
7915        clearTimeout(this._timeout);
7916        this._elements.results.scrollTop = 0;
7917        this._resultsOffset = 0;
7918        this._hasMoreResults = true;
7919        this._elements.results.innerHTML = "";
7920        this._elements.input.setAttribute("aria-expanded", "false");
7921        this._hideSearchResultsStatusMessage();
7922    };
7923
7924    Search.prototype._hideSearchResultsStatusMessage = function() {
7925        var searchResultsStatusMessage = document.querySelector("#" + this._elements.self.id + "> .cmp_search__info");
7926        searchResultsStatusMessage.style.visibility = "hidden";
7927    };
7928
7929    Search.prototype._cacheElements = function(wrapper) {
7930        this._elements = {};
7931        this._elements.self = wrapper;
7932        var hooks = this._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
7933
7934        for (var i = 0; i < hooks.length; i++) {
7935            var hook = hooks[i];
7936            var capitalized = IS;
7937            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
7938            var key = hook.dataset[NS + "Hook" + capitalized];
7939            this._elements[key] = hook;
7940        }
7941    };
7942
7943    Search.prototype._setupProperties = function(options) {
7944        this._properties = {};
7945
7946        for (var key in properties) {
7947            if (Object.prototype.hasOwnProperty.call(properties, key)) {
7948                var property = properties[key];
7949                if (options && options[key] != null) {
7950                    if (property && typeof property.transform === "function") {
7951                        this._properties[key] = property.transform(options[key]);
7952                    } else {
7953                        this._properties[key] = options[key];
7954                    }
7955                } else {
7956                    this._properties[key] = properties[key]["default"];
7957                }
7958            }
7959        }
7960    };
7961
7962    function onDocumentReady() {
7963        var elements = document.querySelectorAll(selectors.self);
7964        for (var i = 0; i < elements.length; i++) {
7965            new Search({ element: elements[i], options: readData(elements[i]) });
7966        }
7967
7968        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
7969        var body = document.querySelector("body");
7970        var observer = new MutationObserver(function(mutations) {
7971            mutations.forEach(function(mutation) {
7972                // needed for IE
7973                var nodesArray = [].slice.call(mutation.addedNodes);
7974                if (nodesArray.length > 0) {
7975                    nodesArray.forEach(function(addedNode) {
7976                        if (addedNode.querySelectorAll) {
7977                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
7978                            elementsArray.forEach(function(element) {
7979                                new Search({ element: element, options: readData(element) });
7980                            });
7981                        }
7982                    });
7983                }
7984            });
7985        });
7986
7987        observer.observe(body, {
7988            subtree: true,
7989            childList: true,
7990            characterData: true
7991        });
7992    }
7993
7994    if (document.readyState !== "loading") {
7995        onDocumentReady();
7996    } else {
7997        document.addEventListener("DOMContentLoaded", onDocumentReady);
7998    }
7999
8000})();
8001
8002/*******************************************************************************
8003 * Copyright 2016 Adobe
8004 *
8005 * Licensed under the Apache License, Version 2.0 (the "License");
8006 * you may not use this file except in compliance with the License.
8007 * You may obtain a copy of the License at
8008 *
8009 *     http://www.apache.org/licenses/LICENSE-2.0
8010 *
8011 * Unless required by applicable law or agreed to in writing, software
8012 * distributed under the License is distributed on an "AS IS" BASIS,
8013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8014 * See the License for the specific language governing permissions and
8015 * limitations under the License.
8016 ******************************************************************************/
8017(function() {
8018    "use strict";
8019
8020    var NS = "cmp";
8021    var IS = "formText";
8022    var IS_DASH = "form-text";
8023    var SELF_SELECTOR = "[data-" + NS + '-is="' + IS + '"]';
8024
8025    var selectors = {
8026        self: SELF_SELECTOR,
8027        validationMessage: SELF_SELECTOR + " .cmp-form-text__validation-message"
8028    };
8029
8030    var displayValidationMessage = false;
8031
8032    var properties = {
8033        /**
8034         * A validation message to display if there is a type mismatch between the user input and expected input.
8035         *
8036         * @type {String}
8037         */
8038        constraintMessage: "",
8039        /**
8040         * A validation message to display if no input is supplied, but input is expected for the field.
8041         *
8042         * @type {String}
8043         */
8044        requiredMessage: ""
8045    };
8046
8047    function readData(element) {
8048        var data = element.dataset;
8049        var options = [];
8050        var capitalized = IS;
8051        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
8052        var reserved = ["is", "hook" + capitalized];
8053
8054        for (var key in data) {
8055            if (Object.prototype.hasOwnProperty.call(data, key)) {
8056                var value = data[key];
8057
8058                if (key.indexOf(NS) === 0) {
8059                    key = key.slice(NS.length);
8060                    key = key.charAt(0).toLowerCase() + key.substring(1);
8061
8062                    if (reserved.indexOf(key) === -1) {
8063                        options[key] = value;
8064                    }
8065                }
8066            }
8067        }
8068
8069        return options;
8070    }
8071
8072    function FormText(config) {
8073        if (config.element) {
8074            // prevents multiple initialization
8075            config.element.removeAttribute("data-" + NS + "-is");
8076        }
8077
8078        this._cacheElements(config.element);
8079        this._setupProperties(config.options);
8080
8081        this._elements.input.addEventListener("invalid", this._onInvalid.bind(this));
8082        this._elements.input.addEventListener("input", this._onInput.bind(this));
8083        if (displayValidationMessage) {
8084            this._elements.input.checkValidity();
8085        }
8086    }
8087
8088    FormText.prototype._onInvalid = function(event) {
8089        event.target.setCustomValidity("");
8090        if (event.target.validity.typeMismatch) {
8091            if (this._properties.constraintMessage) {
8092                event.target.setCustomValidity(this._properties.constraintMessage);
8093            }
8094        } else if (event.target.validity.valueMissing) {
8095            if (this._properties.requiredMessage) {
8096                event.target.setCustomValidity(this._properties.requiredMessage);
8097            }
8098        }
8099        if (displayValidationMessage) {
8100            var validationMessage = event.target.parentElement.querySelector(".cmp-form-text__validation-message");
8101            if (validationMessage) {
8102                validationMessage.innerText = event.target.validationMessage;
8103            }
8104        }
8105    };
8106
8107    FormText.prototype._onInput = function(event) {
8108        event.target.setCustomValidity("");
8109        if (displayValidationMessage) {
8110            event.target.checkValidity();
8111        }
8112    };
8113
8114    FormText.prototype._cacheElements = function(wrapper) {
8115        this._elements = {};
8116        this._elements.self = wrapper;
8117        var hooks = this._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS_DASH + "]");
8118        for (var i = 0; i < hooks.length; i++) {
8119            var hook = hooks[i];
8120            var capitalized = IS;
8121            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
8122            var key = hook.dataset[NS + "Hook" + capitalized];
8123            this._elements[key] = hook;
8124        }
8125    };
8126
8127    FormText.prototype._setupProperties = function(options) {
8128        this._properties = {};
8129
8130        for (var key in properties) {
8131            if (Object.prototype.hasOwnProperty.call(properties, key)) {
8132                var property = properties[key];
8133                if (options && options[key] != null) {
8134                    if (property && typeof property.transform === "function") {
8135                        this._properties[key] = property.transform(options[key]);
8136                    } else {
8137                        this._properties[key] = options[key];
8138                    }
8139                } else {
8140                    this._properties[key] = properties[key]["default"];
8141                }
8142            }
8143        }
8144    };
8145
8146    function onDocumentReady() {
8147        var validationMessages = document.querySelectorAll(selectors.validationMessage);
8148        if (validationMessages && validationMessages.length > 0) {
8149            displayValidationMessage = true;
8150        }
8151
8152        var elements = document.querySelectorAll(selectors.self);
8153        for (var i = 0; i < elements.length; i++) {
8154            new FormText({ element: elements[i], options: readData(elements[i]) });
8155        }
8156
8157        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
8158        var body = document.querySelector("body");
8159        var observer = new MutationObserver(function(mutations) {
8160            mutations.forEach(function(mutation) {
8161                // needed for IE
8162                var nodesArray = [].slice.call(mutation.addedNodes);
8163                if (nodesArray.length > 0) {
8164                    nodesArray.forEach(function(addedNode) {
8165                        if (addedNode.querySelectorAll) {
8166                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
8167                            elementsArray.forEach(function(element) {
8168                                new FormText({ element: element, options: readData(element) });
8169                            });
8170                        }
8171                    });
8172                }
8173            });
8174        });
8175
8176        observer.observe(body, {
8177            subtree: true,
8178            childList: true,
8179            characterData: true
8180        });
8181    }
8182
8183    if (document.readyState !== "loading") {
8184        onDocumentReady();
8185    } else {
8186        document.addEventListener("DOMContentLoaded", onDocumentReady);
8187    }
8188
8189})();
8190
8191/*******************************************************************************
8192 * Copyright 2016 Adobe
8193 *
8194 * Licensed under the Apache License, Version 2.0 (the "License");
8195 * you may not use this file except in compliance with the License.
8196 * You may obtain a copy of the License at
8197 *
8198 *     http://www.apache.org/licenses/LICENSE-2.0
8199 *
8200 * Unless required by applicable law or agreed to in writing, software
8201 * distributed under the License is distributed on an "AS IS" BASIS,
8202 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8203 * See the License for the specific language governing permissions and
8204 * limitations under the License.
8205 ******************************************************************************/
8206(function() {
8207    "use strict";
8208
8209    var NS = "cmp";
8210    var IS = "formText";
8211    var IS_DASH = "form-text";
8212
8213    var selectors = {
8214        self: "[data-" + NS + '-is="' + IS + '"]'
8215    };
8216
8217    var properties = {
8218        /**
8219         * A validation message to display if there is a type mismatch between the user input and expected input.
8220         *
8221         * @type {String}
8222         */
8223        constraintMessage: "",
8224        /**
8225         * A validation message to display if no input is supplied, but input is expected for the field.
8226         *
8227         * @type {String}
8228         */
8229        requiredMessage: ""
8230    };
8231
8232    function readData(element) {
8233        var data = element.dataset;
8234        var options = [];
8235        var capitalized = IS;
8236        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
8237        var reserved = ["is", "hook" + capitalized];
8238
8239        for (var key in data) {
8240            if (Object.prototype.hasOwnProperty.call(data, key)) {
8241                var value = data[key];
8242
8243                if (key.indexOf(NS) === 0) {
8244                    key = key.slice(NS.length);
8245                    key = key.charAt(0).toLowerCase() + key.substring(1);
8246
8247                    if (reserved.indexOf(key) === -1) {
8248                        options[key] = value;
8249                    }
8250                }
8251            }
8252        }
8253
8254        return options;
8255    }
8256
8257    function FormText(config) {
8258        if (config.element) {
8259            // prevents multiple initialization
8260            config.element.removeAttribute("data-" + NS + "-is");
8261        }
8262
8263        this._cacheElements(config.element);
8264        this._setupProperties(config.options);
8265
8266        this._elements.input.addEventListener("invalid", this._onInvalid.bind(this));
8267        this._elements.input.addEventListener("input", this._onInput.bind(this));
8268    }
8269
8270    FormText.prototype._onInvalid = function(event) {
8271        event.target.setCustomValidity("");
8272        if (event.target.validity.typeMismatch) {
8273            if (this._properties.constraintMessage) {
8274                event.target.setCustomValidity(this._properties.constraintMessage);
8275            }
8276        } else if (event.target.validity.valueMissing) {
8277            if (this._properties.requiredMessage) {
8278                event.target.setCustomValidity(this._properties.requiredMessage);
8279            }
8280        }
8281    };
8282
8283    FormText.prototype._onInput = function(event) {
8284        event.target.setCustomValidity("");
8285    };
8286
8287    FormText.prototype._cacheElements = function(wrapper) {
8288        this._elements = {};
8289        this._elements.self = wrapper;
8290        var hooks = this._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS_DASH + "]");
8291        for (var i = 0; i < hooks.length; i++) {
8292            var hook = hooks[i];
8293            var capitalized = IS;
8294            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
8295            var key = hook.dataset[NS + "Hook" + capitalized];
8296            this._elements[key] = hook;
8297        }
8298    };
8299
8300    FormText.prototype._setupProperties = function(options) {
8301        this._properties = {};
8302
8303        for (var key in properties) {
8304            if (Object.prototype.hasOwnProperty.call(properties, key)) {
8305                var property = properties[key];
8306                if (options && options[key] != null) {
8307                    if (property && typeof property.transform === "function") {
8308                        this._properties[key] = property.transform(options[key]);
8309                    } else {
8310                        this._properties[key] = options[key];
8311                    }
8312                } else {
8313                    this._properties[key] = properties[key]["default"];
8314                }
8315            }
8316        }
8317    };
8318
8319    function onDocumentReady() {
8320        var elements = document.querySelectorAll(selectors.self);
8321        for (var i = 0; i < elements.length; i++) {
8322            new FormText({ element: elements[i], options: readData(elements[i]) });
8323        }
8324
8325        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
8326        var body = document.querySelector("body");
8327        var observer = new MutationObserver(function(mutations) {
8328            mutations.forEach(function(mutation) {
8329                // needed for IE
8330                var nodesArray = [].slice.call(mutation.addedNodes);
8331                if (nodesArray.length > 0) {
8332                    nodesArray.forEach(function(addedNode) {
8333                        if (addedNode.querySelectorAll) {
8334                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
8335                            elementsArray.forEach(function(element) {
8336                                new FormText({ element: element, options: readData(element) });
8337                            });
8338                        }
8339                    });
8340                }
8341            });
8342        });
8343
8344        observer.observe(body, {
8345            subtree: true,
8346            childList: true,
8347            characterData: true
8348        });
8349    }
8350
8351    if (document.readyState !== "loading") {
8352        onDocumentReady();
8353    } else {
8354        document.addEventListener("DOMContentLoaded", onDocumentReady);
8355    }
8356
8357})();
8358
8359/*******************************************************************************
8360 * Copyright 2016 Adobe
8361 *
8362 * Licensed under the Apache License, Version 2.0 (the "License");
8363 * you may not use this file except in compliance with the License.
8364 * You may obtain a copy of the License at
8365 *
8366 *     http://www.apache.org/licenses/LICENSE-2.0
8367 *
8368 * Unless required by applicable law or agreed to in writing, software
8369 * distributed under the License is distributed on an "AS IS" BASIS,
8370 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8371 * See the License for the specific language governing permissions and
8372 * limitations under the License.
8373 ******************************************************************************/
8374(function() {
8375    "use strict";
8376
8377    var NS = "cmp";
8378    var IS = "formText";
8379    var IS_DASH = "form-text";
8380
8381    var selectors = {
8382        self: "[data-" + NS + '-is="' + IS + '"]'
8383    };
8384
8385    var properties = {
8386        /**
8387         * A validation message to display if there is a type mismatch between the user input and expected input.
8388         *
8389         * @type {String}
8390         */
8391        constraintMessage: "",
8392        /**
8393         * A validation message to display if no input is supplied, but input is expected for the field.
8394         *
8395         * @type {String}
8396         */
8397        requiredMessage: ""
8398    };
8399
8400    function readData(element) {
8401        var data = element.dataset;
8402        var options = [];
8403        var capitalized = IS;
8404        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
8405        var reserved = ["is", "hook" + capitalized];
8406
8407        for (var key in data) {
8408            if (Object.prototype.hasOwnProperty.call(data, key)) {
8409                var value = data[key];
8410
8411                if (key.indexOf(NS) === 0) {
8412                    key = key.slice(NS.length);
8413                    key = key.charAt(0).toLowerCase() + key.substring(1);
8414
8415                    if (reserved.indexOf(key) === -1) {
8416                        options[key] = value;
8417                    }
8418                }
8419            }
8420        }
8421
8422        return options;
8423    }
8424
8425    function FormText(config) {
8426        if (config.element) {
8427            // prevents multiple initialization
8428            config.element.removeAttribute("data-" + NS + "-is");
8429        }
8430
8431        this._cacheElements(config.element);
8432        this._setupProperties(config.options);
8433
8434        this._elements.input.addEventListener("invalid", this._onInvalid.bind(this));
8435        this._elements.input.addEventListener("input", this._onInput.bind(this));
8436    }
8437
8438    FormText.prototype._onInvalid = function(event) {
8439        event.target.setCustomValidity("");
8440        if (event.target.validity.typeMismatch) {
8441            if (this._properties.constraintMessage) {
8442                event.target.setCustomValidity(this._properties.constraintMessage);
8443            }
8444        } else if (event.target.validity.valueMissing) {
8445            if (this._properties.requiredMessage) {
8446                event.target.setCustomValidity(this._properties.requiredMessage);
8447            }
8448        }
8449    };
8450
8451    FormText.prototype._onInput = function(event) {
8452        event.target.setCustomValidity("");
8453    };
8454
8455    FormText.prototype._cacheElements = function(wrapper) {
8456        this._elements = {};
8457        this._elements.self = wrapper;
8458        var hooks = this._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS_DASH + "]");
8459        for (var i = 0; i < hooks.length; i++) {
8460            var hook = hooks[i];
8461            var capitalized = IS;
8462            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
8463            var key = hook.dataset[NS + "Hook" + capitalized];
8464            this._elements[key] = hook;
8465        }
8466    };
8467
8468    FormText.prototype._setupProperties = function(options) {
8469        this._properties = {};
8470
8471        for (var key in properties) {
8472            if (Object.prototype.hasOwnProperty.call(properties, key)) {
8473                var property = properties[key];
8474                if (options && options[key] != null) {
8475                    if (property && typeof property.transform === "function") {
8476                        this._properties[key] = property.transform(options[key]);
8477                    } else {
8478                        this._properties[key] = options[key];
8479                    }
8480                } else {
8481                    this._properties[key] = properties[key]["default"];
8482                }
8483            }
8484        }
8485    };
8486
8487    function onDocumentReady() {
8488        var elements = document.querySelectorAll(selectors.self);
8489        for (var i = 0; i < elements.length; i++) {
8490            new FormText({ element: elements[i], options: readData(elements[i]) });
8491        }
8492
8493        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
8494        var body = document.querySelector("body");
8495        var observer = new MutationObserver(function(mutations) {
8496            mutations.forEach(function(mutation) {
8497                // needed for IE
8498                var nodesArray = [].slice.call(mutation.addedNodes);
8499                if (nodesArray.length > 0) {
8500                    nodesArray.forEach(function(addedNode) {
8501                        if (addedNode.querySelectorAll) {
8502                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
8503                            elementsArray.forEach(function(element) {
8504                                new FormText({ element: element, options: readData(element) });
8505                            });
8506                        }
8507                    });
8508                }
8509            });
8510        });
8511
8512        observer.observe(body, {
8513            subtree: true,
8514            childList: true,
8515            characterData: true
8516        });
8517    }
8518
8519    if (document.readyState !== "loading") {
8520        onDocumentReady();
8521    } else {
8522        document.addEventListener("DOMContentLoaded", onDocumentReady);
8523    }
8524
8525})();
8526
8527/*******************************************************************************
8528 * Copyright 2020 Adobe
8529 *
8530 * Licensed under the Apache License, Version 2.0 (the "License");
8531 * you may not use this file except in compliance with the License.
8532 * You may obtain a copy of the License at
8533 *
8534 *     http://www.apache.org/licenses/LICENSE-2.0
8535 *
8536 * Unless required by applicable law or agreed to in writing, software
8537 * distributed under the License is distributed on an "AS IS" BASIS,
8538 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8539 * See the License for the specific language governing permissions and
8540 * limitations under the License.
8541 ******************************************************************************/
8542(function() {
8543    "use strict";
8544
8545    var NS = "cmp";
8546    var IS = "pdfviewer";
8547    var SDK_URL = "https://acrobatservices.adobe.com/view-sdk/viewer.js";
8548    var SDK_READY_EVENT = "adobe_dc_view_sdk.ready";
8549
8550    var selectors = {
8551        self: "[data-" + NS + '-is="' + IS + '"]',
8552        sdkScript: 'script[src="' + SDK_URL + '"]'
8553    };
8554
8555    function initSDK() {
8556        var sdkIncluded = document.querySelectorAll(selectors.sdkScript).length > 0;
8557        if (!window.adobe_dc_view_sdk && !sdkIncluded) {
8558            var dcv = document.createElement("script");
8559            dcv.type = "text/javascript";
8560            dcv.src = SDK_URL;
8561            document.body.appendChild(dcv);
8562        }
8563    }
8564
8565    function previewPdf(component) {
8566        // prevents multiple initialization
8567        component.removeAttribute("data-" + NS + "-is");
8568
8569        // add the view sdk to the page
8570        initSDK();
8571
8572        // manage the preview
8573        if (component.dataset && component.id) {
8574            if (window.AdobeDC && window.AdobeDC.View) {
8575                dcView(component);
8576            } else {
8577                document.addEventListener(SDK_READY_EVENT, function() {
8578                    dcView(component);
8579                });
8580            }
8581        }
8582    }
8583
8584    function dcView(component) {
8585        var adobeDCView = new window.AdobeDC.View({
8586            clientId: component.dataset.cmpClientId,
8587            divId: component.id + "-content",
8588            reportSuiteId: component.dataset.cmpReportSuiteId,
8589            locale: typeof Granite !== "undefined" && Granite && Granite.I18n ? Granite.I18n.getLocale() : navigator.language || navigator.userLanguage
8590        });
8591        adobeDCView.previewFile({
8592            content: { location: { url: component.dataset.cmpDocumentPath } },
8593            metaData: { fileName: component.dataset.cmpDocumentFileName }
8594        }, JSON.parse(component.dataset.cmpViewerConfigJson));
8595    }
8596
8597    /**
8598     * Document ready handler and DOM mutation observers. Initializes Accordion components as necessary.
8599     *
8600     * @private
8601     */
8602    function onDocumentReady() {
8603        var elements = document.querySelectorAll(selectors.self);
8604        for (var i = 0; i < elements.length; i++) {
8605            previewPdf(elements[i]);
8606        }
8607
8608        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
8609        var body = document.querySelector("body");
8610        var observer = new MutationObserver(function(mutations) {
8611            mutations.forEach(function(mutation) {
8612                // needed for IE
8613                var nodesArray = [].slice.call(mutation.addedNodes);
8614                if (nodesArray.length > 0) {
8615                    nodesArray.forEach(function(addedNode) {
8616                        if (addedNode.querySelectorAll) {
8617                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
8618                            elementsArray.forEach(function(element) {
8619                                previewPdf(element);
8620                            });
8621                        }
8622                    });
8623                }
8624            });
8625        });
8626
8627        observer.observe(body, {
8628            subtree: true,
8629            childList: true,
8630            characterData: true
8631        });
8632
8633    }
8634
8635    if (document.readyState !== "loading") {
8636        onDocumentReady();
8637    } else {
8638        document.addEventListener("DOMContentLoaded", onDocumentReady);
8639    }
8640}());
8641
8642/*******************************************************************************
8643 * Copyright 2022 Adobe
8644 *
8645 * Licensed under the Apache License, Version 2.0 (the "License");
8646 * you may not use this file except in compliance with the License.
8647 * You may obtain a copy of the License at
8648 *
8649 *     http://www.apache.org/licenses/LICENSE-2.0
8650 *
8651 * Unless required by applicable law or agreed to in writing, software
8652 * distributed under the License is distributed on an "AS IS" BASIS,
8653 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8654 * See the License for the specific language governing permissions and
8655 * limitations under the License.
8656 ******************************************************************************/
8657(function() {
8658    "use strict";
8659
8660    var dataLayerEnabled;
8661    var dataLayer;
8662    var dataLayerName;
8663
8664    /**
8665     * Adds Click Event Listener to the main <div> of the Text Components
8666     */
8667    function addClickEventListenerToTextComponents() {
8668        var componentMainDivs = document.getElementsByClassName("cmp-text");
8669
8670        for (var i = 0; i < componentMainDivs.length; i++) {
8671            componentMainDivs[i].addEventListener("click", addClickedLinkToDataLayer);
8672        }
8673    }
8674
8675    /**
8676     * Adds clicked link contained by the Text Component to Data Layer
8677     *
8678     * @private
8679     * @param {Object} event The Click event
8680     */
8681    function addClickedLinkToDataLayer(event) {
8682        var element = event.currentTarget;
8683        var componentId = getDataLayerId(element);
8684
8685        if (event.target.tagName === "A") {
8686            dataLayer.push({
8687                event: "cmp:click",
8688                eventInfo: {
8689                    path: "component." + componentId,
8690                    link: event.target.getAttribute("href")
8691                }
8692            });
8693        }
8694    }
8695
8696    /**
8697     * Parses the dataLayer string and returns the ID
8698     *
8699     * @private
8700     * @param {HTMLElement} item, the Text item
8701     * @returns {String} dataLayerId or undefined
8702     */
8703    function getDataLayerId(item) {
8704        if (item) {
8705            if (item.dataset.cmpDataLayer) {
8706                return Object.keys(JSON.parse(item.dataset.cmpDataLayer))[0];
8707            } else {
8708                return item.id;
8709            }
8710        }
8711        return null;
8712    }
8713
8714    function onDocumentReady() {
8715        dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
8716        if (dataLayerEnabled) {
8717            dataLayerName = document.body.getAttribute("data-cmp-data-layer-name") || "adobeDataLayer";
8718            dataLayer = window[dataLayerName] = window[dataLayerName] || [];
8719
8720            addClickEventListenerToTextComponents();
8721        }
8722    }
8723
8724    if (document.readyState !== "loading") {
8725        onDocumentReady();
8726    } else {
8727        document.addEventListener("DOMContentLoaded", onDocumentReady);
8728    }
8729})();
8730
8731/*******************************************************************************
8732 * Copyright 2022 Adobe
8733 *
8734 * Licensed under the Apache License, Version 2.0 (the "License");
8735 * you may not use this file except in compliance with the License.
8736 * You may obtain a copy of the License at
8737 *
8738 *     http://www.apache.org/licenses/LICENSE-2.0
8739 *
8740 * Unless required by applicable law or agreed to in writing, software
8741 * distributed under the License is distributed on an "AS IS" BASIS,
8742 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8743 * See the License for the specific language governing permissions and
8744 * limitations under the License.
8745 ******************************************************************************/
8746(function() {
8747    "use strict";
8748
8749    var linkAccessibilityClass = "cmp-link__screen-reader-only";
8750    var selectors = {
8751        linkAccessibility: "." + linkAccessibilityClass,
8752        linkAccessibilityEnabled: "[data-cmp-link-accessibility-enabled]",
8753        linkAccessibilityText: "[data-cmp-link-accessibility-text]"
8754    };
8755
8756    function getLinkAccessibilityText() {
8757        var linkAccessibilityEnabled = document.querySelectorAll(selectors.linkAccessibilityEnabled);
8758        if (!linkAccessibilityEnabled[0]) {
8759            return;
8760        }
8761        var linkAccessibilityTextElements = document.querySelectorAll(selectors.linkAccessibilityText);
8762        if (!linkAccessibilityTextElements[0]) {
8763            return;
8764        }
8765        return linkAccessibilityTextElements[0].dataset.cmpLinkAccessibilityText;
8766    }
8767
8768    function onDocumentReady() {
8769        var linkAccessibilityText = getLinkAccessibilityText();
8770        if (linkAccessibilityText) {
8771            document.querySelectorAll("a[target='_blank']").forEach(function(link) {
8772                if (!link.querySelector(selectors.linkAccessibility)) {
8773                    var linkAccessibilityElement = document.createElement("span");
8774                    linkAccessibilityElement.classList.add(linkAccessibilityClass);
8775                    linkAccessibilityElement.innerText = linkAccessibilityText;
8776                    link.insertAdjacentElement("beforeend", linkAccessibilityElement);
8777                }
8778            });
8779        }
8780    }
8781
8782    if (document.readyState !== "loading") {
8783        onDocumentReady();
8784    } else {
8785        document.addEventListener("DOMContentLoaded", onDocumentReady);
8786    }
8787
8788}());
8789
8790/*******************************************************************************
8791 * Copyright 2020 Adobe
8792 *
8793 * Licensed under the Apache License, Version 2.0 (the "License");
8794 * you may not use this file except in compliance with the License.
8795 * You may obtain a copy of the License at
8796 *
8797 *     http://www.apache.org/licenses/LICENSE2.0
8798 *
8799 * Unless required by applicable law or agreed to in writing, software
8800 * distributed under the License is distributed on an "AS IS" BASIS,
8801 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8802 * See the License for the specific language governing permissions and
8803 * limitations under the License.
8804 ******************************************************************************/
8805
8806/**
8807 * Element.matches()
8808 * https://developer.mozilla.org/enUS/docs/Web/API/Element/matches#Polyfill
8809 */
8810if (!Element.prototype.matches) {
8811    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
8812}
8813
8814// eslint-disable-next-line valid-jsdoc
8815/**
8816 * Element.closest()
8817 * https://developer.mozilla.org/enUS/docs/Web/API/Element/closest#Polyfill
8818 */
8819if (!Element.prototype.closest) {
8820    Element.prototype.closest = function(s) {
8821        "use strict";
8822        var el = this;
8823        if (!document.documentElement.contains(el)) {
8824            return null;
8825        }
8826        do {
8827            if (el.matches(s)) {
8828                return el;
8829            }
8830            el = el.parentElement || el.parentNode;
8831        } while (el !== null && el.nodeType === 1);
8832        return null;
8833    };
8834}
8835
8836// https://tc39.github.io/ecma262/#sec-array.prototype.find
8837if (!Array.prototype.find) {
8838    Object.defineProperty(Array.prototype, "find", {
8839        value: function(predicate) {
8840            "use strict";
8841            // 1. Let O be ? ToObject(this value).
8842            if (this == null) {
8843                throw TypeError('"this" is null or not defined');
8844            }
8845
8846            var o = Object(this);
8847
8848            // 2. Let len be ? ToLength(? Get(O, "length")).
8849            var len = o.length >>> 0;
8850
8851            // 3. If IsCallable(predicate) is false, throw a TypeError exception.
8852            if (typeof predicate !== "function") {
8853                throw TypeError("predicate must be a function");
8854            }
8855
8856            // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
8857            var thisArg = arguments[1];
8858
8859            // 5. Let k be 0.
8860            var k = 0;
8861
8862            // 6. Repeat, while k < len
8863            while (k < len) {
8864                // a. Let Pk be ! ToString(k).
8865                // b. Let kValue be ? Get(O, Pk).
8866                // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
8867                // d. If testResult is true, return kValue.
8868                var kValue = o[k];
8869                if (predicate.call(thisArg, kValue, k, o)) {
8870                    return kValue;
8871                }
8872                // e. Increase k by 1.
8873                k++;
8874            }
8875
8876            // 7. Return undefined.
8877            return undefined;
8878        },
8879        configurable: true,
8880        writable: true
8881    });
8882}
8883
8884"use strict";function _slicedToArray(t,e){return _arrayWithHoles(t)||_iterableToArrayLimit(t,e)||_unsupportedIterableToArray(t,e)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArrayLimit(t,e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t)){var n=[],r=!0,o=!1,a=void 0;try{for(var i,u=t[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!e||n.length!==e);r=!0);}catch(t){o=!0,a=t}finally{try{r||null==u.return||u.return()}finally{if(o)throw a}}return n}}function _arrayWithHoles(t){if(Array.isArray(t))return t}function _createForOfIteratorHelper(t){if("undefined"==typeof Symbol||null==t[Symbol.iterator]){if(Array.isArray(t)||(t=_unsupportedIterableToArray(t))){var e=0,n=function(){};return{s:n,n:function(){return e>=t.length?{done:!0}:{done:!1,value:t[e++]}},e:function(t){throw t},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var r,o,a=!0,i=!1;return{s:function(){r=t[Symbol.iterator]()},n:function(){var t=r.next();return a=t.done,t},e:function(t){i=!0,o=t},f:function(){try{a||null==r.return||r.return()}finally{if(i)throw o}}}}function _unsupportedIterableToArray(t,e){if(t){if("string"==typeof t)return _arrayLikeToArray(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(n):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(t,e):void 0}}function _arrayLikeToArray(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function a(i,u,c){function f(e,t){if(!u[e]){if(!i[e]){var n="function"==typeof require&&require;if(!t&&n)return n(e,!0);if(s)return s(e,!0);var r=new Error("Cannot find module '"+e+"'");throw r.code="MODULE_NOT_FOUND",r}var o=u[e]={exports:{}};i[e][0].call(o.exports,function(t){return f(i[e][1][t]||t)},o,o.exports,a,i,u,c)}return u[e].exports}for(var s="function"==typeof require&&require,t=0;t<c.length;t++)f(c[t]);return f}({1:[function(t,wn,En){(function(On){(function(){function n(t,e){for(var n=-1,r=null==t?0:t.length,o=0,a=[];++n<r;){var i=t[n];e(i,n,t)&&(a[o++]=i)}return a}function a(t,e){for(var n=-1,r=null==t?0:t.length,o=Array(r);++n<r;)o[n]=e(t[n],n,t);return o}function f(t,e){for(var n=-1,r=e.length,o=t.length;++n<r;)t[o+n]=e[n];return t}function b(t,e){for(var n=-1,r=null==t?0:t.length;++n<r;)if(e(t[n],n,t))return!0;return!1}function o(t,e,n){var r=t.length;for(n+=-1;++n<r;)if(e(t[n],n,t))return n;return-1}function i(t){return t!=t}function t(e){return function(t){return e(t)}}function h(t){var n=-1,r=Array(t.size);return t.forEach(function(t,e){r[++n]=[e,t]}),r}function e(e){var n=Object;return function(t){return e(n(t))}}function v(t){var e=-1,n=Array(t.size);return t.forEach(function(t){n[++e]=t}),n}function r(){}function u(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function c(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function s(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function d(t){var e=-1,n=null==t?0:t.length;for(this.__data__=new s;++e<n;)this.add(t[e])}function g(t){this.size=(this.__data__=new c(t)).size}function l(t,e){var n=hn(t),r=!n&&bn(t),o=!n&&!r&&vn(t),a=!n&&!r&&!o&&_n(t);if(n=n||r||o||a){r=t.length;for(var i=String,u=-1,c=Array(r);++u<r;)c[u]=i(u);r=c}else r=[];var f;i=r.length;for(f in t)!e&&!be.call(t,f)||n&&("length"==f||o&&("offset"==f||"parent"==f)||a&&("buffer"==f||"byteLength"==f||"byteOffset"==f)||Q(f,i))||r.push(f);return r}function _(t,e,n){(n===Mt||ft(t[e],n))&&(n!==Mt||e in t)||j(t,e,n)}function y(t,e,n){var r=t[e];be.call(t,e)&&ft(r,n)&&(n!==Mt||e in t)||j(t,e,n)}function p(t,e){for(var n=t.length;n--;)if(ft(t[n][0],e))return n;return-1}function j(t,e,n){"__proto__"==e&&xe?xe(t,e,{configurable:!0,enumerable:!0,value:n,writable:!0}):t[e]=n}function m(n,r,o,t,e,a){var i,u=1&r,c=2&r,f=4&r;
8884if(o&&(i=e?o(n,t,e,a):o(n)),i!==Mt)return i;if(!bt(n))return n;if(t=hn(n)){if(i=function(t){var e=t.length,n=new t.constructor(e);return e&&"string"==typeof t[0]&&be.call(t,"index")&&(n.index=t.index,n.input=t.input),n}(n),!u)return U(n,i)}else{var s=nn(n),l="[object Function]"==s||"[object GeneratorFunction]"==s;if(vn(n))return M(n,u);if("[object Object]"==s||"[object Arguments]"==s||l&&!e){if(i=c||l?{}:Y(n),!u)return c?function(t,e){return P(t,en(t),e)}(n,function(t,e){return t&&P(e,St(e),t)}(i,n)):function(t,e){return P(t,tn(t),e)}(n,function(t,e){return t&&P(e,Lt(e),t)}(i,n))}else{if(!Kt[s])return e?n:{};i=function(t,e,n){var r=t.constructor;switch(e){case"[object ArrayBuffer]":return z(t);case"[object Boolean]":case"[object Date]":return new r(+t);case"[object DataView]":return e=n?z(t.buffer):t.buffer,new t.constructor(e,t.byteOffset,t.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return C(t,n);case"[object Map]":return new r;case"[object Number]":case"[object String]":return new r(t);case"[object RegExp]":return(e=new t.constructor(t.source,Ht.exec(t))).lastIndex=t.lastIndex,e;case"[object Set]":return new r;case"[object Symbol]":return qe?Object(qe.call(t)):{}}}(n,s,u)}}if(e=(a=a||new g).get(n))return e;if(a.set(n,i),gn(n))return n.forEach(function(t){i.add(m(t,r,o,t,n,a))}),i;if(dn(n))return n.forEach(function(t,e){i.set(e,m(t,r,o,e,n,a))}),i;c=f?c?B:H:c?St:Lt;var p=t?Mt:c(n);return function(t,e){for(var n=-1,r=null==t?0:t.length;++n<r&&!1!==e(t[n],n,t););}(p||n,function(t,e){p&&(t=n[e=t]),y(i,e,m(t,r,o,e,n,a))}),i}function A(t,e){for(var n=0,r=(e=F(e,t)).length;null!=t&&n<r;)t=t[nt(e[n++])];return n&&n==r?t:Mt}function O(t,e,n){return e=e(t),hn(t)?e:f(e,n(t))}function w(t){if(null==t)t=t===Mt?"[object Undefined]":"[object Null]";else if(Te&&Te in Object(t)){var e=be.call(t,Te),n=t[Te];try{t[Te]=Mt;var r=!0}catch(t){}var o=ve.call(t);r&&(e?t[Te]=n:delete t[Te]),t=o}else t=ve.call(t);return t}function E(t,e){return null!=t&&be.call(t,e)}function L(t,e){return null!=t&&e in Object(t)}function S(t){return ht(t)&&"[object Arguments]"==w(t)}function T(t,e,n,r,o){if(t===e)e=!0;else if(null==t||null==e||!ht(t)&&!ht(e))e=t!=t&&e!=e;else t:{var a,i,u=hn(t),c=hn(e),f="[object Object]"==(a="[object Arguments]"==(a=u?"[object Array]":nn(t))?"[object Object]":a);c="[object Object]"==(i="[object Arguments]"==(i=c?"[object Array]":nn(e))?"[object Object]":i);if((i=a==i)&&vn(t)){if(!vn(e)){e=!1;break t}f=!(u=!0)}if(i&&!f)o=o||new g,e=u||_n(t)?V(t,e,n,r,T,o):function(t,e,n,r,o,a,i){switch(n){case"[object DataView]":if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)break;t=t.buffer,e=e.buffer;case"[object ArrayBuffer]":if(t.byteLength!=e.byteLength||!a(new me(t),new me(e)))break;return!0;case"[object Boolean]":case"[object Date]":case"[object Number]":return ft(+t,+e);case"[object Error]":return t.name==e.name&&t.message==e.message;case"[object RegExp]":case"[object String]":return t==e+"";case"[object Map]":var u=h;case"[object Set]":if(u=u||v,t.size!=e.size&&!(1&r))break;return(n=i.get(t))?n==e:(r|=2,i.set(t,e),e=V(u(t),u(e),r,o,a,i),i.delete(t),e);case"[object Symbol]":if(qe)return qe.call(t)==qe.call(e)}return!1}(t,e,a,n,r,T,o);else{if(!(1&n)&&(u=f&&be.call(t,"__wrapped__"),a=c&&be.call(e,"__wrapped__"),u||a)){e=T(t=u?t.value():t,e=a?e.value():e,n,r,o=o||new g);break t}if(i)e:if(o=o||new g,u=1&n,a=H(t),c=a.length,i=H(e).length,c==i||u){for(f=c;f--;){var s=a[f];if(!(u?s in e:be.call(e,s))){e=!1;break e}}if((i=o.get(t))&&o.get(e))e=i==e;else{i=!0,o.set(t,e),o.set(e,t);for(var l=u;++f<c;){var p=t[s=a[f]],y=e[s];if(r)var b=u?r(y,p,s,e,t,o):r(p,y,s,t,e,o);if(b===Mt?p!==y&&!T(p,y,n,r,o):!b){i=!1;break}l=l||"constructor"==s}i&&!l&&((n=t.constructor)!=(r=e.constructor)&&"constructor"in t&&"constructor"in e&&!("function"==typeof n&&n instanceof n&&"function"==typeof r&&r instanceof r)&&(i=!1)),o.delete(t),o.delete(e),e=i}}else e=!1;else e=!1}}return e}function x(t){return"function"==typeof t?t:null==t?It:"object"==_typeof(t)?hn(t)?function(n,r){return X(n)&&r==r&&!bt(r)?tt(nt(n),r):function(t){var e=wt(t,n);return e===Mt&&e===r?Et(t,n):T(r,e,3)}}(t[0],t[1]):function(e){var n=function(t){for(var e=Lt(t),n=e.length;n--;){var r=e[n],o=t[r];e[n]=[r,o,o==o&&!bt(o)]}return e}(e);return 1==n.length&&n[0][2]?tt(n[0][0],n[0][1]):function(t){return t===e||function(t,e){var n=e.length,r=n;if(null==t)return!r;for(t=Object(t);n--;){if((o=e[n])[2]?o[1]!==t[o[0]]:!(o[0]in t))return!1}for(;++n<r;
8884){var o,a=(o=e[n])[0],i=t[a],u=o[1];if(o[2]){if(i===Mt&&!(a in t))return!1}else if(o=new g,void 0!==Mt||!T(u,i,3,void 0,o))return!1}return!0}(t,n)}}(t):Nt(t)}function I(t){if(!Z(t))return Ne(t);var e,n=[];for(e in Object(t))be.call(t,e)&&"constructor"!=e&&n.push(e);return n}function k(s,l,p,y,b){s!==l&&Xe(l,function(t,e){if(bt(t)){var n=b=b||new g,r="__proto__"==e?Mt:s[e],o="__proto__"==e?Mt:l[e];if(f=n.get(o))_(s,e,f);else{var a=(f=y?y(r,o,e+"",s,l,n):Mt)===Mt;if(a){var i=hn(o),u=!i&&vn(o),c=!i&&!u&&_n(o),f=o;i||u||c?f=hn(r)?r:lt(r)?U(r):u?M(o,!(a=!1)):c?C(o,!(a=!1)):[]:vt(o)||bn(o)?bn(f=r)?f=At(r):(!bt(r)||p&&pt(r))&&(f=Y(o)):a=!1}a&&(n.set(o,f),k(f,o,p,y,n),n.delete(o)),_(s,e,f)}}else(n=y?y("__proto__"==e?Mt:s[e],t,e+"",s,l,b):Mt)===Mt&&(n=t),_(s,e,n)},St)}function N(t){if("string"==typeof t)return t;if(hn(t))return a(t,N)+"";if(gt(t))return Je?Je.call(t):"";var e=t+"";return"0"==e&&1/t==-zt?"-0":e}function D(t,e){var n;if((e=F(e,t)).length<2)n=t;else{var r=0,o=-1,a=-1,i=(n=e).length;for(r<0&&(r=i<-r?0:i+r),(o=i<o?i:o)<0&&(o+=i),i=o<r?0:o-r>>>0,r>>>=0,o=Array(i);++a<i;)o[a]=n[a+r];n=A(t,o)}null==(t=n)||delete t[nt(it(e))]}function F(t,e){return hn(t)?t:X(t,e)?[t]:ln(Ot(t))}function M(t,e){if(e)return t.slice();var n=t.length;n=Ae?Ae(n):new t.constructor(n);return t.copy(n),n}function z(t){var e=new t.constructor(t.byteLength);return new me(e).set(new me(t)),e}function C(t,e){return new t.constructor(e?z(t.buffer):t.buffer,t.byteOffset,t.length)}function U(t,e){var n=-1,r=t.length;for(e=e||Array(r);++n<r;)e[n]=t[n];return e}function P(t,e,n){var r=!n;n=n||{};for(var o=-1,a=e.length;++o<a;){var i=e[o],u=Mt;u===Mt&&(u=t[i]),r?j(n,i,u):y(n,i,u)}return n}function R(f){return function(t){return sn(et(t,void 0,It),t+"")}(function(t,e){var n,r=-1,o=e.length,a=1<o?e[o-1]:Mt,i=2<o?e[2]:Mt;a=3<f.length&&"function"==typeof a?(o--,a):Mt;if(n=i){n=e[0];var u=e[1];if(bt(i)){var c=_typeof(u);n=!!("number"==c?st(i)&&Q(u,i.length):"string"==c&&u in i)&&ft(i[u],n)}else n=!1}for(n&&(a=o<3?Mt:a,o=1),t=Object(t);++r<o;)(i=e[r])&&f(t,i,r,a);return t})}function $(t){return vt(t)?Mt:t}function V(t,e,n,r,o,a){var i=1&n,u=t.length;if(u!=(c=e.length)&&!(i&&u<c))return!1;if((c=a.get(t))&&a.get(e))return c==e;var c=-1,f=!0,s=2&n?new d:Mt;for(a.set(t,e),a.set(e,t);++c<u;){var l=t[c],p=e[c];if(r)var y=i?r(p,l,c,e,t,a):r(l,p,c,t,e,a);if(y!==Mt){if(y)continue;f=!1;break}if(s){if(!b(e,function(t,e){if(!s.has(e)&&(l===t||o(l,t,n,r,a)))return s.push(e)})){f=!1;break}}else if(l!==p&&!o(l,p,n,r,a)){f=!1;break}}return a.delete(t),a.delete(e),f}function H(t){return O(t,Lt,tn)}function B(t){return O(t,St,en)}function W(t,e){var n=(n=r.iteratee||kt)===kt?x:n;return arguments.length?n(t,e):n}function G(t,e){var n=t.__data__,r=_typeof(e);return("string"==r||"number"==r||"symbol"==r||"boolean"==r?"__proto__"!==e:null===e)?n["string"==typeof e?"string":"hash"]:n.map}function q(t,e){var n=null==t?Mt:t[e];return!bt(n)||he&&he in n||!(pt(n)?ge:Gt).test(rt(n))?Mt:n}function J(t,e,n){for(var r=-1,o=(e=F(e,t)).length,a=!1;++r<o;){var i=nt(e[r]);if(!(a=null!=t&&n(t,i)))break;t=t[i]}return a||++r!=o?a:!!(o=null==t?0:t.length)&&yt(o)&&Q(i,o)&&(hn(t)||bn(t))}function Y(t){return"function"!=typeof t.constructor||Z(t)?{}:Ye(Oe(t))}function K(t){return hn(t)||bn(t)||!!(Se&&t&&t[Se])}function Q(t,e){var n=_typeof(t);return!!(e=null==e?9007199254740991:e)&&("number"==n||"symbol"!=n&&Jt.test(t))&&-1<t&&0==t%1&&t<e}function X(t,e){if(hn(t))return!1;var n=_typeof(t);return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!gt(t))||Pt.test(t)||!Ut.test(t)||null!=e&&t in Object(e)}function Z(t){var e=t&&t.constructor;return t===("function"==typeof e&&e.prototype||le)}function tt(e,n){return function(t){return null!=t&&t[e]===n&&(n!==Mt||e in Object(t))}}function et(o,a,i){return a=De(a===Mt?o.length-1:a,0),function(){for(var t=arguments,e=-1,n=De(t.length-a,0),r=Array(n);++e<n;)r[e]=t[a+e];for(e=-1,n=Array(a+1);++e<a;)n[e]=t[e];return n[a]=i(r),function(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)}(o,this,n)}}function nt(t){if("string"==typeof t||gt(t))return t;var e=t+"";return"0"==e&&1/t==-zt?"-0":e}function rt(t){if(null==t)return"";try{return ye.call(t)}catch(t){}return t+""}function ot(t,e,n){var r=null==t?0:t.length;return r?((n=null==n?0:jt(n))<0&&(n=De(r+n,0)),o(t,W(e,3),n)):-1}function at(t){return null!=t&&t.length?function t(e,n,r,o,a){var i=-1,u=e.length;for(r=r||K,a=a||[];++i<u;){var c=e[i];0<n&&r(c)?1<n?t(c,n-1,r,o,a):f(a,c):o||(a[a.length]=c)}return a}(t,1):[]}function it(t){var e=null==t?0:t.length;return e?t[e-1]:Mt}function ut(r,o){function a(){var t=arguments,e=o?o.apply(this,t):t[0],n=a.cache;return n.has(e)?n.get(e):(t=r.apply(this,t),a.cache=n.set(e,t)||n,t)}if("function"!=typeof r||null!=o&&"function"!=typeof o)throw new TypeError("Expected a function");return a.cache=new(ut.Cache||s),a}function ct(e){if("function"!=typeof e)throw new TypeError("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!e.call(this);case 1:return!e.call(this,t[0]);case 2:return!e.call(this,t[0],t[1]);case 3:return!e.call(this,t[0],t[1],t[2])}return!e.apply(this,t)}}function ft(t,e){return t===e||t!=t&&e!=e}function st(t){return null!=t&&yt(t.length)&&!pt(t)}function lt(t){return ht(t)&&st(t)}function pt(t){return!!bt(t)&&("[object Function]"==(t=w(t))||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t)}function yt(t){return"number"==typeof t&&-1<t&&0==t%1&&t<=9007199254740991}function bt(t){var e=_typeof(t);return null!=t&&("object"==e||"function"==e)}function ht(t){return null!=t&&"object"==_typeof(t)}function vt(t){return!(!ht(t)||"[object Object]"!=w(t))&&(null===(t=Oe(t))||"function"==typeof(t=be.call(t,"constructor")&&t.constructor)&&t instanceof t&&ye.call(t)==de)}function dt(t){return"string"==typeof t||!hn(t)&&ht(t)&&"[object String]"==w(t)}function gt(t){return"symbol"==_typeof(t)||ht(t)&&"[object Symbol]"==w(t)}function _t(t){return t?(t=mt(t))===zt||t===-zt?17976931348623157e292*(t<0?-1:1):t==t?t:0:0===t?t:0}function jt(t){var e=(t=_t(t))%1;return t==t?e?t-e:t:0}function mt(t){if("number"==typeof t)return t;if(gt(t))return Ct;if(bt(t)&&(t=bt(t="function"==typeof t.valueOf?t.valueOf():t)?t+"":t),"string"!=typeof t)return 0===t?t:+t;t=t.replace($t,"");var e=Wt.test(t);return e||qt.test(t)?Xt(t.slice(2),e?2:8):Bt.test(t)?Ct:+t}function At(t){return P(t,St(t))}function Ot(t){return null==t?"":N(t)}function wt(t,e,n){return(t=null==t?Mt:A(t,e))===Mt?n:t}function Et(t,e){return null!=t&&J(t,e,L)}function Lt(t){return st(t)?l(t):I(t)}function St(t){if(st(t))t=l(t,!0);else if(bt(t)){var e,n=Z(t),r=[];for(e in t)("constructor"!=e||!n&&be.call(t,e))&&r.push(e);t=r}else{if(e=[],null!=t)for(n in Object(t))e.push(n);t=e}return t}function Tt(t){return null==t?[]:function(e,t){return a(t,function(t){return e[t]})}(t,Lt(t))}function xt(t){return function(){return t}}function It(t){return t}function kt(t){return x("function"==typeof t?t:m(t,1))}function Nt(t){return X(t)?function(e){return function(t){return null==t?Mt:t[e]}}(nt(t)):function(e){return function(t){return A(t,e)}}(t)}function Dt(){return[]}function Ft(){return!1}var Mt,zt=1/0,Ct=NaN,Ut=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Pt=/^\w*$/,Rt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,$t=/^\s+|\s+$/g,Vt=/\\(\\)?/g,Ht=/\w*$/,Bt=/^[-+]0x[0-9a-f]+$/i,Wt=/^0b[01]+$/i,Gt=/^\[object .+?Constructor\]$/,qt=/^0o[0-7]+$/i,Jt=/^(?:0|[1-9]\d*)$/,Yt={};
8884Yt["[object Float32Array]"]=Yt["[object Float64Array]"]=Yt["[object Int8Array]"]=Yt["[object Int16Array]"]=Yt["[object Int32Array]"]=Yt["[object Uint8Array]"]=Yt["[object Uint8ClampedArray]"]=Yt["[object Uint16Array]"]=Yt["[object Uint32Array]"]=!0,Yt["[object Arguments]"]=Yt["[object Array]"]=Yt["[object ArrayBuffer]"]=Yt["[object Boolean]"]=Yt["[object DataView]"]=Yt["[object Date]"]=Yt["[object Error]"]=Yt["[object Function]"]=Yt["[object Map]"]=Yt["[object Number]"]=Yt["[object Object]"]=Yt["[object RegExp]"]=Yt["[object Set]"]=Yt["[object String]"]=Yt["[object WeakMap]"]=!1;var Kt={};Kt["[object Arguments]"]=Kt["[object Array]"]=Kt["[object ArrayBuffer]"]=Kt["[object DataView]"]=Kt["[object Boolean]"]=Kt["[object Date]"]=Kt["[object Float32Array]"]=Kt["[object Float64Array]"]=Kt["[object Int8Array]"]=Kt["[object Int16Array]"]=Kt["[object Int32Array]"]=Kt["[object Map]"]=Kt["[object Number]"]=Kt["[object Object]"]=Kt["[object RegExp]"]=Kt["[object Set]"]=Kt["[object String]"]=Kt["[object Symbol]"]=Kt["[object Uint8Array]"]=Kt["[object Uint8ClampedArray]"]=Kt["[object Uint16Array]"]=Kt["[object Uint32Array]"]=!0,Kt["[object Error]"]=Kt["[object Function]"]=Kt["[object WeakMap]"]=!1;var Qt,Xt=parseInt,Zt="object"==_typeof(On)&&On&&On.Object===Object&&On,te="object"==("undefined"==typeof self?"undefined":_typeof(self))&&self&&self.Object===Object&&self,ee=Zt||te||Function("return this")(),ne="object"==_typeof(En)&&En&&!En.nodeType&&En,re=ne&&"object"==_typeof(wn)&&wn&&!wn.nodeType&&wn,oe=re&&re.exports===ne,ae=oe&&Zt.process;t:{try{Qt=ae&&ae.binding&&ae.binding("util");break t}catch(t){}Qt=void 0}var ie,ue=Qt&&Qt.isMap,ce=Qt&&Qt.isSet,fe=Qt&&Qt.isTypedArray,se=Array.prototype,le=Object.prototype,pe=ee["__core-js_shared__"],ye=Function.prototype.toString,be=le.hasOwnProperty,he=(ie=/[^.]+$/.exec(pe&&pe.keys&&pe.keys.IE_PROTO||""))?"Symbol(src)_1."+ie:"",ve=le.toString,de=ye.call(Object),ge=RegExp("^"+ye.call(be).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),_e=oe?ee.Buffer:Mt,je=ee.Symbol,me=ee.Uint8Array,Ae=_e?_e.a:Mt,Oe=e(Object.getPrototypeOf),we=Object.create,Ee=le.propertyIsEnumerable,Le=se.splice,Se=je?je.isConcatSpreadable:Mt,Te=je?je.toStringTag:Mt,xe=function(){try{var t=q(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),Ie=Object.getOwnPropertySymbols,ke=_e?_e.isBuffer:Mt,Ne=e(Object.keys),De=Math.max,Fe=Date.now,Me=q(ee,"DataView"),ze=q(ee,"Map"),Ce=q(ee,"Promise"),Ue=q(ee,"Set"),Pe=q(ee,"WeakMap"),Re=q(Object,"create"),$e=rt(Me),Ve=rt(ze),He=rt(Ce),Be=rt(Ue),We=rt(Pe),Ge=je?je.prototype:Mt,qe=Ge?Ge.valueOf:Mt,Je=Ge?Ge.toString:Mt,Ye=function(t){return bt(t)?we?we(t):(Ke.prototype=t,t=new Ke,Ke.prototype=Mt,t):{}};function Ke(){}u.prototype.clear=function(){this.__data__=Re?Re(null):{},this.size=0},u.prototype.delete=function(t){return t=this.has(t)&&delete this.__data__[t],this.size-=t?1:0,t},u.prototype.get=function(t){var e=this.__data__;return Re?"__lodash_hash_undefined__"===(t=e[t])?Mt:t:be.call(e,t)?e[t]:Mt},u.prototype.has=function(t){var e=this.__data__;return Re?e[t]!==Mt:be.call(e,t)},u.prototype.set=function(t,e){var n=this.__data__;return this.size+=this.has(t)?0:1,n[t]=Re&&e===Mt?"__lodash_hash_undefined__":e,this},c.prototype.clear=function(){this.__data__=[],this.size=0},c.prototype.delete=function(t){var e=this.__data__;return!((t=p(e,t))<0||(t==e.length-1?e.pop():Le.call(e,t,1),--this.size,0))},c.prototype.get=function(t){var e=this.__data__;return(t=p(e,t))<0?Mt:e[t][1]},c.prototype.has=function(t){return-1<p(this.__data__,t)},c.prototype.set=function(t,e){var n=this.__data__,r=p(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this},s.prototype.clear=function(){this.size=0,this.__data__={hash:new u,map:new(ze||c),string:new u}},s.prototype.delete=function(t){return t=G(this,t).delete(t),this.size-=t?1:0,t},s.prototype.get=function(t){return G(this,t).get(t)},s.prototype.has=function(t){return G(this,t).has(t)},s.prototype.set=function(t,e){var n=G(this,t),r=n.size;return n.set(t,e),this.size+=n.size==r?0:1,this},d.prototype.add=d.prototype.push=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this},d.prototype.has=function(t){return this.__data__.has(t)},g.prototype.clear=function(){this.__data__=new c,this.size=0},g.prototype.delete=function(t){var e=this.__data__;return t=e.delete(t),this.size=e.size,t},g.prototype.get=function(t){return this.__data__.get(t)},g.prototype.has=function(t){return this.__data__.has(t)},g.prototype.set=function(t,e){var n=this.__data__;if(n instanceof c){var r=n.__data__;if(!ze||r.length<199)return r.push([t,e]),this.size=++n.size,this;n=this.__data__=new s(r)}return n.set(t,e),this.size=n.size,this};var Qe=function(t,e){if(null==t)return t;if(!st(t))return function(t,e){return t&&Xe(t,e,Lt)}(t,e);for(var n=t.length,r=-1,o=Object(t);++r<n&&!1!==e(o[r],r,o););return t},Xe=function(t,e,n){for(var r=-1,o=Object(t),a=(n=n(t)).length;a--;){var i=n[++r];if(!1===e(o[i],i,o))break}return t},Ze=xe?function(t,e){return xe(t,"toString",{configurable:!0,enumerable:!1,value:xt(e),writable:!0})}:It,tn=Ie?function(e){return null==e?[]:(e=Object(e),n(Ie(e),function(t){return Ee.call(e,t)}))}:Dt,en=Ie?function(t){for(var e=[];t;)f(e,tn(t)),t=Oe(t);return e}:Dt,nn=w;(Me&&"[object DataView]"!=nn(new Me(new ArrayBuffer(1)))||ze&&"[object Map]"!=nn(new ze)||Ce&&"[object Promise]"!=nn(Ce.resolve())||Ue&&"[object Set]"!=nn(new Ue)||Pe&&"[object WeakMap]"!=nn(new Pe))&&(nn=function(t){var e=w(t);if(t=(t="[object Object]"==e?t.constructor:Mt)?rt(t):"")switch(t){case $e:return"[object DataView]";case Ve:return"[object Map]";case He:return"[object Promise]";case Be:return"[object Set]";case We:return"[object WeakMap]"}return e});var rn,on,an,un,cn,fn,sn=(un=Ze,fn=cn=0,function(){var t=Fe(),e=16-(t-fn);if(fn=t,0<e){if(800<=++cn)return arguments[0]}else cn=0;return un.apply(Mt,arguments)}),ln=(an=(on=ut(on=function(t){var o=[];return 46===t.charCodeAt(0)&&o.push(""),t.replace(Rt,function(t,e,n,r){o.push(n?r.replace(Vt,"$1"):e||t)}),o},function(t){return 500===an.size&&an.clear(),t})).cache,on),pn=(rn=ot,function(t,e,n){var r=Object(t);if(!st(t)){var o=W(e,3);t=Lt(t),e=function(t){return o(r[t],t,r)}}return-1<(e=rn(t,e,n))?r[o?t[e]:e]:Mt});ut.Cache=s;var yn,bn=S(function(){return arguments}())?S:function(t){return ht(t)&&be.call(t,"callee")&&!Ee.call(t,"callee")},hn=Array.isArray,vn=ke||Ft,dn=ue?t(ue):function(t){return ht(t)&&"[object Map]"==nn(t)},gn=ce?t(ce):function(t){return ht(t)&&"[object Set]"==nn(t)}
8884,_n=fe?t(fe):function(t){return ht(t)&&yt(t.length)&&!!Yt[w(t)]},jn=R(function(t,e,n){k(t,e,n)}),mn=R(function(t,e,n,r){k(t,e,n,r)}),An=sn(et(yn=function(e,t){var n={};if(null==e)return n;var r=!1;t=a(t,function(t){return t=F(t,e),r=r||1<t.length,t}),P(e,B(e),n),r&&(n=m(n,7,$));for(var o=t.length;o--;)D(n,t[o]);return n},Mt,at),yn+"");r.constant=xt,r.flatten=at,r.iteratee=kt,r.keys=Lt,r.keysIn=St,r.memoize=ut,r.merge=jn,r.mergeWith=mn,r.negate=ct,r.omit=An,r.property=Nt,r.reject=function(t,e){return(hn(t)?n:function(t,r){var o=[];return Qe(t,function(t,e,n){r(t,e,n)&&o.push(t)}),o})(t,ct(W(e,3)))},r.toPlainObject=At,r.values=Tt,r.cloneDeep=function(t){return m(t,5)},r.cloneDeepWith=function(t,e){return m(t,5,e="function"==typeof e?e:Mt)},r.eq=ft,r.find=pn,r.findIndex=ot,r.get=wt,r.has=function(t,e){return null!=t&&J(t,e,E)},r.hasIn=Et,r.identity=It,r.includes=function(t,e,n,r){if(t=st(t)?t:Tt(t),n=n&&!r?jt(n):0,r=t.length,n<0&&(n=De(r+n,0)),dt(t))t=n<=r&&-1<t.indexOf(e,n);else{if(r=!!r){if(e==e)t:{for(n-=1,r=t.length;++n<r;)if(t[n]===e){t=n;break t}t=-1}else t=o(t,i,n);r=-1<t}t=r}return t},r.isArguments=bn,r.isArray=hn,r.isArrayLike=st,r.isArrayLikeObject=lt,r.isBuffer=vn,r.isEmpty=function(t){if(null==t)return!0;if(st(t)&&(hn(t)||"string"==typeof t||"function"==typeof t.splice||vn(t)||_n(t)||bn(t)))return!t.length;var e=nn(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if(Z(t))return!I(t).length;for(var n in t)if(be.call(t,n))return!1;return!0},r.isEqual=function(t,e){return T(t,e)},r.isFunction=pt,r.isLength=yt,r.isMap=dn,r.isNull=function(t){return null===t},r.isObject=bt,r.isObjectLike=ht,r.isPlainObject=vt,r.isSet=gn,r.isString=dt,r.isSymbol=gt,r.isTypedArray=_n,r.last=it,r.stubArray=Dt,r.stubFalse=Ft,r.toFinite=_t,r.toInteger=jt,r.toNumber=mt,r.toString=Ot,r.VERSION="4.17.5",re&&((re.exports=r)._=r,ne._=r)}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],2:[function(t,e,n){e.exports={itemType:{DATA:"data",FCTN:"fctn",EVENT:"event",LISTENER_ON:"listenerOn",LISTENER_OFF:"listenerOff"},dataLayerEvent:{CHANGE:"adobeDataLayer:change",EVENT:"adobeDataLayer:event"},listenerScope:{PAST:"past",FUTURE:"future",ALL:"all"}}},{}],3:[function(t,e,n){var r=t("../custom-lodash"),c=t("../version.json").version,l=r.cloneDeep,p=r.get,y=t("./item"),b=t("./listener"),h=t("./listenerManager"),v=t("./constants"),d=t("./utils/customMerge");e.exports=function(t){var f,e=t||{},n=[],r=[],o={},a={getState:function(){return o},getDataLayer:function(){return n}};function i(t){o=d(o,t.data)}function u(t){t.valid?{data:function(t){i(t),f.triggerListeners(t)},fctn:function(t){t.config.call(n,n)},event:function(t){t.data&&i(t),f.triggerListeners(t)},listenerOn:function(t){var e=b(t);switch(e.scope){case v.listenerScope.PAST:var n,r=_createForOfIteratorHelper(c(t));try{for(r.s();!(n=r.n()).done;){var o=n.value;f.triggerListener(e,o)}}catch(t){r.e(t)}finally{r.f()}break;case v.listenerScope.FUTURE:f.register(e);break;case v.listenerScope.ALL:if(f.register(e)){var a,i=_createForOfIteratorHelper(c(t));try{for(i.s();!(a=i.n()).done;){var u=a.value;f.triggerListener(e,u)}}catch(t){i.e(t)}finally{i.f()}}}},listenerOff:function(t){f.unregister(b(t))}}[t.type](t):s(t);function c(t){return 0===n.length||t.index>n.length-1?[]:n.slice(0,t.index).map(function(t){return y(t)})}}function s(t){var e="The following item cannot be handled by the data layer because it does not have a valid format: "+JSON.stringify(t.config);console.error(e)}return function(){Array.isArray(e.dataLayer)||(e.dataLayer=[]);r=e.dataLayer.splice(0,e.dataLayer.length),(n=e.dataLayer).version=c,o={},f=h(a)}(),n.push=function(t){var n=arguments,r=arguments;if(Object.keys(n).forEach(function(t){var e=y(n[t]);switch(e.valid||(s(e),delete r[t]),e.type){case v.itemType.DATA:case v.itemType.EVENT:u(e);break;case v.itemType.FCTN:delete r[t],u(e);break;case v.itemType.LISTENER_ON:case v.itemType.LISTENER_OFF:delete r[t]}}),r[0])return Array.prototype.push.apply(this,r)},n.getState=function(t){return t?p(l(o),t):l(o)},n.addEventListener=function(t,e,n){u(y({on:t,handler:e,scope:n&&n.scope,path:n&&n.path}))},n.removeEventListener=function(t,e){u(y({off:t,handler:e}))},function(){for(var t=0;t<r.length;t++)n.push(r[t])}(),a}},{"../custom-lodash":1,"../version.json":14,"./constants":2,"./item":5,"./listener":7,"./listenerManager":8,"./utils/customMerge":10}],4:[function(t,e,n){var r={Manager:t("./dataLayerManager")};window.adobeDataLayer=window.adobeDataLayer||[],window.adobeDataLayer.version?console.warn("Adobe Client Data Layer v".concat(window.adobeDataLayer.version," has already been imported/initialized on this page. You may be erroneously loading it a second time.")):r.Manager({dataLayer:window.adobeDataLayer}),e.exports=r},{"./dataLayerManager":3}],5:[function(t,e,n){var r=t("../custom-lodash"),i=r.isPlainObject,u=r.isEmpty,c=r.omit,f=r.find,s=t("./utils/dataMatchesContraints"),l=t("./itemConstraints"),p=t("./constants");e.exports=function(t,e){var n=t,r=e,o=f(Object.keys(l),function(t){return s(n,l[t])})||"function"==typeof n&&p.itemType.FCTN||i(n)&&p.itemType.DATA,a=function(){var t=c(n,Object.keys(l.event));if(!u(t))return t}();return{config:n,type:o,data:a,valid:!!o,index:r}}},{"../custom-lodash":1,"./constants":2,"./itemConstraints":6,"./utils/dataMatchesContraints":11}],6:[function(t,e,n){e.exports={event:{event:{type:"string"},eventInfo:{optional:!0}},listenerOn:{on:{type:"string"},handler:{type:"function"},scope:{type:"string",values:["past","future","all"],optional:!0},path:{type:"string",optional:!0}},listenerOff:{off:{type:"string"},handler:{type:"function",optional:!0},scope:{type:"string",values:["past","future","all"],optional:!0},path:{type:"string",optional:!0}}}},{}],7:[function(t,e,n){var r=t("./constants");e.exports=function(t){return{event:t.config.on||t.config.off,handler:t.config.handler||null,scope:t.config.scope||t.config.on&&r.listenerScope.ALL||null,path:t.config.path||null}}},{"./constants":2}],8:[function(t,e,n){var u=t("../custom-lodash").cloneDeep,c=t("./constants"),f=t("./utils/listenerMatch"),s=t("./utils/indexOfListener");e.exports=function(t){var o={},r=t,a=s.bind(null,o);function i(t,e){if(f(t,e)){var n=[u(e.config)];t.handler.apply(r.getDataLayer(),n)}}return{register:function(t){var e=t.event;return Object.prototype.hasOwnProperty.call(o,e)?-1===a(t)&&(o[t.event].push(t),!0):(o[t.event]=[t],!0)},unregister:function(t){var e=t.event;if(Object.prototype.hasOwnProperty.call(o,e))if(t.handler||t.scope||t.path){var n=a(t);-1<n&&o[e].splice(n,1)}else o[e]=[]},triggerListeners:function(r){(function(t){var e=[];switch(t.type){case c.itemType.DATA:e.push(c.dataLayerEvent.CHANGE);break;case c.itemType.EVENT:e.push(c.dataLayerEvent.EVENT),t.data&&e.push(c.dataLayerEvent.CHANGE),t.config.event!==c.dataLayerEvent.CHANGE&&e.push(t.config.event)}return e})(r).forEach(function(t){if(Object.prototype.hasOwnProperty.call(o,t)){var e,n=_createForOfIteratorHelper(o[t]);try{for(n.s();!(e=n.n()).done;){i(e.value,r)}}catch(t){n.e(t)}finally{n.f()}}})},triggerListener:function(t,e){i(t,e)}}}},{"../custom-lodash":1,"./constants":2,"./utils/indexOfListener":12,"./utils/listenerMatch":13}],9:[function(t,e,n){var r=t("../../custom-lodash"),o=r.has,a=r.get;e.exports=function(t,e){for(var n=e.substring(0,e.lastIndexOf("."));n;){if(o(t,n)){var r=a(t,n);if(null==r)return!0}n=n.substring(0,n.lastIndexOf("."))}return!1}},{"../../custom-lodash":1}],10:[function(t,e,n){var r=t("../../custom-lodash"),s=r.cloneDeepWith,l=r.isObject,p=r.isArray,y=r.reject,o=r.mergeWith,a=r.isNull;e.exports=function(t,e){return o(t,e,function(t,e,n,r){if(null==e)return null}),t=function(t,e){return s(t,function(f){return function e(t,n,r,o){if(l(t)){if(p(t))return y(t,f).map(function(t){return s(t,e)});for(var a={},i=0,u=Object.keys(t);i<u.length;i++){var c=u[i];f(t[c])||(a[c]=s(t[c],e))}return a}}}(1<arguments.length&&void 0!==e?e:function(t){return!t}))}(t,a)}},{"../../custom-lodash":1}],11:[function(t,e,n){var r=t("../../custom-lodash"),o=r.find,s=r.includes;e.exports=function(c,f){return void 0===o(Object.keys(f),function(t){var e=f[t].type,n=t&&f[t].values,r=!f[t].optional,o=c[t],a=_typeof(o),i=e&&a!==e,u=n&&!s(n,o);return r?!o||i||u:o&&(i||u)})}},{"../../custom-lodash":1}],12:[function(t,e,n){var c=t("../../custom-lodash").isEqual;e.exports=function(t,e){var n=e.event;if(Object.prototype.hasOwnProperty.call(t,n)){var r,o=_createForOfIteratorHelper(t[n].entries());try{for(o.s();!(r=o.n()).done;){var a=_slicedToArray(r.value,2),i=a[0],u=a[1];if(c(u.handler,e.handler))return i}}catch(t){o.e(t)}finally{o.f()}}return-1}},{"../../custom-lodash":1}],13:[function(t,e,n){var r=t("../../custom-lodash").has,a=t("../constants"),o=t("./ancestorRemoved");function i(t,e){return!e.data||!t.path||(r(e.data,t.path)||o(e.data,t.path))}
8884e.exports=function(t,e){var n=t.event,r=e.config,o=!1;return e.type===a.itemType.DATA?n===a.dataLayerEvent.CHANGE&&(o=i(t,e)):e.type===a.itemType.EVENT&&(n!==a.dataLayerEvent.EVENT&&n!==r.event||(o=i(t,e)),e.data&&n===a.dataLayerEvent.CHANGE&&(o=i(t,e))),o}},{"../../custom-lodash":1,"../constants":2,"./ancestorRemoved":9}],14:[function(t,e,n){e.exports={version:"2.0.2"}},{}]},{},[4]);
8885//# sourceMappingURL=adobe-client-data-layer.min.js.map
8886
8887/*******************************************************************************
8888 * Copyright 2020 Adobe
8889 *
8890 * Licensed under the Apache License, Version 2.0 (the "License");
8891 * you may not use this file except in compliance with the License.
8892 * You may obtain a copy of the License at
8893 *
8894 *     http://www.apache.org/licenses/LICENSE-2.0
8895 *
8896 * Unless required by applicable law or agreed to in writing, software
8897 * distributed under the License is distributed on an "AS IS" BASIS,
8898 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8899 * See the License for the specific language governing permissions and
8900 * limitations under the License.
8901 ******************************************************************************/
8902(function() {
8903    "use strict";
8904
8905    var dataLayerEnabled;
8906    var dataLayerName;
8907    var dataLayer;
8908
8909    function addComponentToDataLayer(component) {
8910        dataLayer.push({
8911            component: getComponentObject(component)
8912        });
8913    }
8914
8915    function attachClickEventListener(element) {
8916        element.addEventListener("click", addClickToDataLayer);
8917    }
8918
8919    function getComponentObject(element) {
8920        var component = getComponentData(element);
8921        var componentID = Object.keys(component)[0];
8922        // if the component does not have a parent ID property, use the ID of the parent element
8923        if (component && component[componentID] && !component[componentID].parentId) {
8924            var parentElement = element.parentNode.closest("[data-cmp-data-layer], body");
8925            if (parentElement) {
8926                component[componentID].parentId = parentElement.id;
8927            }
8928        }
8929
8930        return component;
8931    }
8932
8933    function addClickToDataLayer(event) {
8934        var element = event.currentTarget;
8935        var componentId = getClickId(element);
8936
8937        dataLayer.push({
8938            event: "cmp:click",
8939            eventInfo: {
8940                path: "component." + componentId
8941            }
8942        });
8943    }
8944
8945    function getComponentData(element) {
8946        var dataLayerJson = element.dataset.cmpDataLayer;
8947        if (dataLayerJson) {
8948            return JSON.parse(dataLayerJson);
8949        } else {
8950            return undefined;
8951        }
8952    }
8953
8954    function getClickId(element) {
8955        if (element.dataset.cmpDataLayer) {
8956            return Object.keys(JSON.parse(element.dataset.cmpDataLayer))[0];
8957        }
8958
8959        var componentElement = element.closest("[data-cmp-data-layer]");
8960
8961        return Object.keys(JSON.parse(componentElement.dataset.cmpDataLayer))[0];
8962    }
8963
8964    function onDocumentReady() {
8965        dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
8966        if (dataLayerEnabled) {
8967            dataLayerName = document.body.getAttribute("data-cmp-data-layer-name") || "adobeDataLayer";
8968            dataLayer = window[dataLayerName] = window[dataLayerName] || [];
8969
8970            var components        = document.querySelectorAll("[data-cmp-data-layer]");
8971            var clickableElements = document.querySelectorAll("[data-cmp-clickable]");
8972
8973            components.forEach(function(component) {
8974                addComponentToDataLayer(component);
8975            });
8976
8977            clickableElements.forEach(function(element) {
8978                attachClickEventListener(element);
8979            });
8980
8981            dataLayer.push({
8982                event: "cmp:loaded"
8983            });
8984        }
8985    }
8986
8987    if (document.readyState !== "loading") {
8988        onDocumentReady();
8989    } else {
8990        document.addEventListener("DOMContentLoaded", onDocumentReady);
8991    }
8992
8993}());
8994
8995//Script for Adobe Analytics
8996{
8997  var cjaScript = document.createElement("script");
8998  cjaScript.type = "text/javascript";
8999  cjaScript.async = true;
9000  var windowLocation = location.host;
9001  function callAdobedtm() {
9002    if (windowLocation === "www.blueshieldca.com") {
9003      cjaScript.src = "https://assets.adobedtm.com/4292fae30116/2025583062c9/launch-bc4d4ddee690.min.js";
9004    }
9004 else if (windowLocation === "webh72.bsc.bscal.com") {
9005      cjaScript.src =
9006        "https://assets.adobedtm.com/4292fae30116/2025583062c9/launch-4752dd9a4f78-staging.min.js";
9007    }else {
9008      cjaScript.src =
9009        "https://assets.adobedtm.com/4292fae30116/2025583062c9/launch-73f269d5a602-development.min.js";
9010    }
9011  }
9012  callAdobedtm();
9013
9014  let s = document.getElementsByTagName('script')[0];
9015
9016  if (!document.querySelector('script[src*="assets.adobedtm.com"]')) {
9017    s.parentNode.insertBefore(cjaScript, s);
9018  }
9019  else {
9020    //do nothing
9021  }
9022
9023}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.