PageSourceSearch

https://www.straighttalk.com/etc.clientlibs/tracfone-core/clientli…ase.min.68b28a9a6d0ec52da94a439391632891.js

js straighttalk.com collected 2026-10-01 12:39:53 UTC 355,134 bytes, 7,379 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 dataLayerEnabled;
66    var dataLayer;
67
68    var NS = "cmp";
69    var IS = "accordion";
70
71    var keyCodes = {
72        ENTER: 13,
73        SPACE: 32,
74        END: 35,
75        HOME: 36,
76        ARROW_LEFT: 37,
77        ARROW_UP: 38,
78        ARROW_RIGHT: 39,
79        ARROW_DOWN: 40
80    };
81
82    var selectors = {
83        self: "[data-" + NS + '-is="' + IS + '"]'
84    };
85
86    var cssClasses = {
87        button: {
88            disabled: "cmp-accordion__button--disabled",
89            expanded: "cmp-accordion__button--expanded"
90        },
91        panel: {
92            hidden: "cmp-accordion__panel--hidden",
93            expanded: "cmp-accordion__panel--expanded"
94        }
95    };
96
97    var dataAttributes = {
98        item: {
99            expanded: "data-cmp-expanded"
100        }
101    };
102
103    var properties = {
104        /**
105         * Determines whether a single accordion item is forced to be expanded at a time.
106         * Expanding one item will collapse all others.
107         *
108         * @memberof Accordion
109         * @type {Boolean}
110         * @default false
111         */
112        "singleExpansion": {
113            "default": false,
114            "transform": function(value) {
115                return !(value === null || typeof value === "undefined");
116            }
117        }
118    };
119
120    /**
121     * Accordion Configuration.
122     *
123     * @typedef {Object} AccordionConfig Represents an Accordion configuration
124     * @property {HTMLElement} element The HTMLElement representing the Accordion
125     * @property {Object} options The Accordion options
126     */
127
128    /**
129     * Accordion.
130     *
131     * @class Accordion
132     * @classdesc An interactive Accordion component for toggling panels of related content
133     * @param {AccordionConfig} config The Accordion configuration
134     */
135    function Accordion(config) {
136        var that = this;
137
138        if (config && config.element) {
139            init(config);
140        }
141
142        /**
143         * Initializes the Accordion.
144         *
145         * @private
146         * @param {AccordionConfig} config The Accordion configuration
147         */
148        function init(config) {
149            that._config = config;
150
151            // prevents multiple initialization
152            config.element.removeAttribute("data-" + NS + "-is");
153
154            setupProperties(config.options);
155            cacheElements(config.element);
156
157            if (that._elements["item"]) {
158                // ensures multiple element types are arrays.
159                that._elements["item"] = Array.isArray(that._elements["item"]) ? that._elements["item"] : [that._elements["item"]];
160                that._elements["button"] = Array.isArray(that._elements["button"]) ? that._elements["button"] : [that._elements["button"]];
161                that._elements["panel"] = Array.isArray(that._elements["panel"]) ? that._elements["panel"] : [that._elements["panel"]];
162
163                // Expand the item based on deep-link-id if it matches with any existing accordion item id
164                var deepLinkItem = CQ.CoreComponents.container.utils.getDeepLinkItem(that, "item");
165                if (deepLinkItem && !deepLinkItem.hasAttribute(dataAttributes.item.expanded)) {
166                    setItemExpanded(deepLinkItem, true);
167                }
168
169                if (that._properties.singleExpansion) {
170                    // No deep linking
171                    if (!deepLinkItem) {
172                        var expandedItems = getExpandedItems();
173                        // no expanded item annotated, force the first item to display.
174                        if (expandedItems.length === 0) {
175                            toggle(0);
176                        }
177                        // multiple expanded items annotated, display the last item open.
178                        if (expandedItems.length > 1) {
179                            toggle(expandedItems.length - 1);
180                        }
181                    } else {
182                        // Deep link case
183                        // Collapse the items other than which is deep linked
184                        for (var j = 0; j < that._elements["item"].length; j++) {
185                            if (that._elements["item"][j].id !== deepLinkItem.id &&
186                                that._elements["item"][j].hasAttribute(dataAttributes.item.expanded)) {
187                                setItemExpanded(that._elements["item"][j], false);
188                            }
189                        }
190                    }
191                }
192
193                refreshItems();
194                bindEvents();
195
196                if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
197                    /*
198                     * Editor message handling:
199                     * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
200                     * - check that the message data panel container type is correct and that the id (path) matches this specific Accordion component
201                     * - if so, route the "navigate" operation to enact a navigation of the Accordion based on index data
202                     */
203                    CQ.CoreComponents.MESSAGE_CHANNEL = CQ.CoreComponents.MESSAGE_CHANNEL || new window.Granite.author.MessageChannel("cqauthor", window);
204                    CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage("cmp.panelcontainer", function(message) {
205                        if (message.data && message.data.type === "cmp-accordion" && message.data.id === that._elements.self.dataset["cmpPanelcontainerId"]) {
206                            if (message.data.operation === "navigate") {
207                                // switch to single expansion mode when navigating in edit mode.
208                                var singleExpansion = that._properties.singleExpansion;
209                                that._properties.singleExpansion = true;
210                                toggle(message.data.index);
211
212                                // revert to the configured state.
213                                that._properties.singleExpansion = singleExpansion;
214                            }
215                        }
216                    });
217                }
218            }
219        }
220
221        /**
222         * Caches the Accordion elements as defined via the {@code data-accordion-hook="ELEMENT_NAME"} markup API.
223         *
224         * @private
225         * @param {HTMLElement} wrapper The Accordion wrapper element
226         */
227        function cacheElements(wrapper) {
228            that._elements = {};
229            that._elements.self = wrapper;
230            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
231
232            for (var i = 0; i < hooks.length; i++) {
233                var hook = hooks[i];
234                if (hook.closest("." + NS + "-" + IS) === that._elements.self) { // only process own accordion elements
235                    var capitalized = IS;
236                    capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
237                    var key = hook.dataset[NS + "Hook" + capitalized];
238                    if (that._elements[key]) {
239                        if (!Array.isArray(that._elements[key])) {
240                            var tmp = that._elements[key];
241                            that._elements[key] = [tmp];
242                        }
243                        that._elements[key].push(hook);
244                    } else {
245                        that._elements[key] = hook;
246                    }
247                }
248            }
249        }
250
251        /**
252         * Sets up properties for the Accordion based on the passed options.
253         *
254         * @private
255         * @param {Object} options The Accordion options
256         */
257        function setupProperties(options) {
258            that._properties = {};
259
260            for (var key in properties) {
261                if (properties.hasOwnProperty(key)) {
262                    var property = properties[key];
263                    var value = null;
264
265                    if (options && options[key] != null) {
266                        value = options[key];
267
268                        // transform the provided option
269                        if (property && typeof property.transform === "function") {
270                            value = property.transform(value);
271                        }
272                    }
273
274                    if (value === null) {
275                        // value still null, take the property default
276                        value = properties[key]["default"];
277                    }
278
279                    that._properties[key] = value;
280                }
281            }
282        }
283
284        /**
285         * Binds Accordion event handling.
286         *
287         * @private
288         */
289        function bindEvents() {
290            var buttons = that._elements["button"];
291            if (buttons) {
292                for (var i = 0; i < buttons.length; i++) {
293                    (function(index) {
294                        buttons[i].addEventListener("click", function(event) {
295                            toggle(index);
296                            focusButton(index);
297                        });
298                        buttons[i].addEventListener("keydown", function(event) {
299                            onButtonKeyDown(event, index);
300                        });
301                    })(i);
302                }
303            }
304        }
305
306        /**
307         * Handles button keydown events.
308         *
309         * @private
310         * @param {Object} event The keydown event
311         * @param {Number} index The index of the button triggering the event
312         */
313        function onButtonKeyDown(event, index) {
314            var lastIndex = that._elements["button"].length - 1;
315
316            switch (event.keyCode) {
317                case keyCodes.ARROW_LEFT:
318                case keyCodes.ARROW_UP:
319                    event.preventDefault();
320                    if (index > 0) {
321                        focusButton(index - 1);
322                    }
323                    break;
324                case keyCodes.ARROW_RIGHT:
325                case keyCodes.ARROW_DOWN:
326                    event.preventDefault();
327                    if (index < lastIndex) {
328                        focusButton(index + 1);
329                    }
330                    break;
331                case keyCodes.HOME:
332                    event.preventDefault();
333                    focusButton(0);
334                    break;
335                case keyCodes.END:
336                    event.preventDefault();
337                    focusButton(lastIndex);
338                    break;
339                case keyCodes.ENTER:
340                case keyCodes.SPACE:
341                    event.preventDefault();
342                    toggle(index);
343                    focusButton(index);
344                    break;
345                default:
346                    return;
347            }
348        }
349
350        /**
351         * General handler for toggle of an item.
352         *
353         * @private
354         * @param {Number} index The index of the item to toggle
355         */
356        function toggle(index) {
357            var item = that._elements["item"][index];
358            if (item) {
359                if (that._properties.singleExpansion) {
360                    // ensure only a single item is expanded if single expansion is enabled.
361                    for (var i = 0; i < that._elements["item"].length; i++) {
362                        if (that._elements["item"][i] !== item) {
363                            var expanded = getItemExpanded(that._elements["item"][i]);
364                            if (expanded) {
365                                setItemExpanded(that._elements["item"][i], false);
366                            }
367                        }
368                    }
369                    setItemExpanded(item, true);
370                } else {
371                    setItemExpanded(item, !getItemExpanded(item));
372                }
373
374                if (dataLayerEnabled) {
375                    var accordionId = that._elements.self.id;
376                    var expandedItems = getExpandedItems()
377                        .map(function(item) {
378                            return Object.keys(JSON.parse(item.dataset.cmpDataLayer))[0];
379                        });
380
381                    var uploadPayload = {component: {}};
382                    uploadPayload.component[accordionId] = { shownItems: expandedItems };
383
384                    var removePayload = {component: {}};
385                    removePayload.component[accordionId] = { shownItems: undefined };
386
387                    dataLayer.push(removePayload);
388                    dataLayer.push(uploadPayload);
389                }
390            }
391        }
392
393        /**
394         * Sets an item's expanded state based on the provided flag and refreshes its internals.
395         *
396         * @private
397         * @param {HTMLElement} item The item to mark as expanded, or not expanded
398         * @param {Boolean} expanded true to mark the item expanded, false otherwise
399         */
400        function setItemExpanded(item, expanded) {
401            if (expanded) {
402                item.setAttribute(dataAttributes.item.expanded, "");
403                if (dataLayerEnabled) {
404                    dataLayer.push({
405                        event: "cmp:show",
406                        eventInfo: {
407                            path: "component." + getDataLayerId(item.dataset.cmpDataLayer)
408                        }
409                    });
410                }
411
412            } else {
413                item.removeAttribute(dataAttributes.item.expanded);
414                if (dataLayerEnabled) {
415                    dataLayer.push({
416                        event: "cmp:hide",
417                        eventInfo: {
418                            path: "component." + getDataLayerId(item.dataset.cmpDataLayer)
419                        }
420                    });
421                }
422            }
423            refreshItem(item);
424        }
425
426        /**
427         * Gets an item's expanded state.
428         *
429         * @private
430         * @param {HTMLElement} item The item for checking its expanded state
431         * @returns {Boolean} true if the item is expanded, false otherwise
432         */
433        function getItemExpanded(item) {
434            return item && item.dataset && item.dataset["cmpExpanded"] !== undefined;
435        }
436
437        /**
438         * Refreshes an item based on its expanded state.
439         *
440         * @private
441         * @param {HTMLElement} item The item to refresh
442         */
443        function refreshItem(item) {
444            var expanded = getItemExpanded(item);
445            if (expanded) {
446                expandItem(item);
447            } else {
448                collapseItem(item);
449            }
450        }
451
452        /**
453         * Refreshes all items based on their expanded state.
454         *
455         * @private
456         */
457        function refreshItems() {
458            for (var i = 0; i < that._elements["item"].length; i++) {
459                refreshItem(that._elements["item"][i]);
460            }
461        }
462
463        /**
464         * Returns all expanded items.
465         *
466         * @private
467         * @returns {HTMLElement[]} The expanded items
468         */
469        function getExpandedItems() {
470            var expandedItems = [];
471
472            for (var i = 0; i < that._elements["item"].length; i++) {
473                var item = that._elements["item"][i];
474                var expanded = getItemExpanded(item);
475                if (expanded) {
476                    expandedItems.push(item);
477                }
478            }
479
480            return expandedItems;
481        }
482
483        /**
484         * Annotates the item and its internals with
485         * the necessary style and accessibility attributes to indicate it is expanded.
486         *
487         * @private
488         * @param {HTMLElement} item The item to annotate as expanded
489         */
490        function expandItem(item) {
491            var index = that._elements["item"].indexOf(item);
492            if (index > -1) {
493                var button = that._elements["button"][index];
494                var panel = that._elements["panel"][index];
495                button.classList.add(cssClasses.button.expanded);
496                button.setAttribute("aria-expanded", true);
497                panel.classList.add(cssClasses.panel.expanded);
498                panel.classList.remove(cssClasses.panel.hidden);
499                panel.setAttribute("aria-hidden", false);
500
501                if (that._properties.singleExpansion) {
502                    button.classList.add(cssClasses.button.disabled);
503                    button.setAttribute("aria-disabled", true);
504                }
505            }
506        }
507
508        /**
509         * Annotates the item and its internals with
510         * the necessary style and accessibility attributes to indicate it is not expanded.
511         *
512         * @private
513         * @param {HTMLElement} item The item to annotate as not expanded
514         */
515        function collapseItem(item) {
516            var index = that._elements["item"].indexOf(item);
517            if (index > -1) {
518                var button = that._elements["button"][index];
519                var panel = that._elements["panel"][index];
520                button.classList.remove(cssClasses.button.disabled);
521                button.classList.remove(cssClasses.button.expanded);
522                button.removeAttribute("aria-disabled");
523                button.setAttribute("aria-expanded", false);
524                panel.classList.add(cssClasses.panel.hidden);
525                panel.classList.remove(cssClasses.panel.expanded);
526                panel.setAttribute("aria-hidden", true);
527            }
528        }
529
530        /**
531         * Focuses the button at the provided index.
532         *
533         * @private
534         * @param {Number} index The index of the button to focus
535         */
536        function focusButton(index) {
537            var button = that._elements["button"][index];
538            button.focus();
539        }
540    }
541
542    /**
543     * Reads options data from the Accordion wrapper element, defined via {@code data-cmp-*} data attributes.
544     *
545     * @private
546     * @param {HTMLElement} element The Accordion element to read options data from
547     * @returns {Object} The options read from the component data attributes
548     */
549    function readData(element) {
550        var data = element.dataset;
551        var options = [];
552        var capitalized = IS;
553        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
554        var reserved = ["is", "hook" + capitalized];
555
556        for (var key in data) {
557            if (data.hasOwnProperty(key)) {
558                var value = data[key];
559
560                if (key.indexOf(NS) === 0) {
561                    key = key.slice(NS.length);
562                    key = key.charAt(0).toLowerCase() + key.substring(1);
563
564                    if (reserved.indexOf(key) === -1) {
565                        options[key] = value;
566                    }
567                }
568            }
569        }
570
571        return options;
572    }
573
574    /**
575     * Parses the dataLayer string and returns the ID
576     *
577     * @private
578     * @param {String} componentDataLayer the dataLayer string
579     * @returns {String} dataLayerId or undefined
580     */
581    function getDataLayerId(componentDataLayer) {
582        return Object.keys(JSON.parse(componentDataLayer))[0];
583    }
584
585    /**
586     * Document ready handler and DOM mutation observers. Initializes Accordion components as necessary.
587     *
588     * @private
589     */
590    function onDocumentReady() {
591      dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
592      dataLayer = (dataLayerEnabled)? window.adobeDataLayer = window.adobeDataLayer || [] : undefined;
593
594      var elements = document.querySelectorAll(selectors.self);
595        for (var i = 0; i < elements.length; i++) {
596            new Accordion({ element: elements[i], options: readData(elements[i]) });
597        }
598
599        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
600        var body = document.querySelector("body");
601        var observer = new MutationObserver(function(mutations) {
602            mutations.forEach(function(mutation) {
603                // needed for IE
604                var nodesArray = [].slice.call(mutation.addedNodes);
605                if (nodesArray.length > 0) {
606                    nodesArray.forEach(function(addedNode) {
607                        if (addedNode.querySelectorAll) {
608                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
609                            elementsArray.forEach(function(element) {
610                                new Accordion({ element: element, options: readData(element) });
611                            });
612                        }
613                    });
614                }
615            });
616        });
617
618        observer.observe(body, {
619            subtree: true,
620            childList: true,
621            characterData: true
622        });
623    }
624
625    if (document.readyState !== "loading") {
626        onDocumentReady();
627    } else {
628        document.addEventListener("DOMContentLoaded", onDocumentReady);
629    }
630}());
631
632/*******************************************************************************
633 * Copyright 2018 Adobe
634 *
635 * Licensed under the Apache License, Version 2.0 (the "License");
636 * you may not use this file except in compliance with the License.
637 * You may obtain a copy of the License at
638 *
639 *     http://www.apache.org/licenses/LICENSE2.0
640 *
641 * Unless required by applicable law or agreed to in writing, software
642 * distributed under the License is distributed on an "AS IS" BASIS,
643 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
644 * See the License for the specific language governing permissions and
645 * limitations under the License.
646 ******************************************************************************/
647
648/**
649 * Element.matches()
650 * https://developer.mozilla.org/enUS/docs/Web/API/Element/matches#Polyfill
651 */
652if (!Element.prototype.matches) {
653    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
654}
655
656// eslint-disable-next-line valid-jsdoc
657/**
658 * Element.closest()
659 * https://developer.mozilla.org/enUS/docs/Web/API/Element/closest#Polyfill
660 */
661if (!Element.prototype.closest) {
662    Element.prototype.closest = function(s) {
663        "use strict";
664        var el = this;
665        if (!document.documentElement.contains(el)) {
666            return null;
667        }
668        do {
669            if (el.matches(s)) {
670                return el;
671            }
672            el = el.parentElement || el.parentNode;
673        } while (el !== null && el.nodeType === 1);
674        return null;
675    };
676}
677
678/*******************************************************************************
679 * Copyright 2018 Adobe
680 *
681 * Licensed under the Apache License, Version 2.0 (the "License");
682 * you may not use this file except in compliance with the License.
683 * You may obtain a copy of the License at
684 *
685 *     http://www.apache.org/licenses/LICENSE-2.0
686 *
687 * Unless required by applicable law or agreed to in writing, software
688 * distributed under the License is distributed on an "AS IS" BASIS,
689 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
690 * See the License for the specific language governing permissions and
691 * limitations under the License.
692 ******************************************************************************/
693(function() {
694    "use strict";
695
696    var dataLayerEnabled;
697    var dataLayer;
698
699    var NS = "cmp";
700    var IS = "tabs";
701
702    var keyCodes = {
703        END: 35,
704        HOME: 36,
705        ARROW_LEFT: 37,
706        ARROW_UP: 38,
707        ARROW_RIGHT: 39,
708        ARROW_DOWN: 40
709    };
710
711    var selectors = {
712        self: "[data-" + NS + '-is="' + IS + '"]',
713        active: {
714            tab: "cmp-tabs__tab--active",
715            tabpanel: "cmp-tabs__tabpanel--active"
716        }
717    };
718
719    /**
720     * Tabs Configuration
721     *
722     * @typedef {Object} TabsConfig Represents a Tabs configuration
723     * @property {HTMLElement} element The HTMLElement representing the Tabs
724     * @property {Object} options The Tabs options
725     */
726
727    /**
728     * Tabs
729     *
730     * @class Tabs
731     * @classdesc An interactive Tabs component for navigating a list of tabs
732     * @param {TabsConfig} config The Tabs configuration
733     */
734    function Tabs(config) {
735        var that = this;
736
737        if (config && config.element) {
738            init(config);
739        }
740
741        /**
742         * Initializes the Tabs
743         *
744         * @private
745         * @param {TabsConfig} config The Tabs configuration
746         */
747        function init(config) {
748            that._config = config;
749
750            // prevents multiple initialization
751            config.element.removeAttribute("data-" + NS + "-is");
752
753            cacheElements(config.element);
754            that._active = getActiveIndex(that._elements["tab"]);
755
756            if (that._elements.tabpanel) {
757                refreshActive();
758                bindEvents();
759            }
760
761            // Show the tab based on deep-link-id if it matches with any existing tab item id
762            var deepLinkItemIdx = CQ.CoreComponents.container.utils.getDeepLinkItemIdx(that, "tabpanel");
763            if (deepLinkItemIdx) {
764                var deepLinkItem = that._elements["tab"][deepLinkItemIdx];
765                if (deepLinkItem && that._elements["tab"][that._active].id !== deepLinkItem.id) {
766                    navigateAndFocusTab(deepLinkItemIdx);
767                }
768            }
769
770            if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
771                /*
772                 * Editor message handling:
773                 * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
774                 * - check that the message data panel container type is correct and that the id (path) matches this specific Tabs component
775                 * - if so, route the "navigate" operation to enact a navigation of the Tabs based on index data
776                 */
777                CQ.CoreComponents.MESSAGE_CHANNEL = CQ.CoreComponents.MESSAGE_CHANNEL || new window.Granite.author.MessageChannel("cqauthor", window);
778                CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage("cmp.panelcontainer", function(message) {
779                    if (message.data && message.data.type === "cmp-tabs" && message.data.id === that._elements.self.dataset["cmpPanelcontainerId"]) {
780                        if (message.data.operation === "navigate") {
781                            navigate(message.data.index);
782                        }
783                    }
784                });
785            }
786        }
787
788        /**
789         * Returns the index of the active tab, if no tab is active returns 0
790         *
791         * @param {Array} tabs Tab elements
792         * @returns {Number} Index of the active tab, 0 if none is active
793         */
794        function getActiveIndex(tabs) {
795            if (tabs) {
796                for (var i = 0; i < tabs.length; i++) {
797                    if (tabs[i].classList.contains(selectors.active.tab)) {
798                        return i;
799                    }
800                }
801            }
802            return 0;
803        }
804
805        /**
806         * Caches the Tabs elements as defined via the {@code data-tabs-hook="ELEMENT_NAME"} markup API
807         *
808         * @private
809         * @param {HTMLElement} wrapper The Tabs wrapper element
810         */
811        function cacheElements(wrapper) {
812            that._elements = {};
813            that._elements.self = wrapper;
814            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
815
816            for (var i = 0; i < hooks.length; i++) {
817                var hook = hooks[i];
818                if (hook.closest("." + NS + "-" + IS) === that._elements.self) { // only process own tab elements
819                    var capitalized = IS;
820                    capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
821                    var key = hook.dataset[NS + "Hook" + capitalized];
822                    if (that._elements[key]) {
823                        if (!Array.isArray(that._elements[key])) {
824                            var tmp = that._elements[key];
825                            that._elements[key] = [tmp];
826                        }
827                        that._elements[key].push(hook);
828                    } else {
829                        that._elements[key] = hook;
830                    }
831                }
832            }
833        }
834
835        /**
836         * Binds Tabs event handling
837         *
838         * @private
839         */
840        function bindEvents() {
841            var tabs = that._elements["tab"];
842            if (tabs) {
843                for (var i = 0; i < tabs.length; i++) {
844                    (function(index) {
845                        tabs[i].addEventListener("click", function(event) {
846                            navigateAndFocusTab(index);
847                        });
848                        tabs[i].addEventListener("keydown", function(event) {
849                            onKeyDown(event);
850                        });
851                    })(i);
852                }
853            }
854        }
855
856        /**
857         * Handles tab keydown events
858         *
859         * @private
860         * @param {Object} event The keydown event
861         */
862        function onKeyDown(event) {
863            var index = that._active;
864            var lastIndex = that._elements["tab"].length - 1;
865
866            switch (event.keyCode) {
867                case keyCodes.ARROW_LEFT:
868                case keyCodes.ARROW_UP:
869                    event.preventDefault();
870                    if (index > 0) {
871                        navigateAndFocusTab(index - 1);
872                    }
873                    break;
874                case keyCodes.ARROW_RIGHT:
875                case keyCodes.ARROW_DOWN:
876                    event.preventDefault();
877                    if (index < lastIndex) {
878                        navigateAndFocusTab(index + 1);
879                    }
880                    break;
881                case keyCodes.HOME:
882                    event.preventDefault();
883                    navigateAndFocusTab(0);
884                    break;
885                case keyCodes.END:
886                    event.preventDefault();
887                    navigateAndFocusTab(lastIndex);
888                    break;
889                default:
890                    return;
891            }
892        }
893
894        /**
895         * Refreshes the tab markup based on the current {@code Tabs#_active} index
896         *
897         * @private
898         */
899        function refreshActive() {
900            var tabpanels = that._elements["tabpanel"];
901            var tabs = that._elements["tab"];
902
903            if (tabpanels) {
904                if (Array.isArray(tabpanels)) {
905                    for (var i = 0; i < tabpanels.length; i++) {
906                        if (i === parseInt(that._active)) {
907                            tabpanels[i].classList.add(selectors.active.tabpanel);
908                            tabpanels[i].removeAttribute("aria-hidden");
909                            tabs[i].classList.add(selectors.active.tab);
910                            tabs[i].setAttribute("aria-selected", true);
911                            tabs[i].setAttribute("tabindex", "0");
912                        } else {
913                            tabpanels[i].classList.remove(selectors.active.tabpanel);
914                            tabpanels[i].setAttribute("aria-hidden", true);
915                            tabs[i].classList.remove(selectors.active.tab);
916                            tabs[i].setAttribute("aria-selected", false);
917                            tabs[i].setAttribute("tabindex", "-1");
918                        }
919                    }
920                } else {
921                    // only one tab
922                    tabpanels.classList.add(selectors.active.tabpanel);
923                    tabs.classList.add(selectors.active.tab);
924                }
925            }
926        }
927
928        /**
929         * Focuses the element and prevents scrolling the element into view
930         *
931         * @param {HTMLElement} element Element to focus
932         */
933        function focusWithoutScroll(element) {
934            var x = window.scrollX || window.pageXOffset;
935            var y = window.scrollY || window.pageYOffset;
936            element.focus();
937            window.scrollTo(x, y);
938        }
939
940        /**
941         * Navigates to the tab at the provided index
942         *
943         * @private
944         * @param {Number} index The index of the tab to navigate to
945         */
946        function navigate(index) {
947            that._active = index;
948            refreshActive();
949        }
950
951        /**
952         * Navigates to the item at the provided index and ensures the active tab gains focus
953         *
954         * @private
955         * @param {Number} index The index of the item to navigate to
956         */
957        function navigateAndFocusTab(index) {
958            var exActive = that._active;
959            navigate(index);
960            focusWithoutScroll(that._elements["tab"][index]);
961
962            if (dataLayerEnabled) {
963
964                var activeItem = getDataLayerId(that._elements.tabpanel[index].dataset.cmpDataLayer);
965                var exActiveItem = getDataLayerId(that._elements.tabpanel[exActive].dataset.cmpDataLayer);
966
967                dataLayer.push({
968                    event: "cmp:show",
969                    eventInfo: {
970                        path: "component." + activeItem
971                    }
972                });
973
974                dataLayer.push({
975                    event: "cmp:hide",
976                    eventInfo: {
977                        path: "component." + exActiveItem
978                    }
979                });
980
981                var tabsId = that._elements.self.id;
982                var uploadPayload = { component: {} };
983                uploadPayload.component[tabsId] = { shownItems: [activeItem] };
984
985                var removePayload = { component: {} };
986                removePayload.component[tabsId] = { shownItems: undefined };
987
988                dataLayer.push(removePayload);
989                dataLayer.push(uploadPayload);
990            }
991        }
992    }
993
994    /**
995     * Reads options data from the Tabs wrapper element, defined via {@code data-cmp-*} data attributes
996     *
997     * @private
998     * @param {HTMLElement} element The Tabs element to read options data from
999     * @returns {Object} The options read from the component data attributes
1000     */
1001    function readData(element) {
1002        var data = element.dataset;
1003        var options = [];
1004        var capitalized = IS;
1005        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
1006        var reserved = ["is", "hook" + capitalized];
1007
1008        for (var key in data) {
1009            if (data.hasOwnProperty(key)) {
1010                var value = data[key];
1011
1012                if (key.indexOf(NS) === 0) {
1013                    key = key.slice(NS.length);
1014                    key = key.charAt(0).toLowerCase() + key.substring(1);
1015
1016                    if (reserved.indexOf(key) === -1) {
1017                        options[key] = value;
1018                    }
1019                }
1020            }
1021        }
1022
1023        return options;
1024    }
1025
1026    /**
1027     * Parses the dataLayer string and returns the ID
1028     *
1029     * @private
1030     * @param {String} componentDataLayer the dataLayer string
1031     * @returns {String} dataLayerId or undefined
1032     */
1033    function getDataLayerId(componentDataLayer) {
1034        return Object.keys(JSON.parse(componentDataLayer))[0];
1035    }
1036
1037    /**
1038     * Document ready handler and DOM mutation observers. Initializes Tabs components as necessary.
1039     *
1040     * @private
1041     */
1042    function onDocumentReady() {
1043      dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
1044      dataLayer = (dataLayerEnabled)? window.adobeDataLayer = window.adobeDataLayer || [] : undefined;
1045
1046      var elements = document.querySelectorAll(selectors.self);
1047        for (var i = 0; i < elements.length; i++) {
1048            new Tabs({ element: elements[i], options: readData(elements[i]) });
1049        }
1050
1051        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
1052        var body = document.querySelector("body");
1053        var observer = new MutationObserver(function(mutations) {
1054            mutations.forEach(function(mutation) {
1055                // needed for IE
1056                var nodesArray = [].slice.call(mutation.addedNodes);
1057                if (nodesArray.length > 0) {
1058                    nodesArray.forEach(function(addedNode) {
1059                        if (addedNode.querySelectorAll) {
1060                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
1061                            elementsArray.forEach(function(element) {
1062                                new Tabs({ element: element, options: readData(element) });
1063                            });
1064                        }
1065                    });
1066                }
1067            });
1068        });
1069
1070        observer.observe(body, {
1071            subtree: true,
1072            childList: true,
1073            characterData: true
1074        });
1075    }
1076
1077    if (document.readyState !== "loading") {
1078        onDocumentReady();
1079    } else {
1080        document.addEventListener("DOMContentLoaded", onDocumentReady);
1081    }
1082
1083}());
1084
1085/*******************************************************************************
1086 * Copyright 2018 Adobe
1087 *
1088 * Licensed under the Apache License, Version 2.0 (the "License");
1089 * you may not use this file except in compliance with the License.
1090 * You may obtain a copy of the License at
1091 *
1092 *     http://www.apache.org/licenses/LICENSE-2.0
1093 *
1094 * Unless required by applicable law or agreed to in writing, software
1095 * distributed under the License is distributed on an "AS IS" BASIS,
1096 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1097 * See the License for the specific language governing permissions and
1098 * limitations under the License.
1099 ******************************************************************************/
1100(function() {
1101    "use strict";
1102
1103    var dataLayerEnabled;
1104    var dataLayer;
1105
1106    var NS = "cmp";
1107    var IS = "carousel";
1108
1109    var keyCodes = {
1110        SPACE: 32,
1111        END: 35,
1112        HOME: 36,
1113        ARROW_LEFT: 37,
1114        ARROW_UP: 38,
1115        ARROW_RIGHT: 39,
1116        ARROW_DOWN: 40
1117    };
1118
1119    var selectors = {
1120        self: "[data-" + NS + '-is="' + IS + '"]'
1121    };
1122
1123    var properties = {
1124        /**
1125         * Determines whether the Carousel will automatically transition between slides
1126         *
1127         * @memberof Carousel
1128         * @type {Boolean}
1129         * @default false
1130         */
1131        "autoplay": {
1132            "default": false,
1133            "transform": function(value) {
1134                return !(value === null || typeof value === "undefined");
1135            }
1136        },
1137        /**
1138         * Duration (in milliseconds) before automatically transitioning to the next slide
1139         *
1140         * @memberof Carousel
1141         * @type {Number}
1142         * @default 5000
1143         */
1144        "delay": {
1145            "default": 5000,
1146            "transform": function(value) {
1147                value = parseFloat(value);
1148                return !isNaN(value) ? value : null;
1149            }
1150        },
1151        /**
1152         * Determines whether automatic pause on hovering the carousel is disabled
1153         *
1154         * @memberof Carousel
1155         * @type {Boolean}
1156         * @default false
1157         */
1158        "autopauseDisabled": {
1159            "default": false,
1160            "transform": function(value) {
1161                return !(value === null || typeof value === "undefined");
1162            }
1163        }
1164    };
1165
1166    /**
1167     * Carousel Configuration
1168     *
1169     * @typedef {Object} CarouselConfig Represents a Carousel configuration
1170     * @property {HTMLElement} element The HTMLElement representing the Carousel
1171     * @property {Object} options The Carousel options
1172     */
1173
1174    /**
1175     * Carousel
1176     *
1177     * @class Carousel
1178     * @classdesc An interactive Carousel component for navigating a list of generic items
1179     * @param {CarouselConfig} config The Carousel configuration
1180     */
1181    function Carousel(config) {
1182        var that = this;
1183
1184        if (config && config.element) {
1185            init(config);
1186        }
1187
1188        /**
1189         * Initializes the Carousel
1190         *
1191         * @private
1192         * @param {CarouselConfig} config The Carousel configuration
1193         */
1194        function init(config) {
1195            // prevents multiple initialization
1196            config.element.removeAttribute("data-" + NS + "-is");
1197
1198            setupProperties(config.options);
1199            cacheElements(config.element);
1200
1201            that._active = 0;
1202            that._paused = false;
1203
1204            if (that._elements.item) {
1205                refreshActive();
1206                bindEvents();
1207                resetAutoplayInterval();
1208                refreshPlayPauseActions();
1209            }
1210
1211            // TODO: This section is only relevant in edit mode and should move to the editor clientLib
1212            if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
1213                /*
1214                 * Editor message handling:
1215                 * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
1216                 * - check that the message data panel container type is correct and that the id (path) matches this specific Carousel component
1217                 * - if so, route the "navigate" operation to enact a navigation of the Carousel based on index data
1218                 */
1219                window.CQ = window.CQ || {};
1220                window.CQ.CoreComponents = window.CQ.CoreComponents || {};
1221                CQ.CoreComponents.MESSAGE_CHANNEL = CQ.CoreComponents.MESSAGE_CHANNEL || new window.Granite.author.MessageChannel("cqauthor", window);
1222                CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage("cmp.panelcontainer", function(message) {
1223                    if (message.data && message.data.type === "cmp-carousel" && message.data.id === that._elements.self.dataset["cmpPanelcontainerId"]) {
1224                        if (message.data.operation === "navigate") {
1225                            navigate(message.data.index);
1226                        }
1227                    }
1228                });
1229            }
1230        }
1231
1232        /**
1233         * Caches the Carousel elements as defined via the {@code data-carousel-hook="ELEMENT_NAME"} markup API
1234         *
1235         * @private
1236         * @param {HTMLElement} wrapper The Carousel wrapper element
1237         */
1238        function cacheElements(wrapper) {
1239            that._elements = {};
1240            that._elements.self = wrapper;
1241            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
1242
1243            for (var i = 0; i < hooks.length; i++) {
1244                var hook = hooks[i];
1245                var capitalized = IS;
1246                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
1247                var key = hook.dataset[NS + "Hook" + capitalized];
1248                if (that._elements[key]) {
1249                    if (!Array.isArray(that._elements[key])) {
1250                        var tmp = that._elements[key];
1251                        that._elements[key] = [tmp];
1252                    }
1253                    that._elements[key].push(hook);
1254                } else {
1255                    that._elements[key] = hook;
1256                }
1257            }
1258        }
1259
1260        /**
1261         * Sets up properties for the Carousel based on the passed options.
1262         *
1263         * @private
1264         * @param {Object} options The Carousel options
1265         */
1266        function setupProperties(options) {
1267            that._properties = {};
1268
1269            for (var key in properties) {
1270                if (properties.hasOwnProperty(key)) {
1271                    var property = properties[key];
1272                    var value = null;
1273
1274                    if (options && options[key] != null) {
1275                        value = options[key];
1276
1277                        // transform the provided option
1278                        if (property && typeof property.transform === "function") {
1279                            value = property.transform(value);
1280                        }
1281                    }
1282
1283                    if (value === null) {
1284                        // value still null, take the property default
1285                        value = properties[key]["default"];
1286                    }
1287
1288                    that._properties[key] = value;
1289                }
1290            }
1291        }
1292
1293        /**
1294         * Binds Carousel event handling
1295         *
1296         * @private
1297         */
1298        function bindEvents() {
1299            if (that._elements["previous"]) {
1300                that._elements["previous"].addEventListener("click", function() {
1301                    var index = getPreviousIndex();
1302                    navigate(index);
1303                    if (dataLayerEnabled) {
1304                        dataLayer.push({
1305                            event: "cmp:show",
1306                            eventInfo: {
1307                                path: "component." + getDataLayerId(that._elements.item[index].dataset.cmpDataLayer)
1308                            }
1309                        });
1310                    }
1311                });
1312            }
1313
1314            if (that._elements["next"]) {
1315                that._elements["next"].addEventListener("click", function() {
1316                    var index = getNextIndex();
1317                    navigate(index);
1318                    if (dataLayerEnabled) {
1319                        dataLayer.push({
1320                            event: "cmp:show",
1321                            eventInfo: {
1322                                path: "component." + getDataLayerId(that._elements.item[index].dataset.cmpDataLayer)
1323                            }
1324                        });
1325                    }
1326                });
1327            }
1328
1329            var indicators = that._elements["indicator"];
1330            if (indicators) {
1331                for (var i = 0; i < indicators.length; i++) {
1332                    (function(index) {
1333                        indicators[i].addEventListener("click", function(event) {
1334                            navigateAndFocusIndicator(index);
1335                        });
1336                    })(i);
1337                }
1338            }
1339
1340            if (that._elements["pause"]) {
1341                if (that._properties.autoplay) {
1342                    that._elements["pause"].addEventListener("click", onPauseClick);
1343                }
1344            }
1345
1346            if (that._elements["play"]) {
1347                if (that._properties.autoplay) {
1348                    that._elements["play"].addEventListener("click", onPlayClick);
1349                }
1350            }
1351
1352            that._elements.self.addEventListener("keydown", onKeyDown);
1353
1354            if (!that._properties.autopauseDisabled) {
1355                that._elements.self.addEventListener("mouseenter", onMouseEnter);
1356                that._elements.self.addEventListener("mouseleave", onMouseLeave);
1357            }
1358        }
1359
1360        /**
1361         * Handles carousel keydown events
1362         *
1363         * @private
1364         * @param {Object} event The keydown event
1365         */
1366        function onKeyDown(event) {
1367            var index = that._active;
1368            var lastIndex = that._elements["indicator"].length - 1;
1369
1370            switch (event.keyCode) {
1371                case keyCodes.ARROW_LEFT:
1372                case keyCodes.ARROW_UP:
1373                    event.preventDefault();
1374                    if (index > 0) {
1375                        navigateAndFocusIndicator(index - 1);
1376                    }
1377                    break;
1378                case keyCodes.ARROW_RIGHT:
1379                case keyCodes.ARROW_DOWN:
1380                    event.preventDefault();
1381                    if (index < lastIndex) {
1382                        navigateAndFocusIndicator(index + 1);
1383                    }
1384                    break;
1385                case keyCodes.HOME:
1386                    event.preventDefault();
1387                    navigateAndFocusIndicator(0);
1388                    break;
1389                case keyCodes.END:
1390                    event.preventDefault();
1391                    navigateAndFocusIndicator(lastIndex);
1392                    break;
1393                case keyCodes.SPACE:
1394                    if (that._properties.autoplay && (event.target !== that._elements["previous"] && event.target !== that._elements["next"])) {
1395                        event.preventDefault();
1396                        if (!that._paused) {
1397                            pause();
1398                        } else {
1399                            play();
1400                        }
1401                    }
1402                    if (event.target === that._elements["pause"]) {
1403                        that._elements["play"].focus();
1404                    }
1405                    if (event.target === that._elements["play"]) {
1406                        that._elements["pause"].focus();
1407                    }
1408                    break;
1409                default:
1410                    return;
1411            }
1412        }
1413
1414        /**
1415         * Handles carousel mouseenter events
1416         *
1417         * @private
1418         * @param {Object} event The mouseenter event
1419         */
1420        function onMouseEnter(event) {
1421            clearAutoplayInterval();
1422        }
1423
1424        /**
1425         * Handles carousel mouseleave events
1426         *
1427         * @private
1428         * @param {Object} event The mouseleave event
1429         */
1430        function onMouseLeave(event) {
1431            resetAutoplayInterval();
1432        }
1433
1434        /**
1435         * Handles pause element click events
1436         *
1437         * @private
1438         * @param {Object} event The click event
1439         */
1440        function onPauseClick(event) {
1441            pause();
1442            that._elements["play"].focus();
1443        }
1444
1445        /**
1446         * Handles play element click events
1447         *
1448         * @private
1449         * @param {Object} event The click event
1450         */
1451        function onPlayClick() {
1452            play();
1453            that._elements["pause"].focus();
1454        }
1455
1456        /**
1457         * Pauses the playing of the Carousel. Sets {@code Carousel#_paused} marker.
1458         * Only relevant when autoplay is enabled
1459         *
1460         * @private
1461         */
1462        function pause() {
1463            that._paused = true;
1464            clearAutoplayInterval();
1465            refreshPlayPauseActions();
1466        }
1467
1468        /**
1469         * Enables the playing of the Carousel. Sets {@code Carousel#_paused} marker.
1470         * Only relevant when autoplay is enabled
1471         *
1472         * @private
1473         */
1474        function play() {
1475            that._paused = false;
1476
1477            // If the Carousel is hovered, don't begin auto transitioning until the next mouse leave event
1478            var hovered = false;
1479            if (that._elements.self.parentElement) {
1480                hovered = that._elements.self.parentElement.querySelector(":hover") === that._elements.self;
1481            }
1482            if (that._properties.autopauseDisabled || !hovered) {
1483                resetAutoplayInterval();
1484            }
1485
1486            refreshPlayPauseActions();
1487        }
1488
1489        /**
1490         * Refreshes the play/pause action markup based on the {@code Carousel#_paused} state
1491         *
1492         * @private
1493         */
1494        function refreshPlayPauseActions() {
1495            setActionDisabled(that._elements["pause"], that._paused);
1496            setActionDisabled(that._elements["play"], !that._paused);
1497        }
1498
1499        /**
1500         * Refreshes the item markup based on the current {@code Carousel#_active} index
1501         *
1502         * @private
1503         */
1504        function refreshActive() {
1505            var items = that._elements["item"];
1506            var indicators = that._elements["indicator"];
1507
1508            if (items) {
1509                if (Array.isArray(items)) {
1510                    for (var i = 0; i < items.length; i++) {
1511                        if (i === parseInt(that._active)) {
1512                            items[i].classList.add("cmp-carousel__item--active");
1513                            items[i].removeAttribute("aria-hidden");
1514                            indicators[i].classList.add("cmp-carousel__indicator--active");
1515                            indicators[i].setAttribute("aria-selected", true);
1516                            indicators[i].setAttribute("tabindex", "0");
1517                        } else {
1518                            items[i].classList.remove("cmp-carousel__item--active");
1519                            items[i].setAttribute("aria-hidden", true);
1520                            indicators[i].classList.remove("cmp-carousel__indicator--active");
1521                            indicators[i].setAttribute("aria-selected", false);
1522                            indicators[i].setAttribute("tabindex", "-1");
1523                        }
1524                    }
1525                } else {
1526                    // only one item
1527                    items.classList.add("cmp-carousel__item--active");
1528                    indicators.classList.add("cmp-carousel__indicator--active");
1529                }
1530            }
1531        }
1532
1533        /**
1534         * Focuses the element and prevents scrolling the element into view
1535         *
1536         * @param {HTMLElement} element Element to focus
1537         */
1538        function focusWithoutScroll(element) {
1539            var x = window.scrollX || window.pageXOffset;
1540            var y = window.scrollY || window.pageYOffset;
1541            element.focus();
1542            window.scrollTo(x, y);
1543        }
1544
1545        /**
1546         * Retrieves the next active index, with looping
1547         *
1548         * @private
1549         * @returns {Number} Index of the next carousel item
1550         */
1551        function getNextIndex() {
1552            return that._active === (that._elements["item"].length - 1) ? 0 : that._active + 1;
1553        }
1554
1555        /**
1556         * Retrieves the previous active index, with looping
1557         *
1558         * @private
1559         * @returns {Number} Index of the previous carousel item
1560         */
1561        function getPreviousIndex() {
1562            return that._active === 0 ? (that._elements["item"].length - 1) : that._active - 1;
1563        }
1564
1565        /**
1566         * Navigates to the item at the provided index
1567         *
1568         * @private
1569         * @param {Number} index The index of the item to navigate to
1570         */
1571        function navigate(index) {
1572            if (index < 0 || index > (that._elements["item"].length - 1)) {
1573                return;
1574            }
1575
1576            that._active = index;
1577            refreshActive();
1578
1579            if (dataLayerEnabled) {
1580                var carouselId = that._elements.self.id;
1581                var activeItem = getDataLayerId(that._elements.item[index].dataset.cmpDataLayer);
1582                var updatePayload = { component: {} };
1583                updatePayload.component[carouselId] = { shownItems: [activeItem] };
1584
1585                var removePayload = { component: {} };
1586                removePayload.component[carouselId] = { shownItems: undefined };
1587
1588                dataLayer.push(removePayload);
1589                dataLayer.push(updatePayload);
1590            }
1591
1592            // reset the autoplay transition interval following navigation, if not already hovering the carousel
1593            if (that._elements.self.parentElement) {
1594                if (that._elements.self.parentElement.querySelector(":hover") !== that._elements.self) {
1595                    resetAutoplayInterval();
1596                }
1597            }
1598        }
1599
1600        /**
1601         * Navigates to the item at the provided index and ensures the active indicator gains focus
1602         *
1603         * @private
1604         * @param {Number} index The index of the item to navigate to
1605         */
1606        function navigateAndFocusIndicator(index) {
1607            navigate(index);
1608            focusWithoutScroll(that._elements["indicator"][index]);
1609
1610            if (dataLayerEnabled) {
1611                dataLayer.push({
1612                    event: "cmp:show",
1613                    eventInfo: {
1614                        path: "component." + getDataLayerId(that._elements.item[index].dataset.cmpDataLayer)
1615                    }
1616                });
1617            }
1618        }
1619
1620        /**
1621         * Starts/resets automatic slide transition interval
1622         *
1623         * @private
1624         */
1625        function resetAutoplayInterval() {
1626            if (that._paused || !that._properties.autoplay) {
1627                return;
1628            }
1629            clearAutoplayInterval();
1630            that._autoplayIntervalId = window.setInterval(function() {
1631                if (document.visibilityState && document.hidden) {
1632                    return;
1633                }
1634                var indicators = that._elements["indicators"];
1635                if (indicators !== document.activeElement && indicators.contains(document.activeElement)) {
1636                    // if an indicator has focus, ensure we switch focus following navigation
1637                    navigateAndFocusIndicator(getNextIndex());
1638                } else {
1639                    navigate(getNextIndex());
1640                }
1641            }, that._properties.delay);
1642        }
1643
1644        /**
1645         * Clears/pauses automatic slide transition interval
1646         *
1647         * @private
1648         */
1649        function clearAutoplayInterval() {
1650            window.clearInterval(that._autoplayIntervalId);
1651            that._autoplayIntervalId = null;
1652        }
1653
1654        /**
1655         * Sets the disabled state for an action and toggles the appropriate CSS classes
1656         *
1657         * @private
1658         * @param {HTMLElement} action Action to disable
1659         * @param {Boolean} [disable] {@code true} to disable, {@code false} to enable
1660         */
1661        function setActionDisabled(action, disable) {
1662            if (!action) {
1663                return;
1664            }
1665            if (disable !== false) {
1666                action.disabled = true;
1667                action.classList.add("cmp-carousel__action--disabled");
1668            } else {
1669                action.disabled = false;
1670                action.classList.remove("cmp-carousel__action--disabled");
1671            }
1672        }
1673    }
1674
1675    /**
1676     * Reads options data from the Carousel wrapper element, defined via {@code data-cmp-*} data attributes
1677     *
1678     * @private
1679     * @param {HTMLElement} element The Carousel element to read options data from
1680     * @returns {Object} The options read from the component data attributes
1681     */
1682    function readData(element) {
1683        var data = element.dataset;
1684        var options = [];
1685        var capitalized = IS;
1686        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
1687        var reserved = ["is", "hook" + capitalized];
1688
1689        for (var key in data) {
1690            if (data.hasOwnProperty(key)) {
1691                var value = data[key];
1692
1693                if (key.indexOf(NS) === 0) {
1694                    key = key.slice(NS.length);
1695                    key = key.charAt(0).toLowerCase() + key.substring(1);
1696
1697                    if (reserved.indexOf(key) === -1) {
1698                        options[key] = value;
1699                    }
1700                }
1701            }
1702        }
1703
1704        return options;
1705    }
1706
1707    /**
1708     * Parses the dataLayer string and returns the ID
1709     *
1710     * @private
1711     * @param {String} componentDataLayer the dataLayer string
1712     * @returns {String} dataLayerId or undefined
1713     */
1714    function getDataLayerId(componentDataLayer) {
1715        return Object.keys(JSON.parse(componentDataLayer))[0];
1716    }
1717
1718    /**
1719     * Document ready handler and DOM mutation observers. Initializes Carousel components as necessary.
1720     *
1721     * @private
1722     */
1723    function onDocumentReady() {
1724      dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
1725      dataLayer = (dataLayerEnabled)? window.adobeDataLayer = window.adobeDataLayer || [] : undefined;
1726
1727      var elements = document.querySelectorAll(selectors.self);
1728        for (var i = 0; i < elements.length; i++) {
1729            new Carousel({ element: elements[i], options: readData(elements[i]) });
1730        }
1731
1732        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
1733        var body = document.querySelector("body");
1734        var observer = new MutationObserver(function(mutations) {
1735            mutations.forEach(function(mutation) {
1736                // needed for IE
1737                var nodesArray = [].slice.call(mutation.addedNodes);
1738                if (nodesArray.length > 0) {
1739                    nodesArray.forEach(function(addedNode) {
1740                        if (addedNode.querySelectorAll) {
1741                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
1742                            elementsArray.forEach(function(element) {
1743                                new Carousel({ element: element, options: readData(element) });
1744                            });
1745                        }
1746                    });
1747                }
1748            });
1749        });
1750
1751        observer.observe(body, {
1752            subtree: true,
1753            childList: true,
1754            characterData: true
1755        });
1756    }
1757
1758    if (document.readyState !== "loading") {
1759        onDocumentReady();
1760    } else {
1761        document.addEventListener("DOMContentLoaded", onDocumentReady);
1762    }
1763
1764}());
1765
1766/*******************************************************************************
1767 * Copyright 2017 Adobe
1768 *
1769 * Licensed under the Apache License, Version 2.0 (the "License");
1770 * you may not use this file except in compliance with the License.
1771 * You may obtain a copy of the License at
1772 *
1773 *     http://www.apache.org/licenses/LICENSE-2.0
1774 *
1775 * Unless required by applicable law or agreed to in writing, software
1776 * distributed under the License is distributed on an "AS IS" BASIS,
1777 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1778 * See the License for the specific language governing permissions and
1779 * limitations under the License.
1780 ******************************************************************************/
1781if (window.Element && !Element.prototype.closest) {
1782    // eslint valid-jsdoc: "off"
1783    Element.prototype.closest =
1784        function(s) {
1785            "use strict";
1786            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
1787            var el      = this;
1788            var i;
1789            do {
1790                i = matches.length;
1791                while (--i >= 0 && matches.item(i) !== el) {
1792                    // continue
1793                }
1794            } while ((i < 0) && (el = el.parentElement));
1795            return el;
1796        };
1797}
1798
1799if (window.Element && !Element.prototype.matches) {
1800    Element.prototype.matches =
1801        Element.prototype.matchesSelector ||
1802        Element.prototype.mozMatchesSelector ||
1803        Element.prototype.msMatchesSelector ||
1804        Element.prototype.oMatchesSelector ||
1805        Element.prototype.webkitMatchesSelector ||
1806        function(s) {
1807            "use strict";
1808            var matches = (this.document || this.ownerDocument).querySelectorAll(s);
1809            var i       = matches.length;
1810            while (--i >= 0 && matches.item(i) !== this) {
1811                // continue
1812            }
1813            return i > -1;
1814        };
1815}
1816
1817if (!Object.assign) {
1818    Object.assign = function(target, varArgs) { // .length of function is 2
1819        "use strict";
1820        if (target === null) {
1821            throw new TypeError("Cannot convert undefined or null to object");
1822        }
1823
1824        var to = Object(target);
1825
1826        for (var index = 1; index < arguments.length; index++) {
1827            var nextSource = arguments[index];
1828
1829            if (nextSource !== null) {
1830                for (var nextKey in nextSource) {
1831                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
1832                        to[nextKey] = nextSource[nextKey];
1833                    }
1834                }
1835            }
1836        }
1837        return to;
1838    };
1839}
1840
1841(function(arr) {
1842    "use strict";
1843    arr.forEach(function(item) {
1844        if (item.hasOwnProperty("remove")) {
1845            return;
1846        }
1847        Object.defineProperty(item, "remove", {
1848            configurable: true,
1849            enumerable: true,
1850            writable: true,
1851            value: function remove() {
1852                this.parentNode.removeChild(this);
1853            }
1854        });
1855    });
1856})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
1857
1858/*******************************************************************************
1859 * Copyright 2016 Adobe
1860 *
1861 * Licensed under the Apache License, Version 2.0 (the "License");
1862 * you may not use this file except in compliance with the License.
1863 * You may obtain a copy of the License at
1864 *
1865 *     http://www.apache.org/licenses/LICENSE-2.0
1866 *
1867 * Unless required by applicable law or agreed to in writing, software
1868 * distributed under the License is distributed on an "AS IS" BASIS,
1869 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1870 * See the License for the specific language governing permissions and
1871 * limitations under the License.
1872 ******************************************************************************/
1873(function() {
1874    "use strict";
1875
1876    var NS = "cmp";
1877    var IS = "image";
1878
1879    var EMPTY_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
1880    var LAZY_THRESHOLD_DEFAULT = 0;
1881    var SRC_URI_TEMPLATE_WIDTH_VAR = "{.width}";
1882
1883    var selectors = {
1884        self: "[data-" + NS + '-is="' + IS + '"]',
1885        image: '[data-cmp-hook-image="image"]',
1886        map: '[data-cmp-hook-image="map"]',
1887        area: '[data-cmp-hook-image="area"]'
1888    };
1889
1890    var lazyLoader = {
1891        "cssClass": "cmp-image__image--is-loading",
1892        "style": {
1893            "height": 0,
1894            "padding-bottom": "" // will be replaced with % ratio
1895        }
1896    };
1897
1898    var properties = {
1899        /**
1900         * An array of alternative image widths (in pixels).
1901         * Used to replace a {.width} variable in the src property with an optimal width if a URI template is provided.
1902         *
1903         * @memberof Image
1904         * @type {Number[]}
1905         * @default []
1906         */
1907        "widths": {
1908            "default": [],
1909            "transform": function(value) {
1910                var widths = [];
1911                value.split(",").forEach(function(item) {
1912                    item = parseFloat(item);
1913                    if (!isNaN(item)) {
1914                        widths.push(item);
1915                    }
1916                });
1917                return widths;
1918            }
1919        },
1920        /**
1921         * Indicates whether the image should be rendered lazily.
1922         *
1923         * @memberof Image
1924         * @type {Boolean}
1925         * @default false
1926         */
1927        "lazy": {
1928            "default": false,
1929            "transform": function(value) {
1930                return !(value === null || typeof value === "undefined");
1931            }
1932        },
1933        /**
1934         * Indicates image is DynamicMedia image.
1935         *
1936         * @memberof Image
1937         * @type {Boolean}
1938         * @default false
1939         */
1940        "dmimage": {
1941            "default": false,
1942            "transform": function(value) {
1943                return !(value === null || typeof value === "undefined");
1944            }
1945        },
1946        /**
1947         * The lazy threshold.
1948         * This is the number of pixels, in advance of becoming visible, when an lazy-loading image should begin
1949         * to load.
1950         *
1951         * @memberof Image
1952         * @type {Number}
1953         * @default 0
1954         */
1955        "lazythreshold": {
1956            "default": 0,
1957            "transform": function(value) {
1958                const val =  parseInt(value);
1959                if (isNaN(val)) {
1960                    return LAZY_THRESHOLD_DEFAULT;
1961                }
1962                return val;
1963            }
1964        },
1965        /**
1966         * The image source.
1967         *
1968         * Can be a simple image source, or a URI template representation that
1969         * can be variable expanded - useful for building an image configuration with an alternative width.
1970         * e.g. '/path/image.coreimg{.width}.jpeg/1506620954214.jpeg'
1971         *
1972         * @memberof Image
1973         * @type {String}
1974         */
1975        "src": {
1976            "transform": function(value) {
1977                return decodeURIComponent(value);
1978            }
1979        }
1980    };
1981
1982    var devicePixelRatio = window.devicePixelRatio || 1;
1983
1984    function readData(element) {
1985        var data = element.dataset;
1986        var options = [];
1987        var capitalized = IS;
1988        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
1989        var reserved = ["is", "hook" + capitalized];
1990
1991        for (var key in data) {
1992            if (data.hasOwnProperty(key)) {
1993                var value = data[key];
1994
1995                if (key.indexOf(NS) === 0) {
1996                    key = key.slice(NS.length);
1997                    key = key.charAt(0).toLowerCase() + key.substring(1);
1998
1999                    if (reserved.indexOf(key) === -1) {
2000                        options[key] = value;
2001                    }
2002                }
2003            }
2004        }
2005
2006        return options;
2007    }
2008
2009    function Image(config) {
2010        var that = this;
2011
2012        var smartCrops = {};
2013
2014        function init(config) {
2015            // prevents multiple initialization
2016            config.element.removeAttribute("data-" + NS + "-is");
2017
2018            setupProperties(config.options);
2019            cacheElements(config.element);
2020            //check image is DM asset; if true try to make req=set
2021            if (config.options.src && config.options.hasOwnProperty("dmimage") && (config.options["smartcroprendition"] === "SmartCrop:Auto")) {
2022                var request = new XMLHttpRequest();
2023                var url = decodeURIComponent(config.options.src).split(SRC_URI_TEMPLATE_WIDTH_VAR)[0] + "?req=set,json";
2024
2025
2026                request.open("GET", url, false);
2027                request.onload = function() {
2028                    if (request.status >= 200 && request.status < 400) {
2029                        // success status
2030                        var responseText = request.responseText;
2031						var rePayload = new RegExp(/^(?:\/\*jsonp\*\/)?\s*([^()]+)\(([\s\S]+),\s*"[0-9]*"\);?$/gmi);
2032                        var rePayloadJSON = new RegExp(/^{[\s\S]*}$/gmi);
2033						var resPayload = rePayload.exec(responseText);
2034                        var smartcropList = "";
2035                        var payload;
2036                        if (resPayload) {
2037                            var payloadStr = resPayload[2];
2038                            if (rePayloadJSON.test(payloadStr)) {
2039                                payload = JSON.parse(payloadStr);
2040                            }
2041
2042                        }
2043                        //check "relation" - only in case of smartcrop preset
2044                        if (payload && payload.set.relation && payload.set.relation.length > 0) {
2045                            for(var i = 0; i < payload.set.relation.length ; i++) {
2046                                smartcropList += payload.set.relation[i].n +"\n";
2047			                    smartCrops[parseInt(payload.set.relation[i].userdata.SmartCropWidth)] = ":" + payload.set.relation[i].userdata.SmartCropDef;
2048                            }
2049                        }
2050                    } else {
2051                        // error status
2052                    }
2053                };
2054                request.send();
2055            }
2056
2057            if (!that._elements.noscript) {
2058                return;
2059            }
2060
2061            that._elements.container = that._elements.link ? that._elements.link : that._elements.self;
2062
2063            unwrapNoScript();
2064
2065            if (that._properties.lazy) {
2066                addLazyLoader();
2067            }
2068
2069            if (that._elements.map) {
2070                that._elements.image.addEventListener("load", onLoad);
2071            }
2072
2073            window.addEventListener("resize", onWindowResize);
2074            ["focus", "click", "load", "transitionend", "animationend", "scroll"].forEach(function(name) {
2075                document.addEventListener(name, that.update);
2076            });
2077
2078            that._elements.image.addEventListener("cmp-image-redraw", that.update);
2079            that.update();
2080        }
2081
2082        function loadImage() {
2083            var hasWidths = (that._properties.widths && that._properties.widths.length > 0) || Object.keys(smartCrops).length > 0;
2084            var replacement;
2085            if (Object.keys(smartCrops).length > 0) {
2086                var optimalWidth = getOptimalWidth(Object.keys(smartCrops));
2087                replacement = smartCrops[optimalWidth];
2088            } else {
2089                replacement = hasWidths ? (that._properties.dmimage ? "" : ".") + getOptimalWidth(that._properties.widths) : "";
2090            }
2091            var url = that._properties.src.replace(SRC_URI_TEMPLATE_WIDTH_VAR, replacement);
2092
2093            if (that._elements.image.getAttribute("src") !== url) {
2094                that._elements.image.setAttribute("src", url);
2095                if (!hasWidths) {
2096                    window.removeEventListener("scroll", that.update);
2097                }
2098            }
2099
2100            if (that._lazyLoaderShowing) {
2101                that._elements.image.addEventListener("load", removeLazyLoader);
2102            }
2103        }
2104
2105        function getOptimalWidth(widths) {
2106            var container = that._elements.self;
2107            var containerWidth = container.clientWidth;
2108            while (containerWidth === 0 && container.parentNode) {
2109                container = container.parentNode;
2110                containerWidth = container.clientWidth;
2111            }
2112            var optimalWidth = containerWidth * devicePixelRatio;
2113            var len = widths.length;
2114            var key = 0;
2115
2116            while ((key < len - 1) && (widths[key] < optimalWidth)) {
2117                key++;
2118            }
2119
2120            return widths[key].toString();
2121        }
2122
2123        function addLazyLoader() {
2124            var width = that._elements.image.getAttribute("width");
2125            var height = that._elements.image.getAttribute("height");
2126
2127            if (width && height) {
2128                var ratio = (height / width) * 100;
2129                var styles = lazyLoader.style;
2130
2131                styles["padding-bottom"] = ratio + "%";
2132
2133                for (var s in styles) {
2134                    if (styles.hasOwnProperty(s)) {
2135                        that._elements.image.style[s] = styles[s];
2136                    }
2137                }
2138            }
2139            that._elements.image.setAttribute("src", EMPTY_PIXEL);
2140            that._elements.image.classList.add(lazyLoader.cssClass);
2141            that._lazyLoaderShowing = true;
2142        }
2143
2144        function unwrapNoScript() {
2145            var markup = decodeNoscript(that._elements.noscript.textContent.trim());
2146            var parser = new DOMParser();
2147
2148            // temporary document avoids requesting the image before removing its src
2149            var temporaryDocument = parser.parseFromString(markup, "text/html");
2150            var imageElement = temporaryDocument.querySelector(selectors.image);
2151            imageElement.removeAttribute("src");
2152            that._elements.container.insertBefore(imageElement, that._elements.noscript);
2153
2154            var mapElement = temporaryDocument.querySelector(selectors.map);
2155            if (mapElement) {
2156                that._elements.container.insertBefore(mapElement, that._elements.noscript);
2157            }
2158
2159            that._elements.noscript.parentNode.removeChild(that._elements.noscript);
2160            if (that._elements.container.matches(selectors.image)) {
2161                that._elements.image = that._elements.container;
2162            } else {
2163                that._elements.image = that._elements.container.querySelector(selectors.image);
2164            }
2165
2166            that._elements.map = that._elements.container.querySelector(selectors.map);
2167            that._elements.areas = that._elements.container.querySelectorAll(selectors.area);
2168        }
2169
2170        function removeLazyLoader() {
2171            that._elements.image.classList.remove(lazyLoader.cssClass);
2172            for (var property in lazyLoader.style) {
2173                if (lazyLoader.style.hasOwnProperty(property)) {
2174                    that._elements.image.style[property] = "";
2175                }
2176            }
2177            that._elements.image.removeEventListener("load", removeLazyLoader);
2178            that._lazyLoaderShowing = false;
2179        }
2180
2181        function isLazyVisible() {
2182            if (that._elements.container.offsetParent === null) {
2183                return false;
2184            }
2185
2186            var wt = window.pageYOffset;
2187            var wb = wt + document.documentElement.clientHeight;
2188            var et = that._elements.container.getBoundingClientRect().top + wt;
2189            var eb = et + that._elements.container.clientHeight;
2190
2191            return eb >= wt - that._properties.lazythreshold && et <= wb + that._properties.lazythreshold;
2192        }
2193
2194        function resizeAreas() {
2195            if (that._elements.areas && that._elements.areas.length > 0) {
2196                for (var i = 0; i < that._elements.areas.length; i++) {
2197                    var width = that._elements.image.width;
2198                    var height = that._elements.image.height;
2199
2200                    if (width && height) {
2201                        var relcoords = that._elements.areas[i].dataset.cmpRelcoords;
2202                        if (relcoords) {
2203                            var relativeCoordinates = relcoords.split(",");
2204                            var coordinates = new Array(relativeCoordinates.length);
2205
2206                            for (var j = 0; j < coordinates.length; j++) {
2207                                if (j % 2 === 0) {
2208                                    coordinates[j] = parseInt(relativeCoordinates[j] * width);
2209                                } else {
2210                                    coordinates[j] = parseInt(relativeCoordinates[j] * height);
2211                                }
2212                            }
2213
2214                            that._elements.areas[i].coords = coordinates;
2215                        }
2216                    }
2217                }
2218            }
2219        }
2220
2221        function cacheElements(wrapper) {
2222            that._elements = {};
2223            that._elements.self = wrapper;
2224            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
2225
2226            for (var i = 0; i < hooks.length; i++) {
2227                var hook = hooks[i];
2228                var capitalized = IS;
2229                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
2230                var key = hook.dataset[NS + "Hook" + capitalized];
2231                that._elements[key] = hook;
2232            }
2233        }
2234
2235        function setupProperties(options) {
2236            that._properties = {};
2237
2238            for (var key in properties) {
2239                if (properties.hasOwnProperty(key)) {
2240                    var property = properties[key];
2241                    if (options && options[key] != null) {
2242                        if (property && typeof property.transform === "function") {
2243                            that._properties[key] = property.transform(options[key]);
2244                        } else {
2245                            that._properties[key] = options[key];
2246                        }
2247                    } else {
2248                        that._properties[key] = properties[key]["default"];
2249                    }
2250                }
2251            }
2252        }
2253
2254        function onWindowResize() {
2255            that.update();
2256            resizeAreas();
2257        }
2258
2259        function onLoad() {
2260            resizeAreas();
2261        }
2262
2263        that.update = function() {
2264            if (that._properties.lazy) {
2265                if (isLazyVisible()) {
2266                    loadImage();
2267                }
2268            } else {
2269                loadImage();
2270            }
2271        };
2272
2273        if (config && config.element) {
2274            init(config);
2275        }
2276    }
2277
2278    function onDocumentReady() {
2279        var elements = document.querySelectorAll(selectors.self);
2280        for (var i = 0; i < elements.length; i++) {
2281            new Image({ element: elements[i], options: readData(elements[i]) });
2282        }
2283
2284        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
2285        var body             = document.querySelector("body");
2286        var observer         = new MutationObserver(function(mutations) {
2287            mutations.forEach(function(mutation) {
2288                // needed for IE
2289                var nodesArray = [].slice.call(mutation.addedNodes);
2290                if (nodesArray.length > 0) {
2291                    nodesArray.forEach(function(addedNode) {
2292                        if (addedNode.querySelectorAll) {
2293                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
2294                            elementsArray.forEach(function(element) {
2295                                new Image({ element: element, options: readData(element) });
2296                            });
2297                        }
2298                    });
2299                }
2300            });
2301        });
2302
2303        observer.observe(body, {
2304            subtree: true,
2305            childList: true,
2306            characterData: true
2307        });
2308    }
2309
2310    if (document.readyState !== "loading") {
2311        onDocumentReady();
2312    } else {
2313        document.addEventListener("DOMContentLoaded", onDocumentReady);
2314    }
2315
2316    /*
2317        on drag & drop of the component into a parsys, noscript's content will be escaped multiple times by the editor which creates
2318        the DOM for editing; the HTML parser cannot be used here due to the multiple escaping
2319     */
2320    function decodeNoscript(text) {
2321        text = text.replace(/&(amp;)*lt;/g, "<");
2322        text = text.replace(/&(amp;)*gt;/g, ">");
2323        return text;
2324    }
2325
2326})();
2327
2328/*******************************************************************************
2329 * Copyright 2017 Adobe
2330 *
2331 * Licensed under the Apache License, Version 2.0 (the "License");
2332 * you may not use this file except in compliance with the License.
2333 * You may obtain a copy of the License at
2334 *
2335 *     http://www.apache.org/licenses/LICENSE-2.0
2336 *
2337 * Unless required by applicable law or agreed to in writing, software
2338 * distributed under the License is distributed on an "AS IS" BASIS,
2339 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2340 * See the License for the specific language governing permissions and
2341 * limitations under the License.
2342 ******************************************************************************/
2343(function() {
2344    "use strict";
2345
2346    var NS = "cmp";
2347    var IS = "search";
2348
2349    var DELAY = 300; // time before fetching new results when the user is typing a search string
2350    var LOADING_DISPLAY_DELAY = 300; // minimum time during which the loading indicator is displayed
2351    var PARAM_RESULTS_OFFSET = "resultsOffset";
2352
2353    var keyCodes = {
2354        TAB: 9,
2355        ENTER: 13,
2356        ESCAPE: 27,
2357        ARROW_UP: 38,
2358        ARROW_DOWN: 40
2359    };
2360
2361    var selectors = {
2362        self: "[data-" + NS + '-is="' + IS + '"]',
2363        item: {
2364            self: "[data-" + NS + "-hook-" + IS + '="item"]',
2365            title: "[data-" + NS + "-hook-" + IS + '="itemTitle"]',
2366            focused: "." + NS + "-search__item--is-focused"
2367        }
2368    };
2369
2370    var properties = {
2371        /**
2372         * The minimum required length of the search term before results are fetched.
2373         *
2374         * @memberof Search
2375         * @type {Number}
2376         * @default 3
2377         */
2378        minLength: {
2379            "default": 3,
2380            transform: function(value) {
2381                value = parseFloat(value);
2382                return isNaN(value) ? null : value;
2383            }
2384        },
2385        /**
2386         * The maximal number of results fetched by a search request.
2387         *
2388         * @memberof Search
2389         * @type {Number}
2390         * @default 10
2391         */
2392        resultsSize: {
2393            "default": 10,
2394            transform: function(value) {
2395                value = parseFloat(value);
2396                return isNaN(value) ? null : value;
2397            }
2398        }
2399    };
2400
2401    var idCount = 0;
2402
2403    function readData(element) {
2404        var data = element.dataset;
2405        var options = [];
2406        var capitalized = IS;
2407        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
2408        var reserved = ["is", "hook" + capitalized];
2409
2410        for (var key in data) {
2411            if (data.hasOwnProperty(key)) {
2412                var value = data[key];
2413
2414                if (key.indexOf(NS) === 0) {
2415                    key = key.slice(NS.length);
2416                    key = key.charAt(0).toLowerCase() + key.substring(1);
2417
2418                    if (reserved.indexOf(key) === -1) {
2419                        options[key] = value;
2420                    }
2421                }
2422            }
2423        }
2424
2425        return options;
2426    }
2427
2428    function toggleShow(element, show) {
2429        if (element) {
2430            if (show !== false) {
2431                element.style.display = "block";
2432                element.setAttribute("aria-hidden", false);
2433            } else {
2434                element.style.display = "none";
2435                element.setAttribute("aria-hidden", true);
2436            }
2437        }
2438    }
2439
2440    function serialize(form) {
2441        var query = [];
2442        if (form && form.elements) {
2443            for (var i = 0; i < form.elements.length; i++) {
2444                var node = form.elements[i];
2445                if (!node.disabled && node.name) {
2446                    var param = [node.name, encodeURIComponent(node.value)];
2447                    query.push(param.join("="));
2448                }
2449            }
2450        }
2451        return query.join("&");
2452    }
2453
2454    function mark(node, regex) {
2455        if (!node || !regex) {
2456            return;
2457        }
2458
2459        // text nodes
2460        if (node.nodeType === 3) {
2461            var nodeValue = node.nodeValue;
2462            var match = regex.exec(nodeValue);
2463
2464            if (nodeValue && match) {
2465                var element = document.createElement("mark");
2466                element.className = NS + "-search__item-mark";
2467                element.appendChild(document.createTextNode(match[0]));
2468
2469                var after = node.splitText(match.index);
2470                after.nodeValue = after.nodeValue.substring(match[0].length);
2471                node.parentNode.insertBefore(element, after);
2472            }
2473        } else if (node.hasChildNodes()) {
2474            for (var i = 0; i < node.childNodes.length; i++) {
2475                // recurse
2476                mark(node.childNodes[i], regex);
2477            }
2478        }
2479    }
2480
2481    function Search(config) {
2482        if (config.element) {
2483            // prevents multiple initialization
2484            config.element.removeAttribute("data-" + NS + "-is");
2485        }
2486
2487        this._cacheElements(config.element);
2488        this._setupProperties(config.options);
2489
2490        this._action = this._elements.form.getAttribute("action");
2491        this._resultsOffset = 0;
2492        this._hasMoreResults = true;
2493
2494        this._elements.input.addEventListener("input", this._onInput.bind(this));
2495        this._elements.input.addEventListener("focus", this._onInput.bind(this));
2496        this._elements.input.addEventListener("keydown", this._onKeydown.bind(this));
2497        this._elements.clear.addEventListener("click", this._onClearClick.bind(this));
2498        document.addEventListener("click", this._onDocumentClick.bind(this));
2499        this._elements.results.addEventListener("scroll", this._onScroll.bind(this));
2500
2501        this._makeAccessible();
2502    }
2503
2504    Search.prototype._displayResults = function() {
2505        if (this._elements.input.value.length === 0) {
2506            toggleShow(this._elements.clear, false);
2507            this._cancelResults();
2508        } else if (this._elements.input.value.length < this._properties.minLength) {
2509            toggleShow(this._elements.clear, true);
2510        } else {
2511            this._updateResults();
2512            toggleShow(this._elements.clear, true);
2513        }
2514    };
2515
2516    Search.prototype._onScroll = function(event) {
2517        // fetch new results when the results to be scrolled down are less than the visible results
2518        if (this._elements.results.scrollTop + 2 * this._elements.results.clientHeight >= this._elements.results.scrollHeight) {
2519            this._resultsOffset += this._properties.resultsSize;
2520            this._displayResults();
2521        }
2522    };
2523
2524    Search.prototype._onInput = function(event) {
2525        var self = this;
2526        self._cancelResults();
2527        // start searching when the search term reaches the minimum length
2528        this._timeout = setTimeout(function() {
2529            self._displayResults();
2530        }, DELAY);
2531    };
2532
2533    Search.prototype._onKeydown = function(event) {
2534        var self = this;
2535
2536        switch (event.keyCode) {
2537            case keyCodes.TAB:
2538                if (self._resultsOpen()) {
2539                    event.preventDefault();
2540                }
2541                break;
2542            case keyCodes.ENTER:
2543                event.preventDefault();
2544                if (self._resultsOpen()) {
2545                    var focused = self._elements.results.querySelector(selectors.item.focused);
2546                    if (focused) {
2547                        focused.click();
2548                    }
2549                }
2550                break;
2551            case keyCodes.ESCAPE:
2552                self._cancelResults();
2553                break;
2554            case keyCodes.ARROW_UP:
2555                if (self._resultsOpen()) {
2556                    event.preventDefault();
2557                    self._stepResultFocus(true);
2558                }
2559                break;
2560            case keyCodes.ARROW_DOWN:
2561                if (self._resultsOpen()) {
2562                    event.preventDefault();
2563                    self._stepResultFocus();
2564                } else {
2565                    // test the input and if necessary fetch and display the results
2566                    self._onInput();
2567                }
2568                break;
2569            default:
2570                return;
2571        }
2572    };
2573
2574    Search.prototype._onClearClick = function(event) {
2575        event.preventDefault();
2576        this._elements.input.value = "";
2577        toggleShow(this._elements.clear, false);
2578        toggleShow(this._elements.results, false);
2579    };
2580
2581    Search.prototype._onDocumentClick = function(event) {
2582        var inputContainsTarget =  this._elements.input.contains(event.target);
2583        var resultsContainTarget = this._elements.results.contains(event.target);
2584
2585        if (!(inputContainsTarget || resultsContainTarget)) {
2586            toggleShow(this._elements.results, false);
2587        }
2588    };
2589
2590    Search.prototype._resultsOpen = function() {
2591        return this._elements.results.style.display !== "none";
2592    };
2593
2594    Search.prototype._makeAccessible = function() {
2595        var id = NS + "-search-results-" + idCount;
2596        this._elements.input.setAttribute("aria-owns", id);
2597        this._elements.results.id = id;
2598        idCount++;
2599    };
2600
2601    Search.prototype._generateItems = function(data, results) {
2602        var self = this;
2603
2604        data.forEach(function(item) {
2605            var el = document.createElement("span");
2606            el.innerHTML = self._elements.itemTemplate.innerHTML;
2607            el.querySelectorAll(selectors.item.title)[0].appendChild(document.createTextNode(item.title));
2608            el.querySelectorAll(selectors.item.self)[0].setAttribute("href", item.url);
2609            results.innerHTML += el.innerHTML;
2610        });
2611    };
2612
2613    Search.prototype._markResults = function() {
2614        var nodeList = this._elements.results.querySelectorAll(selectors.item.self);
2615        var escapedTerm = this._elements.input.value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
2616        var regex = new RegExp("(" + escapedTerm + ")", "gi");
2617
2618        for (var i = this._resultsOffset - 1; i < nodeList.length; ++i) {
2619            var result = nodeList[i];
2620            mark(result, regex);
2621        }
2622    };
2623
2624    Search.prototype._stepResultFocus = function(reverse) {
2625        var results = this._elements.results.querySelectorAll(selectors.item.self);
2626        var focused = this._elements.results.querySelector(selectors.item.focused);
2627        var newFocused;
2628        var index = Array.prototype.indexOf.call(results, focused);
2629        var focusedCssClass = NS + "-search__item--is-focused";
2630
2631        if (results.length > 0) {
2632
2633            if (!reverse) {
2634                // highlight the next result
2635                if (index < 0) {
2636                    results[0].classList.add(focusedCssClass);
2637                } else if (index + 1 < results.length) {
2638                    results[index].classList.remove(focusedCssClass);
2639                    results[index + 1].classList.add(focusedCssClass);
2640                }
2641
2642                // if the last visible result is partially hidden, scroll up until it's completely visible
2643                newFocused = this._elements.results.querySelector(selectors.item.focused);
2644                if (newFocused) {
2645                    var bottomHiddenHeight = newFocused.offsetTop + newFocused.offsetHeight - this._elements.results.scrollTop - this._elements.results.clientHeight;
2646                    if (bottomHiddenHeight > 0) {
2647                        this._elements.results.scrollTop += bottomHiddenHeight;
2648                    } else {
2649                        this._onScroll();
2650                    }
2651                }
2652
2653            } else {
2654                // highlight the previous result
2655                if (index >= 1) {
2656                    results[index].classList.remove(focusedCssClass);
2657                    results[index - 1].classList.add(focusedCssClass);
2658                }
2659
2660                // if the first visible result is partially hidden, scroll down until it's completely visible
2661                newFocused = this._elements.results.querySelector(selectors.item.focused);
2662                if (newFocused) {
2663                    var topHiddenHeight = this._elements.results.scrollTop - newFocused.offsetTop;
2664                    if (topHiddenHeight > 0) {
2665                        this._elements.results.scrollTop -= topHiddenHeight;
2666                    }
2667                }
2668            }
2669        }
2670    };
2671
2672    Search.prototype._updateResults = function() {
2673        var self = this;
2674        if (self._hasMoreResults) {
2675            var request = new XMLHttpRequest();
2676            var url = self._action + "?" + serialize(self._elements.form) + "&" + PARAM_RESULTS_OFFSET + "=" + self._resultsOffset;
2677
2678            request.open("GET", url, true);
2679            request.onload = function() {
2680                // when the results are loaded: hide the loading indicator and display the search icon after a minimum period
2681                setTimeout(function() {
2682                    toggleShow(self._elements.loadingIndicator, false);
2683                    toggleShow(self._elements.icon, true);
2684                }, LOADING_DISPLAY_DELAY);
2685                if (request.status >= 200 && request.status < 400) {
2686                    // success status
2687                    var data = JSON.parse(request.responseText);
2688                    if (data.length > 0) {
2689                        self._generateItems(data, self._elements.results);
2690                        self._markResults();
2691                        toggleShow(self._elements.results, true);
2692                    } else {
2693                        self._hasMoreResults = false;
2694                    }
2695                    // the total number of results is not a multiple of the fetched results:
2696                    // -> we reached the end of the query
2697                    if (self._elements.results.querySelectorAll(selectors.item.self).length % self._properties.resultsSize > 0) {
2698                        self._hasMoreResults = false;
2699                    }
2700                } else {
2701                    // error status
2702                }
2703            };
2704            // when the results are loading: display the loading indicator and hide the search icon
2705            toggleShow(self._elements.loadingIndicator, true);
2706            toggleShow(self._elements.icon, false);
2707            request.send();
2708        }
2709    };
2710
2711    Search.prototype._cancelResults = function() {
2712        clearTimeout(this._timeout);
2713        this._elements.results.scrollTop = 0;
2714        this._resultsOffset = 0;
2715        this._hasMoreResults = true;
2716        this._elements.results.innerHTML = "";
2717    };
2718
2719    Search.prototype._cacheElements = function(wrapper) {
2720        this._elements = {};
2721        this._elements.self = wrapper;
2722        var hooks = this._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
2723
2724        for (var i = 0; i < hooks.length; i++) {
2725            var hook = hooks[i];
2726            var capitalized = IS;
2727            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
2728            var key = hook.dataset[NS + "Hook" + capitalized];
2729            this._elements[key] = hook;
2730        }
2731    };
2732
2733    Search.prototype._setupProperties = function(options) {
2734        this._properties = {};
2735
2736        for (var key in properties) {
2737            if (properties.hasOwnProperty(key)) {
2738                var property = properties[key];
2739                if (options && options[key] != null) {
2740                    if (property && typeof property.transform === "function") {
2741                        this._properties[key] = property.transform(options[key]);
2742                    } else {
2743                        this._properties[key] = options[key];
2744                    }
2745                } else {
2746                    this._properties[key] = properties[key]["default"];
2747                }
2748            }
2749        }
2750    };
2751
2752    function onDocumentReady() {
2753        var elements = document.querySelectorAll(selectors.self);
2754        for (var i = 0; i < elements.length; i++) {
2755            new Search({ element: elements[i], options: readData(elements[i]) });
2756        }
2757
2758        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
2759        var body = document.querySelector("body");
2760        var observer = new MutationObserver(function(mutations) {
2761            mutations.forEach(function(mutation) {
2762                // needed for IE
2763                var nodesArray = [].slice.call(mutation.addedNodes);
2764                if (nodesArray.length > 0) {
2765                    nodesArray.forEach(function(addedNode) {
2766                        if (addedNode.querySelectorAll) {
2767                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
2768                            elementsArray.forEach(function(element) {
2769                                new Search({ element: element, options: readData(element) });
2770                            });
2771                        }
2772                    });
2773                }
2774            });
2775        });
2776
2777        observer.observe(body, {
2778            subtree: true,
2779            childList: true,
2780            characterData: true
2781        });
2782    }
2783
2784    if (document.readyState !== "loading") {
2785        onDocumentReady();
2786    } else {
2787        document.addEventListener("DOMContentLoaded", onDocumentReady);
2788    }
2789
2790})();
2791
2792/*******************************************************************************
2793 * Copyright 2016 Adobe
2794 *
2795 * Licensed under the Apache License, Version 2.0 (the "License");
2796 * you may not use this file except in compliance with the License.
2797 * You may obtain a copy of the License at
2798 *
2799 *     http://www.apache.org/licenses/LICENSE-2.0
2800 *
2801 * Unless required by applicable law or agreed to in writing, softw
2801are
2802 * distributed under the License is distributed on an "AS IS" BASIS,
2803 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2804 * See the License for the specific language governing permissions and
2805 * limitations under the License.
2806 ******************************************************************************/
2807(function() {
2808    "use strict";
2809
2810    var NS = "cmp";
2811    var IS = "formText";
2812    var IS_DASH = "form-text";
2813
2814    var selectors = {
2815        self: "[data-" + NS + '-is="' + IS + '"]'
2816    };
2817
2818    var properties = {
2819        /**
2820         * A validation message to display if there is a type mismatch between the user input and expected input.
2821         *
2822         * @type {String}
2823         */
2824        constraintMessage: {
2825        },
2826        /**
2827         * A validation message to display if no input is supplied, but input is expected for the field.
2828         *
2829         * @type {String}
2830         */
2831        requiredMessage: {
2832        }
2833    };
2834
2835    function readData(element) {
2836        var data = element.dataset;
2837        var options = [];
2838        var capitalized = IS;
2839        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
2840        var reserved = ["is", "hook" + capitalized];
2841
2842        for (var key in data) {
2843            if (data.hasOwnProperty(key)) {
2844                var value = data[key];
2845
2846                if (key.indexOf(NS) === 0) {
2847                    key = key.slice(NS.length);
2848                    key = key.charAt(0).toLowerCase() + key.substring(1);
2849
2850                    if (reserved.indexOf(key) === -1) {
2851                        options[key] = value;
2852                    }
2853                }
2854            }
2855        }
2856
2857        return options;
2858    }
2859
2860    function FormText(config) {
2861        if (config.element) {
2862            // prevents multiple initialization
2863            config.element.removeAttribute("data-" + NS + "-is");
2864        }
2865
2866        this._cacheElements(config.element);
2867        this._setupProperties(config.options);
2868
2869        this._elements.input.addEventListener("invalid", this._onInvalid.bind(this));
2870        this._elements.input.addEventListener("input", this._onInput.bind(this));
2871    }
2872
2873    FormText.prototype._onInvalid = function(event) {
2874        event.target.setCustomValidity("");
2875        if (event.target.validity.typeMismatch) {
2876            if (this._properties.constraintMessage) {
2877                event.target.setCustomValidity(this._properties.constraintMessage);
2878            }
2879        } else if (event.target.validity.valueMissing) {
2880            if (this._properties.requiredMessage) {
2881                event.target.setCustomValidity(this._properties.requiredMessage);
2882            }
2883        }
2884    };
2885
2886    FormText.prototype._onInput = function(event) {
2887        event.target.setCustomValidity("");
2888    };
2889
2890    FormText.prototype._cacheElements = function(wrapper) {
2891        this._elements = {};
2892        this._elements.self = wrapper;
2893        var hooks = this._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS_DASH + "]");
2894        for (var i = 0; i < hooks.length; i++) {
2895            var hook = hooks[i];
2896            var capitalized = IS;
2897            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
2898            var key = hook.dataset[NS + "Hook" + capitalized];
2899            this._elements[key] = hook;
2900        }
2901    };
2902
2903    FormText.prototype._setupProperties = function(options) {
2904        this._properties = {};
2905
2906        for (var key in properties) {
2907            if (properties.hasOwnProperty(key)) {
2908                var property = properties[key];
2909                if (options && options[key] != null) {
2910                    if (property && typeof property.transform === "function") {
2911                        this._properties[key] = property.transform(options[key]);
2912                    } else {
2913                        this._properties[key] = options[key];
2914                    }
2915                } else {
2916                    this._properties[key] = properties[key]["default"];
2917                }
2918            }
2919        }
2920    };
2921
2922    function onDocumentReady() {
2923        var elements = document.querySelectorAll(selectors.self);
2924        for (var i = 0; i < elements.length; i++) {
2925            new FormText({ element: elements[i], options: readData(elements[i]) });
2926        }
2927
2928        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
2929        var body = document.querySelector("body");
2930        var observer = new MutationObserver(function(mutations) {
2931            mutations.forEach(function(mutation) {
2932                // needed for IE
2933                var nodesArray = [].slice.call(mutation.addedNodes);
2934                if (nodesArray.length > 0) {
2935                    nodesArray.forEach(function(addedNode) {
2936                        if (addedNode.querySelectorAll) {
2937                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
2938                            elementsArray.forEach(function(element) {
2939                                new FormText({ element: element, options: readData(element) });
2940                            });
2941                        }
2942                    });
2943                }
2944            });
2945        });
2946
2947        observer.observe(body, {
2948            subtree: true,
2949            childList: true,
2950            characterData: true
2951        });
2952    }
2953
2954    if (document.readyState !== "loading") {
2955        onDocumentReady();
2956    } else {
2957        document.addEventListener("DOMContentLoaded", onDocumentReady);
2958    }
2959
2960})();
2961
2962/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */
2963!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).DOMPurify=t()}(this,(function(){"use strict";const{entries:e,setPrototypeOf:t,isFrozen:n,getPrototypeOf:o,getOwnPropertyDescriptor:r}=Object;let{freeze:i,seal:a,create:l}=Object,{apply:c,construct:s}="undefined"!=typeof Reflect&&Reflect;i||(i=function(e){return e}),a||(a=function(e){return e}),c||(c=function(e,t,n){return e.apply(t,n)}),s||(s=function(e,t){return new e(...t)});const u=R(Array.prototype.forEach),m=R(Array.prototype.lastIndexOf),p=R(Array.prototype.pop),f=R(Array.prototype.push),d=R(Array.prototype.splice),h=R(String.prototype.toLowerCase),g=R(String.prototype.toString),T=R(String.prototype.match),y=R(String.prototype.replace),E=R(String.prototype.indexOf),A=R(String.prototype.trim),_=R(Object.prototype.hasOwnProperty),S=R(RegExp.prototype.test),b=(N=TypeError,function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return s(N,t)});var N;function R(e){return function(t){t instanceof RegExp&&(t.lastIndex=0);for(var n=arguments.length,o=new Array(n>1?n-1:0),r=1;r<n;r++)o[r-1]=arguments[r];return c(e,t,o)}}function w(e,o){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:h;t&&t(e,null);let i=o.length;for(;i--;){let t=o[i];if("string"==typeof t){const e=r(t);e!==t&&(n(o)||(o[i]=e),t=e)}e[t]=!0}return e}function O(e){for(let t=0;t<e.length;t++){_(e,t)||(e[t]=null)}return e}function D(t){const n=l(null);for(const[o,r]of e(t)){_(t,o)&&(Array.isArray(r)?n[o]=O(r):r&&"object"==typeof r&&r.constructor===Object?n[o]=D(r):n[o]=r)}return n}function v(e,t){for(;null!==e;){const n=r(e,t);if(n){if(n.get)return R(n.get);if("function"==typeof n.value)return R(n.value)}e=o(e)}return function(){return null}}const L=i(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),C=i(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),x=i(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),I=i(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),M=i(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),k=i(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),U=i(["#text"]),z=i(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","
2963spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),P=i(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),H=i(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),F=i(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),B=a(/\{\{[\w\W]*|[\w\W]*\}\}/gm),W=a(/<%[\w\W]*|[\w\W]*%>/gm),G=a(/\$\{[\w\W]*/gm),Y=a(/^data-[\-\w.\u00B7-\uFFFF]+$/),j=a(/^aria-[\-\w]+$/),X=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),q=a(/^(?:\w+script|data):/i),$=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),K=a(/^html$/i),V=a(/^[a-z][.\w]*(-[.\w]+)+$/i);var Z=Object.freeze({__proto__:null,ARIA_ATTR:j,ATTR_WHITESPACE:$,CUSTOM_ELEMENT:V,DATA_ATTR:Y,DOCTYPE_NAME:K,ERB_EXPR:W,IS_ALLOWED_URI:X,IS_SCRIPT_OR_DATA:q,MUSTACHE_EXPR:B,TMPLIT_EXPR:G});const J=1,Q=3,ee=7,te=8,ne=9,oe=function(){return"undefined"==typeof window?null:window};var re=function t(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:oe();const o=e=>t(e);if(o.version="3.2.6",o.removed=[],!n||!n.document||n.document.nodeType!==ne||!n.Element)return o.isSupported=!1,o;let{document:r}=n;const a=r,c=a.currentScript,{DocumentFragment:s,HTMLTemplateElement:N,Node:R,Element:O,NodeFilter:B,NamedNodeMap:W=n.NamedNodeMap||n.MozNamedAttrMap,HTMLFormElement:G,DOMParser:Y,trustedTypes:j}=n,q=O.prototype,$=v(q,"cloneNode"),V=v(q,"remove"),re=v(q,"nextSibling"),ie=v(q,"childNodes"),ae=v(q,"parentNode");if("function"==typeof N){const e=r.createElement("template");e.content&&e.content.ownerDocument&&(r=e.content.ownerDocument)}let le,ce="";const{implementation:se,createNodeIterator:ue,createDocumentFragment:me,getElementsByTagName:pe}=r,{importNode:fe}=a;let de={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]};o.isSupported="function"==typeof e&&"function"==typeof ae&&se&&void 0!==se.createHTMLDocument;const{MUSTACHE_EXPR:he,ERB_EXPR:ge,TMPLIT_EXPR:Te,DATA_ATTR:ye,ARIA_ATTR:Ee,IS_SCRIPT_OR_DATA:Ae,ATTR_WHITESPACE:_e,CUSTOM_ELEMENT:Se}=Z;let{IS_ALLOWED_URI:be}=Z,Ne=null;const Re=w({},[...L,...C,...x,...M,...U]);let we=null;const Oe=w({},[...z,...P,...H,...F]);let De=Object.seal(l(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ve=null,Le=null,Ce=!0,xe=!0,Ie=!1,Me=!0,ke=!1,Ue=!0,ze=!1,Pe=!1,He=!1,Fe=!1,Be=!1,We=!1,Ge=!0,Ye=!1,je=!0,Xe=!1,qe={},$e=null;const Ke=w({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Ve=null;const Ze=w({},["audio","video","img","source","image","track"]);let Je=null;const Qe=w({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),et="http://www.w3.org/1998/Math/MathML",tt="http://www.w3.org/2000/svg",nt="http://www.w3.org/1999/xhtml";let ot=nt,rt=!1,it=null;const at=w({},[et,tt,nt],g);let lt=w({},["mi","mo","mn","ms","mtext"]),ct=w({},["annotation-xml"]);const st=w({},["title","style","font","a","script"]);let ut=null;const mt=["application/xhtml+xml","text/html"];let pt=null,ft=null;const dt=r.createElement("form"),ht=function(e){return e instanceof RegExp||e instanceof Function},gt=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!ft||ft!==e){if(e&&"object"==typeof e||(e={}
vendor: 4,915 bytes, line 2963
2963),e=D(e),ut=-1===mt.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,pt="application/xhtml+xml"===ut?g:h,Ne=_(e,"ALLOWED_TAGS")?w({},e.ALLOWED_TAGS,pt):Re,we=_(e,"ALLOWED_ATTR")?w({},e.ALLOWED_ATTR,pt):Oe,it=_(e,"ALLOWED_NAMESPACES")?w({},e.ALLOWED_NAMESPACES,g):at,Je=_(e,"ADD_URI_SAFE_ATTR")?w(D(Qe),e.ADD_URI_SAFE_ATTR,pt):Qe,Ve=_(e,"ADD_DATA_URI_TAGS")?w(D(Ze),e.ADD_DATA_URI_TAGS,pt):Ze,$e=_(e,"FORBID_CONTENTS")?w({},e.FORBID_CONTENTS,pt):Ke,ve=_(e,"FORBID_TAGS")?w({},e.FORBID_TAGS,pt):D({}),Le=_(e,"FORBID_ATTR")?w({},e.FORBID_ATTR,pt):D({}),qe=!!_(e,"USE_PROFILES")&&e.USE_PROFILES,Ce=!1!==e.ALLOW_ARIA_ATTR,xe=!1!==e.ALLOW_DATA_ATTR,Ie=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Me=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,ke=e.SAFE_FOR_TEMPLATES||!1,Ue=!1!==e.SAFE_FOR_XML,ze=e.WHOLE_DOCUMENT||!1,Fe=e.RETURN_DOM||!1,Be=e.RETURN_DOM_FRAGMENT||!1,We=e.RETURN_TRUSTED_TYPE||!1,He=e.FORCE_BODY||!1,Ge=!1!==e.SANITIZE_DOM,Ye=e.SANITIZE_NAMED_PROPS||!1,je=!1!==e.KEEP_CONTENT,Xe=e.IN_PLACE||!1,be=e.ALLOWED_URI_REGEXP||X,ot=e.NAMESPACE||nt,lt=e.MATHML_TEXT_INTEGRATION_POINTS||lt,ct=e.HTML_INTEGRATION_POINTS||ct,De=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&ht(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(De.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&ht(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(De.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(De.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),ke&&(xe=!1),Be&&(Fe=!0),qe&&(Ne=w({},U),we=[],!0===qe.html&&(w(Ne,L),w(we,z)),!0===qe.svg&&(w(Ne,C),w(we,P),w(we,F)),!0===qe.svgFilters&&(w(Ne,x),w(we,P),w(we,F)),!0===qe.mathMl&&(w(Ne,M),w(we,H),w(we,F))),e.ADD_TAGS&&(Ne===Re&&(Ne=D(Ne)),w(Ne,e.ADD_TAGS,pt)),e.ADD_ATTR&&(we===Oe&&(we=D(we)),w(we,e.ADD_ATTR,pt)),e.ADD_URI_SAFE_ATTR&&w(Je,e.ADD_URI_SAFE_ATTR,pt),e.FORBID_CONTENTS&&($e===Ke&&($e=D($e)),w($e,e.FORBID_CONTENTS,pt)),je&&(Ne["#text"]=!0),ze&&w(Ne,["html","head","body"]),Ne.table&&(w(Ne,["tbody"]),delete ve.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw b('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw b('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');le=e.TRUSTED_TYPES_POLICY,ce=le.createHTML("")}else void 0===le&&(le=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let n=null;const o="data-tt-policy-suffix";t&&t.hasAttribute(o)&&(n=t.getAttribute(o));const r="dompurify"+(n?"#"+n:"");try{return e.createPolicy(r,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+r+" could not be created."),null}}(j,c)),null!==le&&"string"==typeof ce&&(ce=le.createHTML(""));i&&i(e),ft=e}},Tt=w({},[...C,...x,...I]),yt=w({},[...M,...k]),Et=function(e){f(o.removed,{element:e});try{ae(e).removeChild(e)}catch(t){V(e)}},At=function(e,t){try{f(o.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){f(o.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e)if(Fe||Be)try{Et(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},_t=function(e){let t=null,n=null;if(He)e="<remove></remove>"+e;else{const t=T(e,/^[\r\n\t ]+/);n=t&&t[0]}"application/xhtml+xml"===ut&&ot===nt&&(e='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+e+"</body></html>");const o=le?le.createHTML(e):e;if(ot===nt)try{t=(new Y).parseFromString(o,ut)}catch(e){}if(!t||!t.documentElement){t=se.createDocument(ot,"template",null);try{t.documentElement.innerHTML=rt?ce:o}catch(e){}}const i=t.body||t.documentElement;return e&&n&&i.insertBefore(r.createTextNode(n),i.childNodes[0]||null),ot===nt?pe.call(t,ze?"html":"body")[0]:ze?t.documentElement:i},St=function(e){return ue.call(e.ownerDocument||e,e,B.SHOW_ELEMENT|B.SHOW_COMMENT|B.SHOW_TEXT|B.SHOW_PROCESSING_INSTRUCTION|B.SHOW_CDATA_SECTION,null)},bt=function(e){return e instanceof G&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof W)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},Nt=function(e){return"function"==typeof R&&e instanceof R};function Rt(e,t,n){u(e,(e=>{e.call(o,t,n,ft)}))}const wt=function(e){let t=null;if(Rt(de.beforeSanitizeElements,e,null),bt(e))return Et(e),!0;const n=pt(e.nodeName);if(Rt(de.uponSanitizeElement,e,{tagName:n,allowedTags:Ne}),Ue&&e.hasChildNodes()&&!Nt(e.firstElementChild)&&S(/<[/\w!]/g,e.innerHTML)&&S(/<[/\w!]/g,e.textContent))return Et(e),!0;if(e.nodeType===ee)return Et(e),!0;if(Ue&&e.nodeType===te&&S(/<[/\w]/g,e.data))return Et(e),!0;
vendor: 5,068 bytes, line 2963
2963if(!Ne[n]||ve[n]){if(!ve[n]&&Dt(n)){if(De.tagNameCheck instanceof RegExp&&S(De.tagNameCheck,n))return!1;if(De.tagNameCheck instanceof Function&&De.tagNameCheck(n))return!1}if(je&&!$e[n]){const t=ae(e)||e.parentNode,n=ie(e)||e.childNodes;if(n&&t){for(let o=n.length-1;o>=0;--o){const r=$(n[o],!0);r.__removalCount=(e.__removalCount||0)+1,t.insertBefore(r,re(e))}}}return Et(e),!0}return e instanceof O&&!function(e){let t=ae(e);t&&t.tagName||(t={namespaceURI:ot,tagName:"template"});const n=h(e.tagName),o=h(t.tagName);return!!it[e.namespaceURI]&&(e.namespaceURI===tt?t.namespaceURI===nt?"svg"===n:t.namespaceURI===et?"svg"===n&&("annotation-xml"===o||lt[o]):Boolean(Tt[n]):e.namespaceURI===et?t.namespaceURI===nt?"math"===n:t.namespaceURI===tt?"math"===n&&ct[o]:Boolean(yt[n]):e.namespaceURI===nt?!(t.namespaceURI===tt&&!ct[o])&&!(t.namespaceURI===et&&!lt[o])&&!yt[n]&&(st[n]||!Tt[n]):!("application/xhtml+xml"!==ut||!it[e.namespaceURI]))}(e)?(Et(e),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!S(/<\/no(script|embed|frames)/i,e.innerHTML)?(ke&&e.nodeType===Q&&(t=e.textContent,u([he,ge,Te],(e=>{t=y(t,e," ")})),e.textContent!==t&&(f(o.removed,{element:e.cloneNode()}),e.textContent=t)),Rt(de.afterSanitizeElements,e,null),!1):(Et(e),!0)},Ot=function(e,t,n){if(Ge&&("id"===t||"name"===t)&&(n in r||n in dt))return!1;if(xe&&!Le[t]&&S(ye,t));else if(Ce&&S(Ee,t));else if(!we[t]||Le[t]){if(!(Dt(e)&&(De.tagNameCheck instanceof RegExp&&S(De.tagNameCheck,e)||De.tagNameCheck instanceof Function&&De.tagNameCheck(e))&&(De.attributeNameCheck instanceof RegExp&&S(De.attributeNameCheck,t)||De.attributeNameCheck instanceof Function&&De.attributeNameCheck(t))||"is"===t&&De.allowCustomizedBuiltInElements&&(De.tagNameCheck instanceof RegExp&&S(De.tagNameCheck,n)||De.tagNameCheck instanceof Function&&De.tagNameCheck(n))))return!1}else if(Je[t]);else if(S(be,y(n,_e,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==E(n,"data:")||!Ve[e]){if(Ie&&!S(Ae,y(n,_e,"")));else if(n)return!1}else;return!0},Dt=function(e){return"annotation-xml"!==e&&T(e,Se)},vt=function(e){Rt(de.beforeSanitizeAttributes,e,null);const{attributes:t}=e;if(!t||bt(e))return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:we,forceKeepAttr:void 0};let r=t.length;for(;r--;){const i=t[r],{name:a,namespaceURI:l,value:c}=i,s=pt(a),m=c;let f="value"===a?m:A(m);if(n.attrName=s,n.attrValue=f,n.keepAttr=!0,n.forceKeepAttr=void 0,Rt(de.uponSanitizeAttribute,e,n),f=n.attrValue,!Ye||"id"!==s&&"name"!==s||(At(a,e),f="user-content-"+f),Ue&&S(/((--!?|])>)|<\/(style|title)/i,f)){At(a,e);continue}if(n.forceKeepAttr)continue;if(!n.keepAttr){At(a,e);continue}if(!Me&&S(/\/>/i,f)){At(a,e);continue}ke&&u([he,ge,Te],(e=>{f=y(f,e," ")}));const d=pt(e.nodeName);if(Ot(d,s,f)){if(le&&"object"==typeof j&&"function"==typeof j.getAttributeType)if(l);else switch(j.getAttributeType(d,s)){case"TrustedHTML":f=le.createHTML(f);break;case"TrustedScriptURL":f=le.createScriptURL(f)}if(f!==m)try{l?e.setAttributeNS(l,a,f):e.setAttribute(a,f),bt(e)?Et(e):p(o.removed)}catch(t){At(a,e)}}else At(a,e)}Rt(de.afterSanitizeAttributes,e,null)},Lt=function e(t){let n=null;const o=St(t);for(Rt(de.beforeSanitizeShadowDOM,t,null);n=o.nextNode();)Rt(de.uponSanitizeShadowNode,n,null),wt(n),vt(n),n.content instanceof s&&e(n.content);Rt(de.afterSanitizeShadowDOM,t,null)};return o.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,r=null,i=null,l=null;if(rt=!e,rt&&(e="\x3c!--\x3e"),"string"!=typeof e&&!Nt(e)){if("function"!=typeof e.toString)throw b("toString is not a function");if("string"!=typeof(e=e.toString()))throw b("dirty is not a string, aborting")}if(!o.isSupported)return e;if(Pe||gt(t),o.removed=[],"string"==typeof e&&(Xe=!1),Xe){if(e.nodeName){const t=pt(e.nodeName);if(!Ne[t]||ve[t])throw b("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof R)n=_t("\x3c!----\x3e"),r=n.ownerDocument.importNode(e,!0),r.nodeType===J&&"BODY"===r.nodeName||"HTML"===r.nodeName?n=r:n.appendChild(r);else{if(!Fe&&!ke&&!ze&&-1===e.indexOf("<"))return le&&We?le.createHTML(e):e;if(n=_t(e),!n)return Fe?null:We?ce:""}n&&He&&Et(n.firstChild);const c=St(Xe?e:n);for(;i=c.nextNode();)wt(i),vt(i),i.content instanceof s&&Lt(i.content);if(Xe)return e;if(Fe){if(Be)for(l=me.call(n.ownerDocument);n.firstChild;)l.appendChild(n.firstChild);else l=n;return(we.shadowroot||we.shadowrootmode)&&(l=fe.call(a,l,!0)),l}let m=ze?n.outerHTML:n.innerHTML;return ze&&Ne["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&S(K,n.ownerDocument.doctype.name)&&(m="<!DOCTYPE "+n.ownerDocument.doctype.name+">\n"+m),ke&&u([he,ge,Te],(e=>{m=y(m,e," ")})),le&&We?le.createHTML(m):m},o.setConfig=function(){gt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Pe=!0},o.clearConfig=function(){ft=null,Pe=!1},o.isValidAttribute=function(e,t,n){ft||gt({});const o=pt(e),r=pt(t);return Ot(o,r,n)},o.addHook=function(e,t){"function"==typeof t&&f(de[e],t)},o.removeHook=function(e,t){if(void 0!==t){const n=m(de[e],t);
2963return-1===n?void 0:d(de[e],n,1)[0]}return p(de[e])},o.removeHooks=function(e){de[e]=[]},o.removeAllHooks=function(){de={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},o}();return re}));
2964//# sourceMappingURL=purify.min.js.map
2965var getGeoLocationJS = {
2966    locationVal: "",
2967    cookieValue: "",
2968    postalCode: "",
2969    langId: "",
2970    storeId: "",
2971    domain: "",
2972    reversePath: "",
2973    addressPath: "",
2974    key: "",
2975    locationDesc: "",
2976    locationLabel: "",
2977    locErrorMsg: "",
2978    zipCodeReqErrMsg:"",
2979    locText: "",
2980    maxLength: 5,
2981    locationPrompt: "locationPrompt",
2982    locationPromptValue: "",
2983
2984    prepopulateZipCode: function() {
2985        let locationCookie = getGeoLocationJS.getCookie('location') || getGeoLocationJS.getCookie('zipCode') || getGeoLocationJS.getCookie('userZipCode');
2986        let zipCode = locationCookie;
2987        // Step 2: If cookie is empty or not found, try to get from localStorage and set cookie
2988        if (!locationCookie) {
2989            // Try to get location data from localStorage (MapQuest API response format)
2990            let locationData = localStorage.getItem('locationData');
2991            if (locationData) {
2992                try {
2993                    let parsedLocationData = JSON.parse(locationData);
2994                    if (parsedLocationData.results && parsedLocationData.results[0] && parsedLocationData.results[0].locations && parsedLocationData.results[0].locations[0]) {
2995                        let locationObj = parsedLocationData.results[0].locations[0];
2996                        let zipFromLocationData = locationObj.postalCode;
2997                        
2998                        if (zipFromLocationData) {
2999                            if (zipFromLocationData.indexOf('-') > -1) {
3000                                zipFromLocationData = zipFromLocationData.substring(0, zipFromLocationData.indexOf('-'));
3001                            }
3002                            // Set the location cookie using the zip code from localStorage
3003                            let cookieDuration = document.getElementById('configdata')?.getAttribute('data-cookie');
3004                            if (cookieDuration) {
3005                                let d = new Date();
3006                                d.setSeconds(d.getSeconds() + parseInt(cookieDuration)); 
3007                                if (window.location.protocol === "https:") {
3008                                    document.cookie = "location=" + zipFromLocationData + "; expires=" + d.toUTCString() + "; path=/;secure;sameSite=Strict";
3009                                    document.cookie = "locationState=" + (locationObj.adminArea3 || '') + "; expires=" + d.toUTCString() + "; path=/;secure;sameSite=Strict";
3010                                } else {
3011                                    document.cookie = "location=" + zipFromLocationData + "; expires=" + d.toUTCString() + "; path=/;sameSite=Strict";
3012                                    document.cookie = "locationState=" + (locationObj.adminArea3 || '') + "; expires=" + d.toUTCString() + "; path=/;sameSite=Strict";
3013                                }
3014                                zipCode = zipFromLocationData;
3015                            }
3016                        }
3017                    }
3018                } catch (e) {
3019                    console.error('[LocationJS] Error parsing locationData from localStorage:', e);
3020                }
3021            }
3022            if (!zipCode) {
3023                zipCode = localStorage.getItem('zipCode') || localStorage.getItem('userZipCode') || localStorage.getItem('location');
3024            }
3025        }
3026        if (zipCode) {
3027            const possibleSelectors = [
3028                '#updateLoc',
3029                '#zipCode', 
3030                'input[name="zipCode"]',
3031                '.zipcode-input',
3032                'input[placeholder*="ZIP"]',
3033                'input[placeholder*="zip"]',
3034                'input[data-zip]'
3035            ];
3036            let inputFound = false;
3037            for (let selector of possibleSelectors) {
3038                let zipInput = document.querySelector(selector);
3039                if (zipInput && !zipInput.value) {
3040                    zipInput.value = DOMPurify.sanitize(zipCode);
3041
3042                    if (selector === '#updateLoc') {
3043                        getGeoLocationJS.validateLocationInput(zipInput.value);
3044                    }
3045                    zipInput.dispatchEvent(new Event('change', { bubbles: true }));
3046                    inputFound = true;
3047
3048                    this.changeLinkBgColor('#dfdfdf','#000d59');
3049                    break;
3050                }
3051            }
3052            
3053            if (!inputFound) {
3054                console.log('[LocationJS] No suitable zip code input field found on this page.');
3055            }
3056        } else {
3057            console.log('[LocationJS] No zip code found in cookie or localStorage.');
3058        }
3059    },
3060
3061    getHexColor: function(rgbColor) {
3062        const match = rgbColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
3063        if (!match) {
3064            return null; // Handle cases where the string is not in rgb() format
3065        }
3066        const r = parseInt(match[1]);
3067        const g = parseInt(match[2]);
3068        const b = parseInt(match[3]);
3069
3070        const toHex = (c) => {
3071            const hex = c.toString(16);
3072            return hex.length === 1 ? "0" + hex : hex;
3073        };
3074
3075        return `#${toHex(r)}${toHex(g)}${toHex(b)}`;        
3076    },
3077
3078    getLocation: function() {
3079        getGeoLocationJS.locationDesc = document.getElementById('geo-update')?.getAttribute('data-desc');
3080        getGeoLocationJS.locationLabel = document.getElementById('geo-update')?.getAttribute('data-label');
3081        getGeoLocationJS.locErrorMsg = document.getElementById('geo-update')?.getAttribute('data-errormsg');
3082        getGeoLocationJS.zipCodeReqErrMsg = document.getElementById('geo-update')?.getAttribute('data-noziperrormsg');
3083        getGeoLocationJS.locText = document.getElementById('geo-update')?.getAttribute('data-loctext');
3084        getGeoLocationJS.privacyPolicyInfo = document.getElementById('geo-update')?.getAttribute('data-privacypolicyinfo');
3085
3086        if (document.getElementById("loc-desc")) {
3087            document.getElementById("loc-desc").innerHTML = DOMPurify.sanitize(getGeoLocationJS.locationDesc);
3088        }
3089        if (document.getElementById("loc-label")) {
3090            document.getElementById("loc-label").innerHTML = DOMPurify.sanitize(getGeoLocationJS.locationLabel);
3091        }
3092        if (document.getElementById("loc-text")) {
3093            document.getElementById("loc-text").innerHTML = DOMPurify.sanitize(getGeoLocationJS.locText);
3094        }
3095        if (document.getElementById("location-box")) {
3096            document.getElementById("location-box")?.setAttribute('aria-label',`${getGeoLocationJS.locText} ${document.getElementById("location-box")?.getAttribute('data-modal-label')}`);
3097        }
3098        if (document.getElementById("loc-privacypolicyinfo")) {
3099            document.getElementById("loc-privacypolicyinfo").innerHTML = DOMPurify.sanitize(getGeoLocationJS.privacyPolicyInfo);
3100        }
3101
3102        // Set initial styling for TracFone brand when page loads
3103        let brand = document.querySelector(".section-api-container")?.dataset.brand?.toLowerCase();
3104        if (brand === "tracfone") {
3105            // Set initial label color to gray for TracFone
3106            if (document.querySelector("label[for='updateLoc']")) {
3107                document.querySelector("label[for='updateLoc']").style.color = "#808080";
3108            }
3109        }
3110
3111        let hideZipCodeModal = document.querySelector(".section-api-container")?.dataset.hidezipcodemodal;
3112
3113        console.time('executionTimeForCapturingUserLocationZipCode');
3114        let actCookie = getGeoLocationJS.getCookie("actWebviewEnabled");
3115        if (hideZipCodeModal !== "true") {
3116            if (navigator.geolocation && !actCookie) {
3117            getGeoLocationJS.locationPromptValue = sessionStorage.getItem(getGeoLocationJS.locationPrompt);
3118
3119            if (!getGeoLocationJS.locationPromptValue) {
3120                navigator.geolocation.getCurrentPosition(getGeoLocationJS.showPosition, getGeoLocationJS.showError);
3121            }
3122            else if (getGeoLocationJS.locationPromptValue == "N") {
3123                const errorPrompt = {
3124                    code: 1,
3125                    PERMISSION_DENIED: 1
3126                };
3127                getGeoLocationJS.showError(errorPrompt);
3128            }
3129            else if (getGeoLocationJS.locationPromptValue == "Y")
3130                {
3131                    getGeoLocationJS.mapRequestAPICall(true);
3132                }
3133            }
3134        } else {
3135            var locationBox = document.getElementById("location-box");
3136            if (locationBox) {
3137                locationBox.remove();
3138            }
3139            console.log("Geolocation is not supported by this browser.");
3140        }
3141    },
3142    showPosition: function(position) {
3143        getGeoLocationJS.locationVal = position.coords.latitude + "," + position.coords.longitude;
3144        getGeoLocationJS.mapRequestAPICall(true);
3145        if (!sessionStorage.getItem(getGeoLocationJS.locationPrompt)) {
3146            sessionStorage.setItem(getGeoLocationJS.locationPrompt, "Y");
3147        }
3148
3149
3150    },
3151
3152    getCookie: function(cookieName) {
3153        var decodedCookie = DOMPurify.sanitize(decodeURIComponent(document.cookie));
3154        var ca = decodedCookie.split(';');
3155        var cookieValue = "";
3156        var name = cookieName + "=";
3157        for (var i = 0; i < ca.length; i++) {
3158            var c = ca[i];
3159            while (c.charAt(0) == ' ') {
3160                c = c.substring(1);
3161            }
3162            if (c.indexOf(name) == 0) {
3163                cookieValue = c.substring(name.length, c.length);
3164            }
3165
3166
3167
3168        }
3169        return cookieValue;
3170    },
3171
3172    processLocationData: function (response) {
3173      var zipCode = DOMPurify.sanitize(response.results[0].locations[0].postalCode);
3174      if (zipCode.indexOf('-') > -1) {
3175        zipCode = zipCode.substring(0, zipCode.indexOf('-'));
3176      }
3177      var city = response.results[0].locations[0].adminArea5;
3178      var state = DOMPurify.sanitize(response.results[0].locations[0].adminArea3);
3179      var cityDisplayText = city == '' ? state : city + ' ' + state;
3180      var displayText = zipCode + ' (' + cityDisplayText + ')';
3181      if(document.getElementById('city'))
3182        document.getElementById('city').innerHTML = DOMPurify.sanitize(displayText);
3183      //setting location cookie on page load if it does not exists
3184      var cookieDuration = document.getElementById('configdata')?.getAttribute('data-cookie');
3185      var d = new Date();
3186      if (cookieDuration) {
3187        d.setSeconds(d.getSeconds() + parseInt(cookieDuration));
3188      }
3189      if (d && zipCode && !document.cookie.split(';').some((item) => item.trim().startsWith('location='))) {
3190        createCookieCommon('location', zipCode, d.toUTCString());
3191        createCookieCommon('locationState', state, d.toUTCString());
3192        if (
3193          $('.product-listing-container').length > 0 &&
3194          $('.purchase-flow-wrapper').length == 0 &&
3195          $('.filter-location').length > 0
3196        ) {
3197          document.dispatchEvent(
3198            new Event('DOMContentLoaded', {
3199              bubbles: true,
3200            }),
3201          );
3202        }
3203      }
3204      if ($('.filter-location').length > 0) {
3205        document.getElementById('location-update').innerHTML = DOMPurify.sanitize(displayText);
3206        document.getElementById('available-in').innerHTML = DOMPurify.sanitize(document
3207          .getElementById('available-in')
3208          .getAttribute('data-ziplabel'));
3209        document.getElementById('geo-update').setAttribute('data-gtm-asset', displayText);
3210        document.getElementById('location-update').setAttribute('data-gtm-asset', displayText);
3211        let arialabel = displayText + ' ' + document.querySelector('#location-update').dataset.updatelocation;
3212        document.querySelector('#location-update').setAttribute("aria-label", arialabel);
3213      }
3214    },
3215
3216    mapRequestAPICall: function(isBrowserGeolocation) {
3217        var xhttp = new XMLHttpRequest();
3218        var name = "location";
3219        getGeoLocationJS.domain = document.getElementById('configdata')?.getAttribute('data-domain');
3220        getGeoLocationJS.reversePath = document.getElementById('configdata')?.getAttribute('data-reverse');
3221        getGeoLocationJS.addressPath = document.getElementById('configdata')?.getAttribute('data-path');
3222        getGeoLocationJS.key = document.getElementById('configdata')?.getAttribute('data-key');
3223        getGeoLocationJS.cookieValue = DOMPurify.sanitize(getGeoLocationJS.getCookie(name));
3224        var url = "";
3225        if (getGeoLocationJS.cookieValue != "") {
3226            url = getGeoLocationJS.domain + getGeoLocationJS.addressPath + "?key=" + getGeoLocationJS.key + "&location=" + getGeoLocationJS.cookieValue + "&outFormat=json&maxResults=1";
3227        } else {
3228            url = getGeoLocationJS.domain + getGeoLocationJS.reversePath + "?key=" + getGeoLocationJS.key + "&location=" + getGeoLocationJS.locationVal + "&outFormat=json";
3229        }
3230
3231        xhttp.onreadystatechange = function() {
3232            console.info("onreadystatechange :: User accepted the request for Geolocation");
3233            if (this.readyState == 4 && this.status == 200) {
3234                var response = JSON.parse(this.responseText);
3235                if (response !== null && response !== undefined && response.info !== null && response.info !== undefined) {
3236                    if (response.info.statuscode !== null && response.info.statuscode !== undefined) {
3237                        if (response.info.statuscode == 0) {
3238                            if ((response.results[0].locations[0].adminArea5 != "" || response.results[0].locations[0].adminArea3 != "") && (response.results[0].locations[0].adminArea1 == "US" || response.results[0].locations[0].adminArea1 == "PR")) {
3239                                getGeoLocationJS.addLocationDataToLocalStorage(response);
3240                                getGeoLocationJS.processLocationData(response);
3241                                if (isBrowserGeolocation) createCookieCommon("fccZip", "2", document.getElementById('configdata').getAttribute('data-cookie'));
3242                                document.dispatchEvent(new Event("BrowserGeolocationUpdated"));
3243                            } else {
3244                                var enterZip = document.getElementById('geo-update').getAttribute('data-enterzip');
3245                                document.getElementById("city").innerHTML = DOMPurify.sanitize(enterZip);
3246                                document.getElementById('geo-update').setAttribute("data-gtm-asset", enterZip);
3247                                if ($('.filter-location').length > 0) {
3248                                    document.getElementById('location-update').innerHTML = DOMPurify.sanitize(enterZip);
3249                                    document.getElementById('available-in').innerHTML = "";
3250                                    document.getElementById('location-update').setAttribute("data-gtm-asset", enterZip);
3251                                    document.querySelector('#location-update').setAttribute("aria-label", enterZip);
3252                                }
3253                            }
3254                        } else {
3255                            getGeoLocationJS.handleMapQuestApiError(response.info.statuscode);
3256                        }
3257                    }
3258                }
3259            }
3260        };
3261
3262        if (getGeoLocationJS.cookieValue != '') {
3263          var response = JSON.parse(localStorage.getItem('locationData'));
3264          if (response !== null && response !== undefined) {
3265            getGeoLocationJS.processLocationData(response);
3266          } else {
3267            getGeoLocationJS.invokeRequest(xhttp, url);
3268          }
3269        } else {
3270          console.info("mapRequestAPICall :: User accepted the request for Geolocation");
3271          getGeoLocationJS.invokeRequest(xhttp, url);
3272        }
3273    },
3274
3275    addLocationDataToLocalStorage: function (response) {
3276      localStorage.setItem('locationData', JSON.stringify(response));
3277    },
3278
3279    invokeRequest: function (requestObject, url) {
3280      console.info("invokeRequest :: User accepted the request for Geolocation");
3281      requestObject.open('GET', url, true);
3282      requestObject.onerror = function () {
3283        console.log('Error while trying to fetch data from MaQuest API');
3284      };
3285      requestObject.send();
3286    },
3287
3288    updateLocation: function(e, isUpdate) {
3289        if (e.keyCode == 13 || isUpdate) {
3290            getGeoLocationJS.domain = document.getElementById('configdata').getAttribute('data-domain');
3291            getGeoLocationJS.reversePath = document.getElementById('configdata').getAttribute('data-reverse');
3292            getGeoLocationJS.addressPath = document.getElementById('configdata').getAttribute('data-path');
3293            getGeoLocationJS.key = document.getElementById('configdata').getAttribute('data-key');
3294            var cookieDuration = document.getElementById('configdata').getAttribute('data-cookie');
3295            var req = new XMLHttpRequest();
3296            var name = "location";
3297            var inputText = DOMPurify.sanitize(document.getElementById("updateLoc").value);
3298            var isError = false;
3299            if (inputText.length < getGeoLocationJS.maxLength) {
3300                if(inputText.length == 0){
3301                    getGeoLocationJS.showErrorMessage("showZipReqError");
3302                }else{
3303                    getGeoLocationJS.showErrorMessage();
3304                }
3305                isError = true;
3306            }
3307            var url = getGeoLocationJS.domain + getGeoLocationJS.addressPath + "?key=" + getGeoLocationJS.key + "&location=" + inputText + "&outFormat=json&maxResults=1";
3308
3309            req.onreadystatechange = function() {
3310                if (this.readyState == 4 && this.status == 200) {
3311                    var response = JSON.parse(this.responseText);
3312                    if (response !== null && response !== undefined && response.info !== null && response.info !== undefined) {
3313                        if (response.info.statuscode !== null && response.info.statuscode !== undefined) {
3314                            if (response.info.statuscode == 0) {
3315                                if ((response.results[0].locations[0].adminArea5 != "" || response.results[0].locations[0].adminArea3 != "") && (response.results[0].locations[0].adminArea1 == "US" || response.results[0].locations[0].adminArea1 == "PR")) {
3316                                    createCookieCommon("fccZip", "1", cookieDuration);
3317                                    getGeoLocationJS.hideError();
3318                                    getGeoLocationJS.addLocationDataToLocalStorage(response);
3319                                    var zipCode = response.results[0].locations[0].postalCode;
3320                                    if (zipCode.indexOf('-') > -1) {
3321                                        zipCode = zipCode.substring(0, zipCode.indexOf('-'));
3322                                    }
3323                                    var city = response.results[0].locations[0].adminArea5;
3324                                    var state = DOMPurify.sanitize(response.results[0].locations[0].adminArea3);
3325                                    var cityDisplayText = city == "" ? state : city + " " + state;
3326                                    var displayText = zipCode + " (" + cityDisplayText + ")";
3327                                    document.getElementById("city").innerHTML = DOMPurify.sanitize(displayText);
3328                                    if ($('.filter-location').length > 0) {
3329                                        document.getElementById('location-update').innerHTML = DOMPurify.sanitize(displayText);
3330                                        document.getElementById('available-in').innerHTML = DOMPurify.sanitize(document.querySelector('#available-in').dataset.z
3330iplabel);
3331                                        document.getElementById('geo-update').setAttribute("data-gtm-asset", displayText);
3332                                        document.getElementById('location-update').setAttribute("data-gtm-asset", displayText);
3333                                    }
3334
3335                                    var d = new Date();
3336                                    d.setSeconds(d.getSeconds() + parseInt(cookieDuration));
3337                                    document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';
3338
3339                                    if (window.location.protocol === "https:") {
3340                                        document.cookie = name + "=" + inputText + "; expires=" + d.toUTCString() + "; path=/;secure;sameSite=Strict";
3341                                        document.cookie = "locationState" + "=" + state + "; expires=" + d.toUTCString() + "; path=/;secure;sameSite=Strict";
3342                                    } else {
3343                                        document.cookie = name + "=" + inputText + "; expires=" + d.toUTCString() + "; path=/;sameSite=Strict";
3344                                        document.cookie = "locationState" + "=" + state + "; expires=" + d.toUTCString() + "; path=/;sameSite=Strict";
3345                                    }
3346                                    document.dispatchEvent(new Event('CallMarketingAPI', {
3347                                        'bubbles': true
3348                                    }));
3349                                    $('#location-box').modal('hide');
3350                                } else {
3351                                    getGeoLocationJS.showErrorMessage();
3352                                    if (!$("#location-box").data('bs.modal')._isShown && !hideZipCodeModal)
3353                                        $('#location-box').modal('show');
3354                                }
3355                            } else {
3356                                getGeoLocationJS.handleMapQuestApiError(response.info.statuscode);
3357                            }
3358                        }
3359                    }
3360                }
3361            };
3362
3363            req.open("GET", url, true);
3364            req.onerror = function() {
3365                console.log("Error while trying to fetch data from MaQuest API");
3366            }
3367            if (!isError) {
3368                req.send();
3369            }
3370        }
3371    },
3372
3373    showError: function(error) {
3374        switch (error.code) {
3375            case error.PERMISSION_DENIED:
3376                console.info("User denied the request for Geolocation");
3377                var name = "location";
3378                getGeoLocationJS.cookieValue = getGeoLocationJS.getCookie(name);
3379                if (!getGeoLocationJS.locationPromptValue) {
3380                    sessionStorage.setItem(getGeoLocationJS.locationPrompt, "N");
3381                }
3382                if (getGeoLocationJS.cookieValue == "") {
3383                    var enterZip = document.getElementById('geo-update').getAttribute('data-enterzip');
3384                    document.getElementById("city").innerHTML = DOMPurify.sanitize(enterZip);
3385                    if ($('.filter-location').length > 0) {
3386                        document.getElementById('location-update').innerHTML = DOMPurify.sanitize(enterZip);
3387                        document.getElementById('available-in').innerHTML = "";
3388                        document.getElementById('location-update').setAttribute("data-gtm-asset", enterZip);
3389                    }
3390
3391
3392
3393                } else {
3394                    getGeoLocationJS.mapRequestAPICall();
3395                }
3396                break;
3397            case error.POSITION_UNAVAILABLE:
3398                console.log("Location information is unavailable.");
3399                break;
3400            case error.TIMEOUT:
3401                console.log("The request to get user location timed out.");
3402                break;
3403            case error.UNKNOWN_ERROR:
3404                console.log("An unknown error occurred.");
3405                break;
3406        }
3407    },
3408
3409    handleMapQuestApiError: function(error) {
3410        switch (error) {
3411            case 400:
3412                console.log("Error in MAPQuestAPI -  Error with Input");
3413                break;
3414            case 403:
3415                console.log("Error in MAPQuestAPI -  Key related Error");
3416                break;
3417            case 500:
3418                console.log("Error in MAPQuestAPI - Unknown Error");
3419                break;
3420            default:
3421                console.log("Error in MAPQuestAPI - An unknown error occurred.");
3422                break;
3423        }
3424    },
3425    handleLocationInput: function(value) {
3426        var length = value.length;
3427        var presentValue = value[length - 1];
3428        var isnum = /^\d+$/.test(presentValue);
3429        if (!isnum) {
3430            value = value.slice(0, length - 1);
3431            document.getElementById('updateLoc').value = value;
3432        }
3433        if (value.length > getGeoLocationJS.maxLength) {
3434            value = value.slice(0, getGeoLocationJS.maxLength);
3435            document.getElementById('updateLoc').value = value;
3436        } else if(value.length === getGeoLocationJS.maxLength){
3437            document.querySelector('#locator-button')?.classList.remove('disabled');
3438            getGeoLocationJS.hideError();
3439        } else {
3440            document.querySelector("#updateLoc")?.classList.remove("success");
3441            document.querySelector('#locator-button')?.classList.add('disabled');
3442        }
3443    },
3444    validateLocationInput: function(value) {
3445                if(value && value.length<getGeoLocationJS.maxLength){
3446                        getGeoLocationJS.showErrorMessage();
3447        } else if(value && value.length===getGeoLocationJS.maxLength){
3448                        getGeoLocationJS.hideError();
3449        }
3450    },
3451    showErrorMessage: function(msgType) {
3452
3453        let locErrorMsg = document.getElementById('geo-update')?.getAttribute('data-errormsg');
3454        let zipCodeReqErrMsg = document.getElementById('geo-update')?.getAttribute('data-noziperrormsg');
3455        let brand = document.querySelector(".section-api-container").dataset.brand.toLowerCase();
3456
3457        let hideZipCodeModal = document.querySelector(".section-api-container")?.dataset.hidezipcodemodal;
3458        
3459        hideZipCodeModal === "true" ? document.getElementById("updateLoc")?.classList.add("error-nozip") : document.getElementById("updateLoc")?.classList.add("error");
3460        document.getElementById("updateLoc")?.classList.remove("success");
3461        if(document.querySelector("label[for='updateLoc']") ) {
3462             document.querySelector("label[for='updateLoc']").style.color="#A41412";
3463        }
3464
3465        if(document.getElementById("errorMsg")){
3466            document.getElementById("errorMsg").innerHTML = document.getElementById("errorMsg") ? msgType == "showZipReqError" ? DOMPurify.sanitize(zipCodeReqErrMsg) : DOMPurify.sanitize(locErrorMsg) : "";
3467        }
3468
3469        this.changeLinkBgColor('#000d59','#dfdfdf');
3470
3471        //tracfone specific styling
3472        if(brand === "tracfone") {
3473            if(document.querySelector("label[for='updateLoc']") ) {
3474                // For required field error (no zip entered), use red color
3475                // For invalid zip format error, use gray color
3476                if(msgType === "showZipReqError") {
3477                    document.querySelector("label[for='updateLoc']").style.color="#A41412";
3478                } else {
3479                    document.querySelector("label[for='updateLoc']").style.color="#808080";
3480                }
3481            }
3482
3483            if(document.querySelector("#updateLoc") ) {
3484                document.querySelector("#updateLoc").style.color="#a41412";
3485            }
3486
3487        }
3488
3489    },
3490    hideError: function() {
3491        document.getElementById("updateLoc")?.classList.remove("error");
3492        document.getElementById("updateLoc")?.classList.remove("error-nozip");
3493        document.getElementById("updateLoc")?.classList.add("success");
3494        if(document.querySelector("label[for='updateLoc']") ) {
3495            document.querySelector("label[for='updateLoc']").style.color="#666";     
3496        }       
3497        
3498        if(document.getElementById("errorMsg")){
3499            document.getElementById("errorMsg").innerHTML = "";
3500        }
3501
3502        this.changeLinkBgColor('#dfdfdf','#000d59');
3503
3504        //tracfone specific styling
3505        let brand = document.querySelector(".section-api-container").dataset.brand.toLowerCase();
3506
3507        if(brand === "tracfone") {
3508            if(document.querySelector("label[for='updateLoc']") ) {
3509            document.querySelector("label[for='updateLoc']").style.color="#808080";     
3510            }   
3511
3512            if(document.querySelector("#updateLoc") ) {
3513                document.querySelector("#updateLoc").style.color="#313334";
3514            }
3515
3516        }        
3517
3518    },
3519    changeLinkBgColor:function(fromColor,toColor) {
3520
3521        let plpLinkSelector=".broadband-plans-list .plan-list-heading .containerZip a";
3522        let pdpLinkSelector = ".fcc-review-details .review-details-tab .containerZip a";
3523
3524        let linkSelector = document.querySelector(plpLinkSelector) ? plpLinkSelector : pdpLinkSelector;
3525
3526        let linkBgColor = document.querySelector(linkSelector+" .input-group-addon") ? this.getHexColor(window.getComputedStyle(document.querySelector(linkSelector+" .input-group-addon")).backgroundColor) : "";
3527        if(linkBgColor && linkBgColor.toLowerCase().indexOf(fromColor)>=0) {
3528            document.querySelector(linkSelector).style.backgroundColor=toColor;
3529            document.querySelector(linkSelector+" .input-group-addon").style.backgroundColor=toColor;
3530        }   
3531    }
3532
3533};
3534
3535if (document.getElementById("geo-update") || document.getElementById("updateLoc")) {
3536    getGeoLocationJS.prepopulateZipCode();
3537    getGeoLocationJS.getLocation();
3538}
3539
3540// Add event listeners for zip code prepopulation
3541document.addEventListener('DOMContentLoaded', function() {
3542    getGeoLocationJS.prepopulateZipCode();
3543});
3544
3545document.addEventListener('LoadPDPDetails', function() {
3546    setTimeout(() => {
3547        getGeoLocationJS.prepopulateZipCode();
3548    }, 200);
3549});
3550
3551document.addEventListener('LoadProductDetailContent', function() {
3552    setTimeout(() => {
3553        getGeoLocationJS.prepopulateZipCode();
3554    }, 300);
3555});
3556
3557$(document).on("PurchasePLPLoaded", function() {
3558    if (document.getElementById("geo-update")) {
3559        getGeoLocationJS.getLocation();
3560    }
3561    getGeoLocationJS.prepopulateZipCode();
3562});
3563var rangeSlider = (function(){
3564    var maxRange;
3565    var minRange;
3566    var stepValue;
3567    function init(){
3568        $(".slider").each(function(){
3569        maxRange = parseInt($(this).attr('data-maxrange'));
3570        minRange = parseInt($(this).attr('data-minrange'));
3571        stepValue = parseInt($(this).attr('data-stepvalue'));
3572        var unlimitedLabel = $(this).attr('data-unlimitedlabel');
3573        var sliderType = $(this).attr('data-type');
3574        if(sliderType!=null){
3575            sliderType = sliderType.toLowerCase();
3576        }
3577        var tooltip1 = "";
3578        var tooltip2 = "";
3579        var showUnlimited = $(this).attr('data-showUnlimited');
3580        var currentSlider = $(this);
3581        if(sliderType === 'price'){
3582            $( ".start-price" ).html( "$" + minRange );
3583            $( ".end-price" ).html( "$" + maxRange );
3584            tooltip1 = $('<span class="tooltip-min legal text-color-grey"/>').html( "$" + minRange ).css({position: 'absolute',top: -21,left: '10%'}).attr('data-minVal',minRange);
3585            tooltip2 = $('<span class="tooltip-max legal text-color-grey"/>').html( "$" + maxRange ).css({position: 'absolute',top: 33,left: '10%'}).attr('data-maxVal',maxRange);
3586
3587        } else if(sliderType === 'data'){
3588            var minDataUnit = maxDataUnit ="MB";
3589            var minRangeDsp =minRange;
3590            var maxRangeDsp =maxRange;
3591            if(minRange>=1024){
3592                minRangeDsp = (minRange/1024).toFixed(1);
3593                minDataUnit ="GB";
3594            }
3595            $( ".start-price" ).html( minRangeDsp +" "+minDataUnit);
3596            tooltip1 = $('<span class="tooltip-min legal text-color-grey"/>').html( minRangeDsp+" "+minDataUnit).css({position: 'absolute',top: -21}).attr('data-minVal',minRange-1);
3597
3598            if(showUnlimited==="true"){
3599                $( ".end-price" ).html(unlimitedLabel);
3600                tooltip2 = $('<span class="tooltip-max legal text-color-grey"/>').html( unlimitedLabel).css({position: 'absolute',top: 33}).attr('data-maxVal',maxRange+1);
3601            }else{
3602
3603                if(maxRange>=1024){
3604                    maxRangeDsp =(maxRange/1024).toFixed(1);
3605                    maxDataUnit ="GB";
3606                }
3607                $( ".end-price" ).html( maxRangeDsp+" "+maxDataUnit);
3608                tooltip2 = $('<span class="tooltip-max legal text-color-grey"/>').html( maxRangeDsp+" "+maxDataUnit).css({position: 'absolute',top: 33});
3609            }
3610        }else if(sliderType === 'text'){
3611            $( ".start-price" ).html( minRange );
3612            $( ".end-price" ).html( maxRange );
3613            tooltip1 = $('<span class="tooltip-min legal text-color-grey"/>').html( minRange ).css({position: 'absolute',top: -21,left: '10%'}).attr('data-minVal',minRange);
3614            tooltip2 = $('<span class="tooltip-max legal text-color-grey"/>').html( maxRange ).css({position: 'absolute',top: 33,left: '10%'}).attr('data-maxVal',maxRange);
3615        } else if(sliderType === 'talk'){
3616            $( ".start-price" ).html( minRange );
3617            $( ".end-price" ).html( maxRange );
3618            tooltip1 = $('<span class="tooltip-min legal text-color-grey"/>').html( minRange + "minutes" ).css({position: 'absolute',top: -21,left: '10%'}).attr('data-minVal',minRange);
3619            tooltip2 = $('<span class="tooltip-max legal text-color-grey"/>').html( maxRange + "minutes" ).css({position: 'absolute',top: 33,left: '10%'}).attr('data-maxVal',maxRange);
3620        }
3621        $( function() {
3622            $(currentSlider).slider({
3623                range: true,
3624                step: stepValue,
3625                min: minRange,
3626                max: maxRange,
3627                values: [ minRange , maxRange ],
3628                slide: function( event, ui ) {
3629                    var minVal =  ui.values[ 0 ];
3630                    var maxVal =  ui.values[ 1 ];
3631                    if(sliderType === 'price'){
3632                        $(currentSlider).find( ".tooltip-min" ).text( "$" + minVal ).attr('data-minVal',minVal);
3633                        $(currentSlider).find( ".tooltip-max" ).text( "$" + maxVal ).attr('data-maxVal',maxVal);
3634
3635                    }
3636                    else if(sliderType === 'data'){
3637                        var minDataUnit = maxDataUnit ="MB";
3638                        var minRangeDsp =minVal;
3639                        var maxRangeDsp =maxVal;
3640                        if(minVal>=1024){
3641                            minRangeDsp = (minVal/1024).toFixed(1);
3642                            minDataUnit ="GB";
3643                        }
3644                        $( ".tooltip-min" ).text( minRangeDsp +" "+minDataUnit).attr('data-minVal',minVal - 1);
3645                        if(showUnlimited==="true" && maxVal===maxRange){
3646                            $(currentSlider).find( ".tooltip-max" ).text(unlimitedLabel).attr('data-maxVal',unlimitedLabel);
3647                        }else{
3648                            if(maxVal>=1024){
3649                                maxRangeDsp = (maxVal/1024).toFixed(1);
3650                                maxDataUnit ="GB";
3651                            }
3652                            $(currentSlider).find( ".tooltip-max" ).text(  maxRangeDsp+" "+maxDataUnit).attr('data-maxVal',maxVal + 1);
3653                        }
3654
3655                    } else if(sliderType === 'text'){
3656                        $(currentSlider).find( ".tooltip-min" ).text( minVal ).attr('data-minVal',minVal);
3657                        $(currentSlider).find( ".tooltip-max" ).text( maxVal ).attr('data-maxVal',maxVal);
3658                    } else if(sliderType === 'talk'){
3659                        $(currentSlider).find( ".tooltip-min" ).text( minVal + "minutes" ).attr('data-minVal',minVal);
3660                        $(currentSlider).find( ".tooltip-max" ).text( maxVal + "minutes" ).attr('data-maxVal',maxVal);
3661                    }
3662                    var slideEvent = new CustomEvent('slidechangenew', { bubbles: true });
3663                    this.dispatchEvent(slideEvent);
3664                    $(currentSlider).find('ul.slider-checkboxes li input[type=checkbox]').each(function(){
3665                        if($(this).attr('checked') == 'checked'){
3666                            $(this).removeAttr("checked");
3667                        }
3668                    });
3669                    $(currentSlider).addClass('selectedRange');
3670                    $(currentSlider).find('ul.slider-checkboxes').removeClass('selectedRange');
3671                },
3672            });
3673            setTimeout(function () {
3674                $(currentSlider).find("span.ui-slider-handle:eq(0)").append( tooltip1 );
3675                $(currentSlider).find("span.ui-slider-handle:eq( 1 )" ).append( tooltip2 );
3676            }, 0);
3677
3678        } );
3679
3680
3681        $('ul.slider-checkboxes li input[type=checkbox]').on('click',function(){
3682            currentSlider.removeClass('selectedRange');
3683            $(this).closest('ul.slider-checkboxes').addClass('selectedRange');
3684            resetSlider();
3685        })
3686
3687
3688        //Clear All Start
3689        $(".clear-all > a").on('click', function(){
3690            clearAllFilters();
3691            document.dispatchEvent(new Event('filterclearevent', { 'bubbles': true }));
3692        });
3693        //Clear All End
3694        });
3695    }
3696
3697    function clearAllFilters() {
3698        $('.filter-rating li').each(function(){
3699            $(this).removeClass('filter-rating-black');
3700            $(this).removeClass('selected');
3701        });
3702        resetSlider();
3703        $('.filter-fields li').each(function(){
3704            if($(this).find('.custom-checkbox .custom-control-input').attr("checked")){
3705                $(this).find('.custom-checkbox .custom-control-input').removeAttr("checked");
3706            }
3707        });
3708        if($('.all-filter-count')){
3709            $('.all-filter-count').parent().removeClass('disabled');
3710            $('.all-filter-error').addClass('d-none');
3711        }
3712    }
3713
3714    function resetSlider(){
3715        $(".slider").each(function(){
3716            var $sliderReset = $(this);
3717            $(this).removeClass("selectedRange");
3718            $sliderReset.slider("values", 0, minRange);
3719            $sliderReset.slider("values", 1, maxRange);
3720            $(".tooltip-min").html($( ".start-price" ).html());
3721            $(".tooltip-max").html($( ".end-price" ).html());
3722        });
3723    }
3724
3725    return{
3726        init: init,resetSlider: resetSlider, clearAllFilters: clearAllFilters
3727    }
3728})();
3729
3730$( document ).ready( function(){
3731    rangeSlider.init();
3732});
3733
3734
3735//Compare Page Close button functionality - Start
3736$('body').on('click',".product-compare-nav .close-container", function(){
3737  let id = $(this).attr('data-productId');  
3738  let productId = $(this).attr('data-id');
3739  var itemLength = $('.close-compare').length;
3740  var prdctJson = JSON.parse(window.localStorage.getItem('compareProducts'));
3741  
3742  
3743  if(itemLength-1>0){
3744		for (let count =0; count<prdctJson.compareProducts.length;count++)
3745		{			
3746			if(prdctJson.compareProducts[count] != null && productId==prdctJson.compareProducts[count].productid)
3747			{
3748				prdctJson.compareProducts.splice(count,1);				
3749			}
3750		}
3751		if(prdctJson.compareProducts.length>0)
3752		{			
3753			localStorage.setItem('compareProducts', JSON.stringify(prdctJson));			
3754		}
3755		else
3756		{
3757			 localStorage.removeItem('compareProducts');
3758		}
3759		
3760		$('.compare-wrapper').find('a[data-closeid="'+productId+'"]').trigger('click');
3761        $("div[data-productId='" + id +"']").remove();                   
3762        if($('.phone-compare-carousel').find('.addAnotherPhone').length ==0){
3763          $('.phone-compare-carousel').trigger('add.owl.carousel', [$('<div class ="text-center addAnotherPhone"><div class="phone-card '+($('#horizontal-nav-compare').data('comptype')==='plan'?'plan-card':'')+' text-center d-flex flex-column addAnotherPhoneContainer" aria-label="Phone One"></div></div>')]).trigger('refresh.owl.carousel');
3764        }
3765    if(window.matchMedia("(min-width: 1024px)").matches){  
3766        $(".addAnotherPhone").removeClass('d-none');  
3767        $('.phone-compare-carousel').find('.owl-item.active').each(function(index) {  
3768          if($(this).find('.phone-card').length ==0){
3769            $(this).remove();
3770          }
3771        });
3772  }
3773   else if(window.matchMedia("(max-width: 1023px)").matches){   
3774        $('.phone-compare-carousel').find('.owl-item.active').each(function(index) {  
3775          if($(this).find('.phone-card').length ==0){
3776            $(this).remove();
3777          }     
3778        });
3779        $('.phone-compare-carousel').trigger('destroy.owl.carousel');
3780        $('.phone-compare-carousel').owlCarousel(optionCompare);  
3781      }
3782	  const plpPage = $('.addAnotherPhone a').prop('href');
3783	  if(itemLength==2 && plpPage) {
3784		window.location.href = plpPage;
3785	  }
3786  }
3787});
3788//Compare Page Close button functionality - End
3789var optionCompare = {
3790		loop:false,		
3791		nav:false,
3792		responsive:{
3793			0:{
3794				items:2,
3795				onTranslated:updateCompareTable,
3796				onInitialized:updateCompareTable
3797			},
3798           1024:{
3799               items:3,
3800			   dots:false,
3801               mouseDrag:false,
3802               touchDrag:false,
3803
3804			}
3805		},
3806		onResized:updateCompareTable	
3807	};
3808	//$('.phone-compare-carousel').owlCarousel(optionCompare);
3809	function updateCompareTable(e){	
3810		  $(e.target).find('.owl-item').each(function(index) {
3811			var id = $(this).find('.phone-card').attr('data-productId');
3812			if($(this).hasClass('active')){					
3813				$("div[data-productId='" + id +"']").show();
3814					if($(this).find('.addAnotherPhone').length>0){
3815					  
3816					   $(".addAnotherPhone").removeClass('d-none'); 
3817					}
3818			}
3819			else{
3820				$("div[data-productId='" + id +"']").hide();
3821					$(".addAnotherPhone").addClass('d-none'); 
3822			}
3823		});
3824        var count = $(e.target).find('.owl-dot').length;
3825		var widthDots = ((count*24)+10)+"px";
3826        $(e.target).find('.owl-dots').css('width',widthDots);
3827            $(e.target).find('.owl-dot').each(function(index) {
3828                let slidenbr = index+1;
3829                let desc = "Slide "+slidenbr+ " of " +count;
3830                $(this).attr('aria-label', desc);
3831            });
3832	}
3833
3834document.addEventListener('compareCarouselLoad', function(){
3835	$('.phone-compare-carousel').owlCarousel(optionCompare);
3836});
3837
3838//Compare Tab Start
3839$('body').on("click", ".compare-wrapper .clear-compare-selection ", function() {
3840    var id = $(this).attr('data-closeid');
3841    var accesiblityRemovedLabel = '<span class="sr-only" role="alert">'+$(this).attr('data-removelabel')+'</span>';
3842    var compareData = window.localStorage.getItem('compareProducts');
3843    if (compareData != null && compareData != undefined) {
3844        var prdctJson = JSON.parse(compareData);
3845
3846        for (let count = 0; count < prdctJson.compareProducts.length; count++) {
3847            if (prdctJson.compareProducts[count] != null && id == prdctJson.compareProducts[count].productid) {
3848                prdctJson.compareProducts.splice(count, 1);
3849            }
3850        }
3851        if (prdctJson.compareProducts.length > 0) {
3852            setLocalStorage('compareProducts', JSON.stringify(prdctJson));
3853        } else {
3854            localStorage.removeItem('compareProducts');
3855        }
3856    }
3857    $('.compare-bar .compare-item-removed').html(accesiblityRemovedLabel);
3858    const escapeId = id.indexOf('.') ? id.replaceAll('.','\\.') : id;
3859    const productType = $("div[data-productid='" + id + "']").attr('data-producttype');
3860    if (document.querySelector('.eligible-offer-wrapper input[id="' + escapeId+'"]')) {
3861        $('.eligible-offer-wrapper')?.find('input[id="' + escapeId+'"]').trigger('click');
3862    } else if (document.querySelector('.compare-plp-cards input[id="' + escapeId+'"]')){
3863        $('.compare-plp-cards').find('input[id="' + escapeId+'"]').trigger('click');
3864    } else {
3865        closeCompareTab(id);
3866    }
3867});
3868
3869function compareCheckBoxCommonCode(checkbox, productType) {
3870    var id = checkbox.id;
3871    var modelJsonUrl = checkbox.getAttribute("data-modeljson");
3872    var compareItemSelected = $(".compare-bar .compare-row .phone-wrapper .item-wrapper").length;
3873    var defaultThumbnail = $('section').attr('data-defaultphonethumbnail');
3874    if (productType === 'plan') {
3875        checkbox.getAttribute("checked") !== "checked" ? checkbox.setAttribute("checked", "checked") : checkbox.removeAttribute("checked");
3876    } else {
3877        if ($(checkbox).parents('.eligible-offer-wrapper').length > 0) {
3878            const plpCardVersion = document.querySelector(`.compare-plp-cards .custom-checkbox input[id='${id}']`);
3879            if (plpCardVersion) {
3880                if (checkbox.checked === "checked") {
3881                    plpCardVersion.setAttribute("checked", "checked");
3882                } else {
3883                    plpCardVersion.removeAttribute("checked");
3884                }
3885            }
3886        }
3887    }
3888    if ($(checkbox).parents('.compare-plp-cards').length > 0) {
3889        const queryString = `.eligible-offer-wrapper .custom-checkbox input[id='${id}']`;
3890        const eligibleOfferCardEquivalent = document.querySelector(queryString);
3891        if (eligibleOfferCardEquivalent) {
3892            if (checkbox.getAttribute("checked") === "checked") {
3893                eligibleOfferCardEquivalent.setAttribute("checked", "checked");
3894            } else {
3895                eligibleOfferCardEquivalent.removeAttribute("checked");
3896            }
3897        }
3898    } else if ($(checkbox).parents('.eligible-offer-wrapper').length > 0) {
3899        const queryString = `.compare-plp-cards .custom-checkbox input[id='${id}']`;
3900        const eligibleOfferCardEquivalent = document.querySelector(queryString);
3901        if (eligibleOfferCardEquivalent) {
3902            if (checkbox.getAttribute("checked") === "checked") {
3903                eligibleOfferCardEquivalent.setAttribute("checked", "checked");
3904            } else {
3905                eligibleOfferCardEquivalent.removeAttribute("checked");
3906            }
3907        }
3908    }
3909    if (checkbox.getAttribute("checked")) { // add attributes on check box
3910        if ($('.compare-bar .compare-wrapper').find('[data-id ="' + id + '"]').length == 0) {
3911            $('.compare-bar-close-alert').hide();
3912            if (compareItemSelected < 3) {
3913                var compareImge = $("div[data-productid='" + id + "']").attr('data-compareimage');
3914                var compareImgeAssetId = $("div[data-productid='" + id + "']").attr('data-compareassetid');
3915                var compareImgeAgencyId = $("div[data-productid='" + id + "']").attr('data-compareassetagencyid');
3916                var productName = $("div[data-productid='" + id + "']").attr('data-productName');
3917                var pageUrl = $("div[data-productid='" + id + "'] .product-button a").attr('data-href');
3918                var planDetailList = $("div[data-productid='" + id + "'] .multiple-bucket").is(':visible')?
3919                    '<ul class="pl-0 text-left plan-details-list">'+$("div[data-productid='" + id + "'] .plan-details-list").html()+'</ul>'
3920                    :$("div[data-productid='" + id + "'] .single-bucket .plan-detail").html();
3921                var planPrice = $("div[data-productid='" + id + "'] .plan-price").data('planprice');
3922                var serviceDays = $("div[data-productid='" + id + "']").data('servicedays');
3923                var planDeviceType = $("div[data-productid='" + id + "']").data('plandevicetype');
3924
3925                if(!planPrice) {
3926                    planPrice = productName;
3927                }
3928                if (compareImge == null || compareImge == undefined || compareImge == "") {
3929                    compareImge = defaultThumbnail;
3930                }
3931
3932                if (pageUrl == undefined || pageUrl == null)
3933                    pageUrl = $("div[data-productid='" + id + "'] .product-button a").attr('href') || $("div[data-productid='" + id + "']").parent().attr('data-href') || $("div[data-productid='" + id + "']").attr('data-href');
3934               
3935                var serviceDaysArray = serviceDays ? serviceDays.split(" ") : ["",""];
3936                var compareItemHtml = productType !== 'plan' ?
3937                    `<li class="wrapper item-wrapper" data-id="${id}" data-modelUrl="${modelJsonUrl}" data-imageurl="${compareImge}" data-pageurl="${pageUrl}" data-productname="${productName}"
3938                    data-compareassetid="${compareImgeAssetId}
3938" data-compareassetagencyid="${compareImgeAgencyId}">
3939						<div class="phone-image-wrap d-inline-block">
3940                            <img data-src="${compareImge}" src="" data-gtm-asset="${compareImgeAssetId}" data-gtm-agencyid="${compareImgeAgencyId}" class="responsiveimage" alt="Icon of ${productName}">
3941                    	</div>
3942						<div class="phone-name-wrap caption-one d-inline-block">
3943                    		<span class="text-break">${productName}</span>
3944                    	</div>
3945						<a class="clear-compare-selection" href="javascript:void(0)" data-closeid ="${id}" role="button"
3946                            data-removelabel="${productName} has been removed" aria-label="Remove ${productName} from compare">
3947							<span class="icon dark-theme large-icon"><i class="clear"></i></span>
3948                    	</a>
3949					</li>`:
3950                    `<li class="wrapper plan-wrapper item-wrapper" data-id="${id}" data-modelUrl="${modelJsonUrl}" data-pageurl="${pageUrl}" data-productname="${planPrice}" 
3951                        data-servicedays="${serviceDays}" data-plandevicetype="${planDeviceType}">
3952                        <div class="d-flex flex-row justify-content-between">
3953                            <div class="plan-wrap caption-one">
3954                                <div>
3955                                <div class="legal font-weight-bolder">${planDeviceType}</div>
3956                                    <div class="plan-price border-bottom-medium-grey pb-05">
3957                                        ${planPrice}<span class="plan-days">/${serviceDaysArray[0]}</span>
3958                                        <span class="legal color-black">${serviceDaysArray[1]?serviceDaysArray[1]:''}</span>
3959                                    </div>                                   
3960                                </div>
3961                                <div class="plan-detail mx-auto">${planDetailList}</div>
3962                            </div>
3963                            <a class="clear-compare-selection" data-closeid="${id}" href="javascript:void(0)"  role="button"
3964                                aria-label="Remove ${planPrice} ${planDeviceType} from compare" data-removelabel="${productName} has been removed" >
3965                                <span class="icon dark-theme large-icon"><i class="clear"></i></span>
3966                            </a>
3967                        </div>
3968                    </li>`;
3969                document.querySelector(".compare-wrapper ul.phone-wrapper .empty-wrapper").insertAdjacentHTML('beforebegin', compareItemHtml);
3970
3971                let updatedCount = $(".compare-bar .compare-row .phone-wrapper .item-wrapper").length;
3972                if ($(".compare-bar").is(":hidden"))  $(".compare-bar").show();
3973                const compareBtn = $(".compare-button .btn");
3974                if (updatedCount == 2) {
3975                    const ariaLabel = compareBtn.data('arialabel');
3976                    compareBtn.attr('aria-label', ariaLabel);
3977                    $(".compare-button .extra-small").removeClass('disabled');
3978                    compareBtn.focus();
3979                } else if (updatedCount > 2) {
3980                    $(".compare-wrapper ul .empty-wrapper").hide();
3981                    $(".compare-plp-cards .custom-checkbox .custom-control-input:not(:checked)").attr("disabled", "disabled");
3982                    compareBtn.focus();
3983                }
3984                loadDynamicMediaImages();
3985            } else {
3986                $(this).removeAttr("checked", "checked");
3987                $(".compare-wrapper ul .empty-wrapper").hide();
3988                $(".compare-plp-cards .custom-checkbox .custom-control-input:not(:checked)").attr("disabled", "disabled");
3989            }
3990        }
3991    } else {
3992        closeCompareTab(id);
3993    }
3994}
3995
3996$('body').on("click", ".eligible-offer-wrapper .custom-checkbox .custom-control-input, .compare-plp-cards .custom-checkbox .custom-control-input", function() {
3997    compareCheckBoxCommonCode(this);
3998});
3999
4000function closeCompareTab(id) {
4001    if ($(".compare-bar .compare-row .phone-wrapper .item-wrapper").length <= 3) {
4002        $(".compare-wrapper ul .empty-wrapper").show();
4003    }
4004    $("li.wrapper[data-id='" + id + "']").remove();
4005    $(".eligible-offer-wrapper .custom-checkbox .custom-control-input:not(:checked), .compare-plp-cards .custom-checkbox .custom-control-input:not(:checked)").removeAttr("disabled", "disabled");
4006
4007    var length = $(".compare-bar li.wrapper").length;
4008    if (length == 1) {
4009        $('.compare-bar-close-alert').show();
4010        $(".compare-bar").hide();
4011        $('.compare-bar .compare-item-removed').html('');
4012        const escapeId = id.indexOf('.') ? id.replaceAll('.','\\.') : id;
4013        $('.compare-plp-cards').find('[id="' + escapeId+'"]').focus();
4014    }
4015    if (length == 2) {
4016        const compareBtn = $(".compare-button .btn");
4017        $(".compare-button .extra-small").addClass('disabled');
4018        var disabledLabel = compareBtn.attr('data-disabledarialabel');
4019        compareBtn.attr('aria-label', disabledLabel);
4020    }
4021
4022}
4023//Compare Tab Ends
4024
4025$('body').on("click", ".compare-bar .compare-button a", function() {
4026
4027    var selectedList = $(".compare-bar .compare-wrapper li.item-wrapper");
4028    var filterList = '';
4029
4030    var compareData = {
4031        compareProducts: []
4032    };
4033
4034    var filterList = {
4035        phoneType: [],
4036        brands: [],
4037        price: [],
4038        ratings: []
4039    };
4040
4041    $('.filter-checkbox li').each(function() {
4042        var brandId = $(this).find('input[checked ="checked"]').attr("id");
4043        if (brandId != "" && brandId != null && brandId != undefined) {
4044            var brandData = {
4045                "brandId": brandId
4046            }
4047
4048            filterList.brands.push(brandData);
4049        }
4050
4051    });
4052
4053    if ($('.slider').length > 0 && $('.slider').hasClass('selectedRange')) {
4054
4055        var priceRange = $(".range-slider").attr("data-permanentval");
4056        if (priceRange != "" && priceRange != null && priceRange != undefined) {
4057            var priceData = {
4058                "minVal": priceRange.split(',')[0],
4059                "maxVal": priceRange.split(',')[1]
4060
4061            }
4062
4063            filterList.price.push(priceData);
4064        }
4065
4066    } else if ($('.slider-checkboxes') != null) {
4067
4068        if ($('.slider-checkboxes').length > 0 && $('.slider-checkboxes').hasClass('selectedRange')) {
4069
4070            $('.slider-checkboxes li').each(function() {
4071                var sliderCheckboxId = $(this).find('input[checked ="checked"]').attr("id");
4072                if (sliderCheckboxId != "" && sliderCheckboxId != null && sliderCheckboxId != undefined) {
4073                    var sliderPriceId = {
4074                        "sliderPriceId": sliderPriceId
4075                    }
4076
4077                    filterList.price.push(sliderPriceId);
4078                }
4079
4080            });
4081
4082        }
4083
4084    }
4085
4086
4087
4088    $('.phone-selector.product-type-selector li').each(function() {
4089        var phoneTypeId = $(this).find("label.selected input").attr("id");
4090        if (phoneTypeId != "" && phoneTypeId != null && phoneTypeId != undefined) {
4091            var phoneTypeData = {
4092                "phoneTypeId": phoneTypeId
4093            }
4094
4095            filterList.phoneType.push(phoneTypeData);
4096        }
4097
4098    });
4099
4100    var ratingVal = $('.filter-rating li.selected').attr("data-index");
4101    if (ratingVal != "" && ratingVal != null && ratingVal != undefined) {
4102        var ratingData = {
4103            "rating": ratingVal
4104        }
4105
4106        filterList.ratings.push(ratingData);
4107    }
4108
4109
4110    $('.compare-bar .compare-wrapper li.item-wrapper').each(function() {
4111        var productId = $(this).attr("data-id");
4112        var url = $(this).attr("data-modelurl");
4113        var imageUrl = $(this).attr("data-imageurl");
4114        var compareImgeAssetId = $(this).attr('data-compareassetid');
4115        var compareImgeAgencyId = $(this).attr('data-compareassetagencyid');
4116        var productName = $(this).attr("data-productname");
4117        var pageUrl = $(this).attr("data-pageurl");
4118        var serviceDays = $(this).attr("data-servicedays");
4119        var planDetailList = $(this).find(".plan-detail").html();
4120        var planDeviceType = $(this).attr("data-plandevicetype");
4121
4122        if (productId != "" && productId != null && productId != undefined) {
4123            var jsonData = {
4124                "compareImage": imageUrl,
4125                "productName": productName,
4126                "productid": productId,
4127                "url": url,
4128                "pageurl": pageUrl,
4129                "serviceDays": serviceDays,
4130                "planDetailList": planDetailList,
4131                "planDeviceType": planDeviceType,
4132                "compareImgeAssetId": compareImgeAssetId,
4133                "compareImgeAgencyId": compareImgeAgencyId
4134            }
4135
4136            compareData.compareProducts.push(jsonData);
4137        }
4138
4139
4140    });
4141
4142    compareData.compareType = document.querySelector('.product-filter-container')?.dataset.categorytype||document.querySelector('.multiline-plan-card-wrapper')?.dataset.categorytype;
4143    setLocalStorage('compareProducts', JSON.stringify(compareData));
4144    setLocalStorage('filtersData', JSON.stringify(filterList));
4145
4146});
4147
4148/**
4149 * allow focus on compare buton's item's close buttons
4150 */
4151function focusCompareItemCloseButtons() {
4152    $('.compare-bar .compare-button .btn').on('focus keydown keyup', () => {
4153        const phoneWrapperCount = $('.compare-bar .phone-wrapper .wrapper')?.length
4154        if(phoneWrapperCount && phoneWrapperCount >= 3){
4155            $('.compare-bar .compare-row .phone-wrapper .item-wrapper a.clear-compare-selection').attr('tabindex','0').removeAttr('aria-hidden');
4156        }
4157    })
4158    $('.compare-bar').on('keydown', 'a.clear-compare-selection', (e) => {
4159        const phoneWrappers = $('.compare-bar .phone-wrapper .wrapper');
4160        const phoneWrapperCount = phoneWrappers?.length;
4161        if(e.key === 'Tab' && e.target.parentElement === phoneWrappers[phoneWrapperCount - 2]){
4162            if (e.shiftKey) {
4163                return;
4164            }
4165            e.preventDefault();
4166            if(phoneWrapperCount === 3 ){
4167                const targetId = e.target.dataset.closeid;
4168                const cardContainer = $('#' + targetId)[0]?.closest('.product-card-container');
4169                const siblingContainer = cardContainer?.parentElement?.nextSibling?.querySelector('.product-card-container');
4170                if(siblingContainer){
4171                    siblingContainer?.querySelector('.custom-control.custom-checkbox input.custom-control-input')?.focus();
4172                }else{
4173                    cardContainer.querySelector('#' + targetId)?.focus();
4174                }
4175            }else if(phoneWrapperCount === 4){
4176                tabStop(document.querySelector('.compare-bar .compare-row'),false);
4177            }
4178        }
4179    })
4180}
4181
4182function setLocalStorage(key, val) {
4183    if (window.localStorage.getItem(key) != null) {
4184        localStorage.removeItem(key);
4185    }
4186
4187    localStorage.setItem(key, val);
4188}
4189//Compare Tab End
4190$(function() {
4191  //HYLA Multi Page Form 
4192  const tradeInModal = document.querySelector('.trade-in-modal');
4193  if (tradeInModal === null) return;
4194  const BASE_HYLA_URL = tradeInModal.dataset.apibaseurl;
4195  if (!BASE_HYLA_URL || BASE_HYLA_URL.length <= 0) return console.log('Hyla base url is missing. Check that it is available for the component');
4196  const HYLA_MODELS_PATH =  BASE_HYLA_URL + '/models';
4197  const HYLA_TOKEN_API = BASE_HYLA_URL + '/haas/token';
4198  const HYLA_ATTRIBUTES_API = HYLA_MODELS_PATH + '/attributes';
4199  const HYLA_TOPMODELS_API = HYLA_MODELS_PATH + '/topmodels';
4200  const HYLA_PRICE_API = '/price';
4201  const HYLA_QUESTIONS_API = '/questions';
4202  const HYLA_AGENCY_ID = 'hyla'
4203  const BEARER_STRING = 'Bearer';
4204  const GET_METHOD = 'GET';
4205  const POST_METHOD = 'POST';
4206  const $tradeModal = $('#trade-in-box');
4207  const $stepsForm = $tradeModal.find('.steps-form');
4208  const $nextBtn = $tradeModal.find('.js-step-next');
4209  const $prevBtn = $tradeModal.find('.js-step-previous');
4210  const $submitBtn = $('.js-step-submit');
4211  const $cancelBtn = $('.js-no-thanks-tradein');
4212  const closeBtn = document.querySelector('.trade-in-modal .close');
4213  const $loader = $('.tradein-loader');
4214  const hylaGetCartEvent = new Event('hylaGetCart');
4215  const hylaContentData = JSON.parse(localStorage.getItem('hylaContentData'));
4216  const hylaFormData = JSON.parse(localStorage.getItem('hylaFormData'));
4217  const clientId = $('.section-api-container').attr('data-clientid');
4218  const clientIdParam = 'client_id';
4219
4220  const brandName = $('.section-api-container').attr('data-brand');
4221
4222  let token;
4223  let refreshToken;
4224  let orderId;
4225  let hasDeviceInCart;
4226  let isModalInReact = false;
4227  let formData = new StepsFormData('.steps-form');
4228  let hasContentChangedFromLS = false;
4229  let hylaContentObj = {};
4230  let hasRecalled = false;
4231
4232  if(brandName === "STRAIGHT_TALK" ){
4233    $loader.find('img').attr('src', "/etc.clientlibs/straighttalk/clientlibs/clientlib-base/resources/loader/Bars-1.3s-114px.gif" );
4234  }else if(brandName === "TRACFONE"){
4235    $loader.find('img').attr('src', "/etc.clientlibs/tracfone/clientlibs/clientlib-base/resources/loader/loader.gif" );
4236  }
4237  if (hylaFormData !== null) {
4238    formData = $.extend(formData, hylaFormData);
4239  }
4240  
4241  function createRequest(url, method, tokenStr, params, body) {
4242    const headers = new Headers({
4243      'Content-Type': 'application/json',
4244    });
4245    const requestConfig = {};
4246    let urlStr = url;
4247    if (method) requestConfig.method = method;
4248    if (body) requestConfig.body = body;
4249    if (tokenStr) headers.append('Authorization', `${BEARER_STRING} ${tokenStr}`);
4250    urlStr = `${url}?${clientIdParam}=${clientId}`;
4251    if (params) urlStr = `${urlStr}&${new URLSearchParams(params).toString()}`;
4252
4253    requestConfig.headers = headers;
4254
4255    if (method === POST_METHOD) {
4256      return requestConfig;
4257    }
4258
4259    return new Request(urlStr, requestConfig);
4260  }
4261
4262  async function fetchHylaApi(request, recall, postUrl, skipDefaultErrorHandling = false) {
4263    try {
4264      let response;
4265      if (postUrl) {
4266        response = await fetch(postUrl, request);
4267      } else if (request instanceof Request) {
4268        response = await fetch(request);
4269      }
4270
4271      if (!response.ok) throw await response.text();
4272      const resJson = await response.json();
4273
4274      return resJson;
4275    } catch (error) {
4276      if (!skipDefaultErrorHandling) await handleAPIResponseFailure(error, recall);
4277      throw error;
4278    }
4279  }
4280
4281  async function handleAPIResponseFailure(error, recall) {
4282    let errorJson = {};
4283    //check for valid json
4284    try {
4285      errorJson = JSON.parse(error);
4286    } catch(err) {}
4287
4288    if (errorJson && errorJson.error === 'invalid_token' && !hasRecalled) {
4289      paramsObj = {};
4290      paramsObj.grant_type = 'refresh_token';
4291      paramsObj.refresh_token = refreshToken;
4292      const requestRefreshToken = createRequest(HYLA_TOKEN_API, GET_METHOD, false, paramsObj);
4293      const response = await fetchHylaApi(requestRefreshToken);
4294      token = response.access_token;
4295      refreshToken = response.refresh_token;
4296      hasRecalled = true;
4297      return recall();
4298    } 
4299    showErrorModal();
4300  }
4301  
4302  function createHylaAddToCartObj(orderId) {
4303    const hylaAddToCartObj = 
4304      {
4305        id: orderId,
4306        orderItems: [
4307          {
4308            orderItemExtension: [
4309              {
4310                name: "processHyla",
4311                value: "true"
4312              },
4313              {
4314                name: "hylaModelCode",
4315                value: formData.confirmedModel
4316              },
4317              {
4318                name: "hylaModelName",
4319                value: formData.confirmedModelName
4320              },
4321              {
4322                name: "hylaCurrencyCode",
4323                value: formData.currencyCode
4324              },
4325              {
4326                name: "hylaEstimatedPrice",
4327                value: formData.price.toFixed(2).toString()
4328              },
4329            ]
4330          }
4331        ]
4332      }
4333
4334    $.each(formData.questions, function(index, question) {
4335      const indexUp = index + 1;
4336      hylaAddToCartObj.orderItems[0].orderItemExtension.push({
4337        name: 'hylaQuestionCode_' + indexUp,
4338        value: question.questionCode
4339      });
4340      hylaAddToCartObj.orderItems[0].orderItemExtension.push({
4341        name: 'hylaTextResponse_' + indexUp,
4342        value: question.answerText
4343      });
4344      hylaAddToCartObj.orderItems[0].orderItemExtension.push({
4345        name: 'hylaAnswerSkuCode_' + indexUp,
4346        value: question.skuCode
4347      });
4348    });
4349
4350    return hylaAddToCartObj;
4351  }
4352
4353  function resetFormData(skips) {
4354    $.each(formData, function(key, value) {
4355      if (skips.indexOf(key) >= 0 || typeof formData[key] === 'function') return true;     
4356      if (key === 'questions') {
4357        $('.tradein-questions .tradein-question-list').empty();
4358        return formData.setData(key, []);
4359      }
4360      formData.setData(key, undefined);
4361    });
4362    //uncheck confirm ship checkbox
4363    $('.js-confirm-ship').prop('checked', false);
4364  }
4365
4366  //event listeners and handlers
4367  $(document).on('cartLoaded', function(event) {
4368    orderId = event.detail.orderId;  
4369    hasDeviceInCart = event.detail.hasDeviceInCart;
4370  });
4371
4372  //listen for event fired from react app and open modal
4373  $(document).on('tradeInInitiated', function(event) {
4374    isModalInReact = true;
4375    $tradeModal.modal('show');
4376  });
4377
4378  //listen for tradein submit success and close modal - react app related event
4379  $(document).on('tradeInSuccess', function(event) {
4380    const href = $submitBtn.attr('href');
4381    $tradeModal.modal('hide');
4382    hasContentChangedFromLS = false;
4383    localStorage.setItem('hylaFormData', JSON.stringify(formData));
4384    localStorage.setItem('hylaContentData', JSON.stringify(hylaContentObj));
4385    
4386    //go to first step
4387    for (let i = 0; i < 6; i++) {
4388      $stepsForm.steps('previous');
4389    }
4390
4391    if (isModalInReact) return;
4392      
4393    return href ? window.location.href = href : false;
4394  });
4395
4396  //listen for event fired from cif component when response failure
4397  $(document).on('hylaCartResponseFailed', function(event) {
4398    showErrorModal();
4399  });
4400
4401  $submitBtn.click(function(event) {
4402    event.preventDefault();
4403    if (!validate(['confirmShip'])) {   
4404      return;
4405    }
4406
4407    if (!hasContentChangedFromLS && hylaContentData !== null && hylaFormData !== null) {
4408      return;
4409    }
4410
4411    const hylaCart = createHylaAddToCartObj(orderId);
4412
4413    if (hylaContentData !== null) {
4414      hylaContentObj = $.extend(hylaContentData, hylaContentObj);
4415    }
4416    const hylaDataObj = {
4417      hyla: hylaCart
4418    }
4419
4420    return document.dispatchEvent(new CustomEvent('hylaAddToCart', {detail: hylaDataObj}));
4421  });
4422
4423  $nextBtn.click(function(event) {
4424    event.preventDefault();
4425    $stepsForm.steps('next');
4426  });
4427
4428  $prevBtn.click(function(event) {
4429    event.preventDefault();
4430    $stepsForm.steps('previous');
4431  });
4432
4433  function onInitSteps(event, currentIndex) {
4434    switchNextText(currentIndex);
4435    $loader.css('opacity', '');
4436    $submitBtn.hide();
4437    $loader.hide();
4438  }
4439
4440  $stepsForm.on('click', '.single-select-btn', function(event) {
4441    event.preventDefault();
4442    const $this = $(this);
4443    const fieldName = this.parentNode.dataset.name;
4444    const fieldValue = this.value;
4445    $this.siblings().removeClass('selected');
4446    $this.addClass('selected');
4447    formData.setData(fieldName, fieldValue);
4448    if (fieldName === 'storage') {
4449      resetFormData(['manufacturer', 'deviceModel', 'deviceImg', 'carrier', 'storage']);
4450      return validate([fieldName, 'carrier']);
4451    }
4452
4453    if (fieldName === 'questions') {
4454      resetFormData(['manufacturer', 'deviceModel', 'deviceImg', 'carrier', 'storage', 'confirmedModel', 'confirmedModelName', 'questions']);
4455    }
4456    return validate([fieldName]);
4457  });
4458
4459  //HYLA Manufacturers single select
4460  $stepsForm.on("click", ".manufacturer", function(){
4461    $('.manufacturer').removeClass('border-0');
4462    $('.manufacturer .manufacturer-checkbox').removeClass('selected');
4463    $(this).toggleClass('border-0').find('.manufacturer-checkbox').toggleClass('selected').find('.manufacturer-check');
4464    formData.setData('manufacturer', this.dataset.manufacturer);
4465    resetFormData(['manufacturer']);
4466    $('.tradein-summary-list').hide();
4467    if (formData.manufacturer === 'Apple') {
4468      $('.tradein-summary-list-ios').show();
4469    } else {
4470      $('.tradein-summary-list-android').show();
4471    }
4472    
4473    validate(['manufacturer']);
4474  });
4475
4476  function createManufacturersFromLS() {
4477    const $manufacturers = $('.js-manufacturers');
4478    
4479    $.each(hylaContentData.manufacturers, function(index, value) {
4480      let selected = '';
4481      if (value.value === hylaFormData.manufacturer) selected = 'selected';
4482      $manufacturers.append(
4483        $(
4484          '<div data-manufacturer="' + value.value + '" class="col manufacturer">' +
4485            '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-1').html()), value.value]) + '" type="button" aria-label="' + value.value + '" class="manufacturer-checkbox ' + selected + '">' +
4486              '<img data-gtm-asset="' + value.url + '" data-gtm-agencyid="' + HYLA_AGENCY_ID + '" src="' + value.url + '" class="manufacturer-icon"/>' +
4487              '<span class="manufacturer-check icon light-theme large-icon"><i class="success"></i></span>' +
4488            '</button>' +
4489          '</div>')
4490      )
4491    });
4492  }
4493
4494  function createDeviceModelsFromLS() {
4495    const $deviceSelect = $('select.select-input[name="deviceModel"]');           
4496    $deviceSelect.parents('.dropdown-wrapper').addClass('js-show-mini-placeholder');
4497    $deviceSelect.append($('<option value="empty" data-hidden="true"></option>'))
4498    $.each(hylaContentData.productFamilies, function(index, value) {
4499      let selected = '';
4500      if (value.value === hylaFormData.deviceModel) selected = 'selected';
4501      $deviceSelect.append(
4502        $('<option ' + selected + ' value="' + value.value + '">' + value.value + '</option>')
4503      )
4504    });
4505  }
4506
4507  function createCarriersFromLS() {
4508    const $carrierSelect = $('select.select-input[name="carrier"]');
4509    $carrierSelect.parents('.dropdown-wrapper').addClass('js-show-mini-placeholder');
4510    $('.js-tradein-current-image').attr({
4511      'src': formData.deviceImg,
4512      'data-gtm-asset': formData.deviceImg
4513    });
4514    $carrierSelect.append($('<option value="empty" data-hidden="true"></option>'))
4515    $.each(hylaContentData.carriers, function(index, value) {
4516      let selected = '';
4517      if (value.value === hylaFormData.carrier) selected = 'selected';
4518      $carrierSelect.append(
4519        $('<option ' + selected + ' value="' + value.value + '">' + value.value + '</option>')
4520      )
4521    });
4522  }
4523
4524  function createStorageFromLS() {
4525    const $storageSelect = $('.single-select-group[data-name=storage]');
4526    $.each(hylaContentData.capacities, function(index, value) {
4527      let selected = '';
4528      if (value.value === hylaFormData.storage) selected = 'selected';
4529      $storageSelect.append(
4530        $('<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-3').html()), value.value]) + '" class="single-select-btn ' + selected + '" value="' + value.value + '">' + value.value + '</button>')
4531      )
4532    });
4533  }
4534
4535  function createDeviceConfirmFromLS() {
4536    const $deviceList = $('.device-confirm-list');
4537    $.each(hylaContentData.models, function(index, value) {
4538      let active = '';
4539      if (value.modelCode === hylaFormData.confirmedModel) active = 'active';
4540
4541      $deviceList.append(
4542        $('<div  class="phone-card-container text-center mt-60">' +
4543            '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-4').html()), value.modelCode]) + '" data-name="confirmedModel" data-modelname="' + value.consumerDisplayAlias + '" data-value="' + value.modelCode + '" class="text-center phone-card-detail
4543s js-select-ext-phone-card ' + active + '">' +
4544              '<img data-gtm-asset="' + value.imageUrl + '" data-gtm-agencyid="' + HYLA_AGENCY_ID + '" src="' + value.imageUrl + '"/>' + 
4545              '<div class="tradein-confirm-text">' +
4546                '<p class="heading-container caption-one font-weight-bold">' + value.consumerDisplayAlias + '</p>' +
4547              '</div>' +
4548            '</button>' +
4549          '</div>')
4550      )});
4551  }
4552
4553  function createQuestionsFromLS() {
4554    const $questions = $('.tradein-questions .tradein-question-list');
4555
4556    $.each(hylaContentData.questions, function(index, value) {
4557      if (value.questionType !== 'SINGLE_SELECT') return;
4558      value.validAnswers[0].questionCode = value.code;
4559      value.validAnswers[1].questionCode = value.code;
4560      let selectedYes = '';
4561      let selectedNo = 'selected';
4562      if (value.validAnswers[0].answerText === formData.questions[index].answerText) {
4563        selectedYes = 'selected';
4564        selectedNo = '';
4565      }
4566      $questions.append(
4567        $('<li class="tradein-question-item">' +
4568            '<div class="tradein-question-wrap">' +
4569              '<label class="tradein-question-label">' + value.text + '</label>' +
4570              '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-5').html()), value.validAnswers[0].answerText, 'popover']) + '" rel="popover" type="button" data-trigger="focus" class="popover-btn icon light-theme large-icon" data-toggle="popover" data-content="<p>' + value.helpText + '</p>"><i class="question-mark-black"></i></button>' +
4571            '</div>' +
4572            '<div class="d-flex flex-column tradein-answers-wrap">' +
4573              '<div data-name="questions" class="single-select-group">' +
4574                '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-5').html()), value.validAnswers[0].answerText]) + '"' + ' class="single-select-btn ' + selectedYes + '" ' + 'value=' + JSON.stringify(value.validAnswers[0]) + '>' + value.validAnswers[0].answerText + '</button>' +
4575                '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-5').html()), value.validAnswers[1].answerText]) + '"' + ' class="single-select-btn ' + selectedNo + '" ' + 'value=' + JSON.stringify(value.validAnswers[1]) + '>' + value.validAnswers[1].answerText + '</button>' +
4576              '</div>' +
4577            '</div>' +
4578          '</li>'
4579        )
4580      )
4581    });
4582  }
4583
4584  async function createPriceFromLS() {
4585    $('.js-tradein-price').text('$' + formData.price.toFixed(2));
4586    $('.js-confirm-ship').attr('data-gtm-cta', trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-6').html()), 'agreement'])); 
4587    $('.tradein-summary-terms').attr('data-gtm-cta', trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-6').html()), 'terms_and_conditions']));
4588    $('.js-tradein-device').text(formData.deviceModel);
4589    $('.js-tradein-storage').text(formData.storage);
4590    $('.js-tradein-carrier').text(formData.carrier);
4591    $('.tradein-summary-list-ios, .tradein-summary-list-android').hide();
4592    if (formData.manufacturer === 'Apple') {
4593      $('.tradein-summary-list-ios').show();
4594    } else {
4595      $('.tradein-summary-list-android').show();
4596    }
4597  }
4598
4599  $('#trade-in-box').one('show.bs.modal', async function (e) {
4600    $loader.css('opacity', 1)
4601    $loader.show();
4602    if (hasDeviceInCart === undefined) document.dispatchEvent(hylaGetCartEvent);
4603    if (hylaContentData !== null && hylaFormData !== null) {
4604      createManufacturersFromLS();
4605      createDeviceModelsFromLS();
4606      createCarriersFromLS();
4607      createStorageFromLS();
4608      createDeviceConfirmFromLS();
4609      createQuestionsFromLS();
4610      createPriceFromLS();
4611    }
4612
4613    const request = createRequest(HYLA_TOKEN_API, GET_METHOD);
4614    const submitBtnUrl = $('.step-block')[6].dataset.submiturl;
4615
4616    if (!submitBtnUrl) {
4617      $cancelBtn.find('a').on('click', function(event) {
4618        event.preventDefault();
4619        $tradeModal.modal('hide');
4620      });
4621    }
4622    
4623    try {
4624      let response = await fetchHylaApi(request);
4625    
4626      token = response.access_token;
4627      refreshToken = response.refresh_token;
4628
4629      $stepsForm.steps({
4630        headerTag: "h5",
4631        bodyTag: "div",
4632        transitionEffect: "slideLeft",
4633        actionContainerTag: "footer",
4634        onInit: onInitSteps,
4635        onStepChanging: beforeStepChange,
4636        autoFocus: true,
4637        suppressPaginationOnFocus: false
4638      });
4639      $('select.select-input').selectpicker({size: 4});
4640
4641      $('.device-confirm-list').on('click', '.js-select-ext-phone-card', function(){
4642        const fieldName = this.dataset.name;
4643        const fieldValue = this.dataset.value;
4644        const fieldModelName = this.dataset.modelname;
4645        $('.device-confirm-list .js-select-ext-phone-card').removeClass('active');
4646        $(this).addClass('active');
4647        formData.setData(fieldName, fieldValue);
4648        formData.setData("confirmedModelName", fieldModelName);
4649        resetFormData(['manufacturer', 'deviceModel', 'deviceImg', 'carrier', 'storage', 'confirmedModel', 'confirmedModelName']);
4650        validate([fieldName]);
4651      });
4652
4653      //scroll to bottom of modal on click of checkbox
4654      $('.trade-in-modal .custom-control-label').one('click', function() {
4655        setTimeout(function(){
4656          $('.trade-in-modal .purchase-modal-box-body').animate({ scrollTop: $('.tradein-summary-step').height() }, "slow");
4657        }, 200);
4658      });
4659
4660      const $confirmShip = $('.js-confirm-ship');
4661
4662      $confirmShip.change(function() {
4663        if (this.checked) {
4664          formData.setData(this.name, this.value);
4665        } else {
4666          formData.setData(this.name, undefined);
4667        }
4668        validate([this.name]);
4669      });
4670    
4671      $('select.select-input').on("changed.bs.select", function(event, clickedIndex, newValue, oldValue) {
4672        formData.setData(this.name, this.value);         
4673        $(this).parents('.dropdown-wrapper').addClass('js-show-mini-placeholder');
4674        if (this.name === 'deviceModel') { 
4675          resetFormData(['manufacturer', 'deviceModel', 'deviceImg']);
4676          $('.js-tradein-storage-label').hide();
4677          this.dataset.gtmCta = trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-2').html()), this.value]);
4678          validate([this.name]);
4679        }
4680        
4681        if (this.name === 'carrier') {
4682          $('#trade-in-box .carrier-check').show();
4683          $loader.show();
4684          $('.js-step-next').removeClass('js-active');
4685          this.dataset.gtmCta = trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-3').html()), this.value]);
4686          createStorage();
4687        }
4688      });
4689    } catch (error) {
4690      console.log(error);
4691    };
4692  }); 
4693
4694  function beforeStepChange(event, currentIndex, newIndex) {
4695    if (createHylaContent(newIndex) === false) {
4696      return false;
4697    }
4698
4699    switchNextText(newIndex);
4700    return true;
4701  }
4702
4703  function showErrorModal() {
4704    $loader.hide(200);
4705    $('.tradein-error-background').show(200);
4706  }
4707
4708  function switchNextText(index) {
4709    let submitBtnUrl;
4710    let submitBtnText;
4711    
4712    const next = $('.step-block')[index].dataset.next;
4713    const previous = $('.step-block')[index].dataset.prev;
4714    if (index === 6) {
4715      if (hasDeviceInCart) {
4716        // const stepBlockSubmit = 
4717        submitBtnText = $('.step-block')[index].dataset.next;
4718        submitBtnUrl = $('.step-block')[index].dataset.submiturl;
4719      } else {
4720        submitBtnText = $('.step-block')[index].dataset.nodevice;
4721        submitBtnUrl = $('.step-block')[index].dataset.nodeviceurl;
4722      }
4723      $nextBtn.hide();
4724      $submitBtn.attr('data-gtm-cta', trimSplitJoin(['trade_in', removeSpecialChars($('.js-tradein-step-title-' + index).html()), 'next']));
4725      $prevBtn.attr('data-gtm-cta', trimSplitJoin(['trade_in', removeSpecialChars($('.js-tradein-step-title-' + index).html()), 'previous']));
4726      $submitBtn.text(submitBtnText).attr('href', submitBtnUrl).show();
4727      $submitBtn.css('display', 'inline-block');
4728      return;
4729    }
4730
4731    $nextBtn.attr('data-gtm-cta', trimSplitJoin(['trade_in', removeSpecialChars($('.js-tradein-step-title-' + index).html()), 'next']));
4732    $prevBtn.attr('data-gtm-cta', trimSplitJoin(['trade_in', removeSpecialChars($('.js-tradein-step-title-' + index).html()), 'previous']));
4733    if (index === 0) {
4734      $cancelBtn.show();
4735      $prevBtn.hide();
4736      $nextBtn.text(next);
4737
4738      return;
4739    }
4740
4741    $submitBtn.hide();
4742    $nextBtn.show();
4743    $nextBtn.text(next);
4744    $prevBtn.text(previous).css('display', 'inline-block');
4745    $cancelBtn.hide();
4746
4747    return;
4748  }
4749
4750  function createHylaContent(index) {
4751    // reset scroll position to top on step
4752    document.querySelector('#trade-in-box .purchase-modal-box-body').scrollTop = 0;
4753    if (index === 0) {
4754      $loader.show();
4755      $('.trade-in-modal').addClass('tradein-flow-start');
4756      $loader.hide();
4757    }
4758
4759    //manufacturers
4760    if (index === 1) {     
4761      return createManufacturers();           
4762    }
4763
4764    //device model
4765    if (index === 2) {
4766      return createDeviceModels();          
4767    }
4768
4769    //carrier and storage
4770    if (index === 3) {
4771      return createCarriersAndStorage();       
4772    }
4773
4774    //confirm device
4775    if (index === 4) {      
4776      return createDeviceConfirmtaion();
4777    }
4778
4779    //Questions
4780    if (index === 5) {
4781      return createQuestions();
4782    }
4783
4784    //price summary
4785    if (index === 6) {
4786      return createPrice();
4787    }
4788    return;
4789  }
4790  
4791  //HYLA API Content Setters
4792  function createStorage() {
4793    (async function() {
4794      try {
4795        const paramsObj = {};
4796        paramsObj.manufacturer = formData.manufacturer;
4797        paramsObj.productfamily = formData.deviceModel;
4798        paramsObj.carrier = formData.carrier;
4799        const request = createRequest(HYLA_ATTRIBUTES_API, GET_METHOD, token, paramsObj);
4800        let storageRes = await fetchHylaApi(request, createStorage);
4801        const $storageSelect = $('.single-select-group[data-name=storage]');
4802        $storageSelect.empty();
4803        resetFormData(['manufacturer', 'deviceModel', 'deviceImg', 'carrier']);
4804        $('.js-tradein-storage-label').show();
4805        $.each(storageRes.capacities, function(index, value) {
4806          $storageSelect.append(
4807            $('<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-3').html()), value.value]) + '"aria-label="'+ parseInt(value.value)+" "+"gigabyte" +'" class="single-select-btn" value="' + value.value + '">' + value.value + '</button>')
4808          )
4809        });
4810        hylaContentObj.capacities = storageRes.capacities;
4811        $loader.hide();
4812        hasRecalled = false;
4813      } catch (error) {
4814        console.log(error);
4815      };
4816    })();
4817  }
4818
4819  function createPrice() {
4820    if (!validate(['questions'])) return false;
4821    if (!hasContentChangedFromLS && hylaContentData !== null && hylaFormData !== null) {
4822      $('.js-step-next').removeClass('js-active');
4823      $submitBtn.removeClass('js-active');
4824      document.querySelector('.js-confirm-ship').checked = true;
4825    }
4826    if (formData.price !== undefined) return;
4827    $loader.show();
4828    $('.js-step-next').removeClass('js-active');
4829    $submitBtn.removeClass('js-active');
4830
4831    (async function() {
4832      try {
4833        const url = `${HYLA_MODELS_PATH}/${formData.confirmedModel}${HYLA_PRICE_API}?${clientIdParam}=${clientId}`;
4834        const request = createRequest(url, POST_METHOD, token, false, JSON.stringify(formData.questions));
4835        let response = await fetchHylaApi(request, createPrice, url)
4836        formData.setData('price', (response.moneyDTO.amount));
4837        formData.setData('currencyCode', (response.moneyDTO.currencyCode));
4838        $('.js-tradein-price').text('$' + formData.price.toFixed(2));
4839
4840        $('.js-confirm-ship')[0].focus();
4841        $loader.hide();         
4842
4843        $('.js-confirm-ship').attr('data-gtm-cta', trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-6').html()), 'agreement']));
4844        $('.tradein-summary-terms').attr('data-gtm-cta', trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-6').html()), 'terms_and_conditions']));
4845        $('.js-tradein-device').text(formData.deviceModel);
4846        $('.js-tradein-storage').text(formData.storage);
4847        $('.js-tradein-carrier').text(formData.carrier);
4848        hasRecalled = false;
4849      } catch (error) {
4850        console.log(error);
4851      };
4852    })();
4853  }
4854
4855  function createDeviceConfirmtaion() {
4856    if (!validate(['carrier', 'storage'])) return false;
4857    if (formData.confirmedModel !== undefined) return;
4858    $('.js-step-next').removeClass('js-active');
4859    $loader.show();
4860    const $deviceList = $('.device-confirm-list');
4861
4862    (async function() {
4863      try {
4864        const paramsObj = {};
4865        paramsObj.manufacturer = formData.manufacturer;
4866        paramsObj.productfamily = formData.deviceModel;
4867        paramsObj.carrier = formData.carrier;
4868        paramsObj.capacity = formData.storage;
4869
4870        const request = createRequest(HYLA_TOPMODELS_API, GET_METHOD, token, paramsObj);
4871        let response = await fetchHylaApi(request, createDeviceConfirmtaion);
4872        $deviceList.empty();
4873        $.each(response.models, function(index, value) {
4874          $deviceList.append(
4875            $('<div  class="phone-card-container text-center mt-60">' +
4876                '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-4').html()), value.modelCode]) + '" data-name="confirmedModel" data-modelname="' + value.consumerDisplayAlias + '" data-value="' + value.modelCode + '" class="text-center phone-card-details js-select-ext-phone-card">' +
4877                  '<img data-gtm-asset="' + value.imageUrl + '" data-gtm-agencyid="' + HYLA_AGENCY_ID + '" src="' + value.imageUrl + '"/>' + 
4878                  '<div class="tradein-confirm-text">' +
4879                    '<p class="heading-container caption-one font-weight-bold">' + value.consumerDisplayAlias + '</p>' +
4880                  '</div>' +
4881                '</button>' +
4882              '</div>')
4883          )});
4884        hylaContentObj.models = response.models;
4885
4886        closeBtn.focus();
4887        document.activeElement.blur();
4888        $loader.hide();
4889        hasRecalled = false;
4890      } catch (error) {
4891        console.log(error);
4892      };
4893    })();
4894  }
4895
4896  function createCarriersAndStorage() {
4897    if (!validate(['deviceModel'])) return false;
4898    if (formData.carrier !== undefined || formData.storage !== undefined) return;
4899    $('#trade-in-box .carrier-check').hide();
4900    const $storageSelect = $('.single-select-group[data-name=storage]');
4901    $('.js-step-next').removeClass('js-active');
4902    $('.js-tradein-current-description').text(formData.deviceModel);
4903    $storageSelect.empty();
4904    $loader.show();  
4905    (async function() {
4906      try {
4907        const paramsObj = {};
4908        paramsObj.manufacturer = formData.manufacturer;
4909        paramsObj.productfamily = formData.deviceModel;
4910        const attributesRequest = createRequest(HYLA_ATTRIBUTES_API, GET_METHOD, token, paramsObj);
4911        const topModelsRequest = createRequest(HYLA_TOPMODELS_API, GET_METHOD, token, paramsObj);
4912        let fetchAttributes = fetchHylaApi(attributesRequest, createCarriersAndStorage, false, true);
4913        let fetchTopModels = fetchHylaApi(topModelsRequest, createCarriersAndStorage, false, true);
4914        let allResponses = await Promise.all([fetchAttributes, fetchTopModels]);
4915        const attributesRes = allResponses[0];
4916        const topModelsRes = allResponses[1];
4917        const $carrierSelect = $('select.select-input[name="carrier"]');    
4918        $carrierSelect.empty();
4919        $storageSelect.empty();
4920        hylaContentObj.carriers = attributesRes.carriers;
4921        $carrierSelect.append($('<option value="empty" data-hidden="true"></option>'))
4922        $.each(attributesRes.carriers, function(index, value) {
4923          $carrierSelect.append(
4924            $('<option value="' + value.value + '">' + value.value + '</option>')
4925          )
4926        });
4927        $carrierSelect.selectpicker('refresh');
4928        $carrierSelect.parents('.dropdown-wrapper').removeClass('js-show-mini-placeholder');
4929
4930        //add first image found in topmodels response
4931        formData.setData('deviceImg', topModelsRes.models[0].imageUrl);
4932        $('.js-tradein-current-image').attr({
4933          'src': formData.deviceImg,
4934          'data-gtm-asset': formData.deviceImg
4935        });
4936        $('.form-select-custom')[1].focus();   
4937        $loader.hide();
4938        hasRecalled = false;
4939      } catch(error) {
4940        handleAPIResponseFailure(error, createCarriersAndStorage);
4941      }
4942    })();
4943  }
4944
4945  function createDeviceModels() {
4946    if (!validate(['manufacturer'])) return false;
4947    if (formData.deviceModel !== undefined) return;
4948    $('.js-step-previous').css('display', 'inline-block');
4949    $('.js-step-next').removeClass('js-active');
4950    $loader.show();
4951    
4952    (async function() {
4953      try {
4954        const paramsObj = {};
4955        paramsObj.manufacturer = formData.manufacturer;
4956        const request = createRequest(HYLA_ATTRIBUTES_API, GET_METHOD, token, paramsObj);
4957        let response = await fetchHylaApi(request, createDeviceModels);
4958        const $deviceSelect = $('select.select-input[name="deviceModel"]');           
4959        $deviceSelect.empty();
4960        $deviceSelect.parents('.dropdown-wrapper').removeClass('js-show-mini-placeholder');
4961        $deviceSelect.append($('<option value="empty" data-hidden="true"></option>'))
4962        $.each(response.productFamilies, function(index, value) {
4963          $deviceSelect.append(
4964            $('<option value="' + value.value + '">' + value.value + '</option>')
4965          )
4966        });
4967        hylaContentObj.productFamilies = response.productFamilies;
4968        $deviceSelect.selectpicker('refresh');
4969        $('.form-select-custom')[0].focus();    
4970        $loader.hide();
4971        hasRecalled = false;
4972      } catch (error) {
4973        console.log(error);
4974      }
4975    })();
4976  }
4977
4978  function createManufacturers() {
4979    $('.trade-in-modal').removeClass('tradein-flow-start');
4980    validate(['manufacturer']);
4981    if (formData.manufacturer !== undefined) return;
4982    $loader.show();
4983    $('.js-step-next').removeClass('js-active');
4984    (async function() {
4985      try {
4986        let request = createRequest(HYLA_ATTRIBUTES_API, GET_METHOD, token);
4987        let response = await fetchHylaApi(request, createManufacturers);
4988        const $manufacturers = $('.js-manufacturers');
4989        $manufacturers.empty();
4990        $.each(response.manufacturers, function(index, value) {
4991          $manufacturers.append(
4992            $(
4993              '<div data-manufacturer="' + value.value + '" class="col manufacturer">' +
4994                '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-1').html()), value.value]) + '" type="button" aria-label="' + value.value + (index+1) + "of" + (response.manufacturers.length) + '" class="manufacturer-checkbox">' +
4995                  '<img data-gtm-asset="' + value.url + '" data-gtm-agencyid="' + HYLA_AGENCY_ID + '" src="' + value.url + '" class="manufacturer-icon"/>' +
4996                  '<span class="manufacturer-check icon light-theme large-icon"><i class="success"></i></span>' +
4997                '</button>' +
4998              '</div>')
4999          )
5000        });
5001        hylaContentObj.manufacturers = response.manufacturers;
5002        closeBtn.focus();
5003        document.activeElement.blur();
5004        $loader.hide();
5005        hasRecalled = false;
5006      } catch (error) {
5007        console.log(error);
5008      }
5009    })();
5010  }
5011
5012  function createQuestions() {
5013    if (!validate(['confirmedModel'])) return false;
5014    if (formData.questions.length > 0) return;
5015    $('.js-step-next').removeClass('js-active'); 
5016    const $questions = $('.tradein-questions .tradein-question-list');
5017    if($questions.children().length > 0) return;
5018    $loader.show();
5019    
5020    (async function() {
5021      try {
5022        const url = `${HYLA_MODELS_PATH}/${formData.confirmedModel}${HYLA_QUESTIONS_API}`
5023        const request = createRequest(url, GET_METHOD, token);
5024        let response = await fetchHylaApi(request, createQuestions);
5025        $.each(response, function(index, value) {
5026          if (value.questionType !== 'SINGLE_SELECT') return;
5027          value.validAnswers[0].questionCode = value.code;
5028          value.validAnswers[1].questionCode = value.code;
5029          $questions.append(
5030            $('<li class="tradein-question-item">' +
5031                '<div class="tradein-question-wrap">' +
5032                  '<label class="tradein-question-label">' + value.text + '</label>' +
5033                  '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-5').html()), value.validAnswers[0].answerText, 'popover']) + '" rel="popover" type="button" data-trigger="focus" class="popover-btn icon light-theme large-icon" data-toggle="popover" data-content="<p>' + value.helpText + '</p>"><i class="question-mark-black"></i></button>' +
5034                '</div>' +
5035                '<div class="d-flex flex-column tradein-answers-wrap">' +
5036                  '<div data-name="questions" class="single-select-group">' +
5037                    '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-5').html()), value.validAnswers[0].answerText]) + '" class="single-select-btn" value=' + JSON.stringify(value.validAnswers[0]) + '>' + value.validAnswers[0].answerText + '</button>' +
5038                    '<button data-gtm-cta="' + trimSplitJoin([removeSpecialChars($('.js-tradein-step-title-5').html()), value.validAnswers[1].answerText]) + '" class="single-select-btn" value=' + JSON.stringify(value.validAnswers[1]) + '>' + value.validAnswers[1].answerText + '</button>' +
5039                  '</div>' +
5040                '</div>' +
5041              '</li>'
5042            )
5043          )
5044        });
5045        hylaContentObj.questions = response;
5046
5047        $(".popover-btn").popover({  
5048          placement: 'top', 
5049          html: true,
5050          trigger: 'focus',
5051          template: '<div class="tradein-popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-body"></div></div></div>'
5052        });
5053        closeBtn.focus();
5054        $loader.hide();        
5055        hasRecalled = false;
5056      } catch (error) {
5057        console.log(error);
5058      }
5059    })();
5060  }
5061
5062  function validate(keys) {   
5063    let valid = false;
5064    if (keys[0] === 'questions') {
5065      valid = $('.single-select-group[data-name="questions"]').length === formData.questions.length;
5066    } else {
5067      $.each(keys, function(index, value) {
5068        if(formData[value] === undefined) return valid = false;
5069        return valid = true; 
5070      });
5071    }
5072    if(valid && hasContentChangedFromLS) {
5073      $('.js-step-next, .js-step-submit').addClass('js-active').attr('aria-disabled', 'false');
5074    } else if(!valid && hasContentChangedFromLS) {
5075      $('.js-step-next, .js-step-submit').removeClass('js-active').attr('aria-disabled', 'true');
5076    }
5077    return valid;    
5078  }
5079
5080  function trimSplitJoin(strings) {
5081    let newString = '';
5082    for(let i = 0; i < strings.length; i++) {
5083      newString += strings[i].toLowerCase().trim().split(' ').join('_');
5084      //add colon if not last element
5085      if (i < strings.length - 1) {
5086        newString += ':';
5087      }
5088    }
5089    return newString;
5090  }
5091
5092  function removeSpecialChars(string) {
5093    if (string !== undefined) {
5094      return string.replace(/[`~!@#$%^*()_|+=?;:'",.<>\{\}\[\]\\\/]/gi, '');
5095    }
5096  }
5097
5098  function isJson(str) {
5099    let json;
5100    try {
5101      json = JSON.parse(str);
5102    } catch(e) {
5103      return false;
5104    }
5105    return json;
5106  }
5107
5108  //custom form data constructor
5109  function StepsFormData(selector) { 
5110    if (!selector || selector === null) {
5111      return undefined;
5112    }
5113
5114    this.deviceImg = undefined;
5115    this.questions = [];
5116    this.setData = (key, value) => {
5117      let json = false;
5118      //check if value is JSON and push to array, specific to questions array
5119      if (isNaN(parseInt(value))){
5120        json = isJson(value);
5121      }
5122
5123      if (json) {
5124        //filter out non unique objects by questionCode
5125        this[key] = this[key].filter(( obj ) => obj.questionCode !== json.questionCode);
5126        return this[key].push(json);
5127      }
5128
5129      hasContentChangedFromLS = true;
5130
5131      return this[key] = value;
5132    };
5133  }  
5134});
5135
5136
5137/*Helper function to get cookie value*/
5138function getCookie(name) {
5139    var nameEQ = name + "=";
5140    var ca = document.cookie.split(';');
5141    for (var i = 0; i < ca.length; i++) {
5142        var c = ca[i];
5143        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
5144        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
5145    }
5146    return null;
5147}
5148
5149/*Event listener for PLP experience-fragment load in purchase flow*/
5150$(document).on("PurchasePLPLoaded", function() {
5151
5152    /*set the selected value in sort dropdown*/
5153    $('.sort-dropdown').each(function(index) {
5154        var dd1 = new DropDown($(this));
5155        var selectedSortValue = $(this).find('ul.drop li.selected').html();
5156        $('.sort-dropdown span.sort-selected').html(selectedSortValue);
5157    });
5158
5159    /*close menu on document click*/
5160    $(document).click(function() {
5161        $('.wrap-drop').removeClass('active');
5162    });
5163
5164    /*distpatch event for compare overlay on compare click*/
5165    $('body').on("click", ".purchase-compare", function() {
5166        this.dispatchEvent(new Event('loadCompareOverlay', {
5167            'bubbles': true
5168        }));
5169    });
5170    /*set the selected value in sort dropdown*/
5171    var clickCount = 0;
5172    $('body').on("click", '.purchase-flow-wrapper .product-filter-container .wrap-drop.sort-dropdown', function(e) {
5173        e.stopImmediatePropagation();
5174        if (clickCount == 0) {
5175            var dd1 = new DropDown($(this));
5176            var selectedSortValue = $(this).find('ul.drop li.selected').html();
5177            $('.sort-dropdown span.sort-selected').html(selectedSortValue);
5178            clickCount = clickCount + 1;
5179            $(this).click();
5180        }
5181    });
5182
5183
5184
5185    /*function call to set hpp data in modal*/
5186    setHppModalData();
5187
5188});
5189/*On purchase listener loaded*/
5190$(document).on("PurchasePLPListenersLoaded", function() {
5191    $(document).on("click", ".cart-wizard-heading .skipEvent, .product-listing-container .skipEvent, .purchase-flow-plp-item-loaded .skipEvent", function() {
5192        this.dispatchEvent(new Event('PuchasePLPSkipEvent', {
5193            'bubbles': true
5194        }));
5195    });
5196    $(document).on("click", "#modalClosePdp", function() {
5197        document.dispatchEvent(new Event('PuchasePDPModalCloseEvent', {
5198            'bubbles': true
5199        }));
5200    });
5201    attachCloseModelEventListener();
5202});
5203/*On Document ready*/
5204$(document).ready(function() {
5205    setHppModalData();
5206    attachCloseModelEventListener();
5207     startDiagnostic();
5208    $('.hppeligibilitychecker #not-logged-in-type .button').addClass('disabled');
5209});
5210/*Attach modal close event listener*/
5211function attachCloseModelEventListener() {
5212    $(document).on("click", '.learn-more-modal .modal-body .close-modal', function() {
5213        if (document.querySelector('#checkme').getAttribute("checked") == "checked") {
5214            document.querySelector('#checkme').click();
5215        }
5216        if (document.querySelector('.show .close') != null) {
5217            document.querySelector('.show .close').click();
5218        }
5219    });
5220}
5221/* function to enable the HPP submut button on selection of value form dropdown */
5222function enableHppButtonOnDropDownSelection(element) {
5223    var esnValue =$(element).attr('data-esn');
5224    if(esnValue) {
5225        $('.hppeligibilitychecker #not-logged-in-type .button').removeClass('disabled');
5226    }
5227
5228}
5229
5230/*function to set hpp data in enroll now modal*/
5231function setHppModalData() {
5232    var agree = document.getElementById('checkme');
5233    if (agree) {
5234        agree.onchange = function() {
5235            $('#confirmBtn').toggleClass('disabled');
5236            var accesibilityEnableLabel = "";
5237            var accesibilityDisableLabel = "";
5238            if (document.querySelector('#confirmBtn .confirm') != null) {
5239                accesibilityEnableLabel = document.querySelector('#confirmBtn .confirm').getAttribute("data-enable-btnmsg");
5240                accesibilityDisableLabel = document.querySelector('#confirmBtn .confirm').getAttribute("data-disable-btnmsg");
5241            }
5242            if ($('#confirmBtn').hasClass('disabled')) {
5243                $('#confirmBtn .confirm').attr('aria-label', accesibilityDisableLabel);
5244            } else {
5245                $('#confirmBtn .confirm').attr('aria-label', accesibilityEnableLabel);
5246            }
5247        };
5248    }
5249    /*See Detail & TNC Modal Start*/
5250     $('body').on("click", ".dynamic-modal-button", function() {
5251                // Get data-partnumber from parent div.hpp-plan.plan-card
5252                var partNumber = $(this).closest('div.hpp-plan.plan.card').attr('data-partnumber');
5253                if (!$(this).hasClass("disabled")) {
5254                    var modal = document.querySelector($(this).attr('data-target'));
5255                    var modalAriaLabel = modal.getAttribute('data-appended-aria-text') ? $(this).html() + modal.getAttribute('data-appended-aria-text') : '';
5256                    var gtaText = $('.dynamic-modal-button').attr('data-gtm-cta');
5257                    if((partNumber && partNumber.indexOf('DPP') !== -1) && (gtaText.indexOf('Assurant_Care_see_details') !== -1)){
5258                        // Show ST Protect content in modal body
5259                        var modalData = $(this).attr('data-modalval');
5260                        $('.hpp-dynamic-data').html(modalData);
5261                    }
5262                    else if (partNumber && partNumber.indexOf('DPP') !== -1) {
5263                        // Show the .dpp-see-details-modal section in the modal body
5264                        var dppSection = $('.dpp-see-details-modal').html();
5265                        $('.hpp-dynamic-data').html(dppSection); //enter see detail for dpp see details
5266                    } else {
5267                        var modalData = $(this).attr('data-modalval');
5268                        $('.hpp-dynamic-data').html(modalData);
5269                    }
5270                    if(modalAriaLabel) modal.setAttribute('aria-label', modalAriaLabel);
5271                    addTabindexAccordian(modal);
5272                    tabStop(modal, true);
5273                }
5274            });
5275
5276
5277
5278    /*Enroll Now Model Open*/
5279    $('body').on("click", ".hpp-enrollnow-button", function(event) {
5280        if (!$(this).parent().hasClass("disabled") && !$(event.target).hasClass('dynamic-modal-button')) {
5281            var $modal = $(document.querySelector($(this).attr('data-target')));
5282            var enrollTitle = $(this).attr('data-enrolltitle');
5283            var enrollDescription = $(this).attr('data-enrolldescription');
5284            var enrollCondition = $(this).attr('data-enrollcondition');
5285            let deviceCheckDescription = $(this).attr('data-devicecheckdesc');
5286            let deviceCheckDescriptionMobile = $(this).attr('data-devicecheckdescmobile');
5287            let deviceCheckPopupMsg = $(this).attr('data-devicecheckpopupimg');
5288            var hppPlanName = $(this).attr('data-planname');
5289            var productId = $(this).attr('data-productid');
5290            var skuId = $(this).attr('data-skuid');
5291            var serviceDays = $(this).attr('data-planservicedays');
5292            var thumbnailimage = $(this).attr('data-thumbnailimage');
5293            var productAssetId = $(this).attr('data-productassetid');
5294            var productAssetAgencyId = $(this).attr('data-productassetagencyid');
5295            var hppPlanPrice = $(this).attr('data-planprice');
5296            var hppPartNo = $(this).attr('data-skupartnumber');
5297            var duration = $(this).attr('data-hppduration');
5298            var planId = $(this).attr('data-planid');
5299            var isMonthlyPlan = $(this).attr('data-ismonthlyplan');
5300            var hppVendorName = $(this).attr('data-vendorname');
5301            var thumbnailimageCancelled = $(this).attr('data-thumbnailimagecancelled')
5302            $('.enroll-title').text(enrollTitle);
5303            $('.enroll-description').text(enrollDescription);
5304            $('.enroll-condition').text(enrollCondition);
5305            $('.enroll-now-confirm').attr('data-productid', productId);
5306            $('.enroll-now-confirm').attr('data-skuid', skuId);
5307            $('.enroll-now-confirm').attr('data-planname', hppPlanName);
5308            $('.enroll-now-confirm').attr('data-thumbnailimage', thumbnailimage);
5309            $('.enroll-now-confirm').attr('data-servicedays', serviceDays);
5310            $('.enroll-now-confirm').attr('data-productassetid', productAssetId);
5311            $('.enroll-now-confirm').attr('data-productassetagencyid', productAssetAgencyId);
5312            $('.enroll-now-confirm').attr('data-planprice', hppPlanPrice);
5313            $('.enroll-now-confirm').attr('data-partno', hppPartNo);
5314            $('.enroll-now-confirm').attr('data-hppduration', duration);
5315            $('.enroll-now-confirm').attr('data-planid', planId);
5316            $('.enroll-now-confirm').attr('data-ismonthlyplan', isMonthlyPlan);
5317            $('.enroll-now-confirm').attr('data-vendorname', hppVendorName);
5318            $('.enroll-now-confirm').attr('data-thumbnailimagecancelled', thumbnailimageCancelled);
5319            $('.hpp-enrollnow-button').attr('data-productid', productId);
5320            $('.hpp-enrollnow-button').attr('data-skuid', skuId);
5321            $('.hpp-enrollnow-button').attr('data-planname', hppPlanName);
5322            $('.hpp-enrollnow-button').attr('data-thumbnailimage', thumbnailimage);
5323            $('.hpp-enrollnow-button').attr('data-servicedays', serviceDays);
5324            $('.hpp-enrollnow-button').attr('data-productassetid', productAssetId);
5325            $('.hpp-enrollnow-button').attr('data-productassetagencyid', productAssetAgencyId);
5326            $('.hpp-enrollnow-button').attr('data-planprice', hppPlanPrice);
5327            $('.hpp-enrollnow-button').attr('data-partno', hppPartNo);
5328            $('.hpp-enrollnow-button').attr('data-hppduration', duration);
5329            $('.hpp-enrollnow-button').attr('data-planid', planId);
5330            $('.hpp-enrollnow-button').attr('data-ismonthlyplan', isMonthlyPlan);
5331            $('.hpp-enrollnow-button').attr('data-vendorname', hppVendorName);
5332            $('.hpp-enrollnow-button').attr('data-thumbnailimagecancelled', thumbnailimageCancelled);
5333                /* Mirror key HPP data attributes onto the device-check continue button
5334                    so _setHppAddTOCartData() can build a valid HPP payload when
5335                    the logged-in user clicks "Continue" after device check. */
5336
5337            if(hppVendorName&&hppVendorName==="APPLE"){
5338                $('.protection-device-check-modal-body').addClass('d-none');
5339                $('.view-brochure-link').addClass('d-none');
5340                $('.tncmodal-body').removeClass('d-none');
5341
5342             }else if (hppPartNo && hppPartNo.indexOf('DPP') !== -1) {
5343                // Store the selected HPP plan's part number in localStorage
5344                console.log('DPP plan selected:', hppPartNo);
5345                
5346                // Check flowType cookie first
5347                var flowTypeCookie = getCookie('flowType');      
5348                // ACTIVATION FLOW: dispatch VAS Purchase event and stop
5349                if (flowTypeCookie === 'activation') {
5350                    console.log('FlowType is activation, dispatching hppcheckvaspurchase event');
5351                    
5352                    // Prevent Bootstrap modal from opening
5353                    event.preventDefault();
5354                    event.stopImmediatePropagation();
5355                    
5356                    // Dispatch the event
5357                    document.dispatchEvent(new CustomEvent('hppcheckvaspurchase', {
5358                        detail: {
5359                            hppPartNo: hppPartNo
5360                        },
5361                        bubbles: true
5362                    }));
5363                    // Stop execution here - VAS API response handler will manage next steps
5364                    return;
5365                }
5366              
5367                // PURCHASE FLOW: device check popup (flowType is 'purchase' or not present)
5368                // If user is NOT logged in — skip device check popup, add directly to cart
5369                var isLoggedIn = document.cookie.indexOf('roToken') > -1;
5370                if (!isLoggedIn) {
5371                    console.log("DPP plan: User not logged in — adding directly to cart, skipping device check");
5372
5373                    /* Prevent Bootstrap modal from showing (it was triggered by data-toggle) */
5374                    event.preventDefault();
5375                    event.stopImmediatePropagation();
5376
5377                    /* Force-close modal in case Bootstrap already started opening it */
5378                    if ($modal && $modal.length) {
5379                        $modal.modal('hide');
5380                    }
5381                    $('#terms-box').modal('hide');
5382                    $('.modal-backdrop').remove();
5383                    $('body').removeClass('modal-open');
5384
5385                    return;
5386                }
5387                else if(isLoggedIn && flowTypeCookie === 'purchase') {
5388                /* Logged-in user — show device check popup as normal */
5389                $('.device-check-continue-btn').attr('data-productid', productId);
5390                $('.device-check-continue-btn').attr('data-skuid', skuId);
5391                $('.device-check-continue-btn').attr('data-planname', hppPlanName);
5392                $('.device-check-continue-btn').attr('data-thumbnailimage', thumbnailimage);
5393                $('.device-check-continue-btn').attr('data-servicedays', serviceDays);
5394                $('.device-check-continue-btn').attr('data-productassetid', productAssetId);
5395                $('.device-check-continue-btn').attr('data-productassetagencyid', productAssetAgencyId);
5396                $('.device-check-continue-btn').attr('data-planprice', hppPlanPrice);
5397                $('.device-check-continue-btn').attr('data-partno', hppPartNo);
5398                $('.device-check-continue-btn').attr('data-hppduration', duration);
5399                $('.device-check-continue-btn').attr('data-planid', planId);
5400                $('.device-check-continue-btn').attr('data-ismonthlyplan', isMonthlyPlan);
5401                $('.device-check-continue-btn').attr('data-vendorname', hppVendorName);
5402                $('.device-check-continue-btn').attr('data-thumbnailimagecancelled', thumbnailimageCancelled);
5403                $('.tncmodal-body').addClass('d-none');
5404                $('.protection-device-check-modal-body').removeClass('d-none');
5405                $modal.find('.device-check-enroll-title').text(enrollTitle);
5406                $modal.find('.device-check-enroll-subtitle').text(enrollDescription);
5407                $modal.find('.device-check-enroll-desc-mobile').html(deviceCheckDescriptionMobile);
5408                $modal.find('.device-check-enroll-description').html(deviceCheckDescription);
5409                $modal.find('.protection-logo-img').attr('src', deviceCheckPopupMsg);
5410                
5411                }
5412            } else if(hppVendorName&&hppVendorName!="APPLE"){
5413                     $('.tncmodal-body').removeClass('d-none');
5414                     $('.protection-device-check-modal-body').addClass('d-none');
5415            		 $('.view-brochure-link').removeClass('d-none');
5416              }
5417        }
5418    });
5419}
5420
5421
5422/**Cancel HPP Plp TnC Modal */
5423function cancelHppTnC() {
5424    if (document.querySelector('#checkme').getAttribute("checked") == "checked") {
5425        document.querySelector('#checkme').click();
5426    }
5427    if (document.querySelector('#terms-box .close') != null) {
5428        document.querySelector('#terms-box .close').click();
5429    }
5430}
5431
5432/**Start Diagnostic - Opens diagnostic URL in new tab */
5433function startDiagnostic() {
5434    $('body').on('click', '#startdiagnostic-button', function(e) {
5435        e.preventDefault();
5436        var diagnosticUrl = $('.device-check-content').attr('data-diagnostic-url');
5437        if (diagnosticUrl) {
5438            window.open(diagnosticUrl, '_blank');
5439        }
5440    });
5441}
5442
5443var hppPlanObserver = new MutationObserver(function(mutations) {
5444    var hppPlan = document.querySelector('.hpp-plan');
5445    if (hppPlan) {
5446       var partNo= hppPlan.getAttribute("data-partnumber");
5447         if(partNo && partNo.indexOf('DPP') !== -1){
5448            hppPlanObserver.disconnect();
5449            var dppSection = document.querySelector('.dpp-product-section');
5450            var nonDppSection = document.querySelector('.non-dpp-product-section');
5451            console.log(dppSection);
5452            if(dppSection){
5453                dppSection.classList.remove('d-none');
5454                nonDppSection.classList.add('d-none');
5455            }
5456         }
5457         else{
5458            var dppSection = document.querySelector('.dpp-product-section');
5459            if(dppSection){
5460                dppSection.classList.add('d-none');
5461            }
5462         }
5463         /* Disconnect observer after finding the element to avoid unnecessary future observations */
5464        
5465    }
5466
5467});
5468hppPlanObserver.observe(document.body, { childList: true, subtree: true });
5469
5470/*Event listener for PLP load in activation flow*/
5471$( document ).on("ActivationPLPLoaded", function() {
5472    /*attach event on sort dropdown after load*/
5473    setTimeout(function() {
5474        if ($('.sort-dropdown ul li').length > 0) {
5475            $('.sort-dropdown ul li').click(function(event) {
5476                document.dispatchEvent(new CustomEvent("PLPSortDropdownFilterClicked", {
5477                    "detail": {
5478                        "_type": "sort-by-click",
5479                        "selectedDropdown": event.currentTarget
5480                    }
5481                }));
5482            })
5483        }
5484    }, 5000);
5485
5486    /*set the selected value in sort dropdown*/
5487    $('.sort-dropdown').each(function( index ) {
5488        var dd1 = new DropDown($(this));
5489        var selectedSortValue = $(this).find('ul.drop li.selected').html();
5490        $('.sort-dropdown span.sort-selected').html(selectedSortValue);
5491    });
5492    var clickCount = 0;
5493    $('body').on("click",'.activation-flow-wrapper .product-filter-container .wrap-drop.sort-dropdown',function (e) {
5494        e.stopImmediatePropagation();
5495        if(clickCount==0){
5496            var dd1 = new DropDown($(this));
5497            var selectedSortValue = $(this).find('ul.drop li.selected').html();
5498            $('.sort-dropdown span.sort-selected').html(selectedSortValue);
5499            clickCount = clickCount+1;
5500            $(this).click();
5501        }
5502    });
5503
5504    /*close menu on document click*/
5505    $(document).click(function () {
5506        $('.wrap-drop').removeClass('active');
5507    });
5508
5509    /*distpatch event for compare overlay on compare click*/
5510    $('body').on("click",".purchase-compare",function(){
5511        this.dispatchEvent(new Event('loadCompareOverlay', { 'bubbles': true }));
5512    });
5513
5514
5515
5516    /*function call to set hpp data in modal*/
5517    setHppModalData();
5518});
5519/*On activations listener loaded*/
5520$( document ).on( "ActivationPLPListenersLoaded", function() {
5521	// Added .purchase-flow-plp-item-loaded .skipEvent for BYOP flow where _enforceProtectionPLPVisibility() shows the purchase PLP and hides the activation PLP
5522	$(document).on("click",".cart-wizard-heading .skipEvent, .activation-flow-plp-item-loaded .skipEvent, .purchase-flow-plp-item-loaded .skipEvent",function(){
5523		this.dispatchEvent(new Event('AcivationPLPSkipEvent', { 'bubbles': true }));
5524	});
5525	$(document).on("click","#modalClosePdp",function(){
5526		document.dispatchEvent(new Event('ActivationPDPModalCloseEvent', { 'bubbles': true }));
5527	});
5528	attachCloseModelEventListener();
5529});
5530
5531$(document).ready(function () {
5532	setHppModalData();
5533    attachCloseModelEventListener();
5534});
5535
5536function attachCloseModelEventListener(){
5537	$(document).on("click",'.learn-m
5537ore-modal .modal-body .close-modal',function(){
5538		if(document.querySelector('#checkme').getAttribute("checked") == "checked"){
5539            document.querySelector('#checkme').click();
5540		}
5541		if(document.querySelector('.show .close')!=null){
5542			document.querySelector('.show .close').click();
5543		}
5544    });
5545}
5546
5547/* PLP Buttons */
5548$(".phone-selector :checkbox").on('change', function() {
5549    if ($(".refresh_plp").length === 1) {
5550        $(".phone-selector :checkbox").removeAttr("checked").parent('label').removeClass('selected');
5551        $(".phone-selector .nav li").removeClass("selected");
5552        $(".phone-selector :checkbox").parent('label').attr("aria-checked", "false");
5553        $(".phone-selector .nav li").attr("aria-selected",false);
5554        $('.phone-selector .nav li').removeClass('active');
5555
5556        $(this).parents('.phone-selector .nav li').attr("aria-selected",true);
5557        $(this).parents('.phone-selector .nav li').addClass('selected');
5558        $(this).attr("checked", "checked").parent('label').addClass('selected');
5559        if ($(this).parent('label').attr("aria-checked") !== undefined) { 
5560            $(this).parent('label').attr("aria-checked", "true") 
5561        };
5562
5563    } else {
5564        if ($(this).attr('checked') == 'checked') {
5565            $(this).removeAttr("checked").parent('label').removeClass('selected');
5566            if ($(this).parent('label').attr("aria-checked") !== undefined) { $(this).parent('label').attr("aria-checked", "false") };
5567        } else {
5568            $(this).attr("checked", "checked").parent('label').addClass('selected');
5569            if ($(this).parent('label').attr("aria-checked") !== undefined) { $(this).parent('label').attr("aria-checked", "true") };
5570        }
5571    }
5572});
5573
5574
5575$(".phone-selector li").on('keypress', function(event) {
5576    if ($(".refresh_plp").length === 1 && event.which == 13) {
5577        $(this).find("input").click();
5578        $(this).find("input").trigger('change');
5579    }
5580});
5581
5582$(".phone-selector ul li").keypress(function(e) {
5583    if (e.which == 13) {
5584        $(this).find('label').toggleClass('selected');
5585    }
5586});
5587/* PLP Buttons */
5588
5589/*Filter Modal Position*/
5590$(".all-filter").on("click", function() {
5591    //$("#allFilterModal").modal("show");
5592    var offset = $(this).offset();
5593    offset.top -= 160;
5594    $('html').animate({ scrollTop: offset.top,}, 100);
5595    $('body').css("padding-right", "").removeClass('modal-open');
5596    //$("body").append("<div class='modal-backdrop-filter fade show' style='z-index: 1210'></div>");
5597});
5598
5599/*Filter rating -Start*/
5600$(".filter-rating>li").on('click', function(e) {
5601    let indexSel = $(this).attr('data-index');
5602    $(".filter-rating>li").each(function(index) {
5603        $(this).removeClass('selected');
5604        if (index < indexSel) {
5605            $(this).addClass('filter-rating-black');
5606        } else {
5607            $(this).removeClass('filter-rating-black');
5608        }
5609    });
5610    $(this).addClass('selected');
5611});
5612/*Filter rating -End*/
5613
5614/*Filter Modal Close Functioning*/
5615$("#allFilterModal .close").on("click", function() {
5616    //$("body").find("div.modal-backdrop-filter").remove();
5617    // options button
5618    let buttonVal = $('.all-filter-count').attr('data-permanentval');
5619    if (buttonVal) {
5620        $('.all-filter-count').text(buttonVal);
5621        $('.filter-counter').text(buttonVal);
5622        $('.all-filter-count').parent().removeClass('disabled');
5623        $('.all-filter-error').addClass('d-none');
5624    }
5625    /*checkbox selector*/
5626    let checkBoxList = $('.filter-checkbox');
5627
5628    for (var index = 0; index < checkBoxList.length; index++) {
5629        var checkboxAnalyticsLabel = $(checkBoxList[index]).attr('data-labelanalytics');
5630        var checkboxAnalyticsValue = "";
5631
5632        $(checkBoxList[index]).find('li').each(function() {
5633            var checkboxVal = $(this).attr('data-value');
5634            var value = $(this).attr('data-permanentval');
5635            if (value != 'permanent') {
5636                if ($(this).find('.custom-checkbox .custom-control-input').attr("checked")) {
5637                    $(this).find('.custom-checkbox .custom-control-input').removeAttr("checked");
5638                    $(this).find('.custom-checkbox .custom-control-input').prop("checked", false);
5639                }
5640            } else if (value == 'permanent') {
5641                if (checkboxAnalyticsValue == "") {
5642                    checkboxAnalyticsValue = checkboxVal;
5643                } else {
5644                    checkboxAnalyticsValue = checkboxAnalyticsValue + "~" + checkboxVal;
5645                }
5646                if (!$(this).find('.custom-checkbox .custom-control-input').attr("checked")) {
5647                    $(this).find('.custom-checkbox .custom-control-input').attr("checked", "checked");
5648                    $(this).find('.custom-checkbox .custom-control-input').prop("checked", true);
5649                }
5650            }
5651        });
5652        checkboxAnalyticsValue = checkboxAnalyticsValue.replace(/ /g, "_").toLowerCase();
5653        checkBoxList[index].parentElement.parentElement.setAttribute("data-gtm-cta", checkboxAnalyticsLabel + checkboxAnalyticsValue);
5654    }
5655    /*rating selector*/
5656    if ($('.filter-rating').length > 0) {
5657        let ratingPermVal = $('.filter-rating').attr("data-permanentval");
5658        let ratingAnalyticsValue = "";
5659        let filterRatingTextAnalytics = $('.filter-rating').attr("data-labelanalytics");
5660        $('.filter-rating li').each(function() {
5661            let index = $(this).attr("data-index");
5662            if (index > ratingPermVal) {
5663                $(this).removeClass('filter-rating-green');
5664                $(this).removeClass('filter-rating-black');
5665                $(this).removeClass('selected');
5666            } else if (index < ratingPermVal) {
5667
5668                $(this).addClass('filter-rating-green');
5669                $(this).addClass('filter-rating-black');
5670                $(this).removeClass('selected');
5671            } else if (index === ratingPermVal) {
5672                $(this).addClass('filter-rating-green');
5673                $(this).addClass('filter-rating-black');
5674                $(this).addClass('selected');
5675                ratingAnalyticsValue = index;
5676            }
5677        });
5678        $('.filter-rating')[0].parentElement.parentElement.setAttribute("data-gtm-cta", filterRatingTextAnalytics + ratingAnalyticsValue);
5679    }
5680    /*range Selector*/
5681    if ($('.range-slider').length > 0) {
5682        var rangePermVal = $('.range-slider').attr("data-permanentval");
5683        var rangeAnalyticsValue = "";
5684        var filterRangeTextAnalytics = $('.range-slider').attr("data-labelanalytics");
5685        if (rangePermVal) {
5686            let sliderType = $('.slider').attr("data-type");
5687            let minVal = rangePermVal.split(',')[0];
5688            let maxVal = rangePermVal.split(',')[1];
5689            rangeAnalyticsValue = minVal + "-" + maxVal;
5690            let $sliderReset = $(".slider");
5691            $sliderReset.slider("values", 0, minVal);
5692            $sliderReset.slider("values", 1, maxVal);
5693            if (sliderType === "price") {
5694                $('.tooltip-min').text("$" + minVal);
5695                $('.tooltip-max').text("$" + maxVal);
5696            }
5697            if (sliderType === "data") {
5698                let maxRange = $('.slider').attr("data-maxrange");
5699                let showUnlimited = $('.slider').attr('data-showUnlimited');
5700                let unlimitedLabel = $('.slider').attr('data-unlimitedlabel');
5701                var minDataUnit = maxDataUnit = "MB";
5702                var minRangeDsp = minVal;
5703                var maxRangeDsp = maxVal;
5704                if (minVal >= 1024) {
5705                    minRangeDsp = (minVal / 1024).toFixed(1);
5706                    minDataUnit = "GB";
5707                }
5708                $(".tooltip-min").text(minRangeDsp + " " + minDataUnit).attr('data-minVal', minVal - 1);
5709                if (showUnlimited == "true" && maxVal == maxRange) {
5710                    $(".tooltip-max").text(unlimitedLabel).attr('data-maxVal', unlimitedLabel);
5711                } else {
5712                    if (maxVal >= 1024) {
5713                        maxRangeDsp = (maxVal / 1024).toFixed(1);
5714                        maxDataUnit = "GB";
5715                    }
5716                    $(".tooltip-max").text(maxRangeDsp + " " + maxDataUnit).attr('data-maxVal', maxVal + 1);
5717                }
5718            }
5719            if (sliderType === "text") {
5720                $('.tooltip-min').text(minVal);
5721                $('.tooltip-max').text(maxVal);
5722            }
5723            if (sliderType === "talk") {
5724                const minutes = $('.product-filter-container').getAttribute('data-lblminutes');
5725
5726                $('.tooltip-min').text(minVal + minutes );
5727                $('.tooltip-max').text(maxVal + minutes );
5728            }
5729
5730            var sliderCheckboxAnalyticsValue = "";
5731            $('.slider-checkboxes li').each(function() {
5732
5733                let value = $(this).attr('data-permanentval');
5734                let checkboxMin = $(this).attr('data-checkboxmin');
5735                let checkboxMax = $(this).attr('data-checkboxmax');
5736                if (value != 'permanent') {
5737                    if ($(this).find('.custom-checkbox .custom-control-input').attr("checked")) {
5738                        $(this).find('.custom-checkbox .custom-control-input').removeAttr("checked");
5739                        $(this).find('.custom-checkbox .custom-control-input').prop("checked", false);
5740                    }
5741                } else if (value == 'permanent') {
5742                    if (sliderCheckboxAnalyticsValue == "") {
5743                        sliderCheckboxAnalyticsValue = checkboxMin + "-" + checkboxMax;
5744                    } else {
5745                        sliderCheckboxAnalyticsValue = sliderCheckboxAnalyticsValue + "~" + checkboxMin + "-" + checkboxMax;
5746                    }
5747                    if (!$(this).find('.custom-checkbox .custom-control-input').attr("checked")) {
5748                        $(this).find('.custom-checkbox .custom-control-input').attr("checked", "checked");
5749                        $(this).find('.custom-checkbox .custom-control-input').prop("checked", true);
5750                    }
5751
5752                }
5753            });
5754
5755            if (sliderCheckboxAnalyticsValue != "") {
5756                $('.range-slider')[0].parentElement.parentElement.setAttribute("data-gtm-cta", filterRangeTextAnalytics + sliderCheckboxAnalyticsValue);
5757            } else {
5758                $('.range-slider')[0].parentElement.parentElement.setAttribute("data-gtm-cta", filterRangeTextAnalytics + rangeAnalyticsValue);
5759            }
5760        }
5761    }
5762});
5763/*Filter modal Close functioning*/
5764
5765/*Filter modal button functioning*/
5766$("#allFilterModal .all-filter-count").on("click", function() {
5767    //$("body").find("div.modal-backdrop-filter").remove();
5768    let clearfilter = document.querySelector('.clear-filter-accessibility').innerHTML;
5769    let badgeHtml = '  <div class="badges" data-id="{{id}}" data-type="{{type}}"><span class="badge-title caption-two">{{value}}</span><span role="button" tabindex="0" aria-label="{{clearfilter}} {{filtername}}" class="icon light-theme small-icon"><i class="clear"></i></span></div>';
5770    document.querySelector('.filter-badges').innerHTML = "";
5771    let totalCount = 0;
5772    /*checkboxes*/
5773    let filterCheckboxList = $(".filter-checkbox");
5774    $(".filter-checkbox").each(function(index) {
5775        let viewType = $(this).attr("data-selctedcheckboxview");
5776        let label = $(this).attr("data-label");
5777        let checkboxId = $(this).attr("id");
5778        let count = "";
5779        let checkboxList = filterCheckboxList[index].querySelectorAll('li');
5780        for (let j = 0; j < checkboxList.length; j++) {
5781
5782            if (checkboxList[j].querySelector('input').checked) {
5783                let id = checkboxList[j].querySelector('input').id;
5784                let selectedval = checkboxList[j].querySelector('p').innerText;
5785                checkboxList[j].setAttribute('data-permanentVal', 'permanent');
5786                if (viewType === "showseperate") {
5787                    totalCount = totalCount + 1;
5788                    let badge = badgeHtml.replaceAll("{{value}}", selectedval).replace("{{id}}", id).replace("{{type}}", "checkbox").replaceAll("{{clearfilter}}", clearfilter).replaceAll("{{filtername}}", selectedval);
5789                    document.querySelector('.filter-badges').insertAdjacentHTML('beforeend', badge);
5790                }
5791                count++;
5792            } else {
5793                checkboxList[j].removeAttribute('data-permanentVal');
5794            }
5795        }
5796        if (viewType === "showcount") {
5797            if (count != "") {
5798                totalCount = totalCount + 1;
5799                let badge = badgeHtml.replaceAll("{{value}}", label + " (" + count + ")").replace("{{id}}", checkboxId).replace("{{type}}", "checkboxlist").replaceAll("{{clearfilter}}", clearfilter).replaceAll("{{filtername}}", label + " (" + count + ")");
5800                document.querySelector('.filter-badges').insertAdjacentHTML('beforeend', badge);
5801            }
5802        }
5803
5804    });
5805
5806    /*range selector*/
5807    let rangeSelector = $('.range-slider');
5808    let labelRange = rangeSelector.attr("data-label");
5809    let sliderType = $('.slider').attr("data-type");
5810    if ($('.slider').hasClass("selectedRange")) {
5811        let rangeMin = rangeSelector.find('.tooltip-min').attr("data-minval");
5812        let rangeMax = rangeSelector.find('.tooltip-max').attr("data-maxval");
5813        let rangeMinLabel = rangeSelector.find('.tooltip-min').text();
5814        let rangeMaxLabel = rangeSelector.find('.tooltip-max').text();
5815        totalCount = totalCount + 1;
5816        let rangeBadge = badgeHtml.replaceAll("{{value}}", labelRange + " (" + rangeMinLabel + "-" + rangeMaxLabel + ")").replace("{{id}}", labelRange).replace("{{type}}", "rangeslider").replaceAll("{{clearfilter}}", clearfilter).replaceAll("{{filtername}}", labelRange + " (" + rangeMinLabel + "-" + rangeMaxLabel + ")");
5817        document.querySelector('.filter-badges').insertAdjacentHTML('beforeend', rangeBadge);
5818        if (sliderType === "data" || sliderType === "talk" || sliderType === "text") {
5819            rangeMin = +rangeMin + 1;
5820            rangeMax = rangeMax - 1;
5821            rangeSelector.attr('data-permanentVal', rangeMin + "," + rangeMax);
5822        } else {
5823            rangeSelector.attr('data-permanentVal', rangeMin + "," + rangeMax);
5824        }
5825    } else {
5826        rangeSelector.attr('data-permanentVal', $('.slider').attr("data-minrange") + "," + $('.slider').attr("data-maxrange"));
5827    }
5828
5829    let sliderCheckboxes = $('.slider-checkboxes li');
5830    for (let s = 0; s < sliderCheckboxes.length; s++) {
5831
5832        if (sliderCheckboxes[s].querySelector('input').checked) {
5833            let id = sliderCheckboxes[s].querySelector('input').id;
5834            let selectedval = sliderCheckboxes[s].querySelector('p').innerText;
5835            sliderCheckboxes[s].setAttribute('data-permanentVal', 'permanent');
5836            labelRange =  document.querySelector('.range-slider').getAttribute('data-label');
5837            totalCount = totalCount + 1;
5838            let badgeVal = labelRange + " (" + selectedval + ")";
5839            let badge = badgeHtml.replaceAll("{{value}}", badgeVal).replace("{{id}}", id).replace("{{type}}", "checkbox").replaceAll("{{clearfilter}}", clearfilter).replaceAll("{{filtername}}", badgeVal);
5840            document.querySelector('.filter-badges').insertAdjacentHTML('beforeend', badge);
5841
5842        } else {
5843            sliderCheckboxes[s].removeAttribute('data-permanentVal');
5844        }
5845    }
5846
5847    /* rating selector*/
5848    let ratingSelector = $('.filter-rating li.selected');
5849    let labelRating = $('.filter-rating').attr("data-label");
5850    let labelRatingSelected = $('.filter-rating').attr("data-ratinglabel");
5851    let labelRatingMaxSelected = $('.filter-rating').attr("data-maxratinglabel");
5852    let ratingId = $('.filter-rating').attr("id");
5853    if (ratingSelector.length > 0) {
5854        totalCount = totalCount + 1;
5855        let ratingValue = $('.filter-rating li.selected').attr('data-index');
5856        let ratingBadge = "";
5857        if (ratingValue === $('.filter-rating li').length) {
5858            ratingBadge = badgeHtml.replaceAll("{{value}}", labelRating + " ( " + ratingValue + " " + labelRatingMaxSelected + " )").replace("{{id}}", ratingId).replace("{{type}}", "ratingselector").replaceAll("{{clearfilter}}", clearfilter).replaceAll("{{filtername}}", labelRating + " ( " + ratingValue + " " + labelRatingMaxSelected + " )");
5859        } else {
5860            ratingBadge = badgeHtml.replaceAll("{{value}}", labelRating + " ( " + ratingValue + " " + labelRatingSelected + " )").replace("{{id}}", ratingId).replace("{{type}}", "ratingselector").replaceAll("{{clearfilter}}", clearfilter).replaceAll("{{filtername}}", labelRating + " ( " + ratingValue + " " + labelRatingMaxSelected + " )");
5861        }
5862        document.querySelector('.filter-badges').insertAdjacentHTML('beforeend', ratingBadge);
5863        $('.filter-rating').attr('data-permanentVal', ratingValue);
5864
5865    } else {
5866        $('.filter-rating').attr('data-permanentVal', "0");
5867    }
5868    /*options button*/
5869    $('.mobile-filter-count').text("(" + totalCount + ")");
5870    let optionButton = $('.all-filter-count').text();
5871    $('.all-filter-count').attr('data-permanentVal', optionButton);
5872});
5873/*Filter modal button functioning*/
5874
5875/*Filter Badges Start*/
5876$('body').on("click", ".filter-badges span.icon", function() {
5877    let id = $(this).parent('.badges').attr('data-id');
5878    let type = $(this).parent('.badges').attr('data-type');
5879
5880    if (type === 'checkbox') {
5881        $('.filters-container').find('#' + id).removeAttr("checked");
5882        $('.filters-container').find('#' + id).parent().parent().removeAttr("data-permanentval");
5883    }
5884    if (type === 'checkboxlist') {
5885
5886        let checkboxLi = $('.filters-container').find('#' + id).find('li');
5887        if (checkboxLi.length > 0) {
5888            checkboxLi.each(function() {
5889                $(this).removeAttr("data-permanentval");
5890                $(this).find('.custom-checkbox .custom-control-input').removeAttr("checked");
5891            });
5892        }
5893    }
5894    if (type === 'rangeslider') {
5895        $(".slider").each(function(){
5896            let sliderType = $(this).attr("data-type");
5897            let minVal = $(this).attr("data-minrange");
5898            let maxVal = $(this).attr("data-maxrange");
5899            var $sliderReset = $(this);
5900            $(".range-slider").attr('data-permanentVal', minVal + "," + maxVal);
5901            $(this).removeClass("selectedRange");
5902            $sliderReset.slider("values", 0, minVal);
5903            $sliderReset.slider("values", 1, maxVal);
5904            $(this).find('.tooltip-min').text($('.start-price').html());
5905            $(this).find('.tooltip-max').text($('.end-price').html());
5906        });
5907    }
5908    if (type === 'ratingselector') {
5909        let ratingLi = $('.filters-container').find('#' + id).find('li');
5910        $('.filter-rating').attr('data-permanentVal', "0");
5911        if (ratingLi.length > 0) {
5912            ratingLi.each(function() {
5913
5914                $(this).removeClass('filter-rating-green');
5915                $(this).removeClass('filter-rating-black');
5916                $(this).removeClass('selected');
5917
5918            });
5919        }
5920    }
5921    /*custom event*/
5922    this.dispatchEvent(new Event('closeBadge', {
5923        'bubbles': true
5924    }));
5925    $(".all-filter-count").removeAttr("data-permanentval");
5926    $(this).parent('.badges').remove();
5927    $(".toal-count").focus();
5928});
5929/*Filter Badges End*/
5930
5931/* To display smartpay preapproval banner */
5932
5933$("#sp-preapproval-banner").attr("style", "display:none");
5934$("#sp-preapproval-banner-pdp").attr("style", "display:none");
5935$("#overview").attr("banner-visible","false");
5936$(window).load(function () {
5937        var preApprovalValue = getCookieCommon("preApproval");
5938        if (preApprovalValue) {
5939            $(".cmp-experiencefragment--paypal-banner-plp-xf").attr("style", "display:none");
5940            $("#deals-monthly_payment_plan") && $("#deals-monthly_payment_plan").click();
5941            $("#monthly_payment_plan-monthly_payment_plan") && $("#monthly_payment_plan-monthly_payment_plan").click();
5942            $("#plan_de_pago_mensual-plan_de_pago_mensual") && $("#plan_de_pago_mensual-plan_de_pago_mensual").click();
5943            $("#ofertas-plan_de_pago_mensual") && $("#ofertas-plan_de_pago_mensual").click();
5944            $(".all-filter-count") && $(".all-filter-count").click();
5945            $('[value="emi"]') && $('[value="emi"]').click();
5946        }
5947});
5948
5949/* To switch button on smartpay preapproval banner */
5950$(document).on("click","#finance-phn-btn .btn", function(){
5951    $("#deals-monthly_payment_plan") && $("#deals-monthly_payment_plan").click();
5952    $("#ofertas-plan_de_pago_mensual") && $("#ofertas-plan_de_pago_mensual").click();
5953    $("#monthly_payment_plan-monthly_payment_plan") && $("#monthly_payment_plan-monthly_payment_plan").click();
5954    $("#plan_de_pago_mensual-plan_de_pago_mensual") && $("#plan_de_pago_mensual-plan_de_pago_mensual").click();
5955    $(".all-filter-count") &&  $(".all-filter-count").click();
5956    $(this).hide();
5957});
5958
5959$(document).on("click","#deals-monthly_payment_plan, #ofertas-plan_de_pago_mensual, #monthly_payment_plan-monthly_payment_plan, #plan_de_pago_mensual-plan_de_pago_mensual", function(){
5960    if($("#deals-monthly_payment_plan").prop('checked') || $("#ofertas-plan_de_pago_mensual").prop('checked') || $("#monthly_payment_plan-monthly_payment_plan").prop('checked') || $("#plan_de_pago_mensual-plan_de_pago_mensual").prop('checked')){
5961        $("#finance-phn-btn .btn").hide();
5962    }else {
5963        $("#finance-phn-btn .btn").show();
5964    }
5965});
5966
5967function replaceAsLowAs(scriptValue){
5968    $("p").each(function(){
5969        var html= $(this).html();
5970         if(html.indexOf("As low as")>=0){
5971             $(this).html(html.replace("As low as",scriptValue));
5972         } else if(html.indexOf("Desde solo")>=0) {
5973            $(this).html(html.replace("Desde solo",scriptValue));
5974         } else if(html.indexOf("As Low")>=0) {
5975            $(this).html(html.replace("As Low",scriptValue));
5976         }
5977     })
5978}
5979/**
5980 * This function will display the alert message for Free Phones when user select the Ineligible plan from Shop Plan Journey
5981 * 
5982 */
5983async function freePhoneAlert() {
5984    let buttonText = await getScriptingValueCommon('_BTN_OK');
5985    let modalDataObj = {
5986        heading: await getScriptingValueCommon('_ERR_FREE_PHONE_INELIGIBLE_PLAN_TITLE'),
5987        summary: await getScriptingValueCommon('_ERR_FREE_PHONE_INELIGIBLE_PLAN_BODY'),
5988        firstCtaLabel: buttonText,
5989        firstCtaEvent: 'document.dispatchEvent(new CustomEvent("openPDPModal",{"detail": {}}))',
5990        firstCtaLink: ' ',
5991        firstCtaAriaLabel: buttonText,
5992        firstCtaGtmText: buttonText,
5993        preventClose: "true"
5994    }
5995    $('#purchase-modal-box').modal('hide');
5996    document.dispatchEvent(new CustomEvent("ShowGenericPopup", {
5997        'bubbles': true,
5998        'detail': {
5999            "modalDataObj": modalDataObj
6000        }
6001    }));
6002}
6003
6004/**
6005 * This function is use to enable the message for portin/veriff disclaimer on PDP if verification screen is coming in purchase flow journey
6006 * @param {*} element 
6007 */
6008function setPortinDisclaimer(element) {
6009    const showportinflow = element.querySelector('#portInVerification')?.dataset?.showportinflow;
6010    if (showportinflow === TRUE_FLAG) {
6011        if (element.querySelector('#portInVerification-phone #portinverifysuccess'))
6012            element.querySelector('#portInVerification-phone #portinverifysuccess').style.display = 'block';
6013        if (element.querySelector('#portInVerification .portIn-disclosure2'))
6014            element.querySelector("#portInVerification .portIn-disclosure2").style.display = 'none';
6015        element.querySelector("#portInAddCartBtn")?.classList.remove("disabled");
6016        if (document.querySelector('.purchase-modal-box-footer .primary-btn')) {
6017            document.querySelector('.purchase-modal-box-footer .primary-btn').classList.remove('disabled');
6018        }
6019        window.portInAddToCartBtnDisabled = false;
6020        if (element.querySelector("#portInAddCartBtn .addToCartBtn"))
6021            element.querySelector("#portInAddCartBtn .addToCartBtn").setAttribute('aria-label', element.querySelector("#portInAddCartBtn .addToCartBtn").dataset.addtocarttext);
6022    }
6023}
6024
6025/**
6026 * This function will toggle the option if user choose the Free payment option from Phone PDP Page
6027 * * @params {STRING} - {@paymentType - payment type option} 
6028 */
6029async function setFreePhoneData(paymentType) {
6030    let element = document.querySelector('.phonedetail-price-container');
6031    element.querySelector('#addtocart .pp-disclaimer')?.classList.remove("pt-20");
6032    if (paymentType === LBL_FREE_OPTION) { 
6033        var offerType = $(".color-swatch .selected").attr("data-offertype");
6034        clearRadio('.zipapi-config .payment-type .custom-control-input');
6035        this.setClawBackInstructions(element,'.clawback-footnote',offerType,document.querySelector(lbl_dot_section_api_container)?.dataset?.enableveriffidentification,TRUE_FLAG);
6036        let hideVeriff = document.querySelector(".section-api-container")?.dataset.migrateverifftocart;
6037
6038        if(hideVeriff === 'true' && (offerType === lbl_offer_port_in || offerType === lbl_offer_veriff)) {
6039            element.querySelector('#portInVerification-phone')?.classList.add("d-none");
6040            document.querySelector("#portInAddCartBtn")?.classList.remove("disabled");
6041            window.portInAddToCartBtnDisabled = false;
6042
6043            //persist offer type to make add to cart call
6044            sessionStorage.setItem("great-price-offer-type",document.querySelector(".selected.imageChange")?.dataset?.offertype);
6045
6046            //if twp section is visible, hide it here
6047            document.querySelector("#twp-plan-details")?.classList?.add("d-none");
6048            document.querySelector(".legal-disclosure.pb-30.text-left.cart-footnote")?.classList?.add("d-none");
6049            document.querySelector("#addtocart")?.classList?.add("d-none");
6050            element.querySelector('#portInVerification')?.classList?.remove("d-none");
6051
6052        } else if (hideVeriff !== 'true' && (offerType === lbl_offer_port_in || offerType === lbl_offer_veriff)) {
6053            element.querySelector('#addtocart').classList.add("d-none");
6054            element.querySelector('#portInVerification')?.classList.remove("d-none");
6055            element.querySelector('#portInVerification-phone')?.classList.remove("d-none");
6056            this.setPortinDisclaimer(element);
6057            resetPortIn();
6058        } else if (offerType === lbl_offer_activation) {
6059            element.querySelector('#addtocart').classList.remove("d-none");
6060            element.querySelector('#portInVerification')?.classList.add("d-none");
6061            element.querySelector('#portInVerification-phone')?.classList.add("d-none");
6062            element.querySelector('#addtocart .zipapi-config .choice-card.upgrade')?.classList.add("d-none");
6063            element.querySelector('#addtocart .zipapi-config .upgradeNotEligible')?.classList.remove("d-none");
6064            element.querySelector('#addtocart .paypal-container')?.classList.remove("d-none");
6065            element.querySelector('#addtocart #cart-option-counter')?.classList.remove("d-none");
6066            element.querySelector('#addtocart .payment-type-heading')?.classList.remove("d-none");
6067            element.querySelector('#addtocart .cart-footnote')?.classList.remove("d-none");
6068            element.querySelector('#addtocart .choice-cards')?.classList.remove("d-none");
6069            var addToCartElements = $('#addtocart .zipapi-config');
6070            if (addToCartElements != null && addToCartElements.length > 0) {
6071                addToCartElements[0]?.classList.remove("disabledPageContent");
6072                setAddToCartTabIndex();
6073            }           
6074        }
6075        
6076    } else {
6077        element.querySelector('#addtocart').classList.remove("d-none");
6078        element.querySelector('#portInVerification')?.classList.add("d-none");
6079        element.querySelector('#portInVerification-phone')?.classList.add("d-none");
6080        element.querySelector('#addtocart .zipapi-config .choice-card.upgrade')?.classList.remove("d-none");
6081        element.querySelector('#addtocart .zipapi-config .upgradeNotEligible')?.classList.add("d-none");
6082        element.querySelector('#addtocart .paypal-container')?.classList.remove("d-none");
6083        element.querySelector('#addtocart .payment-type-heading')?.classList.remove("d-none");
6084        element.querySelector('#addtocart .cart-footnote')?.classList.remove("d-none");
6085        if(document.querySelector('.section-api-container')?.dataset?.brand?.toUpperCase() !== 'TOTAL_WIRELESS') {
6086            element.querySelector('#addtocart .choice-cards')?.classList.remove("d-none");
6087            element.querySelector('#addtocart #cart-option-counter')?.classList.remove("d-none");
6088        }
6089        var addToCartElements = $('#addtocart .zipapi-config');
6090        if (addToCartElements != null && addToCartElements.length > 0) {
6091            addToCartElements[0]?.classList.remove("disabledPageContent");
6092            setAddToCartTabIndex();
6093        }    
6094
6095        element.querySelector("#addtocart .clawback-footnote")?.classList.add("d-none");  
6096    }
6097
6098    let enableDcotPromoOffers = document.querySelector('.section-api-container')?.dataset?.enabledcotpromooffers;
6099    const dcotModelName = document.querySelector(".phonedetail-price-container")?.dataset.dcotmodelname;
6100    const enabledcotpaymentoptionposition = document.querySelector(".phonedetail-price-container")?.dataset.enabledcotpaymentoptionposition;
6101
6102    if(enableDcotPromoOffers && dcotModelName && enabledcotpaymentoptionposition &&
6103        enabledcotpaymentoptionposition == "true") {
6104        if($('.payment-option-ex .custom-control-input:checked').val() == "full-price"){
6105            element.querySelector(".dcot-full-price-promo.dcot-full-price-promo-payment-section")?.classList.remove("d-none");
6106            element.querySelector(".dcot-full-price-promo.dcot-full-price-promo-payment-section .offer-details-link")?.classList.remove("d-none");
6107        } else {
6108            element.querySelector(".dcot-full-price-promo.dcot-full-price-promo-payment-section")?.classList.add("d-none");
6109        }
6110    }
6111
6112}
6113/**
6114   * Function to unchecked the radio button
6115   * @params {STRING} - {@elementClass - element class name                         
6116   * }
6117   **/
6118function clearRadio(elementClass) {
6119    let radio = document.querySelectorAll(elementClass);
6120    for (let index = 0; index < radio.length; index++) {
6121        radio[index].checked = false;
6122        radio[index]?.closest('.choice-card')?.classList.remove("selected");
6123        var custType = document.querySelector(elementClass)?.closest('input')?.value;
6124        if (custType != 'upgrade' && document.querySelector('#phoneNo')) {
6125            document.querySelector('#phoneNo').setAttribute('tabindex', '-1');
6126            document.querySelector('#phoneNo').value = '';
6127        }
6128    }
6129}
6130/**
6131   * Function to set the promotional offer Labels
6132   * @params {STRING,INT} - {@element - Element
6133   *                         @offertype - Type of promotional offer
6134   *                         @elemntClass - element Class
6135   *                         @label - label
6136  * }
6137   **/
6138function setOfferLabels(element,elemntClass,label,offertype,flag, _setDynamicPlansLabels){
6139
6140    if(label && label.includes('|')){
6141    let plantypes =  (document.querySelector('.promooffer-subheading')?.dataset?.planlabel) ? document.querySelector('.promooffer-subheading')?.dataset?.planlabel : '';
6142        if (element.querySelector(elemntClass)) {
6143            if (element.querySelector(elemntClass) && label  && (offertype == lbl_offer_port_in || offertype == lbl_offer_activation || offertype == lbl_offer_veriff)) {
6144                if (label.split('|').length > 1) {
6145                    if(label.split('|').length > 2){
6146                        if ((offertype == lbl_offer_port_in ) && !flag) {
6147                            element.querySelector(elemntClass).innerHTML = label.split('|')[0];
6148
6149                        } else if ((offertype == lbl_offer_activation) && !flag) {
6150                            element.querySelector(elemntClass).innerHTML = label.split('|')[1];
6151
6152                        } else if ((offertype == lbl_offer_veriff) && !flag) {
6153                            element.querySelector(elemntClass).innerHTML = label.split('|')[2];
6154                        }
6155                     } else {
6156
6157                        let price =  element.querySelector('.colorImageSwitch .imageChange.selected')?.dataset.tabprice?.toLowerCase();
6158
6159                        if(flag && price==="free")
6160                             element.querySelector(elemntClass).innerHTML = label.split('|')[0];
6161                        else
6162                            element.querySelector(elemntClass).innerHTML = label.split('|')[1];
6163                    }
6164                } else
6165                    element.querySelector(elemntClass).innerHTML = DOMPurify.sanitize(label);
6166
6167            } else {
6168                element.querySelector(elemntClass).innerHTML = "";
6169            }
6170
6171            let text = element.querySelector(elemntClass).innerHTML;
6172            if(_setDynamicPlansLabels) {
6173                const element = document.querySelector(".phonedetail-price-container");
6174                const orLabel = element?.dataset.orlabel;
6175                const higherlabel = element?.dataset.higherlabel;
6176                let updatedText = _setDynamicPlansLabels(text,null,orLabel, higherlabel, plantypes);
6177                element.querySelector(elemntClass).innerHTML = DOMPurify.sanitize(updatedText);
6178            }
6179        }
6180    }
6181}
6182/**
6183   * Function to set the Clawback instructions for promotional devices
6184   * @params {STRING,INT} - {@element - Element
6185   *                         @offertype - Type of promotional offer
6186   *                         @elemntClass - element Class
6187   *                         @label - label
6188  * }
6189   **/
6190async function setClawBackInstructions(element,elemntClass,offertype,enableVeriffIdentification,optionChangeFlag){
6191    let optionSelected= element.querySelector(".payment-option .choice-card.promo-offer")?.classList?.contains("selected");
6192    var enableClawBackInstr = document.querySelector(lbl_dot_section_api_container)?.dataset?.enableclawbackinstr;
6193    var enableCBIForDiscount = document.querySelector(lbl_dot_section_api_container)?.dataset?.enablecbifordiscount;
6194    var clawBackInstrForOffers= document.querySelector(lbl_dot_section_api_container)?.dataset?.clawbackinstrforoffers;
6195    if(enableClawBackInstr === TRUE_FLAG && clawBackInstrForOffers.includes(offertype)){
6196        let price =  element.querySelector('.colorImageSwitch .imageChange.selected')?.dataset.tabprice?.toLowerCase();
6197        let clawBackFlag = FALSE_FLAG;
6198        let freeLabel = document.querySelectorAll(".tabprice-free")[0]?.innerText?.toLowerCase();
6199        if(enableCBIForDiscount === TRUE_FLAG || price=== freeLabel){
6200            clawBackFlag = TRUE_FLAG;
6201        }
6202        if(clawBackFlag === TRUE_FLAG){
6203            var elementName,cfLabel,footNoteEle,cfVal;
6204            if((offertype == lbl_offer_port_in ) ){
6205                elementName= ".port-in-footnote "+ elemntClass;
6206                footNoteEle = elementName +" .footnote";
6207                cfLabel = "_LBL_CLAWBACK_INSTRUCTIONS_PORT_IN_OFFER";
6208            }else if((offertype == lbl_offer_veriff && enableVeriffIdentification === TRUE_FLAG)){
6209                elementName= ".veriff-footnote "+ elemntClass;
6210                footNoteEle = elementName +" .footnote";
6211                cfLabel = "_LBL_CLAWBACK_INSTRUCTIONS_VERIFF_OFFER";
6212            }else if((offertype == lbl_offer_activation && (optionSelected || optionSelected===TRUE_FLAG))){
6213                elementName= "#addtocart "+ elemntClass;
6214                footNoteEle = elementName;
6215                cfLabel = "_LBL_CLAWBACK_INSTRUCTIONS_ACTIVATION_OFFER";
6216            }
6217            cfVal = DOMPurify.sanitize(await getScriptingValueCommon(cfLabel))
6218            if(element.querySelector(footNoteEle))element.querySelector(footNoteEle).innerHTML=cfVal; 
6219            element.querySelector(elementName)?.classList.remove("d-none");              
6220
6221            if(optionChangeFlag=== FALSE_FLAG  && element.querySelector(".payment-option .offer-details-link")){
6222                let offerLink= document.querySelector(element.querySelector(".payment-option .offer-details-link").getAttribute("data-target"));
6223                if(offerLink){
6224                   let ultag = offerLink.getElementsByClassName('dynamic-desc')[0]?.querySelector("ul")
6225                    const li = document.createElement('li');
6226                    li.innerHTML = cfVal;	 
6227                    ultag?.appendChild(li);
6228                }
6229           }            
6230        }       
6231    }
6232}
6233
6234
6235function setDynamicPromoLabels(promoPlanPriceListItems, orLabel, orHigherLabel, _setDynamicPlansLabels, promoScriptText, element) {
6236
6237    let dcotPromoMessage;
6238    if($(".dcot-promo-subheading").length > 0){
6239        dcotPromoMessage = $(".dcot-promo-subheading").html();
6240     } else if(promoScriptText){
6241        dcotPromoMessage = promoScriptText;
6242     }
6243     let defaultModelName = $('.product-name').length > 0 ? $('.product-name').text() : "";
6244    const dcotModelName = element?.dataset.dcotmodelname ? element?.dataset.dcotmodelname : defaultModelName;
6245    const dcotMonthlyDisc = element?.dataset.dcotmonthlydisc;
6246    const dcotOfferEndDt = element?.dataset.dcotofferenddt;
6247    const dcotPaidAmt = element?.dataset.dcotpaidamt;
6248    const dcotTotalMonthText = element?.dataset.dcottotalmonthtext;
6249    const dcotSaving = element?.dataset.dcotsaving;
6250    const enabledcotpaymentoptionposition = element.dataset.enabledcotpaymentoptionposition ? element.dataset.enabledcotpaymentoptionposition : "false";
6251
6252    if (dcotPromoMessage) {
6253        dcotPromoMessage = dcotPromoMessage.replace(/{{monthlyDisc}}/g, dcotMonthlyDisc).replace(/{{totalMonths}}/g, dcotTotalMonthText).replace(/{{offerEndDate}}/g, dcotOfferEndDt).replace(/{{saving}}/g, dcotSaving).replace(/{{paidAmt}}/g, dcotPaidAmt).replace(/{{phone-name}}/g, dcotModelName);
6254        dcotPromoMessage = _setDynamicPlansLabels(dcotPromoMessage,promoPlanPriceListItems,orLabel, orHigherLabel,)
6255        dcotPromoMessage = updateDcotDynamicLabels(dcotPromoMessage);
6256        let dcotPromoMessagehtml = '<div class="dcot-promobanner"><span class="pdp-dcot-promo-text-icon"></span><span class="promo-msg bold">'+dcotPromoMessage +"</span></div>";
6257        $(".promooffer-subheading").html(dcotPromoMessagehtml);
6258        let targetEle = document.querySelector('.promooffer-subheading .promo-msg p') ? '.promooffer-subheading .promo-msg p' : '.promooffer-subheading .promo-msg'
6259        this.setOfferDetailLink(element,dcotPromoMessage,targetEle," .dcot-offer-details-link");
6260
6261        if($(".promooffer-subheading-mob div").length > 0){
6262            $(".promooffer-subheading-mob div").html(dcotPromoMessagehtml);
6263            let targetElemob = document.querySelector('.promooffer-subheading-mob .promo-msg p') ? '.promooffer-subheading-mob .promo-msg p' : '.promooffer-subheading-mob .promo-msg'
6264
6265            this.setOfferDetailLink(element,dcotPromoMessage, targetElemob, ".dcot-offer-details-link");
6266        }
6267    }
6268    if($(".dcot-promo-offer-data .offer-desc").length > 0){
6269    let dynamicTitleBody = $(".dcot-promo-offer-data .offer-desc").html();
6270    dynamicTitleBody = dynamicTitleBody.replace(/{{monthlyDisc}}/g, dcotMonthlyDisc).replace(/{{totalMonths}}/g, dcotTotalMonthText).replace(/{{offerEndDate}}/g, dcotOfferEndDt).replace(/{{saving}}/g, dcotSaving).replace(/{{paidAmt}}/g, dcotPaidAmt).replace(/{{phone-name}}/g, dcotModelName);
6271    dynamicTitleBody && $("#dcot-offer-box .modal-body .dynamic-desc").html(dynamicTitleBody);
6272    }
6273     if($(".dcot-promo-offer-data .offer-heading").length > 0){
6274        let dynamicModelTitle = $(".dcot-promo-offer-data .offer-heading").html();
6275        dynamicModelTitle = dynamicModelTitle.replace(/{{monthlyDisc}}/g, dcotMonthlyDisc).replace(/{{totalMonths}}/g, dcotTotalMonthText).replace(/{{offerEndDate}}/g, dcotOfferEndDt).replace(/{{saving}}/g, dcotSaving).replace(/{{paidAmt}}/g, dcotPaidAmt).replace(/{{phone-name}}/g, dcotModelName);
6276        dynamicModelTitle && $("#dcot-offer-box .modal-body .dynamic-title").html(dynamicModelTitle);
6277        }
6278
6279
6280    if ($("#dcot-offer-box .modal-body .dynamic-desc").length > 0) {
6281        let dcotOfferDetailBodyHtml = $("#dcot-offer-box .modal-body .dynamic-desc").html();
6282
6283        dcotOfferDetailBodyHtml = dcotOfferDetailBodyHtml.replace(/{{monthlyDisc}}/g, dcotMonthlyDisc).replace(/{{totalMonths}}/g, dcotTotalMonthText).replace(/{{offerEndDate}}/g, dcotOfferEndDt).replace(/{{saving}}/g, dcotSaving).replace(/{{paidAmt}}/g, dcotPaidAmt).replace(/{{phone-name}}/g, dcotModelName);
6284        dcotOfferDetailBodyHtml =  _setDynamicPlansLabels(dcotOfferDetailBodyHtml,promoPlanPriceListItems,orLabel, orHigherLabel);
6285		dcotOfferDetailBodyHtml = updateDcotDynamicLabels(dcotOfferDetailBodyHtml);
6286        $("#dcot-offer-box .modal-body .dynamic-desc").html(dcotOfferDetailBodyHtml);
6287        if($('#dcot-offer-box .button a.btn').length > 0){
6288            $('#dcot-offer-box .button a.btn').attr('data-dismiss', "modal");
6289        }
6290    }
6291
6292
6293    if ($(".dcot-full-price-promo")) {
6294        let dcotFullpriceOfferHtml = $(".dcot-full-price-promo").html();
6295        dcotFullpriceOfferHtml = dcotFullpriceOfferHtml.replace(/{{monthlyDisc}}/g, dcotMonthlyDisc).replace(/{{totalMonths}}/g, dcotTotalMonthText).replace(/{{offerEndDate}}/g, dcotOfferEndDt).replace(/{{saving}}/g, dcotSaving).replace(/{{paidAmt}}/g, dcotPaidAmt).replace(/{{phone-name}}/g, dcotModelName);
6296        dcotFullpriceOfferHtml =  _setDynamicPlansLabels(dcotFullpriceOfferHtml,promoPlanPriceListItems,orLabel, orHigherLabel);
6297        dcotFullpriceOfferHtml = updateDcotDynamicLabels(dcotFullpriceOfferHtml);
6298        $(".dcot-full-price-promo").html(dcotFullpriceOfferHtml);
6299        window.setOfferDetailLink(element,dcotFullpriceOfferHtml,'.dcot-full-price-promo.promo-detail-price .dcot-fullprice-promo-text'," .dcot-offer-details-link");
6300    }
6301    let enableDcotPromoOffers = document.querySelector('.section-api-container')?.dataset?.enabledcotpromooffers;
6302
6303    if(enableDcotPromoOffers && dcotModelName) {
6304            $('.dcot-promo-subheading')?.addClass('dcot-promobanner');
6305            $('.dcot-promo-subheading-mob')?.addClass('dcot-promo-banner-mob');
6306
6307        if(enabledcotpaymentoptionposition == "true"){
6308            $(".dcot-full-price-promo.promo-detail-price")?.addClass("d-none");
6309        } else {
6310            $(".dcot-full-price-promo.dcot-full-price-promo-payment-section")?.addClass("d-none");
6311            $(".dcot-full-price-promo.promo-detail-price")?.removeClass("d-none");
6312            $(".dcot-full-price-promo.promo-detail-price .offer-details-link")?.removeClass("d-none");
6313            $(".dcot-full-price-promo.promo-detail-price .offer-details-link")?.attr("aria-hidden", "false");
6314        }
6315
6316    }
6317
6318    let dynamicTitleHeader = $("#dcot-offer-box .modal-body .dynamic-title")?.html();
6319    if(dynamicTitleHeader && dynamicTitleHeader == ''){
6320        dynamicTitleHeader = $("#dcot-offer-box .modal-body .dynamic-title")?.html();
6321    }
6322    if(dynamicTitleHeader) {
6323        if(enableDcotPromoOffers && dcotModelName) {
6324           dynamicTitleHeader = dynamicTitleHeader.replace(/{{monthlyDisc}}/g, dcotMonthlyDisc).replace(/{{totalMonths}}/g, dcotTotalMonthText).replace(/{{offerEndDate}}/g, dcotOfferEndDt).replace(/{{saving}}/g, dcotSaving).replace(/{{paidAmt}}/g, dcotPaidAmt).replace(/{{phone-name}}/g, dcotModelName);
6325        }
6326        setTimeout(()=>{
6327            $("#dcot-offer-box .modal-body .dynamic-title").html(dynamicTitleHeader);
6328        },10);
6329    }
6330}
6331
6332function updateDcotDynamicLabels(promoText,dcotautorefillflag, dcotactivatenewline,dcotupgrade){
6333
6334    const element = document.querySelector(".phonedetail-price-container");
6335    if(promoText) {
6336        if(element) {
6337            dcotautorefillflag = element.dataset.dcotautorefillflag ? element.dataset.dcotautorefillflag : "";
6338            dcotactivatenewline = element.dataset.dcotactivatenewline ? element.dataset.dcotactivatenewline : "";
6339            dcotupgrade = element.dataset.dcotupgrade ? element.dataset.dcotupgrade : "";
6340        }
6341
6342        if(dcotautorefillflag && dcotautorefillflag == 'true') {
6343            promoText = promoText.replace(/{{autopay-st}}/g,"").replace(/{{autopay-end}}/g, "");
6344        } else {
6345            promoText = removeTextBetweenWords(promoText, "{{autopay-st}}", "{{autopay-end}}")
6346        }
6347
6348        if(dcotactivatenewline && dcotactivatenewline == 'true' && dcotupgrade && dcotupgrade == 'true') {
6349             promoText = promoText.replace(/{{newline-st}}/g,"").replace(/{{newline-end}}/g, "");
6350             promoText = promoText.replace(/{{upg-st}}/g,"").replace(/{{upg-end}}/g, "");
6351             promoText = promoText.replace(/{{newlineand-st}}/g,"").replace(/{{newlineand-end}}/g, "");
6352        } else if(!(dcotactivatenewline && dcotactivatenewline == 'true') && dcotupgrade && dcotupgrade == 'true'){
6353            promoText = removeTextBetweenWords(promoText, "{{newline-st}}", "{{newline-end}}");
6354            promoText = promoText.replace(/{{upg-st}}/g,"").replace(/{{upg-end}}/g, "");
6355        } else if(dcotactivatenewline && dcotactivatenewline == 'true' && !(dcotupgrade && dcotupgrade == 'true')){
6356            promoText = removeTextBetweenWords(promoText, "{{newlineand-st}}", "{{newlineand-end}}");
6357            promoText = promoText.replace(/{{newline-st}}/g,"").replace(/{{newline-end}}/g, "");
6358            promoText = removeTextBetweenWords(promoText, "{{upg-st}}", "{{upg-end}}");
6359          } else {
6360          promoText = removeTextBetweenWords(promoText, "{{upg-st}}", "{{upg-end}}");
6361          promoText = removeTextBetweenWords(promoText, "{{newline-st}}", "{{newline-end}}");
6362          }
6363      }
6364
6365    return promoText
6366}
6367
6368function removeTextBetweenWords(fullText, startText, endText){
6369    if(fullText && fullText.includes(startText) && fullText.includes(endText)){
6370        const startIndex = fullText.indexOf(startText);
6371        const endIndex = fullText.indexOf(endText)+endText.length;
6372        let returnString = fullText.slice(0, startIndex)+ fullText.slice(endIndex);
6373        if(returnString.indexOf(startText) != -1 && returnString.indexOf(endText) != -1){
6374            return removeTextBetweenWords(returnString, startText, endText)
6375        }
6376        return returnString;
6377    } else {
6378        return fullText;
6379    }
6380
6381}
6382
6383/**
6384   * Function to set the offer labels on images dynamically
6385   * @params {STRING,STRING} - {@element - Element
6386   *                         @label - label
6387   * }
6388   **/
6389function setImageBadge(element,label){
6390    if(element.querySelector("#phoneThumbnailImage li") && element.querySelector("#phoneThumbnailImage li").classList.contains('active')){ 
6391        $('#phoneImageCarousel .carousel-item.active').append("<div class='offer-price-img-badge d-none'>"+label+"</div>");
6392    }else
6393    {
6394        let childNode = element.querySelector(".offer-price-img-badge"); 
6395        if(childNode)element.querySelector("#phoneImageCarousel .carousel-item")?.removeChild(childNode);
6396    } 
6397}
6398/**
6399   * Function to set the offer labels on images dynamically
6400   * @params {STRING,STRING} - {@element - Element
6401   *                         @offertype - Type of promotional offer
6402   * }
6403   **/
6404async function setOfferLabelOnImage(element,offertype){
6405    let price =  element.querySelector('.colorImageSwitch .imageChange.selected')?.dataset.tabprice?.toLowerCase();
6406    let label;
6407    let freeLabel = document.querySelectorAll(".tabprice-free")[0]?.innerText?.toLowerCase();
6408    if( price=== freeLabel )
6409        label = await getScriptingValueCommon('_LBL_FREE_PRICE_OFFER_IMAGE_BADGE');
6410    else
6411        label = await getScriptingValueCommon('_LBL_GREAT_PRICE_OFFER_IMAGE_BADGE');
6412
6413   this.setImageBadge(element,label);
6414    let offerLabel = DOMPurify.sanitize(await getScriptingValueCommon(offertype+'_PHONE_SUB_HEADING'));
6415    let promoSubHeading = document.querySelector('.promooffer-subheading');
6416    if(promoSubHeading && promoSubHeading.getAttribute("data-promolabel")){
6417        offerLabel = promoSubHeading.getAttribute("data-promolabel");        
6418    }
6419
6420    let offerTypeVal = "";
6421    if(offertype == lbl_offer_veriff ) {
6422    offerTypeVal = 'veriff';
6423    } else if(offertype == lbl_offer_activation ) {
6424        offerTypeVal = "activation";
6425    } else if(offertype == lbl_offer_port_in ) {
6426              offerTypeVal = "port-in";
6427    }
6428
6429//    if(document.querySelector('.promooffer-subheading div') && offerLabel && !document.querySelector('.promooffer-subheading .promo-msg')){
6430    if(document.querySelector('.promooffer-subheading') && offerLabel ){
6431        document.querySelector('.promooffer-subheading').innerHTML = '<span class="promo-msg bold">'+offerLabel+'</span>';
6432        let targetele = document.querySelector('.promooffer-subheading .promo-msg p')? '.promooffer-subheading .promo-msg p' : '.promooffer-subheading .promo-msg';
6433        this.setOfferDetailLink(element,document.querySelector('.promooffer-subheading .promo-msg')?.innerHTML,targetele," .offer-details-link");
6434        if(offerTypeVal !== ""){
6435        document.querySelector('.promooffer-subheading .promo-msg .offer-details-link')?.setAttribute('data-target', '#'+offerTypeVal+'-offer-box');
6436        }
6437
6438    }
6439//    if(document.querySelector('.promooffer-subheading-mob') && offerLabel && !document.querySelector('.promooffer-subheading-mob .promo-msg')){
6440    if(document.querySelector('.promooffer-subheading-mob') && offerLabel ){
6441        document.querySelector('.promooffer-subheading-mob').innerHTML = '<span class="promo-msg bold">'+offerLabel+'</span>';
6442        let targetele = document.querySelector('.promooffer-subheading-mob .promo-msg p')? '.promooffer-subheading-mob .promo-msg p' : '.promooffer-subheading-mob .promo-msg';
6443        this.setOfferDetailLink(element,document.querySelector('.promooffer-subheading-mob .promo-msg')?.innerHTML,targetele," .offer-details-link");
6444        if(offerTypeVal !== ""){
6445            document.querySelector('.promooffer-subheading-mob .promo-msg .offer-details-link')?.setAttribute('data-target', '#'+offerTypeVal+'-offer-box');
6446        }
6447    }
6448}
6449/**
6450   * Function to add offer detail link dynamically in promo Label
6451   * @params {STRING,INT} - {@element - element
6452   *                         @offerLabel - promotional label
6453   *                         @targetElement - Target element
6454   * }
6455   **/
6456async function setOfferDetailLink(element,offerLabel,targetElement,targetElementClass){
6457
6458    if(offerLabel && offerLabel.includes("{{offerdetail}}") && element.querySelector(targetElement)){
6459       let new_element = element.querySelector('.payment-option '+targetElementClass)?.cloneNode(true);
6460       if(new_element) element.querySelectorAll(targetElement).forEach(updateElement => {updateElement.appendChild(new_element); });
6461
6462       let newContent= element.querySelector(targetElement).innerHTML.replace(/{{offerdetail}}/g,"");
6463       ele
6463ment.querySelectorAll(targetElement).forEach(updateElement => {updateElement.innerHTML = newContent; });
6464       let seeOfferLabel = await getScriptingValueCommon('_LBL_SEE_OFFER_DETAILS');
6465       if(seeOfferLabel && seeOfferLabel !='_LBL_SEE_OFFER_DETAILS' && element.querySelector(targetElement+' '+targetElementClass)){
6466       element.querySelectorAll(targetElement+' '+targetElementClass).forEach(updateElement => { updateElement.innerHTML = seeOfferLabel; });
6467       element.querySelector(targetElement+' '+targetElementClass)?.setAttribute("tabindex", "0");
6468       element.querySelector(targetElement+' '+targetElementClass)?.removeAttribute("aria-hidden");
6469       }
6470    }
6471}
6472
6473/**
6474   * Function to check if promotion available for product then enable the Free Payment option
6475   * @params {STRING,INT} - {@showsmartpay - showsmartpay flag 
6476   *                         @offertype - Type of promotional offer
6477   *                         @stockStatus - stock status 
6478   *                         @element - element
6479   *                         @isColorSelection - method call when clicked on color
6480   * }
6481   **/
6482var enableFreePaymentOption = async (showsmartpay, offertype, stockStatus, element, isColorSelection, _setDynamicPlansLabels) => {
6483    var prefixlabel = element.querySelector(".choice-card.promo-offer .prefixlabel")?.dataset.prefixlabel;
6484    var optionlabel = element.querySelector(".choice-card.promo-offer .optionlabel")?.dataset.optionlabel;
6485    var summarylabel = element.querySelector(".choice-card.promo-offer .summarylabel")?.dataset.summarylabel;
6486    var suffixLabel = element.querySelector(".choice-card.promo-offer .po-suffix")?.dataset.suffixlalel;
6487    var enableVeriffIdentification = document.querySelector(lbl_dot_section_api_container)?.dataset?.enableveriffidentification;
6488    const stepNo = 'step_no';
6489    let stepArray = [STEP_AVAILABLE_COLOR_CONTAINER];
6490    if (showsmartpay === 'true' || (offertype == lbl_offer_activation || offertype == lbl_offer_veriff || offertype == lbl_offer_port_in ) )
6491        stepArray.push(STEP_PAYMENT_OPTION);
6492    if (offertype == lbl_offer_port_in || offertype == lbl_offer_veriff)
6493        stepArray.push(STEP_PORT_IN_ADD_TO_CART);
6494    else
6495        stepArray.push(STEP_ADD_TO_CART);
6496    if(document.getElementById("upgrade-verify-code-block") && document.getElementById("upgradeFlagValue")?.value==="true")
6497        stepArray.push("verifyCode");
6498    await setStepNo(stepArray, stepNo);
6499    this.setOfferLabels(element,".choice-card.promo-offer .optionlabel",optionlabel,offertype,true, _setDynamicPlansLabels);
6500    this.setOfferLabels(element,".choice-card.promo-offer .summarylabel",summarylabel,offertype,false, _setDynamicPlansLabels);
6501    this.setOfferLabels(element,".choice-card.promo-offer .po-suffix",suffixLabel,offertype,false, _setDynamicPlansLabels);
6502    if (element.querySelector(".choice-card.promo-offer .prefixlabel") ) {
6503        if (element.querySelector(".choice-card.promo-offer .prefixlabel") && prefixlabel && element.querySelector(".offer-details-link") && (offertype == lbl_offer_port_in || offertype == lbl_offer_activation || offertype == lbl_offer_veriff)) {
6504            if (offertype == lbl_offer_port_in) {
6505                if(element.querySelector(".choice-card.promo-offer .prefixlabel-acc"))
6506                    element.querySelector(".choice-card.promo-offer .prefixlabel-acc").innerHTML = prefixlabel.split('|')[0];
6507                element.querySelector(".choice-card.promo-offer .prefixlabel").innerHTML = prefixlabel.split('|')[0];
6508                element.querySelector(".offer-details-link").setAttribute("data-target", element.querySelector(".offer-details-link")?.dataset.portinlink);
6509            }else if (offertype == lbl_offer_veriff) {
6510                if(element.querySelector(".choice-card.promo-offer .prefixlabel-acc"))
6511                    element.querySelector(".choice-card.promo-offer .prefixlabel-acc").innerHTML = prefixlabel.split('|')[2];
6512                element.querySelector(".choice-card.promo-offer .prefixlabel").innerHTML = prefixlabel.split('|')[2];
6513                element.querySelector(".offer-details-link").setAttribute("data-target", element.querySelector(".offer-details-link")?.dataset.verifflink);
6514            }             
6515            else {
6516                if(element.querySelector(".choice-card.promo-offer .prefixlabel-acc"))
6517                    element.querySelector(".choice-card.promo-offer .prefixlabel-acc").innerHTML = prefixlabel.split('|')[1];
6518                element.querySelector(".choice-card.promo-offer .prefixlabel").innerHTML = prefixlabel.split('|')[1];
6519                element.querySelector(".offer-details-link").setAttribute("data-target", element.querySelector(".offer-details-link")?.dataset.activationlink);
6520            }
6521            if(element.querySelector(".choice-card.promo-offer .
6521summary-acc") && element.querySelector(".choice-card.promo-offer .summarylabel"))
6522                element.querySelector(".choice-card.promo-offer .summary-acc").innerHTML = element.querySelector(".choice-card.promo-offer .summarylabel").innerHTML;
6523                    
6524        } else {
6525            if(element.querySelector(".choice-card.promo-offer .prefixlabel-acc"))
6526                    element.querySelector(".choice-card.promo-offer .prefixlabel-acc").innerHTML = "";  
6527            if(element.querySelector(".choice-card.promo-offer .summary-acc"))
6528                    element.querySelector(".choice-card.promo-offer .summary-acc").innerHTML="";              
6529            element.querySelector(".choice-card.promo-offer .prefixlabel").innerHTML = "";
6530        }
6531    }
6532
6533    if((offertype == lbl_offer_veriff && enableVeriffIdentification ==='true')){
6534        let portinverifysuccess = document.getElementById("portinverifysuccess");
6535        let headingText = portinverifysuccess?.dataset.hedingtext;
6536        let descriptionText = portinverifysuccess?.dataset.descriptiontext;
6537
6538        if(headingText && descriptionText){
6539            if(portinverifysuccess.querySelector('.promo-heading'))
6540                portinverifysuccess.querySelector('.promo-heading').innerHTML = headingText;
6541            if(portinverifysuccess.querySelector('.promo-desc')){
6542                portinverifysuccess.querySelector('.promo-desc').innerHTML = descriptionText;
6543				portinverifysuccess.querySelector('.promo-alert')?.setAttribute("aria-label",(headingText+" "+portinverifysuccess.querySelector('.promo-desc').innerText))            
6544			}
6545        } 
6546        portinverifysuccess.querySelector('.port-in-footnote')?.classList.add("d-none");
6547        portinverifysuccess.querySelector('.veriff-footnote')?.classList.remove("d-none");
6548
6549        let loggedInFN = portinverifysuccess.querySelector('.veriff-footnote .footnote-data .fn-li')?.innerHTML;
6550        let notLoggedInFN = portinverifysuccess.querySelector('.veriff-footnote .footnote-data .fn-nl')?.innerHTML;
6551        let loggedInVerifiedFN = portinverifysuccess.querySelector('.veriff-footnote .footnote-data .fn-lv')?.innerHTML;
6552        let isUserLoggedIn = await checkUserLoggedInCommon();
6553        if(isUserLoggedIn){
6554            let veriffStatus = window.decryptStringCommon(window.getCookieCommon(COOKIE_VERIFF_STATUS));                
6555            let veriffPurStatus = window.decryptStringCommon(window.getCookieCommon(COOKIE_VERIFF_PURCHASE_STATUS));
6556            if (veriffPurStatus && veriffPurStatus.indexOf("|") > -1){
6557                let veriffPurchaseStatus = veriffPurStatus.split("|")[0];
6558                
6559                if(veriffStatus===VERIFF_STATUS_APPROVED && veriffPurchaseStatus != VERIFF_STATUS_LIMIT_EXCEEDED){
6560                    portinverifysuccess.querySelector('.veriff-footnote .cart-footnote .footnote-dynamic').innerHTML = DOMPurify.sanitize(loggedInVerifiedFN);
6561                }
6562                else
6563                    portinverifysuccess.querySelector('.veriff-footnote .cart-footnote .footnote-dynamic').innerHTML = DOMPurify.sanitize(loggedInFN);
6564            }
6565        }else if(portinverifysuccess.querySelector('.veriff-footnote .cart-footnote .footnote-dynamic')){
6566            portinverifysuccess.querySelector('.veriff-footnote .cart-footnote .footnote-dynamic').innerHTML = notLoggedInFN;
6567        }
6568     }
6569    this.setClawBackInstructions(element,'.clawback-footnote',offertype,enableVeriffIdentification,FALSE_FLAG);    
6570    if(offertype == lbl_offer_port_in || offertype == lbl_offer_activation || offertype == lbl_offer_veriff)
6571        this.setOfferLabelOnImage(element,offertype);
6572    let hidedropDown = 'false';
6573    if(element.querySelector('.other-options-accordion'))
6574        hidedropDown=element.querySelector('.other-options-accordion').getAttribute("data-hidepodropdown");
6575    if(element.querySelector('.payment-type .choice-card.selected input')?.value==="upgrade" && (offertype == lbl_offer_port_in || offertype == lbl_offer_activation || (offertype == lbl_offer_veriff && enableVeriffIdentification ==='true')) ){
6576        //added below code to handle the upgrade Scenario for promotional offers
6577        element.querySelector('.payment-option-ex')?.classList.remove("d-none");
6578        if ($('.payment-option-ex .custom-control-input:checked').val() === 'promo=offer' && isColorSelection) clearRadio('.payment-option-ex .custom-control-input');
6579    }else if (showsmartpay == 'true' && (offertype == lbl_offer_port_in || offertype == lbl_offer_activation || (offertype == lbl_offer_veriff && enableVeriffIdentification ==='true'))) {
6580        //hide other payment options accordion, if smart pay is not there 
6581        element.querySelector('.promoofferdisable')?.classList.remove("d-none");
6582        if(hidedropDown != 'true'){
6583            element.querySelector('.other-options-accordion')?.classList.remove("d-none");
6584            if (!(document.querySelector('.payment-option .choice-card.full-price .custom-control-input')?.checked || document.querySelector('.payment-option .choice-card.emi .custom-control-input')?.checked)) {
6585                element.querySelector('.other-payment-options-container')?.classList.add("collapse");
6586            }
6587        }
6588        element.querySelector('#addtocart')?.classList.add("d-none");
6589        element.querySelector('#portInVerification')?.classList.remove("d-none");
6590        element.querySelector('#portInVerification-phone')?.classList.add("d-none");
6591        if (isColorSelection) {
6592            setEnablePaymentOptionsElement();
6593            element.querySelector(".choice-card.promo-offer")?.classList.remove("d-none");
6594            clearRadio('.payment-option-ex .custom-control-input');
6595        }
6596        element.querySelector('#addtocart .pp-disclaimer')?.classList.add("pt-20");
6597        element.querySelector('.offer-details-link ')?.classList.remove("d-none");
6598        element.querySelector('.offer-details-link ')?.setAttribute("tabindex", "0");
6599        element.querySelector('.offer-details-link ')?.setAttribute("aria-hidden", "false");
6600    } else if (showsmartpay == 'true' && (offertype == "" || offertype == undefined || offertype == null || (offertype == lbl_offer_veriff && enableVeriffIdentification !='true'))) {
6601        //hide other payment options accordion, if smart pay is not there 
6602        element.querySelector('.promoofferdisable')?.classList.add("d-none");
6603        if(hidedropDown != 'true'){
6604        element.querySelector('.other-options-accordion')?.classList.add("d-none");
6605        element.querySelector('.other-payment-options-container')?.classList.remove("collapse");
6606        }
6607        element.querySelector('#addtocart')?.classList.remove("d-none");
6608        element.querySelector('#portInVerification')?.classList.add("d-none");
6609        element.querySelector('#portInVerification-phone')?.classList.add("d-none");
6610        element.querySelector(".choice-card.promo-offer")?.classList.add("d-none");
6611        if (stockStatus && stockStatus.toLowerCase() != UNAVAILABLE) 
6612        setEnablePaymentOptionsElement();
6613        element.querySelector('.offer-details-link ')?.classList.add("d-none");
6614        element.querySelector('.offer-details-link ')?.setAttribute("tabindex", "-1");
6615        element.querySelector('.offer-details-link ')?.setAttribute("aria-hidden", "true");
6616        if ($('.payment-option-ex .custom-control-input:checked').val() === 'promo=offer' && isColorSelection) clearRadio('.payment-option-ex .custom-control-input');
6617    } else if (showsmartpay == 'false' && (offertype == lbl_offer_port_in || offertype == lbl_offer_activation || (offertype == lbl_offer_veriff && enableVeriffIdentification ==='true'))) {
6618        element.querySelector('.payment-option-ex')?.classList.remove("d-none");
6619        setEnablePaymentOptionsElement();
6620        document.querySelector("#twp-protection-plan-banner")?.classList?.add("d-none");
6621        //hide other payment options accordion, if smart pay is not there 
6622        element.querySelector('.promoofferdisable')?.classList.remove("d-none");
6623        if(hidedropDown != 'true'){
6624        element.querySelector('.other-options-accordion')?.classList.add("d-none");
6625        element.querySelector('.other-payment-options-container')?.classList.remove("collapse");
6626        }
6627        if (offertype == lbl_offer_port_in || offertype == lbl_offer_veriff) {
6628            element.querySelector('#addtocart')?.classList.add("d-none");
6629            element.querySelector('#portInVerification')?.classList.remove("d-none");
6630            element.querySelector('#portInVerification-phone')?.classList.add("d-none");
6631        }
6632        if (offertype == lbl_offer_activation) {
6633            element.querySelector('#addtocart')?.classList.remove("d-none");
6634            element.querySelector('#portInVerification')?.classList.add("d-none");
6635            element.querySelector('#portInVerification-phone')?.classList.add("d-none");
6636            element.querySelector('#addtocart .paypal-container')?.classList.add("d-none");
6637            element.querySelector('#addtocart #cart-option-counter')?.classList.add("d-none");
6638            element.querySelector('#addtocart .payment-type-heading')?.classList.add("d-none");
6639            element.querySelector('#addtocart .cart-footnote')?.classList.add("d-none");
6640            element.querySelector('#addtocart .choice-cards')?.classList.add("d-none");
6641        }
6642        element.querySelector(".choice-card.promo-offer")?.classList.remove("d-none");
6643        
6644        if (element.querySelector('#paymentOption').classList.contains("disabledPageContent")) {
6645            element.querySelector('#paymentOption')?.classList.remove("disabledPageContent");
6646            setEnablePaymentOptionsElement();
6647        }
6648        element.querySelector(".choice-card.emi")?.classList.add("d-none");
6649        element.querySelector('.smart-pay-link')?.classList.add("d-none");
6650        element.querySelector('.smart-pay-link')?.setAttribute("tabindex", "-1");
6651        element.querySelector('.smart-pay-link')?.setAttribute("aria-hidden", "true");
6652        if (isColorSelection) clearRadio('.payment-option-ex .custom-control-input');
6653        element.querySelector('#addtocart .pp-disclaimer')?.classList.add("pt-20");
6654        element.querySelector('.offer-details-link ')?.classList.remove("d-none");
6655        element.querySelector('.offer-details-link ')?.setAttribute("tabindex", "0");
6656        element.querySelector('.offer-details-link ')?.setAttribute("aria-hidden", "false");
6657
6658        /* Disable the Select button in PDP Overlay */
6659        if(document.querySelector('.purchase-modal-box-footer .primary-btn') && !document.querySelector('.payment-option .custom-control-input:checked ~ .custom-control-label') 
6660        && document.querySelector('.colorImageSwitch .imageChange.selected') 
6661        && (document.querySelector('.colorImageSwitch .imageChange.selected').dataset.offertype === lbl_offer_veriff  || document.querySelector('.colorImageSwitch .imageChange.selected').dataset.offertype === lbl_offer_port_in || document.querySelector('.colorImageSwitch .imageChange.selected').dataset.offertype === lbl_offer_activation)){
6662            document.querySelector('.purchase-modal-box-footer .primary-btn').classList.add('disabled');   
6663            const disabledLabel = document.querySelector('.purchase-modal-box-footer .primary-btn a').getAttribute('data-add-cart-accessible');
6664            document.querySelector('.purchase-modal-box-footer .primary-btn a').setAttribute("aria-label", disabledLabel);
6665            if(document.querySelector('div#paymentOption') && document.querySelector('div#paymentOption').classList.contains("disabledPageContent"))  {
6666                document.querySelector('div#paymentOption').classList.remove("disabledPageContent");
6667            }                            
6668        }
6669
6670    } else if (showsmartpay == 'false' && (offertype == "" || offertype == undefined || offertype == null || (offertype == lbl_offer_veriff && enableVeriffIdentification !='true'))) {
6671        //hide other payment options accordion, if smart pay is not there 
6672        element.querySelector('.payment-option-ex')?.classList.add("d-none");
6673        element.querySelector('.promoofferdisable')?.classList.add("d-none");
6674        if(hidedropDown != 'true'){
6675        element.querySelector('.other-options-accordion')?.classList.add("d-none");
6676        element.querySelector('.other-payment-options-container')?.classList.remove("collapse");
6677        }
6678        element.querySelector('#addtocart')?.classList.remove("d-none");
6679        element.querySelector('#portInVerification')?.classList.add("d-none");
6680        element.querySelector('#portInVerification-phone')?.classList.add("d-none");
6681        if (!element.querySelector('#paymentOption')?.classList.contains("disabledPageContent")) {
6682            element.querySelector('#paymentOption')?.classList.add("disabledPageContent");
6683            setDisabledPaymentOptionsElement();
6684        }
6685        element.querySelector(".choice-card.emi")?.classList.add("d-none");
6686        element.querySelector('.smart-pay-link')?.classList.add("d-none");
6687        element.querySelector('.smart-pay-link')?.setAttribute("tabindex", "-1");
6688        element.querySelector('.smart-pay-link')?.setAttribute("aria-hidden", "true");
6689        element.querySelector('.offer-details-link ')?.classList.add("d-none");
6690        element.querySelector('.offer-details-link ')?.setAttribute("tabindex", "-1");
6691        element.querySelector('.offer-details-link ')?.setAttribute("aria-hidden", "true");
6692        var colorSelectedElement = element.querySelector('.color-swatch .selected');
6693        if (colorSelectedElement != null && colorSelectedElement != undefined) {
6694            if (element.querySelector('#addtocart .zipapi-config')?.classList.contains("disabledPageContent")) {
6695                element.querySelector('#addtocart .zipapi-config')?.classList.remove("disabledPageContent");
6696                setEnableAddToCartElement();
6697            }
6698        }
6699    }
6700
6701    if (stockStatus && stockStatus.toLowerCase() === UNAVAILABLE) {
6702        element.querySelector('#paymentOption').classList.add("disabledPageContent");
6703        setDisabledPaymentOptionsElement();
6704        element.querySelector('.zipapi-config').classList.add("disabledPageContent");
6705        setDisabledAddToCartElement();       
6706    }
6707    if(window.getCookieCommon(COOKIE_VERIFF_DATA) && (offertype == lbl_offer_veriff && enableVeriffIdentification ==='true') && document.querySelector('.other-options-accordion')){
6708        window.deleteCookieCommon(COOKIE_VERIFF_DATA);
6709        if(!document.querySelector('.other-options-accordion').classList.contains("d-none")) document.querySelector('.other-payment-options-container-toggle').click();;
6710    } 
6711    if((offertype === lbl_offer_veriff && enableVeriffIdentification ==='true')|| offertype == lbl_offer_activation || offertype == lbl_offer_port_in )
6712        this.disableFreePromoOption(element,offertype,enableVeriffIdentification);        
6713
6714}
6715/**
6716 * This function will disable the free option if user chosen the $30 or $40 plan in shop plan journey
6717 * * @params {STRING} - {@element - Element} 
6718 */
6719async function disableFreePromoOption(element){
6720     /* Disable the Free option in PDP Overlay */
6721      let planLSData = window.localStorage.getItem("plan");
6722        if(document.querySelector('#purchase-modal-box') && planLSData){
6723            let planLS = JSON.parse(planLSData);
6724            let planLSDetails = Array.isArray(planLS) ? planLS[0] : planLS;
6725            let freeOptHideflag = true;
6726            if (planLSDetails) {
6727                let skuId = document.querySelector('.colorImageSwitch .imageChange.selected')?.dataset.promoplanids;
6728                const skuIdarray = skuId ? skuId.split(",") : [];
6729                if (skuIdarray.includes(planLSDetails.skuPartNo)) {
6730                    freeOptHideflag = false;
6731                }
6732            }
6733            if (planLSDetails && freeOptHideflag)  {
6734                var poElements = element.querySelectorAll('.payment-option.choice-cards .choice-card.promo-offer .custom-control-input')
6735                for (let index = 0; index < poElements.length; index++) {
6736                    poElements[index].setAttribute("tabindex","-1");
6737                    poElements[index].setAttribute("aria-hidden","true");
6738                    poElements[index].setAttribute("disabled","");
6739                }
6740                element.querySelector(".payment-option.choice-cards .choice-card.promo-offer")?.classList.add("disabledRadioContent");
6741               if(!element.querySelector('.other-options-accordion')?.classList.contains("d-none")) 
6742                element.querySelector('.other-payment-options-container-toggle')?.click();
6743                element.querySelector(".payment-option.choice-cards .promo-plan-ineligible")?.classList.remove("d-none");                
6744                let promoPlanLink =  element.querySelector(".payment-option.choice-cards .promo-plan-ineligible a");
6745                if( promoPlanLink){
6746                    promoPlanLink.removeAttribute("tabindex");
6747                    promoPlanLink.removeAttribute("aria-hidden");
6748                    promoPlanLink.removeAttribute("disabled");
6749                }
6750            }else{
6751                element.querySelector(".payment-option.choice-cards .choice-card.promo-offer")?.classList.remove("disabledRadioContent");
6752                var poElements = element.querySelectorAll('.payment-option.choice-cards .choice-card.promo-offer .custom-control-input')
6753                for (let index = 0; index < poElements.length; index++) {
6754                    poElements[index].removeAttribute("tabindex");
6755                    poElements[index].removeAttribute("aria-hidden");
6756                    poElements[index].removeAttribute("disabled");
6757                }
6758            }
6759        } 
6760}
6761
6762/**
6763* Function to set the disabled the payment options radio buttons in case of stock not available
6764* }
6765**/
6766function setDisabledPaymentOptionsElement() {
6767    var paymentOptionElements = document.querySelectorAll('#paymentOption .choice-cards .choice-card .custom-control-input')
6768    for (let index = 0; index < paymentOptionElements.length; index++) {
6769        paymentOptionElements[index].setAttribute("tabindex", "-1");
6770        paymentOptionElements[index].setAttribute("aria-hidden", "true");
6771        paymentOptionElements[index].setAttribute("disabled", "");
6772    }
6773    document.querySelector('#paymentOption .choice-cards .smart-pay-link')?.setAttribute("tabindex", "-1");
6774    document.querySelector('#paymentOption .choice-cards .smart-pay-link')?.setAttribute("aria-hidden", "true");
6775}
6776/**
6777* Function to set the disabled the add to cart radio buttons in case of stock not available
6778* }
6779**/
6780function setDisabledAddToCartElement() { 
6781    var addToCartInputElements = document.querySelectorAll('#addtocart .zipapi-config .choice-cards .choice-card .custom-control-input')
6782    for (let index = 0; index < addToCartInputElements.length; index++) {
6783        addToCartInputElements[index].setAttribute("tabindex", "-1");
6784        addToCartInputElements[index].setAttribute("aria-hidden", "true");
6785        addToCartInputElements[index].setAttribute("disabled", "");
6786    }
6787    document.querySelector('#addtocart .zipapi-config .legal-disclosure .legal')?.setAttribute("aria-hidden", "true");
6788}
6789/**
6790* Function to set the enable the add to cart radio buttons in case of stock available
6791* }
6792**/
6793function setEnableAddToCartElement() {
6794    var addToCartInputElements = document.querySelectorAll('#addtocart .zipapi-config .choice-cards .choice-card .custom-control-input')
6795    for (let index = 0; index < addToCartInputElements.length; index++) {
6796        addToCartInputElements[index].removeAttribute("tabindex");
6797        addToCartInputElements[index].removeAttribute("aria-hidden");
6798        addToCartInputElements[index].removeAttribute("disabled");
6799    }
6800    document.querySelector('#phoneNo')?.removeAttribute("tabindex");
6801    document.querySelector('#addtocart .zipapi-config .legal-disclosure .legal')?.removeAttribute("aria-hidden");
6802}
6803
6804/**
6805* Function to set the enable the Payment options radio buttons in case of stock available
6806* }
6807**/
6808function setEnablePaymentOptionsElement() {
6809    var paymentOptionElements = document.querySelectorAll('#paymentOption .choice-cards .choice-card .custom-control-input')
6810    for (let index = 0; index < paymentOptionElements.length; index++) {
6811        paymentOptionElements[index].removeAttribute("tabindex");
6812        paymentOptionElements[index].removeAttribute("aria-hidden");
6813        paymentOptionElements[index].removeAttribute("disabled");
6814    }
6815    document.querySelector('#paymentOption .choice-cards .smart-pay-link')?.removeAttribute("aria-hidden");
6816    document.querySelector('#paymentOption .choice-cards .smart-pay-link')?.removeAttribute("tabindex");
6817}
6818
6819
6820/**
6821 * Function to set Step numbers for PDP pages. Array must be unique IDs and/or ClassNames.
6822 * @param {*String_Array} - parentDivArray 
6823 * @param {*String} - stepClassName 
6824 */
6825var setStepNo = async (parentDivArray, stepClassName) => {
6826    if (parentDivArray && Array.isArray(parentDivArray) && stepClassName) {
6827        const len = parentDivArray.length;
6828        if (len && len > 1) {
6829            let newHtml = await getScriptingValueCommon('_LBL_STEP_OF_TOTAL');
6830            parentDivArray.map((div, i) => {
6831                let newDiv = document.querySelector(`#${div}`) ?
6832                    document.querySelector(`#${div} .${stepClassName}`) :
6833                    document.querySelector(`.${div} .${stepClassName}`);
6834                if (newDiv && newHtml) {
6835                    newDiv.innerHTML = DOMPurify.sanitize(newHtml.replace("{{index}}", i + 1).replace("{{total}}", len));
6836                }
6837            })
6838        }
6839    }
6840}
6841
6842
6843/**
6844* Function to reset the port in section if user switches payment option or checking with another number
6845* }
6846**/
6847function resetPortIn(){
6848    let portInPhoneNo = document.getElementById("portInPhoneNo");
6849    let portinverifysuccess = document.getElementById("portinverifysuccess");
6850    let portinverifyerror = document.getElementById("portinverifyerror");
6851    let portInPhoneNoBtn = document.querySelector(".portInPhoneNoBtn");
6852    let portinverifiycode = document.getElementById("portinverifiycode");
6853    let portInFootNote = document.querySelector(".portIn-disclosure2");
6854    let portInVerifyCodeInput = document.querySelector("#portInVerificationCode");
6855    let portInFailureMsg = document.getElementById("port-in-failure-msg");
6856    let portInResendOtpError = document.getElementById("resend-otp-error-section");
6857    document.getElementById("portInVerification-phone")?.classList?.remove("portin-success-container");  
6858    if(portInPhoneNo){
6859        portInPhoneNo.value="";
6860        portInVerifyCodeInput.value="";
6861        portInPhoneNo.dispatchEvent(new KeyboardEvent('keyup', {'key': ''}));
6862        portInVerifyCodeInput.dispatchEvent(new KeyboardEvent('keyup', {'key': ''}));
6863        portInVerifyCodeInput?.classList.remove("success");
6864        portInVerifyCodeInput?.classList.remove("error");
6865        document.querySelector(".verification-code-error")?.classList?.add("d-none");
6866        document.querySelector(".verification-code-error .error-text").innerHTML="";
6867        portInResendOtpError.style.display='none';
6868        $("#btnPortInVerifyCodeIdentity").attr("disabled",true);
6869        document.querySelector("#phonumber-block").classList="";
6870        document.querySelector(".resend-port-in-section").style.display='block';
6871        portinverifiycode.style.display='none';
6872        portinverifysuccess.style.display='none';
6873        portinverifyerror.style.display='none';
6874        if(portInFailureMsg)portInFailureMsg.style.display='none';
6875        if(portInFootNote)portInFootNote.style.display='block';
6876        document.getElementById("portIn-number-validate").style.display='block';
6877        if (portInPhoneNoBtn.style.display==='none') {
6878            portInPhoneNoBtn.style.display='block';
6879            portInPhoneNoBtn.setAttribute("disabled", false);
6880        } else {
6881            portInPhoneNoBtn.style.display='block'
6882        }
6883        document.getElementById("portInAddCartBtn")?.classList.add("disabled");
6884        if (document.querySelector('.purchase-modal-box-footer .primary-btn')) {
6885            document.querySelector('.purchase-modal-box-footer .primary-btn').classList.add('disabled');
6886        }
6887    }
6888}
6889
6890
6891/**
6892 * This function is used to validate verification code.
6893 * @param {String} {@value value of the item}
6894 * @param {String} {@element element of the item}
6895 * @param {String} {@btnElement button which needs to hide/show}
6896 * @returns {*|Null}
6897 **/
6898function validatePortInVerificationCode(value, element, btnElement) {
6899    if (value && value.length >5) {
6900        $(element).addClass("success");
6901        $(btnElement).removeClass('disabled');
6902        $("#btnPortInVerifyCodeIdentity").attr("disabled",false);
6903    } else {
6904        $(element).removeClass("success");
6905        $(btnElement).addClass('disabled');
6906        $("#btnPortInVerifyCodeIdentity").attr("disabled",true);
6907    }
6908}
6909
6910/**
6911 * This function is used to set local storage for ineligible plan purchase for store1.
6912 **/
6913function setLocalStorageForPromo(event) {
6914    const currentProduct = localStorage.getItem("currentProduct");
6915    const phoneType = localStorage.getItem("phoneType");
6916    const autoRefillSelectedStatus = localStorage.getItem("autoRefillSelectedStatus");
6917    let selected = document.querySelector('.colorImageSwitch .imageChange.selected');
6918    const skuId = selected.dataset.productid;
6919    localStorage.setItem("prevValuesForPromo", JSON.stringify({ currentProduct, phoneType, autoRefillSelectedStatus, skuId }));
6920    const href = event.target.getAttribute("data-href");
6921    window.location.href = href + "?promo_ip=true";
6922}
6923$(document).ready(function() {
6924    var skinnyElement = document.getElementById("skinny-data");
6925    var deviceDetailSkinnyElement = document.getElementById("device-skinny-data");
6926    if (skinnyElement) {
6927
6928        var skinnyData = localStorage.getItem("skinnyBanner");
6929        if (skinnyData) {
6930            var skinnyObj = JSON.parse(skinnyData);
6931            var enableSkinnyBanner = skinnyObj.enableSkinnyBanner;
6932            if (enableSkinnyBanner && enableSkinnyBanner === 'true') {
6933                if (deviceDetailSkinnyElement) {
6934                    deviceDetailSkinnyElement.remove();
6935                }
6936                var bannerText = DOMPurify.sanitize(skinnyObj.bannerText);
6937                var modalText = DOMPurify.sanitize(skinnyObj.modalText);
6938                var modalLink = DOMPurify.sanitize(skinnyObj.modalLink);
6939                var ctaText = DOMPurify.sanitize(skinnyObj.ctaText);
6940                var modalId = skinnyObj.modalId;
6941                var enableModal = skinnyObj.enableModal;
6942                var simKitPage = skinnyObj.simKitPage;
6943                var bgColor = skinnyElement.dataset.bgcolor;
6944                var showSkinnybannerOnCart = skinnyElement.dataset.showskinnybanneroncart;
6945                var compModalMsg = skinnyElement.dataset.compmodal;
6946                var compCtaText = skinnyElement.dataset.compctatext;
6947                var compLink = skinnyElement.dataset.complink;
6948                var pagestodisplay = skinnyElement.dataset.pagestodisplay;
6949                var addedToCart = skinnyObj.addedToCart ? skinnyObj.addedToCart : "false";
6950                var tempSkinnyObj = {
6951                    ...skinnyObj,
6952                    bgColor: bgColor,
6953                    showSkinnybannerOnCart: showSkinnybannerOnCart,
6954                    addedToCart: addedToCart
6955                };
6956                localStorage.setItem("skinnyBanner", JSON.stringify(tempSkinnyObj));
6957                if (localStorage.getItem("priceType")) {
6958                    var priceType = localStorage.getItem("priceType");
6959                }
6960                if (localStorage.getItem("skinnyPromo")) {
6961                    var skinnyPromo = localStorage.getItem("skinnyPromo");
6962                    var skinnyPromoObj = JSON.parse(skinnyPromo);
6963                    var promoLabel = skinnyPromoObj.promoLabel;
6964                    var modalDesc = skinnyPromoObj.modalDesc;
6965                }
6966                if (document.getElementById("seeDetailModalLink")) {
6967                    var seeDetailModalLink = document.getElementById("seeDetailModalLink");
6968                }
6969                if (document.getElementById("seeDetailLink")) {
6970                    var seeDetailLink = document.getElementById("seeDetailLink");
6971                }
6972                if (enableModal && enableModal !== 'true' && seeDetailModalLink && seeDetailLink) {
6973                    seeDetailModalLink.remove();
6974                    seeDetailLink.href = DOMPurify.sanitize(modalLink);
6975                } else if (enableModal && enableModal === 'true' && seeDetailLink) {
6976                    seeDetailLink.remove();
6977                }
6978                if (seeDetailLink && (!modalText || modalText.trim().length === 0 || modalText === 'keep_empty')) {
6979                    seeDetailLink.remove();
6980                    seeDetailModalLink.remove();
6981                }
6982                var pathLastselector = window.location.pathname.split('.').slice(-1)[0];
6983                if (pathLastselector !== 'html') {
6984                    var purchaseStep = window.location.pathname.split('.').slice(-1)[0];
6985                } else {
6986                    purchaseStep = window.location.pathname.split('.').slice(-2)[0];
6987                }
6988                var tabletPath = window.location.pathname;
6989                if (pagestodisplay && pagestodisplay.includes(purchaseStep)) {
6990                    if (bannerText && bannerText !== 'keep_empty') {
6991                        document.querySelector(".cmp-skinnybanner__text-message").innerHTML = DOMPurify.sanitize(bannerText.replace('<p>','').replace('</p>','').replace('<br>',''));
6992                    } else if (promoLabel && modalDesc) {
6993                        document.querySelector(".cmp-skinnybanner__text-message").innerHTML = DOMPurify.sanitize(promoLabel.replace('<p>','').replace('</p>','').replace('<br>',''));
6994                    } else if (skinnyElement) {
6995                        skinnyElement.remove();
6996                    }
6997                    if (ctaText && ctaText !== 'keep_empty') {
6998                        document.querySelector(".cmp-skinnybanner__modal-ctatext").innerHTML = DOMPurify.sanitize(ctaText);
6999                    } else if (compCtaText) {
7000                        document.querySelector(".cmp-skinnybanner__modal-ctatext").innerHTML = DOMPurify.sanitize(compCtaText);
7001                    }
7002                    if (modalText && modalText !== 'keep_empty') {
7003                        document.querySelector(".cmp-skinnybanner__modal-message").innerHTML = DOMPurify.sanitize(modalText);
7004                    } else if (modalDesc && promoLabel) {
7005                        document.querySelector(".skinny-modal-content").innerHTML = DOMPurify.sanitize(modalDesc);
7006                    } else if (compModalMsg) {
7007                        document.querySelector(".cmp-skinnybanner__modal-message").innerHTML = DOMPurify.sanitize(compModalMsg);
7008                    }
7009                    if (modalLink && modalLink !== 'keep_empty' && document.querySelector(".cmp-skinnybanner__modal-link")) {
7010                        document.querySelector(".cmp-skinnybanner__modal-link").innerHTML = DOMPurify.sanitize(modalLink);
7011                    } else if (compLink && document.querySelector(".cmp-skinnybanner__modal-link")) {
7012                        document.querySelector(".cmp-skinnybanner__modal-link").innerHTML = DOMPurify.sanitize(compLink);
7013                    }
7014                } else if (pagestodisplay && pagestodisplay.includes(purchaseStep) && simKitPage) {
7015                    if (bannerText && bannerText !== 'keep_empty') {
7016                        document.querySelector(".cmp-skinnybanner__text-message").innerHTML = DOMPurify.sanitize(bannerText.replace('<p>','').replace('</p>','').replace('<br>',''));
7017                    } else if (skinnyElement) {
7018                        skinnyElement.remove();
7019                    }
7020                    if (ctaText && ctaText !== 'keep_empty') {
7021                        document.querySelector(".cmp-skinnybanner__modal-ctatext").innerHTML = DOMPurify.sanitize(ctaText);
7022                    }
7023                    if (modalText && modalText !== 'keep_empty') {
7024                        document.querySelector(".cmp-skinnybanner__modal-message").innerHTML = DOMPurify.sanitize(modalText);
7025                    }
7026                    if (modalLink && modalLink !== 'keep_empty' && document.querySelector(".cmp-skinnybanner__modal-link")) {
7027                        document.querySelector(".cmp-skinnybanner__modal-link").innerHTML = DOMPurify.sanitize(modalLink);
7028                    }
7029                } else if (pagestodisplay && pagestodisplay.includes(purchaseStep) && tabletPath.includes('tablets')) {
7030                    if (bannerText && bannerText !== 'keep_empty') {
7031                        document.querySelector(".cmp-skinnybanner__text-message").innerHTML = bannerText.replace('<p>','').replace('</p>','').replace('<br>','');
7032                    } else if (skinnyElement) {
7033                        skinnyElement.remove();
7034                    }
7035                    if (ctaText && ctaText !== 'keep_empty') {
7036                        document.querySelector(".cmp-skinnybanner__modal-ctatext").innerHTML = ctaText;
7037                    }
7038                    if (modalText && modalText !== 'keep_empty') {
7039                        document.querySelector(".cmp-skinnybanner__modal-message").innerHTML = modalText;
7040                    }
7041                    if (modalLink && modalLink !== 'keep_empty') {
7042                        document.querySelector(".cmp-skinnybanner__modal-link").innerHTML = modalLink;
7043                    }
7044                } else if (skinnyElement) {
7045                    skinnyElement.remove();
7046                }
7047                
7048            } else {
7049                skinnyElement.remove();
7050            }
7051        } else {
7052            skinnyElement.remove();
7053        }
7054    }
7055
7056    let simSkinnyData = localStorage.getItem("simKitSkinnyBanner");
7057    let skinnyBannerData = localStorage.getItem("skinnyBanner");
7058    let brandType = document.querySelector(".section-api-container")?.dataset.brand;
7059    if (simSkinnyData) {
7060        var simSkinnyObj = JSON.parse(simSkinnyData);
7061        let activationEnableSkinnyBanner = simSkinnyObj.enableSkinnyBanner;
7062        let activationSkinnyPromoText = simSkinnyObj.bannerText;
7063        let activationSkinnyModalText = simSkinnyObj.modalText;
7064        let activationSkinnyModalLink = simSkinnyObj.modalLink;
7065        let activationSkinnyCtaText = simSkinnyObj.ctaText;
7066        let activationEnableSkinnyModal = simSkinnyObj.enableModal;
7067        let activationSkinnyBannerColor = simSkinnyObj.bgColor;
7068        let colorElement = document.querySelector(".byop-cmp-skinnybanner");
7069
7070        if (document.getElementById("seeDetailModalLink") !== 'undefined' && document.getElementById("seeDetailModalLink") !== null) {
7071            var seeDetailModalLink = document.getElementById("seeDetailModalLink");
7072        }
7073        if (document.getElementById("seeDetailLink") !== 'undefined' && document.getElementById("seeDetailLink") !== null) {
7074            var seeDetailLink = document.getElementById("seeDetailLink");
7075        }
7076        if (typeof activationEnableSkinnyModal !== 'undefined' && activationEnableSkinnyModal !== 'true' && typeof seeDetailModalLink !== 'undefined' && typeof seeDetailLink !== 'undefined') {
7077            seeDetailModalLink.remove();
7078            seeDetailLink.href = DOMPurify.sanitize(activationSkinnyModalLink);
7079        } else if (typeof activationEnableSkinnyModal !== 'undefined' && activationEnableSkinnyModal === 'true' && typeof seeDetailLink !== 'undefined') {
7080            seeDetailLink.remove();
7081        }
7082        if (typeof activationEnableSkinnyBanner !== 'undefined' && activationEnableSkinnyBanner !== null && activationEnableSkinnyBanner === 'true') {
7083            if (typeof activationSkinnyPromoText !== 'undefined' && activationSkinnyPromoText !== null) {
7084                const skinnyBannerMessageElement = document.querySelector(".cmp-byop-skinnybanner__text-message");
7085                if (skinnyBannerMessageElement) {
7086                    skinnyBannerMessageElement.innerHTML = DOMPurify.sanitize(activationSkinnyPromoText.replace('<p>','').replace('</p>','').replace('<br>',''));
7087                }
7088                if (colorElement !== undefined && colorElement !== null && activationSkinnyBannerColor !== undefined && activationSkinnyBannerColor !== null) {
7089                    colorElement.style.backgroundColor = activationSkinnyBannerColor;
7090                } else if (colorElement !== undefined && colorElement !== null) {
7091                    colorElement.style.backgroundColor = '#E5F2FC';
7092                }
7093            }
7094        } else if (colorElement != 'undefined' && colorElement != null) {
7095            colorElement.style.display = 'none';
7096        }
7097        if (typeof activationSkinnyModalText !== 'undefined' && activationSkinnyModalText !== null) {
7098            if (document.querySelector(".cmp-byop-skinnybanner__modal-message")) {
7099                document.querySelector(".cmp-byop-skinnybanner__modal-message").innerHTML = DOMPurify.sanitize(activationSkinnyModalText);
7100            }
7101        }
7102        if (typeof activationSkinnyCtaText !== 'undefined' && activationSkinnyCtaText !== null) {
7103            if (document.querySelector(".cmp-byop-skinnybanner__cta-text")) {
7104                document.querySelector(".cmp-byop-skinnybanner__cta-text").innerHTML = DOMPurify.sanitize(activationSkinnyCtaText);
7105            }
7106        }
7107    } 
7108    if (skinnyBannerData && brandType === "TRACFONE") {
7109        var simSkinnyObj = JSON.parse(skinnyBannerData);
7110        let activationEnableSkinnyBanner = simSkinnyObj.enableSkinnyBanner;
7111        let activationSkinnyPromoText = simSkinnyObj.bannerText;
7112        let activationSkinnyModalText = simSkinnyObj.modalText;
7113        let activationSkinnyModalLink = simSkinnyObj.modalLink;
7114        let activationSkinnyCtaText = simSkinnyObj.ctaText;
7115        let activationEnableSkinnyModal = simSkinnyObj.enableModal;
7116        let activationSkinnyBannerColor = simSkinnyObj.bgColor;
7117        let colorElement = document.querySelector(".byop-cmp-skinnybanner");
7118        window.localStorage.setItem("simKitSkinnyBanner", skinnyBannerData);
7119
7120    	$(document).on("click",".choice-card input[name='addToYourCartOption']", function () {
7121            let simSkinnyData = localStorage.getItem("simKitSkinnyBanner");
7122            if (simSkinnyData) {
7123                window.localStorage.setItem("skinnyBanner", simSkinnyData);
7124                localStorage.removeItem("simKitSkinnyBanner");
7125            }
7126        });
7127
7128        if (document.getElementById("seeDetailModalLink") !== 'undefined' && document.getElementById("seeDetailModalLink") !== null) {
7129            var seeDetailModalLink = document.getElementById("seeDetailModalLink");
7130        }
7131        if (document.getElementById("seeDetailLink") !== 'undefined' && document.getElementById("seeDetailLink") !== null) {
7132            var seeDetailLink = document.getElementById("seeDetailLink");
7133        }
7134        if (typeof activationEnableSkinnyModal !== 'undefined' && activationEnableSkinnyModal !== 'true' && typeof seeDetailModalLink !== 'undefined' && typeof seeDetailLink !== 'undefined') {
7135            seeDetailModalLink.remove();
7136            seeDetailLink.href = DOMPurify.sanitize(activationSkinnyModalLink);
7137        } else if (typeof activationEnableSkinnyModal !== 'undefined' && activationEnableSkinnyModal === 'true' && typeof seeDetailLink !== 'undefined') {
7138            seeDetailLink.remove();
7139        }
7140        if (typeof activationEnableSkinnyBanner !== 'undefined' && activationEnableSkinnyBanner !== null && activationEnableSkinnyBanner === 'true') {
7141            if (typeof activationSkinnyPromoText !== 'undefined' && activationSkinnyPromoText !== null) {
7142                const skinnyBannerMessageElement = document.querySelector(".cmp-byop-skinnybanner__text-message");
7143                if (skinnyBannerMessageElement) {
7144                    skinnyBannerMessageElement.innerHTML = DOMPurify.sanitize(activationSkinnyPromoText.replace('<p>','').replace('</p>','').replace('<br>',''));
7145                }
7146                if (colorElement !== undefined && colorElement != null && activationSkinnyBannerColor !== undefined && activationSkinnyBannerColor !== null) {
7147                    colorElement.style.backgroundColor = activationSkinnyBannerColor;
7148                } else if (colorElement !== undefined && colorElement !== null) {
7149                    colorElement.style.backgroundColor = '#E5F2FC';
7150                }
7151            }
7152        } else if (colorElement !== undefined && colorElement != null) {
7153            colorElement.style.display = 'none';
7154        }
7155        if (typeof activationSkinnyModalText !== 'undefined' && activationSkinnyModalText !== null) {
7156            if (document.querySelector(".cmp-byop-skinnybanner__modal-message")) {
7157                document.querySelector(".cmp-byop-skinnybanner__modal-message").innerHTML = DOMPurify.sanitize(activationSkinnyModalText);
7158            }
7159        }
7160        if (typeof activationSkinnyCtaText !== 'undefined' && activationSkinnyCtaText !== null) {
7161            if (document.querySelector(".cmp-byop-skinnybanner__cta-text")) {
7162                document.querySelector(".cmp-byop-skinnybanner__cta-text").innerHTML = DOMPurify.sanitize(activationSkinnyCtaText);
7163            }
7164        }
7165    } else {
7166        const deviceSkinny = document.querySelector('.cmp-skinnybanner__text-message > p');
7167        let deviceSkinnyText = '';
7168        if (deviceSkinny) {
7169            for(const node of deviceSkinny.childNodes) {
7170                if(node.nodeType === Node.TEXT_NODE) {
7171                    deviceSkinnyText += node.textContent.trim();
7172                }
7173            }
7174            if (!deviceSkinnyText) {
7175                let mainSkinnyBanner = document.querySelector(".cmp-skinnybanner--main");
7176                if (mainSkinnyBanner != 'undefined' && mainSkinnyBanner != null) {
7177                    mainSkinnyBanner.style.display = 'none';
7178                }
7179            } 
7180        } else if (skinnyBannerData) {
7181            let skinnyObj = JSON.parse(skinnyBannerData);
7182            var enableSkinnyBanner = skinnyObj.enableSkinnyBanner;
7183            let mainSkinnyBanner = document.querySelector(".cmp-skinnybanner--main");
7184            if (!enableSkinnyBanner && mainSkinnyBanner != 'undefined' && mainSkinnyBanner != null) {
7185                mainSkinnyBanner.style.display = 'none';
7186            }
7187        } else {
7188            let mainSkinnyBanner = document.querySelector(".cmp-skinnybanner--main");
7189            if (mainSkinnyBanner != 'undefined' && mainSkinnyBanner != null) {
7190                mainSkinnyBanner.style.display = 'none';
7191            }
7192        }
7193    }
7194
7195    let byopSimKit = document.querySelector(".section-api-container");
7196	let skinnyBanner = document.querySelector(".skinnybanner");
7197    if (brandType === "STRAIGHT_TALK" || brandType === "TRACFONE") {
7198        var pagePath = window.location.pathname;
7199        if(pagePath.includes("activate") || pagePath.includes("purchase")) {
7200            if (skinnyBannerData) {
7201				let skinnyObj = JSON.parse(skinnyBannerData);
7202				var bannerText = skinnyObj.bannerText;
7203				if (!bannerText && skinnyBanner != 'undefined' && skinnyBanner != null) {
7204					skinnyBanner.style.display = 'none';
7205				} else {
7206					document.querySelector(".skinnybanner")?.style.setProperty("background-color", "#ffff");
7207					document.querySelector(".skinnybanner")?.style.setProperty("padding-top", "16px");
7208				}
7209			} else if (skinnyBanner) {
7210				skinnyBanner.style.display = 'none';
7211			}
7212        } 
7213        if (pagePath.includes('byop-simkit')) {
7214            let byopSimKitEnableSkinnyBanner = byopSimKit.dataset.enableskinnybanner;
7215            let byopSimKitSkinnyPromoText = byopSimKit.dataset.skinnybannerpromotext;
7216            let byopSimKitSkinnyModalText = byopSimKit.dataset.skinnybannerpromomodaltext;
7217            let byopSimKitSkinnyModalLink = byopSimKit.dataset.skinnybannermodallink;
7218            let byopSimKitSkinnyCtaText = byopSimKit.dataset.skinnybannerctatext;
7219            let byopSimKitEnableSkinnyModal = byopSimKit.dataset.enableskinnymodal;
7220            let byopSimKitSkinnyBannerColor = byopSimKit.dataset.skinnybannercolor ? activationElement.dataset.skinnybannercolor : '#E5F2FC';;
7221            let byopSimKitShowSkinnyBannerOnCart = byopSimKit.dataset.showskinnybanneroncart;
7222            let colorElement = document.querySelector(".byop-cmp-skinnybanner");
7223
7224            if (document.getElementById("seeDetailModalLink") !== 'undefined' &&  document.getElementById("seeDetailModalLink") !== null) {
7225                var seeDetailModalLink = document.getElementById("seeDetailModalLink");
7226            }
7227            if (document.getElementById("seeDetailLink") !== 'undefined' &&  document.getElementById("seeDetailLink") !== null) {
7228                var seeDetailLink = document.getElementById("seeDetailLink");
7229            }
7230
7231            if (typeof byopSimKitEnableSkinnyModal !== 'undefined' && byopSimKitEnableSkinnyModal !== 'true' && typeof seeDetailModalLink !== 'undefined' && typeof seeDetailLink !== 'undefined') {
7232                seeDetailModalLink.remove();
7233                seeDetailLink.href = byopSimKitSkinnyModalLink;
7234            } else if (typeof byopSimKitEnableSkinnyModal !== 'undefined' && byopSimKitEnableSkinnyModal === 'true' && typeof seeDetailLink !== 'undefined') {
7235                seeDetailLink.remove();
7236            }
7237            if (typeof byopSimKitEnableSkinnyBanner !== 'undefined' && byopSimKitEnableSkinnyBanner !== null && byopSimKitEnableSkinnyBanner === 'true') {
7238                if (typeof byopSimKitSkinnyPromoText !== 'undefined' && byopSimKitSkinnyPromoText !== null) {
7239                    if (document.querySelector(".cmp-byop-skinnybanner__text-message")) {
7240                            const cleanedText = byopSimKitSkinnyPromoText.replace(/<p>/gi, '').replace(/<\/p>/gi, '').replace(/<br\s*\/?>/gi, '');
7241                            document.querySelector(".cmp-byop-skinnybanner__text-message").innerHTML = cleanedText;
7242                    }
7243                    if (colorElement != 'undefined' && colorElement != null && byopSimKitSkinnyBannerColor != 'undefined' && byopSimKitSkinnyBannerColor != null) {
7244                        colorElement.style.backgroundColor = byopSimKitSkinnyBannerColor;
7245                    }
7246                }
7247            }
7248
7249            if (typeof byopSimKitSkinnyModalText !== 'undefined' && byopSimKitSkinnyModalText !== null) {
7250                if (document.querySelector(".cmp-byop-skinnybanner__modal-message")) {
7251                    const modalText = byopSimKitSkinnyModalText.replace(/<p>/gi, '').replace(/<\/p>/gi, '').replace(/<br\s*\/?>/gi, '');
7252                    document.querySelector(".cmp-byop-skinnybanner__modal-message").innerHTML = modalText;
7253                }
7254
7255            }
7256            if (typeof byopSimKitSkinnyCtaText !== 'undefined' && byopSimKitSkinnyCtaText !== null) {
7257                if (document.querySelector(".cmp-byop-skinnybanner__cta-text")) {
7258                    const ctaText = byopSimKitSkinnyCtaText.replace(/<p>/gi, '').replace(/<\/p>/gi, '').replace(/<br\s*\/?>/gi, '');
7259                    document.querySelector(".cmp-byop-skinnybanner__cta-text").innerHTML = ctaText;
7260                }
7261            }
7262
7263            let byopSimKitBannerObj = {};
7264            if (byopSimKitEnableSkinnyBanner) {
7265                byopSimKitBannerObj.bannerText = byopSimKitSkinnyPromoText;
7266                byopSimKitBannerObj.modalText = byopSimKitSkinnyModalText;
7267                byopSimKitBannerObj.modalLink = byopSimKitSkinnyModalLink;
7268                byopSimKitBannerObj.ctaText = byopSimKitSkinnyCtaText;
7269                byopSimKitBannerObj.enableSkinnyBanner = byopSimKitEnableSkinnyBanner;
7270                byopSimKitBannerObj.enableModal = byopSimKitEnableSkinnyModal;
7271                byopSimKitBannerObj.bgColor = byopSimKitSkinnyBannerColor;
7272                byopSimKitBannerObj.addedToCart = "true";
7273                byopSimKitBannerObj.showSkinnybannerOnCart = byopSimKitShowSkinnyBannerOnCart;
7274                window.localStorage.setItem("skinnyBanner", JSON.stringify(byopSimKitBannerObj));
7275            }
7276        }
7277    }
7278    $(document).on("click", "div.cmp-skinnybanner__text-message a.add-role-btn", function() {
7279        const skinnyModalPopupClose = document.getElementById("skinnyModalPopupClose");
7280        skinnyModalPopupClose?.addEventListener("click", function(e) {
7281            e.stopPropagation();
7282            $("#skinny-modal").modal("hide");
7283        });
7284    });
7285     (function enforceEmptyJourneySkinnyBannerRemoval() {
7286        var pathLower = window.location.pathname.toLowerCase();
7287
7288        // Cart / checkout are React-driven (overrideSkinnyBannerPromoText) — never touch here
7289        var isCartPage = pathLower.includes("cart") || pathLower.includes("checkout");
7290        if (isCartPage) {
7291            return;
7292        }
7293
7294        // Do NOT interfere with SIM-kit / BYOP / activation banner flows (separate LS keys)
7295        if (pathLower.includes("byop-simkit") || pathLower.includes("activate")
7296            || localStorage.getItem("simKitSkinnyBanner")) {
7297            return;
7298        }
7299        // Only enforce on phone/plan purchase journey pages
7300        if (!pathLower.includes("purchase")) {
7301            return;
7302        }
7303
7304        // SOURCE OF TRUTH: decide from localStorage bannerText, not rendered DOM text.
7305        // This is available immediately, regardless of when the banner node renders.
7306        function isBannerTextEmpty() {
7307            try {
7308                var raw = localStorage.getItem("skinnyBanner");
7309                if (!raw) {
7310                    return true; // no config => nothing to show on journey
7311                }
7312                var obj = JSON.parse(raw);
7313
7314                // If banner not enabled, journey should not render it
7315                if (!obj || obj.enableSkinnyBanner !== "true") {
7316                    return true;
7317                }
7318
7319                var text = (obj.bannerText || "")
7320                    .replace(/<p>/gi, "")
7321                    .replace(/<\/p>/gi, "")
7322                    .replace(/<br\s*\/?>/gi, "")
7323                    .replace(/&nbsp;/gi, " ")
7324                    .replace(/\u00a0/g, " ")
7325                    .replace(/\s+/g, " ")
7326                    .trim();
7327
7328                return !text || text.length === 0 || text === "keep_empty";
7329            } catch (e) {
7330                return true; // on parse error, fail safe -> hide
7331            }
7332        }
7333
7334        function removeEmptyBanner() {
7335            if (!isBannerTextEmpty()) {
7336                return false; // valid text -> leave banner visible
7337            }
7338            var mainWrapper = document.querySelector(".cmp-skinnybanner--main");
7339            if (mainWrapper) {
7340                mainWrapper.style.display = 'none'; // hides wrapper + background container
7341                return true;
7342            }
7343            return false; // node not present yet
7344        }
7345
7346        // 1) Try immediately (covers PDP where node already exists)
7347        if (removeEmptyBanner()) {
7348            return;
7349        }
7350
7351        // 2) If bannerText is valid, no need to observe — exit
7352        if (!isBannerTextEmpty()) {
7353            return;
7354        }
7355
7356        // 3) Node not yet rendered (journey pages). Observe DOM until it appears, then remove.
7357        var observer = new MutationObserver(function() {
7358            if (removeEmptyBanner()) {
7359                observer.disconnect();
7360            }
7361        });
7362        observer.observe(document.body, { childList: true, subtree: true });
7363
7364        // 4) Safety timeouts (in case observer misses / SPA hydration)
7365        var attempts = 0;
7366        var poll = setInterval(function() {
7367            attempts++;
7368            if (removeEmptyBanner() || attempts >= 20) { // ~5s max at 250ms
7369                clearInterval(poll);
7370                observer.disconnect();
7371            }
7372        }, 250);
7373
7374        // 5) Final guard on full load
7375        window.addEventListener("load", function() {
7376            removeEmptyBanner();
7377        });
7378    })();
7379});

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.