PageSourceSearch

https://dempsters.ca/sites/default/files/js/js_X0YWUNo-1s0dE020sdZ6s6iarSGwuiVGWEpcB-obKJQ.js

js dempsters.ca collected 2026-09-26 11:27:42 UTC 221,264 bytes, 5,786 lines download raw bytes

1/**
2 * @file
3 * Behaviors of Boostrap Layout Builder local video background.
4 */
5
6(function ($, _, Drupal, drupalSettings) {
7  "use strict";
8
9  Drupal.behaviors.scrollEffectsInit = {
10    attach: function (context, settings) {
11      AOS.init();
12    }
13  }
14
15})(window.jQuery, window._, window.Drupal, window.drupalSettings);
16;
17// /**
18//  * @file
19//  * Vote Up/Down behavior service
20//  */
21// (function ($, Drupal) {
22
23//   window.voteUpDownService = (function() {
24//     function voteUpDownService() {}
25//     voteUpDownService.vote = function(baseWidget, url, operation) {
26//       $.ajax({
27//         type: "GET",
28//         url: url,
29//         success: function(response) {
30//           baseWidget.find('.throbber').remove();
31//           baseWidget.find('.reset').addClass('element-invisible');
32//           baseWidget.find('.up.active').each(function () {
33//             $(this).removeClass('active').addClass('inactive');
34//           });
35//           baseWidget.find('.down.active').each(function () {
36//             $(this).removeClass('active').addClass('inactive');
37//           });
38//           if(operation !== 'reset') {
39//             baseWidget.find('.' + operation).each(function () {
40//               $(this).removeClass('inactive').addClass('active');
41//             });
42//             baseWidget.find('.reset').removeClass('element-invisible');
43//           }
44//           if (baseWidget.hasClass('vud-widget-upanddown')) {
45//             baseWidget.find('.points-up').first().html(response.data.up);
46//             baseWidget.find('.points-down').first().html(response.data.down);
47//           } else {
48//             baseWidget.find('.points-sum').first().html(response.data.sum);
49//           }
50//         }
51//       });
52//     };
53//     return voteUpDownService;
54//   })();
55
56// })(jQuery, Drupal);
57
58
59/**
60 * @file
61 * Vote Up/Down behavior service
62 */
63(function ($, Drupal) {
64  $(".like-widget .up").attr("aria-label", "Like");
65  window.voteUpDownService = (function () {
66    function voteUpDownService() {}
67    voteUpDownService.vote = function (baseWidget, url, operation) {
68      $.ajax({
69        type: "GET",
70        url: url,
71        success: function (response) {
72          baseWidget.find(".throbber").remove();
73          baseWidget.find(".reset").addClass("element-invisible");
74          baseWidget.find(".up.active").each(function () {
75            $(this).removeClass("active").addClass("inactive");
76            $(this).attr("aria-label", "Like");
77            $('html[lang = "fr"]')
78              .find(".vud-widget a.up")
79              .attr("aria-label", "Aimer");
80          });
81          baseWidget.find(".down.active").each(function () {
82            $(this).removeClass("active").addClass("inactive");
83            $(this).attr("aria-label", "Like");
84            $('html[lang = "fr"]')
85              .find(".vud-widget a.up")
86              .attr("aria-label", "Aimer");
87          });
88          if (operation !== "reset") {
89            baseWidget.find("." + operation).each(function () {
90              $(this).removeClass("inactive").addClass("active");
91              $(this).attr("aria-label", "Unlike");
92              $('html[lang = "fr"]')
93                .find(".vud-widget a.up")
94                .attr("aria-label", "Ne plus aimer");
95            });
96            baseWidget.find(".reset").removeClass("element-invisible");
97          }
98          if (baseWidget.hasClass("vud-widget-upanddown")) {
99            baseWidget.find(".points-up").first().html(response.data.up);
100            baseWidget.find(".points-down").first().html(response.data.down);
101          } else {
102            baseWidget.find(".points-sum").first().html(response.data.sum);
103          }
104        },
105      });
106    };
107    return voteUpDownService;
108  })();
109})(jQuery, Drupal);
110;
111/**
112 * @file
113 * Vote Up/Down behavior.
114 */
115(function ($, Drupal) {
116
117  Drupal.behaviors.voteUpDown = {
118    attach: function (context, settings) {
119      $('.vud-widget a').click(function (e) {
120        e.preventDefault();
121        var baseWidget = $(this).parents('.vud-widget');
122        var routeUrl = $(this).is('a') ? $(this).attr('href') : $(this).parent().attr('href');
123        var operation;
124
125        // if($(this).is('.inactive'))
126          // baseWidget.append('<img class="throbber" src="' + drupalSettings.path.baseUrl + '/' + settings.basePath + '/img/status-active.gif">');
127          baseWidget.append('<span class="throbber"><i class="icon icon-reset fa-spin"></i><span class="sr-only">' + Drupal.t('Loading...') + '</span></span>');
128
129        if($(this).is('a.up.inactive'))
130          operation = 'up';
131        else if($(this).is('a.down.inactive'))
132          operation = 'down';
133        else
134          operation = 'reset';
135
136        voteUpDownService.vote(baseWidget, routeUrl, operation);
137        e.stopImmediatePropagation();
138      });
139    }
140  };
141
142})(jQuery, Drupal);
143;
144/******/ (function(modules) { // webpackBootstrap
145/******/ 	// The module cache
146/******/ 	var installedModules = {};
147/******/
148/******/ 	// The require function
149/******/ 	function __webpack_require__(moduleId) {
150/******/
151/******/ 		// Check if module is in cache
152/******/ 		if(installedModules[moduleId]) {
153/******/ 			return installedModules[moduleId].exports;
154/******/ 		}
155/******/ 		// Create a new module (and put it into the cache)
156/******/ 		var module = installedModules[moduleId] = {
157/******/ 			i: moduleId,
158/******/ 			l: false,
159/******/ 			exports: {}
160/******/ 		};
161/******/
162/******/ 		// Execute the module function
163/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
164/******/
165/******/ 		// Flag the module as loaded
vendor: 2,824 bytes, lines 166-231
166/******/ 		module.l = true;
167/******/
168/******/ 		// Return the exports of the module
169/******/ 		return module.exports;
170/******/ 	}
171/******/
172/******/
173/******/ 	// expose the modules object (__webpack_modules__)
174/******/ 	__webpack_require__.m = modules;
175/******/
176/******/ 	// expose the module cache
177/******/ 	__webpack_require__.c = installedModules;
178/******/
179/******/ 	// define getter function for harmony exports
180/******/ 	__webpack_require__.d = function(exports, name, getter) {
181/******/ 		if(!__webpack_require__.o(exports, name)) {
182/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
183/******/ 		}
184/******/ 	};
185/******/
186/******/ 	// define __esModule on exports
187/******/ 	__webpack_require__.r = function(exports) {
188/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
189/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
190/******/ 		}
191/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
192/******/ 	};
193/******/
194/******/ 	// create a fake namespace object
195/******/ 	// mode & 1: value is a module id, require it
196/******/ 	// mode & 2: merge all properties of value into the ns
197/******/ 	// mode & 4: return value when already ns object
198/******/ 	// mode & 8|1: behave like require
199/******/ 	__webpack_require__.t = function(value, mode) {
200/******/ 		if(mode & 1) value = __webpack_require__(value);
201/******/ 		if(mode & 8) return value;
202/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
203/******/ 		var ns = Object.create(null);
204/******/ 		__webpack_require__.r(ns);
205/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
206/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
207/******/ 		return ns;
208/******/ 	};
209/******/
210/******/ 	// getDefaultExport function for compatibility with non-harmony modules
211/******/ 	__webpack_require__.n = function(module) {
212/******/ 		var getter = module && module.__esModule ?
213/******/ 			function getDefault() { return module['default']; } :
214/******/ 			function getModuleExports() { return module; };
215/******/ 		__webpack_require__.d(getter, 'a', getter);
216/******/ 		return getter;
217/******/ 	};
218/******/
219/******/ 	// Object.prototype.hasOwnProperty.call
220/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
221/******/
222/******/ 	// __webpack_public_path__
223/******/ 	__webpack_require__.p = "/";
224/******/
225/******/
226/******/ 	// Load entry module and return exports
227/******/ 	return __webpack_require__(__webpack_require__.s = 17);
228/******/ })
229/************************************************************************/
230/******/ ({
231
232/***/ "./src/components/search-rest/search-rest.js":
233/*!***************************************************!*\
234  !*** ./src/components/search-rest/search-rest.js ***!
235  \***************************************************/
236/*! no static exports found */
237/***/ (function(module, exports) {
238
239function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
240
241//current
242(function ($, Drupal) {
243  Drupal.behaviors.searchRest = {
244    attach: function attach(context) {
245      // get from block data-url attr
246      // const SEARCH_URL = 'https://dev-bc-villaggio.millenniumweb.com/rest/products';
247      var SEARCH_URL = $(".search-rest").attr("data-url");
248      var pathname = window.location.pathname; // Returns path only (/path/example.html)
249      // let url      = window.location.href;     // Returns full URL (https://example.com/path/example.html)
250
251      var origin = window.location.origin; // Returns base URL (https://example.com)
252      // let search   = window.location.search;
253      // Templates inside JS technique
254      // https://stackoverflow.com/a/39065147
255
256      var Select = function Select(_ref) {
257        var identifier = _ref.identifier,
258            label = _ref.label,
259            multiple = _ref.multiple,
260            options = _ref.options;
261        return "\n        <div class=\"select-item select-item-".concat(identifier, "\">\n            <label for=\"form-").concat(identifier, "\">").concat(label, "</label>\n            <select id=\"form-").concat(identifier, "\" name=\"").concat(identifier, "\" class=\"form-select form-").concat(identifier, " selectpicker\" ").concat(multiple ? "multiple" : "", " data-width=\"auto\" data-dropup-auto=\"false\" data-display=\"static\">\n                ").concat(options, "\n            </select>\n        </div>\n        ");
262      };
263
264      var SelectGroup = function SelectGroup(_ref2) {
265        var identifier = _ref2.identifier,
266            label = _ref2.label,
267            options = _ref2.options;
268        return "\n            <optgroup label=\"".concat(label, "\">").concat(options, "</option>\n        ");
269      };
270
271      var SelectOption = function SelectOption(_ref3) {
272        var identifier = _ref3.identifier,
273            label = _ref3.label,
274            parent = _ref3.parent;
275        return "\n            <option value=\"".concat(identifier, "\" data-parent=\"").concat(parent, "\">").concat(label, "</option>\n        ");
276      };
277
278      var Pill = function Pill(_ref4) {
279        var name = _ref4.name,
280            value = _ref4.value,
281            label = _ref4.label;
282        return "\n           <button class=\"pill badge badge-success\" data-filter=\"".concat(name, "\" data-value=\"").concat(value, "\">").concat(label, " <span class=\"sr-only\">") + Drupal.t("remove filter") + "</span><span aria-hidden=\"true\">&times;</span></button>\n        ";
283      }; // TODO: load filters separately?
284      // function loadFilters(feedUrl) {
285      // }
286
287
288      function loadSearchResults(feedUrl, keep_results) {
289        $.ajax({
290          method: "GET",
291          url: feedUrl,
292          dataType: "JSON",
293          beforeSend: function beforeSend(xhr) {
294            $(".search-rest").removeClass("is-loaded").addClass("is-loading");
295          },
296          error: function error() {
297            $(".search-rest").removeClass("is-loading").addClass("loading-error");
298          },
299          success: function success(data) {
300            var $body = $("body"); // console.log('success');
301
302            $(".search-rest").removeClass("is-loading").addClass("is-loaded").addClass("is-initialized");
303
304            if (!keep_results) {
305              $(".search-content").html("");
306            }
307
308            $(".filters-pills").html(""); // hide mobile filters.
309
310            $(".search-filters .filters-wrapper").removeClass("show-filters");
311            $body.removeClass("modal-open"); // console.log('data', data);
312            // if (!$('.search-content').hasClass('filters-loaded')) {
313            // load filters
314
315            $(".search-filters .filters-placeholder").html("");
316            $.each(data.options, function (index, element) {
317              if (element.options) {
318                // console.log(element);
319                if (!element.settings.exposed) {
320                  return;
321                }
322
323                var options = []; // if is not required AND not multiple,
324                // add - Any - option
325
326                if (!element.settings.expose.required && !element.settings.expose.multiple) {
327                  options.push(SelectOption({
328                    identifier: "All",
329                    label: "- Any -",
330                    parent: 0
331                  }));
332                } // check if it's a vocabulary.
333                // console.log('element.options', element.options);
334
335
336                for (var key in element.options) {
337                  var newOptions = [];
338
339                  if (_typeof(element.options[key]) === "object" && element.options[key] !== null) {
340                    // console.log('Variable is an object!');
341                    // console.log(element.options[key]);
342                    if (element.options[key]["tid"]) {
343                      // console.log('is a term', element.options[key]['tid']);
344                      newOptions.push(SelectOption({
345                        identifier: element.options[key]["value"],
346                        label: element.options[key]["label"],
347                        parent: 0
348                      }));
349                    }
350                  } else {
351                    newOptions.push(SelectOption({
352                      identifier: key,
353                      label: element.options[key],
354                      parent: 0
355                    }));
356                  } // check if has children
357
358
359                  if (element.options[key]["children"]) {
360                    // console.log('has children');
361                    for (var childrenKey in element.options[key]["children"]) {
362                      // check if it's a vocabulary.
363                      if (_typeof(element.options[key]["children"][childrenKey]) === "object" && element.options[key]["children"][childrenKey] !== null) {
364                        // console.log('Variable is an object!');
365                        // console.log(element.options[key]['children'][childrenKey]);
366                        if (element.options[key]["children"][childrenKey]["tid"]) {
367                          // console.log('is a term', element.options[key]['children'][childrenKey]['tid']);
368                          newOptions.push(SelectOption({
369                            identifier: element.options[key]["children"][childrenKey]["value"],
370                            label: "- " + element.options[key]["children"][childrenKey]["label"],
371                            parent: element.options[key]["value"]
372                          }));
373                        }
374                      } else {
375                        newOptions.push(SelectOption({
376                          identifier: childrenKey,
377                          label: element.options[key]["children"][childrenKey],
378                          parent: element.options[key]
379                        }));
380                      }
381                    } // wrap the new options first in an option group, then to the select
382
383
384                    options.push(SelectGroup({
385                      identifier: element.options[key]["value"],
386                      label: element.options[key]["label"],
387                      options: newOptions.join("")
388                    }));
389                  } else {
390                    // push the new options directly to the select
391                    //console.log("newOptions");
392                    options.push(newOptions);
393                  }
394                }
395
396                $(".search-filters .filters-placeholder").append([{
397                  identifier: element.settings.expose.identifier,
398                  label: element.settings.expose.label,
399                  options: options.join(""),
400                  multiple: element.settings.expose.multiple
401                }].map(Select).join(""));
402              }
403            }); // Sort by (uncomment code below to enable this filter)
404            // identifier: sort_by
405            // label: Sort By
406            // options:
407            // items: data.options.sorting
408            // id: data.options.sorting.[item].id
409            // label: data.options.sorting.[item].expose.label
410
411            var sortByOptions = []; // console.log('data', data.options.sorting[key].expose.label)
412
413            for (var key in data.options.sorting) {
414              if (data.options.sorting[key].exposed) {
415                sortByOptions.push(SelectOption({
416                  identifier: key,
417                  label: data.options.sorting[key].expose.label
418                }));
419              } // sortByOptions.push(SelectOption({identifier: key, label: data.options.sorting[key].expose.label}))
420
421            }
422
423            var sortText = Drupal.t("Sort By");
424            $(".sorting-placeholder", context).html("");
425            $(".sorting-placeholder", context).append(Select({
426              identifier: "sort_by",
427              label: Drupal.t("Sort By"),
428              options: sortByOptions.join("")
429            }));
430            $(".sorting-placeholder .form-select", context).on("change", function () {
431              // console.log('sorting change');
432              $(".search-filters .form-submit", context).trigger("click");
433            }); // $('.search-filters .filters-placeholder').append(
434            //     Select({
435            //         identifier: 'sort_by',
436            //         label: 'Sort By',
437            //         options: sortByOptions.join(''),
438            //     })
439            // );
440            // Order (uncomment code below to enable this filter)
441            // identifier: sort_order
442            // label: "Order"
443            // options:
444            // ASC: Asc
445            // DESC: Desc
446            // let sortOrderOptions = [
447            //     { identifier: 'ASC', label: 'Asc' },
448            //     { identifier: 'DESC', label: 'Desc' },
449            // ].map(SelectOption).join('');
450            // $('.search-filters .filters-placeholder').append(
451            //     Select({
452            //         identifier: 'sort_order',
453            //         label: 'Order',
454            //         options: sortOrderOptions,
455            //     })
456            // );
457            // Items per page (uncomment code below to enable this filter)
458            // identifier: items_per_page
459            // boolean: data.paging.options.items_per_page
460            // label: data.paging.options.items_per_page_label
461            // options: data.paging.options.items_per_page_options
462            // boolean: data.paging.options.items_per_page_options_all
463            // all label: data.paging.options.items_per_page_options_all_label
464            // if (data.paging.options.items_per_page) {
465            //     let itemsPerPageOptions = data.paging.options.items_per_page_options.split(',').map(item => item.trim());
466            //     $.each(itemsPerPageOptions, function(key, value) {
467            //         itemsPerPageOptions.push(SelectOption({identifier: value, label: value}))
468            //     });
469            //     if (data.paging.options.items_per_page_options_all) {
470            //         itemsPerPageOptions.unshift(SelectOption({identifier: 'All', label: data.paging.options.items_per_page_options_all_label}));
471            //     }
472            //     $('.search-filters .filters-placeholder').append(
473            //         Select({
474            //             identifier: 'items_per_page',
475            //             label: data.paging.options.items_per_page_label,
476            //             options: itemsPerPageOptions.join(''),
477            //         })
478            //     );
479            // }
480
481            $(".search-content").addClass("filters-loaded"); // }
482            // compare request with filters and highligh selected items
483
484            if (data.request) {
485              // console.log(data.request);
486              $.each(data.request, function (index, element) {
487                // console.log(index, element);
488                var requestOptions = [];
489
490                if (element) {
491                  requestOptions = element.split(",");
492                }
493
494                if ($(".search-filters .form-" + index).length > 0) {
495                  $(".search-filters .form-" + index + " option").each(function () {
496                    var decodedOption = decodeURIComponent($(this).val()).replace(/\+/g, " "); // console.log('decodedOption', decodedOption);
497                    // console.log('requestOptions', requestOptions);
498
499                    if ($.inArray(decodedOption, requestOptions) !== -1) {
500                      $(this).attr("selected", "selected");
501                    }
502                  });
503                } // Sort by.
504
505
506                if (index == "sort_by") {
507                  if ($(".sorting-placeholder .form-" + index).length > 0) {
508                    $(".sorting-placeholder .form-" + index + " option").each(function () {
509                      var decodedOption = decodeURIComponent($(this).val()).replace(/\+/g, " "); // console.log('decodedOption', decodedOption);
510                      // console.log('requestOptions', requestOptions);
511
512                      if ($.inArray(decodedOption, requestOptions) !== -1) {
513                        $(this).attr("selected", "selected");
514                      }
515                    });
516                  }
517                } // // place pill (based on request)
518                // let $select = $('.search-filters .form-' + index);
519                // if (index != 'items_per_page'
520                //     && index != 'sort_by'
521                //     && index != 'sort_order'
522                //     && element != 'All'
523                // ) {
524                //     // if (Array.isArray(requestOptions)) {
525                //         // let text = [];
526                //         // $select.find("option:selected").each(function () {
527                //         //     text.push($(this).text());
528                //         // });
529                //         $.each(requestOptions, function(optionIndex, optionElement) {
530                //             $('.filters-pills').append(Pill({
531                //                 // TODO: need to find the user friendly name
532                //                 label: optionElement,
533                //                 name: index,
534                //                 value: optionElement,
535                //             }));
536                //         });
537                //     // } else {
538                //     //     let text = $select.find("option:selected").text();
539                //     //     if (value !== "All") {
540                //     //         $('.filters-pills').append(Pill({
541                //     //             label: text,
542                //     //             name: index,
543                //     //             value: element,
544                //     //         }));
545                //     //     }
546                //     // }
547                // }
548
549              });
550            } // place pills (getting values from the html)
551
552
553            $(".select-item").each(function () {
554              var $select = $(this).find($("select"));
555              var name = $select.attr("name");
556              var value = $select.val(); // params.push(name + '=' + value);
557
558              if (name != "items_per_page" && name != "sort_order" && name != "sort_by") {
559                if (Array.isArray(value)) {
560                  var text = [];
561                  $select.find("option:selected").each(function () {
562                    text.push($(this).text());
563                  });
564                  $.each(value, function (index, element) {
565                    $(".filters-pills").append(Pill({
566                      label: text[index],
567                      name: name,
568                      value: element
569                    }));
570                  });
571                } else {
571
572                  var _text = $select.find("option:selected").text();
573
574                  if (value !== "All") {
575                    $(".filters-pills").append(Pill({
576                      label: _text,
577                      name: name,
578                      value: value
579                    }));
580                  }
581                }
582              }
583            }); // pills
584
585            $(".pill").on("click", function () {
586              // console.log($(this).attr('data-filter'), $(this).attr('data-value'));
587              var filter = $(this).attr("data-filter");
588              var value = $(this).attr("data-value");
589              var params = new URLSearchParams(window.location.search);
590              var currentValue = params.get(filter);
591              var decodedValue = decodeURIComponent(value).replace(/\+/g, " "); // console.log("currentValue", currentValue);
592              // console.log("decodedValue", decodedValue);
593
594              currentValue = currentValue.split(",");
595              var newValue = currentValue.filter(function (elem) {
596                return elem != decodedValue;
597              });
598              console.log(newValue);
599
600              if (newValue.length > 0) {
601                params.set(filter, newValue);
602              } else {
603                params["delete"](filter);
604              }
605
606              params = params.toString();
607              params = params.toString().replace(/\%2C/g, ",");
608              console.log("params", params);
609              params = "?" + params;
610              loadSearchResults(SEARCH_URL + params);
611              history.replaceState(params, null, origin + pathname + params);
612            }); // apply bootstrap-select plugin
613
614            if ($("html").attr("lang") == "fr") {
615              $(".search-rest .selectpicker").selectpicker({
616                lang: "FR"
617              });
618            } else {
619              $(".search-rest .selectpicker").selectpicker();
620            } //ADA 2-20-2023
621            // ADA fix for select dropdowns
622            // $('.search-rest .dropdown-toggle', context).off('keyup.activedescendant').on('keyup.activedescendant', function () {
623            //     var owns = $(this).attr('aria-owns');
624            //     var dropWrap = $('#'+owns);
625            //     var activeItem = dropWrap.find('li.active').find('a');
626            //     var activeId = activeItem.attr('id');
627            //     console.log('active desc:', dropWrap ,activeItem,activeItem.length, activeId);
628            //     if(activeItem.length < 1){
629            //         $(this).removeAttr('aria-activedescendant');
630            //         return;
631            //     }
632            //     $(this).attr('aria-activedescendant', activeId);
633            // });
634            // bootstrap-select hierarchy (cascade)
635
636
637            $(".search-rest .selectpicker", context).on("changed.bs.select", function (e, clickedIndex, isSelected, previousValue) {
638              //var activeItem = $(this).siblings('.dropdown-menu').find('.active a');
639              //var activeId = activeItem.attr('id');
640              // do something...
641              // console.log($(this));
642              // console.log($(this).val());
643              // console.log('e', e);
644              // console.log('clickedIndex', clickedIndex);
645              // console.log(e.currentTarget['id']);
646              var $selectId = $("#" + e.currentTarget["id"]);
647              var $optionClicked = $selectId.find("option:eq(" + clickedIndex + ")"); // console.log("data-parent", e.currentTarget[clickedIndex]['attributes']["data-parent"]['value']);
648              // console.log("value", e.currentTarget[clickedIndex]['attributes']["value"]['value']);
649              // console.log('option clicked is ', $optionClicked.attr('value'));
650              // console.log('option parent is ', $optionClicked.attr('data-parent'));
651              // console.log('option clicked is selected: ', $optionClicked.is(':selected'));
652
653              var value = $optionClicked.attr("value");
654              var parent = $optionClicked.attr("data-parent"); // if level 1
655
656              if (parent == 0) {
657                // console.log('is root');
658                // if selecting
659                if ($optionClicked.is(":selected")) {
660                  $selectId.find('option[data-parent="' + value + '"]').prop("selected", true);
661                  $selectId.selectpicker("refresh");
662                } // if deselecting
663                else {
664                    $selectId.find('option[data-parent="' + value + '"]').prop("selected", false);
665                    $selectId.selectpicker("refresh");
666                  }
667              } // if level 2
668              else {
669                  // console.log('is not root, parent is ', parent);
670                  // if selecting
671                  if ($optionClicked.is(":selected")) {
672                    var allSelected = true; // verify if all are selected and check the parent
673                    // console.log($selectId.find('option[data-parent='+parent+']').is(':selected'));
674                    // console.log($selectId.find('option[data-parent="'+parent+']"'));
675
676                    $selectId.find('option[data-parent="' + parent + '"]').each(function (index, element) {
677                      if ($(this).is(":selected") == false) {
678                        allSelected = false;
679                      }
680                    }); // console.log('allSelected', allSelected);
681
682                    if (allSelected) {
683                      $selectId.find('option[value="' + parent + '"]').prop("selected", true);
684                      $selectId.selectpicker("refresh");
685                    }
686                  } // if deselecting
687                  else {
688                      var _allSelected = true; // verify if all are selected and uncheck the parent
689                      // console.log($selectId.find('option[data-parent='+parent+']').is(':selected'));
690                      // console.log('option[data-parent="'+parent+']');
691
692                      $selectId.find('option[data-parent="' + parent + '"]').each(function (index, element) {
693                        if ($(this).is(":selected") == false) {
694                          _allSelected = false;
695                        }
696                      }); // console.log('allSelected', allSelected);
697
698                      if (_allSelected == false) {
699                        $selectId.find('option[value="' + parent + '"]').prop("selected", false);
700                        $selectId.selectpicker("refresh");
701                      }
702                    }
703                } // console.log($('#' + selectId).val());
704              // $('#'+ selectId + ' option').each(function(index, element) {
705              // console.log(index, element);
706              // });
707
708            });
709
710            function fixOptionsText(target) {
711              $(target).find(".dropdown-item .text").each(function () {
712                if ($(this).html().indexOf("- ") > -1) {
713                  $(this).addClass("d-flex");
714                  $(this).html($(this).html().replace("- ", '<span aria-hidden="true">-&nbsp;</span>'));
715                }
716              });
717            }
718
719            $(".search-rest .filters-placeholder .selectpicker", context).on("show.bs.select", function (e, clickedIndex, isSelected, previousValue) {
720              $(".search-content-wrapper").addClass("overlay_filter");
721              $(".search-results-wrapper").addClass("overlay_filter");
722              fixOptionsText(e.target.offsetParent);
723            });
724            $(".search-rest .filters-placeholder .selectpicker", context).on("refreshed.bs.select", function (e, clickedIndex, isSelected, previousValue) {
725              fixOptionsText(e.target.offsetParent);
726            });
727            $(".search-rest .sorting-placeholder .selectpicker", context).on("show.bs.select", function (e, clickedIndex, isSelected, previousValue) {
728              $(".search-content-wrapper").addClass("overlay_filter");
729            });
730            $(".search-rest .selectpicker", context).on("hide.bs.select", function (e, clickedIndex, isSelected, previousValue) {
731              $(".search-content-wrapper").removeClass("overlay_filter");
732              $(".search-results-wrapper").removeClass("overlay_filter");
733            }); // load content
734
735            if (data.data.length > 0) {
736              $(".search-empty").html("");
737              $(".results-placeholder").html(data.paging.rows_total + " " + Drupal.t("results"));
738              $.each(data.data, function (index, element) {
739                // console.log('element', element);
740                var rendered_entity = element.rendered_entity;
741                $(".search-content").append( // '<div class="search__col" role="group" aria-label="product">' +
742                //   rendered_entity +
743                //   "</div>"
744                '<div class="search__col" role="group" aria-label="item">' + rendered_entity + "</div>");
745                $(".search-rest .search-content .recipe-featured__card img").removeAttr("alt").attr("alt", "");
746              }); //ADA 2-20-2023
747              //focus the first item of the current page. skip for first page.
748
749              if (data.paging.page_current > 0) {
750                $(".search__col").eq(data.paging.page_current * data.paging.rows_per_page).find("a").focus();
751              }
752            } else {
753              if (data.empty) {
754                $(".search-empty").html(data.empty.value);
755                $(".results-placeholder").html("");
756              }
757            } // pagination
758            // console.log('data.paging.page_current', data.paging.page_current);
759
760
761            var nextPage = data.paging.page_current + 1; // console.log('nextPage', nextPage)
762
763            if (nextPage < data.paging.page_total) {
764              // Bind button click function with new url
765              $(".view-more").show();
766              $(".view-more").html(data.paging.tags.next);
767              $(".view-more").off("click").on("click", function (e) {
768                e.preventDefault();
769                var params = "?page=" + nextPage;
770                var searchParams = new URLSearchParams(window.location.search);
771                searchParams.set("page", nextPage);
772                searchParams = searchParams.toString();
773                searchParams = "?" + searchParams; // console.log(searchParams);
774                // if (searchParams) {
775                //     params = '?' + searchParams + '&page=' + nextPage;
776                // }
777
778                loadSearchResults(SEARCH_URL + searchParams, true); // history.replaceState(null, null, origin + pathname + searchParams);
779              });
780            } else {
781              // Hide view more button.
782              $(".view-more").hide();
783            }
784          }
785        });
786      } // $('.search-filters .form-select', context).on('change', function() {
787      // console.log('filter change');
788      // });
789
790
791      $(".search-filters .form-submit", context).on("click", function () {
792        // console.log('filter submit');
793        // build search url parameters
794        var params = [];
795        $(".select-item").each(function () {
796          var $select = $(this).find($("select"));
797          var name = $select.attr("name");
798          var value = $select.val();
799          params.push(name + "=" + value); // // place pill
800          // if (name != 'items_per_page') {
801          //     if (Array.isArray(value)) {
802          //         let text = [];
803          //         $select.find("option:selected").each(function () {
804          //             text.push($(this).text());
805          //         });
806          //         $.each(value, function(index, element) {
807          //             $('.filters-pills').append(Pill({
808          //                 label: text[index],
809          //                 name: name,
810          //                 value: element,
811          //             }));
812          //         });
813          //     } else {
814          //         let text = $select.find("option:selected").text();
815          //         if (value !== "All") {
816          //             $('.filters-pills').append(Pill({
817          //                 label: text,
818          //                 name: name,
819          //                 value: value,
820          //             }));
821          //         }
822          //     }
823          // }
824        });
825
826        if (params) {
827          params = params.join("&");
828          params = "?" + params;
829          loadSearchResults(SEARCH_URL + params);
830          history.replaceState(params, null, origin + pathname + params);
831        } else {
832          loadSearchResults(SEARCH_URL);
833          history.replaceState(null, null, origin + pathname);
834        }
835      }); // Reset
836
837      $(".search-filters .form-reset", context).on("click", function () {
838        loadSearchResults(SEARCH_URL);
839        history.replaceState(null, null, origin + pathname);
840      }); // urls
841      // window.addEventListener('popstate', function(e) {
842
843      window.onpopstate = function (e) {
844        console.log("e", e);
845
846        if (e.state) {
847          console.log("e.state", e.state);
848          loadSearchResults(SEARCH_URL + e.state);
849        } else {
850          loadSearchResults(SEARCH_URL);
851        }
852      }; // });
853      // mobile filters
854      // btn show filters
855
856
857      $(".btn-filters", context).on("click", function () {
858        $(".search-filters .filters-wrapper").addClass("show-filters");
859        $("body").addClass("modal-open");
860      }); // close filters
861
862      $(".search-filters .filters-close").on("click", function (e) {
863        $(".search-filters .filters-wrapper").removeClass("show-filters");
864        $("body").removeClass("modal-open");
865      });
866
867      function initSearch() {
868        $(".search-content", context).each(function () {
869          var searchParams = new URLSearchParams(window.location.search);
870          searchParams = searchParams.toString();
871
872          if (searchParams) {
873            // console.log('has searchParams')
874            searchParams = "?" + searchParams;
875          }
876
877          loadSearchResults(SEARCH_URL + searchParams);
878        });
879      }
880
881      initSearch();
882    }
883  };
884})(jQuery, Drupal);
885
886/***/ }),
887
888/***/ 17:
889/*!*********************************************************!*\
890  !*** multi ./src/components/search-rest/search-rest.js ***!
891  \*********************************************************/
892/*! no static exports found */
893/***/ (function(module, exports, __webpack_require__) {
894
895module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/search-rest/search-rest.js */"./src/components/search-rest/search-rest.js");
896
897
898/***/ })
899
900/******/ });;
901(function ($) {
902
903	var $stickyFilter = $(".sticky-filter");
904    var subNavPosition = $stickyFilter.offset().top;
905
906    var $mainNav = $("#navbar");
907	var initHeaderHeight = $mainNav.outerHeight();
908	
909	var isToolbarFixed = $('body').hasClass('toolbar-fixed');
910
911	// if ($stickyFilter.is(':visible')){
912		$stickyFilter.css("top", initHeaderHeight+"px");
913	// }
914
915    $( window ).resize(function() {
916    	subNavPosition = $stickyFilter.offset().top;
917    	initHeaderHeight = $mainNav.outerHeight();
918		$stickyFilter.css("top", initHeaderHeight+"px");
919    });
920
921
922	function snapMenus() {
923		var scrollTop = $(document).scrollTop() + initHeaderHeight;
924		var subNavHeight = $stickyFilter.outerHeight(true);
925		
926
927		if (scrollTop >= subNavPosition && $stickyFilter.is(':visible') ) {
928			$stickyFilter.addClass("sticky");
929			$stickyFilter.parent().css("margin-top", subNavHeight+"px");
930
931			if (scrollTop >= subNavPosition + initHeaderHeight){
932				$stickyFilter.addClass("pushed-up");
933				$mainNav.addClass("pushed-up");
934			} else {
935				$stickyFilter.removeClass("pushed-up");
936			}	
937			
938		} else {
939			$mainNav.removeClass("pushed-up");
940			$stickyFilter.removeClass("sticky");
941			$stickyFilter.parent().css("margin-top",0);
942		}
943	}
944
945    window.addEventListener('scroll', function(e){
946		if (!isToolbarFixed) {
947			//run on scroll
948			snapMenus();
949		}
950    });    
951
952	//run on load
953	if (!isToolbarFixed) {
954		snapMenus();
955	}
956	
957
958})(jQuery);;
959/*!
960 * Bootstrap-select v1.14.0-beta3 (https://developer.snapappointments.com/bootstrap-select)
961 *
962 * Copyright 2012-2023 SnapAppointments, LLC
963 * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE)
964 */
965
966(function (root, factory) {
967  if (root === undefined && window !== undefined) root = window;
968  if (typeof define === 'function' && define.amd) {
969    // AMD. Register as an anonymous module unless amdModuleId is set
970    define(["jquery"], function (a0) {
971      return (factory(a0));
972    });
973  } else if (typeof module === 'object' && module.exports) {
974    // Node. Does not work with strict CommonJS, but
975    // only CommonJS-like environments that support module.exports,
976    // like Node.
977    module.exports = factory(require("jquery"));
978  } else {
979    factory(root["jQuery"]);
980  }
981}(this, function (jQuery) {
982
983(function ($) {
984  'use strict';
985
986  var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
987
988  var uriAttrs = [
989    'background',
990    'cite',
991    'href',
992    'itemtype',
993    'longdesc',
994    'poster',
995    'src',
996    'xlink:href'
997  ];
998
999  var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
1000
1001  var DefaultWhitelist = {
1002    // Global attributes allowed on any supplied element below.
1003    '*': ['class', 'dir', 'id', 'lang', 'role', 'tabindex', 'style', ARIA_ATTRIBUTE_PATTERN],
1004    a: ['target', 'href', 'title', 'rel'],
1005    area: [],
1006    b: [],
1007    br: [],
1008    col: [],
1009    code: [],
1010    div: [],
1011    em: [],
1012    hr: [],
1013    h1: [],
1014    h2: [],
1015    h3: [],
1016    h4: [],
1017    h5: [],
1018    h6: [],
1019    i: [],
1020    img: ['src', 'alt', 'title', 'width', 'height'],
1021    li: [],
1022    ol: [],
1023    p: [],
1024    pre: [],
1025    s: [],
1026    small: [],
1027    span: [],
1028    sub: [],
1029    sup: [],
1030    strong: [],
1031    u: [],
1032    ul: []
1033  };
1034
1035  /**
1036   * A pattern that recognizes a commonly useful subset of URLs that are safe.
1037   *
1038   * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
1039   */
1040  var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
1041
1042  /**
1043   * A pattern that matches safe data URLs. Only matches image, video and audio types.
1044   *
1045   * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
1046   */
1047  var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;
1048
1049  var ParseableAttributes = ['title', 'placeholder']; // attributes to use as settings, can add others in the future
1050
1051  function allowedAttribute (attr, allowedAttributeList) {
1052    var attrName = attr.nodeName.toLowerCase();
1053
1054    if ($.inArray(attrName, allowedAttributeList) !== -1) {
1055      if ($.inArray(attrName, uriAttrs) !== -1) {
1056        return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));
1057      }
1058
1059      return true;
1060    }
1061
1062    var regExp = $(allowedAttributeList).filter(function (index, value) {
1063      return value instanceof RegExp;
1064    });
1065
1066    // Check if a regular expression validates the attribute.
1067    for (var i = 0, l = regExp.length; i < l; i++) {
1068      if (attrName.match(regExp[i])) {
1069        return true;
1070      }
1071    }
1072
1073    return false;
1074  }
1075
1076  function sanitizeHtml (unsafeElements, whiteList, sanitizeFn) {
1077    if (sanitizeFn && typeof sanitizeFn === 'function') {
1078      return sanitizeFn(unsafeElements);
1079    }
1080
1081    var whitelistKeys = Object.keys(whiteList);
1082
1083    for (var i = 0, len = unsafeElements.length; i < len; i++) {
1084      var elements = unsafeElements[i].querySelectorAll('*');
1085
1086      for (var j = 0, len2 = elements.length; j < len2; j++) {
1087        var el = elements[j];
1088        var elName = el.nodeName.toLowerCase();
1089
1090        if (whitelistKeys.indexOf(elName) === -1) {
1091          el.parentNode.removeChild(el);
1092
1093          continue;
1094        }
1095
1096        var attributeList = [].slice.call(el.attributes);
1097        var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
1098
1099        for (var k = 0, len3 = attributeList.length; k < len3; k++) {
1100          var attr = attributeList[k];
1101
1102          if (!allowedAttribute(attr, whitelistedAttributes)) {
1103            el.removeAttribute(attr.nodeName);
1104          }
1105        }
1106      }
1107    }
1108  }
1109
1110  // function srSpeak(text, priority) {
1111  //     var el = document.createElement("div");
1112  //     var id = "speak-" + Date.now();
1113  //     el.setAttribute("id", id);
1114  //     el.setAttribute("aria-live", priority || "polite");
1115  //     el.classList.add("visually-hidden");
1116  //     document.body.appendChild(el);
1117
1118  //     window.setTimeout(function () {
1119  //       document.getElementById(id).innerHTML = text;
1120  //     }, 100);
1121
1122  //     window.setTimeout(function () {
1123  //         document.body.removeChild(document.getElementById(id));
1124  //     }, 1000);
1125  // }
1126
1127  function getAttributesObject ($select) {
1128    var attributesObject = {},
1129        attrVal;
1130
1131    ParseableAttributes.forEach(function (item) {
1132      attrVal = $select.attr(item);
1133      if (attrVal) attributesObject[item] = attrVal;
1134    });
1135
1136    // for backwards compatibility
1137    // (using title as placeholder is deprecated - remove in v2.0.0)
1138    if (!attributesObject.placeholder && attributesObject.title) {
1139      attributesObject.placeholder = attributesObject.title;
1140    }
1141
1142    return attributesObject;
1143  }
1144
1145  // Polyfill for browsers with no classList support
1146  // Remove in v2
1147  if (!('classList' in document.createElement('_'))) {
1148    (function (view) {
1149      if (!('Element' in view)) return;
1150
1151      var classListProp = 'classList',
1152          protoProp = 'prototype',
1153          elemCtrProto = view.Element[protoProp],
1154          objCtr = Object,
1155          classListGetter = function () {
1156            var $elem = $(this);
1157
1158            return {
1159              add: function (classes) {
1160                classes = Array.prototype.slice.call(arguments).join(' ');
1161                return $elem.addClass(classes);
1162              },
1163              remove: function (classes) {
1164                classes = Array.prototype.slice.call(arguments).join(' ');
1165                return $elem.removeClass(classes);
1166              },
1167              toggle: function (classes, force) {
1168                return $elem.toggleClass(classes, force);
1169              },
1170              contains: function (classes) {
1171                return $elem.hasClass(classes);
1172              }
1173            };
1174          };
1175
1176      if (objCtr.defineProperty) {
1177        var classListPropDesc = {
1178          get: classListGetter,
1179          enumerable: true,
1180          configurable: true
1181        };
1182        try {
1183          objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
1184        } catch (ex) { // IE 8 doesn't support enumerable:true
1185          // adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36
1186          // modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected
1187          if (ex.number === undefined || ex.number === -0x7FF5EC54) {
1188            classListPropDesc.enumerable = false;
1189            objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
1190          }
1191        }
1192      } else if (objCtr[protoProp].__defineGetter__) {
1193        elemCtrProto.__defineGetter__(classListProp, classListGetter);
1194      }
1195    }(window));
1196  }
1197
1198  var testElement = document.createElement('_');
1199
1200  testElement.classList.add('c1', 'c2');
1201
1202  if (!testElement.classList.contains('c2')) {
1203    var _add = DOMTokenList.prototype.add,
1204        _remove = DOMTokenList.prototype.remove;
1205
1206    DOMTokenList.prototype.add = function () {
1207      Array.prototype.forEach.call(arguments, _add.bind(this));
1208    };
1209
1210    DOMTokenList.prototype.remove = function () {
1211      Array.prototype.forEach.call(arguments, _remove.bind(this));
1212    };
1213  }
1214
1215  testElement.classList.toggle('c3', false);
1216
1217  // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
1218  // support the second argument.
1219  if (testElement.classList.contains('c3')) {
1220    var _toggle = DOMTokenList.prototype.toggle;
1221
1222    DOMTokenList.prototype.toggle = function (token, force) {
1223      if (1 in arguments && !this.contains(token) === !force) {
1224        return force;
1225      } else {
1226        return _toggle.call(this, token);
1227      }
1228    };
1229  }
1230
1231  testElement = null;
1232
1233  // Polyfill for IE (remove in v2)
1234  Object.values = typeof Object.values === 'function' ? Object.values : function (obj) {
1235    return Object.keys(obj).map(function (key) {
1236      return obj[key];
1237    });
1238  };
1239
1240  // shallow array comparison
1241  function isEqual (array1, array2) {
1242    return array1.length === array2.length && array1.every(function (element, index) {
1243      return element === array2[index];
1244    });
1245  };
1246
1247  // <editor-fold desc="Shims">
1248  if (!String.prototype.startsWith) {
1249    (function () {
1250      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
1251      var toString = {}.toString;
1252      var startsWith = function (search) {
1253        if (this == null) {
1254          throw new TypeError();
1255        }
1256        var string = String(this);
1257        if (search && toString.call(search) == '[object RegExp]') {
1258          throw new TypeError();
1259        }
1260        var stringLength = string.length;
1261        var searchString = String(search);
1262        var searchLength = searchString.length;
1263        var position = arguments.length > 1 ? arguments[1] : undefined;
1264        // `ToInteger`
1265        var pos = position ? Number(position) : 0;
1266        if (pos != pos) { // better `isNaN`
1267          pos = 0;
1268        }
1269        var start = Math.min(Math.max(pos, 0), stringLength);
1270        // Avoid the `indexOf` call if no match is possible
1271        if (searchLength + start > stringLength) {
1272          return false;
1273        }
1274        var index = -1;
1275        while (++index < searchLength) {
1276          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {
1277            return false;
1278          }
1279        }
1280        return true;
1281      };
1282      if (Object.defineProperty) {
1283        Object.defineProperty(String.prototype, 'startsWith', {
1284          'value': startsWith,
1285          'configurable': true,
1286          'writable': true
1287        });
1288      } else {
1289        String.prototype.startsWith = startsWith;
1290      }
1291    }());
1292  }
1293
1294  function toKebabCase (str) {
1295    return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, function ($, ofs) {
1296      return (ofs ? '-' : '') + $.toLowerCase();
1297    });
1298  }
1299
1300  function getSelectedOptions () {
1301    var options = this.selectpicker.main.data;
1302
1303    if (this.options.source.data || this.options.source.search) {
1304      options = Object.values(this.selectpicker.optionValuesDataMap);
1305    }
1306
1307    var selectedOptions = options.filter(function (item) {
1308      if (item.selected) {
1309        if (this.options.hideDisabled && item.disabled) return false;
1310        return true;
1311      }
1312
1313      return false;
1314    }, this);
1315
1316    // ensure only 1 option is selected if multiple are set in the data source
1317    if (this.options.source.data && !this.multiple && selectedOptions.length > 1) {
1318      for (var i = 0; i < selectedOptions.length - 1; i++) {
1319        selectedOptions[i].selected = false;
1320      }
1321
1322      selectedOptions = [ selectedOptions[selectedOptions.length - 1] ];
1323    }
1324
1325    return selectedOptions;
1326  }
1327
1328  // much faster than $.val()
1329  function getSelectValues (selectedOptions) {
1330    var value = [],
1331        options = selectedOptions || getSelectedOptions.call(this),
1332        opt;
1333
1334    for (var i = 0, len = options.length; i < len; i++) {
1335      opt = options[i];
1336
1337      if (!opt.disabled) {
1338        value.push(opt.value === undefined ? opt.text : opt.value);
1339      }
1340    }
1341
1342    if (!this.multiple) {
1343      return !value.length ? null : value[0];
1344    }
1345
1346    return value;
1347  }
1348
1349  // set data-selected on select element if the value has been programmatically selected
1350  // prior to initialization of bootstrap-select
1351  // * consider removing or replacing an alternative method *
1352  var valHooks = {
1353    useDefault: false,
1354    _set: $.valHooks.select.set
1355  };
1356
1357  $.valHooks.select.set = function (elem, value) {
1358    if (value && !valHooks.useDefault) $(elem).data('selected', true);
1359
1360    return valHooks._set.apply(this, arguments);
1361  };
1362
1363  var changedArguments = null;
1364
1365  var EventIsSupported = (function () {
1366    try {
1367      new Event('change');
1368      return true;
1369    } catch (e) {
1370      return false;
1371    }
1372  })();
1373
1374  $.fn.triggerNative = function (eventName) {
1375    var el = this[0],
1376        event;
1377
1378    if (el.dispatchEvent) { // for modern browsers & IE9+
1379      if (EventIsSupported) {
1380        // For modern browsers
1381        event = new Event(eventName, {
1382          bubbles: true
1383        });
1384      } else {
1385        // For IE since it doesn't support Event constructor
1386        event = document.createEvent('Event');
1387        event.initEvent(eventName, true, false);
1388      }
1389
1390      el.dispatchEvent(event);
1391    }
1392  };
1393  // </editor-fold>
1394
1395  function stringSearch (li, searchString, method, normalize) {
1396    var stringTypes = [
1397          'display',
1398          'subtext',
1399          'tokens'
1400        ],
1401        searchSuccess = false;
1402
1403    for (var i = 0; i < stringTypes.length; i++) {
1404      var stringType = stringTypes[i],
1405          string = li[stringType];
1406
1407      if (string) {
1408        string = string.toString();
1409
1410        // Strip HTML tags. This isn't perfect, but it's much faster than any other method
1411        if (stringType === 'display') {
1412          string = string.replace(/<[^>]+>/g, '');
1413        }
1414
1415        if (normalize) string = normalizeToBase(string);
1416        string = string.toUpperCase();
1417
1418        if (typeof method === 'function') {
1419          searchSuccess = method(string, searchString);
1420        } else if (method === 'contains') {
1421          searchSuccess = string.indexOf(searchString) >= 0;
1422        } else if (method === 'containsAll') {
1423          var searchArray = searchString.split(' ');
1424          var notAllMatched = false;
1425          searchSuccess = false;
1426
1427          for (var searchSubString in searchArray) {
1428            searchSuccess = string.indexOf(searchArray[searchSubString]) >= 0;
1429            if (!searchSuccess) notAllMatched = true;
1430          }
1431
1432          if (notAllMatched) searchSuccess = false;
1433        } else {
1434          searchSuccess = string.startsWith(searchString);
1435        }
1436
1437        if (searchSuccess) break;
1438      }
1439    }
1440
1441    return searchSuccess;
1442  }
1443
1444  function toInteger (value) {
1445    return parseInt(value, 10) || 0;
1446  }
1447
1448  // Borrowed from Lodash (_.deburr)
1449  /** Used to map Latin Unicode letters to basic Latin letters. */
1450  var deburredLetters = {
1451    // Latin-1 Supplement block.
1452    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
1453    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
1454    '\xc7': 'C',  '\xe7': 'c',
1455    '\xd0': 'D',  '\xf0': 'd',
1456    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
1457    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
1458    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
1459    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
1460    '\xd1': 'N',  '\xf1': 'n',
1461    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
1462    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
1463    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
1464    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
1465    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
1466    '\xc6': 'Ae', '\xe6': 'ae',
1467    '\xde': 'Th', '\xfe': 'th',
1468    '\xdf': 'ss',
1469    // Latin Extended-A block.
1470    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
1471    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
1472    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
1473    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
1474    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
1475    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
1476    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
1477    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
1478    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
1479    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
1480    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
1481    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
1482    '\u0134': 'J',  '\u0135': 'j',
1483    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
1484    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
1485    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
1486    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
1487    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
1488    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
1489    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
1490    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
1491    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
1492    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
1493    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
1494    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
1495    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
1496    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
1497    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
1498    '\u0174': 'W',  '\u0175': 'w',
1499    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
1500    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
1501    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
1502    '\u0132': 'IJ', '\u0133': 'ij',
1503    '\u0152': 'Oe', '\u0153': 'oe',
1504    '\u0149': "'n", '\u017f': 's'
1505  };
1506
1507  /** Used to match Latin Unicode letters (excluding mathematical operators). */
1508  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
1509
1510  /** Used to compose unicode character classes. */
1511  var rsComboMarksRange = '\\u0300-\\u036f',
1512      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
1513      rsComboSymbolsRange = '\\u20d0-\\u20ff',
1514      rsComboMarksExtendedRange = '\\u1ab0-\\u1aff',
1515      rsComboMarksSupplementRange = '\\u1dc0-\\u1dff',
1516      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange;
1517
1518  /** Used to compose unicode capture groups. */
1519  var rsCombo = '[' + rsComboRange + ']';
1520
1521  /**
1522   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
1523   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
1524   */
1525  var reComboMark = RegExp(rsCombo, 'g');
1526
1527  function deburrLetter (key) {
1528    return deburredLetters[key];
1529  };
1530
1531  function normalizeToBase (string) {
1532    string = string.toString();
1533    return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
1534  }
1535
1536  // List of HTML entities for escaping.
1537  var escapeMap = {
1538    '&': '&amp;',
1539    '<': '&lt;',
1540    '>': '&gt;',
1541    '"': '&quot;',
1542    "'": '&#x27;',
1543    '`': '&#x60;'
1544  };
1545
1546  // Functions for escaping and unescaping strings to/from HTML interpolation.
1547  var createEscaper = function (map) {
1548    var escaper = function (match) {
1549      return map[match];
1550    };
1551    // Regexes for identifying a key that needs to be escaped.
1552    var source = '(?:' + Object.keys(map).join('|') + ')';
1553    var testRegexp = RegExp(source);
1554    var replaceRegexp = RegExp(source, 'g');
1555    return function (string) {
1556      string = string == null ? '' : '' + string;
1557      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
1558    };
1559  };
1560
1561  var htmlEscape = createEscaper(escapeMap);
1562
1563  /**
1564   * ------------------------------------------------------------------------
1565   * Constants
1566   * ------------------------------------------------------------------------
1567   */
1568
1569  var keyCodeMap = {
1570    32: ' ',
1571    48: '0',
1572    49: '1',
1573    50: '2',
1574    51: '3',
1575    52: '4',
1576    53: '5',
1577    54: '6',
1578    55: '7',
1579    56: '8',
1580    57: '9',
1581    59: ';',
1582    65: 'A',
1583    66: 'B',
1584    67: 'C',
1585    68: 'D',
1586    69: 'E',
1587    70: 'F',
1588    71: 'G',
1589    72: 'H',
1590    73: 'I',
1591    74: 'J',
1592    75: 'K',
1593    76: 'L',
1594    77: 'M',
1595    78: 'N',
1596    79: 'O',
1597    80: 'P',
1598    81: 'Q',
1599    82: 'R',
1600    83: 'S',
1601    84: 'T',
1602    85: 'U',
1603    86: 'V',
1604    87: 'W',
1605    88: 'X',
1606    89: 'Y',
1607    90: 'Z',
1608    96: '0',
1609    97: '1',
1610    98: '2',
1611    99: '3',
1612    100: '4',
1613    101: '5',
1614    102: '6',
1615    103: '7',
1616    104: '8',
1617    105: '9'
1618  };
1619
1620  var keyCodes = {
1621    ESCAPE: 27, // KeyboardEvent.which value for Escape (Esc) key
1622    ENTER: 13, // KeyboardEvent.which value for Enter key
1623    SPACE: 32, // KeyboardEvent.which value for space key
1624    TAB: 9, // KeyboardEvent.which value for tab key
1625    ARROW_UP: 38, // KeyboardEvent.which value for up arrow key
1626    ARROW_DOWN: 40 // KeyboardEvent.which value for down arrow key
1627  };
1628
1629  var Dropdown = window.Dropdown || window.bootstrap && window.bootstrap.Dropdown;
1630
1631  function getVersion () {
1632    var version;
1633
1634    try {
1635      version = $.fn.dropdown.Constructor.VERSION;
1636    } catch (err) {
1637      version = Dropdown.VERSION;
1638    }
1639
1640    return version;
1641  }
1642
1643  var version = {
1644    success: false,
1645    major: '3'
1646  };
1647
1648  try {
1649    version.full = (getVersion() || '').split(' ')[0].split('.');
1650    version.major = version.full[0];
1651    version.success = true;
1652  } catch (err) {
1653    // do nothing
1654  }
1655
1656  var selectId = 0;
1657
1658  var EVENT_KEY = '.bs.select';
1659
1660  var classNames = {
1661    DISABLED: 'disabled',
1662    DIVIDER: 'divider',
1663    SHOW: 'open',
1664    DROPUP: 'dropup',
1665    MENU: 'dropdown-menu',
1666    MENURIGHT: 'dropdown-menu-right',
1667    MENULEFT: 'dropdown-menu-left',
1668    // to-do: replace with more advanced template/customization options
1669    BUTTONCLASS: 'btn-default',
1670    POPOVERHEADER: 'popover-title',
1671    ICONBASE: 'glyphicon',
1672    TICKICON: 'glyphicon-ok'
1673  };
1674
1675  var Selector = {
1676    MENU: '.' + classNames.MENU,
1677    DATA_TOGGLE: 'data-toggle="dropdown"'
1678  };
1679
1680  var elementTemplates = {
1681    div: document.createElement('div'),
1682    span: document.createElement('span'),
1683    i: document.createElement('i'),
1684    subtext: document.createElement('small'),
1685    // TODO remove <a>
1686    a: document.createElement('span'),
1687    li: document.createElement('li'),
1688    whitespace: document.createTextNode('\u00A0'),
1689    fragment: document.createDocumentFragment(),
1690    option: document.createElement('option'),
1691    group: document.createElement('li'),
1692    listbox: document.createElement('ul'),
1693    groupNotice: document.createElement('span')
1694  };
1695
1696  var hiddenContent = " group. Selecting this option will toggle all items in this group.";
1697  elementTemplates.groupNotice.className = 'sr-only';  
1698  elementTemplates.groupNotice.innerText = hiddenContent;
1699
1700                
1701
1702  elementTemplates.selectedOption = elementTemplates.option.cloneNode(false);
1703  elementTemplates.selectedOption.setAttribute('selected', true);
1704
1705  elementTemplates.noResults = elementTemplates.li.cloneNode(false);
1706  elementTemplates.noResults.className = 'no-results';
1707
1708  elementTemplates.li.setAttribute('role', 'option');
1709  // elementTemplates.li.className = 'dropdown-item';
1710
1711  // TODO remove <a>
1712  // elementTemplates.a.setAttribute('role', 'option');
1713  elementTemplates.a.className = 'dropdown-item';
1714
1715  elementTemplates.subtext.className = 'text-muted';
1716
1717  elementTemplates.text = elementTemplates.span.cloneNode(false);
1718  elementTemplates.text.className = 'text';
1719
1720  elementTemplates.group.className = 'group';
1721  elementTemplates.group.setAttribute('role', 'group');
1722
1723  elementTemplates.listbox.className = 'group-options list-unstyled';
1724  elementTemplates.listbox.setAttribute('role', 'listbox');
1725
1726  elementTemplates.checkMark = elementTemplates.span.cloneNode(false);
1727
1728  var REGEXP_ARROW = new RegExp(keyCodes.ARROW_UP + '|' + keyCodes.ARROW_DOWN);
1729  var REGEXP_TAB_OR_ESCAPE = new RegExp('^' + keyCodes.TAB + '$|' + keyCodes.ESCAPE);
1730
1731  var generateOption = {
1732
1733    li: function (content, classes, optgroup) {
1734      var li = elementTemplates.li.cloneNode(false);
1735      if (content) {
1736        if (content.nodeType === 1 || content.nodeType === 11) {
1737          li.appendChild(content);
1738        } else {
1739          li.innerHTML = content;
1740        }
1741      }
1742
1743      if (typeof classes !== 'undefined' && classes !== '') li.className = classes;
1744      if (typeof optgroup !== 'undefined' && optgroup !== null) li.classList.add('optgroup-' + optgroup);
1745
1746      return li;
1747    },
1748
1749    a: function (text, classes, inline) {
1750      var a = elementTemplates.a.cloneNode(true);
1751      if (text) {
1752        if (text.nodeType === 11) {
1753          a.appendChild(text);
1754        } else {
1755          a.insertAdjacentHTML('beforeend', text);
1756        }
1757      }
1758      if (typeof classes !== 'undefined' && classes !== '') a.classList.add.apply(a.classList, classes.split(/\s+/));
1759      if (inline) a.setAttribute('style', inline);
1760
1761      return a;
1762    },
1763
1764    text: function (options, useFragment) {
1765      var textElement = elementTemplates.text.cloneNode(false),
1766          subtextElement,
1767          iconElement;
1768
1769      if (options.content) {
1770        textElement.innerHTML = options.content;
1771      } else {
1772        textElement.textContent = options.text;
1773
1774        if (options.icon) {
1775          var whitespace = elementTemplates.whitespace.cloneNode(false);
1776
1777          // need to use <i> for icons in the button to prevent a breaking change
1778          // note: switch to span in next major release
1779          iconElement = (useFragment === true ? elementTemplates.i : elementTemplates.span).cloneNode(false);
1780          iconElement.className = this.options.iconBase + ' ' + options.icon;
1781
1782          elementTemplates.fragment.appendChild(iconElement);
1783          elementTemplates.fragment.appendChild(whitespace);
1784        }
1785
1786        if (options.subtext) {
1787          subtextElement = elementTemplates.subtext.cloneNode(false);
1788          subtextElement.textContent = options.subtext;
1789          textElement.appendChild(subtextElement);
1790        }
1791      }
1792
1793      if (useFragment === true) {
1794        while (textElement.childNodes.length > 0) {
1795          elementTemplates.fragment.appendChild(textElement.childNodes[0]);
1796        }
1797      } else {
1798        elementTemplates.fragment.appendChild(textElement);
1799      }
1800
1801      return elementTemplates.fragment;
1802    },
1803
1804    label: function (options) {
1805      // generate a option group label
1806      // TODO remove
1807      var textElement = elementTemplates.text.cloneNode(false),
1808          subtextElement,
1809          iconElement;
1810
1811      textElement.innerHTML = options.display;
1812
1813      if (options.icon) {
1814        var whitespace = elementTemplates.whitespace.cloneNode(false);
1815
1816        iconElement = elementTemplates.span.cloneNode(false);
1817        iconElement.className = this.options.iconBase + ' ' + options.icon;
1818
1819        elementTemplates.fragment.appendChild(iconElement);
1820        elementTemplates.fragment.appendChild(whitespace);
1821      }
1822
1823      if (options.subtext) {
1824        subtextElement = elementTemplates.subtext.cloneNode(false);
1825        subtextElement.textContent = options.subtext;
1826        textElement.appendChild(subtextElement);
1827      }
1828
1829      elementTemplates.fragment.appendChild(textElement);
1830
1831      return elementTemplates.fragment;
1832    }
1833  };
1834
1835  var getOptionData = {
1836    fromOption: function (option, type) {
1837      var value;
1838
1839      switch (type) {
1840        case 'divider':
1841          value = option.getAttribute('data-divider') === 'true';
1842          break;
1843
1844        case 'text':
1845          value = option.textContent;
1846          break;
1847
1848        case 'label':
1849          value = option.label;
1850          break;
1851
1852        case 'style':
1853          value = option.style.cssText;
1854          break;
1855
1856        case 'title':
1857          value = option.title;
1858          break;
1859
1860        default:
1861          value = option.getAttribute('data-' + toKebabCase(type));
1862          break;
1863      }
1864
1865      return value;
1866    },
1867    fromDataSource: function (option, type) {
1868      var value;
1869
1870      switch (type) {
1871        case 'text':
1872        case 'label':
1873          value = option.text || option.value || '';
1874          break;
1875
1876        default:
1877          value = option[type];
1878          break;
1879      }
1880
1881      return value;
1882    }
1883  };
1884
1885  function showNoResults (searchMatch, searchValue) {
1886    if (!searchMatch.length) {
1887      elementTemplates.noResults.innerHTML = this.options.noneResultsText.replace('{0}', '"' + htmlEscape(searchValue) + '"');
1888      this.$menuInner[0].firstChild.appendChild(elementTemplates.noResults);
1889    }
1890  }
1891
1892  function filterHidden (item) {
1893    return !(item.hidden || this.options.hideDisabled && item.disabled);
1894  }
1895
1896  var Selectpicker = function (element, options) {
1897    var that = this;
1898
1899    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function
1900    if (!valHooks.useDefault) {
1901      $.valHooks.select.set = valHooks._set;
1902      valHooks.useDefault = true;
1903    }
1904
1905    this.$element = $(element);
1906    this.$newElement = null;
1907    this.$button = null;
1908    this.$menu = null;
1909    this.options = options;
1910    this.selectpicker = {
1911      main: {
1912        data: [],
1913        optionQueue: elementTemplates.fragment.cloneNode(false),
1914        hasMore: false
1915      },
1916      search: {
1917        data: [],
1918        hasMore: false
1919      },
1920      current: {}, // current is either equal to main or search depending on if a search is in progress
1921      view: {},
1922      // map of option values and their respective data (only used in conjunction with options.source)
1923      optionValuesDataMap: {},
1924      isSearching: false,
1925      keydown: {
1926        keyHistory: '',
1927        resetKeyHistory: {
1928          start: function () {
1929            return setTimeout(function () {
1930              that.selectpicker.keydown.keyHistory = '';
1931            }, 800);
1932          }
1933        }
1934      }
1935    };
1936
1937    this.sizeInfo = {};
1938
1939    // Format window padding
1940    var winPad = this.options.windowPadding;
1941    if (typeof winPad === 'number') {
1942      this.options.windowPadding = [winPad, winPad, winPad, winPad];
1943    }
1944
1945    // Expose public methods
1946    this.val = Selectpicker.prototype.val;
1947    this.render = Selectpicker.prototype.render;
1948    this.refresh = Selectpicker.prototype.refresh;
1949    this.setStyle = Selectpicker.prototype.setStyle;
1950    this.selectAll = Selectpicker.prototype.selectAll;
1951    this.deselectAll = Selectpicker.prototype.deselectAll;
1952    this.destroy = Selectpicker.prototype.destroy;
1953    this.remove = Selectpicker.prototype.remove;
1954    this.show = Selectpicker.prototype.show;
1955    this.hide = Selectpicker.prototype.hide;
1956
1957    this.init();
1958  };
1959
1960  Selectpicker.VERSION = '1.14.0-beta3';
1961
1962  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.
1963  Selectpicker.DEFAULTS = {
1964    noneSelectedText: 'Nothing selected',
1965    noneResultsText: 'No results matched {0}',
1966    countSelectedText: function (numSelected, numTotal) {
1967      return (numSelected == 1) ? '{0} item selected' : '{0} items selected';
1968    },
1969    maxOptionsText: function (numAll, numGroup) {
1970      return [
1971        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',
1972        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'
1973      ];
1974    },
1975    selectAllText: 'Select All',
1976    deselectAllText: 'Deselect All',
1977    source: {
1978      pageSize: 40
1979    },
1980    chunkSize: 40,
1981    doneButton: false,
1982    doneButtonText: 'Close',
1983    multipleSeparator: ', ',
1984    styleBase: 'btn',
1985    style: classNames.BUTTONCLASS,
1986    size: 'auto',
1987    title: null,
1988    placeholder: null,
1989    titleTip: null,
1990    allowClear: false,
1991    selectedTextFormat: 'values',
1992    width: false,
1993    container: false,
1994    hideDisabled: false,
1995    showSubtext: false,
1996    showIcon: true,
1997    showContent: true,
1998    dropupAuto: true,
1999    header: false,
2000    liveSearch: false,
2001    liveSearchPlaceholder: null,
2002    liveSearchNormalize: false,
2003    liveSearchStyle: 'contains',
2004    actionsBox: false,
2005    iconBase: classNames.ICONBASE,
2006    tickIcon: classNames.TICKICON,
2007    showTick: false,
2008    template: {
2009      caret: '<span class="caret"></span>'
2010    },
2011    maxOptions: false,
2012    mobile: false,
2013    selectOnTab: false,
2014    dropdownAlignRight: false,
2015    windowPadding: 0,
2016    virtualScroll: 600,
2017    display: false,
2018    sanitize: true,
2019    sanitizeFn: null,
2020    whiteList: DefaultWhitelist
2021  };
2022
2023  Selectpicker.prototype = {
2024
2025    constructor: Selectpicker,
2026
2027    init: function () {
2028      var that = this,
2029          id = this.$element.attr('id'),
2030          element = this.$element[0],
2031          form = element.form;
2032
2033      selectId++;
2034      this.selectId = 'bs-select-' + selectId;
2035
2036      // add tabindex -1 and aria hidden to hidden <select> element
2037      this.$element.attr('tabindex', '-1').attr('aria-hidden', 'true');
2038
2039      element.classList.add('bs-select-hidden');
2040
2041      this.multiple = this.$element.prop('multiple');
2042      this.autofocus = this.$element.prop('autofocus');
2043
2044      // if the current select has a label
2045      // change it to be associated to the button bar instead
2046      var label = $('label[for="' + id + '"]').get(0);
2047      var labelID;
2048      if ($(label).attr('id')){
2049        labelID = $(label).attr('id');
2050      } else {
2051        labelID = 'bs-label-' + selectId;
2052        $(label).attr('id', labelID);
2053      }
2054
2055
2056
2057      if (element.classList.contains('show-tick')) {
2058        this.options.showTick = true;
2059      }
2060
2061      this.$newElement = this.createDropdown();
2062
2063      this.$element
2064        .after(this.$newElement)
2065        .prependTo(this.$newElement);
2066
2067      // ensure select is associated with form element if it got unlinked after mov
2067ing it inside newElement
2068      if (form && element.form === null) {
2069        if (!form.id) form.id = 'form-' + this.selectId;
2070        element.setAttribute('form', form.id);
2071      }
2072
2073
2074
2075      this.$button = this.$newElement.children('button');
2076
2077      if (this.options.allowClear) this.$clearButton = this.$button.children('.bs-select-clear-selected');
2078      this.$menu = this.$newElement.children(Selector.MENU);
2079      this.$menuInner = this.$menu.children('.inner');
2080      this.$searchbox = this.$menu.find('input');
2081
2082      element.classList.remove('bs-select-hidden');
2083
2084      this.fetchData(function () {
2085        that.render(true);
2086        that.buildList();
2087
2088        requestAnimationFrame(function () {
2089          that.$element.trigger('loaded' + EVENT_KEY);
2090        });
2091      });
2092
2093      if (this.options.dropdownAlignRight === true) this.$menu[0].classList.add(classNames.MENURIGHT);
2094
2095      if (typeof id !== 'undefined') {
2096        this.$button.attr('data-id', id);
2097      }
2098
2099      if (typeof labelID !== 'undefined') {
2100        this.$button.attr('aria-labelledby', labelID);
2101      }
2102
2103      this.$button.attr('aria-live', 'polite');
2104      this.$button.attr('aria-atomic', 'true');
2105
2106      this.checkDisabled();
2107      this.clickListener();
2108
2109      if (version.major > 4) this.dropdown = new Dropdown(this.$button[0]);
2110
2111      if (this.options.liveSearch) {
2112        this.liveSearchListener();
2113        this.focusedParent = this.$searchbox[0];
2114      } else {
2115        this.focusedParent = this.$menuInner[0];
2116      }
2117
2118      this.setStyle();
2119      this.setWidth();
2120      if (this.options.container) {
2121        this.selectPosition();
2122      } else {
2123        this.$element.on('hide' + EVENT_KEY, function () {
2124          if (that.isVirtual()) {
2125            // empty menu on close
2126            var menuInner = that.$menuInner[0],
2127                emptyMenu = menuInner.firstChild.cloneNode(false);
2128
2129            // replace the existing UL with an empty one - this is faster than $.empty() or innerHTML = ''
2130            menuInner.replaceChild(emptyMenu, menuInner.firstChild);
2131            menuInner.scrollTop = 0;
2132          }
2133        });
2134      }
2135      this.$menu.data('this', this);
2136      this.$newElement.data('this', this);
2137      if (this.options.mobile) this.mobile();
2138
2139      this.$newElement.on({
2140        'hide.bs.dropdown': function (e) {
2141          that.$element.trigger('hide' + EVENT_KEY, e);
2142        },
2143        'hidden.bs.dropdown': function (e) {
2144          that.$element.trigger('hidden' + EVENT_KEY, e);
2145        },
2146        'show.bs.dropdown': function (e) {
2147          that.$element.trigger('show' + EVENT_KEY, e);
2148        },
2149        'shown.bs.dropdown': function (e) {
2150          that.$element.trigger('shown' + EVENT_KEY, e);
2151        }
2152      });
2153
2154      if (element.hasAttribute('required')) {
2155        this.$element.on('invalid' + EVENT_KEY, function () {
2156          that.$button[0].classList.add('bs-invalid');
2157
2158          that.$element
2159            .on('shown' + EVENT_KEY + '.invalid', function () {
2160              that.$element
2161                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened
2162                .off('shown' + EVENT_KEY + '.invalid');
2163            })
2164            .on('rendered' + EVENT_KEY, function () {
2165              // if select is no longer invalid, remove the bs-invalid class
2166              if (this.validity.valid) that.$button[0].classList.remove('bs-invalid');
2167              that.$element.off('rendered' + EVENT_KEY);
2168            });
2169
2170          that.$button.on('blur' + EVENT_KEY, function () {
2171            that.$element.trigger('focus').trigger('blur');
2172            that.$button.off('blur' + EVENT_KEY);
2173          });
2174        });
2175      }
2176
2177      if (form) {
2178        $(form).on('reset' + EVENT_KEY, function () {
2179          requestAnimationFrame(function () {
2180            that.render();
2181          });
2182        });
2183      }
2184    },
2185
2186    createDropdown: function () {
2187      // Options
2188      // If we are multiple or showTick option is set, then add the show-tick class
2189      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',
2190          // multiselectable = this.multiple ? ' aria-multiselectable="true"' : '',
2191          multiselectable = this.multiple ? ' aria-multiselectable="true"' : '',
2192          inputGroup = '',
2193          autofocus = this.autofocus ? ' autofocus' : '';
2194
2195      if (version.major < 4 && this.$element.parent().hasClass('input-group')) {
2196        inputGroup = ' input-group-btn';
2197      }
2198
2199      // Elements
2200      var drop,
2201          header = '',
2202          searchbox = '',
2203          actionsbox = '',
2204          donebutton = '',
2205          clearButton = '';
2206
2207      if (this.options.header) {
2208        header =
2209          '<div class="' + classNames.POPOVERHEADER + '">' +
2210            '<button type="button" class="close" aria-hidden="true">&times;</button>' +
2211              this.options.header +
2212          '</div>';
2213      }
2214
2215      if (this.options.liveSearch) {
2216        searchbox =
2217          '<div class="bs-searchbox">' +
2218            '<input type="search" class="form-control" autocomplete="off"' +
2219              (
2220                this.options.liveSearchPlaceholder === null ? ''
2221                :
2222                ' placeholder="' + htmlEscape(this.options.liveSearchPlaceholder) + '"'
2223              ) +
2224              ' role="combobox" aria-label="Search" aria-controls="' + this.selectId + '" aria-autocomplete="list">' +
2225          '</div>';
2226      }
2227
2228      if (this.multiple && this.options.actionsBox) {
2229        actionsbox =
2230          '<div class="bs-actionsbox">' +
2231            '<div class="btn-group btn-group-sm">
2231' +
2232              '<button type="button" class="actions-btn bs-select-all btn ' + classNames.BUTTONCLASS + '">' +
2233                this.options.selectAllText +
2234              '</button>' +
2235              '<button type="button" class="actions-btn bs-deselect-all btn ' + classNames.BUTTONCLASS + '">' +
2236                this.options.deselectAllText +
2237              '</button>' +
2238            '</div>' +
2239          '</div>';
2240      }
2241
2242      if (this.multiple && this.options.doneButton) {
2243        donebutton =
2244          '<div class="bs-donebutton">' +
2245            '<div class="btn-group">' +
2246              '<button type="button" class="btn btn-sm ' + classNames.BUTTONCLASS + '">' +
2247                this.options.doneButtonText +
2248              '</button>' +
2249            '</div>' +
2250          '</div>';
2251      }
2252
2253      if (this.options.allowClear) {
2254        clearButton = '<span class="close bs-select-clear-selected" title="' + this.options.deselectAllText + '"><span>&times;</span>';
2255      }
2256
2257      drop =
2258        '<div class="dropdown bootstrap-select' + showTick + inputGroup + '">' +
2259          '<button type="button" tabindex="0" class="' +
2260            this.options.styleBase +
2261            ' dropdown-toggle" ' +
2262            (this.options.display === 'static' ? 'data-display="static"' : '') +
2263            Selector.DATA_TOGGLE +
2264            autofocus +
2265            ' role="combobox"' +
2266            ' aria-controls="' + this.selectId + '"' +
2267            ' aria-haspopup="listbox"' +
2268            ' aria-expanded="false">' +
2269            '<div class="filter-option">' +
2270              '<div class="filter-option-inner">' +
2271                '<div class="filter-option-inner-inner">&nbsp;</div>' +
2272              '</div> ' +
2273            '</div>' +
2274            clearButton +
2275            '</span>' +
2276            (
2277              version.major >= '4' ? ''
2278              :
2279              '<span class="bs-caret">' +
2280                this.options.template.caret +
2281              '</span>'
2282            ) +
2283          '</button>' +
2284           '<div class="' + classNames.MENU + ' ' + (version.major >= '4' ? '' : classNames.SHOW) + '">' +
2285             header +
2286             searchbox +
2287             actionsbox +
2288             '<div class="inner ' + classNames.SHOW + '" id="' + this.selectId + '" '  + '>' +
2289                '<ul class="' + classNames.MENU + ' inner ' + (version.major >= '4' ? classNames.SHOW : '') + '" role="listbox" ' + multiselectable + '>' +
2290                '</ul>' +
2291             '</div>' +
2292             donebutton +
2293           '</div>' +
2294        '</div>';
2295
2296      return $(drop);
2297    },
2298
2299    setPositionData: function () {
2300      this.selectpicker.view.canHighlight = [];
2301      this.selectpicker.view.size = 0;
2302      this.selectpicker.view.firstHighlightIndex = false;
2303
2304      for (var i = 0; i < this.selectpicker.current.data.length; i++) {
2305        var li = this.selectpicker.current.data[i],
2306            canHighlight = true;
2307
2308        if (li.type === 'divider') {
2309          canHighlight = false;
2310          li.height = this.sizeInfo.dividerHeight;
2311        } else if (li.type === 'optgroup-label') {
2312          canHighlight = false;
2313          li.height = this.sizeInfo.dropdownHeaderHeight;
2314        } else {
2315          li.height = this.sizeInfo.liHeight;
2316        }
2317
2318        if (li.disabled) canHighlight = false;
2319
2320        this.selectpicker.view.canHighlight.push(canHighlight);
2321
2322        if (canHighlight) {
2323          this.selectpicker.view.size++;
2324          li.posinset = this.selectpicker.view.size;
2325          if (this.selectpicker.view.firstHighlightIndex === false) this.selectpicker.view.firstHighlightIndex = i;
2326        }
2327
2328        li.position = (i === 0 ? 0 : this.selectpicker.current.data[i - 1].position) + li.height;
2329        console.log(li);
2330      }
2331    },
2332
2333    isVirtual: function () {
2334      return (this.options.virtualScroll !== false) && (this.selectpicker.main.data.length >= this.options.virtualScroll) || this.options.virtualScroll === true;
2335    },
2336
2337    createView: function (isSearching, setSize, refresh) {
2338      var that = this,
2339          scrollTop = 0;
2340
2341      this.selectpicker.isSearching = isSearching;
2342      this.selectpicker.current = isSearching ? this.selectpicker.search : this.selectpicker.main;
2343
2344      this.setPositionData();
2345
2346      if (setSize) {
2347        if (refresh) {
2348          scrollTop = this.$menuInner[0].scrollTop;
2349        } else if (!that.multiple) {
2350          var element = that.$element[0],
2351              selectedIndex = (element.options[element.selectedIndex] || {}).liIndex;
2352
2353          if (typeof selectedIndex === 'number' && that.options.size !== false) {
2354            var selectedData = that.selectpicker.main.data[selectedIndex],
2355                position = selectedData && selectedData.position;
2356
2357            if (position) {
2358              scrollTop = position - ((that.sizeInfo.menuInnerHeight + that.sizeInfo.liHeight) / 2);
2359            }
2360          }
2361        }
2362      }
2363
2364      scroll(scrollTop, true);
2365
2366      this.$menuInner.off('scroll.createView').on('scroll.createView', function (e, updateV
2366alue) {
2367        if (!that.noScroll) scroll(this.scrollTop, updateValue);
2368        that.noScroll = false;
2369      });
2370
2371      function scroll (scrollTop, init) {
2372        var size = that.selectpicker.current.data.length,
2373            chunks = [],
2374            chunkSize,
2375            chunkCount,
2376            firstChunk,
2377            lastChunk,
2378            currentChunk,
2379            prevPositions,
2380            positionIsDifferent,
2381            previousElements,
2382            menuIsDifferent = true,
2383            isVirtual = that.isVirtual();
2384
2385        that.selectpicker.view.scrollTop = scrollTop;
2386
2387        chunkSize = that.options.chunkSize; // number of options in a chunk
2388        chunkCount = Math.ceil(size / chunkSize) || 1; // number of chunks
2389
2390        for (var i = 0; i < chunkCount; i++) {
2391          var endOfChunk = (i + 1) * chunkSize;
2392
2393          if (i === chunkCount - 1) {
2394            endOfChunk = size;
2395          }
2396
2397          chunks[i] = [
2398            (i) * chunkSize + (!i ? 0 : 1),
2399            endOfChunk
2400          ];
2401
2402          if (!size) break;
2403
2404          if (currentChunk === undefined && scrollTop - 1 <= that.selectpicker.current.data[endOfChunk - 1].position - that.sizeInfo.menuInnerHeight) {
2405            currentChunk = i;
2406          }
2407        }
2408
2409        if (currentChunk === undefined) currentChunk = 0;
2410
2411        prevPositions = [that.selectpicker.view.position0, that.selectpicker.view.position1];
2412
2413        // always display previous, current, and next chunks
2414        firstChunk = Math.max(0, currentChunk - 1);
2415        lastChunk = Math.min(chunkCount - 1, currentChunk + 1);
2416
2417        that.selectpicker.view.position0 = isVirtual === false ? 0 : (Math.max(0, chunks[firstChunk][0]) || 0);
2418        that.selectpicker.view.position1 = isVirtual === false ? size : (Math.min(size, chunks[lastChunk][1]) || 0);
2419
2420        positionIsDifferent = prevPositions[0] !== that.selectpicker.view.position0 || prevPositions[1] !== that.selectpicker.view.position1;
2421
2422        if (that.activeElement !== undefined) {
2423          if (init) {
2424            if (that.activeElement !== that.selectedElement) {
2425              that.defocusItem(that.activeElement);
2426            }
2427            that.activeElement = undefined;
2428          }
2429
2430          if (that.activeElement !== that.selectedElement) {
2431            that.defocusItem(that.selectedElement);
2432          }
2433        }
2434
2435        if (that.prevActiveElement !== undefined && that.prevActiveElement !== that.activeElement && that.prevActiveElement !== that.selectedElement) {
2436          that.defocusItem(that.prevActiveElement);
2437        }
2438
2439        if (init || positionIsDifferent || that.selectpicker.current.hasMore) {
2440          previousElements = that.selectpicker.view.visibleElements ? that.selectpicker.view.visibleElements.slice() : [];
2441
2442          if (isVirtual === false) {
2443            that.selectpicker.view.visibleElements = that.selectpicker.current.elements;
2444          } else {
2445            that.selectpicker.view.visibleElements = that.selectpicker.current.elements.slice(that.selectpicker.view.position0, that.selectpicker.view.position1);
2446          }
2447
2448          that.setOptionStatus();
2449
2450          // if searching, check to make sure the list has actually been updated before updating DOM
2451          // this prevents unnecessary repaints
2452          if (isSearching || (isVirtual === false && init)) menuIsDifferent = !isEqual(previousElements, that.selectpicker.view.visibleElements);
2453
2454          // if virtual scroll is disabled and not searching,
2455          // menu should never need to be updated more than once
2456          if ((init || isVirtual === true) && menuIsDifferent) {
2457            var menuInner = that.$menuInner[0],
2458                menuFragment = document.createDocumentFragment(),
2459                emptyMenu = menuInner.firstChild.cloneNode(false),
2460                marginTop,
2461                marginBottom,
2462                elements = that.selectpicker.view.visibleElements,
2463                toSanitize = [];
2464
2465            // replace the existing UL with an empty one - this is faster than $.empty()
2466            menuInner.replaceChild(emptyMenu, menuInner.firstChild);
2467            var currentOptID;
2468            for (var i = 0, visibleElementsLen = elements.length; i < visibleElementsLen; i++) {
2469              var element = elements[i],
2470                  elText,
2471                  elementData;
2472
2473              console.log(elementData);
2474
2475              if (that.options.sanitize) {
2476                elText = element.lastChild;
2477
2478                if (elText) {
2479                  elementData = that.selectpicker.current.data[i + that.selectpicker.view.position0];
2480
2481                  if (elementData && elementData.content && !elementData.sanitized) {
2482                    toSanitize.push(elText);
2483                    elementData.sanitized = true;
2484                  }
2485                }
2486              }
2487
2488              if (elementData.optID && currentOptID != elementData.optID) {
2489                // its a new option group wrapper
2490                var groupWrapper = elementTemplates.group.cloneNode(false);
2491                var listbox = elementTemplates.listbox.cloneNode(false);
2492                var groupNotice = elementTemplates.groupNotice.cloneNode(true);
2493                listbox.setAttribute('aria-label', elementData.display);
2494                listbox.id = 'optgroup-' + elementData.optID;
2495                
2496                element.appendChild(groupNotice);
2497
2498                groupWrapper.appendChild(listbox);
2499                menuFragment.appendChild(groupWrapper);
2500                
2501
2502                element.setAttribute('data-index', elementData.index);
2503                menuFragment.getElementById('optgroup-' + elementData.optID).appendChild(element);
2504
2505                currentOptID = elementData.optID;
2506              } else if (elementData.type ==  'option' && elementData.optID) {
2507                // its an option within a group
2508                element.setAttribute('data-index', elementData.index);
2509                menuFragment.getElementById('optgroup-' + elementData.optID).appendChild(element);
2510              } else if (!elementData.optID) {
2511                // its an option without a group
2512                element.setAttribute('data-index', elementData.index);
2513                menuFragment.appendChild(element);
2514              }
2515            }
2516
2517            if (that.options.sanitize && toSanitize.length) {
2518              sanitizeHtml(toSanitize, that.options.whiteList, that.options.sanitizeFn);
2519            }
2520
2521            if (isVirtual === true) {
2522              marginTop = (that.selectpicker.view.position0 === 0 ? 0 : that.selectpicker.current.data[that.selectpicker.view.position0 - 1].position);
2523              marginBottom = (that.selectpicker.view.position1 > size - 1 ? 0 : that.selectpicker.current.data[size - 1].position - that.selectpicker.current.data[that.selectpicker.view.position1 - 1].position);
2524
2525              menuInner.firstChild.style.marginTop = marginTop + 'px';
2526              menuInner.firstChild.style.marginBottom = marginBottom + 'px';
2527            } else {
2528              menuInner.firstChild.style.marginTop = 0;
2529              menuInner.firstChild.style.marginBottom = 0;
2530            }
2531
2532            // write menu to DOM - NL
2533            menuInner.firstChild.appendChild(menuFragment);
2534
2535            // if an option is encountered that is wider than the current menu width, update the menu width accordingly
2536            // switch to ResizeObserver with increased browser support
2537            if (isVirtual === true && that.sizeInfo.hasScrollBar) {
2538              var menuInnerInnerWidth = menuInner.firstChild.offsetWidth;
2539
2540              if (init && menuInnerInnerWidth < that.sizeInfo.menuInnerInnerWidth && that.sizeInfo.totalMenuWidth > that.sizeInfo.selectWidth) {
2541                menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px';
2542              } else if (menuInnerInnerWidth > that.sizeInfo.menuInnerInnerWidth) {
2543                // set to 0 to get actual width of menu
2544                that.$menu[0].style.minWidth = 0;
2545
2546                var actualMenuWidth = menuInner.firstChild.offsetWidth;
2547
2548                if (actualMenuWidth > that.sizeInfo.menuInnerInnerWidth) {
2549                  that.sizeInfo.menuInnerInnerWidth = actualMenuWidth;
2550                  menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px';
2551                }
2552
2553                // reset to default CSS styling
2554                that.$menu[0].style.minWidth = '';
2555              }
2556            }
2557          }
2558
2559          if ((!isSearching && that.options.source.data || isSearching && that.options.source.search) && that.selectpicker.current.hasMore && currentChunk === chunkCount - 1) {
2560            // Don't load the next chunk until scrolling has started
2561            // This prevents unnecessary requests while the user is typing if pageSize is <= chunkSize
2562            if (scrollTop > 0) {
2563              // Chunks use 0-based indexing, but pages use 1-based. Add 1 to convert and add 1 again to get next page
2564              var page = Math.floor((currentChunk * that.options.chunkSize) / that.options.source.pageSize) + 2;
2565
2566              that.fetchData(function () {
2567                that.render();
2568                that.buildList(size, isSearching);
2569                that.setPositionData();
2570                scroll(scrollTop);
2571              }, isSearching ? 'search' : 'data', page, isSearching ? that.selectpicker.search.previousValue : undefined);
2572            }
2573          }
2574        }
2575
2576        that.prevActiveElement = that.activeElement;
2577
2578        if (!that.options.liveSearch) {
2579          that.$menuInner.trigger('focus');
2580        } else if (isSearching && init) {
2581          var index = 0,
2582              newActive;
2583
2584          if (!that.selectpicker.view.canHighlight[index]) {
2585            index = 1 + that.selectpicker.view.canHighlight.slice(1).indexOf(true);
2586          }
2587
2588          newActive = that.selectpicker.view.visibleElements[index];
2589
2590          that.defocusItem(that.selectpicker.view.currentActive);
2591
2592          that.activeElement = (that.selectpicker.current.data[index] || {}).element;
2593
2594          that.focusItem(newActive);
2595        }
2596      }
2597
2598      $(window)
2599        .off('resize' + EVENT_KEY + '.' + this.selectId + '.createView')
2600        .on('resize' + EVENT_KEY + '.' + this.selectId + '.createView', function () {
2601          var isActive = that.$newElement.hasClass(classNames.SHOW);
2602
2603          if (isActive) scroll(that.$menuInner[0].scrollTop);
2604        });
2605    },
2606
2607    focusItem: function (li, liData, noStyle) {
2608      if (li) {
2609        liData = liData || this.selectpicker.current.data[this.selectpicker.current.elements.indexOf(this.activeElement)];
2610        var a = li.firstChild;
2611
2612        if (a) {
2613          // NL TODO maybe remove
2614          // a.setAttribute('aria-setsize', this.selectpicker.view.size);
2615          // a.setAttribute('aria-posinset', liData.posinset);
2616
2617          if (noStyle !== true) {
2618            // this.focusedParent.setAttribute('aria-activedescendant', a.id);
2619            // this.$button[0].setAttribute('aria-activedescendant', a.id);
2620            this.$button[0].setAttribute('aria-activedescendant', li.id);
2621            li.classList.add('active');
2622            a.classList.add('active');
2623          }
2624        }
2625      }
2626    },
2627
2628    defocusItem: function (li) {
2629      if (li) {
2630        li.classList.remove('active');
2631        if (li.firstChild) li.firstChild.classList.remove('active');
2632      }
2633    },
2634
2635    setPlaceholder: function () {
2636      var that = this,
2637          updateIndex = false;
2638
2639      if ((this.options.placeholder || this.options.allowClear) && !this.multiple) {
2640        if (!this.selectpicker.view.titleOption) this.selectpicker.view.titleOption = document.createElement('option');
2641
2642        // this option doesn't create a new <li> element, but does add a new option at the start,
2643        // so startIndex should increase to prevent having to check every option for the bs-title-option class
2644        updateIndex = true;
2645
2646        var element = this.$element[0],
2647            selectTitleOption = false,
2648            titleNotAppended = !this.selectpicker.view.titleOption.parentNode,
2649            selectedIndex = element.selectedIndex,
2650            selectedOption = element.options[selectedIndex],
2651            firstSelectable = element.querySelector('select > *:not(:disabled)'),
2652            firstSelectableIndex = firstSelectable ? firstSelectable.index : 0,
2653            navigation = window.performance && window.performance.getEntriesByType('navigation'),
2654            // Safari doesn't support getEntriesByType('navigation') - fall back to performance.navigation
2655            isNotBackForward = (navigation && navigation.length) ? navigation[0].type !== 'back_forward' : window.performance.navigation.type !== 2;
2656
2657        if (titleNotAppended) {
2658          // Use native JS to prepend option (faster)
2659          this.selectpicker.view.titleOption.className = 'bs-title-option';
2660          this.selectpicker.view.titleOption.value = '';
2661
2662          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.
2663          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,
2664          // if so, the select will have the data-selected attribute
2665          selectTitleOption = !selectedOption || (selectedIndex === firstSelectableIndex && selectedOption.defaultSelected === false && this.$element.data('selected') === undefined);
2666        }
2667
2668        if (titleNotAppended || this.selectpicker.view.titleOption.index !== 0) {
2669          element.insertBefore(this.selectpicker.view.titleOption, element.firstChild);
2670        }
2671
2672        // Set selected *after* appending to select,
2673        // otherwise the option doesn't get selected in IE
2674        // set using selectedIndex, as setting the selected attr to true here doesn't work in IE11
2675        if (selectTitleOption && isNotBackForward) {
2676          element.selectedIndex = 0;
2677        } else if (document.readyState !== 'complete') {
2678          // if navigation type is back_forward, there's a chance the select will have its value set by BFCache
2679          // wait for that value to be set, then run render again
2680          window.addEventListener('pageshow', function () {
2681            if (that.selectpicker.view.displayedValue !== element.value) that.render();
2682          });
2683        }
2684      }
2685
2686      return updateIndex;
2687    },
2688
2689    fetchData: function (callback, type, page, searchValue) {
2690      page = page || 1;
2691      type = type || 'data';
2692
2693      var that = this,
2694          data = this.options.source[type],
2695          builtData;
2696
2697      if (data) {
2698        this.options.virtualScroll = true;
2699
2700        if (typeof data === 'function') {
2701          data.call(
2702            this,
2703            function (data, more, totalItems) {
2704              var current = that.selectpicker[type === 'search' ? 'search' : 'main'];
2705              current.hasMore = more;
2706              current.totalItems = totalItems;
2707              builtData = that.buildData(data, type);
2708              callback.call(that, builtData);
2709              that.$element.trigger('fetched' + EVENT_KEY);
2710            },
2711            page,
2712            searchValue
2713          );
2714        } else if (Array.isArray(data)) {
2715          builtData = that.buildData(data, type);
2716          callback.call(that, builtData);
2717        }
2718      } else {
2719        builtData = this.buildData(false, type);
2720        callback.call(that, builtData);
2721      }
2722    },
2723
2724    buildData: function (data, type) {
2725      var that = this;
2726      var dataGetter = data === false ? getOptionData.fromOption : getOptionData.fromDataSource;
2727
2728      var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([style*="display: none"])',
2729          mainData = [],
2730          // startLen = this.selectpicker.main.data ? this.selectpicker.main.data.length : 0,
2731          optID = 0,
2732          startIndex = this.setPlaceholder() && !data ? 1 : 0; // append the titleOption if necessary and skip the first option in the loop
2733
2734      // if (type === 'search') {
2735      //   startLen = this.selectpicker.search.data.length;
2736      // }
2737
2738      if (this.options.hideDisabled) optionSelector += ':not(:disabled)';
2739
2740      var selectOptions = data ? data.filter(filterHidden, this) : this.$element[0].querySelectorAll('select > *' + optionSelector);
2741
2742      // function addDivider (config) {
2743      //   var previousData = mainData[mainData.length - 1];
2744
2745      //   // ensure optgroup doesn't create back-to-back dividers
2746      //   if (
2747      //     previousData &&
2748      //     previousData.type === 'divider' &&
2749      //     (previousData.optID || config.optID)
2750      //   ) {
2751      //     return;
2752      //   }
2753
2754      //   config = config || {};
2755      //   config.type = 'divider';
2756
2757      //   // mainData.push(config);
2758      // }
2759
2760      function addOption (item, config) {
2761        config = config || {};
2762
2763        config.divider = dataGetter(item, 'divider');
2764
2765        if (config.divider === true) {
2766          // addDivider({
2767          //   optID: config.optID
2768          // });
2769        } else {
2770          // var liIndex = mainData.length + startLen,
2771          var liIndex = mainData.length,
2772              cssText = dataGetter(item, 'style'),
2773              inlineStyle = cssText ? htmlEscape(cssText) : '',
2774              optionClass = (item.className || '') + (config.optgroupClass || '');
2775
2776          if (config.optID) optionClass = 'opt ' + optionClass;
2777
2778          config.optionClass = optionClass.trim();
2779          config.inlineStyle = inlineStyle;
2780
2781          config.text = dataGetter(item, 'text');
2782          config.title = dataGetter(item, 'title');
2783          config.content = dataGetter(item, 'content');
2784          config.tokens = dataGetter(item, 'tokens');
2785          config.subtext = dataGetter(item, 'subtext');
2786          config.icon = dataGetter(item, 'icon');
2787
2788          config.display = config.content || config.text;
2789          config.value = item.value === undefined ? item.text : item.value;
2790          config.type = 'option';
2791          config.index = liIndex;
2792
2793          config.option = !item.option ? item : item.option; // reference option element if it exists
2794          config.option.liIndex = liIndex;
2795          config.selected = !!item.selected;
2796          config.disabled = config.disabled || !!item.disabled;
2797
2798          if (data !== false) {
2799            if (that.selectpicker.optionValuesDataMap[config.value]) {
2800              config = $.extend(that.selectpicker.optionValuesDataMap[config.value], config);
2801            } else {
2802              that.selectpicker.optionValuesDataMap[config.value] = config;
2803            }
2804          }
2805
2806          mainData.push(config);
2807        }
2808      }
2809
2810      function addOptgroup (index, selectOptions) {
2811        // console.log("addOptgroup");
2812        // console.log(index, selectOptions);
2813        var optgroup = selectOptions[index],
2814            // skip placeholder option
2815            previous = index - 1 < startIndex ? false : selectOptions[index - 1],
2816            // next = selectOptions[index + 1],
2817            options = data ? optgroup.children.filter(filterHidden, this) : optgroup.querySelectorAll('option' + optionSelector);
2818
2819        if (!options.length) return;
2820
2821        var config = {
2822              display: htmlEscape(dataGetter(item, 'label')),
2823              subtext: dataGetter(optgroup, 'subtext'),
2824              icon: dataGetter(optgroup, 'icon'),
2825              type: 'optgroup-label',
2826              optgroupClass: ' ' + (optgroup.className || ''),
2827              optgroup: optgroup
2828            },
2829            headerIndex,
2830            lastIndex;
2831
2832        optID++;
2833
2834        if (previous) {
2835          // addDivider({ optID: optID });
2836        }
2837
2838        config.optID = optID;
2839
2840        // push the option group to the main config
2841        // mainData.push(config);
2842
2843        for (var j = 0, len = options.length; j < len; j++) {
2844          var option = options[j];
2845
2846          if (j === 0) {
2847            headerIndex = mainData.length - 1;
2848            lastIndex = headerIndex + len;
2849          }
2850
2851          addOption(option, {
2852            headerIndex: headerIndex,
2853            lastIndex: lastIndex,
2854            optID: config.optID,
2855            optgroupClass: config.optgroupClass,
2856            disabled: optgroup.disabled,
2857            optGroupLabel: config.display
2858          });
2859        }
2860
2861        // NL commented out, ends with divider
2862        // if (next) {
2863        // addDivider({ optID: optID });
2864        // }
2865      }
2866
2867      for (var len = selectOptions.length, i = startIndex; i < len; i++) {
2868        var item = selectOptions[i],
2869            children = item.children;
2870
2871        if (children && children.length) {
2872          addOptgroup.call(this, i, selectOptions);
2873        } else {
2874          addOption.call(this, item, {});
2875        }
2876      }
2877
2878      switch (type) {
2879        case 'data': {
2880          if (!this.selectpicker.main.data) {
2881            this.selectpicker.main.data = [];
2882          }
2883          // Array.prototype.push.apply(this.selectpicker.main.data, mainData);
2884          // this.selectpicker.current.data = this.selectpicker.main.data;
2885          this.selectpicker.main.data = this.selectpicker.current.data = mainData;
2886          break;
2887        }
2888        case 'search': {
2889          Array.prototype.push.apply(this.selectpicker.search.data, mainData);
2890          break;
2891        }
2892      }
2893
2894      return mainData;
2895    },
2896
2897    buildList: function (size, searching) {
2898      var that = this,
2899          selectData = searching ? this.selectpicker.search.data : this.selectpicker.main.data,
2900          mainElements = [],
2901          widestOptionLength = 0;
2902
2903      if ((that.options.showTick || that.multiple) && !elementTemplates.checkMark.parentNode) {
2904        elementTemplates.checkMark.className = this.options.iconBase + ' ' + that.options.tickIcon + ' check-mark';
2905        elementTemplates.a.appendChild(elementTemplates.checkMark);
2906      }
2907
2908      function buildElement (mainElements, item) {
2909        // console.log("buildElement: mainElements, item");
2910        // console.log(mainElements, item);
2911        var liElement,
2912            combinedLength = 0;
2913
2914        switch (item.type) {
2915          case 'divider':
2916            liElement = generateOption.li(
2917              false,
2918              classNames.DIVIDER,
2919              (item.optID ? item.optID + 'div' : undefined)
2920            );
2921
2922            break;
2923
2924          case 'option':
2925            liElement = generateOption.li(
2926              generateOption.a(
2927                generateOption.text.call(that, item),
2928                item.optionClass,
2929                item.inlineStyle
2930              ),
2931              '',
2932              item.optID
2933            );
2934
2935            // if (liElement.firstChild) {
2936            //   liElement.firstChild.id = that.selectId + '-' + item.index;
2937            // }
2938
2939            liElement.id = that.selectId + '-' + item.index;
2940
2941            break;
2942
2943          case 'optgroup-label':
2944            liElement = generateOption.li(
2945              generateOption.label.call(that, item),
2946              'dropdown-header' + item.optgroupClass,
2947              item.optID
2948            );
2949
2950            break;
2951        }
2952
2953        if (!item.element) {
2954          item.element = liElement;
2955        } else {
2956          item.element.innerHTML = liElement.innerHTML;
2957        }
2958        mainElements.push(item.element);
2959
2960        // count the number of characters in the option - not perfect, but should work in most cases
2961        if (item.display) combinedLength += item.display.length;
2962        if (item.subtext) combinedLength += item.subtext.length;
2963        // if there is an icon, ensure this option's width is checked
2964        if (item.icon) combinedLength += 1;
2965
2966        if (combinedLength > widestOptionLength) {
2967          widestOptionLength = combinedLength;
2968
2969          // guess which option is the widest
2970          // use this when calculating menu width
2971          // not perfect, but it's fast, and the width will be updating accordingly when scrolling
2972          that.selectpicker.view.widestOption = mainElements[mainElements.length - 1];
2973        }
2974      }
2975
2976      var startIndex = size || 0;
2977
2978      for (var len = selectData.length, i = startIndex; i < len; i++) {
2979        var item = selectData[i];
2980
2981        buildElement(mainElements, item);
2982      }
2983
2984      if (size) {
2985        if (searching) {
2986          Array.prototype.push.apply(this.selectpicker.search.elements, mainElements);
2987        } else {
2988          Array.prototype.push.apply(this.selectpicker.main.elements, mainElements);
2989          this.selectpicker.current.elements = this.selectpicker.main.elements;
2990        }
2991      } else {
2992        if (searching) {
2993          this.selectpicker.search.elements = mainElements;
2994        } else {
2995          this.selectpicker.main.elements = this.selectpicker.current.elements = mainElements;
2996        }
2997      }
2998    },
2999
3000    findLis: function () {
3001      return this.$menuInner.find('.inner li[role="option"]');
3002    },
3003
3004    render: function (init) {
3005      var that = this,
3006          element = this.$element[0],
3007          // ensure titleOption is appended and selected (if necessary) before getting selectedOptions
3008          placeholderSelected = this.setPlaceholder() && element.selectedIndex === 0,
3009          selectedOptions = getSelectedOptions.call(this),
3010          selectedCount = selectedOptions.length,
3011          selectedValues = getSelectValues.call(this, selectedOptions),
3012          button = this.$button[0],
3013          buttonInner = button.querySelector('.filter-option-inner-inner'),
3014          multipleSeparator = document.createTextNode(this.options.multipleSeparator),
3015          titleFragment = elementTemplates.fragment.cloneNode(false),
3016          titleTipFragment = elementTemplates.fragment.cloneNode(false),
3017          showCount,
3018          countMax,
3019          hasContent = false;
3020
3021      // console.log('render start : that.selectpicker.main.data', that.selectpicker.main.data);
3022
3023      function createSelected (item) {
3024        if (item.selected) {
3025          that.createOption(item, true);
3026        } else if (item.children && item.children.length) {
3027          item.children.map(createSelected);
3028        }
3029      }
3030
3031      // create selected option elements to ensure select value is correct
3032      if (this.options.source.data && init) {
3033        selectedOptions.map(createSelected);
3034        element.appendChild(this.selectpicker.main.optionQueue);
3035
3036        if (placeholderSelected) placeholderSelected = element.selectedIndex === 0;
3037      }
3038
3039      button.classList.toggle('bs-placeholder', that.multiple ? !selectedCount : !selectedValues && selectedValues !== 0);
3040
3041      if (!that.multiple && selectedOptions.length === 1) {
3042        that.selectpicker.view.displayedValue = selectedValues;
3043      }
3044
3045      if (this.options.selectedTextFormat === 'static') {
3046        titleFragment = generateOption.text.call(this, { text: this.options.placeholder }, true);
3047      } else {
3048        showCount = this.multiple && this.options.selectedTextFormat.indexOf('count') !== -1 && selectedCount > 0;
3049
3050        // determine if the number of selected options will be shown (showCount === true)
3051        if (showCount) {
3052          countMax = this.options.selectedTextFormat.split('>');
3053          showCount = (countMax.length > 1 && selectedCount > countMax[1]) || (countMax.length === 1 && selectedCount >= 2);
3054        }
3055
3056        // only loop through all selected options if the count won't be shown
3057        if (showCount === false) {
3058          if (!placeholderSelected) {
3059            for (var selectedIndex = 0; selectedIndex < selectedCount; selectedIndex++) {
3060              if (selectedIndex < 50) {
3061                var option = selectedOptions[selectedIndex],
3062                    titleOptions = {};
3063
3064                if (option) {
3065                  if (this.multiple && selectedIndex > 0) {
3066                    titleFragment.appendChild(multipleSeparator.cloneNode(false));
3067                  }
3068
3069                  if (option.title) {
3070                    titleOptions.text = option.title;
3071                  } else if (option.content && that.options.showContent) {
3072                    titleOptions.content = option.content.toString();
3073                    hasContent = true;
3074                  } else {
3075                    if (that.options.showIcon) {
3076                      titleOptions.icon = option.icon;
3077                    }
3078                    if (that.options.showSubtext && !that.multiple && option.subtext) titleOptions.subtext = ' ' + option.subtext;
3079                    titleOptions.text = option.text.trim();
3080                  }
3081
3082                  titleFragment.appendChild(generateOption.text.call(this, titleOptions, true));
3083                }
3084              } else {
3085                break;
3086              }
3087            }
3088
3089            // add ellipsis
3090            if (selectedCount > 49) {
3091              titleFragment.appendChild(document.createTextNode('...'));
3092            }
3093          }
3094        } else {
3095          var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([data-divider="true"]):not([style*="display: none"])';
3096          if (this.options.hideDisabled) optionSelector += ':not(:disabled)';
3097
3098          // If this is a multiselect, and selectedTextFormat is count, then show 1 of 2 selected, etc.
3099          var totalCount = this.$element[0].querySelectorAll('select > option' + optionSelector + ', optgroup' + optionSelector + ' option' + optionSelector).length,
3100              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedCount, totalCount) : this.options.countSelectedText;
3101
3102          titleFragment = generateOption.text.call(this, {
3103            text: tr8nText.replace('{0}', selectedCount.toString()).replace('{1}', totalCount.toString())
3104          }, true);
3105        }
3106      }
3107
3108      // If the select doesn't have a title, then use the default, or if nothing is set at all, use noneSelectedText
3109      if (!titleFragment.childNodes.length) {
3110        titleFragment = generateOption.text.call(this, {
3111          text: this.options.placeholder ? this.options.placeholder : this.options.noneSelectedText
3112        }, true);
3113      }
3114
3115      // if the select has a title, apply it to the button, and if not, apply titleFragment text
3116      // strip all HTML tags and trim the result, then unescape any escaped tags
3117      // removed NL
3118      // button.title = titleFragment.textContent.replace(/<[^>]*>?/g, '').trim();
3119
3120      if (this.options.sanitize && hasContent) {
3121        sanitizeHtml([titleFragment], that.options.whiteList, that.options.sanitizeFn);
3122      }
3123
3124      buttonInner.innerHTML = '<span class="sr-only">Selected options: </span>';
3125      buttonInner.appendChild(titleFragment);
3126
3127      if (this.options.titleTip && !button.querySelector('.title-tip')) {
3128        var titleTip = document.createElement('div');
3129        titleTip.setAttribute('class', 'title-tip');
3130        titleTipFragment = generateOption.text.call(this, {
3131          text: this.options.titleTip ? this.options.titleTip : ''
3132        }, true);
3133        titleTip.appendChild(titleTipFragment);
3134        button.querySelector('.filter-option').prepend(titleTip);
3135      }
3136
3137      if (version.major < 4 && this.$newElement[0].classList.contains('bs3-has-addon')) {
3138        var filterExpand = button.querySelector('.filter-expand'),
3139            clone = buttonInner.cloneNode(true);
3140
3141        clone.className = 'filter-expand';
3142
3143        if (filterExpand) {
3144          button.replaceChild(clone, filterExpand);
3145        } else {
3146          button.appendChild(clone);
3147        }
3148      }
3149      // console.log('render END : that.selectpicker.main.data', that.selectpicker.main.data);
3150
3151      this.$element.trigger('rendered' + EVENT_KEY);
3152    },
3153
3154    /**
3155     * @param [style]
3156     * @param [status]
3157     */
3158    setStyle: function (newStyle, status) {
3159      var button = this.$button[0],
3160          newElement = this.$newElement[0],
3161          style = this.options.style.trim(),
3162          buttonClass;
3163
3164      if (this.$element.attr('class')) {
3165        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, ''));
3166      }
3167
3168      if (version.major < 4) {
3169        newElement.classList.add('bs3');
3170
3171        if (newElement.parentNode.classList && newElement.parentNode.classList.contains('input-group') &&
3172            (newElement.previousElementSibling || newElement.nextElementSibling) &&
3173            (newElement.previousElementSibling || newElement.nextElementSibling).classList.contains('input-group-addon')
3174        ) {
3175          newElement.classList.add('bs3-has-addon');
3176        }
3177      }
3178
3179      if (newStyle) {
3180        buttonClass = newStyle.trim();
3181      } else {
3182        buttonClass = style;
3183      }
3184
3185      if (status == 'add') {
3186        if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' '));
3187      } else if (status == 'remove') {
3188        if (buttonClass) button.classList.remove.apply(button.classList, buttonClass.split(' '));
3189      } else {
3190        if (style) button.classList.remove.apply(button.classList, style.split(' '));
3191        if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' '));
3192      }
3193    },
3194
3195    liHeight: function (refresh) {
3196      if (!refresh && (this.options.size === false || Object.keys(this.sizeInfo).length)) return;
3197
3198      var newElement = elementTemplates.div.cloneNode(false),
3199          menu = elementTemplates.div.cloneNode(false),
3200          menuInner = elementTemplates.div.cloneNode(false),
3201          menuInnerInner = document.createElement('ul'),
3202          divider = elementTemplates.li.cloneNode(false),
3203          dropdownHeader = elementTemplates.li.cloneNode(false),
3204          li,
3205          a = elementTemplates.a.cloneNode(false),
3206          text = elementTemplates.span.cloneNode(false),
3207          header = this.options.header && this.$menu.find('.' + classNames.POPOVERHEADER).length > 0 ? this.$menu.find('.' + classNames.POPOVERHEADER)[0].cloneNode(true) : null,
3208          search = this.options.liveSearch ? elementTemplates.div.cloneNode(false) : null,
3209          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,
3210          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null,
3211          firstOption = this.$element[0].options[0];
3212
3213      this.sizeInfo.selectWidth = this.$newElement[0].offsetWidth;
3214
3215      text.className = 'text';
3216      a.className = 'dropdown-item ' + (firstOption ? firstOption.className : '');
3217      newElement.className = this.$menu[0].parentNode.className + ' ' + classNames.SHOW;
3218      newElement.style.width = 0; // ensure button width doesn't affect natural width of menu when calculating
3219      if (this.options.width === 'auto') menu.style.minWidth = 0;
3220      menu.className = classNames.MENU + ' ' + classNames.SHOW;
3221      menuInner.className = 'inner ' + classNames.SHOW;
3222      menuInnerInner.className = classNames.MENU + ' inner ' + (version.major >= '4' ? classNames.SHOW : '');
3223      divider.className = classNames.DIVIDER;
3224      dropdownHeader.className = 'dropdown-header';
3225
3226      text.appendChild(document.createTextNode('\u200b'));
3227
3228      if (this.selectpicker.current.data.length) {
3229        for (var i = 0; i < this.selectpicker.current.data.length; i++) {
3230          var data = this.selectpicker.current.data[i];
3231          if (data.type === 'option' && $(data.element.firstChild).css('display') !== 'none') {
3232            li = data.element;
3233            break;
3234          }
3235        }
3236      } else {
3237        li = elementTemplates.li.cloneNode(false);
3238        a.appendChild(text);
3239        li.appendChild(a);
3240      }
3241
3242      dropdownHeader.appendChild(text.cloneNode(true));
3243
3244      if (this.selectpicker.view.widestOption) {
3245        menuInnerInner.appendChild(this.selectpicker.view.widestOption.cloneNode(true));
3246      }
3247
3248      menuInnerInner.appendChild(li);
3249      menuInnerInner.appendChild(divider);
3250      menuInnerInner.appendChild(dropdownHeader);
3251      if (header) menu.appendChild(header);
3252      if (search) {
3253        var input = document.createElement('input');
3254        search.className = 'bs-searchbox';
3255        input.className = 'form-control';
3256        search.appendChild(input);
3257        menu.appendChild(search);
3258      }
3259      if (actions) menu.appendChild(actions);
3260      menuInner.appendChild(menuInnerInner);
3261      menu.appendChild(menuInner);
3262      if (doneButton) menu.appendChild(doneButton);
3263      newElement.appendChild(menu);
3264
3265      document.body.appendChild(newElement);
3266
3267      var liHeight = li.offsetHeight,
3268          dropdownHeaderHeight = dropdownHeader ? dropdownHeader.offsetHeight : 0,
3269          headerHeight = header ? header.offsetHeight : 0,
3270          searchHeight = search ? search.offsetHeight : 0,
3271          actionsHeight = actions ? actions.offsetHeight : 0,
3272          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,
3273          dividerHeight = $(divider).outerHeight(true),
3274          menuStyle = window.getComputedStyle(menu),
3275          menuWidth = menu.offsetWidth,
3276          menuPadding = {
3277            vert: toInteger(menuStyle.paddingTop) +
3278                  toInteger(menuStyle.paddingBottom) +
3279                  toInteger(menuStyle.borderTopWidth) +
3280                  toInteger(menuStyle.borderBottomWidth),
3281            horiz: toInteger(menuStyle.paddingLeft) +
3282                  toInteger(menuStyle.paddingRight) +
3283                  toInteger(menuStyle.borderLeftWidth) +
3284                  toInteger(menuStyle.borderRightWidth)
3285          },
3286          menuExtras = {
3287            vert: menuPadding.vert +
3288                  toInteger(menuStyle.marginTop) +
3289                  toInteger(menuStyle.marginBottom) + 2,
3290            horiz: menuPadding.horiz +
3291                  toInteger(menuStyle.marginLeft) +
3292                  toInteger(menuStyle.marginRight) + 2
3293          },
3294          scrollBarWidth;
3295
3296      menuInner.style.overflowY = 'scroll';
3297
3298      scrollBarWidth = menu.offsetWidth - menuWidth;
3299
3300      document.body.removeChild(newElement);
3301
3302      this.sizeInfo.liHeight = liHeight;
3303      this.sizeInfo.dropdownHeaderHeight = dropdownHeaderHeight;
3304      this.sizeInfo.headerHeight = headerHeight;
3305      this.sizeInfo.searchHeight = searchHeight;
3306      this.sizeInfo.actionsHeight = actionsHeight;
3307      this.sizeInfo.doneButtonHeight = doneButtonHeight;
vendor: 8,813 bytes, lines 3308-3508
3308      this.sizeInfo.dividerHeight = dividerHeight;
3309      this.sizeInfo.menuPadding = menuPadding;
3310      this.sizeInfo.menuExtras = menuExtras;
3311      this.sizeInfo.menuWidth = menuWidth;
3312      this.sizeInfo.menuInnerInnerWidth = menuWidth - menuPadding.horiz;
3313      this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth;
3314      this.sizeInfo.scrollBarWidth = scrollBarWidth;
3315      this.sizeInfo.selectHeight = this.$newElement[0].offsetHeight;
3316
3317      this.setPositionData();
3318    },
3319
3320    getSelectPosition: function () {
3321      var that = this,
3322          $window = $(window),
3323          pos = that.$newElement.offset(),
3324          $container = $(that.options.container),
3325          containerPos;
3326
3327      if (that.options.container && $container.length && !$container.is('body')) {
3328        containerPos = $container.offset();
3329        containerPos.top += parseInt($container.css('borderTopWidth'));
3330        containerPos.left += parseInt($container.css('borderLeftWidth'));
3331      } else {
3332        containerPos = { top: 0, left: 0 };
3333      }
3334
3335      var winPad = that.options.windowPadding;
3336
3337      this.sizeInfo.selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();
3338      this.sizeInfo.selectOffsetBot = $window.height() - this.sizeInfo.selectOffsetTop - this.sizeInfo.selectHeight - containerPos.top - winPad[2];
3339      this.sizeInfo.selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();
3340      this.sizeInfo.selectOffsetRight = $window.width() - this.sizeInfo.selectOffsetLeft - this.sizeInfo.selectWidth - containerPos.left - winPad[1];
3341      this.sizeInfo.selectOffsetTop -= winPad[0];
3342      this.sizeInfo.selectOffsetLeft -= winPad[3];
3343    },
3344
3345    setMenuSize: function (isAuto) {
3346      this.getSelectPosition();
3347
3348      var selectWidth = this.sizeInfo.selectWidth,
3349          liHeight = this.sizeInfo.liHeight,
3350          headerHeight = this.sizeInfo.headerHeight,
3351          searchHeight = this.sizeInfo.searchHeight,
3352          actionsHeight = this.sizeInfo.actionsHeight,
3353          doneButtonHeight = this.sizeInfo.doneButtonHeight,
3354          divHeight = this.sizeInfo.dividerHeight,
3355          menuPadding = this.sizeInfo.menuPadding,
3356          menuInnerHeight,
3357          menuHeight,
3358          divLength = 0,
3359          minHeight,
3360          _minHeight,
3361          maxHeight,
3362          menuInnerMinHeight,
3363          estimate,
3364          isDropup;
3365
3366      if (this.options.dropupAuto) {
3367        // Get the estimated height of the menu without scrollbars.
3368        // This is useful for smaller menus, where there might be plenty of room
3369        // below the button without setting dropup, but we can't know
3370        // the exact height of the menu until createView is called later
3371        estimate = liHeight * this.selectpicker.current.data.length + menuPadding.vert;
3372
3373        isDropup = this.sizeInfo.selectOffsetTop - this.sizeInfo.selectOffsetBot > this.sizeInfo.menuExtras.vert && estimate + this.sizeInfo.menuExtras.vert + 50 > this.sizeInfo.selectOffsetBot;
3374
3375        // ensure dropup doesn't change while searching (so menu doesn't bounce back and forth)
3376        if (this.selectpicker.isSearching === true) {
3377          isDropup = this.selectpicker.dropup;
3378        }
3379
3380        this.$newElement.toggleClass(classNames.DROPUP, isDropup);
3381        this.selectpicker.dropup = isDropup;
3382      }
3383
3384      if (this.options.size === 'auto') {
3385        _minHeight = this.selectpicker.current.data.length > 3 ? this.sizeInfo.liHeight * 3 + this.sizeInfo.menuExtras.vert - 2 : 0;
3386        menuHeight = this.sizeInfo.selectOffsetBot - this.sizeInfo.menuExtras.vert;
3387        minHeight = _minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight;
3388        menuInnerMinHeight = Math.max(_minHeight - menuPadding.vert, 0);
3389
3390        if (this.$newElement.hasClass(classNames.DROPUP)) {
3391          menuHeight = this.sizeInfo.selectOffsetTop - this.sizeInfo.menuExtras.vert;
3392        }
3393
3394        maxHeight = menuHeight;
3395        menuInnerHeight = menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert;
3396      } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) {
3397        for (var i = 0; i < this.options.size; i++) {
3398          if (this.selectpicker.current.data[i].type === 'divider') divLength++;
3399        }
3400
3401        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;
3402        menuInnerHeight = menuHeight - menuPadding.vert;
3403        maxHeight = menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight;
3404        minHeight = menuInnerMinHeight = '';
3405      }
3406
3407      this.$menu.css({
3408        'max-height': maxHeight + 'px',
3409        'overflow': 'hidden',
3410        'min-height': minHeight + 'px'
3411      });
3412
3413      this.$menuInner.css({
3414        'max-height': menuInnerHeight + 'px',
3415        'overflow': 'hidden auto',
3416        'min-height': menuInnerMinHeight + 'px'
3417      });
3418
3419      // ensure menuInnerHeight is always a positive number to prevent issues calculating chunkSize in createView
3420      this.sizeInfo.menuInnerHeight = Math.max(menuInnerHeight, 1);
3421
3422      if (this.selectpicker.current.data.length && this.selectpicker.current.data[this.selectpicker.current.data.length - 1].position > this.sizeInfo.menuInnerHeight) {
3423        this.sizeInfo.hasScrollBar = true;
3424        this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth + this.sizeInfo.scrollBarWidth;
3425      }
3426
3427      if (this.options.dropdownAlignRight === 'auto') {
3428        this.$menu.toggleClass(classNames.MENURIGHT, this.sizeInfo.selectOffsetLeft > this.sizeInfo.selectOffsetRight && this.sizeInfo.selectOffsetRight < (this.sizeInfo.totalMenuWidth - selectWidth));
3429      }
3430
3431      if (this.dropdown && this.dropdown._popper) this.dropdown._popper.update();
3432    },
3433
3434    setSize: function (refresh) {
3435      this.liHeight(refresh);
3436
3437      if (this.options.header) this.$menu.css('padding-top', 0);
3438
3439      if (this.options.size !== false) {
3440        var that = this,
3441            $window = $(window);
3442
3443        this.setMenuSize();
3444
3445        if (this.options.liveSearch) {
3446          this.$searchbox
3447            .off('input.setMenuSize propertychange.setMenuSize')
3448            .on('input.setMenuSize propertychange.setMenuSize', function () {
3449              return that.setMenuSize();
3450            });
3451        }
3452
3453        if (this.options.size === 'auto') {
3454          $window
3455            .off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize')
3456            .on('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize', function () {
3457              return that.setMenuSize();
3458            });
3459        } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) {
3460          $window.off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize');
3461        }
3462      }
3463
3464      this.createView(false, true, refresh);
3465    },
3466
3467    setWidth: function () {
3468      var that = this;
3469
3470      if (this.options.width === 'auto') {
3471        requestAnimationFrame(function () {
3472          that.$menu.css('min-width', '0');
3473
3474          that.$element.on('loaded' + EVENT_KEY, function () {
3475            that.liHeight();
3476            that.setMenuSize();
3477
3478            // Get correct width if element is hidden
3479            var $selectClone = that.$newElement.clone().appendTo('body'),
3480                btnWidth = $selectClone.css('width', 'auto').children('button').outerWidth();
3481
3482            $selectClone.remove();
3483
3484            // Set width to whatever's larger, button title or longest option
3485            that.sizeInfo.selectWidth = Math.max(that.sizeInfo.totalMenuWidth, btnWidth);
3486            that.$newElement.css('width', that.sizeInfo.selectWidth + 'px');
3487          });
3488        });
3489      } else if (this.options.width === 'fit') {
3490        // Remove inline min-width so width can be changed from 'auto'
3491        this.$menu.css('min-width', '');
3492        this.$newElement.css('width', '').addClass('fit-width');
3493      } else if (this.options.width) {
3494        // Remove inline min-width so width can be changed from 'auto'
3495        this.$menu.css('min-width', '');
3496        this.$newElement.css('width', this.options.width);
3497      } else {
3498        // Remove inline min-width/width so width can be changed
3499        this.$menu.css('min-width', '');
3500        this.$newElement.css('width', '');
3501      }
3502      // Remove fit-width class if width is changed programmatically
3503      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {
3504        this.$newElement[0].classList.remove('fit-width');
3505      }
3506    },
3507
3508    selectPosition: function () {
3509      this.$bsContainer = $('<div class="bs-container" />');
3510
3511      var that = this,
3512          $container = $(this.options.container),
3513          pos,
3514          containerPos,
3515          actualHeight,
3516          getPlacement = function ($element) {
3517            var containerPosition = {},
3518                // fall back to dropdown's default display setting if display is not manually set
3519                display = that.options.display || (
3520                  // Bootstrap 3 doesn't have $.fn.dropdown.Constructor.Default
3521                  $.fn.dropdown.Constructor.Default ? $.fn.dropdown.Constructor.Default.display
3522                  : false
3523                );
3524
3525            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass(classNames.DROPUP, $element.hasClass(classNames.DROPUP));
3526            pos = $element.offset();
3527
3528            if (!$container.is('body')) {
3529              containerPos = $container.offset();
3530              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();
3531              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();
3532            } else {
3533              containerPos = { top: 0, left: 0 };
3534            }
3535
3536            actualHeight = $element.hasClass(classNames.DROPUP) ? 0 : $element[0].offsetHeight;
3537
3538            // Bootstrap 4+ uses Popper for menu positioning
3539            if (version.major < 4 || display === 'static') {
3540              containerPosition.top = pos.top - containerPos.top + actualHeight;
3541              containerPosition.left = pos.left - containerPos.left;
3542            }
3543
3544            containerPosition.width = $element[0].offsetWidth;
3545
3546            that.$bsContainer.css(containerPosition);
3547          };
3548
3549      this.$button.on('click.bs.dropdown.data-api', function () {
3550        if (that.isDisabled()) {
3551          return;
3552        }
3553
3554        getPlacement(that.$newElement);
3555
3556        that.$bsContainer
3557          .appendTo(that.options.container)
3558          .toggleClass(classNames.SHOW, !that.$button.hasClass(classNames.SHOW))
3559          .append(that.$menu);
3560      });
3561
3562      $(window)
3563        .off('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId)
3564        .on('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId, function () {
3565          var isActive = that.$newElement.hasClass(classNames.SHOW);
3566
3567          if (isActive) getPlacement(that.$newElement);
3568        });
3569
3570      this.$element.on('hide' + EVENT_KEY, function () {
3571        that.$menu.data('height', that.$menu.height());
3572        that.$bsContainer.detach();
3573      });
3574    },
3575
3576    createOption: function (data, init) {
3577      var optionData = !data.option ? data : data.option;
3578
3579      if (optionData && optionData.nodeType !== 1) {
3580        var option = (init ? elementTemplates.selectedOption : elementTemplates.option).cloneNode(true);
3581        if (optionData.value !== undefined) option.value = optionData.value;
3582        option.textContent = optionData.text;
3583
3584        option.selected = true;
3585
3586        if (optionData.liIndex !== undefined) {
3587          option.liIndex = optionData.liIndex;
3588        } else if (!init) {
3589          option.liIndex = data.index;
3590        }
3591
3592        data.option = option;
3593
3594        this.selectpicker.main.optionQueue.appendChild(option);
3595      }
3596    },
3597
3598    setOptionStatus: function (selectedOnly) {
3599      var that = this;
3600
3601      that.noScroll = false;
3602
3603      if (that.selectpicker.view.visibleElements && that.selectpicker.view.visibleElements.length) {
3604        for (var i = 0; i < that.selectpicker.view.visibleElements.length; i++) {
3605          var liData = that.selectpicker.current.data[i + that.selectpicker.view.position0],
3606              option = liData.option;
3607
3608          if (option) {
3609            if (selectedOnly !== true) {
3610              that.setDisabled(liData);
3611            }
3612
3613            that.setSelected(liData);
3614          }
3615        }
3616
3617        // append optionQueue (documentFragment with option elements for select options)
3618        if (this.options.source.data) this.$element[0].appendChild(this.selectpicker.main.optionQueue);
3619      }
3620    },
3621
3622    /**
3623     * @param {Object} liData - the option object that is being changed
3624     * @param {boolean} selected - true if the option is being selected, false if being deselected
3625     */
3626    setSelected: function (liData, selected) {
3627      // console.log(liData);
3628      // console.log(selected);
3629
3630      selected = selected === undefined ? liData.selected : selected;
3631
3632      var li = liData.element,
3633          activeElementIsSet = this.activeElement !== undefined,
3634          thisIsActive = this.activeElement === li,
3635          prevActive,
3636          a,
3637          // if current option is already active
3638          // OR
3639          // if the current option is being selected, it's NOT multiple, and
3640          // activeElement is undefined:
3641          //  - when the menu is first being opened, OR
3642          //  - after a search has been performed, OR
3643          //  - when retainActive is false when selecting a new option (i.e. index of the newly selected option is not the same as the current activeElement)
3644          keepActive = thisIsActive || (selected && !this.multiple && !activeElementIsSet);
3645
3646      if (!li) return;
3647
3648      if (selected !== undefined) {
3649        liData.selected = selected;
3650        if (liData.option) liData.option.selected = selected;
3651      } else if (selected == true) {
3652        // srSpeak("Selected");
3653      } else if (selected == false) {
3654        // srSpeak("Unselected");
3655      }
3656
3657      if (selected && this.options.source.data) {
3658        this.createOption(liData, false);
3659      }
3660
3661      a = li.firstChild;
3662
3663      if (selected) {
3664        this.selectedElement = li;
3665      }
3666
3667      li.classList.toggle('selected', selected);
3668
3669      if (selected) {
3670        li.setAttribute('aria-selected', true);
3671      } else {
3672        if (this.multiple) {
3673          li.setAttribute('aria-selected', false);
3674        } else {
3675          li.removeAttribute('aria-selected');
3676        }
3677      }
3678
3679      if (keepActive) {
3680        this.focusItem(li, liData);
3681        this.selectpicker.view.currentActive = li;
3682        this.activeElement = li;
3683      } else {
3684        this.defocusItem(li);
3685      }
3686
3687      // TODO remove <a>
3688      if (a) {
3689        a.classList.toggle('selected', selected);
3690      }
3691
3692      if (!keepActive && !activeElementIsSet && selected && this.prevActiveElement !== undefined) {
3693        prevActive = this.prevActiveElement;
3694
3695        this.defocusItem(prevActive);
3696      }
3697    },
3698
3699    /**
3700     * @param {number} index - the index of the option that is being disabled
3701     * @param {boolean} disabled - true if the option is being disabled, false if being enabled
3702     */
3703    setDisabled: function (liData) {
3704      var disabled = liData.disabled,
3705          li = liData.element,
3706          a;
3707
3708      if (!li) return;
3709
3710      a = li.firstChild;
3711
3712      li.classList.toggle(classNames.DISABLED, disabled);
3713
3714      if (a) {
3715        if (version.major >= '4') a.classList.toggle(classNames.DISABLED, disabled);
3716
3717        if (disabled) {
3718          a.setAttribute('aria-disabled', disabled);
3719          // a.setAttribute('tabindex', -1);
3720        } else {
3721          a.removeAttribute('aria-disabled');
3722          // no need to have options in tab index
3723          // a.setAttribute('tabindex', 0);
3724        }
3725      }
3726    },
3727
3728    isDisabled: function () {
3729      return this.$element[0].disabled;
3730    },
3731
3732    checkDisabled: function () {
3733      if (this.isDisabled()) {
3734        this.$newElement[0].classList.add(classNames.DISABLED);
3735        this.$button.addClass(classNames.DISABLED).attr('aria-disabled', true);
3736      } else {
3737        if (this.$button[0].classList.contains(classNames.DISABLED)) {
3738          this.$newElement[0].classList.remove(classNames.DISABLED);
3739          this.$button.removeClass(classNames.DISABLED).attr('aria-disabled', false);
3740        }
3741      }
3742    },
3743
3744    clickListener: function () {
3745      var that = this,
3746          $document = $(document);
3747
3748      $document.data('spaceSelect', false);
3749
3750      this.$button.on('keyup', function (e) {
3751        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {
3752          e.preventDefault();
3753          $document.data('spaceSelect', false);
3754        }
3755      });
3756
3757      this.$newElement.on('show.bs.dropdown', function () {
3758        if (!that.dropdown && version.major === '4') {
3759          that.dropdown = that.$button.data('bs.dropdown');
3760          that.dropdown._menu = that.$menu[0];
3761        }
3762      });
3763
3764      function clearSelection (e) {
3765        if (that.multiple) {
3766          that.deselectAll();
3767        } else {
3768          var element = that.$element[0],
3769              prevValue = element.value,
3770              prevIndex = element.selectedIndex,
3771              prevOption = element.options[prevIndex],
3772              prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false;
3773
3774          if (prevData) {
3775            that.setSelected(prevData, false);
3776          }
3777
3778          element.selectedIndex = 0;
3779
3780          changedArguments = [prevIndex, false, prevValue];
3781          that.$element.triggerNative('change');
3782        }
3783
3784        // remove selected styling if menu is open
3785        if (that.$newElement.hasClass(classNames.SHOW)) {
3786          if (that.options.liveSearch) {
3787            that.$searchbox.trigger('focus');
3788          }
3789
3790          that.createView(false);
3791        }
3792      }
3793
3794      this.$button.on('click.bs.dropdown.data-api', function (e) {
3795        if (that.options.allowClear) {
3796          var target = e.target,
3797              clearButton = that.$clearButton[0];
3798
3799          // IE doesn't support event listeners on child elements of buttons
3800          if (/MSIE|Trident/.test(window.navigator.userAgent)) {
3801            target = document.elementFromPoint(e.clientX, e.clientY);
3802          }
3803
3804          if (target === clearButton || target.parentElement === clearButton) {
3805            e.stopImmediatePropagation();
3806            clearSelection(e);
3807          }
3808        }
3809
3810        if (!that.$newElement.hasClass(classNames.SHOW)) {
3811          that.setSize();
3812        }
3813      });
3814
3815      function setFocus () {
3816        if (that.options.liveSearch) {
3817          that.$searchbox.trigger('focus');
3818        } else {
3819          that.$menuInner.trigger('focus');
3820        }
3821      }
3822
3823      function checkPopperExists () {
3824        if (that.dropdown && that.dropdown._popper && that.dropdown._popper.state) {
3825          setFocus();
3826        } else {
3827          requestAnimationFrame(checkPopperExists);
3828        }
3829      }
3830
3831      this.$element.on('shown' + EVENT_KEY, function () {
3832        if (that.$menuInner[0].scrollTop !== that.selectpicker.view.scrollTop) {
3833          that.$menuInner[0].scrollTop = that.selectpicker.view.scrollTop;
3834        }
3835
3836        if (version.major > 3) {
3837          requestAnimationFrame(checkPopperExists);
3838        } else {
3839          setFocus();
3840        }
3841      });
3842
3843      // ensure posinset and setsize are correct before selecting an option via a click
3844      this.$menuInner.on('mouseenter', 'li .dropdown-item', function (e) {
3845        var hoverLi = this.parentElement,
3846            position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0,
3847            index = Array.prototype.indexOf.call(hoverLi.parentElement.children, hoverLi),
3848            hoverData = that.selectpicker.current.data[index + position0];
3849
3850        that.focusItem(hoverLi, hoverData, true);
3851      });
3852
3853      this.$menuInner.on('click', 'li .dropdown-item', function (e, retainActive) {
3854        var $this = $(this),
3855            element = that.$element[0],
3856            position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0,
3857            // $items = that.findLis(),
3858            $parent = $this.parent(),
3859            // clickedIndex = $items.index($parent),
3860            clickedIndex = Number($parent.attr('data-index')),
3861            clickedData = that.selectpicker.current.data[clickedIndex + position0],
3862            clickedElement = clickedData.element,
3863            prevValue = getSelectValues.call(that),
3864            prevIndex = element.selectedIndex,
3865            prevOption = element.options[prevIndex],
3866            prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false,
3867            triggerChange = true;
3868
3869        // console.log('that.selectpicker.main.data', that.selectpicker.main.data);
3870
3871        // Don't close on multi choice menu
3872        if (that.multiple && that.options.maxOptions !== 1) {
3873          e.stopPropagation();
3874        }
3875
3876        e.preventDefault();
3877
3878        // Don't run if the select is disabled
3879        if (!that.isDisabled() && !$this.parent().hasClass(classNames.DISABLED)) {
3880          var option = clickedData.option,
3881              $option = $(option),
3882              state = option.selected,
3883              optgroupData = that.selectpicker.current.data.find(function (datum) {
3884                return datum.optID === clickedData.optID && datum.type === 'optgroup-label';
3885              }),
3886              optgroup = optgroupData ? optgroupData.optgroup : undefined,
3887              dataGetter = optgroup instanceof Element ? getOptionData.fromOption : getOptionData.fromDataSource,
3888              optgroupOptions = optgroup && optgroup.children,
3889              maxOptions = parseInt(that.options.maxOptions),
3890              maxOptionsGrp = optgroup && parseInt(dataGetter(optgroup, 'maxOptions')) || false;
3891
3892          if (clickedElement === that.activeElement) retainActive = true;
3893
3894          if (!retainActive) {
3895            that.prevActiveElement = that.activeElement;
3896            that.activeElement = undefined;
3897          }
3898
3899          if (!that.multiple || maxOptions === 1) { // Deselect previous option if not multi select
3900            if (prevData) that.setSelected(prevData, false);
3901            that.setSelected(clickedData, true);
3902          } else { // Toggle the clicked option if multi select.
3903            that.setSelected(clickedData, !state);
3904            that.focusedParent.focus();
3905
3906            if (maxOptions !== false || maxOptionsGrp !== false) {
3907              var maxReached = maxOptions < getSelectedOptions.call(that).length,
3908                  selectedGroupOptions = 0;
3909
3910              if (optgroup && optgroup.children) {
3911                for (var i = 0; i < optgroup.children.length; i++) {
3912                  if (optgroup.children[i].selected) selectedGroupOptions++;
3913                }
3914              }
3915
3916              var maxReachedGrp = maxOptionsGrp < selectedGroupOptions;
3917
3918              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {
3919                if (maxOptions && maxOptions === 1) {
3920                  element.selectedIndex = -1;
3921                  that.setOptionStatus(true);
3922                } else if (maxOptionsGrp && maxOptionsGrp === 1) {
3923                  for (var i = 0; i < optgroupOptions.length; i++) {
3924                    var _option = optgroupOptions[i];
3925                    that.setSelected(that.selectpicker.current.data[_option.liIndex], false);
3926                  }
3927
3928                  that.setSelected(clickedData, true);
3929                } else {
3930                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,
3931                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,
3932                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),
3933                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),
3934                      $notify = $('<div class="notify"></div>');
3935                  // If {var} is set in array, replace it
3936                  /** @deprecated */
3937                  if (maxOptionsArr[2]) {
3938                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);
3939                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);
3940                  }
3941
3942                  that.$menu.append($notify);
3943
3944                  if (maxOptions && maxReached) {
3945                    $notify.append($('<div>' + maxTxt + '</div>'));
3946                    triggerChange = false;
vendor: 6,946 bytes, lines 3947-4137
3947                    that.$element.trigger('maxReached' + EVENT_KEY);
3948                  }
3949
3950                  if (maxOptionsGrp && maxReachedGrp) {
3951                    $notify.append($('<div>' + maxTxtGrp + '</div>'));
3952                    triggerChange = false;
3953                    that.$element.trigger('maxReachedGrp' + EVENT_KEY);
3954                  }
3955
3956                  setTimeout(function () {
3957                    that.setSelected(clickedData, false);
3958                  }, 10);
3959
3960                  $notify[0].classList.add('fadeOut');
3961
3962                  setTimeout(function () {
3963                    $notify.remove();
3964                  }, 1050);
3965                }
3966              }
3967            }
3968          }
3969
3970          if (that.options.source.data) that.$element[0].appendChild(that.selectpicker.main.optionQueue);
3971
3972          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {
3973            that.$button.trigger('focus');
3974          } else if (that.options.liveSearch) {
3975            that.$searchbox.trigger('focus');
3976          }
3977
3978          // Trigger select 'change'
3979          if (triggerChange) {
3980            if (that.multiple || prevIndex !== element.selectedIndex) {
3981              // $option.prop('selected') is current option state (selected/unselected). prevValue is the value of the select prior to being changed.
3982              changedArguments = [option.index, $option.prop('selected'), prevValue];
3983              that.$element
3984                .triggerNative('change');
3985            }
3986          }
3987        }
3988      });
3989
3990      this.$menu.on('click', 'li.' + classNames.DISABLED + ' .dropdown-item, .' + classNames.POPOVERHEADER + ', .' + classNames.POPOVERHEADER + ' :not(.close)', function (e) {
3991        if (e.currentTarget == this) {
3992          e.preventDefault();
3993          e.stopPropagation();
3994          if (that.options.liveSearch && !$(e.target).hasClass('close')) {
3995            that.$searchbox.trigger('focus');
3996          } else {
3997            that.$button.trigger('focus');
3998          }
3999        }
4000      });
4001
4002      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {
4003        e.preventDefault();
4004        e.stopPropagation();
4005        if (that.options.liveSearch) {
4006          that.$searchbox.trigger('focus');
4007        } else {
4008          that.$button.trigger('focus');
4009        }
4010      });
4011
4012      this.$menu.on('click', '.' + classNames.POPOVERHEADER + ' .close', function () {
4013        that.$button.trigger('click');
4014      });
4015
4016      this.$searchbox.on('click', function (e) {
4017        e.stopPropagation();
4018      });
4019
4020      this.$menu.on('click', '.actions-btn', function (e) {
4021        if (that.options.liveSearch) {
4022          that.$searchbox.trigger('focus');
4023        } else {
4024          that.$button.trigger('focus');
4025        }
4026
4027        e.preventDefault();
4028        e.stopPropagation();
4029
4030        if ($(this).hasClass('bs-select-all')) {
4031          that.selectAll();
4032        } else {
4033          that.deselectAll();
4034        }
4035      });
4036
4037      // this.$button
4038      //   .on('focus' + EVENT_KEY, function (e) {
4039      //     var tabindex = that.$element[0].getAttribute('tabindex');
4040      //     // only change when button is actually focused
4041      //     if (tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) {
4042      //       // removing this NL
4043      //       // apply select element's tabindex to ensure correct order is followed when tabbing to the next element
4044      //       // this.setAttribute('tabindex', tabindex);
4045      //       // set element's tabindex to -1 to allow for reverse tabbing
4046      //       // removing this NL
4047      //       // that.$element[0].setAttribute('tabindex', -1);
4048      //       // that.selectpicker.view.tabindex = tabindex;
4049      //     }
4050      //   })
4051      //   .on('blur' + EVENT_KEY, function (e) {
4052      //     // removing this NL
4053      //     // revert everything to original tabindex
4054      //     // if (that.selectpicker.view.tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) {
4055      //     //   that.$element[0].setAttribute('tabindex', that.selectpicker.view.tabindex);
4056      //     //   this.setAttribute('tabindex', -1);
4057      //     //   that.selectpicker.view.tabindex = undefined;
4058      //     // }
4059      //   });
4060
4061      this.$element
4062        .on('change' + EVENT_KEY, function () {
4063          that.render();
4064          that.$element.trigger('changed' + EVENT_KEY, changedArguments);
4065          changedArguments = null;
4066        })
4067        .on('focus' + EVENT_KEY, function () {
4068          if (!that.options.mobile) that.$button[0].focus();
4069        });
4070    },
4071
4072    liveSearchListener: function () {
4073      var that = this;
4074
4075      this.$button.on('click.bs.dropdown.data-api', function () {
4076        if (!!that.$searchbox.val()) {
4077          that.$searchbox.val('');
4078          that.selectpicker.search.previousValue = undefined;
4079        }
4080      });
4081
4082      this.$searchbox.on('click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api', function (e) {
4083        e.stopPropagation();
4084      });
4085
4086      this.$searchbox.on('input propertychange', function () {
4087        var searchValue = that.$searchbox[0].value;
4088
4089        that.selectpicker.search.elements = [];
4090        that.selectpicker.search.data = [];
4091
4092        if (searchValue) {
4093          that.selectpicker.search.previousValue = searchValue;
4094
4095          if (that.options.source.search) {
4096            that.fetchData(function (builtData) {
4097              that.render();
4098              that.buildList(undefined, true);
4099              that.noScroll = true;
4100              that.$menuInner.scrollTop(0);
4101              that.createView(true);
4102              showNoResults.call(that, builtData, searchValue);
4103            }, 'search', 0, searchValue);
4104          } else {
4105            var i,
4106                searchMatch = [],
4107                q = searchValue.toUpperCase(),
4108                cache = {},
4109                cacheArr = [],
4110                searchStyle = that._searchStyle(),
4111                normalizeSearch = that.options.liveSearchNormalize;
4112
4113            if (normalizeSearch) q = normalizeToBase(q);
4114
4115            for (var i = 0; i < that.selectpicker.main.data.length; i++) {
4116              var li = that.selectpicker.main.data[i];
4117
4118              if (!cache[i]) {
4119                cache[i] = stringSearch(li, q, searchStyle, normalizeSearch);
4120              }
4121
4122              if (cache[i] && li.headerIndex !== undefined && cacheArr.indexOf(li.headerIndex) === -1) {
4123                if (li.headerIndex > 0) {
4124                  cache[li.headerIndex - 1] = true;
4125                  cacheArr.push(li.headerIndex - 1);
4126                }
4127
4128                cache[li.headerIndex] = true;
4129                cacheArr.push(li.headerIndex);
4130
4131                cache[li.lastIndex + 1] = true;
4132              }
4133
4134              if (cache[i] && li.type !== 'optgroup-label') cacheArr.push(i);
4135            }
4136
4137            for (var i = 0, cacheLen = cacheArr.length; i < cacheLen; i++) {
4138              var index = cacheArr[i],
4139                  prevIndex = cacheArr[i - 1],
4140                  li = that.selectpicker.main.data[index],
4141                  liPrev = that.selectpicker.main.data[prevIndex];
4142
4143              if (li.type !== 'divider' || (li.type === 'divider' && liPrev && liPrev.type !== 'divider' && cacheLen - 1 !== i)) {
4144                that.selectpicker.search.data.push(li);
4145                searchMatch.push(that.selectpicker.main.elements[index]);
4146              }
4147            }
4148
4149            that.activeElement = undefined;
4150            that.noScroll = true;
4151            that.$menuInner.scrollTop(0);
4152            that.selectpicker.search.elements = searchMatch;
4153            that.createView(true);
4154            showNoResults.call(that, searchMatch, searchValue);
4155          }
4156        } else if (that.selectpicker.search.previousValue) { // for IE11 (#2402)
4157          that.$menuInner.scrollTop(0);
4158          that.createView(false);
4159        }
4160      });
4161    },
4162
4163    _searchStyle: function () {
4164      return this.options.liveSearchStyle || 'contains';
4165    },
4166
4167    val: function (value) {
4168      var element = this.$element[0];
4169
4170      if (typeof value !== 'undefined') {
4171        var selectedOptions = getSelectedOptions.call(this),
4172            prevValue = getSelectValues.call(this, selectedOptions);
4173
4174        changedArguments = [null, null, prevValue];
4175
4176        if (!Array.isArray(value)) value = [ value ];
4177
4178        value.map(String);
4179
4180        for (var i = 0; i < selectedOptions.length; i++) {
4181          var item = selectedOptions[i];
4182
4183          if (item && value.indexOf(String(item.value)) === -1) {
4184            this.setSelected(item, false);
4185          }
4186        }
4187
4188        // only update selected value if it matches an existing option
4189        this.selectpicker.main.data.filter(function (item) {
4190          if (value.indexOf(String(item.value)) !== -1) {
4191            this.setSelected(item, true);
4192            return true;
4193          }
4194
4195          return false;
4196        }, this);
4197
4198        if (this.options.source.data) element.appendChild(this.selectpicker.main.optionQueue);
4199
4200        this.$element.trigger('changed' + EVENT_KEY, changedArguments);
4201
4202        if (this.$newElement.hasClass(classNames.SHOW)) {
4203          if (this.multiple) {
4204            this.setOptionStatus(true);
4205          } else {
4206            var liSelectedIndex = (element.options[element.selectedIndex] || {}).liIndex;
4207
4208            if (typeof liSelectedIndex === 'number') {
4209              this.setSelected(this.selectpicker.current.data[liSelectedIndex], true);
4210            }
4211          }
4212        }
4213
4214        this.render();
4215
4216        changedArguments = null;
4217
4218        return this.$element;
4219      } else {
4220        return this.$element.val();
4221      }
4222    },
4223
4224    changeAll: function (status) {
4225      if (!this.multiple) return;
4226      if (typeof status === 'undefined') status = true;
4227
4228      var element = this.$element[0],
4229          previousSelected = 0,
4230          currentSelected = 0,
4231          prevValue = getSelectValues.call(this);
4232
4233      element.classList.add('bs-select-hidden');
4234
4235      for (var i = 0, data = this.selectpicker.current.data, len = data.length; i < len; i++) {
4236        var liData = data[i],
4237            option = liData.option;
4238
4239        if (option && !liData.disabled && liData.type !== 'divider') {
4240          if (liData.selected) previousSelected++;
4241          option.selected = status;
4242          liData.selected = status;
4243          if (status === true) currentSelected++;
4244        }
4245      }
4246
4247      element.classList.remove('bs-select-hidden');
4248
4249      if (previousSelected === currentSelected) return;
4250
4251      this.setOptionStatus();
4252
4253      changedArguments = [null, null, prevValue];
4254
4255      this.$element
4256        .triggerNative('change');
4257    },
4258
4259    selectAll: function () {
4260      return this.changeAll(true);
4261    },
4262
4263    deselectAll: function () {
4264      return this.changeAll(false);
4265    },
4266
4267    toggle: function (e, state) {
4268      var isActive,
4269          triggerClick = state === undefined;
4270
4271      e = e || window.event;
4272
4273      if (e) e.stopPropagation();
4274
4275      if (triggerClick === false) {
4276        isActive = this.$newElement[0].classList.contains(classNames.SHOW);
4277        triggerClick = state === true && isActive === false || state === false && isActive === true;
4278      }
4279
4280      if (triggerClick) this.$button.trigger('click.bs.dropdown.data-api');
4281    },
4282
4283    open: function (e) {
4284      this.toggle(e, true);
4285    },
4286
4287    close: function (e) {
4288      this.toggle(e, false);
4289    },
4290
4291    keydown: function (e) {
4292      var $this = $(this),
4293          isToggle = $this.hasClass('dropdown-toggle'),
4294          $parent = isToggle ? $this.closest('.dropdown') : $this.closest(Selector.MENU),
4295          that = $parent.data('this'),
4296          $items = that.findLis(),
4297          index,
4298          isActive,
4299          liActive,
4300          activeLi,
4301          offset,
4302          updateScroll = false,
4303          downOnTab = e.which === keyCodes.TAB && !isToggle && !that.options.selectOnTab,
4304          isArrowKey = REGEXP_ARROW.test(e.which) || downOnTab,
4305          scrollTop = that.$menuInner[0].scrollTop,
4306          isVirtual = that.isVirtual(),
4307          position0 = isVirtual === true ? that.selectpicker.view.position0 : 0;
4308
4309      // do nothing if a function key is pressed
4310      if (e.which >= 112 && e.which <= 123) return;
4311
4312      isActive = that.$menu.hasClass(classNames.SHOW);
4313
4314      if (
4315        !isActive &&
4316        (
4317          isArrowKey ||
4318          (e.which >= 48 && e.which <= 57) ||
4319          (e.which >= 96 && e.which <= 105) ||
4320          (e.which >= 65 && e.which <= 90) ||
4321          e.which === keyCodes.SPACE ||
4322          e.which === keyCodes.ENTER
4323        )
4324      ) {
4325        that.$button.trigger('click.bs.dropdown.data-api');
4326
4327        if (that.options.liveSearch) {
4328          that.$searchbox.trigger('focus');
4329          return;
4330        }
4331      }
4332
4333      if (e.which === keyCodes.ESCAPE && isActive) {
4334        e.preventDefault();
4335        that.$button.trigger('click.bs.dropdown.data-api').trigger('focus');
4336      }
4337
4338      // if the dropdown wasn't active, activte the first item when pushing space, enter or "down"
4339      if (
4340        !isActive &&
4341        (
4342          e.which === keyCodes.SPACE ||
4343          e.which === keyCodes.ENTER ||
4344          e.which === keyCodes.ARROW_DOWN
4345        )
4346      ) {
4347        liActive = that.selectpicker.current.elements[0];
4348
4349        that.focusItem(liActive);
4350      }
4351
4352      if (isArrowKey) { // if up or down, enter or space
4353        // if (!$items.length) return;
4354        $items = that.findLis();
4355
4356        liActive = that.activeElement;
4357        // index = liActive ? Array.prototype.indexOf.call($items, liActive) : -1;
4358        // index = liActive ? Array.prototype.indexOf.call(liActive.parentElement.children, liActive) : -1;
4359        index =  liActive ? $items.index(liActive) : -1;
4360        // var index =  liActive ? Number(liActive.getAttribute('data-index')) : -1;
4361
4362        if (index !== -1) {
4363          that.defocusItem(liActive);
4364        }
4365
4366        if (e.which === keyCodes.ARROW_UP) { // up
4367          if (index !== -1) {
4368            index--;
4369          }
4370          // if (index + position0 < 0) index += $items.length;
4371          if (index + position0 < 0) index += $items.length; // that.selectpicker.current.data.length;
4372
4373          // console.log(index);
4374          // console.log($items);
4375          // console.log('$items.length', $items.length);
4376
4377          if (!that.selectpicker.view.canHighlight[index + position0]) {
4378            index = that.selectpicker.view.canHighlight.slice(0, index + position0).lastIndexOf(true) - position0;
4379            if (index === -1) {
4380              index = $items.length - 1;
4381            };
4382          }
4383        } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down
4384          index++;
4385          if (index + position0 >= that.selectpicker.view.canHighlight.length) index = that.selectpicker.view.firstHighlightIndex;
4386
4387          if (!that.selectpicker.view.canHighlight[index + position0]) {
4388            index = index + 1 + that.selectpicker.view.canHighlight.slice(index + position0 + 1).indexOf(true);
4389          }
4390        }
4391
4392        e.preventDefault();
4393
4394        var liActiveIndex = position0 + index;
4395        if (e.which === keyCodes.ARROW_UP) { // up
4396          // scroll to bottom and highlight last option
4397          if (position0 === 0 && index === $items.length - 1) {
4398          // if (position0 === 0 && index === $items.length - 1) {
4399            that.$menuInner[0].scrollTop = that.$menuInner[0].scrollHeight;
4400
4401            liActiveIndex = that.selectpicker.current.elements.length - 1;
4402          } else {
4403            activeLi = that.selectpicker.current.data[liActiveIndex];
4404
4405            // could be undefined if no results exist
4406            if (activeLi) {
4407              offset = activeLi.position - activeLi.height;
4408
4409              updateScroll = offset < scrollTop;
4410            }
4411          }
4412        } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down
4413          // scroll to top and highlight first option
4414          if (index === that.selectpicker.view.firstHighlightIndex) {
4415            that.$menuInner[0].scrollTop = 0;
4416
4417            liActiveIndex = that.selectpicker.view.firstHighlightIndex;
4418          } else {
4419            activeLi = that.selectpicker.current.data[liActiveIndex];
4420
4421            // could be undefined if no results exist
4422            if (activeLi) {
4423              offset = activeLi.position - that.sizeInfo.menuInnerHeight;
4424
4425              updateScroll = offset > scrollTop;
4426            }
4427          }
4428        }
4429
4430        liActive = that.selectpicker.current.elements[liActiveIndex];
4431
4432        that.activeElement = (that.selectpicker.current.data[liActiveIndex] || {}).element;
4433
4434        that.focusItem(liActive);
4435
4436        that.selectpicker.view.currentActive = liActive;
4437
4438        if (updateScroll) that.$menuInner[0].scrollTop = offset;
4439
4440        if (that.options.liveSearch) {
4441          that.$searchbox.trigger('focus');
4442        } else {
4443          $this.trigger('focus');
4444        }
4445      } else if (
4446        (!$this.is('input') && !REGEXP_TAB_OR_ESCAPE.test(e.which)) ||
4447        (e.which === keyCodes.SPACE && that.selectpicker.keydown.keyHistory)
4448      ) {
4449        var searchMatch,
4450            matches = [],
4451            keyHistory;
4452
4453        e.preventDefault();
4454
4455        that.selectpicker.keydown.keyHistory += keyCodeMap[e.which];
4456
4457        if (that.selectpicker.keydown.resetKeyHistory.cancel) clearTimeout(that.selectpicker.keydown.resetKeyHistory.cancel);
4458        that.selectpicker.keydown.resetKeyHistory.cancel = that.selectpicker.keydown.resetKeyHistory.start();
4459
4460        keyHistory = that.selectpicker.keydown.keyHistory;
4461
4462        // if all letters are the same, set keyHistory to just the first character when searching
4463        if (/^(.)\1+$/.test(keyHistory)) {
4464          keyHistory = keyHistory.charAt(0);
4465        }
4466
4467        // find matches
4468        for (var i = 0; i < that.selectpicker.current.data.length; i++) {
4469          var li = that.selectpicker.current.data[i],
4470              hasMatch;
4471
4472          hasMatch = stringSearch(li, keyHistory, 'startsWith', true);
4473
4474          if (hasMatch && that.selectpicker.view.canHighlight[i]) {
4475            matches.push(li.element);
4476          }
4477        }
4478
4479        if (matches.length) {
4480          var matchIndex = 0;
4481
4482          // TODO remove a
4483          $items.removeClass('active').find('dropdown-item').removeClass('active');
4484
4485          // either only one key has been pressed or they are all the same key
4486          if (keyHistory.length === 1) {
4487            matchIndex = matches.indexOf(that.activeElement);
4488
4489            if (matchIndex === -1 || matchIndex === matches.length - 1) {
4490              matchIndex = 0;
4491            } else {
4492              matchIndex++;
4493            }
4494          }
4495
4496          searchMatch = matches[matchIndex];
4497
4498          activeLi = that.selectpicker.main.data[searchMatch];
4499
4500          if (scrollTop - activeLi.position > 0) {
4501            offset = activeLi.position - activeLi.height;
4502            updateScroll = true;
4503          } else {
4504            offset = activeLi.position - that.sizeInfo.menuInnerHeight;
4505            // if the option is already visible at the current scroll position, just keep it the same
4506            updateScroll = activeLi.position > scrollTop + that.sizeInfo.menuInnerHeight;
4507          }
4508
4509          liActive = that.selectpicker.main.elements[searchMatch];
4510
4511          that.activeElement = liActive;
4512
4513          that.focusItem(liActive);
4514
4515          if (liActive) liActive.firstChild.focus();
4516
4517          if (updateScroll) that.$menuInner[0].scrollTop = offset;
4518
4519          $this.trigger('focus');
4520        }
4521      }
4522
4523      // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu.
4524      // console.log('!that.selectpicker.keydown.keyHistory', !that.selectpicker.keydown.keyHistory);
4525      // console.log('keyCodes.SPACE?', e.which === keyCodes.SPACE);
4526      // console.log('keyCodes', e.which);
4527      if (
4528        isActive &&
4529        (
4530          e.which === keyCodes.SPACE ||
4531          e.which === keyCodes.ENTER ||
4532          (e.which === keyCodes.TAB && that.options.selectOnTab)
4533        )
4534      ) {
4535        // if (e.which !== keyCodes.SPACE) e.preventDefault();
4536        // console.log(e.which);
4537        // on click of Enter of Space, activate that dropdown item.
4538        if (!that.options.liveSearch && (e.which === keyCodes.ENTER || e.which == keyCodes.SPACE)) {
4539          // console.log('clicked!');
4540          that.$menuInner.find('.active .dropdown-item').trigger('click', true); // retain active class
4541          $this.trigger('focus');
4542
4543          if (!that.options.liveSearch) {
4544            // Prevent screen from scrolling if the user hits the spacebar
4545            e.preventDefault();
4546            // Fixes spacebar selection of dropdown items in FF & IE
4547            $(document).data('spaceSelect', true);
4548          }
4549        }
4550      }
4551    },
4552
4553    mobile: function () {
4554      // ensure mobile is set to true if mobile function is called after init
4555      this.options.mobile = true;
4556      this.$element[0].classList.add('mobile-device');
4557    },
4558
4559    refresh: function () {
4560      var that = this;
4561      // activeElement = that.activeElement;
4562      var activeElementIndex = this.selectpicker.current.elements.indexOf(this.activeElement);
4563      // var activeElementIndex = this.selectpicker.current.data[this.selectpicker.current.elements.indexOf(this.activeElement)]
4564      // update options if data attributes have been changed
4565      var config = $.extend({}, this.options, getAttributesObject(this.$element), this.$element.data()); // in this order on refresh, as user may change attributes on select, and options object is not passed on refresh
4566      this.options = config;
4567
4568      if (this.options.source.data) {
4569        this.render();
4570        this.buildList();
4571      } else {
4572        this.fetchData(function () {
4573          that.render();
4574          that.buildList();
4575        });
4576      }
4577
4578      this.checkDisabled();
4579
4580      this.setStyle();
4581      this.setWidth();
4582
4583      this.setSize(true);
4584
4585      this.$element.trigger('refreshed' + EVENT_KEY);
4586
4587      // refocus the element with focus after a refresh
4588      if (activeElementIndex !== -1) {
4589        var li = this.selectpicker.current.data[activeElementIndex].element;
4590        var liData = this.selectpicker.current.data[activeElementIndex];
4591        this.focusItem(li, liData);
4592        this.selectpicker.view.currentActive = li;
4593        this.activeElement = li;
4594      }
4595    },
4596
4597    hide: function () {
4598      this.$newElement.hide();
4599    },
4600
4601    show: function () {
4602      this.$newElement.show();
4603    },
4604
4605    remove: function () {
4606      this.$newElement.remove();
4607      this.$element.remove();
4608    },
4609
4610    destroy: function () {
4611      this.$newElement.before(this.$element).remove();
4612
4613      if (this.$bsContainer) {
4614        this.$bsContainer.remove();
4615      } else {
4616        this.$menu.remove();
4617      }
4618
4619      if (this.selectpicker.view.titleOption && this.selectpicker.view.titleOption.parentNode) {
4620        this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption);
4621      }
4622
4623      this.$element
4624        .off(EVENT_KEY)
4625        .removeData('selectpicker')
4626        .removeClass('bs-select-hidden selectpicker mobile-device');
4627
4628      $(window).off(EVENT_KEY + '.' + this.selectId);
4629    }
4630  };
4631
4632  // SELECTPICKER PLUGIN DEFINITION
4633  // ==============================
4634  function Plugin (option) {
4635    // get the args of the outer function..
4636    var args = arguments;
4637    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them
4638    // to get lost/corrupted in android 2.3 and IE9 #715 #775
4639    var _option = option;
4640
4641    [].shift.apply(args);
4642
4643    // if the version was not set successfully
4644    if (!version.success) {
4645      // try to retreive it again
4646      try {
4647        version.full = (getVersion() || '').split(' ')[0].split('.');
4648      } catch (err) {
4649        // fall back to use BootstrapVersion if set
4650        if (Selectpicker.BootstrapVersion) {
4651          version.full = Selectpicker.BootstrapVersion.split(' ')[0].split('.');
4652        } else {
4653          version.full = [version.major, '0', '0'];
4654
4655          console.warn(
4656            'There was an issue retrieving Bootstrap\'s version. ' +
4657            'Ensure Bootstrap is being loaded before bootstrap-select and there is no namespace collision. ' +
4658            'If loading Bootstrap asynchronously, the version may need to be manually specified via $.fn.selectpicker.Constructor.BootstrapVersion.',
4659            err
4660          );
4661        }
4662      }
4663
4664      version.major = version.full[0];
4665      version.success = true;
4666    }
4667
4668    if (version.major >= '4') {
4669      // some defaults need to be changed if using Bootstrap 4
4670      // check to see if they have already been manually changed before forcing them to update
4671      var toUpdate = [];
4672
4673      if (Selectpicker.DEFAULTS.style === classNames.BUTTONCLASS) toUpdate.push({ name: 'style', className: 'BUTTONCLASS' });
4674      if (Selectpicker.DEFAULTS.iconBase === classNames.ICONBASE) toUpdate.push({ name: 'iconBase', className: 'ICONBASE' });
4675      if (Selectpicker.DEFAULTS.tickIcon === classNames.TICKICON) toUpdate.push({ name: 'tickIcon', className: 'TICKICON' });
4676
4677      classNames.DIVIDER = 'dropdown-divider';
4678      classNames.SHOW = 'show';
4679      classNames.BUTTONCLASS = 'btn-light';
4680      classNames.POPOVERHEADER = 'popover-header';
4681      classNames.ICONBASE = '';
4682      classNames.TICKICON = 'bs-ok-default';
4683
4684      for (var i = 0; i < toUpdate.length; i++) {
4685        var option = toUpdate[i];
4686        Selectpicker.DEFAULTS[option.name] = classNames[option.className];
4687      }
4688    }
4689
4690    if (version.major > '4') {
4691      Selector.DATA_TOGGLE = 'data-bs-toggle="dropdown"';
4692    }
4693
4694    var value;
4695    var chain = this.each(function () {
4696      var $this = $(this);
4697      if ($this.is('select')) {
4698        var data = $this.data('selectpicker'),
4699            options = typeof _option == 'object' && _option;
4700
4701        // for backwards compatibility
4702        // (using title as placeholder is deprecated - remove in v2.0.0)
4703        if (options.title) options.placeholder = options.title;
4704
4705        if (!data) {
4706          var dataAttributes = $this.data();
4707
4708          for (var dataAttr in dataAttributes) {
4709            if (Object.prototype.hasOwnProperty.call(dataAttributes, dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) {
4710              delete dataAttributes[dataAttr];
4711            }
4712          }
4713
4714          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, getAttributesObject($this), dataAttributes, options); // this is correct order on initial render
4715          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), dataAttributes.template, options.template);
4716          config.source = $.extend({}, Selectpicker.DEFAULTS.source, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.source : {}), options.source);
4717          $this.data('selectpicker', (data = new Selectpicker(this, config)));
4718        } else if (options) {
4719          for (var i in options) {
4720            if (Object.prototype.hasOwnProperty.call(options, i)) {
4721              data.options[i] = options[i];
4722            }
4723          }
4724        }
4725
4726        if (typeof _option == 'string') {
4727          if (data[_option] instanceof Function) {
4728            value = data[_option].apply(data, args);
4729          } else {
4730            value = data.options[_option];
4731          }
4732        }
4733      }
4734    });
4735
4736    if (typeof value !== 'undefined') {
4737      // noinspection JSUnusedAssignment
4738      return value;
4739    } else {
4740      return chain;
4741    }
4742  }
4743
4744  var old = $.fn.selectpicker;
4745  $.fn.selectpicker = Plugin;
4746  $.fn.selectpicker.Constructor = Selectpicker;
4747
4748  // SELECTPICKER NO CONFLICT
4749  // ========================
4750  $.fn.selectpicker.noConflict = function () {
4751    $.fn.selectpicker = old;
4752    return this;
4753  };
4754
4755  // get Bootstrap's keydown event handler for either Bootstrap 4 or Bootstrap 3
4756  function keydownHandler () {
4757    if (version.major < 5) {
4758      if ($.fn.dropdown) {
4759        // wait to define until function is called in case Bootstrap isn't loaded yet
4760        var bootstrapKeydown = $.fn.dropdown.Constructor._dataApiKeydownHandler || $.fn.dropdown.Constructor.prototype.keydown;
4761        return bootstrapKeydown.apply(this, arguments);
4762      }
4763    } else {
4764      return Dropdown.dataApiKeydownHandler;
4765    }
4766  }
4767
4768  $(document)
4769    .off('keydown.bs.dropdown.data-api')
4770    .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > [' + Selector.DATA_TOGGLE + ']', keydownHandler)
4771    .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > .dropdown-menu', keydownHandler)
4772    .on('keydown' + EVENT_KEY, '.bootstrap-select [' + Selector.DATA_TOGGLE + '], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', Selectpicker.prototype.keydown)
4773    .on('focusin.modal', '.bootstrap-select [' + Selector.DATA_TOGGLE + '], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', function (e) {
4774      e.stopPropagation();
4775    });
4776
4777  // SELECTPICKER DATA-API
4778  // =====================
4779  document.addEventListener('DOMContentLoaded', function () {
4780    $('.selectpicker').each(function () {
4781      var $selectpicker = $(this);
4782      Plugin.call($selectpicker, $selectpicker.data());
4783    });
4784  });
4785})(jQuery);
4786
4787
4788}));
4789
4790/******/ (function(modules) { // webpackBootstrap
4791/******/ 	// The module cache
4792/******/ 	var installedModules = {};
4793/******/
4794/******/ 	// The require function
4795/******/ 	function __webpack_require__(moduleId) {
4796/******/
4797/******/ 		// Check if module is in cache
4798/******/ 		if(installedModules[moduleId]) {
4799/******/ 			return installedModules[moduleId].exports;
4800/******/ 		}
4801/******/ 		// Create a new module (and put it into the cache)
4802/******/ 		var module = installedModules[moduleId] = {
4803/******/ 			i: moduleId,
4804/******/ 			l: false,
4805/******/ 			exports: {}
4806/******/ 		};
4807/******/
4808/******/ 		// Execute the module function
4809/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
4810/******/
4811/******/ 		// Flag the module as loaded
4812/******/ 		module.l = true;
4813/******/
4814/******/ 		// Return the exports of the module
4815/******/ 		return module.exports;
4816/******/ 	}
4817/******/
4818/******/
4819/******/ 	// expose the modules object (__webpack_modules__)
4820/******/ 	__webpack_require__.m = modules;
4821/******/
4822/******/ 	// expose the module cache
4823/******/ 	__webpack_require__.c = installedModules;
4824/******/
4825/******/ 	// define getter function for harmony exports
4826/******/ 	__webpack_require__.d = function(exports, name, getter) {
4827/******/ 		if(!__webpack_require__.o(exports, name)) {
4828/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
4829/******/ 		}
4830/******/ 	};
4831/******/
4832/******/ 	// define __esModule on exports
4833/******/ 	__webpack_require__.r = function(exports) {
4834/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
4835/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4836/******/ 		}
4837/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
4838/******/ 	};
4839/******/
4840/******/ 	// create a fake namespace object
4841/******/ 	// mode & 1: value is a module id, require it
4842/******/ 	// mode & 2: merge all properties of value into the ns
4843/******/ 	// mode & 4: return value when already ns object
4844/******/ 	// mode & 8|1: behave like require
4845/******/ 	__webpack_require__.t = function(value, mode) {
4846/******/ 		if(mode & 1) value = __webpack_require__(value);
4847/******/ 		if(mode & 8) return value;
4848/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
4849/******/ 		var ns = Object.create(null);
4850/******/ 		__webpack_require__.r(ns);
4851/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
4852/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
4853/******/ 		return ns;
4854/******/ 	};
4855/******/
4856/******/ 	// getDefaultExport function for compatibility with non-harmony modules
4857/******/ 	__webpack_require__.n = function(module) {
4858/******/ 		var getter = module && module.__esModule ?
4859/******/ 			function getDefault() { return module['default']; } :
4860/******/ 			function getModuleExports() { return module; };
4861/******/ 		__webpack_require__.d(getter, 'a', getter);
4862/******/ 		return getter;
4863/******/ 	};
4864/******/
4865/******/ 	// Object.prototype.hasOwnProperty.call
4866/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
4867/******/
4868/******/ 	// __webpack_public_path__
4869/******/ 	__webpack_require__.p = "/";
4870/******/
4871/******/
4872/******/ 	// Load entry module and return exports
4873/******/ 	return __webpack_require__(__webpack_require__.s = 10);
4874/******/ })
4875/************************************************************************/
4876/******/ ({
4877
4878/***/ "./src/components/heroes/heroes.js":
4879/*!*****************************************!*\
4880  !*** ./src/components/heroes/heroes.js ***!
4881  \*****************************************/
4882/*! no static exports found */
4883/***/ (function(module, exports, __webpack_require__) {
4884
4885"use strict";
4886 // import { tns } from "../../js/main.script";
4887
4888(function ($, Drupal) {
4889  $(document).ready(function () {
4890    var tnsCarouselPrimary = document.querySelectorAll(".heroes-primary");
4891    tnsCarouselPrimary.forEach(function (slider) {
4892      // if( $('.heroes-primary .heroes__item').length > 1) {
4893      var heroes_primary__slider = document.tnsAda.init({
4894        container: slider.querySelector(".heroes-primary .heroes__row"),
4895        controlsContainer: slider.querySelector(".tns__controls"),
4896        // navContainer: slider.querySelector(".tns__dots"),
4897        // prevButton: slider.querySelector(".tns__arrow.prev"),
4898        // nextButton: slider.querySelector(".tns__arrow.next"),
4899        navPosition: "top",
4900        gutter: 1,
4901        nav: true,
4902        controls: true,
4903        buttonPosition: 'after',
4904        navBetweenControls: true,
4905        controlWrap: "<div class='tns__controls'></div>",
4906        controlsText: ["<span class='sr-only'>previous slide</span>", "<span class='sr-only'>next slide</span>"],
4907        onInit: function onInit(info) {
4908          // debugger;
4909          // console.log(slider);
4910          $(slider).find(".heroes").css("display", "flex"); // setTimeout(() => {
4911          //    $(slider).find(".tns-inner").children().not(".heroes__row").wrap("<div class='tns__controls'></div>");
4912          // }, "1000");
4913          // if ($(info).find(".heroes__item").length > 1) {
4914          //   info.controlsContainer.setAttribute("tabindex", -1);
4915          //   info.nextButton.setAttribute("tabindex", 3);
4916          //   info.prevButton.setAttribute("tabindex", 3);
4917          //   document
4918          //     .querySelectorAll(".tns-slide-cloned a")
4919          //     .forEach(function (btn) {
4920          //       btn.setAttribute("tabindex", -1);
4921          //     });
4922          // }
4923        }
4924      }); // }
4925    }); // if( $('.heroes-secondary .heroes__item').length > 1) {
4926
4927    var tnsCarouselSecondary = document.querySelectorAll(".heroes-secondary");
4928    tnsCarouselSecondary.forEach(function (slider) {
4929      var heroes_secondary__slider = document.tnsAda.init({
4930        container: slider.querySelector(".heroes-secondary .heroes__row"),
4931        controlsContainer: slider.querySelector(".tns__controls"),
4932        // navContainer: slider.querySelector(".tns__dots"),
4933        // prevButton: slider.querySelector(".tns__arrow.prev"),
4934        // nextButton: slider.querySelector(".tns__arrow.next"),
4935        navPosition: "top",
4936        nav: true,
4937        controls: true,
4938        buttonPosition: 'after',
4939        navBetweenControls: true,
4940        controlWrap: "<div class='tns__controls'></div>",
4941        controlsText: ["<span class='sr-only'>previous slide</span>", "<span class='sr-only'>next slide</span>"],
4942        onInit: function onInit(info) {// $(slider).find(".tns-inner").children().not(".heroes__row").wrap("<div class='tns__controls'></div>");
4943          //   info.controlsContainer.setAttribute("tabindex", -1);
4944          //   info.nextButton.setAttribute("tabindex", 3);
4945          //   info.prevButton.setAttribute("tabindex", 3);
4946          //   document
4947          //     .querySelectorAll(".tns-slide-cloned a")
4948          //     .forEach(function (btn) {
4949          //       btn.setAttribute("tabindex", -1);
4950          //     });
4951        }
4952      }); // }
4953    });
4954  });
4955})(jQuery, Drupal);
4956
4957/***/ }),
4958
4959/***/ 10:
4960/*!***********************************************!*\
4961  !*** multi ./src/components/heroes/heroes.js ***!
4962  \***********************************************/
4963/*! no static exports found */
4964/***/ (function(module, exports, __webpack_require__) {
4965
4966module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/heroes/heroes.js */"./src/components/heroes/heroes.js");
4967
4968
4969/***/ })
4970
4971/******/ });;
4972/******/ (function(modules) { // webpackBootstrap
4973/******/ 	// The module cache
4974/******/ 	var installedModules = {};
4975/******/
4976/******/ 	// The require function
4977/******/ 	function __webpack_require__(moduleId) {
4978/******/
4979/******/ 		// Check if module is in cache
4980/******/ 		if(installedModules[moduleId]) {
4981/******/ 			return installedModules[moduleId].exports;
4982/******/ 		}
4983/******/ 		// Create a new module (and put it into the cache)
4984/******/ 		var module = installedModules[moduleId] = {
4985/******/ 			i: moduleId,
4986/******/ 			l: false,
4987/******/ 			exports: {}
4988/******/ 		};
4989/******/
4990/******/ 		// Execute the module function
4991/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
4992/******/
4993/******/ 		// Flag the module as loaded
vendor: 2,823 bytes, lines 4994-5059
4994/******/ 		module.l = true;
4995/******/
4996/******/ 		// Return the exports of the module
4997/******/ 		return module.exports;
4998/******/ 	}
4999/******/
5000/******/
5001/******/ 	// expose the modules object (__webpack_modules__)
5002/******/ 	__webpack_require__.m = modules;
5003/******/
5004/******/ 	// expose the module cache
5005/******/ 	__webpack_require__.c = installedModules;
5006/******/
5007/******/ 	// define getter function for harmony exports
5008/******/ 	__webpack_require__.d = function(exports, name, getter) {
5009/******/ 		if(!__webpack_require__.o(exports, name)) {
5010/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
5011/******/ 		}
5012/******/ 	};
5013/******/
5014/******/ 	// define __esModule on exports
5015/******/ 	__webpack_require__.r = function(exports) {
5016/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
5017/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5018/******/ 		}
5019/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
5020/******/ 	};
5021/******/
5022/******/ 	// create a fake namespace object
5023/******/ 	// mode & 1: value is a module id, require it
5024/******/ 	// mode & 2: merge all properties of value into the ns
5025/******/ 	// mode & 4: return value when already ns object
5026/******/ 	// mode & 8|1: behave like require
5027/******/ 	__webpack_require__.t = function(value, mode) {
5028/******/ 		if(mode & 1) value = __webpack_require__(value);
5029/******/ 		if(mode & 8) return value;
5030/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
5031/******/ 		var ns = Object.create(null);
5032/******/ 		__webpack_require__.r(ns);
5033/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
5034/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
5035/******/ 		return ns;
5036/******/ 	};
5037/******/
5038/******/ 	// getDefaultExport function for compatibility with non-harmony modules
5039/******/ 	__webpack_require__.n = function(module) {
5040/******/ 		var getter = module && module.__esModule ?
5041/******/ 			function getDefault() { return module['default']; } :
5042/******/ 			function getModuleExports() { return module; };
5043/******/ 		__webpack_require__.d(getter, 'a', getter);
5044/******/ 		return getter;
5045/******/ 	};
5046/******/
5047/******/ 	// Object.prototype.hasOwnProperty.call
5048/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
5049/******/
5050/******/ 	// __webpack_public_path__
5051/******/ 	__webpack_require__.p = "/";
5052/******/
5053/******/
5054/******/ 	// Load entry module and return exports
5055/******/ 	return __webpack_require__(__webpack_require__.s = 9);
5056/******/ })
5057/************************************************************************/
5058/******/ ({
5059
5060/***/ "./src/components/header/header.js":
5061/*!*****************************************!*\
5062  !*** ./src/components/header/header.js ***!
5063  \*****************************************/
5064/*! no static exports found */
5065/***/ (function(module, exports, __webpack_require__) {
5066
5067"use strict";
5068
5069
5070(function ($, Drupal) {
5071  var valueTerm = $("#term");
5072  var searchToggle = false;
5073  var w = window.innerWidth;
5074  Drupal.behaviors.header = {
5075    attach: function attach(context) {
5076      $(".navbar-actions .icon", context).on("click", function (e) {
5077        Drupal.behaviors.header.toggleSearch(context);
5078
5079        if ($("body").hasClass("page__header--active")) {
5080          $(".navbar-actions .icon").attr({
5081            "aria-expanded": "true",
5082            "aria-label": "Close search",
5083            title: "Close search"
5084          });
5085        } else {
5086          $(".navbar-actions .icon").attr({
5087            "aria-expanded": "false",
5088            "aria-label": "Open search",
5089            title: "Open search"
5090          });
5091        }
5092      });
5093      $(".we-mega-menu-li", context).on("mousedown", function (e) {
5094        if (searchToggle) Drupal.behaviors.header.toggleSearch(context);
5095      });
5096      $(window).resize(function () {
5097        var btnCloseMenu = $(".btn-close");
5098
5099        if (w != window.innerWidth && window.innerWidth <= 768) {
5100          $("body").removeClass("page__header--active");
5101          $("body").removeClass("toggled");
5102          $(".navbar-we-mega-menu").removeClass("we-mobile-megamenu-active has-clicked");
5103          $(".we-mega-menu-submenu").removeAttr("style");
5104          btnCloseMenu.removeClass("d-none");
5105          searchToggle = false;
5106        }
5107      });
5108    },
5109    toggleSearch: function toggleSearch(context) {
5110      $("body").toggleClass("page__header--active");
5111      searchToggle = !searchToggle;
5112      var btnCloseMenu = $(".btn-close");
5113
5114      if (searchToggle) {
5115        if (window.innerWidth >= 768) {
5116          $(".we-mega-menu-li.dropdown-menu").removeClass("clicked");
5117        }
5118
5119        Drupal.behaviors.header.setFocusSearch(context);
5120        btnCloseMenu.addClass("d-none");
5121      } else {
5122        btnCloseMenu.removeClass("d-none");
5123      }
5124    },
5125    clearSearchTerm: function clearSearchTerm(context) {
5126      valueTerm.val("");
5127    },
5128    setFocusSearch: function setFocusSearch(context) {
5129      valueTerm.focus();
5130    }
5131  };
5132})(jQuery, Drupal);
5133
5134/***/ }),
5135
5136/***/ 9:
5137/*!***********************************************!*\
5138  !*** multi ./src/components/header/header.js ***!
5139  \***********************************************/
5140/*! no static exports found */
5141/***/ (function(module, exports, __webpack_require__) {
5142
5143module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/header/header.js */"./src/components/header/header.js");
5144
5145
5146/***/ })
5147
5148/******/ });;
5149/******/ (function(modules) { // webpackBootstrap
5150/******/ 	// The module cache
5151/******/ 	var installedModules = {};
5152/******/
5153/******/ 	// The require function
5154/******/ 	function __webpack_require__(moduleId) {
5155/******/
5156/******/ 		// Check if module is in cache
5157/******/ 		if(installedModules[moduleId]) {
5158/******/ 			return installedModules[moduleId].exports;
5159/******/ 		}
5160/******/ 		// Create a new module (and put it into the cache)
5161/******/ 		var module = installedModules[moduleId] = {
5162/******/ 			i: moduleId,
5163/******/ 			l: false,
5164/******/ 			exports: {}
5165/******/ 		};
5166/******/
5167/******/ 		// Execute the module function
5168/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
5169/******/
5170/******/ 		// Flag the module as loaded
5171/******/ 		module.l = true;
5172/******/
5173/******/ 		// Return the exports of the module
5174/******/ 		return module.exports;
5175/******/ 	}
5176/******/
5177/******/
5178/******/ 	// expose the modules object (__webpack_modules__)
5179/******/ 	__webpack_require__.m = modules;
5180/******/
5181/******/ 	// expose the module cache
5182/******/ 	__webpack_require__.c = installedModules;
5183/******/
5184/******/ 	// define getter function for harmony exports
5185/******/ 	__webpack_require__.d = function(exports, name, getter) {
5186/******/ 		if(!__webpack_require__.o(exports, name)) {
5187/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
5188/******/ 		}
5189/******/ 	};
5190/******/
5191/******/ 	// define __esModule on exports
5192/******/ 	__webpack_require__.r = function(exports) {
5193/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
5194/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5195/******/ 		}
5196/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
5197/******/ 	};
5198/******/
5199/******/ 	// create a fake namespace object
5200/******/ 	// mode & 1: value is a module id, require it
5201/******/ 	// mode & 2: merge all properties of value into the ns
5202/******/ 	// mode & 4: return value when already ns object
5203/******/ 	// mode & 8|1: behave like require
5204/******/ 	__webpack_require__.t = function(value, mode) {
5205/******/ 		if(mode & 1) value = __webpack_require__(value);
5206/******/ 		if(mode & 8) return value;
5207/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esMo
vendor: 1,304 bytes, lines 5207-5236
5207dule) return value;
5208/******/ 		var ns = Object.create(null);
5209/******/ 		__webpack_require__.r(ns);
5210/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
5211/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
5212/******/ 		return ns;
5213/******/ 	};
5214/******/
5215/******/ 	// getDefaultExport function for compatibility with non-harmony modules
5216/******/ 	__webpack_require__.n = function(module) {
5217/******/ 		var getter = module && module.__esModule ?
5218/******/ 			function getDefault() { return module['default']; } :
5219/******/ 			function getModuleExports() { return module; };
5220/******/ 		__webpack_require__.d(getter, 'a', getter);
5221/******/ 		return getter;
5222/******/ 	};
5223/******/
5224/******/ 	// Object.prototype.hasOwnProperty.call
5225/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
5226/******/
5227/******/ 	// __webpack_public_path__
5228/******/ 	__webpack_require__.p = "/";
5229/******/
5230/******/
5231/******/ 	// Load entry module and return exports
5232/******/ 	return __webpack_require__(__webpack_require__.s = 13);
5233/******/ })
5234/************************************************************************/
5235/******/ ({
5236
5237/***/ "./src/components/navbar/navbar.js":
5238/*!*****************************************!*\
5239  !*** ./src/components/navbar/navbar.js ***!
5240  \*****************************************/
5241/*! no static exports found */
5242/***/ (function(module, exports) {
5243
5244(function ($, Drupal) {
5245  Drupal.behaviors.navbar = {
5246    attach: function attach(context) {
5247      var $navbar = $('#navbar'),
5248          prevScroll = 0,
5249          scrollDir = 'up';
5250      $(document).off('scroll.navdir').on('scroll.navdir', function () {
5251        var st = $(window).scrollTop();
5252
5253        if (st < prevScroll && scrollDir === 'down') {
5254          //console.log('up',st);
5255          scrollDir = 'up';
5256          $navbar.addClass('scroll-dir-up');
5257          prevScroll = st;
5258          return;
5259        }
5260
5261        if (st > prevScroll && scrollDir === 'up' && st > 100) {
5262          //console.log('down',st);
5263          $navbar.removeClass('scroll-dir-up');
5264          scrollDir = 'down';
5265        }
5266
5267        prevScroll = st;
5268        return;
5269      });
5270    }
5271  };
5272})(jQuery, Drupal);
5273
5274/***/ }),
5275
5276/***/ 13:
5277/*!***********************************************!*\
5278  !*** multi ./src/components/navbar/navbar.js ***!
5279  \***********************************************/
5280/*! no static exports found */
5281/***/ (function(module, exports, __webpack_require__) {
5282
5283module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/navbar/navbar.js */"./src/components/navbar/navbar.js");
5284
5285
5286/***/ })
5287
5288/******/ });;
5289/**
5290* DO NOT EDIT THIS FILE.
5291* See the following change record for more information,
5292* https://www.drupal.org/node/2815083
5293* @preserve
5294**/
5295function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
5296function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
5297function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
5298function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5299function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
5300function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
5301(function ($, Drupal, cookies) {
5302  var deprecatedMessageSuffix = "is deprecated in Drupal 9.0.0 and will be removed in Drupal 10.0.0. Use the core/js-cookie library instead. See https://www.drupal.org/node/3104677";
5303  var isFunction = function isFunction(obj) {
5304    return Object.prototype.toString.call(obj) === '[object Function]';
5305  };
5306  var parseCookieValue = function parseCookieValue(value, parseJson) {
5307    if (value.indexOf('"') === 0) {
5308      value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
5309    }
5310    try {
5311      value = decodeURIComponent(value.replace(/\+/g, ' '));
5312      return parseJson ? JSON.parse(value) : value;
5313    } catch (e) {}
5314  };
5315  var reader = function reader(cookieValue, cookieName, converter, readUnsanitized, parseJson) {
5316    var value = readUnsanitized ? cookieValue : parseCookieValue(cookieValue, parseJson);
5317    if (converter !== undefined && isFunction(converter)) {
5318      return converter(value, cookieName);
5319    }
5320    return value;
5321  };
5322  $.cookie = function (key) {
5323    var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
5324    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
5325    Drupal.deprecationError({
5326      message: "jQuery.cookie() ".concat(deprecatedMessageSuffix)
5327    });
5328    if (value !== undefined && !isFunction(value)) {
5329      var attributes = _objectSpread(_objectSpread({}, $.cookie.defaults), options);
5330      if (typeof attributes.expires === 'string' && attributes.expires !== '') {
5331        attributes.expires = new Date(attributes.expires);
5332      }
5333      var cookieSetter = cookies.withConverter({
5334        write: function write(cookieValue) {
5335          return encodeURIComponent(cookieValue);
5336        }
5337      });
5338      value = $.cookie.json && !$.cookie.raw ? JSON.stringify(value) : String(value);
5339      return cookieSetter.set(key, value, attributes);
5340    }
5341    var userProvidedConverter = value;
5342    var cookiesShim = cookies.withConverter({
5343      read: function read(cookieValue, cookieName) {
5344        return reader(cookieValue, cookieName, userProvidedConverter, $.cookie.raw, $.cookie.json);
5345      }
5346    });
5347    if (key !== undefined) {
5348      return cookiesShim.get(key);
5349    }
5350    var results = cookiesShim.get();
5351    Object.keys(results).forEach(function (resultKey) {
5352      if (results[resultKey] === undefined) {
5353        delete results[resultKey];
5354      }
5355    });
5356    return results;
5357  };
5358  $.cookie.defaults = _objectSpread({
5359    path: ''
5360  }, cookies.defaults);
5361  $.cookie.json = false;
5362  $.cookie.raw = false;
5363  $.removeCookie = function (key, options) {
5364    Drupal.deprecationError({
5365      message: "jQuery.removeCookie() ".concat(deprecatedMessageSuffix)
5366    });
5367    cookies.remove(key, _objectSpread(_objectSpread({}, $.cookie.defaults), options));
5368    return !cookies.get(key);
5369  };
5370})(jQuery, Drupal, window.Cookies);;
5371(function ($, Drupal) {
5372  Drupal.behaviors.provinceSelector = {
5373    attach: function (context, settings) {
5374      // When juicer.io block is enabled it breaks jQuery.once, The following
5375      // is a fix for this behavior.
5376      let queryString = window.location.search;
5377      let urlParams = new URLSearchParams(queryString);
5378      let regionFocus = urlParams.get('regionFocus');
5379      if (regionFocus != null) {
5380        $("#region-select").focus();
5381        var simpleLiveCurl=location.protocol + '//' + location.host + location.pathname;
5382        window.history.replaceState( {} , 'regionFocus', simpleLiveCurl);
5383      }
5384      let $selector = null;
5385      let $selector_mobile = null;
5386      if (typeof jQuery.fn.once !== "undefined") {
5387        $selector = $("#province-selector select").once("provinceSelector");
5388        $selector_mobile = $("#province-selector-mobile select").once(
5389          "provinceSelector"
5390        );
5391      } else {
5392        $selector = $("#province-selector select");
5393        $selector_mobile = $("#province-selector-mobile select");
5394      }
5395      provinceSelector.setDefault();
5396      // Bypass megamenu caching issue
5397      const activeProvince = provinceSelector.getProvince();
5398
5399      $('option', $selector_mobile).removeAttr('selected')
5400      $selector_mobile.val(activeProvince);
5401
5402      $selector.on("change", () => {
5403        const region = $("option:selected", $selector).data("region");
5404        provinceSelector.setCookie($selector.val(), region);
5405      });
5406
5407      $selector_mobile.on("change", () => {
5408        // Fix issue with variable undefined
5409        let $sMobile =  $("#province-selector-mobile select");
5410        const region = $("option:selected", $sMobile).data("region");
5411        provinceSelector.setCookie($sMobile.val(), region);
5412      });
5413    },
5414  };
5415
5416  // Helper object.
5417  const provinceSelector = {
5418    provinceCookie: "currentProvince",
5419    regionCookie: "currentRegion",
5420    setDefault: () => {
5421      // Get default province from backend integration.
5422      $.cookie(
5423        provinceSelector.provinceCookie, drupalSettings.defaultProvince,
5424        { path: "/" }
5425      );
5426      $.cookie(
5427        provinceSelector.regionCookie, drupalSettings.defaultRegion,
5428        { path: "/" }
5429      );
5430    },
5431    setCookie: (province, region) => {
5432      $.cookie(provinceSelector.provinceCookie, province, { path: "/" });
5433      $.cookie(provinceSelector.regionCookie, region, { path: "/" });
5434      // document.location.reload(true);
5435      let queryString = window.location.search;
5436      let urlParams = new URLSearchParams(queryString);
5437      urlParams.delete('regionFocus');
5438      urlParams.set('regionFocus', '');
5439      document.location.href += '?' + urlParams;
5440    },
5441    getProvince: () => {
5442      return $.cookie(provinceSelector.provinceCookie)
5443    }
5444  };
5445})(jQuery, Drupal);
5446;
5447/******/ (function(modules) { // webpackBootstrap
5448/******/ 	// The module cache
5449/******/ 	var installedModules = {};
5450/******/
5451/******/ 	// The require function
5452/******/ 	function __webpack_require__(moduleId) {
5453/******/
5454/******/ 		// Check if module is in cache
5455/******/ 		if(installedModules[moduleId]) {
5456/******/ 			return installedModules[moduleId].exports;
5457/******/ 		}
5458/******/ 		// Create a new module (and put it into the cache)
5459/******/ 		var module = installedModules[moduleId] = {
5460/******/ 			i: moduleId,
5461/******/ 			l: false,
5462/******/ 			exports: {}
5463/******/ 		};
5464/******/
5465/******/ 		// Execute the module function
5466/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
5467/******/
5468/******/ 		// Flag the module as loaded
vendor: 2,824 bytes, lines 5469-5534
5469/******/ 		module.l = true;
5470/******/
5471/******/ 		// Return the exports of the module
5472/******/ 		return module.exports;
5473/******/ 	}
5474/******/
5475/******/
5476/******/ 	// expose the modules object (__webpack_modules__)
5477/******/ 	__webpack_require__.m = modules;
5478/******/
5479/******/ 	// expose the module cache
5480/******/ 	__webpack_require__.c = installedModules;
5481/******/
5482/******/ 	// define getter function for harmony exports
5483/******/ 	__webpack_require__.d = function(exports, name, getter) {
5484/******/ 		if(!__webpack_require__.o(exports, name)) {
5485/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
5486/******/ 		}
5487/******/ 	};
5488/******/
5489/******/ 	// define __esModule on exports
5490/******/ 	__webpack_require__.r = function(exports) {
5491/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
5492/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5493/******/ 		}
5494/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
5495/******/ 	};
5496/******/
5497/******/ 	// create a fake namespace object
5498/******/ 	// mode & 1: value is a module id, require it
5499/******/ 	// mode & 2: merge all properties of value into the ns
5500/******/ 	// mode & 4: return value when already ns object
5501/******/ 	// mode & 8|1: behave like require
5502/******/ 	__webpack_require__.t = function(value, mode) {
5503/******/ 		if(mode & 1) value = __webpack_require__(value);
5504/******/ 		if(mode & 8) return value;
5505/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
5506/******/ 		var ns = Object.create(null);
5507/******/ 		__webpack_require__.r(ns);
5508/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
5509/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
5510/******/ 		return ns;
5511/******/ 	};
5512/******/
5513/******/ 	// getDefaultExport function for compatibility with non-harmony modules
5514/******/ 	__webpack_require__.n = function(module) {
5515/******/ 		var getter = module && module.__esModule ?
5516/******/ 			function getDefault() { return module['default']; } :
5517/******/ 			function getModuleExports() { return module; };
5518/******/ 		__webpack_require__.d(getter, 'a', getter);
5519/******/ 		return getter;
5520/******/ 	};
5521/******/
5522/******/ 	// Object.prototype.hasOwnProperty.call
5523/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
5524/******/
5525/******/ 	// __webpack_public_path__
5526/******/ 	__webpack_require__.p = "/";
5527/******/
5528/******/
5529/******/ 	// Load entry module and return exports
5530/******/ 	return __webpack_require__(__webpack_require__.s = 11);
5531/******/ })
5532/************************************************************************/
5533/******/ ({
5534
5535/***/ "./src/components/mega-nav/mega-nav.js":
5536/*!*********************************************!*\
5537  !*** ./src/components/mega-nav/mega-nav.js ***!
5538  \*********************************************/
5539/*! no static exports found */
5540/***/ (function(module, exports, __webpack_require__) {
5541
5542"use strict";
5543 // import {MmenuLight} from './mmenu-light.js'
5544
5545(function ($, Drupal) {
5546  $(document).ready(function () {
5547    //focus trap
5548    function focusTrap(trapSelector) {
5549      // Focus Trap: Causes the tab key to loop focus within the given selector.
5550      var focusableElements = 'button:not(.hidden), [href]:not(.hidden), input:not(.hidden), select:not(.hidden), textarea:not(.hidden), [tabindex]:not([tabindex="-1"])'; // All focusable elements
5551
5552      document.addEventListener("keydown", function (e) {
5553        console.log("KEYDOWN");
5554        var trap = document.querySelector(trapSelector); // If the key pressed is not 'Tab' or the trap element is not present: do nothing
5555
5556        console.log("TRAP:", trap);
5557        var isTabPressed = e.key === "Tab" || e.keyCode === 9;
5558
5559        if (!isTabPressed || !trap) {
5560          return;
5561        }
5562
5563        var focusableContent = trap.querySelectorAll(focusableElements),
5564            firstFocusableElement = focusableContent[0],
5565            // first focusable element
5566        lastFocusableElement = focusableContent[focusableContent.length - 1]; // last focusable element
5567
5568        if (e.shiftKey) {
5569          // if shift + tab on first element, focus the last focusable element
5570          if (document.activeElement === firstFocusableElement) {
5571            lastFocusableElement.focus(); //
5572
5573            e.preventDefault();
5574          }
5575        } else {
5576          // if tab on last element, focus the first focusable element
5577          if (document.activeElement === lastFocusableElement) {
5578            firstFocusableElement.focus();
5579            e.preventDefault();
5580          }
5581        }
5582      });
5583    }
5584
5585    focusTrap("#main-menu-mobile");
5586    setTimeout(function () {
5587      $(".mm-ocd").attr("role", "dialog").attr("aria-hidden", "true");
5588    }, "1000"); // Clone Main Menu.
5589
5590    var mainMenu = $("#main-menu").html();
5591    var providenceSelector = $("#province-selector").html();
5592    var socialLinks = $("#block-dempsters-block-social-links > ul.nav").html();
5593    var socialLinks2 = $(".block-language ul.links.nav").html();
5594    $("#main-menu").after('<div id="main-menu-mobile" class="main-nav main-menu-wrapper d-block d-lg-none">' + '<div id="mobileNav" class="container"><a href="/" class="navbar-brand d-flex align-items-center " tabindex="0"><h1 class="sr-only">Dempster\'s</h1><img width="130px" height="86px" alt="Dempster\'s" src="/themes/custom/dempsters/logo.svg"><div class="d-flex flex-column logo-text"></div></a><div class="navbar-actions mobile"><button aria-label="Open search" aria-controls="search-container" id="menu-search" aria-expanded="false" class="btn icon icon-search icon-fill-tertiary hidden" title="Open search"></button></div> <button id="main-menu-button-close" class="menu-button d-block hidden" aria-label="Close" href="#main-menu-mobile-close"><i class="icon icon-close-bold icon-fill-tertiary"></i></button></div>' + mainMenu + "</div>");
5595    $("#main-menu-mobile .main-menu").append("<li class='nav-item providence-item'><div id='province-selector-mobile'>" + providenceSelector + "</div></li>");
5596    $("#main-menu-mobile .main-menu").append("<li class='nav-item language-item'><div id='language-selector'></div></li>");
5597    $("#main-menu-mobile .main-menu").append("<li class='nav-item social-item'><ul id='social-menu'>" + socialLinks + "</ul></li>");
5598    $("#province-selector-mobile label").attr("for", "region-selector-mobile");
5599    $("#province-selector-mobile #region-select").attr("id", "region-selector-mobile");
5600    setTimeout(function () {
5601      var languageSelector = $(".block-language ul.links.nav li").not(".is-active").html();
5602      $(".language-item #language-selector").append(languageSelector);
5603      $('#main-menu-mobile #region-select-warning').removeAttr('id').attr('id', 'region-select-warning-mobile');
5604    }, 1000);
5605    setTimeout(function () {
5606      $("#mobileNav #province-selector-mobile option").attr("id", "width_tmp_option_mb"); //UPDATES NAV HEIGHT VARIABLE FOR SEARCH MODAL
5607
5608      var root = document.documentElement;
5609      var navHeight = $('#navbar').height();
5610      console.log('NAV HEIGHT', navHeight);
5611      root.style.setProperty('--navbar-height', navHeight + "px");
5612    }, 2000); //INSIDE MENU SEARCH BUTTON
5613
5614    $('#menu-search').on('click', function () {
5615      $('#main-menu-button-close').trigger('click');
5616      setTimeout(function () {
5617        $('#navbar .mobile .icon-search').trigger('click');
5618      }, 100);
5619    }); //add custom menback button
5620
5621    var backText = Drupal.t("Back");
5622    $("#main-menu-mobile .main-menu").find(".dropdown-menu").prepend("<li class='nav-item'><button class='mm-back-button'>" + backText + "</button></li>");
5623    var $backbutton = $("#main-menu-mobile .main-menu .dropdown-menu .mm-back-button");
5624    $("#main-menu-mobile #products-submenu").removeAttr("id").attr("id", "products-submenu-mobile");
5625    $("#main-menu-button-close").on("click", function () {
5626      $(".mm-ocd").attr("aria-hidden", "true");
5627    }); //submenu open on click or keypress
5628
5629    $("#main-menu-mobile .main-menu>li:first-of-type").on("click", function () {
5630      $("#main-menu-mobile .main-menu > li:not(:first-of-type)").addClass("d-none hidden");
5631      $("#main-menu-mobile .main-menu > li:not(:first-of-type) a, #main-menu-mobile .main-menu > li:not(:first-of-type) label, #main-menu-mobile .main-menu > li:not(:first-of-type) select").addClass("d-none hidden").attr("tabindex", "-1");
5632      $("#products-submenu").focus();
5633    });
5634    $("#main-menu-mobile .main-menu>li:first-of-type").on("keypress", function (event) {
5635      console.log("KEYPRESS");
5636
5637      if (event.which == 13 || event.which == 32) {
5638        $("#main-menu-mobile .main-menu > li:not(:first-of-type)").addClass("d-none hidden");
5639        $("#main-menu-mobile .main-menu > li:not(:first-of-type) a, #main-menu-mobile .main-menu > li:not(:first-of-type) label, #main-menu-mobile .main-menu > li:not(:first-of-type) select").addClass("d-none hidden").attr("tabindex", "-1");
5640        $("#products-submenu").focus();
5641      }
5642    }); //submenu close on click or keypress
5643
5644    $(".mm-back-button").on("click", function () {
5645      console.log("back button pressed");
5646      setTimeout(function () {
5647        $("#main-menu-mobile .main-menu > li:not(:first-of-type)").removeClass("d-none hidden");
5648        $("#main-menu-mobile .main-menu").removeClass("mm-spn--open mm-spn--parent");
5649        $(".main-menu .active .dropdown-menu").removeClass("mm-spn--open");
5650        $("#main-menu-mobile .main-menu > li:not(:first-of-type) a, #main-menu-mobile .main-menu > li:not(:first-of-type) label, #main-menu-mobile .main-menu > li:not(:first-of-type) select").removeClass("d-none hidden").attr("tabindex", "0");
5651        $("#main-menu-button-close").focus();
5652      }, 100);
5653    });
5654    $(".mm-back-button").on("keypress", function (event) {
5655      console.log("KEYPRESS");
5656
5657      if (event.which == 13 || event.which == 32) {
5658        setTimeout(function () {
5659          $("#main-menu-mobile .main-menu > li:not(:first-of-type)").removeClass("d-none hidden");
5660          $("#main-menu-mobile .main-menu").removeClass("mm-spn--open mm-spn--parent");
5661          $(".main-menu .active .dropdown-menu").removeClass("mm-spn--open");
5662          $("#main-menu-mobile .main-menu > li:not(:first-of-type) a, #main-menu-mobile .main-menu > li:not(:first-of-type) label, #main-menu-mobile .main-menu > li:not(:first-of-type) select").removeClass("d-none hidden").attr("tabindex", "0");
5663          $("#main-menu-button-close").focus();
5664        }, 100);
5665      }
5666    });
5667    Drupal.attachBehaviors(document.getElementById("province-selector-mobile")); // Add MmenuLight.
5668
5669    var menu = new MmenuLight(document.querySelector("#main-menu-mobile"), "(max-width: 992px)");
5670    var navigator = menu.navigation({
5671      selectedClass: "dropdown",
5672      slidingSubmenus: true,
5673      title: "Main Screen"
5674    }); // const navigator = menu.navigation();
5675
5676    var drawer = menu.offcanvas({
5677      position: "right",
5678      title: "Main Screen"
5679    });
5680    navigator.openPanel(document.querySelector("ul")); //  Open the menu.
5681
5682    document.querySelector('button[href="#main-menu-mobile"]').addEventListener("click", function (evnt) {
5683      evnt.preventDefault();
5684      var openButton = document.getElementById("main-menu-button");
5685      openButton.classList.add("hidden");
5686      var closeButton = document.getElementById("main-menu-button-close");
5687      closeButton.classList.remove("hidden");
5688      drawer.open();
5689      $(closeButton).focus();
5690      $(".mm-ocd").removeAttr("aria-hidden", "false");
5691    });
5692    document.querySelector('button[href="#main-menu-mobile-close"]').addEventListener("click", function (evnt) {
5693      evnt.preventDefault();
5694      var openButton = document.getElementById("main-menu-button");
5695      openButton.classList.remove("hidden");
5696      var closeButton = document.getElementById("main-menu-button-close");
5697      closeButton.classList.add("hidden");
5698      drawer.close();
5699      $(".mm-ocd").attr("aria-hidden", "true");
5700      $(openButton).focus();
5701    });
5702    $("#main-menu-mobile li.dropdown").on("click", function () {
5703      //$(this).addClass('active').removeClass('off').siblings().addClass('off').removeClass('active'); // no need to add .off
5704      $(this).addClass("active").siblings().removeClass("active");
5705    }); // Main menu active class.
5706    // Nos produits
5707
5708    if ($("body").hasClass("node-921896") || $("body").hasClass("path-products") || $("body").hasClass("path-produits") || $("body").hasClass("page-node-type-products") || $("body").hasClass("page-term-bread-type")) {
5709      $(".main-nav .nav-link.dropdown-toggle").each(function () {
5710        if ($(this).text() == "Our products" || $(this).text() == "Nos produits") {
5711          $(this).closest(".nav-item").addClass("active");
5712        }
5713      });
5714    } // Nos recettes
5715
5716
5717    if ($("body").hasClass("page-node-type-recipes")) {
5718      $(".main-nav .nav-link").each(function () {
5719        if ($(this).attr("data-drupal-link-system-path") == "node/921901") {
5720          $(this).closest(".nav-item").addClass("active");
5721        }
5722      });
5723    } // Nutrition & Bien-Être
5724
5725
5726    if ($("body").hasClass("page-node-type-blog")) {
5727      $(".main-nav .nav-link").each(function () {
5728        if ($(this).attr("data-drupal-link-system-path") == "node/922741") {
5729          $(this).closest(".nav-item").addClass("active");
5730        }
5731      });
5732    } // Detect Valid Keyboard Clicks
5733    // https://karlgroves.com/2014/11/24/ridiculously-easy-trick-for-keyboard-accessibility
5734
5735
5736    function a11yClick(event) {
5737      if (event.type === "click") {
5738        return true;
5739      } else if (event.type === "keypress") {
5740        var code = event.charCode || event.keyCode;
5741
5742        if (code === 32 || code === 13) {
5743          return true;
5744        }
5745      } else {
5746        return false;
5747      }
5748    }
5749
5750    $(".main-nav .nav-link.dropdown-toggle").on("keypress", function (event) {
5751      event.preventDefault();
5752
5753      if (a11yClick(event) === true) {
5754        if ($(window).innerWidth() >= 992) {
5755          $(this).trigger("click");
5756        } else {
5757          navigator.openPanel(document.querySelector("#main-menu-mobile .dropdown-menu"));
5758          $("#main-menu-mobile .menu-item__item").first().find("a").focus();
5759        }
5760      }
5761    }); // Resizes the width of #region-select dynamically according to the width of the selected option
5762
5763    $("#width_tmp_option").html($("#province-selector #region-select option:selected").text());
5764    $("#province-selector #region-select").width($("#width_tmp_select").width());
5765    $("#province-selector #region-select").change(function () {
5766      $("#width_tmp_option").html($("#province-selector #region-select option:selected").text());
5767      $(this).width($("#width_tmp_select").width());
5768    });
5769  });
5770})(jQuery, Drupal);
5771
5772/***/ })
5772,
5773
5774/***/ 11:
5775/*!***************************************************!*\
5776  !*** multi ./src/components/mega-nav/mega-nav.js ***!
5777  \***************************************************/
5778/*! no static exports found */
5779/***/ (function(module, exports, __webpack_require__) {
5780
5781module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/mega-nav/mega-nav.js */"./src/components/mega-nav/mega-nav.js");
5782
5783
5784/***/ })
5785
5786/******/ });;

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.