PageSourceSearch

https://fec-co.com/sites/default/files/js/js_OeAr4xa8uAxhuUiXiIKUY31ry3zH8eHM_g1y4-Z5MkA.js

js fec-co.com collected 2026-09-30 04:58:37 UTC 132,261 bytes, 3,817 lines download raw bytes

1/**
2 * @file
3 * Drupal Bootstrap object.
4 */
5
6/**
7 * All Drupal Bootstrap JavaScript APIs are contained in this namespace.
8 *
9 * @param {underscore} _
10 * @param {jQuery} $
11 * @param {Drupal} Drupal
12 * @param {drupalSettings} drupalSettings
13 */
14(function (_, $, Drupal, drupalSettings) {
15  'use strict';
16
17  /**
18   * @typedef Drupal.bootstrap
19   */
20  var Bootstrap = {
21    processedOnce: {},
22    settings: drupalSettings.bootstrap || {}
23  };
24
25  /**
26   * Wraps Drupal.checkPlain() to ensure value passed isn't empty.
27   *
28   * Encodes special characters in a plain-text string for display as HTML.
29   *
30   * @param {string} str
31   *   The string to be encoded.
32   *
33   * @return {string}
34   *   The encoded string.
35   *
36   * @ingroup sanitization
37   */
38  Bootstrap.checkPlain = function (str) {
39    return str && Drupal.checkPlain(str) || '';
40  };
41
42  /**
43   * Creates a jQuery plugin.
44   *
45   * @param {String} id
46   *   A jQuery plugin identifier located in $.fn.
47   * @param {Function} plugin
48   *   A constructor function used to initialize the for the jQuery plugin.
49   * @param {Boolean} [noConflict]
50   *   Flag indicating whether or not to create a ".noConflict()" helper method
51   *   for the plugin.
52   */
53  Bootstrap.createPlugin = function (id, plugin, noConflict) {
54    // Immediately return if plugin doesn't exist.
55    if ($.fn[id] !== void 0) {
56      return this.fatal('Specified jQuery plugin identifier already exists: @id. Use Drupal.bootstrap.replacePlugin() instead.', {'@id': id});
57    }
58
59    // Immediately return if plugin isn't a function.
60    if (typeof plugin !== 'function') {
61      return this.fatal('You must provide a constructor function to create a jQuery plugin "@id": @plugin', {'@id': id, '@plugin':  plugin});
62    }
63
64    // Add a ".noConflict()" helper method.
65    this.pluginNoConflict(id, plugin, noConflict);
66
67    $.fn[id] = plugin;
68  };
69
70  /**
71   * Diff object properties.
72   *
73   * @param {...Object} objects
74   *   Two or more objects. The first object will be used to return properties
75   *   values.
76   *
77   * @return {Object}
78   *   Returns the properties of the first passed object that are not present
79   *   in all other passed objects.
80   */
81  Bootstrap.diffObjects = function (objects) {
82    var args = Array.prototype.slice.call(arguments);
83    return _.pick(args[0], _.difference.apply(_, _.map(args, function (obj) {
84      return Object.keys(obj);
85    })));
86  };
87
88  /**
89   * Map of supported events by regular expression.
90   *
91   * @type {Object<Event|MouseEvent|KeyboardEvent|TouchEvent,RegExp>}
92   */
93  Bootstrap.eventMap = {
94    Event: /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
95    MouseEvent: /^(?:click|dblclick|mouse(?:down|enter|leave|up|over|move|out))$/,
96    KeyboardEvent: /^(?:key(?:down|press|up))$/,
97    TouchEvent: /^(?:touch(?:start|end|move|cancel))$/
98  };
99
100  /**
101   * Extends a jQuery Plugin.
102   *
103   * @param {String} id
104   *   A jQuery plugin identifier located in $.fn.
105   * @param {Function} callback
106   *   A constructor function used to initialize the for the jQuery plugin.
107   *
108   * @return {Function|Boolean}
109   *   The jQuery plugin constructor or FALSE if the plugin does not exist.
110   */
111  Bootstrap.extendPlugin = function (id, callback) {
112    // Immediately return if plugin doesn't exist.
113    if (typeof $.fn[id] !== 'function') {
114      return this.fatal('Specified jQuery plugin identifier does not exist: @id', {'@id':  id});
115    }
116
117    // Immediately return if callback isn't a function.
118    if (typeof callback !== 'function') {
119      return this.fatal('You must provide a callback function to extend the jQuery plugin "@id": @callback', {'@id': id, '@callback':  callback});
120    }
121
122    // Determine existing plugin constructor.
123    var constructor = $.fn[id] && $.fn[id].Constructor || $.fn[id];
124    var plugin = callback.apply(constructor, [this.settings]);
125    if (!$.isPlainObject(plugin)) {
126      return this.fatal('Returned value from callback is not a plain object that can be used to extend the jQuery plugin "@id": @obj', {'@obj':  plugin});
127    }
128
129    this.wrapPluginConstructor(constructor, plugin, true);
130
131    return $.fn[id];
132  };
133
134  Bootstrap.superWrapper = function (parent, fn) {
135    return function () {
136      var previousSuper = this.super;
137      this.super = parent;
138      var ret = fn.apply(this, arguments);
139      if (previousSuper) {
140        this.super = previousSuper;
141      }
142      else {
143        delete this.super;
144      }
145      return ret;
146    };
147  };
148
149  /**
150   * Provide a helper method for displaying when something is went wrong.
151   *
152   * @param {String} message
153   *   The message to display.
154   * @param {Object} [args]
155   *   An arguments to use in message.
156   *
157   * @return {Boolean}
158   *   Always returns FALSE.
159   */
160  Bootstrap.fatal = function (message, args) {
161    if (this.settings.dev && console.warn) {
162      for (var name in args) {
163        if (args.hasOwnProperty(name) && typeof args[name] === 'object') {
164          args[name] = JSON.stringify(args[name]);
165        }
166      }
167      Drupal.throwError(new Error(Drupal.formatString(message, args)));
168    }
169    return false;
170  };
171
172  /**
173   * Intersects object properties.
174   *
175   * @param {...Object} objects
176   *   Two or more objects. The first object will be used to return properties
177   *   values.
178   *
179   * @return {Object}
180   *   Returns the properties of first passed object that intersects with all
181   *   other passed objects.
182   */
183  Bootstrap.intersectObjects = function (objects) {
184    var args = Array.prototype.slice.call(arguments);
185    return _.pick(args[0], _.intersection.apply(_, _.map(args, function (obj) {
186      return Object.keys(obj);
187    })));
188  };
189
190  /**
191   * Normalizes an object's values.
192   *
193   * @param {Object} obj
194   *   The object to normalize.
195   *
196   * @return {Object}
197   *   The normalized object.
198   */
199  Bootstrap.normalizeObject = function (obj) {
200    if (!$.isPlainObject(obj)) {
201      return obj;
202    }
203
204    for (var k in obj) {
205      if (typeof obj[k] === 'string') {
206        if (obj[k] === 'true') {
207          obj[k] = true;
208        }
209        else if (obj[k] === 'false') {
210          obj[k] = false;
211        }
212        else if (obj[k].match(/^[\d-.]$/)) {
213          obj[k] = parseFloat(obj[k]);
214        }
215      }
216      else if ($.isPlainObject(obj[k])) {
217        obj[k] = Bootstrap.normalizeObject(obj[k]);
218      }
219    }
220
221    return obj;
222  };
223
224  /**
225   * An object based once plugin (similar to jquery.once, but without the DOM).
226   *
227   * @param {String} id
228   *   A unique identifier.
229   * @param {Function} callback
230   *   The callback to invoke if the identifier has not yet been seen.
231   *
232   * @return {Bootstrap}
233   */
234  Bootstrap.once = function (id, callback) {
235    // Immediately return if identifier has already been processed.
236    if (this.processedOnce[id]) {
237      return this;
238    }
239    callback.call(this, this.settings);
240    this.processedOnce[id] = true;
241    return this;
242  };
243
244  /**
245   * Provide jQuery UI like ability to get/set options for Bootstrap plugins.
246   *
247   * @param {string|object} key
248   *   A string value of the option to set, can be dot like to a nested key.
249   *   An object of key/value pairs.
250   * @param {*} [value]
251   *   (optional) A value to set for key.
252   *
253   * @returns {*}
254   *   - Returns nothing if key is an object or both key and value parameters
255   *   were provided to set an option.
256   *   - Returns the a value for a specific setting if key was provided.
257   *   - Returns an object of key/value pairs of all the options if no key or
258   *   value parameter was provided.
259   *
260   * @see https://github.com/jquery/jquery-ui/blob/master/ui/widget.js
261   */
262  Bootstrap.option = function (key, value) {
263    var options = $.isPlainObject(key) ? $.extend({}, key) : {};
264
265    // Get all options (clone so it doesn't reference the internal object).
266    if (arguments.length === 0) {
267      return $.extend({}, this.options);
268    }
269
270    // Get/set single option.
271    if (typeof key === "string") {
272      // Handle nested keys in dot notation.
273      // e.g., "foo.bar" => { foo: { bar: true } }
274      var parts = key.split('.');
275      key = parts.shift();
276      var obj = options;
277      if (parts.length) {
278        for (var i = 0; i < parts.length - 1; i++) {
279          obj[parts[i]] = obj[parts[i]] || {};
280          obj = obj[parts[i]];
281        }
282        key = parts.pop();
283      }
284
285      // Get.
286      if (arguments.length === 1) {
287        return obj[key] === void 0 ? null : obj[key];
288      }
289
290      // Set.
291      obj[key] = value;
292    }
293
294    // Set multiple options.
295    $.extend(true, this.options, options);
296  };
297
298  /**
299   * Adds a ".noConflict()" helper method if needed.
300   *
301   * @param {String} id
302   *   A jQuery plugin identifier located in $.fn.
303   * @param {Function} plugin
304   * @param {Function} plugin
305   *   A constructor function used to initialize the for the jQuery plugin.
306   * @param {Boolean} [noConflict]
307   *   Flag indicating whether or not to create a ".noConflict()" helper method
308   *   for the plugin.
309   */
310  Bootstrap.pluginNoConflict = function (id, plugin, noConflict) {
311    if (plugin.noConflict === void 0 && (noConflict === void 0 || noConflict)) {
312      var old = $.fn[id];
313      plugin.noConflict = function () {
314        $.fn[id] = old;
315        return this;
316      };
317    }
318  };
319
320  /**
321   * Creates a handler that relays to another event name.
322   *
323   * @param {HTMLElement|jQuery} target
324   *   A target element.
325   * @param {String} name
326   *   The name of the event to trigger.
327   * @param {Boolean} [stopPropagation=true]
328   *   Flag indicating whether to stop the propagation of the event, defaults
329   *   to true.
330   *
331   * @return {Function}
332   *   An even handler callback function.
333   */
334  Bootstrap.relayEvent = function (target, name, stopPropagation) {
335    return function (e) {
336      if (stopPropagation === void 0 || stopPropagation) {
337        e.stopPropagation();
338      }
339      var $target = $(target);
340      var parts = name.split('.').filter(Boolean);
341      var type = parts.shift();
342      e.target = $target[0];
343      e.currentTarget = $target[0];
344      e.namespace = parts.join('.');
345      e.type = type;
346      $target.trigger(e);
347    };
348  };
349
350  /**
351   * Replaces a Bootstrap jQuery plugin definition.
352   *
353   * @param {String} id
354   *   A jQuery plugin identifier located in $.fn.
355   * @param {Function} callback
356   *   A callback function that is immediately invoked and must return a
357   *   function that will be used as the plugin constructor.
358   * @param {Boolean} [noConflict]
359   *   Flag indicating whether or not to create a ".noConflict()" helper method
360   *   for the plugin.
361   */
362  Bootstrap.replacePlugin = function (id, callback, noConflict) {
363    // Immediately return if plugin doesn't exist.
364    if (typeof $.fn[id] !== 'function') {
365      return this.fatal('Specified jQuery plugin identifier does not exist: @id', {'@id':  id});
366    }
367
368    // Immediately return if callback isn't a function.
369    if (typeof callback !== 'function') {
370      return this.fatal('You must provide a valid callback function to replace a jQuery plugin: @callback', {'@callback': callback});
371    }
372
373    // Determine existing plugin constructor.
374    var constructor = $.fn[id] && $.fn[id].Constructor || $.fn[id];
375    var plugin = callback.apply(constructor, [this.settings]);
376
377    // Immediately return if plugin isn't a function.
378    if (typeof plugin !== 'function') {
379      return this.fatal('Returned value from callback is not a usable function to replace a jQuery plugin "@id": @plugin', {'@id': id, '@plugin': plugin});
380    }
381
382    this.wrapPluginConstructor(constructor, plugin);
383
384    // Add a ".noConflict()" helper method.
385    this.pluginNoConflict(id, plugin, noConflict);
386
387    $.fn[id] = plugin;
388  };
389
390  /**
391   * Simulates a native event on an element in the browser.
392   *
393   * Note: This is a fairly complete modern implementation. If things aren't
394   * working quite the way you intend (in older browsers), you may wish to use
395   * the jQuery.simulate plugin. If it's available, this method will defer to
396   * that plugin.
397   *
398   * @see https://github.com/jquery/jquery-simulate
399   *
400   * @param {HTMLElement|jQuery} element
401   *   A DOM element to dispatch event on. Note: this may be a jQuery object,
402   *   however be aware that this will trigger the same event for each element
403   *   inside the jQuery collection; use with caution.
404   * @param {String|String[]} type
405   *   The type(s) of event to simulate.
406   * @param {Object} [options]
407   *   An object of options to pass to the event constructor. Typically, if
408   *   an event is being proxied, you should just pass the original event
409   *   object here. This allows, if the browser supports it, to be a truly
410   *   simulated event.
411   *
412   * @return {Boolean}
413   *   The return value is false if event is cancelable and at least one of the
414   *   event handlers which handled this event called Event.preventDefault().
415   *   Otherwise it returns true.
416   */
417  Bootstrap.simulate = function (element, type, options) {
418    // Handle jQuery object wrappers so it triggers on each element.
419    var ret = true;
420    if (element instanceof $) {
421      element.each(function () {
422        if (!Bootstrap.simulate(this, type, options)) {
423          ret = false;
424        }
425      });
426      return ret;
427    }
428
429    if (!(element instanceof HTMLElement)) {
430      this.fatal('Passed element must be an instance of HTMLElement, got "@type" instead.', {
431        '@type': typeof element,
432      });
433    }
434
435    // Defer to the jQuery.simulate plugin, if it's available.
436    if (typeof $.simulate === 'function') {
437      new $.simulate(element, type, options);
438      return true;
439    }
440
441    var event;
442    var ctor;
443    var types = [].concat(type);
444    for (var i = 0, l = types.length; i < l; i++) {
445      type = types[i];
446      for (var name in this.eventMap) {
447        if (this.eventMap[name].test(type)) {
448          ctor = name;
449          break;
450        }
451      }
452      if (!ctor) {
453        throw new SyntaxError('Only rudimentary HTMLEvents, KeyboardEvents and MouseEvents are supported: ' + type);
454      }
455      var opts = {bubbles: true, cancelable: true};
456      if (ctor === 'KeyboardEvent' || ctor === 'MouseEvent') {
457        $.extend(opts, {ctrlKey: !1, altKey: !1, shiftKey: !1, metaKey: !1});
458      }
459      if (ctor === 'MouseEvent') {
460        $.extend(opts, {button: 0, pointerX: 0, pointerY: 0, view: window});
461      }
462      if (options) {
463        $.extend(opts, options);
464      }
465      if (typeof window[ctor] === 'function') {
466        event = new window[ctor](type, opts);
467        if (!element.dispatchEvent(event)) {
468          ret = false;
469        }
470      }
471      else if (document.createEvent) {
472        event = document.createEvent(ctor);
473        event.initEvent(type, opts.bubbles, opts.cancelable);
474        if (!element.dispatchEvent(event)) {
475          ret = false;
476        }
477      }
478      else if (typeof element.fireEvent === 'function') {
479        event = $.extend(document.createEventObject(), opts);
480        if (!element.fireEvent('on' + type, event)) {
481          ret = false;
482        }
483      }
484      else if (typeof element[type]) {
485        element[type]();
486      }
487    }
488    return ret;
489  };
490
491  /**
492   * Strips HTML and returns just text.
493   *
494   * @param {String|Element|jQuery} html
495   *   A string of HTML content, an Element DOM object or a jQuery object.
496   *
497   * @return {String}
498   *   The text without HTML tags.
499   *
500   * @todo Replace with http://locutus.io/php/strings/strip_tags/
501   */
502  Bootstrap.stripHtml = function (html) {
503    if (html instanceof $) {
504      html = html.html();
505    }
506    else if (html instanceof Element) {
507      html = html.innerHTML;
508    }
509    var tmp = document.createElement('DIV');
510    tmp.innerHTML = html;
511    return (tmp.textContent || tmp.innerText || '').replace(/^[\s\n\t]*|[\s\n\t]*$/, '');
512  };
513
514  /**
515   * Provide a helper method for displaying when something is unsupported.
516   *
517   * @param {String} type
518   *   The type of unsupported object, e.g. method or option.
519   * @param {String} name
520   *   The name of the unsupported object.
521   * @param {*} [value]
522   *   The value of the unsupported object.
523   */
524  Bootstrap.unsupported = function (type, name, value) {
525    Bootstrap.warn('Unsupported by Drupal Bootstrap: (@type) @name -> @value', {
526      '@type': type,
527      '@name': name,
528      '@value': typeof value === 'object' ? JSON.stringify(value) : value
529    });
530  };
531
532  /**
533   * Provide a helper method to display a warning.
534   *
535   * @param {String} message
536   *   The message to display.
537   * @param {Object} [args]
538   *   Arguments to use as replacements in Drupal.formatString.
539   */
540  Bootstrap.warn = function (message, args) {
541    if (this.settings.dev && console.warn) {
542      console.warn(Drupal.formatString(message, args));
543    }
544  };
545
546  /**
547   * Wraps a plugin with common functionality.
548   *
549   * @param {Function} constructor
550   *   A plugin constructor being wrapped.
551   * @param {Object|Function} plugin
552   *   The plugin being wrapped.
553   * @param {Boolean} [extend = false]
554   *   Whether to add super extensibility.
555   */
556  Bootstrap.wrapPluginConstructor = function (constructor, plugin, extend) {
557    var proto = constructor.prototype;
558
559    // Add a jQuery UI like option getter/setter method.
560    var option = this.option;
561    if (proto.option === void(0)) {
562      proto.option = function () {
563        return option.apply(this, arguments);
564      };
565    }
566
567    if (extend) {
568      // Handle prototype properties separately.
569      if (plugin.prototype !== void 0) {
570        for (var key in plugin.prototype) {
571          if (!plugin.prototype.hasOwnProperty(key)) continue;
572          var value = plugin.prototype[key];
573          if (typeof value === 'function') {
574            proto[key] = this.superWrapper(proto[key] || function () {}, value);
575          }
576          else {
577            proto[key] = $.isPlainObject(value) ? $.extend(true, {}, proto[key], value) : value;
578          }
579        }
580      }
581      delete plugin.prototype;
582
583      // Handle static properties.
584      for (key in plugin) {
585        if (!plugin.hasOwnProperty(key)) continue;
586        value = plugin[key];
587        if (typeof value === 'function') {
588          constructor[key] = this.superWrapper(constructor[key] || function () {}, value);
589        }
590        else {
591          constructor[key] = $.isPlainObject(value) ? $.extend(true, {}, constructor[key], value) : value;
592        }
593      }
594    }
595  };
596
597  // Add Bootstrap to the global Drupal object.
598  Drupal.bootstrap = Drupal.bootstrap || Bootstrap;
599
600})(window._, window.jQuery, window.Drupal, window.drupalSettings);
601;
602(function ($, _) {
603
604  /**
605   * @class Attributes
606   *
607   * Modifies attributes.
608   *
609   * @param {Object|Attributes} attributes
610   *   An object to initialize attributes with.
611   */
612  var Attributes = function (attributes) {
613    this.data = {};
614    this.data['class'] = [];
615    this.merge(attributes);
616  };
617
618  /**
619   * Renders the attributes object as a string to inject into an HTML element.
620   *
621   * @return {String}
622   *   A rendered string suitable for inclusion in HTML markup.
623   */
624  Attributes.prototype.toString = function () {
625    var output = '';
626    var name, value;
627    var checkPlain = function (str) {
628      return str && str.toString().replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;') || '';
629    };
630    var data = this.getData();
631    for (name in data) {
632      if (!data.hasOwnProperty(name)) continue;
633      value = data[name];
634      if (_.isFunction(value)) value = value();
635      if (_.isObject(value)) value = _.values(value);
636      if (_.isArray(value)) value = value.join(' ');
637      output += ' ' + checkPlain(name) + '="' + checkPlain(value) + '"';
638    }
639    return output;
640  };
641
642  /**
643   * Renders the Attributes object as a plain object.
644   *
645   * @return {Object}
646   *   A plain object suitable for inclusion in DOM elements.
647   */
648  Attributes.prototype.toPlainObject = function () {
649    var object = {};
650    var name, value;
651    var data = this.getData();
652    for (name in data) {
653      if (!data.hasOwnProperty(name)) continue;
654      value = data[name];
655      if (_.isFunction(value)) value = value();
656      if (_.isObject(value)) value = _.values(value);
657      if (_.isArray(value)) value = value.join(' ');
658      object[name] = value;
659    }
660    return object;
661  };
662
663  /**
664   * Add class(es) to the array.
665   *
666   * @param {string|Array} value
667   *   An individual class or an array of classes to add.
668   *
669   * @return {Attributes}
670   *
671   * @chainable
672   */
673  Attributes.prototype.addClass = function (value) {
674    var args = Array.prototype.slice.call(arguments);
675    this.data['class'] = this.sanitizeClasses(this.data['class'].concat(args));
676    return this;
677  };
678
679  /**
680   * Returns whether the requested attribute exists.
681   *
682   * @param {string} name
683   *   An attribute name to check.
684   *
685   * @return {boolean}
686   *   TRUE or FALSE
687   */
688  Attributes.prototype.exists = function (name) {
689    return this.data[name] !== void(0) && this.data[name] !== null;
690  };
691
692  /**
693   * Retrieve a specific attribute from the array.
694   *
695   * @param {string} name
696   *   The specific attribute to retrieve.
697   * @param {*} defaultValue
698   *   (optional) The default value to set if the attribute does not exist.
699   *
700   * @return {*}
701   *   A specific attribute value, passed by reference.
702   */
703  Attributes.prototype.get = function (name, defaultValue) {
704    if (!this.exists(name)) this.data[name] = defaultValue;
705    return this.data[name];
706  };
707
708  /**
709   * Retrieves a cloned copy of the internal attributes data object.
710   *
711   * @return {Object}
712   */
713  Attributes.prototype.getData = function () {
714    return _.extend({}, this.data);
715  };
716
717  /**
718   * Retrieves classes from the array.
719   *
720   * @return {Array}
721   *   The classes array.
722   */
723  Attributes.prototype.getClasses = function () {
724    return this.get('class', []);
725  };
726
727  /**
728   * Indicates whether a class is present in the array.
729   *
730   * @param {string|Array} className
731   *   The class(es) to search for.
732   *
733   * @return {boolean}
734   *   TRUE or FALSE
735   */
736  Attributes.prototype.hasClass = function (className) {
737    className = this.sanitizeClasses(Array.prototype.slice.call(arguments));
738    var classes = this.getClasses();
739    for (var i = 0, l = className.length; i < l; i++) {
740      // If one of the classes fails, immediately return false.
741      if (_.indexOf(classes, className[i]) === -1) {
742        return false;
743      }
744    }
745    return true;
746  };
747
748  /**
749   * Merges multiple values into the array.
750   *
751   * @param {Attributes|Node|jQuery|Object} object
752   *   An Attributes object with existing data, a Node DOM element, a jQuery
753   *   instance or a plain object where the key is the attribute name and the
754   *   value is the attribute value.
755   * @param {boolean} [recursive]
756   *   Flag determining whether or not to recursively merge key/value pairs.
757   *
758   * @return {Attributes}
759   *
760   * @chainable
761   */
762  Attributes.prototype.merge = function (object, recursive) {
763    // Immediately return if there is nothing to merge.
764    if (!object) {
765      return this;
766    }
767
768    // Get attributes from a jQuery element.
769    if (object instanceof $) {
770      object = object[0];
771    }
772
773    // Get attributes from a DOM element.
774    if (object instanceof Node) {
775      object = Array.prototype.slice.call(object.attributes).reduce(function (attributes, attribute) {
776        attributes[attribute.name] = attribute.value;
777        return attributes;
778      }, {});
779    }
780    // Get attributes from an Attributes instance.
781    else if (object instanceof Attributes) {
782      object = object.getData();
783    }
784    // Otherwise, clone the object.
785    else {
786      object = _.extend({}, object);
787    }
788
789    // By this point, there should be a valid plain object.
790    if (!$.isPlainObject(object)) {
791      setTimeout(function () {
792        throw new Error('Passed object is not supported: ' + object);
793      });
794      return this;
795    }
796
797    // Handle classes separately.
798    if (object && object['class'] !== void 0) {
799      this.addClass(object['class']);
800      delete object['class'];
801    }
802
803    if (recursive === void 0 || recursive) {
804      this.data = $.extend(true, {}, this.data, object);
805    }
806    else {
807      this.data = $.extend({}, this.data, object);
808    }
809
810    return this;
811  };
812
813  /**
814   * Removes an attribute from the array.
815   *
816   * @param {string} name
817   *   The name of the attribute to remove.
818   *
819   * @return {Attributes}
820   *
821   * @chainable
822   */
823  Attributes.prototype.remove = function (name) {
824    if (this.exists(name)) delete this.data[name];
825    return this;
826  };
827
828  /**
829   * Removes a class from the attributes array.
830   *
831   * @param {...string|Array} className
832   *   An individual class or an array of classes to remove.
833   *
834   * @return {Attributes}
835   *
836   * @chainable
837   */
838  Attributes.prototype.removeClass = function (className) {
839    var remove = this.sanitizeClasses(Array.prototype.slice.apply(arguments));
840    this.data['class'] = _.without(this.getClasses(), remove);
841    return this;
842  };
843
844  /**
845   * Replaces a class in the attributes array.
846   *
847   * @param {string} oldValue
848   *   The old class to remove.
849   * @param {string} newValue
850   *   The new class. It will not be added if the old class does not exist.
851   *
852   * @return {Attributes}
853   *
854   * @chainable
855   */
856  Attributes.prototype.replaceClass = function (oldValue, newValue) {
857    var classes = this.getClasses();
858    var i = _.indexOf(this.sanitizeClasses(oldValue), classes);
859    if (i >= 0) {
860      classes[i] = newValue;
861      this.set('class', classes);
862    }
863    return this;
864  };
865
866  /**
867   * Ensures classes are flattened into a single is an array and sanitized.
868   *
869   * @param {...String|Array} classes
870   *   The class or classes to sanitize.
871   *
872   * @return {Array}
873   *   A sanitized array of classes.
874   */
875  Attributes.prototype.sanitizeClasses = function (classes) {
876    return _.chain(Array.prototype.slice.call(arguments))
877      // Flatten in case there's a mix of strings and arrays.
878      .flatten()
879
880      // Split classes that may have been added with a space as a separator.
881      .map(function (string) {
882        return string.split(' ');
883      })
884
885      // Flatten again since it was just split into arrays.
886      .flatten()
887
888      // Filter out empty items.
889      .filter()
890
891      // Clean the class to ensure it's a valid class name.
892      .map(function (value) {
893        return Attributes.cleanClass(value);
894      })
895
896      // Ensure classes are unique.
897      .uniq()
898
899      // Retrieve the final value.
900      .value();
901  };
902
903  /**
904   * Sets an attribute on the array.
905   *
906   * @param {string} name
907   *   The name of the attribute to set.
908   * @param {*} value
909   *   The value of the attribute to set.
910   *
911   * @return {Attributes}
912   *
913   * @chainable
914   */
915  Attributes.prototype.set = function (name, value) {
916    var obj = $.isPlainObject(name) ? name : {};
917    if (typeof name === 'string') {
918      obj[name] = value;
919    }
920    return this.merge(obj);
921  };
922
923  /**
924   * Prepares a string for use as a CSS identifier (element, class, or ID name).
925   *
926   * Note: this is essentially a direct copy from
927   * \Drupal\Component\Utility\Html::cleanCssIdentifier
928   *
929   * @param {string} identifier
930   *   The identifier to clean.
931   * @param {Object} [filter]
932   *   An object of string replacements to use on the identifier.
933   *
934   * @return {string}
935   *   The cleaned identifier.
936   */
937  Attributes.cleanClass = function (identifier, filter) {
938    filter = filter || {
939      ' ': '-',
940      '_': '-',
941      '/': '-',
942      '[': '-',
943      ']': ''
944    };
945
946    identifier = identifier.toLowerCase();
947
948    if (filter['__'] === void 0) {
949      identifier = identifier.replace('__', '#DOUBLE_UNDERSCORE#');
950    }
951
952    identifier = identifier.replace(Object.keys(filter), Object.keys(filter).map(function(key) { return filter[key]; }));
953
954    if (filter['__'] === void 0) {
955      identifier = identifier.replace('#DOUBLE_UNDERSCORE#', '__');
956    }
957
958    identifier = identifier.replace(/[^\u002D\u0030-\u0039\u0041-\u005A\u005F\u0061-\u007A\u00A1-\uFFFF]/g, '');
959    identifier = identifier.replace(['/^[0-9]/', '/^(-[0-9])|^(--)/'], ['_', '__']);
960
961    return identifier;
962  };
963
964  /**
965   * Creates an Attributes instance.
966   *
967   * @param {object|Attributes} [attributes]
968   *   An object to initialize attributes with.
969   *
970   * @return {Attributes}
971   *   An Attributes instance.
972   *
973   * @constructor
974   */
975  Attributes.create = function (attributes) {
976    return new Attributes(attributes);
977  };
978
979  window.Attributes = Attributes;
980
981})(window.jQuery, window._);
982;
983/**
984 * @file
985 * Theme hooks for the Drupal Bootstrap base theme.
986 */
987(function ($, Drupal, Bootstrap, Attributes) {
988
989  /**
990   * Fallback for theming an icon if the Icon API module is not installed.
991   */
992  if (!Drupal.icon) Drupal.icon = { bundles: {} };
993  if (!Drupal.theme.icon || Drupal.theme.prototype.icon) {
994    $.extend(Drupal.theme, /** @lends Drupal.theme */ {
995      /**
996       * Renders an icon.
997       *
998       * @param {string} bundle
999       *   The bundle which the icon belongs to.
1000       * @param {string} icon
1001       *   The name of the icon to render.
1002       * @param {object|Attributes} [attributes]
1003       *   An object of attributes to also apply to the icon.
1004       *
1005       * @returns {string}
1006       */
1007      icon: function (bundle, icon, attributes) {
1008        if (!Drupal.icon.bundles[bundle]) return '';
1009        attributes = Attributes.create(attributes).addClass('icon').set('aria-hidden', 'true');
1010        icon = Drupal.icon.bundles[bundle](icon, attributes);
1011        return '<span' + attributes + '></span>';
1012      }
1013    });
1014  }
1015
1016  /**
1017   * Callback for modifying an icon in the "bootstrap" icon bundle.
1018   *
1019   * @param {string} icon
1020   *   The icon being rendered.
1021   * @param {Attributes} attributes
1022   *   Attributes object for the icon.
1023   */
1024  Drupal.icon.bundles.bootstrap = function (icon, attributes) {
1025    attributes.addClass(['glyphicon', 'glyphicon-' + icon]);
1026  };
1027
1028  /**
1029   * Add necessary theming hooks.
1030   */
1031  $.extend(Drupal.theme, /** @lends Drupal.theme */ {
1032
1033    /**
1034     * Renders a Bootstrap AJAX glyphicon throbber.
1035     *
1036     * @returns {string}
1037     */
1038    ajaxThrobber: function () {
1039      return Drupal.theme('bootstrapIcon', 'refresh', {'class': ['ajax-throbber', 'glyphicon-spin'] });
1040    },
1041
1042    /**
1043     * Renders a button element.
1044     *
1045     * @param {object|Attributes} attributes
1046     *   An object of attributes to apply to the button. If it contains one of:
1047     *   - value: The label of the button.
1048     *   - context: The context type of Bootstrap button, can be one of:
1049     *     - default
1050     *     - primary
1051     *     - success
1052     *     - info
1053     *     - warning
1054     *     - danger
1055     *     - link
1056     *
1057     * @returns {string}
1058     */
1059    button: function (attributes) {
1060      attributes = Attributes.create(attributes).addClass('btn');
1061      var context = attributes.get('context', 'default');
1062      var label = attributes.get('value', '');
1063      attributes.remove('context').remove('value');
1064      if (!attributes.hasClass(['btn-default', 'btn-primary', 'btn-success', 'btn-info', 'btn-warning', 'btn-danger', 'btn-link'])) {
1065        attributes.addClass('btn-' + Bootstrap.checkPlain(context));
1066      }
1067
1068      // Attempt to, intelligently, provide a default button "type".
1069      if (!attributes.exists('type')) {
1070        attributes.set('type', attributes.hasClass('form-submit') ? 'submit' : 'button');
1071      }
1072
1073      return '<button' + attributes + '>' + label + '</button>';
1074    },
1075
1076    /**
1077     * Alias for "button" theme hook.
1078     *
1079     * @param {object|Attributes} attributes
1080     *   An object of attributes to apply to the button.
1081     *
1082     * @see Drupal.theme.button()
1083     *
1084     * @returns {string}
1085     */
1086    btn: function (attributes) {
1087      return Drupal.theme('button', attributes);
1088    },
1089
1090    /**
1091     * Renders a button block element.
1092     *
1093     * @param {object|Attributes} attributes
1094     *   An object of attributes to apply to the button.
1095     *
1096     * @see Drupal.theme.button()
1097     *
1098     * @returns {string}
1099     */
1100    'btn-block': function (attributes) {
1101      return Drupal.theme('button', Attributes.create(attributes).addClass('btn-block'));
1102    },
1103
1104    /**
1105     * Renders a large button element.
1106     *
1107     * @param {object|Attributes} attributes
1108     *   An object of attributes to apply to the button.
1109     *
1110     * @see Drupal.theme.button()
1111     *
1112     * @returns {string}
1113     */
1114    'btn-lg': function (attributes) {
1115      return Drupal.theme('button', Attributes.create(attributes).addClass('btn-lg'));
1116    },
1117
1118    /**
1119     * Renders a small button element.
1120     *
1121     * @param {object|Attributes} attributes
1122     *   An object of attributes to apply to the button.
1123     *
1124     * @see Drupal.theme.button()
1125     *
1126     * @returns {string}
1127     */
1128    'btn-sm': function (attributes) {
1129      return Drupal.theme('button', Attributes.create(attributes).addClass('btn-sm'));
1130    },
1131
1132    /**
1133     * Renders an extra small button element.
1134     *
1135     * @param {object|Attributes} attributes
1136     *   An object of attributes to apply to the button.
1137     *
1138     * @see Drupal.theme.button()
1139     *
1140     * @returns {string}
1141     */
1142    'btn-xs': function (attributes) {
1143      return Drupal.theme('button', Attributes.create(attributes).addClass('btn-xs'));
1144    },
1145
1146    /**
1147     * Renders a glyphicon.
1148     *
1149     * @param {string} name
1150     *   The name of the glyphicon.
1151     * @param {object|Attributes} [attributes]
1152     *   An object of attributes to apply to the icon.
1153     *
1154     * @returns {string}
1155     */
1156    bootstrapIcon: function (name, attributes) {
1157      return Drupal.theme('icon', 'bootstrap', name, attributes);
1158    }
1159
1160  });
1161
1162})(window.jQuery, window.Drupal, window.Drupal.bootstrap, window.Attributes);
1163;
1164/**
1165* DO NOT EDIT THIS FILE.
1166* See the following change record for more information,
1167* https://www.drupal.org/node/2815083
1168* @preserve
1169**/
1170(function ($, Drupal) {
1171  Drupal.theme.progressBar = function (id) {
1172    return "<div id=\"".concat(id, "\" class=\"progress\" aria-live=\"polite\">") + '<div class="progress__label">&nbsp;</div>' + '<div class="progress__track"><div class="progress__bar"></div></div>' + '<div class="progress__percentage"></div>' + '<div class="progress__description">&nbsp;</div>' + '</div>';
1173  };
1174  Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) {
1175    this.id = id;
1176    this.method = method || 'GET';
1177    this.updateCallback = updateCallback;
1178    this.errorCallback = errorCallback;
1179    this.element = $(Drupal.theme('progressBar', id));
1180  };
1181  $.extend(Drupal.ProgressBar.prototype, {
1182    setProgress: function setProgress(percentage, message, label) {
1183      if (percentage >= 0 && percentage <= 100) {
1184        $(this.element).find('div.progress__bar').css('width', "".concat(percentage, "%"));
1185        $(this.element).find('div.progress__percentage').html("".concat(percentage, "%"));
1186      }
1187      $('div.progress__description', this.element).html(message);
1188      $('div.progress__label', this.element).html(label);
1189      if (this.updateCallback) {
1190        this.updateCallback(percentage, message, this);
1191      }
1192    },
1193    startMonitoring: function startMonitoring(uri, delay) {
1194      this.delay = delay;
1195      this.uri = uri;
1196      this.sendPing();
1197    },
1198    stopMonitoring: function stopMonitoring() {
1199      clearTimeout(this.timer);
1200      this.uri = null;
1201    },
1202    sendPing: function sendPing() {
1203      if (this.timer) {
1204        clearTimeout(this.timer);
1205      }
1206      if (this.uri) {
1207        var pb = this;
1208        var uri = this.uri;
1209        if (uri.indexOf('?') === -1) {
1210          uri += '?';
1211        } else {
1212          uri += '&';
1213        }
1214        uri += '_format=json';
1215        $.ajax({
1216          type: this.method,
1217          url: uri,
1218          data: '',
1219          dataType: 'json',
1220          success: function success(progress) {
1221            if (progress.status === 0) {
1222              pb.displayError(progress.data);
1223              return;
1224            }
1225            pb.setProgress(progress.percentage, progress.message, progress.label);
1226            pb.timer = setTimeout(function () {
1227              pb.sendPing();
1228            }, pb.delay);
1229          },
1230          error: function error(xmlhttp) {
1231            var e = new Drupal.AjaxError(xmlhttp, pb.uri);
1232            pb.displayError("<pre>".concat(e.message, "</pre>"));
1233          }
1234        });
1235      }
1236    },
1237    displayError: function displayError(string) {
1238      var error = $('<div class="messages messages--error"></div>').html(string);
1239      $(this.element).before(error).hide();
1240      if (this.errorCallback) {
1241        this.errorCallback(this);
1242      }
1243    }
1244  });
1245})(jQuery, Drupal);;
1246/**
1247 * @file
1248 * Extends methods from core/misc/progress.js.
1249 */
1250
1251(function ($, Drupal) {
1252
1253  'use strict';
1254
1255  /**
1256   * Theme function for the progress bar.
1257   *
1258   * @param {string} id
1259   *
1260   * @return {string}
1261   *   The HTML for the progress bar.
1262   */
1263  Drupal.theme.progressBar = function (id) {
1264    return '<div class="progress-wrapper" aria-live="polite">' +
1265             '<div class="message"></div>'+
1266             '<div id ="' + id + '" class="progress progress-striped active">' +
1267               '<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' +
1268                 '<span class="percentage"></span>' +
1269               '</div>' +
1270             '</div>' +
1271             '<div class="progress-label"></div>' +
1272           '</div>';
1273  };
1274
1275  $.extend(Drupal.ProgressBar.prototype, /** @lends Drupal.ProgressBar */{
1276
1277    /**
1278     * Set the percentage and status message for the progressbar.
1279     *
1280     * @param {number} percentage
1281     * @param {string} message
1282     * @param {string} label
1283     */
1284    setProgress: function (percentage, message, label) {
1285      if (percentage >= 0 && percentage <= 100) {
1286        $(this.element).find('.progress-bar').css('width', percentage + '%').attr('aria-valuenow', percentage);
1287        $(this.element).find('.percentage').html(percentage + '%');
1288      }
1289      if (message) {
1290        // Remove the unnecessary whitespace at the end of the message.
1291        message = message.replace(/<br\/>&nbsp;|\s*$/, '');
1292
1293        $('.message', this.element).html(message);
1294      }
1295      if (label) {
1296        $('.progress-label', this.element).html(label);
1297      }
1298      if (this.updateCallback) {
1299        this.updateCallback(percentage, message, this);
1300      }
1301    },
1302
1303    /**
1304     * Display errors on the page.
1305     *
1306     * @param {string} string
1307     */
1308    displayError: function (string) {
1309      var error = $('<div class="alert alert-block alert-error"><button class="close" data-dismiss="alert">&times;</button><h4>' + Drupal.t('Error message') + '</h4></div>').append(string);
1310      $(this.element).before(error).hide();
1311
1312      if (this.errorCallback) {
1313        this.errorCallback(this);
1314      }
1315    }
1316  });
1317
1318})(jQuery, Drupal);
1319;
1320/**
1321* DO NOT EDIT THIS FILE.
1322* See the following change record for more information,
1323* https://www.drupal.org/node/2815083
1324* @preserve
1325**/
1326(function ($, once) {
1327  var deprecatedMessageSuffix = "is deprecated in Drupal 9.3.0 and will be removed in Drupal 10.0.0. Use the core/once library instead. See https://www.drupal.org/node/3158256";
1328  var originalJQOnce = $.fn.once;
1329  var originalJQRemoveOnce = $.fn.removeOnce;
1330  $.fn.once = function jQueryOnce(id) {
1331    Drupal.deprecationError({
1332      message: "jQuery.once() ".concat(deprecatedMessageSuffix)
1333    });
1334    return originalJQOnce.apply(this, [id]);
1335  };
1336  $.fn.removeOnce = function jQueryRemoveOnce(id) {
1337    Drupal.deprecationError({
1338      message: "jQuery.removeOnce() ".concat(deprecatedMessageSuffix)
1339    });
1340    return originalJQRemoveOnce.apply(this, [id]);
1341  };
1342  var drupalOnce = once;
1343  function augmentedOnce(id, selector, context) {
1344    originalJQOnce.apply($(selector, context), [id]);
1345    return drupalOnce(id, selector, context);
1346  }
1347  function remove(id, selector, context) {
1348    originalJQRemoveOnce.apply($(selector, context), [id]);
1349    return drupalOnce.remove(id, selector, context);
1350  }
1351  window.once = Object.assign(augmentedOnce, drupalOnce, {
1352    remove: remove
1353  });
1354})(jQuery, once);;
1355loadjs=function(){var h=function(){},c={},u={},f={};function o(e,n){if(e){var r=f[e];if(u[e]=n,r)for(;r.length;)r[0](e,n),r.splice(0,1)}}function l(e,n){e.call&&(e={success:e}),n.length?(e.error||h)(n):(e.success||h)(e)}function d(r,t,s,i){var c,o,e=document,n=s.async,u=(s.numRetries||0)+1,f=s.before||h,l=r.replace(/[\?|#].*$/,""),a=r.replace(/^(css|img)!/,"");i=i||0,/(^css!|\.css$)/.test(l)?((o=e.createElement("link")).rel="stylesheet",o.href=a,(c="hideFocus"in o)&&o.relList&&(c=0,o.rel="preload",o.as="style")):/(^img!|\.(png|gif|jpg|svg|webp)$)/.test(l)?(o=e.createElement("img")).src=a:((o=e.createElement("script")).src=r,o.async=void 0===n||n),!(o.onload=o.onerror=o.onbeforeload=function(e){var n=e.type[0];if(c)try{o.sheet.cssText.length||(n="e")}catch(e){18!=e.code&&(n="e")}if("e"==n){if((i+=1)<u)return d(r,t,s,i)}else if("preload"==o.rel&&"style"==o.as)return o.rel="stylesheet";t(r,n,e.defaultPrevented)})!==f(r,o)&&e.head.appendChild(o)}function r(e,n,r){var t,s;if(n&&n.trim&&(t=n),s=(t?r:n)||{},t){if(t in c)throw"LoadJS";c[t]=!0}function i(n,r){!function(e,t,n){var r,s,i=(e=e.push?e:[e]).length,c=i,o=[];for(r=function(e,n,r){if("e"==n&&o.push(e),"b"==n){if(!r)return;o.push(e)}--i||t(o)},s=0;s<c;s++)d(e[s],r,n)}(e,function(e){l(s,e),n&&l({success:n,error:r},e),o(t,e)},s)}if(s.returnPromise)return new Promise(i);i()}return r.ready=function(e,n){return function(e,r){e=e.push?e:[e];var n,t,s,i=[],c=e.length,o=c;
1355for(n=function(e,n){n.length&&i.push(e),--o||r(i)};c--;)t=e[c],(s=u[t])?n(t,s):(f[t]=f[t]||[]).push(n)}(e,function(e){l(n,e)}),r},r.done=function(e){o(e,[])},r.reset=function(){c={},u={},f={}},r.isDefined=function(e){return e in c},r}();;
1356/**
1357* DO NOT EDIT THIS FILE.
1358* See the following change record for more information,
1359* https://www.drupal.org/node/2815083
1360* @preserve
1361**/
1362function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
1363function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
1364function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
1365function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
1366function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
1367function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
1368(function ($, window, Drupal, drupalSettings, loadjs, _ref) {
1369  var isFocusable = _ref.isFocusable,
1370    tabbable = _ref.tabbable;
1371  Drupal.behaviors.AJAX = {
1372    attach: function attach(context, settings) {
1373      function loadAjaxBehavior(base) {
1374        var elementSettings = settings.ajax[base];
1375        if (typeof elementSettings.selector === 'undefined') {
1376          elementSettings.selector = "#".concat(base);
1377        }
1378        once('drupal-ajax', $(elementSettings.selector)).forEach(function (el) {
1379          elementSettings.element = el;
1380          elementSettings.base = base;
1381          Drupal.ajax(elementSettings);
1382        });
1383      }
1384      Object.keys(settings.ajax || {}).forEach(function (base) {
1385        return loadAjaxBehavior(base);
1386      });
1387      Drupal.ajax.bindAjaxLinks(document.body);
1388      once('ajax', '.use-ajax-submit').forEach(function (el) {
1389        var elementSettings = {};
1390        elementSettings.url = $(el.form).attr('action');
1391        elementSettings.setClick = true;
1392        elementSettings.event = 'click';
1393        elementSettings.progress = {
1394          type: 'throbber'
1395        };
1396        elementSettings.base = el.id;
1397        elementSettings.element = el;
1398        Drupal.ajax(elementSettings);
1399      });
1400    },
1401    detach: function detach(context, settings, trigger) {
1402      if (trigger === 'unload') {
1403        Drupal.ajax.expired().forEach(function (instance) {
1404          Drupal.ajax.instances[instance.instanceIndex] = null;
1405        });
1406      }
1407    }
1408  };
1409  Drupal.AjaxError = function (xmlhttp, uri, customMessage) {
1410    var statusCode;
1411    var statusText;
1412    var responseText;
1413    if (xmlhttp.status) {
1414      statusCode = "\n".concat(Drupal.t('An AJAX HTTP error occurred.'), "\n").concat(Drupal.t('HTTP Result Code: !status', {
1415        '!status': xmlhttp.status
1416      }));
1417    } else {
1418      statusCode = "\n".concat(Drupal.t('An AJAX HTTP request terminated abnormally.'));
1419    }
1420    statusCode += "\n".concat(Drupal.t('Debugging information follows.'));
1421    var pathText = "\n".concat(Drupal.t('Path: !uri', {
1422      '!uri': uri
1423    }));
1424    statusText = '';
1425    try {
1426      statusText = "\n".concat(Drupal.t('StatusText: !statusText', {
1427        '!statusText': xmlhttp.statusText.trim()
1428      }));
1429    } catch (e) {}
1430    responseText = '';
1431    try {
1432      responseText = "\n".concat(Drupal.t('ResponseText: !responseText', {
1433        '!responseText': xmlhttp.responseText.trim()
1434      }));
1435    } catch (e) {}
1436    responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi, '');
1437    responseText = responseText.replace(/[\n]+\s+/g, '\n');
1438    var readyStateText = xmlhttp.status === 0 ? "\n".concat(Drupal.t('ReadyState: !readyState', {
1439      '!readyState': xmlhttp.readyState
1440    })) : '';
1441    customMessage = customMessage ? "\n".concat(Drupal.t('CustomMessage: !customMessage', {
1442      '!customMessage': customMessage
1443    })) : '';
1444    this.message = statusCode + pathText + statusText + customMessage + responseText + readyStateText;
1445    this.name = 'AjaxError';
1446  };
1447  Drupal.AjaxError.prototype = new Error();
1448  Drupal.AjaxError.prototype.constructor = Drupal.AjaxError;
1449  Drupal.ajax = function (settings) {
1450    if (arguments.length !== 1) {
1451      throw new Error('Drupal.ajax() function must be called with one configuration object only');
1452    }
1453    var base = settings.base || false;
1454    var element = settings.element || false;
1455    delete settings.base;
1456    delete settings.element;
1457    if (!settings.progress && !element) {
1458      settings.progress = false;
1459    }
1460    var ajax = new Drupal.Ajax(base, element, settings);
1461    ajax.instanceIndex = Drupal.ajax.instances.length;
1462    Drupal.ajax.instances.push(ajax);
1463    return ajax;
1464  };
1465  Drupal.ajax.instances = [];
1466  Drupal.ajax.expired = function () {
1467    return Drupal.ajax.instances.filter(function (instance) {
1468      return instance && instance.element !== false && !document.body.contains(instance.element);
1469    });
1470  };
1471  Drupal.ajax.bindAjaxLinks = function (element) {
1472    once('ajax', '.use-ajax', element).forEach(function (ajaxLink) {
1473      var $linkElement = $(ajaxLink);
1474      var elementSettings = {
1475        progress: {
1476          type: 'throbber'
1477        },
1478        dialogType: $linkElement.data('dialog-type'),
1479        dialog: $linkElement.data('dialog-options'),
1480        dialogRenderer: $linkElement.data('dialog-renderer'),
1481        base: $linkElement.attr('id'),
1482        element: ajaxLink
1483      };
1484      var href = $linkElement.attr('href');
1485      if (href) {
1486        elementSettings.url = href;
1487        elementSettings.event = 'click';
1488      }
1489      Drupal.ajax(elementSettings);
1490    });
1491  };
1492  Drupal.Ajax = function (base, element, elementSettings) {
1493    var defaults = {
1494      event: element ? 'mousedown' : null,
1495      keypress: true,
1496      selector: base ? "#".concat(base) : null,
1497      effect: 'none',
1498      speed: 'none',
1499      method: 'replaceWith',
1500      progress: {
1501        type: 'throbber',
1502        message: Drupal.t('Please wait...')
1503      },
1504      submit: {
1505        js: true
1506      }
1507    };
1508    $.extend(this, defaults, elementSettings);
1509    this.commands = new Drupal.AjaxCommands();
1510    this.instanceIndex = false;
1511    if (this.wrapper) {
1512      this.wrapper = "#".concat(this.wrapper);
1513    }
1514    this.element = element;
1515    this.element_settings = elementSettings;
1516    this.elementSettings = elementSettings;
1517    if (this.element && this.element.form) {
1518      this.$form = $(this.element.form);
1519    }
1520    if (!this.url) {
1521      var $element = $(this.element);
1522      if ($element.is('a')) {
1523        this.url = $element.attr('href');
1524      } else if (this.element && element.form) {
1525        this.url = this.$form.attr('action');
1526      }
1527    }
1528    var originalUrl = this.url;
1529    this.url = this.url.replace(/\/nojs(\/|$|\?|#)/, '/ajax$1');
1530    if (drupalSettings.ajaxTrustedUrl[originalUrl]) {
1531      drupalSettings.ajaxTrustedUrl[this.url] = true;
1532    }
1533    var ajax = this;
1534    ajax.options = {
1535      url: ajax.url,
1536      data: ajax.submit,
1537      isInProgress: function isInProgress() {
1538        return ajax.ajaxing;
1539      },
1540      beforeSerialize: function beforeSerialize(elementSettings, options) {
1541        return ajax.beforeSerialize(elementSettings, options);
1542      },
1543      beforeSubmit: function beforeSubmit(formValues, elementSettings, options) {
1544        ajax.ajaxing = true;
1545        return ajax.beforeSubmit(formValues, elementSettings, options);
1546      },
1547      beforeSend: function beforeSend(xmlhttprequest, options) {
1548        ajax.ajaxing = true;
1549        return ajax.beforeSend(xmlhttprequest, options);
1550      },
1551      success: function success(response, status, xmlhttprequest) {
1552        var _this = this;
1553        if (typeof response === 'string') {
1554          response = $.parseJSON(response);
1555        }
1556        if (response !== null && !drupalSettings.ajaxTrustedUrl[ajax.url]) {
1557          if (xmlhttprequest.getResponseHeader('X-Drupal-Ajax-Token') !== '1') {
1558            var customMessage = Drupal.t('The response failed verification so will not be processed.');
1559            return ajax.error(xmlhttprequest, ajax.url, customMessage);
1560          }
1561        }
1562        return Promise.resolve(ajax.success(response, status)).then(function () {
1563          ajax.ajaxing = false;
1564          $(document).trigger('ajaxSuccess', [xmlhttprequest, _this]);
1565          $(document).trigger('ajaxComplete', [xmlhttprequest, _this]);
1566          if (--$.active === 0) {
1567            $(document).trigger('ajaxStop');
1568          }
1569        });
1570      },
1571      error: function error(xmlhttprequest, status, _error) {
1572        ajax.ajaxing = false;
1573      },
1574      complete: function complete(xmlhttprequest, status) {
1575        if (status === 'error' || status === 'parsererror') {
1576          return ajax.error(xmlhttprequest, ajax.url);
1577        }
1578      },
1579      dataType: 'json',
1580      jsonp: false,
1581      type: 'POST'
1582    };
1583    if (elementSettings.dialog) {
1584      ajax.options.data.dialogOptions = elementSettings.dialog;
1585    }
1586    if (ajax.options.url.indexOf('?') === -1) {
1587      ajax.options.url += '?';
1588    } else {
1589      ajax.options.url += '&';
1590    }
1591    var wrapper = "drupal_".concat(elementSettings.dialogType || 'ajax');
1592    if (elementSettings.dialogRenderer) {
1593      wrapper += ".".concat(elementSettings.dialogRenderer);
1594    }
1595    ajax.options.url += "".concat(Drupal.ajax.WRAPPER_FORMAT, "=").concat(wrapper);
1596    $(ajax.element).on(elementSettings.event, function (event) {
1597      if (!drupalSettings.ajaxTrustedUrl[ajax.url] && !Drupal.url.isLocal(ajax.url)) {
1598        throw new Error(Drupal.t('The callback URL is not local and n
1598ot trusted: !url', {
1599          '!url': ajax.url
1600        }));
1601      }
1602      return ajax.eventResponse(this, event);
1603    });
1604    if (elementSettings.keypress) {
1605      $(ajax.element).on('keypress', function (event) {
1606        return ajax.keypressResponse(this, event);
1607      });
1608    }
1609    if (elementSettings.prevent) {
1610      $(ajax.element).on(elementSettings.prevent, false);
1611    }
1612  };
1613  Drupal.ajax.WRAPPER_FORMAT = '_wrapper_format';
1614  Drupal.Ajax.AJAX_REQUEST_PARAMETER = '_drupal_ajax';
1615  Drupal.Ajax.prototype.execute = function () {
1616    if (this.ajaxing) {
1617      return;
1618    }
1619    try {
1620      this.beforeSerialize(this.element, this.options);
1621      return $.ajax(this.options);
1622    } catch (e) {
1623      this.ajaxing = false;
1624      window.alert("An error occurred while attempting to process ".concat(this.options.url, ": ").concat(e.message));
1625      return $.Deferred().reject();
1626    }
1627  };
1628  Drupal.Ajax.prototype.keypressResponse = function (element, event) {
1629    var ajax = this;
1630    if (event.which === 13 || event.which === 32 && element.type !== 'text' && element.type !== 'textarea' && element.type !== 'tel' && element.type !== 'number') {
1631      event.preventDefault();
1632      event.stopPropagation();
1633      $(element).trigger(ajax.elementSettings.event);
1634    }
1635  };
1636  Drupal.Ajax.prototype.eventResponse = function (element, event) {
1637    event.preventDefault();
1638    event.stopPropagation();
1639    var ajax = this;
1640    if (ajax.ajaxing) {
1641      return;
1642    }
1643    try {
1644      if (ajax.$form) {
1645        if (ajax.setClick) {
1646          element.form.clk = element;
1647        }
1648        ajax.$form.ajaxSubmit(ajax.options);
1649      } else {
1650        ajax.beforeSerialize(ajax.element, ajax.options);
1651        $.ajax(ajax.options);
1652      }
1653    } catch (e) {
1654      ajax.ajaxing = false;
1655      window.alert("An error occurred while attempting to process ".concat(ajax.options.url, ": ").concat(e.message));
1656    }
1657  };
1658  Drupal.Ajax.prototype.beforeSerialize = function (element, options) {
1659    if (this.$form && document.body.contains(this.$form.get(0))) {
1660      var settings = this.settings || drupalSettings;
1661      Drupal.detachBehaviors(this.$form.get(0), settings, 'serialize');
1662    }
1663    options.data[Drupal.Ajax.AJAX_REQUEST_PARAMETER] = 1;
1664    var pageState = drupalSettings.ajaxPageState;
1665    options.data['ajax_page_state[theme]'] = pageState.theme;
1666    options.data['ajax_page_state[theme_token]'] = pageState.theme_token;
1667    options.data['ajax_page_state[libraries]'] = pageState.libraries;
1668  };
1669  Drupal.Ajax.prototype.beforeSubmit = function (formValues, element, options) {};
1670  Drupal.Ajax.prototype.beforeSend = function (xmlhttprequest, options) {
1671    if (this.$form) {
1672      options.extraData = options.extraData || {};
1673      options.extraData.ajax_iframe_upload = '1';
1674      var v = $.fieldValue(this.element);
1675      if (v !== null) {
1676        options.extraData[this.element.name] = v;
1677      }
1678    }
1679    $(this.element).prop('disabled', true);
1680    if (!this.progress || !this.progress.type) {
1681      return;
1682    }
1683    var progressIndicatorMethod = "setProgressIndicator".concat(this.progress.type.slice(0, 1).toUpperCase()).concat(this.progress.type.slice(1).toLowerCase());
1684    if (progressIndicatorMethod in this && typeof this[progressIndicatorMethod] === 'function') {
1685      this[progressIndicatorMethod].call(this);
1686    }
1687  };
1688  Drupal.theme.ajaxProgressThrobber = function (message) {
1689    var messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : '';
1690    var throbber = '<div class="throbber">&nbsp;</div>';
1691    return "<div class=\"ajax-progress ajax-progress-throbber\">".concat(throbber).concat(messageMarkup, "</div>");
1692  };
1693  Drupal.theme.ajaxProgressIndicatorFullscreen = function () {
1694    return '<div class="ajax-progress ajax-progress-fullscreen">&nbsp;</div>';
1695  };
1696  Drupal.theme.ajaxProgressMessage = function (message) {
1697    return "<div class=\"message\">".concat(message, "</div>");
1698  };
1699  Drupal.theme.ajaxProgressBar = function ($element) {
1700    return $('<div class="ajax-progress ajax-progress-bar"></div>').append($element);
1701  };
1702  Drupal.Ajax.prototype.setProgressIndicatorBar = function () {
1703    var progressBar = new Drupal.ProgressBar("ajax-progress-".concat(this.element.i
1703d), $.noop, this.progress.method, $.noop);
1704    if (this.progress.message) {
1705      progressBar.setProgress(-1, this.progress.message);
1706    }
1707    if (this.progress.url) {
1708      progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500);
1709    }
1710    this.progress.element = $(Drupal.theme('ajaxProgressBar', progressBar.element));
1711    this.progress.object = progressBar;
1712    $(this.element).after(this.progress.element);
1713  };
1714  Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () {
1715    this.progress.element = $(Drupal.theme('ajaxProgressThrobber', this.progress.message));
1716    $(this.element).after(this.progress.element);
1717  };
1718  Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function () {
1719    this.progress.element = $(Drupal.theme('ajaxProgressIndicatorFullscreen'));
1720    $('body').append(this.progress.element);
1721  };
1722  Drupal.Ajax.prototype.commandExecutionQueue = function (response, status) {
1723    var _this2 = this;
1724    var ajaxCommands = this.commands;
1725    return Object.keys(response || {}).reduce(function (executionQueue, key) {
1726      return executionQueue.then(function () {
1727        var command = response[key].command;
1728        if (command && ajaxCommands[command]) {
1729          return ajaxCommands[command](_this2, response[key], status);
1730        }
1731      });
1732    }, Promise.resolve());
1733  };
1734  Drupal.Ajax.prototype.success = function (response, status) {
1735    var _this3 = this;
1736    if (this.progress.element) {
1737      $(this.progress.element).remove();
1738    }
1739    if (this.progress.object) {
1740      this.progress.object.stopMonitoring();
1741    }
1742    $(this.element).prop('disabled', false);
1743    var elementParents = $(this.element).parents('[data-drupal-selector]').addBack().toArray();
1744    var focusChanged = Object.keys(response || {}).some(function (key) {
1745      var _response$key = response[key],
1746        command = _response$key.command,
1747        method = _response$key.method;
1748      return command === 'focusFirst' || command === 'invoke' && method === 'focus';
1749    });
1750    return this.commandExecutionQueue(response, status).then(function () {
1751      if (!focusChanged && _this3.element && !$(_this3.element).data('disable-refocus')) {
1752        var target = false;
1753        for (var n = elementParents.length - 1; !target && n >= 0; n--) {
1754          target = document.querySelector("[data-drupal-selector=\"".concat(elementParents[n].getAttribute('data-drupal-selector'), "\"]"));
1755        }
1756        if (target) {
1757          $(target).trigger('focus');
1758        }
1759      }
1760      if (_this3.$form && document.body.contains(_this3.$form.get(0))) {
1761        var settings = _this3.settings || drupalSettings;
1762        Drupal.attachBehaviors(_this3.$form.get(0), settings);
1763      }
1764      _this3.settings = null;
1765    }).catch(function (error) {
1766      return console.error(Drupal.t('An error occurred during the execution of the Ajax response: !error', {
1767        '!error': error
1768      }));
1769    });
1770  };
1771  Drupal.Ajax.prototype.getEffect = function (response) {
1772    var type = response.effect || this.effect;
1773    var speed = response.speed || this.speed;
1774    var effect = {};
1775    if (type === 'none') {
1776      effect.showEffect = 'show';
1777      effect.hideEffect = 'hide';
1778      effect.showSpeed = '';
1779    } else if (type === 'fade') {
1780      effect.showEffect = 'fadeIn';
1781      effect.hideEffect = 'fadeOut';
1782      effect.showSpeed = speed;
1783    } else {
1784      effect.showEffect = "".concat(type, "Toggle");
1785      effect.hideEffect = "".concat(type, "Toggle");
1786      effect.showSpeed = speed;
1787    }
1788    return effect;
1789  };
1790  Drupal.Ajax.prototype.error = function (xmlhttprequest, uri, customMessage) {
1791    if (this.progress.element) {
1792      $(this.progress.element).remove();
1793    }
1794    if (this.progress.object) {
1795      this.progress.object.stopMonitoring();
1796    }
1797    $(this.wrapper).show();
1798    $(this.element).prop('disabled', false);
1799    if (this.$form && document.body.contains(this.$form.get(0))) {
1800      var settings = this.settings || drupalSettings;
1801      Drupal.attachBehaviors(this.$form.get(0), settings);
1802    }
1803    throw new Drupal.AjaxError(xmlhttprequest, uri, customMessage);
1804  };
1805  Drupal.theme.ajaxWrapperNewContent = function ($newContent, ajax, response) {
1806    return (response.effect || ajax.effect) !== 'none' && $newContent.filter(function (i) {
1807      return !($newContent[i].nodeName === '#comment' || $newContent[i].nodeName === '#text' && /^(\s|\n|\r)*$/.test($newContent[i].textContent));
1808    }).length > 1 ? Drupal.theme('ajaxWrapperMultipleRootElements', $newContent) : $newContent;
1809  };
1810  Drupal.theme.ajaxWrapperMultipleRootElements = function ($elements) {
1811    return $('<div></div>').append($elements);
1812  };
1813  Drupal.AjaxCommands = function () {};
1814  Drupal.AjaxCommands.prototype = {
1815    insert: function insert(ajax, response) {
1816      var $wrapper = response.selector ? $(response.selector) : $(ajax.wrapper);
1817      var method = response.method || ajax.method;
1818      var effect = ajax.getEffect(response);
1819      var settings = response.settings || ajax.settings || drupalSettings;
1820      var $newContent = $($.parseHTML(response.data, document, true));
1821      $newContent = Drupal.theme('ajaxWrapperNewContent', $newContent, ajax, response);
1822      switch (method) {
1823        case 'html':
1824        case 'replaceWith':
1825        case 'replaceAll':
1826        case 'empty':
1827        case 'remove':
1828          Drupal.detachBehaviors($wrapper.get(0), settings);
1829          break;
1830        default:
1831          break;
1832      }
1833      $wrapper[method]($newContent);
1834      if (effect.showEffect !== 'show') {
1835        $newContent.hide();
1836      }
1837      var $ajaxNewContent = $newContent.find('.ajax-new-content');
1838      if ($ajaxNewContent.length) {
1839        $ajaxNewContent.hide();
1840        $newContent.show();
1841        $ajaxNewContent[effect.showEffect](effect.showSpeed);
1842      } else if (effect.showEffect !== 'show') {
1843        $newContent[effect.showEffect](effect.showSpeed);
1844      }
1845      if ($newContent.parents('html').length) {
1846        $newContent.each(function (index, element) {
1847          if (element.nodeType === Node.ELEMENT_NODE) {
1848            Drupal.attachBehaviors(element, settings);
1849          }
1850        });
1851      }
1852    },
1853    remove: function remove(ajax, response, status) {
1854      var settings = response.settings || ajax.settings || drupalSettings;
1855      $(response.selector).each(function () {
1856        Drupal.detachBehaviors(this, settings);
1857      }).remove();
1858    },
1859    changed: function changed(ajax, response, status) {
1860      var $element = $(response.selector);
1861      if (!$element.hasClass('ajax-changed')) {
1862        $element.addClass('ajax-changed');
1863        if (response.asterisk) {
1864          $element.find(response.asterisk).append(" <abbr class=\"ajax-changed\" title=\"".concat(Drupal.t('Changed'), "\">*</abbr> "));
1865        }
1866      }
1867    },
1868    alert: function alert(ajax, response, status) {
1869      window.alert(response.text);
1870    },
1871    announce: function announce(ajax, response) {
1872      if (response.priority) {
1873        Drupal.announce(response.text, response.priority);
1874      } else {
1875        Drupal.announce(response.text);
1876      }
1877    },
1878    redirect: function redirect(ajax, response, status) {
1879      window.location = response.url;
1880    },
1881    css: function css(ajax, response, status) {
1882      $(response.selector).css(response.argument);
1883    },
1884    settings: function settings(ajax, response, status) {
1885      var ajaxSettings = drupalSettings.ajax;
1886      if (ajaxSettings) {
1887        Drupal.ajax.expired().forEach(function (instance) {
1888          if (instance.selector) {
1889            var selector = instance.selector.replace('#', '');
1890            if (selector in ajaxSettings) {
1891              delete ajaxSettings[selector];
1892            }
1893          }
1894        });
1895      }
1896      if (response.merge) {
1897        $.extend(true, drupalSettings, response.settings);
1898      } else {
1899        ajax.settings = response.settings;
1900      }
1901    },
1902    data: function data(ajax, response, status) {
1903      $(response.selector).data(response.name, response.value);
1904    },
1905    focusFirst: function focusFirst(ajax, response, status) {
1906      var focusChanged = false;
1907      var container = document.querySelector(response.selector);
1908      if (container) {
1909        var tabbableElements = tabbable(container);
1910        if (tabbableElements.length) {
1911          tabbableElements[0].focus();
1912          focusChanged = true;
1913        } else if (isFocusable(container)) {
1914          container.focus();
1915          focusChanged = true;
1916        }
1917      }
1918      if (ajax.hasOwnProperty('element') && !focusChanged) {
1919        ajax.element.focus();
1920      }
1921    },
1922    invoke: function invoke(ajax, response, status) {
1923      var $element = $(response.selector);
1924      $element[response.method].apply($element, _toConsumableArray(response.args));
1925    },
1926    restripe: function restripe(ajax, response, status) {
1927      $(response.selector).find('> tbody > tr:visible, > tr:visible').removeClass('odd even').filter(':even').addClass('odd').end().filter(':odd').addClass('even');
1928    },
1929    update_build_id: function update_build_id(ajax, response, status) {
1930      document.querySelectorAll("input[name=\"form_build_id\"][value=\"".concat(response.old, "\"]")).forEach(function (item) {
1931        item.value = response.new;
1932      });
1933    },
1934    add_css: function add_css(ajax, response, status) {
1935      $('head').prepend(response.data);
1936    },
1937    message: function message(ajax, response) {
1938      var messages = new Drupal.Message(document.querySelector(response.messageWrapperQuerySelector));
1939      if (response.clearPrevious) {
1940        messages.clear();
1941      }
1942      messages.add(response.message, response.messageOptions);
1943    },
1944    add_js: function add_js(ajax, response, status) {
1945      var parentEl = document.querySelector(response.selector || 'body');
1946      var settings = ajax.settings || drupalSettings;
1947      var allUniqueBundleIds = response.data.map(function (script) {
1948        var uniqueBundleId = script.src + ajax.instanceIndex;
1949        loadjs(script.src, uniqueBundleId, {
1950          async: false,
1951          before: function before(path, scriptEl) {
1952            Object.keys(script).forEach(function (attributeKey) {
1953              scriptEl.setAttribute(attributeKey, script[attributeKey]);
1954            });
1955            parentEl.appendChild(scriptEl);
1956            return false;
1957          }
1958        });
1959        return uniqueBundleId;
1960      });
1961      return new Promise(function (resolve, reject) {
1962        loadjs.ready(allUniqueBundleIds, {
1963          success: function success() {
1964            Drupal.attachBehaviors(parentEl, settings);
1965            resolve();
1966          },
1967          error: function error(depsNotFound) {
1968            var message = Drupal.t("The following files could not be loaded: @dependencies", {
1969              '@dependencies': depsNotFound.join(', ')
1970            });
1971            reject(message);
1972          }
1973        });
1974      });
1975    }
1976  };
1977  var stopEvent = function stopEvent(xhr, settings) {
1978    return xhr.getResponseHeader('X-Drupal-Ajax-Token') === '1' && settings.isInProgress && settings.isInProgress();
1979  };
1980  $.extend(true, $.event.special, {
1981    ajaxSuccess: {
1982      trigger: function trigger(event, xhr, settings) {
1983        if (stopEvent(xhr, settings)) {
1984          return false;
1985        }
1986      }
1987    },
1988    ajaxComplete: {
1989      trigger: function trigger(event, xhr, settings) {
1990        if (stopEvent(xhr, settings)) {
1991          $.active++;
1992          return false;
1993        }
1994      }
1995    }
1996  });
1997})(jQuery, window, Drupal, drupalSettings, loadjs, window.tabbable);;
1998/**
1999 * @file
2000 * Extends methods from core/misc/ajax.js.
2001 */
2002
2003(function ($, window, Drupal, drupalSettings) {
2004
2005  /**
2006   * Attempts to find the closest glyphicon progress indicator.
2007   *
2008   * @param {jQuery|Element} element
2009   *   A DOM element.
2010   *
2011   * @returns {jQuery}
2012   *   A jQuery object.
2013   */
2014  Drupal.Ajax.prototype.findGlyphicon = function (element) {
2015    return $(element).closest('.form-item').find('.ajax-progress.glyphicon')
2016  };
2017
2018  /**
2019   * Starts the spinning of the glyphicon progress indicator.
2020   *
2021   * @param {jQuery|Element} element
2022   *   A DOM element.
2023   * @param {string} [message]
2024   *   An optional message to display (tooltip) for the progress.
2025   *
2026   * @returns {jQuery}
2027   *   A jQuery object.
2028   */
2029  Drupal.Ajax.prototype.glyphiconStart = function (element, message) {
2030    var $glyphicon = this.findGlyphicon(element);
2031    if ($glyphicon[0]) {
2032      $glyphicon.addClass('glyphicon-spin');
2033
2034      // Add any message as a tooltip to the glyphicon.
2035      if ($.fn.tooltip && drupalSettings.bootstrap.tooltip_enabled) {
2036        $glyphicon
2037          .removeAttr('data-toggle')
2038          .removeAttr('data-original-title')
2039          .removeAttr('title')
2040          .tooltip('destroy')
2041        ;
2042
2043        if (message) {
2044          $glyphicon.attr('data-toggle', 'tooltip').attr('title', message).tooltip();
2045        }
2046      }
2047
2048      // Append a message for screen readers.
2049      if (message) {
2050        $glyphicon.parent().append('<div class="sr-only message">' + message + '</div>');
2051      }
2052    }
2053    return $glyphicon;
2054  };
2055
2056  /**
2057   * Stop the spinning of a glyphicon progress indicator.
2058   *
2059   * @param {jQuery|Element} element
2060   *   A DOM element.
2061   */
2062  Drupal.Ajax.prototype.glyphiconStop = function (element) {
2063    var $glyphicon = this.findGlyphicon(element);
2064    if ($glyphicon[0]) {
2065      $glyphicon.removeClass('glyphicon-spin');
2066      if ($.fn.tooltip && drupalSettings.bootstrap.tooltip_enabled) {
2067        $glyphicon
2068          .removeAttr('data-toggle')
2069          .removeAttr('data-original-title')
2070          .removeAttr('title')
2071          .tooltip('destroy')
2072        ;
2073      }
2074    }
2075  };
2076
2077  /**
2078   * Sets the throbber progress indicator.
2079   */
2080  Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () {
2081    var $element = $(this.element);
2082
2083    // Find an existing glyphicon progress indicator.
2084    var $glyphicon = this.glyphiconStart($element, this.progress.message);
2085    if ($glyphicon[0]) {
2086      this.progress.element = $glyphicon.parent();
2087      this.progress.glyphicon = true;
2088      return;
2089    }
2090
2091    // Otherwise, add a glyphicon throbber after the element.
2092    if (!this.progress.element) {
2093      this.progress.element = $(Drupal.theme('ajaxThrobber'));
2094    }
2095    if (this.progress.message) {
2096      this.progress.element.after('<div class="message">' + this.progress.message + '</div>');
2097    }
2098
2099    // If element is an input DOM element type (not :input), append after.
2100    if ($element.is('input')) {
2101      $element.after(this.progress.element);
2102    }
2103    // Otherwise append the throbber inside the element.
2104    else {
2105      $element.append(this.progress.element);
2106    }
2107  };
2108
2109
2110  /**
2111   * Handler for the form redirection completion.
2112   *
2113   * @param {Array.<Drupal.AjaxCommands~commandDefinition>} response
2114   * @param {number} status
2115   */
2116  var success = Drupal.Ajax.prototype.success;
2117  Drupal.Ajax.prototype.success = function (response, status) {
2118    if (this.progress.element) {
2119
2120      // Stop a glyphicon throbber.
2121      if (this.progress.glyphicon) {
2122        this.glyphiconStop(this.progress.element);
2123      }
2124      // Remove the progress element.
2125      else {
2126        this.progress.element.remove();
2127      }
2128
2129      // Remove any message set.
2130      this.progress.element.parent().find('.message').remove();
2131    }
2132
2133    // Invoke the original success handler.
2134    return success.apply(this, [response, status]);
2135  };
2136
2137})(jQuery, this, Drupal, drupalSettings);
2138;
2139/**
2140* DO NOT EDIT THIS FILE.
2141* See the following change record for more information,
2142* https://www.drupal.org/node/2815083
2143* @preserve
2144**/
2145(function ($, Drupal, _ref) {
2146  var isTabbable = _ref.isTabbable;
2147  $.extend($.expr[':'], {
2148    tabbable: function tabbable(element) {
2149      Drupal.deprecationError({
2150        message: 'The :tabbable selector is deprecated in Drupal 9.2.0 and will be removed in Drupal 11.0.0. Use the core/tabbable library instead. See https://www.drupal.org/node/3183730'
2151      });
2152      if (element.tagName === 'SUMMARY' || element.tagName === 'DETAILS') {
2153        var tabIndex = element.getAttribute('tabIndex');
2154        if (tabIndex === null || tabIndex < 0) {
2155          return false;
2156        }
2157      }
2158      return isTabbable(element);
2159    }
2160  });
2161})(jQuery, Drupal, window.tabbable);;
vendor: 327 bytes, lines 2161-2162
2161
2162(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','
2162GTM-KMLH4SZ
vendor: 3 bytes, line 2162
2162');
2162;
2163// Custom scripts file
2164
2165(function ($) {
2166
2167  'use strict';
2168
2169  // Generic function that runs on window resize.
2170  function resizeStuff() {
2171
2172  }
2173
2174  // Runs function once on window resize.
2175  var TO = false;
2176  $(window).resize(function () {
2177    if (TO !== false) {
2178      clearTimeout(TO);
2179    }
2180
2181    // 200 is time in miliseconds.
2182    TO = setTimeout(resizeStuff, 200);
2183  }).resize();
2184
2185  // Count function for the infographic component types
2186  $('.count').each(function () {
2187    $(this).prop('Counter',0).animate({
2188      Counter: $(this).text()
2189    }, {
2190      duration: 3000,
2191      easing: 'swing',
2192      step: function (now) {
2193        $(this).text(Math.ceil(now).toLocaleString('en'));
2194      }
2195    });
2196  });
2197  $("#closeit").click(function() {
2198    $("#shoutbar").slideUp();
2199  });
2200  // $(document).ready(function(){$("#openit").click(function(){$("#shoutbar").effect("bounce","slow");$("#openit").slideUp()})});
2201  // $(document).ready(function(){$("#shoutbar").effect("bounce","slow");$("#closeit").click(function(){$("#shoutbar").slideUp();$("#openit").slideDown()})});
2202})(jQuery);;
2203$ = jQuery;
2204$(function(){
2205    // Add classes to header elements so they can shrink when the page scrolls
2206    var shrinkHeader = 40;
2207    var glitchHeader = 50;
2208    $(window).scroll(function() {
2209        var scroll = getCurrentScroll();
2210        if ( scroll >= glitchHeader ) {
2211            $('header.header').addClass('shrink');
2212            $('.site-logo__grid').addClass('shrink');
2213            $('.region-midline').addClass('shrink');
2214            $('.page-wrapper').addClass('shrink');
2215            $('body.user-logged-in header.header').removeClass('shrink');
2216            $('body.user-logged-in .site-logo__grid').removeClass('shrink');
2217            $('body.user-logged-in .region-midline').removeClass('shrink');
2218        }
2219        // else if ( scroll <= shrinkHeader ) {
2220        //     $('.page-wrapper').removeClass('shrink');
2221        //     $('header.header').removeClass('shrink');
2222        //     $('.site-logo__grid').removeClass('shrink');
2223        //     $('.region-midline').removeClass('shrink');
2224        // }
2225        document.onscroll = scroll;
2226    });
2227    function getCurrentScroll() {
2228        // console.log(scroll);
2229        return window.pageYOffset || document.documentElement.scrollTop;
2230    }
2231
2232    // Add a click function for the ... icon in the footer of the sliding navigation
2233    $("a#toggle").click(function()
2234    {
2235        $(".mm-searchfield").slideToggle();
2236        $(".mmenu_tsesearch").slideToggle();
2237        $(".mmenu_tsecoop").slideToggle();
2238        return false;
2239    });
2240    
2241    // Create a clone of the menu, right next to original.
2242    // Clone is used to sync up elements when the header becomes fixed after scrolling 50 pixels vertically down the page
2243    // $('header.header').addClass('original').clone().insertAfter('.header').addClass('cloned').css('position','fixed').css('top','0').css('margin-top','0').css('z-index','500').removeClass('original').hide();
2244    //
2245    // scrollIntervalID = setInterval(stickIt, 10);
2246    //
2247    // function stickIt() {
2248    //
2249    //     var orgElementPos = $('.original').offset();
2250    //     orgElementTop = orgElementPos.top;
2251    //
2252    //     if ($(window).scrollTop() >= (orgElementTop)) {
2253    //         // scrolled past the original position; now only show the cloned, sticky element.
2254    //
2255    //         // Cloned element should always have same left position and width as original element.
2256    //         orgElement = $('.original');
2257    //         coordsOrgElement = orgElement.offset();
2258    //         leftOrgElement = coordsOrgElement.left;
2259    //         widthOrgElement = orgElement.css('width');
2260    //         $('.cloned').css('left',leftOrgElement+'px').css('top',0).css('width',widthOrgElement).show();
2261    //         $('.original').css('visibility','hidden');
2262    //     } else {
2263    //         // not scrolled past the menu; only show the original menu.
2264    //         $('.cloned').hide();
2265    //         $('.original').css('visibility','visible');
2266    //     }
2267    // }
2268});
2269
2270function rotateCard(btn){
2271    var $card = $(btn).closest('.card-container');
2272    console.log($card);
2273    if($card.hasClass('hover')){
2274        $card.removeClass('hover');
2275    } else {
2276        $card.addClass('hover');
2277    }
2278};
2279/**
2280 * Due to the construction of the responsive_menu module, there exists no
2281 * API or method of injecting navbar information
2282 */
2283(function ($, undefined) {
2284  'use strict';
2285  /**
2286   * Provides the off-canvas menu.
2287   *
2288   * @type {Drupal~behavior}
2289   *
2290   * @prop {Drupal~behaviorAttach} attach
2291   *   Attaches the behavior for the off-canvas menu.
2292   */
2293  Drupal.behaviors.responsive_menu_mmenu = {
2294    attach: function (context) {
2295      $('body').once('cwb-responsive-menu-mmenu').each(function () {
2296        const mmenuId = '#off-canvas';
2297        const offCanvas = document.querySelector(mmenuId);
2298
2299        const settings = drupalSettings.responsive_menu;
2300        const position = settings.position,
2301          theme = settings.theme,
2302          pagedim = settings.pagedim;
2303
2304        const options = {
2305          extensions: [
2306            theme,
2307            'fx-menu-slide',
2308            position === 'left' ? 'position-left' : 'position-right'
2309          ],
2310          keyboardNavigation: {
2311            enable: true,
2312            enhance: true,
2313          },
2314          drag: {
2315            open: settings.drag
2316          },
2317          navbars: [
2318            {
2319              "position": "bottom",
2320              "content": [
2321                "<a class='glyphicon glyphicon-option-horizontal' href='#' id='toggle' aria-hidden='true'></a>",
2322                "searchfield",
2323                "<div class='mmenu_tsesearch'><p>Can't find what you are looking for?</p><p>Use our instant search to find relevant pages.</p></div>",
2324                "<div class='mmenu_tsecoop'>Touchstone Energy® Cooperatives</div></div>"
2325              ]
2326            }
2327          ]
2328        };
2329
2330        if (pagedim !== 'none') {
2331          options.extensions.push(pagedim);
2332        }
2333
2334        const config = {
2335          classNames: {
2336            selected: 'menu-item--active-trail'
2337          }
2338        };
2339
2340        // Allow the settings and options to be extended or overridden.
2341        if (typeof settings.custom !== 'undefined') {
2342          if (typeof settings.custom.options !== 'undefined') {
2343            extend(options, drupalSettings.responsive_menu.custom.options);
2344          }
2345          if (typeof drupalSettings.responsive_menu.custom.config !== 'undefined') {
2346            extend(config, drupalSettings.responsive_menu.custom.config);
2347          }
2348        }
2349
2350        // Set up the off canvas menu.
2351        const mmenu = new Mmenu(mmenuId, options, config);
2352
2353        // Due to a rendering issue with Chrome the page needs the viewport
2354        // metatag to have a value including initial-scale=1.0 otherwise it
2355        // won't render properly.
2356        // @see issue #3153145
2357        const mmenuApi = mmenu.API;
2358        const viewports = document.getElementsByName('viewport');
2359
2360        if (viewports.length !== 0 && settings.modifyViewport) {
2361          const viewportMeta = viewports[0];
2362          const defaultViewport = viewports[0].content;
2363          const staticViewport = "width=device-width, initial-scale=1.0, minimum-scale=1.0";
2364
2365          mmenuApi.bind('open:start', function () {
2366            viewportMeta.setAttribute('content', staticViewport);
2367          });
2368          mmenuApi.bind('close:start', function () {
2369            viewportMeta.setAttribute('content', defaultViewport);
2370          });
2371        }
2372      });
2373    }
2374  };
2375})(jQuery);
2376;
2377(function ($) {
2378
2379    'use strict';
2380
2381    Drupal.behaviors.timeline = {
2382        attach: function (context, settings) {
2383
2384            var $timeline_block = $('.cd-timeline-block');
2385
2386            $('main .cd-timeline-block', context).once('timeline').each(function(){
2387                console.log($(this));
2388
2389                //hide any timeline blocks that are outside of the viewport
2390                if($(this).offset().top > $(window).scrollTop()+$(window).height()*0.75) {
2391                    $(this).find('.cd-timeline-img, .cd-timeline-content').addClass('is-hidden');
2392                }
2393
2394                //on scrolling, show/animate the timeline blocks as they enter the viewport
2395                $(window).on('scroll', function(){
2396                    $timeline_block.each(function(){
2397                        if( $(this).offset().top <= $(window).scrollTop()+$(window).height()*0.75 && $(this).find('.cd-timeline-img').hasClass('is-hidden') ) {
2398                            $(this).find('.cd-timeline-img, .cd-timeline-content').removeClass('is-hidden').addClass('bounce-in');
2399                        }
2400                    });
2401                });
2402            });
2403        }
2404    };
2405})(jQuery);;
2406(function ($, undefined) {
2407    $(document).ready(function () {
2408        var
2409            selectors       = {
2410                tabGroups:  '.paragraph--type--bp-accordion',
2411                tabLinks:   '.panel-title',
2412            }
2413            ;
2414        // Iterate through each accordion group...
2415        $(selectors.tabGroups).each(function () {
2416            var
2417                tabGroup    = this
2418            tabId       = tabGroup.id
2419            ;
2420            // Iterate through all links in accordion group...
2421            counter = 0;
2422            $(selectors.tabLinks, tabGroup).each(function () {
2423
2424                /**
2425                 * Get this tab's href, which matches the ID of one of the panes
2426                 * in this accordion group. Craft a new, unique href/id based on
2427                 * the current group's id, then re-assign href and ID accordingly.
2428                 * This ensures that each accordion group gets a uniquely named
2429                 * set of matching accordions/panes per group.
2430                 */
2431
2432                var
2433                    href            = $('> a', this).attr('href'),
2434                    newHref         = tabId+'-'+counter,
2435                    linkedContent   = $(href, tabGroup)
2436                    ;
2437                $('> a', this).attr('href', '#'+newHref)
2438                $(linkedContent).each(function () {
2439                    this.id = newHref;
2440                })
2441                counter++;
2442            });
2443        });
2444    });
2445})(jQuery);;
2446var timeOut;
2447function scrollToTop() {
2448    if (document.body.scrollTop!=0 || document.documentElement.scrollTop!=0){
2449        window.scrollBy(0,-50);
2450        timeOut=setTimeout('scrollToTop()',10);
2451    }
2452    else clearTimeout(timeOut);
2453};
2454/**
2455 * @file
2456 * External links js file.
2457 */
2458
2459(function ($, Drupal, drupalSettings) {
2460
2461  'use strict';
2462
2463  Drupal.extlink = Drupal.extlink || {};
2464
2465  Drupal.extlink.attach = function (context, drupalSettings) {
2466    if (typeof drupalSettings.data === 'undefined' || !drupalSettings.data.hasOwnProperty('extlink')) {
2467      return;
2468    }
2469
2470    // Define the jQuery method (either 'append' or 'prepend') of placing the
2471    // icon, defaults to 'append'.
2472    var extIconPlacement = 'append';
2473    if (drupalSettings.data.extlink.extIconPlacement && drupalSettings.data.extlink.extIconPlacement != '0') {
2474          extIconPlacement = drupalSettings.data.extlink.extIconPlacement;
2475        }
2476
2477    // Strip the host name down, removing ports, subdomains, or www.
2478    var pattern = /^(([^\/:]+?\.)*)([^\.:]{1,})((\.[a-z0-9]{1,253})*)(:[0-9]{1,5})?$/;
2479    var host = window.location.host.replace(pattern, '$2$3$6');
2480    var subdomain = window.location.host.replace(host, '');
2481
2482    // Determine what subdomains are considered internal.
2483    var subdomains;
2484    if (drupalSettings.data.extlink.extSubdomains) {
2485      subdomains = '([^/]*\\.)?';
2486    }
2487    else if (subdomain === 'www.' || subdomain === '') {
2488      subdomains = '(www\\.)?';
2489    }
2490    else {
2491      subdomains = subdomain.replace('.', '\\.');
2492    }
2493
2494    // Whitelisted domains.
2495    var whitelistedDomains = false;
2496    if (drupalSettings.data.extlink.whitelistedDomains) {
2497      whitelistedDomains = [];
2498      for (var i = 0; i < drupalSettings.data.extlink.whitelistedDomains.length; i++) {
2499        whitelistedDomains.push(new RegExp('^https?:\\/\\/' + drupalSettings.data.extlink.whitelistedDomains[i].replace(/(\r\n|\n|\r)/gm,'') + '.*$', 'i'));
2500      }
2501    }
2502
2503    // Build regular expressions that define an internal link.
2504    var internal_link = new RegExp('^https?://([^@]*@)?' + subdomains + host, 'i');
2505
2506    // Extra internal link matching.
2507    var extInclude = false;
2508    if (drupalSettings.data.extlink.extInclude) {
2509      extInclude = new RegExp(drupalSettings.data.extlink.extInclude.replace(/\\/, '\\'), 'i');
2510    }
2511
2512    // Extra external link matching.
2513    var extExclude = false;
2514    if (drupalSettings.data.extlink.extExclude) {
2515      extExclude = new RegExp(drupalSettings.data.extlink.extExclude.replace(/\\/, '\\'), 'i');
2516    }
2517
2518    // Extra external link CSS selector exclusion.
2519    var extCssExclude = false;
2520    if (drupalSettings.data.extlink.extCssExclude) {
2521      extCssExclude = drupalSettings.data.extlink.extCssExclude;
2522    }
2523
2524    // Extra external link CSS selector explicit.
2525    var extCssExplicit = false;
2526    if (drupalSettings.data.extlink.extCssExplicit) {
2527      extCssExplicit = drupalSettings.data.extlink.extCssExplicit;
2528    }
2529
2530    // Find all links which are NOT internal and begin with http as opposed
2531    // to ftp://, javascript:, etc. other kinds of links.
2532    // When operating on the 'this' variable, the host has been appended to
2533    // all links by the browser, even local ones.
2534    // In jQuery 1.1 and higher, we'd use a filter method here, but it is not
2535    // available in jQuery 1.0 (Drupal 5 default).
2536    var external_links = [];
2537    var mailto_links = [];
2538    $('a:not([data-extlink]), area:not([data-extlink])', context).each(function (el) {
2539      try {
2540        var url = '';
2541        if (typeof this.href == 'string') {
2542          url = this.href.toLowerCase();
2543        }
2544        // Handle SVG links (xlink:href).
2545        else if (typeof this.href == 'object') {
2546          url = this.href.baseVal;
2547        }
2548        if (url.indexOf('http') === 0
2549          && ((!internal_link.test(url) && !(extExclude && extExclude.test(url))) || (extInclude && extInclude.test(url)))
2550          && !(extCssExclude && $(this).is(extCssExclude))
2551          && !(extCssExclude && $(this).parents(extCssExclude).length > 0)
2552          && !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) {
2553          var match = false;
2554          if (whitelistedDomains) {
2555            for (var i = 0; i < whitelistedDomains.length; i++) {
2556              if (whitelistedDomains[i].test(url)) {
2557                match = true;
2558                break;
2559              }
2560            }
2561          }
2562          if (!match) {
2563            external_links.push(this);
2564          }
2565        }
2566        // Do not include area tags with begin with mailto: (this prohibits
2567        // icons from being added to image-maps).
2568        else if (this.tagName !== 'AREA'
2569          && url.indexOf('mailto:') === 0
2570          && !(extCssExclude && $(this).parents(extCssExclude).length > 0)
2571          && !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) {
2572          mailto_links.push(this);
2573        }
2574      }
2575      // IE7 throws errors often when dealing with irregular links, such as:
2576      // <a href="node/10"></a> Empty tags.
2577      // <a href="http://user:[email protected]">example</a> User:pass syntax.
2578      catch (error) {
2579        return false;
2580      }
2581    });
2582
2583    if (drupalSettings.data.extlink.extClass !== '0' && drupalSettings.data.extlink.extClass !== '') {
2584      Drupal.extlink.applyClassAndSpan(external_links, drupalSettings.data.extlink.extClass, extIconPlacement);
2585    }
2586
2587    if (drupalSettings.data.extlink.mailtoClass !== '0' && drupalSettings.data.extlink.mailtoClass !== '') {
2588      Drupal.extlink.applyClassAndSpan(mailto_links, drupalSettings.data.extlink.mailtoClass, extIconPlacement);
2589    }
2590
2591    if (drupalSettings.data.extlink.extTarget) {
2592      // Apply the target attribute to all links.
2593      $(external_links).filter(function () {
2594        // Filter out links with target set if option specified.
2595        return !(drupalSettings.data.extlink.extTargetNoOverride && $(this).is('a[target]'));
2596      }).attr({target: '_blank'});
2597
2598      // Add noopener rel attribute to combat phishing.
2599      $(external_links).attr('rel', function (i, val) {
2600        // If no rel attribute is present, create one with the value noopener.
2601        if (val === null || typeof val === 'undefined') {
2602          return 'noopener';
2603        }
2604        // Check to see if rel contains noopener. Add what doesn't exist.
2605        if (val.indexOf('noopener') > -1) {
2606          if (val.indexOf('noopener') === -1) {
2607            return val + ' noopener';
2608          }
2609          // Noopener exists. Nothing needs to be added.
2610          else {
2611            return val;
2612          }
2613        }
2614        // Else, append noopener to val.
2615        else {
2616          return val + ' noopener';
2617        }
2618      });
2619    }
2620
2621    if (drupalSettings.data.extlink.extNofollow) {
2622      $(external_links).attr('rel', function (i, val) {
2623        // When the link does not have a rel attribute set it to 'nofollow'.
2624        if (val === null || typeof val === 'undefined') {
2625          return 'nofollow';
2626        }
2627        var target = 'nofollow';
2628        // Change the target, if not overriding follow.
2629        if (drupalSettings.data.extlink.extFollowNoOverride) {
2630          target = 'follow';
2631        }
2632        if (val.indexOf(target) === -1) {
2633          return val + ' nofollow';
2634        }
2635        return val;
2636      });
2637    }
2638
2639    if (drupalSettings.data.extlink.extNoreferrer) {
2640      $(external_links).attr('rel', function (i, val) {
2641        // When the link does not have a rel attribute set it to 'noreferrer'.
2642        if (val === null || typeof val === 'undefined') {
2643          return 'noreferrer';
2644        }
2645        if (val.indexOf('noreferrer') === -1) {
2646          return val + ' noreferrer';
2647        }
2648        return val;
2649      });
2650    }
2651
2652    Drupal.extlink = Drupal.extlink || {};
2653
2654    // Set up default click function for the external links popup. This should be
2655    // overridden by modules wanting to alter the popup.
2656    Drupal.extlink.popupClickHandler = Drupal.extlink.popupClickHandler || function () {
2657      if (drupalSettings.data.extlink.extAlert) {
2658        return confirm(drupalSettings.data.extlink.extAlertText);
2659      }
2660    };
2661
2662    $(external_links).off("click.extlink");
2663    $(external_links).on("click.extlink", function (e) {
2664      return Drupal.extlink.popupClickHandler(e, this);
2665    });
2666  };
2667
2668  /**
2669   * Apply a class and a trailing <span> to all links not containing images.
2670   *
2671   * @param {object[]} links
2672   *   An array of DOM elements representing the links.
2673   * @param {string} class_name
2674   *   The class to apply to the links.
2675   * @param {string} icon_placement
2676   *   'append' or 'prepend' the icon to the link.
2677   */
2678  Drupal.extlink.applyClassAndSpan = function (links, class_name, icon_placement) {
2679    var $links_to_process;
2680    if (drupalSettings.data.extlink.extImgClass) {
2681      $links_to_process = $(links);
2682    }
2683    else {
2684      var links_with_images = $(links).find('img, svg').parents('a');
2685      $links_to_process = $(links).not(links_with_images);
2686    }
2687
2688    if (class_name !== '0') {
2689      $links_to_process.addClass(class_name);
2690    }
2691
2692    // Add data-extlink attribute.
2693    $links_to_process.attr('data-extlink', '');
2694
2695    var i;
2696    var length = $links_to_process.length;
2697    for (i = 0; i < length; i++) {
2698      var $link = $($links_to_process[i]);
2699      if (drupalSettings.data.extlink.extUseFontAwesome) {
2700        if (class_name === drupalSettings.data.extlink.mailtoClass) {
2701          $link[icon_placement]('<span class="fa-' + class_name + ' extlink"><span class="' + drupalSettings.data.extlink.extFaMailtoClasses + '" aria-label="' + drupalSettings.data.extlink.mailtoLabel + '"></span></span>');
2702        }
2703        else {
2704          $link[icon_placement]('<span class="fa-' + class_name + ' extlink"><span class="' + drupalSettings.data.extlink.extFaLinkClasses + '" aria-label="' + drupalSettings.data.extlink.extLabel + '"></span></span>');
2705        }
2706      }
2707      else {
2708        if (class_name === drupalSettings.data.extlink.mailtoClass) {
2709          $link[icon_placement]('<svg focusable="false" class="' + class_name + '" role="img" aria-label="' + drupalSettings.data.extlink.mailtoLabel + '" xmlns="http://www.w3.org/2000/svg" viewBox="0 10 70 20"><metadata><sfw xmlns="http://ns.adobe.com/SaveForWeb/1.0/"><sliceSourceBounds y="-8160" x="-8165" width="16389" height="16384" bottomLeftOrigin="true"/><optimizationSettings><targetSettings targetSettingsID="0" fileFormat="PNG24Format"><PNG24Format transparency="true" filtered="false" interlaced="false" noMatteColor="false" matteColor="#FFFFFF"/></targetSettings></optimizationSettings></sfw></metadata><title>' + drupalSettings.data.extlink.mailtoLabel + '</title><path d="M56 14H8c-1.1 0-2 0.9-2 2v32c0 1.1 0.9 2 2 2h48c1.1 0 2-0.9 2-2V16C58 14.9 57.1 14 56 14zM50.5 18L32 33.4 13.5 18H50.5zM10 46V20.3l20.7 17.3C31.1 37.8 31.5 38 32 38s0.9-0.2 1.3-0.5L54 20.3V46H10z"/></svg>');
2710        }
2711        else {
2712          $link[icon_placement]('<svg focusable="false" class="' + class_name + '" role="img" aria-label="' + drupalSettings.data.extlink.extLabel + '" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 40"><metadata><sfw xmlns="http://ns.adobe.com/SaveForWeb/1.0/"><sliceSourceBounds y="-8160" x="-8165" width="16389" height="16384" bottomLeftOrigin="true"/><optimizationSettings><targetSettings targetSettingsID="0" fileFormat="PNG24Format"><PNG24Format transparency="true" filtered="false" interlaced="false" noMatteColor="false" matteColor="#FFFFFF"/></targetSettings></optimizationSettings></sfw></metadata><title>' + drupalSettings.data.extlink.extLabel + '</title><path d="M48 26c-1.1 0-2 0.9-2 2v26H10V18h26c1.1 0 2-0.9 2-2s-0.9-2-2-2H8c-1.1 0-2 0.9-2 2v40c0 1.1 0.9 2 2 2h40c1.1 0 2-0.9 2-2V28C50 26.9 49.1 26 48 26z"/><path d="M56 6H44c-1.1 0-2 0.9-2 2s0.9 2 2 2h7.2L30.6 30.6c-0.8 0.8-0.8 2 0 2.8C31 33.8 31.5 34 32 34s1-0.2 1.4-0.6L54 12.8V20c0 1.1 0.9 2 2 2s2-0.9 2-2V8C58 6.9 57.1 6 56 6z"/></svg>');
2713        }
2714      }
2715    }
2716  };
2717
2718  Drupal.behaviors.extlink = Drupal.behaviors.extlink || {};
2719  Drupal.behaviors.extlink.attach = function (context, drupalSettings) {
2720    // Backwards compatibility, for the benefit of modules overriding extlink
2721    // functionality by defining an "extlinkAttach" global function.
2722    if (typeof extlinkAttach === 'function') {
2723      extlinkAttach(context);
2724    }
2725    else {
2726      Drupal.extlink.attach(context, drupalSettings);
2727    }
2728  };
2729
2730})(jQuery, Drupal, drupalSettings);
2731;
2732/**
2733 * @file
2734 * Webform behaviors.
2735 */
2736
2737(function ($, Drupal) {
2738
2739  'use strict';
2740
2741  // Trigger Drupal's attaching of behaviors after the page is
2742  // completely loaded.
2743  // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button
2744  // @see https://stackoverflow.com/questions/20899274/how-to-refresh-page-on-back-button-click/20899422#20899422
2745  var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase()));
2746  if (isChrome) {
2747    // Track back button in navigation.
2748    // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button
2749    var backButton = false;
2750    if (window.performance) {
2751      var navEntries = window.performance.getEntriesByType('navigation');
2752      if (navEntries.length > 0 && navEntries[0].type === 'back_forward') {
2753        backButton = true;
2754      }
2755      else if (window.performance.navigation
2756        && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) {
2757        backButton = true;
2758      }
2759    }
2760
2761    // If the back button is pressed, delay Drupal's attaching of behaviors.
2762    if (backButton) {
2763      var attachBehaviors = Drupal.attachBehaviors;
2764      Drupal.attachBehaviors = function (context, settings) {
2765        setTimeout(function (context, settings) {
2766          attachBehaviors(context, settings);
2767        }, 300);
2768      };
2769    }
2770  }
2771
2772})(jQuery, Drupal);
2773;
2774/**
2775* DO NOT EDIT THIS FILE.
2776* See the following change record for more information,
2777* https://www.drupal.org/node/2815083
2778* @preserve
2779**/
2780(function ($, Drupal) {
2781  var states = {
2782    postponed: []
2783  };
2784  Drupal.states = states;
2785  function invert(a, invertState) {
2786    return invertState && typeof a !== 'undefined' ? !a : a;
2787  }
2788  function _compare2(a, b) {
2789    if (a === b) {
2790      return typeof a === 'undefined' ? a : true;
2791    }
2792    return typeof a === 'undefined' || typeof b === 'undefined';
2793  }
2794  function ternary(a, b) {
2795    if (typeof a === 'undefined') {
2796      return b;
2797    }
2798    if (typeof b === 'undefined') {
2799      return a;
2800    }
2801    return a && b;
2802  }
2803  Drupal.behaviors.states = {
2804    attach: function attach(context, settings) {
2805      var $states = $(context).find('[data-drupal-states]');
2806      var il = $states.length;
2807      var _loop = function _loop(i) {
2808        var config = JSON.parse($states[i].getAttribute('data-drupal-states'));
2809        Object.keys(config || {}).forEach(function (state) {
2810          new states.Dependent({
2811            element: $($states[i]),
2812            state: states.State.sanitize(state),
2813            constraints: config[state]
2814          });
2815        });
2816      };
2817      for (var i = 0; i < il; i++) {
2818        _loop(i);
2819      }
2820      while (states.postponed.length) {
2821        states.postponed.shift()();
2822      }
2823    }
2824  };
2825  states.Dependent = function (args) {
2826    var _this = this;
2827    $.extend(this, {
2828      values: {},
2829      oldValue: null
2830    }, args);
2831    this.dependees = this.getDependees();
2832    Object.keys(this.dependees || {}).forEach(function (selector) {
2833      _this.initializeDependee(selector, _this.dependees[selector]);
2834    });
2835  };
2836  states.Dependent.comparisons = {
2837    RegExp: function RegExp(reference, value) {
2838      return reference.test(value);
2839    },
2840    Function: function Function(reference, value) {
2841      return reference(value);
2842    },
2843    Number: function Number(reference, value) {
2844      return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value);
2845    }
2846  };
2847  states.Dependent.prototype = {
2848    initializeDependee: function initializeDependee(selector, dependeeStates) {
2849      var _this2 = this;
2850      this.values[selector] = {};
2851      Object.keys(dependeeStates).forEach(function (i) {
2852        var state = dependeeStates[i];
2853        if ($.inArray(state, dependeeStates) === -1) {
2854          return;
2855        }
2856        state = states.State.sanitize(state);
2857        _this2.values[selector][state.name] = null;
2858        $(selector).on("state:".concat(state), {
2859          selector: selector,
2860          state: state
2861        }, function (e) {
2862          _this2.update(e.data.selector, e.data.state, e.value);
2863        });
2864        new states.Trigger({
2865          selector: selector,
2866          state: state
2867        });
2868      });
2869    },
2870    compare: function compare(reference, selector, state) {
2871      var value = this.values[selector][state.name];
2872      if (reference.constructor.name in states.Dependent.comparisons) {
2873        return states.Dependent.comparisons[reference.constructor.name](reference, value);
2874      }
2875      return _compare2(reference, value);
2876    },
2877    update: function update(selector, state, value) {
2878      if (value !== this.values[selector][state.name]) {
2879        this.values[selector][state.name] = value;
2880        this.reevaluate();
2881      }
2882    },
2883    reevaluate: function reevaluate() {
2884      var value = this.verifyConstraints(this.constraints);
2885      if (value !== this.oldValue) {
2886        this.oldValue = value;
2887        value = invert(value, this.state.invert);
2888        this.element.trigger({
2889          type: "state:".concat(this.state),
2890          value: value,
2891          trigger: true
2892        });
2893      }
2894    },
2895    verifyConstraints: function verifyConstraints(constraints, selector) {
2896      var result;
2897      if ($.isArray(constraints)) {
2898        var hasXor = $.inArray('xor', constraints) === -1;
2899        var len = constraints.length;
2900        for (var i = 0; i < len; i++) {
2901          if (constraints[i] !== 'xor') {
2902            var constraint = this.checkConstraints(constraints[i], selector, i);
2903            if (constraint && (hasXor || result)) {
2904              return hasXor;
2905            }
2906            result = result || constraint;
2907          }
2908        }
2909      } else if ($.isPlainObject(constraints)) {
2910        for (var n in constraints) {
2911          if (constraints.hasOwnProperty(n)) {
2912            result = ternary(result, this.checkConstraints(constraints[n], selector, n));
2913            if (result === false) {
2914              return false;
2915            }
2916          }
2917        }
2918      }
2919      return result;
2920    },
2921    checkConstraints: function checkConstraints(value, selector, state) {
2922      if (typeof state !== 'string' || /[0-9]/.test(state[0])) {
2923        state = null;
2924      } else if (typeof selector === 'undefined') {
2925        selector = state;
2926        state = null;
2927      }
2928      if (state !== null) {
2929        state = states.State.sanitize(state);
2930        return invert(this.compare(value, selector, state), state.invert);
2931      }
2932      return this.verifyConstraints(value, selector);
2933    },
2934    getDependees: function getDependees() {
2935      var cache = {};
2936      var _compare = this.compare;
2937      this.compare = function (reference, selector, state) {
2938        (cache[selector] || (cache[selector] = [])).push(state.name);
2939      };
2940      this.verifyConstraints(this.constraints);
2941      this.compare = _compare;
2942      return cache;
2943    }
2944  };
2945  states.Trigger = function (args) {
2946    $.extend(this, args);
2947    if (this.state in states.Trigger.states) {
2948      this.element = $(this.selector);
2949      if (!this.element.data("trigger:".concat(this.state))) {
2950        this.initialize();
2951      }
2952    }
2953  };
2954  states.Trigger.prototype = {
2955    initialize: function initialize() {
2956      var _this3 = this;
2957      var trigger = states.Trigger.states[this.state];
2958      if (typeof trigger === 'function') {
2959        trigger.call(window, this.element);
2960      } else {
2961        Object.keys(trigger || {}).forEach(function (event) {
2962          _this3.defaultTrigger(event, trigger[event]);
2963        });
2964      }
2965      this.element.data("trigger:".concat(this.state), true);
2966    },
2967    defaultTrigger: function defaultTrigger(event, valueFn) {
2968      var oldValue = valueFn.call(this.element);
2969      this.element.on(event, $.proxy(function (e) {
2970        var value = valueFn.call(this.element, e);
2971        if (oldValue !== value) {
2972          this.element.trigger({
2973            type: "state:".concat(this.state),
2974            value: value,
2975            oldValue: oldValue
2976          });
2977          oldValue = value;
2978        }
2979      }, this));
2980      states.postponed.push($.proxy(function () {
2981        this.element.trigger({
2982          type: "state:".concat(this.state),
2983          value: oldValue,
2984          oldValue: null
2985        });
2986      }, this));
2987    }
2988  };
2989  states.Trigger.states = {
2990    empty: {
2991      keyup: function keyup() {
2992        return this.val() === '';
2993      },
2994      change: function change() {
2995        return this.val() === '';
2996      }
2997    },
2998    checked: {
2999      change: function change() {
3000        var checked = false;
3001        this.each(function () {
3002          checked = $(this).prop('checked');
3003          return !checked;
3004        });
3005        return checked;
3006      }
3007    },
3008    value: {
3009      keyup: function keyup() {
3010        if (this.length > 1) {
3011          return this.filter(':checked').val() || false;
3012        }
3013        return this.val();
3014      },
3015      change: function change() {
3016        if (this.length > 1) {
3017          return this.filter(':checked').val() || false;
3018        }
3019        return this.val();
3020      }
3021    },
3022    collapsed: {
3023      collapsed: function collapsed(e) {
3024        return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]');
3025      }
3026    }
3027  };
3028  states.State = function (state) {
3029    this.pristine = state;
3030    this.name = state;
3031    var process = true;
3032    do {
3033      while (this.name.charAt(0) === '!') {
3034        this.name = this.name.substring(1);
3035        this.invert = !this.invert;
3036      }
3037      if (this.name in states.State.aliases) {
3038        this.name = states.State.aliases[this.name];
3039      } else {
3040        process = false;
3041      }
3042    } while (process);
3043  };
3044  states.State.sanitize = function (state) {
3045    if (state instanceof states.State) {
3046      return state;
3047    }
3048    return new states.State(state);
3049  };
3050  states.State.aliases = {
3051    enabled: '!disabled',
3052    invisible: '!visible',
3053    invalid: '!valid',
3054    untouched: '!touched',
3055    optional: '!required',
3056    filled: '!empty',
3057    unchecked: '!checked',
3058    irrelevant: '!relevant',
3059    expanded: '!collapsed',
3060    open: '!collapsed',
3061    closed: 'collapsed',
3062    readwrite: '!readonly'
3063  };
3064  states.State.prototype = {
3065    invert: false,
3066    toString: function toString() {
3067      return this.name;
3068    }
3069  };
3070  var $document = $(document);
3071  $document.on('state:disabled', function (e) {
3072    if (e.trigger) {
3073      $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value).find('select, input, textarea').prop('disabled', e.value);
3074    }
3075  });
3076  $document.on('state:required', function (e) {
3077    if (e.trigger) {
3078      if (e.value) {
3079        var label = "label".concat(e.target.id ? "[for=".concat(e.target.id, "]") : '');
3080        var $label = $(e.target).attr({
3081          required: 'required',
3082          'aria-required': 'true'
3083        }).closest('.js-form-item, .js-form-wrapper').find(label);
3084        if (!$label.hasClass('js-form-required').length) {
3085          $label.addClass('js-form-required form-required');
3086        }
3087      } else {
3088        $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required');
3089      }
3090    }
3091  });
3092  $document.on('state:visible', function (e) {
3093    if (e.trigger) {
3094      $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value);
3095    }
3096  });
3097  $document.on('state:checked', function (e) {
3098    if (e.trigger) {
3099      $(e.target).closest('.js-form-item, .js-form-wrapper').find('input').prop('checked', e.value).trigger('change');
3100    }
3101  });
3102  $document.on('state:collapsed', function (e) {
3103    if (e.trigger) {
3104      if ($(e.target).is('[open]') === e.value) {
3105        $(e.target).find('> summary').trigger('click');
3106      }
3107    }
3108  });
3109})(jQuery, Drupal);;
3110/**
3111 * @file
3112 * Extends core/misc/states.js.
3113 */
3114(function($) {
3115
3116  // Unbind core state.js from document first so we can then override below.
3117  $(document).unbind('state:disabled');
3118
3119  /**
3120   * Global state change handlers. These are bound to "document" to cover all
3121   * elements whose state changes. Events sent to elements within the page
3122   * bubble up to these handlers. We use this system so that themes and modules
3123   * can override these state change handlers for particular parts of a page.
3124   */
3125  $(document).bind('state:disabled', function(e) {
3126    // Only act when this change was triggered by a dependency and not by the
3127    // element monitoring itself.
3128    if (e.trigger) {
3129      $(e.target)
3130        .attr('disabled', e.value)
3131        .closest('.form-item, .form-submit, .form-wrapper').toggleClass('form-disabled', e.value)
3132        .find(':input').attr('disabled', e.value);
3133
3134      // Note: WebKit nightlies don't reflect that change correctly.
3135      // See https://bugs.webkit.org/show_bug.cgi?id=23789
3136    }
3137  });
3138
3139})(jQuery);
3140;
3141/**
3142 * @file
3143 * JavaScript behaviors for custom webform #states.
3144 */
3145
3146(function ($, Drupal) {
3147
3148  'use strict';
3149
3150  Drupal.webform = Drupal.webform || {};
3151  Drupal.webform.states = Drupal.webform.states || {};
3152  Drupal.webform.states.slideDown = Drupal.webform.states.slideDown || {};
3153  Drupal.webform.states.slideDown.duration = 'slow';
3154  Drupal.webform.states.slideUp = Drupal.webform.states.slideUp || {};
3155  Drupal.webform.states.slideUp.duration = 'fast';
3156
3157  /* ************************************************************************ */
3158  // jQuery functions.
3159  /* ************************************************************************ */
3160
3161  /**
3162   * Check if an element has a specified data attribute.
3163   *
3164   * @param {string} data
3165   *   The data attribute name.
3166   *
3167   * @return {boolean}
3168   *   TRUE if an element has a specified data attribute.
3169   */
3170  $.fn.hasData = function (data) {
3171    return (typeof this.data(data) !== 'undefined');
3172  };
3173
3174  /**
3175   * Check if element is within the webform or not.
3176   *
3177   * @return {boolean}
3178   *   TRUE if element is within the webform.
3179   */
3180  $.fn.isWebform = function () {
3181    return $(this).closest('form.webform-submission-form, form[id^="webform"], form[data-is-webform]').length ? true : false;
3182  };
3183
3184  /**
3185   * Check if element is to be treated as a webform element.
3186   *
3187   * @return {boolean}
3188   *   TRUE if element is to be treated as a webform element.
3189   */
3190  $.fn.isWebformElement = function () {
3191    return ($(this).isWebform() || $(this).closest('[data-is-webform-element]').length) ? true : false;
3192  };
3193
3194  /* ************************************************************************ */
3195  // Trigger.
3196  /* ************************************************************************ */
3197
3198  // The change event is triggered by cut-n-paste and select menus.
3199  // Issue #2445271: #states element empty check not triggered on mouse
3200  // based paste.
3201  // @see https://www.drupal.org/node/2445271
3202  Drupal.states.Trigger.states.empty.change = function change() {
3203    return this.val() === '';
3204  };
3205
3206  /* ************************************************************************ */
3207  // Dependents.
3208  /* ************************************************************************ */
3209
3210  // Apply solution included in #1962800 patch.
3211  // Issue #1962800: Form #states not working with literal integers as
3212  // values in IE11.
3213  // @see https://www.drupal.org/project/drupal/issues/1962800
3214  // @see https://www.drupal.org/files/issues/core-states-not-working-with-integers-ie11_1962800_46.patch
3215  //
3216  // This issue causes pattern, less than, and greater than support to break.
3217  // @see https://www.drupal.org/project/webform/issues/2981724
3218  var states = Drupal.states;
3219  Drupal.states.Dependent.prototype.compare = function compare(reference, selector, state) {
3220    var value = this.values[selector][state.name];
3221
3222    var name = reference.constructor.name;
3223    if (!name) {
3224      name = $.type(reference);
3225
3226      name = name.charAt(0).toUpperCase() + name.slice(1);
3227    }
3228    if (name in states.Dependent.comparisons) {
3229      return states.Dependent.comparisons[name](reference, value);
3230    }
3231
3232    if (reference.constructor.name in states.Dependent.comparisons) {
3233      return states.Dependent.comparisons[reference.constructor.name](reference, value);
3234    }
3235
3236    return _compare2(reference, value);
3237  };
3238  function _compare2(a, b) {
3239    if (a === b) {
3240      return typeof a === 'undefined' ? a : true;
3241    }
3242
3243    return typeof a === 'undefined' || typeof b === 'undefined';
3244  }
3245
3246  // Adds pattern, less than, and greater than support to #state API.
3247  // @see http://drupalsun.com/julia-evans/2012/03/09/extending-form-api-states-regular-expressions
3248  Drupal.states.Dependent.comparisons.Object = function (reference, value) {
3249    if ('pattern' in reference) {
3250      return (new RegExp(reference['pattern'])).test(value);
3251    }
3252    else if ('!pattern' in reference) {
3253      return !((new RegExp(reference['!pattern'])).test(value));
3254    }
3255    else if ('less' in reference) {
3256      return (value !== '' && parseFloat(reference['less']) > parseFloat(value));
3257    }
3258    else if ('less_equal' in reference) {
3259      return (value !== '' && parseFloat(reference['less_equal']) >= parseFloat(value));
3260    }
3261    else if ('greater' in reference) {
3262      return (value !== '' && parseFloat(reference['greater']) < parseFloat(value));
3263    }
3264    else if ('greater_equal' in reference) {
3265      return (value !== '' && parseFloat(reference['greater_equal']) <= parseFloat(value));
3266    }
3267    else if ('between' in reference || '!between' in reference) {
3268      if (value === '') {
3269        return false;
3270      }
3271
3272      var between = reference['between'] || reference['!between'];
3273      var betweenParts = between.split(':');
3274      var greater = betweenParts[0];
3275      var less = (typeof betweenParts[1] !== 'undefined') ? betweenParts[1] : null;
3276      var isGreaterThan = (greater === null || greater === '' || parseFloat(value) >= parseFloat(greater));
3277      var isLessThan = (less === null || less === '' || parseFloat(value) <= parseFloat(less));
3278      var result = (isGreaterThan && isLessThan);
3279      return (reference['!between']) ? !result : result;
3280    }
3281    else {
3282      return reference.indexOf(value) !== false;
3283    }
3284  };
3285
3286  /* ************************************************************************ */
3287  // States events.
3288  /* ************************************************************************ */
3289
3290  var $document = $(document);
3291
3292  $document.on('state:required', function (e) {
3293    if (e.trigger && $(e.target).isWebformElement()) {
3294      var $target = $(e.target);
3295      // Fix #required file upload.
3296      // @see Issue #2860529: Conditional required File upload field don't work.
3297      toggleRequired($target.find('input[type="file"]'), e.value);
3298
3299      // Fix #required for radios and likert.
3300      // @see Issue #2856795: If radio buttons are required but not filled form is nevertheless submitted.
3301      if ($target.is('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other, .js-webform-type-webform-entity-radios, .webform-likert-table')) {
3302        $target.toggleClass('required', e.value);
3303        toggleRequired($target.find('input[type="radio"]'), e.value);
3304      }
3305
3306      // Fix #required for checkboxes.
3307      // @see Issue #2938414: Checkboxes don't support #states required.
3308      // @see checkboxRequiredhandler
3309      if ($target.is('.js-form-type-checkboxes, .js-form-type-webform-checkboxes-other, .js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other')) {
3310        $target.toggleClass('required', e.value);
3311        var $checkboxes = $target.find('input[type="checkbox"]');
3312        if (e.value) {
3313          // Add event handler.
3314          $checkboxes.on('click', statesCheckboxesRequiredEventHandler);
3315          // Initialize and add required attribute.
3316          checkboxesRequired($target);
3317        }
3318        else {
3319          // Remove event handler.
3320          $checkboxes.off('click', statesCheckboxesRequiredEventHandler);
3321          // Remove required attribute.
3322          toggleRequired($checkboxes, false);
3323        }
3324      }
3325
3326      // Fix #required for tableselect.
3327      // @see Issue #3212581: Table select does not trigger client side validation
3328      if ($target.is('.js-webform-tableselect')) {
3329        $target.toggleClass('required', e.value);
3330        var isMultiple = $target.is('[multiple]');
3331        if (isMultiple) {
3332          // Checkboxes.
3333          var $tbody = $target.find('tbody');
3334          var $checkboxes = $tbody.find('input[type="checkbox"]');
3335          copyRequireMessage($target, $checkboxes);
3336          if (e.value) {
3337            $checkboxes.on('click change', statesCheckboxesRequiredEventHandler);
3338            checkboxesRequired($tbody);
3339          }
3340          else {
3341            $checkboxes.off('click change ', statesCheckboxesRequiredEventHandler);
3342            toggleRequired($tbody, false);
3343          }
3344        }
3345        else {
3346          // Radios.
3347          var $radios = $target.find('input[type="radio"]');
3348          copyRequireMessage($target, $radios);
3349          toggleRequired($radios, e.value);
3350        }
3351      }
3352
3353      // Fix required label for elements without the for attribute.
3354      // @see Issue #3145300: Conditional Visible Select Other not working.
3355      if ($target.is('.js-form-type-webform-select-other, .js-webform-type-webform-select-other')) {
3356        var $select = $target.find('select');
3357        toggleRequired($select, e.value);
3358        copyRequireMessage($target, $select);
3359      }
3360      if ($target.find('> label:not([for])').length) {
3361        $target.find('> label').toggleClass('js-form-required form-required', e.value);
3362      }
3363
3364      // Fix required label for checkboxes and radios.
3365      // @see Issue #2938414: Checkboxes don't support #states required
3366      // @see Issue #2731991: Setting required on radios marks all options required.
3367      // @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset.
3368      // Fix #required for fieldsets.
3369      // @see Issue #2977569: Hidden fieldsets that become visible with conditional logic cannot be made required.
3370      if ($target.is('.js-webform-type-radios, .js-webform-type-checkboxes, fieldset')) {
3371        $target.find('legend span.fieldset-legend:not(.visually-hidden)').toggleClass('js-form-required form-required', e.value);
3372      }
3373
3374      // Issue #2986017: Fieldsets shouldn't have required attribute.
3375      if ($target.is('fieldset')) {
3376        $target.removeAttr('required aria-required');
3377      }
3378    }
3379  });
3380
3381  $document.on('state:checked', function (e) {
3382    if (e.trigger) {
3383      $(e.target).trigger('change');
3384    }
3385  });
3386
3387  $document.on('state:readonly', function (e) {
3388    if (e.trigger && $(e.target).isWebformElement()) {
3389      $(e.target).prop('readonly', e.value).closest('.js-form-item, .js-form-wrapper').toggleClass('webform-readonly', e.value).find('input, textarea').prop('readonly', e.value);
3390
3391      // Trigger webform:readonly.
3392      $(e.target).trigger('webform:readonly')
3393        .find('select, input, textarea, button').trigger('webform:readonly');
3394    }
3395  });
3396
3397  $document.on('state:visible state:visible-slide', function (e) {
3398    if (e.trigger && $(e.target).isWebformElement()) {
3399      if (e.value) {
3400        $(':input', e.target).addBack().each(function () {
3401          restoreValueAndRequired(this);
3402          triggerEventHandlers(this);
3403        });
3404      }
3405      else {
3406        // @see https://www.sitepoint.com/jquery-function-clear-form-data/
3407        $(':input', e.target).addBack().each(function () {
3408          backupValueAndRequired(this);
3409          clearValueAndRequired(this);
3410          triggerEventHandlers(this);
3411        });
3412      }
3413    }
3414  });
3415
3416  $document.on('state:visible-slide', function (e) {
3417    if (e.trigger && $(e.target).isWebformElement()) {
3418      var effect = e.value ? 'slideDown' : 'slideUp';
3419      var duration = Drupal.webform.states[effect].duration;
3420      $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper')[effect](duration);
3421    }
3422  });
3423  Drupal.states.State.aliases['invisible-slide'] = '!visible-slide';
3424
3425  $document.on('state:disabled', function (e) {
3426    if (e.trigger && $(e.target).isWebformElement()) {
3427      // Make sure disabled property is set before triggering webform:disabled.
3428      // Copied from: core/misc/states.js
3429      $(e.target)
3430        .prop('disabled', e.value)
3431        .closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value)
3432        .find('select, input, textarea, button').prop('disabled', e.value);
3433
3434      // Never disable hidden file[fids] because the existing values will
3435      // be completely lost when the webform is submitted.
3436      var fileElements = $(e.target)
3437        .find(':input[type="hidden"][name$="[fids]"]');
3438      if (fileElements.length) {
3439        // Remove 'disabled' attribute from fieldset which will block
3440        // all disabled elements from being submitted.
3441        if ($(e.target).is('fieldset')) {
3442          $(e.target).prop('disabled', false);
3443        }
3444        fileElements.removeAttr('disabled');
3445      }
3446
3447      // Trigger webform:disabled.
3448      $(e.target).trigger('webform:disabled')
3449        .find('select, input, textarea, button').trigger('webform:disabled');
3450    }
3451  });
3452
3453  /* ************************************************************************ */
3454  // Behaviors.
3455  /* ************************************************************************ */
3456
3457  /**
3458   * Adds HTML5 validation to required checkboxes.
3459   *
3460   * @type {Drupal~behavior}
3461   *
3462   * @see https://www.drupal.org/project/webform/issues/3068998
3463   */
3464  Drupal.behaviors.webformCheckboxesRequired = {
3465    attach: function (context) {
3466      $('.js-form-type-checkboxes.required, .js-form-type-webform-checkboxes-other.required, .js-webform-type-checkboxes.required, .js-webform-type-webform-checkboxes-other.required, .js-webform-type-webform-radios-other.checkboxes', context)
3467        .once('webform-checkboxes-required')
3468        .each(function () {
3469          var $element = $(this);
3470          $element.find('input[type="checkbox"]').on('click', statesCheckboxesRequiredEventHandler);
3471          setTimeout(function () {checkboxesRequired($element);});
3472        });
3473    }
3474  };
3475
3476  /**
3477   * Adds HTML5 validation to required radios.
3478   *
3479   * @type {Drupal~behavior}
3480   *
3481   * @see https://www.drupal.org/project/webform/issues/2856795
3482   */
3483  Drupal.behaviors.webformRadiosRequired = {
3484    attach: function (context) {
3485      $('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other, .js-webform-type-webform-entity-radios, .js-webform-type-webform-scale', context)
3486        .once('webform-radios-required')
3487        .each(function () {
3488          var $element = $(this);
3489          setTimeout(function () {radiosRequired($element);});
3490        });
3491    }
3492  };
3493
3494 /**
3495   * Adds HTML5 validation to required table select.
3496   *
3497   * @type {Drupal~behavior}
3498   *
3499   * @see https://www.drupal.org/project/webform/issues/2856795
3500   */
3501  Drupal.behaviors.webformTableSelectRequired = {
3502    attach: function (context) {
3503      $('.js-webform-tableselect.required', context)
3504        .once('webform-tableselect-required')
3505        .each(function () {
3506          var $element = $(this);
3507          var $tbody = $element.find('tbody');
3508          var isMultiple = $element.is('[multiple]');
3509
3510          if (isMultiple) {
3511            // Check all checkbox triggers checkbox 'change' event on
3512            // select and deselect all.
3513            // @see Drupal.tableSelect
3514            $tbody.find('input[type="checkbox"]').on('click change', function () {
3515              checkboxesRequired($tbody);
3516            });
3517          }
3518
3519          setTimeout(function () {
3520            isMultiple ? checkboxesRequired($tbody) : radiosRequired($element);
3521          });
3522        });
3523    }
3524  };
3525
3526  /**
3527   * Add HTML5 multiple checkboxes required validation.
3528   *
3529   * @param {jQuery} $element
3530   *   An jQuery object containing HTML5 radios.
3531   *
3532   * @see https://stackoverflow.com/a/37825072/145846
3533   */
3534  function checkboxesRequired($element) {
3535    var $firstCheckbox = $element.find('input[type="checkbox"]').first();
3536    var isChecked = $element.find('input[type="checkbox"]').is(':checked');
3537    toggleRequired($firstCheckbox, !isChecked);
3538    copyRequireMessage($element, $firstCheckbox);
3539  }
3540
3541  /**
3542   * Add HTML5 radios required validation.
3543   *
3544   * @param {jQuery} $element
3545   *   An jQuery object containing HTML5 radios.
3546   *
3547   * @see https://www.drupal.org/project/webform/issues/2856795
3548   */
3549  function radiosRequired($element) {
3550    var $radios = $element.find('input[type="radio"]');
3551    var isRequired = $element.hasClass('required');
3552    toggleRequired($radios, isRequired);
3553    copyRequireMessage($element, $radios);
3554  }
3555
3556  /* ************************************************************************ */
3557  // Event handlers.
3558  /* ************************************************************************ */
3559
3560  /**
3561   * Trigger #states API HTML5 multiple checkboxes required validation.
3562   *
3563   * @see https://stackoverflow.com/a/37825072/145846
3564   */
3565  function statesCheckboxesRequiredEventHandler() {
3566    var $element = $(this).closest('.js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other');
3567    checkboxesRequired($element);
3568  }
3569
3570  /**
3571   * Trigger an input's event handlers.
3572   *
3573   * @param {element} input
3574   *   An input.
3575   */
3576  function triggerEventHandlers(input) {
3577    var $input = $(input);
3578    var type = input.type;
3579    var tag = input.tagName.toLowerCase();
3580    // Add 'webform.states' as extra parameter to event handlers.
3581    // @see Drupal.behaviors.webformUnsaved
3582    var extraParameters = ['webform.states'];
3583    if (type === 'checkbox' || type === 'radio') {
3584      $input
3585        .trigger('change', extraParameters)
3586        .trigger('blur', extraParameters);
3587    }
3588    else if (tag === 'select') {
3589      // Do not trigger the onchange event for Address element's country code
3590      // when it is initialized.
3591      // @see \Drupal\address\Element\Country
3592      if ($input.closest('.webform-type-address').length) {
3593        if (!$input.data('webform-states-address-initialized')
3594          && $input.attr('autocomplete') === 'country'
3595          && $input.val() === $input.find("option[selected]").attr('value')) {
3596          return;
3597        }
3598        $input.data('webform-states-address-initialized', true);
3599      }
3600
3601      $input
3602        .trigger('change', extraParameters)
3603        .trigger('blur', extraParameters);
3604    }
3605    else if (type !== 'submit' && type !== 'button' && type !== 'file') {
3606      // Make sure input mask is removed and then reset when value is restored.
3607      // @see https://www.drupal.org/project/webform/issues/3124155
3608      // @see https://www.drupal.org/project/webform/issues/3202795
3609      var hasInputMask = ($.fn.inputmask && $input.hasClass('js-webform-input-mask'));
3610      hasInputMask && $input.inputmask('remove');
3611
3612      $input
3613        .trigger('input', extraParameters)
3614        .trigger('change', extraParameters)
3615        .trigger('keydown', extraParameters)
3616        .trigger('keyup', extraParameters)
3617        .trigger('blur', extraParameters);
3618
3619      hasInputMask && $input.inputmask();
3620    }
3621  }
3622
3623  /* ************************************************************************ */
3624  // Backup and restore value functions.
3625  /* ************************************************************************ */
3626
3627  /**
3628   * Backup an input's current value and required attribute
3629   *
3630   * @param {element} input
3631   *   An input.
3632   */
3633  function backupValueAndRequired(input) {
3634    var $input = $(input);
3635    var type = input.type;
3636    var tag = input.tagName.toLowerCase(); // Normalize case.
3637
3638    // Backup required.
3639    if ($input.prop('required') && !$input.hasData('webform-required')) {
3640      $input.data('webform-required', true);
3641    }
3642
3643    // Backup value.
3644    if (!$input.hasData('webform-value')) {
3645      if (type === 'checkbox' || type === 'radio') {
3646        $input.data('webform-value', $input.prop('checked'));
3647      }
3648      else if (tag === 'select') {
3649        var values = [];
3650        $input.find('option:selected').each(function (i, option) {
3651          values[i] = option.value;
3652        });
3653        $input.data('webform-value', values);
3654      }
3655      else if (type !== 'submit' && type !== 'button') {
3656        $input.data('webform-value', input.value);
3657      }
3658    }
3659  }
3660
3661  /**
3662   * Restore an input's value and required attribute.
3663   *
3664   * @param {element} input
3665   *   An input.
3666   */
3667  function restoreValueAndRequired(input) {
3668    var $input = $(input);
3669
3670    // Restore value.
3671    var value = $input.data('webform-value');
3672    if (typeof value !== 'undefined') {
3673      var type = input.type;
3674      var tag = input.tagName.toLowerCase(); // Normalize case.
3675
3676      if (type === 'checkbox' || type === 'radio') {
3677        $input.prop('checked', value);
3678      }
3679      else if (tag === 'select') {
3680        $.each(value, function (i, option_value) {
3681          // Prevent "Syntax error, unrecognized expression" error by
3682          // escaping single quotes.
3683          // @see https://forum.jquery.com/topic/escape-characters-prior-to-using-selector
3684          option_value = option_value.replace(/'/g, "\\\'");
3685          $input.find("option[value='" + option_value + "']").prop('selected', true);
3686        });
3687      }
3688      else if (type !== 'submit' && type !== 'button') {
3689        input.value = value;
3690      }
3691      $input.removeData('webform-value');
3692    }
3693
3694    // Restore required.
3695    var required = $input.data('webform-required');
3696    if (typeof required !== 'undefined') {
3697      if (required) {
3698        $input.prop('required', true);
3699      }
3700      $input.removeData('webform-required');
3701    }
3702  }
3703
3704  /**
3705   * Clear an input's value and required attributes.
3706   *
3707   * @param {element} input
3708   *   An input.
3709   */
3710  function clearValueAndRequired(input) {
3711    var $input = $(input);
3712
3713    // Check for #states no clear attribute.
3714    // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/
3715    if ($input.closest('[data-webform-states-no-clear]').length) {
3716      return;
3717    }
3718
3719    // Clear value.
3720    var type = input.type;
3721    var tag = input.tagName.toLowerCase(); // Normalize case.
3722    if (type === 'checkbox' || type === 'radio') {
3723      $input.prop('checked', false);
3724    }
3725    else if (tag === 'select') {
3726      if ($input.find('option[value=""]').length) {
3727        $input.val('');
3728      }
3729      else {
3730        input.selectedIndex = -1;
3731      }
3732    }
3733    else if (type !== 'submit' && type !== 'button') {
3734      input.value = (type === 'color') ? '#000000' : '';
3735    }
3736
3737    // Clear required.
3738    $input.prop('required', false);
3739  }
3740
3741  /* ************************************************************************ */
3742  // Helper functions.
3743  /* ************************************************************************ */
3744
3745  /**
3746   * Toggle an input's required attributes.
3747   *
3748   * @param {element} $input
3749   *   An input.
3750   * @param {boolean} required
3751   *   Is input required.
3752   */
3753  function toggleRequired($input, required) {
3754    var isCheckboxOrRadio = ($input.attr('type') === 'radio' || $input.attr('type') === 'checkbox');
3755    if (required) {
3756      if (isCheckboxOrRadio) {
3757        $input.attr({'required': 'required'});
3758      }
3759      else {
3760        $input.attr({'required': 'required', 'aria-required': 'true'});
3761      }
3762    }
3763    else {
3764      if (isCheckboxOrRadio) {
3765        $input.removeAttr('required');
3766      }
3767      else {
3768        $input.removeAttr('required aria-required');
3769      }
3770    }
3771  }
3772
3773  /**
3774   * Copy the clientside_validation.module's message.
3775   *
3776   * @param {jQuery} $source
3777   *   The source element.
3778   * @param {jQuery} $destination
3779   *   The destination element.
3780   */
3781  function copyRequireMessage($source, $destination) {
3782    if ($source.attr('data-msg-required')) {
3783      $destination.attr('data-msg-required', $source.attr('data-msg-required'));
3784    }
3785  }
3786
3787})(jQuery, Drupal);
3788;
3789/**
3790 * @file
3791 * JavaScript behaviors for custom webform #states.
3792 */
3793
3794(function ($, Drupal) {
3795
3796  'use strict';
3797
3798  $(document).on('state:required', function (e) {
3799    if (e.trigger && $(e.target).isWebform()) {
3800      var $target = $(e.target);
3801
3802      // @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset.
3803      // Fix #required for fieldsets.
3804      if ($target.is('.js-form-wrapper.panel')) {
3805        if (e.value) {
3806          $target.find('.panel-heading .panel-title').addClass('js-form-required form-required');
3807        }
3808        else {
3809          $target.find('.panel-heading .panel-title').removeClass('js-form-required form-required');
3810        }
3811      }
3812
3813    }
3814  });
3815
3816})(jQuery, Drupal);
3817;

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.