PageSourceSearch

https://ansahotels.com/sites/default/files/js/js_36mP5BfZi0zLy-WI2kIKaIcLHqRFiVxl6pQ2Z7TB_Eo.js

js ansahotels.com collected 2026-10-07 23:10:29 UTC 63,505 bytes, 2,111 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 * @namespace
10 */
11(function (_, $, Drupal, drupalSettings) {
12  'use strict';
13
14  var Bootstrap = {
15    processedOnce: {},
16    settings: drupalSettings.bootstrap || {}
17  };
18
19  /**
20   * Wraps Drupal.checkPlain() to ensure value passed isn't empty.
21   *
22   * Encodes special characters in a plain-text string for display as HTML.
23   *
24   * @param {string} str
25   *   The string to be encoded.
26   *
27   * @return {string}
28   *   The encoded string.
29   *
30   * @ingroup sanitization
31   */
32  Bootstrap.checkPlain = function (str) {
33    return str && Drupal.checkPlain(str) || '';
34  };
35
36  /**
37   * Creates a jQuery plugin.
38   *
39   * @param {String} id
40   *   A jQuery plugin identifier located in $.fn.
41   * @param {Function} plugin
42   *   A constructor function used to initialize the for the jQuery plugin.
43   * @param {Boolean} [noConflict]
44   *   Flag indicating whether or not to create a ".noConflict()" helper method
45   *   for the plugin.
46   */
47  Bootstrap.createPlugin = function (id, plugin, noConflict) {
48    // Immediately return if plugin doesn't exist.
49    if ($.fn[id] !== void 0) {
50      return this.fatal('Specified jQuery plugin identifier already exists: @id. Use Drupal.bootstrap.replacePlugin() instead.', {'@id': id});
51    }
52
53    // Immediately return if plugin isn't a function.
54    if (typeof plugin !== 'function') {
55      return this.fatal('You must provide a constructor function to create a jQuery plugin "@id": @plugin', {'@id': id, '@plugin':  plugin});
56    }
57
58    // Add a ".noConflict()" helper method.
59    this.pluginNoConflict(id, plugin, noConflict);
60
61    $.fn[id] = plugin;
62  };
63
64  /**
65   * Diff object properties.
66   *
67   * @param {...Object} objects
68   *   Two or more objects. The first object will be used to return properties
69   *   values.
70   *
71   * @return {Object}
72   *   Returns the properties of the first passed object that are not present
73   *   in all other passed objects.
74   */
75  Bootstrap.diffObjects = function (objects) {
76    var args = Array.prototype.slice.call(arguments);
77    return _.pick(args[0], _.difference.apply(_, _.map(args, function (obj) {
78      return Object.keys(obj);
79    })));
80  };
81
82  /**
83   * Map of supported events by regular expression.
84   *
85   * @type {Object<Event|MouseEvent|KeyboardEvent|TouchEvent,RegExp>}
86   */
87  Bootstrap.eventMap = {
88    Event: /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
89    MouseEvent: /^(?:click|dblclick|mouse(?:down|enter|leave|up|over|move|out))$/,
90    KeyboardEvent: /^(?:key(?:down|press|up))$/,
91    TouchEvent: /^(?:touch(?:start|end|move|cancel))$/
92  };
93
94  /**
95   * Extends a jQuery Plugin.
96   *
97   * @param {String} id
98   *   A jQuery plugin identifier located in $.fn.
99   * @param {Function} callback
100   *   A constructor function used to initialize the for the jQuery plugin.
101   *
102   * @return {Function|Boolean}
103   *   The jQuery plugin constructor or FALSE if the plugin does not exist.
104   */
105  Bootstrap.extendPlugin = function (id, callback) {
106    // Immediately return if plugin doesn't exist.
107    if (typeof $.fn[id] !== 'function') {
108      return this.fatal('Specified jQuery plugin identifier does not exist: @id', {'@id':  id});
109    }
110
111    // Immediately return if callback isn't a function.
112    if (typeof callback !== 'function') {
113      return this.fatal('You must provide a callback function to extend the jQuery plugin "@id": @callback', {'@id': id, '@callback':  callback});
114    }
115
116    // Determine existing plugin constructor.
117    var constructor = $.fn[id] && $.fn[id].Constructor || $.fn[id];
118    var plugin = callback.apply(constructor, [this.settings]);
119    if (!$.isPlainObject(plugin)) {
120      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});
121    }
122
123    this.wrapPluginConstructor(constructor, plugin, true);
124
125    return $.fn[id];
126  };
127
128  Bootstrap.superWrapper = function (parent, fn) {
129    return function () {
130      var previousSuper = this.super;
131      this.super = parent;
132      var ret = fn.apply(this, arguments);
133      if (previousSuper) {
134        this.super = previousSuper;
135      }
136      else {
137        delete this.super;
138      }
139      return ret;
140    };
141  };
142
143  /**
144   * Provide a helper method for displaying when something is went wrong.
145   *
146   * @param {String} message
147   *   The message to display.
148   * @param {Object} [args]
149   *   An arguments to use in message.
150   *
151   * @return {Boolean}
152   *   Always returns FALSE.
153   */
154  Bootstrap.fatal = function (message, args) {
155    if (this.settings.dev && console.warn) {
156      for (var name in args) {
157        if (args.hasOwnProperty(name) && typeof args[name] === 'object') {
158          args[name] = JSON.stringify(args[name]);
159        }
160      }
161      Drupal.throwError(new Error(Drupal.formatString(message, args)));
162    }
163    return false;
164  };
165
166  /**
167   * Intersects object properties.
168   *
169   * @param {...Object} objects
170   *   Two or more objects. The first object will be used to return properties
171   *   values.
172   *
173   * @return {Object}
174   *   Returns the properties of first passed object that intersects with all
175   *   other passed objects.
176   */
177  Bootstrap.intersectObjects = function (objects) {
178    var args = Array.prototype.slice.call(arguments);
179    return _.pick(args[0], _.intersection.apply(_, _.map(args, function (obj) {
180      return Object.keys(obj);
181    })));
182  };
183
184  /**
185   * Normalizes an object's values.
186   *
187   * @param {Object} obj
188   *   The object to normalize.
189   *
190   * @return {Object}
191   *   The normalized object.
192   */
193  Bootstrap.normalizeObject = function (obj) {
194    if (!$.isPlainObject(obj)) {
195      return obj;
196    }
197
198    for (var k in obj) {
199      if (typeof obj[k] === 'string') {
200        if (obj[k] === 'true') {
201          obj[k] = true;
202        }
203        else if (obj[k] === 'false') {
204          obj[k] = false;
205        }
206        else if (obj[k].match(/^[\d-.]$/)) {
207          obj[k] = parseFloat(obj[k]);
208        }
209      }
210      else if ($.isPlainObject(obj[k])) {
211        obj[k] = Bootstrap.normalizeObject(obj[k]);
212      }
213    }
214
215    return obj;
216  };
217
218  /**
219   * An object based once plugin (similar to jquery.once, but without the DOM).
220   *
221   * @param {String} id
222   *   A unique identifier.
223   * @param {Function} callback
224   *   The callback to invoke if the identifier has not yet been seen.
225   *
226   * @return {Bootstrap}
227   */
228  Bootstrap.once = function (id, callback) {
229    // Immediately return if identifier has already been processed.
230    if (this.processedOnce[id]) {
231      return this;
232    }
233    callback.call(this, this.settings);
234    this.processedOnce[id] = true;
235    return this;
236  };
237
238  /**
239   * Provide jQuery UI like ability to get/set options for Bootstrap plugins.
240   *
241   * @param {string|object} key
242   *   A string value of the option to set, can be dot like to a nested key.
243   *   An object of key/value pairs.
244   * @param {*} [value]
245   *   (optional) A value to set for key.
246   *
247   * @returns {*}
248   *   - Returns nothing if key is an object or both key and value parameters
249   *   were provided to set an option.
250   *   - Returns the a value for a specific setting if key was provided.
251   *   - Returns an object of key/value pairs of all the options if no key or
252   *   value parameter was provided.
253   *
254   * @see https://github.com/jquery/jquery-ui/blob/master/ui/widget.js
255   */
256  Bootstrap.option = function (key, value) {
257    var options = $.isPlainObject(key) ? $.extend({}, key) : {};
258
259    // Get all options (clone so it doesn't reference the internal object).
260    if (arguments.length === 0) {
261      return $.extend({}, this.options);
262    }
263
264    // Get/set single option.
265    if (typeof key === "string") {
266      // Handle nested keys in dot notation.
267      // e.g., "foo.bar" => { foo: { bar: true } }
268      var parts = key.split('.');
269      key = parts.shift();
270      var obj = options;
271      if (parts.length) {
272        for (var i = 0; i < parts.length - 1; i++) {
273          obj[parts[i]] = obj[parts[i]] || {};
274          obj = obj[parts[i]];
275        }
276        key = parts.pop();
277      }
278
279      // Get.
280      if (arguments.length === 1) {
281        return obj[key] === void 0 ? null : obj[key];
282      }
283
284      // Set.
285      obj[key] = value;
286    }
287
288    // Set multiple options.
289    $.extend(true, this.options, options);
290  };
291
292  /**
293   * Adds a ".noConflict()" helper method if needed.
294   *
295   * @param {String} id
296   *   A jQuery plugin identifier located in $.fn.
297   * @param {Function} plugin
298   * @param {Function} plugin
299   *   A constructor function used to initialize the for the jQuery plugin.
300   * @param {Boolean} [noConflict]
301   *   Flag indicating whether or not to create a ".noConflict()" helper method
302   *   for the plugin.
303   */
304  Bootstrap.pluginNoConflict = function (id, plugin, noConflict) {
305    if (plugin.noConflict === void 0 && (noConflict === void 0 || noConflict)) {
306      var old = $.fn[id];
307      plugin.noConflict = function () {
308        $.fn[id] = old;
309        return this;
310      };
311    }
312  };
313
314  /**
315   * Replaces a Bootstrap jQuery plugin definition.
316   *
317   * @param {String} id
318   *   A jQuery plugin identifier located in $.fn.
319   * @param {Function} callback
320   *   A callback function that is immediately invoked and must return a
321   *   function that will be used as the plugin constructor.
322   * @param {Boolean} [noConflict]
323   *   Flag indicating whether or not to create a ".noConflict()" helper method
324   *   for the plugin.
325   */
326  Bootstrap.replacePlugin = function (id, callback, noConflict) {
327    // Immediately return if plugin doesn't exist.
328    if (typeof $.fn[id] !== 'function') {
329      return this.fatal('Specified jQuery plugin identifier does not exist: @id', {'@id':  id});
330    }
331
332    // Immediately return if callback isn't a function.
333    if (typeof callback !== 'function') {
334      return this.fatal('You must provide a valid callback function to replace a jQuery plugin: @callback', {'@callback': callback});
335    }
336
337    // Determine existing plugin constructor.
338    var constructor = $.fn[id] && $.fn[id].Constructor || $.fn[id];
339    var plugin = callback.apply(constructor, [this.settings]);
340
341    // Immediately return if plugin isn't a function.
342    if (typeof plugin !== 'function') {
343      return this.fatal('Returned value from callback is not a usable function to replace a jQuery plugin "@id": @plugin', {'@id': id, '@plugin': plugin});
344    }
345
346    this.wrapPluginConstructor(constructor, plugin);
347
348    // Add a ".noConflict()" helper method.
349    this.pluginNoConflict(id, plugin, noConflict);
350
351    $.fn[id] = plugin;
352  };
353
354  /**
355   * Simulates a native event on an element in the browser.
356   *
357   * Note: This is a fairly complete modern implementation. If things aren't
358   * working quite the way you intend (in older browsers), you may wish to use
359   * the jQuery.simulate plugin. If it's available, this method will defer to
360   * that plugin.
361   *
362   * @see https://github.com/jquery/jquery-simulate
363   *
364   * @param {HTMLElement|jQuery} element
365   *   A DOM element to dispatch event on. Note: this may be a jQuery object,
366   *   however be aware that this will trigger the same event for each element
367   *   inside the jQuery collection; use with caution.
368   * @param {String|String[]} type
369   *   The type(s) of event to simulate.
370   * @param {Object} [options]
371   *   An object of options to pass to the event constructor. Typically, if
372   *   an event is being proxied, you should just pass the original event
373   *   object here. This allows, if the browser supports it, to be a truly
374   *   simulated event.
375   *
376   * @return {Boolean}
377   *   The return value is false if event is cancelable and at least one of the
378   *   event handlers which handled this event called Event.preventDefault().
379   *   Otherwise it returns true.
380   */
381  Bootstrap.simulate = function (element, type, options) {
382    // Handle jQuery object wrappers so it triggers on each element.
383    var ret = true;
384    if (element instanceof $) {
385      element.each(function () {
386        if (!Bootstrap.simulate(this, type, options)) {
387          ret = false;
388        }
389      });
390      return ret;
391    }
392
393    if (!(element instanceof HTMLElement)) {
394      this.fatal('Passed element must be an instance of HTMLElement, got "@type" instead.', {
395        '@type': typeof element,
396      });
397    }
398
399    // Defer to the jQuery.simulate plugin, if it's available.
400    if (typeof $.simulate === 'function') {
401      new $.simulate(element, type, options);
402      return true;
403    }
404
405    var event;
406    var ctor;
407    var types = [].concat(type);
408    for (var i = 0, l = types.length; i < l; i++) {
409      type = types[i];
410      for (var name in this.eventMap) {
411        if (this.eventMap[name].test(type)) {
412          ctor = name;
413          break;
414        }
415      }
416      if (!ctor) {
417        throw new SyntaxError('Only rudimentary HTMLEvents, KeyboardEvents and MouseEvents are supported: ' + type);
418      }
419      var opts = {bubbles: true, cancelable: true};
420      if (ctor === 'KeyboardEvent' || ctor === 'MouseEvent') {
421        $.extend(opts, {ctrlKey: !1, altKey: !1, shiftKey: !1, metaKey: !1});
422      }
423      if (ctor === 'MouseEvent') {
424        $.extend(opts, {button: 0, pointerX: 0, pointerY: 0, view: window});
425      }
426      if (options) {
427        $.extend(opts, options);
428      }
429      if (typeof window[ctor] === 'function') {
430        event = new window[ctor](type, opts);
431        if (!element.dispatchEvent(event)) {
432          ret = false;
433        }
434      }
435      else if (document.createEvent) {
436        event = document.createEvent(ctor);
437        event.initEvent(type, opts.bubbles, opts.cancelable);
438        if (!element.dispatchEvent(event)) {
439          ret = false;
440        }
441      }
442      else if (typeof element.fireEvent === 'function') {
443        event = $.extend(document.createEventObject(), opts);
444        if (!element.fireEvent('on' + type, event)) {
445          ret = false;
446        }
447      }
448      else if (typeof element[type]) {
449        element[type]();
450      }
451    }
452    return ret;
453  };
454
455  /**
456   * Strips HTML and returns just text.
457   *
458   * @param {String|Element|jQuery} html
459   *   A string of HTML content, an Element DOM object or a jQuery object.
460   *
461   * @return {String}
462   *   The text without HTML tags.
463   *
464   * @todo Replace with http://locutus.io/php/strings/strip_tags/
465   */
466  Bootstrap.stripHtml = function (html) {
467    if (html instanceof $) {
468      html = html.html();
469    }
470    else if (html instanceof Element) {
471      html = html.innerHTML;
472    }
473    var tmp = document.createElement('DIV');
474    tmp.innerHTML = html;
475    return (tmp.textContent || tmp.innerText || '').replace(/^[\s\n\t]*|[\s\n\t]*$/, '');
476  };
477
478  /**
479   * Provide a helper method for displaying when something is unsupported.
480   *
481   * @param {String} type
482   *   The type of unsupported object, e.g. method or option.
483   * @param {String} name
484   *   The name of the unsupported object.
485   * @param {*} [value]
486   *   The value of the unsupported object.
487   */
488  Bootstrap.unsupported = function (type, name, value) {
489    Bootstrap.warn('Unsupported by Drupal Bootstrap: (@type) @name -> @value', {
490      '@type': type,
491      '@name': name,
492      '@value': typeof value === 'object' ? JSON.stringify(value) : value
493    });
494  };
495
496  /**
497   * Provide a helper method to display a warning.
498   *
499   * @param {String} message
500   *   The message to display.
501   * @param {Object} [args]
502   *   Arguments to use as replacements in Drupal.formatString.
503   */
504  Bootstrap.warn = function (message, args) {
505    if (this.settings.dev && console.warn) {
506      console.warn(Drupal.formatString(message, args));
507    }
508  };
509
510  /**
511   * Wraps a plugin with common functionality.
512   *
513   * @param {Function} constructor
514   *   A plugin constructor being wrapped.
515   * @param {Object|Function} plugin
516   *   The plugin being wrapped.
517   * @param {Boolean} [extend = false]
518   *   Whether to add super extensibility.
519   */
520  Bootstrap.wrapPluginConstructor = function (constructor, plugin, extend) {
521    var proto = constructor.prototype;
522
523    // Add a jQuery UI like option getter/setter method.
524    var option = this.option;
525    if (proto.option === void(0)) {
526      proto.option = function () {
527        return option.apply(this, arguments);
528      };
529    }
530
531    if (extend) {
532      // Handle prototype properties separately.
533      if (plugin.prototype !== void 0) {
534        for (var key in plugin.prototype) {
535          if (!plugin.prototype.hasOwnProperty(key)) continue;
536          var value = plugin.prototype[key];
537          if (typeof value === 'function') {
538            proto[key] = this.superWrapper(proto[key] || function () {}, value);
539          }
540          else {
541            proto[key] = $.isPlainObject(value) ? $.extend(true, {}, proto[key], value) : value;
542          }
543        }
544      }
545      delete plugin.prototype;
546
547      // Handle static properties.
548      for (key in plugin) {
549        if (!plugin.hasOwnProperty(key)) continue;
550        value = plugin[key];
551        if (typeof value === 'function') {
552          constructor[key] = this.superWrapper(constructor[key] || function () {}, value);
553        }
554        else {
555          constructor[key] = $.isPlainObject(value) ? $.extend(true, {}, constructor[key], value) : value;
556        }
557      }
558    }
559  };
560
561  /**
562   * Add Bootstrap to the global Drupal object.
563   *
564   * @type {Bootstrap}
565   */
566  Drupal.bootstrap = Drupal.bootstrap || Bootstrap;
567
568})(window._, window.jQuery, window.Drupal, window.drupalSettings);
569;
570(function ($, _) {
571
572  /**
573   * @class Attributes
574   *
575   * Modifies attributes.
576   *
577   * @param {Object|Attributes} attributes
578   *   An object to initialize attributes with.
579   */
580  var Attributes = function (attributes) {
581    this.data = {};
582    this.data['class'] = [];
583    this.merge(attributes);
584  };
585
586  /**
587   * Renders the attributes object as a string to inject into an HTML element.
588   *
589   * @return {String}
590   *   A rendered string suitable for inclusion in HTML markup.
591   */
592  Attributes.prototype.toString = function () {
593    var output = '';
594    var name, value;
595    var checkPlain = function (str) {
596      return str && str.toString().replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;') || '';
597    };
598    var data = this.getData();
599    for (name in data) {
600      if (!data.hasOwnProperty(name)) continue;
601      value = data[name];
602      if (_.isFunction(value)) value = value();
603      if (_.isObject(value)) value = _.values(value);
604      if (_.isArray(value)) value = value.join(' ');
605      output += ' ' + checkPlain(name) + '="' + checkPlain(value) + '"';
606    }
607    return output;
608  };
609
610  /**
611   * Renders the Attributes object as a plain object.
612   *
613   * @return {Object}
614   *   A plain object suitable for inclusion in DOM elements.
615   */
616  Attributes.prototype.toPlainObject = function () {
617    var object = {};
618    var name, value;
619    var data = this.getData();
620    for (name in data) {
621      if (!data.hasOwnProperty(name)) continue;
622      value = data[name];
623      if (_.isFunction(value)) value = value();
624      if (_.isObject(value)) value = _.values(value);
625      if (_.isArray(value)) value = value.join(' ');
626      object[name] = value;
627    }
628    return object;
629  };
630
631  /**
632   * Add class(es) to the array.
633   *
634   * @param {string|Array} value
635   *   An individual class or an array of classes to add.
636   *
637   * @return {Attributes}
638   *
639   * @chainable
640   */
641  Attributes.prototype.addClass = function (value) {
642    var args = Array.prototype.slice.call(arguments);
643    this.data['class'] = this.sanitizeClasses(this.data['class'].concat(args));
644    return this;
645  };
646
647  /**
648   * Returns whether the requested attribute exists.
649   *
650   * @param {string} name
651   *   An attribute name to check.
652   *
653   * @return {boolean}
654   *   TRUE or FALSE
655   */
656  Attributes.prototype.exists = function (name) {
657    return this.data[name] !== void(0) && this.data[name] !== null;
658  };
659
660  /**
661   * Retrieve a specific attribute from the array.
662   *
663   * @param {string} name
664   *   The specific attribute to retrieve.
665   * @param {*} defaultValue
666   *   (optional) The default value to set if the attribute does not exist.
667   *
668   * @return {*}
669   *   A specific attribute value, passed by reference.
670   */
671  Attributes.prototype.get = function (name, defaultValue) {
672    if (!this.exists(name)) this.data[name] = defaultValue;
673    return this.data[name];
674  };
675
676  /**
677   * Retrieves a cloned copy of the internal attributes data object.
678   *
679   * @return {Object}
680   */
681  Attributes.prototype.getData = function () {
682    return _.extend({}, this.data);
683  };
684
685  /**
686   * Retrieves classes from the array.
687   *
688   * @return {Array}
689   *   The classes array.
690   */
691  Attributes.prototype.getClasses = function () {
692    return this.get('class', []);
693  };
694
695  /**
696   * Indicates whether a class is present in the array.
697   *
698   * @param {string|Array} className
699   *   The class(es) to search for.
700   *
701   * @return {boolean}
702   *   TRUE or FALSE
703   */
704  Attributes.prototype.hasClass = function (className) {
705    className = this.sanitizeClasses(Array.prototype.slice.call(arguments));
706    var classes = this.getClasses();
707    for (var i = 0, l = className.length; i < l; i++) {
708      // If one of the classes fails, immediately return false.
709      if (_.indexOf(classes, className[i]) === -1) {
710        return false;
711      }
712    }
713    return true;
714  };
715
716  /**
717   * Merges multiple values into the array.
718   *
719   * @param {Attributes|Node|jQuery|Object} object
720   *   An Attributes object with existing data, a Node DOM element, a jQuery
721   *   instance or a plain object where the key is the attribute name and the
722   *   value is the attribute value.
723   * @param {boolean} [recursive]
724   *   Flag determining whether or not to recursively merge key/value pairs.
725   *
726   * @return {Attributes}
727   *
728   * @chainable
729   */
730  Attributes.prototype.merge = function (object, recursive) {
731    // Immediately return if there is nothing to merge.
732    if (!object) {
733      return this;
734    }
735
736    // Get attributes from a jQuery element.
737    if (object instanceof $) {
738      object = object[0];
739    }
740
741    // Get attributes from a DOM element.
742    if (object instanceof Node) {
743      object = Array.prototype.slice.call(object.attributes).reduce(function (attributes, attribute) {
744        attributes[attribute.name] = attribute.value;
745        return attributes;
746      }, {});
747    }
748    // Get attributes from an Attributes instance.
749    else if (object instanceof Attributes) {
750      object = object.getData();
751    }
752    // Otherwise, clone the object.
753    else {
754      object = _.extend({}, object);
755    }
756
757    // By this point, there should be a valid plain object.
758    if (!$.isPlainObject(object)) {
759      setTimeout(function () {
760        throw new Error('Passed object is not supported: ' + object);
761      });
762      return this;
763    }
764
765    // Handle classes separately.
766    if (object && object['class'] !== void 0) {
767      this.addClass(object['class']);
768      delete object['class'];
769    }
770
771    if (recursive === void 0 || recursive) {
772      this.data = $.extend(true, {}, this.data, object);
773    }
774    else {
775      this.data = $.extend({}, this.data, object);
776    }
777
778    return this;
779  };
780
781  /**
782   * Removes an attribute from the array.
783   *
784   * @param {string} name
785   *   The name of the attribute to remove.
786   *
787   * @return {Attributes}
788   *
789   * @chainable
790   */
791  Attributes.prototype.remove = function (name) {
792    if (this.exists(name)) delete this.data[name];
793    return this;
794  };
795
796  /**
797   * Removes a class from the attributes array.
798   *
799   * @param {...string|Array} className
800   *   An individual class or an array of classes to remove.
801   *
802   * @return {Attributes}
803   *
804   * @chainable
805   */
806  Attributes.prototype.removeClass = function (className) {
807    var remove = this.sanitizeClasses(Array.prototype.slice.apply(arguments));
808    this.data['class'] = _.without(this.getClasses(), remove);
809    return this;
810  };
811
812  /**
813   * Replaces a class in the attributes array.
814   *
815   * @param {string} oldValue
816   *   The old class to remove.
817   * @param {string} newValue
818   *   The new class. It will not be added if the old class does not exist.
819   *
820   * @return {Attributes}
821   *
822   * @chainable
823   */
824  Attributes.prototype.replaceClass = function (oldValue, newValue) {
825    var classes = this.getClasses();
826    var i = _.indexOf(this.sanitizeClasses(oldValue), classes);
827    if (i >= 0) {
828      classes[i] = newValue;
829      this.set('class', classes);
830    }
831    return this;
832  };
833
834  /**
835   * Ensures classes are flattened into a single is an array and sanitized.
836   *
837   * @param {...String|Array} classes
838   *   The class or classes to sanitize.
839   *
840   * @return {Array}
841   *   A sanitized array of classes.
842   */
843  Attributes.prototype.sanitizeClasses = function (classes) {
844    return _.chain(Array.prototype.slice.call(arguments))
845      // Flatten in case there's a mix of strings and arrays.
846      .flatten()
847
848      // Split classes that may have been added with a space as a separator.
849      .map(function (string) {
850        return string.split(' ');
851      })
852
853      // Flatten again since it was just split into arrays.
854      .flatten()
855
856      // Filter out empty items.
857      .filter()
858
859      // Clean the class to ensure it's a valid class name.
860      .map(function (value) {
861        return Attributes.cleanClass(value);
862      })
863
864      // Ensure classes are unique.
865      .uniq()
866
867      // Retrieve the final value.
868      .value();
869  };
870
871  /**
872   * Sets an attribute on the array.
873   *
874   * @param {string} name
875   *   The name of the attribute to set.
876   * @param {*} value
877   *   The value of the attribute to set.
878   *
879   * @return {Attributes}
880   *
881   * @chainable
882   */
883  Attributes.prototype.set = function (name, value) {
884    var obj = $.isPlainObject(name) ? name : {};
885    if (typeof name === 'string') {
886      obj[name] = value;
887    }
888    return this.merge(obj);
889  };
890
891  /**
892   * Prepares a string for use as a CSS identifier (element, class, or ID name).
893   *
894   * Note: this is essentially a direct copy from
895   * \Drupal\Component\Utility\Html::cleanCssIdentifier
896   *
897   * @param {string} identifier
898   *   The identifier to clean.
899   * @param {Object} [filter]
900   *   An object of string replacements to use on the identifier.
901   *
902   * @return {string}
903   *   The cleaned identifier.
904   */
905  Attributes.cleanClass = function (identifier, filter) {
906    filter = filter || {
907      ' ': '-',
908      '_': '-',
909      '/': '-',
910      '[': '-',
911      ']': ''
912    };
913
914    identifier = identifier.toLowerCase();
915
916    if (filter['__'] === void 0) {
917      identifier = identifier.replace('__', '#DOUBLE_UNDERSCORE#');
918    }
919
920    identifier = identifier.replace(Object.keys(filter), Object.keys(filter).map(function(key) { return filter[key]; }));
921
922    if (filter['__'] === void 0) {
923      identifier = identifier.replace('#DOUBLE_UNDERSCORE#', '__');
924    }
925
926    identifier = identifier.replace(/[^\u002D\u0030-\u0039\u0041-\u005A\u005F\u0061-\u007A\u00A1-\uFFFF]/g, '');
927    identifier = identifier.replace(['/^[0-9]/', '/^(-[0-9])|^(--)/'], ['_', '__']);
928
929    return identifier;
930  };
931
932  /**
933   * Creates an Attributes instance.
934   *
935   * @param {object|Attributes} [attributes]
936   *   An object to initialize attributes with.
937   *
938   * @return {Attributes}
939   *   An Attributes instance.
940   *
941   * @constructor
942   */
943  Attributes.create = function (attributes) {
944    return new Attributes(attributes);
945  };
946
947  window.Attributes = Attributes;
948
949})(window.jQuery, window._);
950;
951/**
952 * @file
953 * Theme hooks for the Drupal Bootstrap base theme.
954 */
955(function ($, Drupal, Bootstrap, Attributes) {
956
957  /**
958   * Fallback for theming an icon if the Icon API module is not installed.
959   */
960  if (!Drupal.icon) Drupal.icon = { bundles: {} };
961  if (!Drupal.theme.icon || Drupal.theme.prototype.icon) {
962    $.extend(Drupal.theme, /** @lends Drupal.theme */ {
963      /**
964       * Renders an icon.
965       *
966       * @param {string} bundle
967       *   The bundle which the icon belongs to.
968       * @param {string} icon
969       *   The name of the icon to render.
970       * @param {object|Attributes} [attributes]
971       *   An object of attributes to also apply to the icon.
972       *
973       * @returns {string}
974       */
975      icon: function (bundle, icon, attributes) {
976        if (!Drupal.icon.bundles[bundle]) return '';
977        attributes = Attributes.create(attributes).addClass('icon').set('aria-hidden', 'true');
978        icon = Drupal.icon.bundles[bundle](icon, attributes);
979        return '<span' + attributes + '></span>';
980      }
981    });
982  }
983
984  /**
985   * Callback for modifying an icon in the "bootstrap" icon bundle.
986   *
987   * @param {string} icon
988   *   The icon being rendered.
989   * @param {Attributes} attributes
990   *   Attributes object for the icon.
991   */
992  Drupal.icon.bundles.bootstrap = function (icon, attributes) {
993    attributes.addClass(['glyphicon', 'glyphicon-' + icon]);
994  };
995
996  /**
997   * Add necessary theming hooks.
998   */
999  $.extend(Drupal.theme, /** @lends Drupal.theme */ {
1000
1001    /**
1002     * Renders a Bootstrap AJAX glyphicon throbber.
1003     *
1004     * @returns {string}
1005     */
1006    ajaxThrobber: function () {
1007      return Drupal.theme('bootstrapIcon', 'refresh', {'class': ['ajax-throbber', 'glyphicon-spin'] });
1008    },
1009
1010    /**
1011     * Renders a button element.
1012     *
1013     * @param {object|Attributes} attributes
1014     *   An object of attributes to apply to the button. If it contains one of:
1015     *   - value: The label of the button.
1016     *   - context: The context type of Bootstrap button, can be one of:
1017     *     - default
1018     *     - primary
1019     *     - success
1020     *     - info
1021     *     - warning
1022     *     - danger
1023     *     - link
1024     *
1025     * @returns {string}
1026     */
1027    button: function (attributes) {
1028      attributes = Attributes.create(attributes).addClass('btn');
1029      var context = attributes.get('context', 'default');
1030      var label = attributes.get('value', '');
1031      attributes.remove('context').remove('value');
1032      if (!attributes.hasClass(['btn-default', 'btn-primary', 'btn-success', 'btn-info', 'btn-warning', 'btn-danger', 'btn-link'])) {
1033        attributes.addClass('btn-' + Bootstrap.checkPlain(context));
1034      }
1035
1036      // Attempt to, intelligently, provide a default button "type".
1037      if (!attributes.exists('type')) {
1038        attributes.set('type', attributes.hasClass('form-submit') ? 'submit' : 'button');
1039      }
1040
1041      return '<button' + attributes + '>' + label + '</button>';
1042    },
1043
1044    /**
1045     * Alias for "button" theme hook.
1046     *
1047     * @param {object|Attributes} attributes
1048     *   An object of attributes to apply to the button.
1049     *
1050     * @see Drupal.theme.button()
1051     *
1052     * @returns {string}
1053     */
1054    btn: function (attributes) {
1055      return Drupal.theme('button', attributes);
1056    },
1057
1058    /**
1059     * Renders a button block element.
1060     *
1061     * @param {object|Attributes} attributes
1062     *   An object of attributes to apply to the button.
1063     *
1064     * @see Drupal.theme.button()
1065     *
1066     * @returns {string}
1067     */
1068    'btn-block': function (attributes) {
1069      return Drupal.theme('button', Attributes.create(attributes).addClass('btn-block'));
1070    },
1071
1072    /**
1073     * Renders a large button element.
1074     *
1075     * @param {object|Attributes} attributes
1076     *   An object of attributes to apply to the button.
1077     *
1078     * @see Drupal.theme.button()
1079     *
1080     * @returns {string}
1081     */
1082    'btn-lg': function (attributes) {
1083      return Drupal.theme('button', Attributes.create(attributes).addClass('btn-lg'));
1084    },
1085
1086    /**
1087     * Renders a small button element.
1088     *
1089     * @param {object|Attributes} attributes
1090     *   An object of attributes to apply to the button.
1091     *
1092     * @see Drupal.theme.button()
1093     *
1094     * @returns {string}
1095     */
1096    'btn-sm': function (attributes) {
1097      return Drupal.theme('button', Attributes.create(attributes).addClass('btn-sm'));
1098    },
1099
1100    /**
1101     * Renders an extra small button element.
1102     *
1103     * @param {object|Attributes} attributes
1104     *   An object of attributes to apply to the button.
1105     *
1106     * @see Drupal.theme.button()
1107     *
1108     * @returns {string}
1109     */
1110    'btn-xs': function (attributes) {
1111      return Drupal.theme('button', Attributes.create(attributes).addClass('btn-xs'));
1112    },
1113
1114    /**
1115     * Renders a glyphicon.
1116     *
1117     * @param {string} name
1118     *   The name of the glyphicon.
1119     * @param {object|Attributes} [attributes]
1120     *   An object of attributes to apply to the icon.
1121     *
1122     * @returns {string}
1123     */
1124    bootstrapIcon: function (name, attributes) {
1125      return Drupal.theme('icon', 'bootstrap', name, attributes);
1126    }
1127
1128  });
1129
1130})(window.jQuery, window.Drupal, window.Drupal.bootstrap, window.Attributes);
1131;
1132/**
1133* DO NOT EDIT THIS FILE.
1134* See the following change record for more information,
1135* https://www.drupal.org/node/2815083
1136* @preserve
1137**/
1138
1139(function ($, Drupal) {
1140  var states = {
1141    postponed: []
1142  };
1143
1144  Drupal.states = states;
1145
1146  function invert(a, invertState) {
1147    return invertState && typeof a !== 'undefined' ? !a : a;
1148  }
1149
1150  function _compare2(a, b) {
1151    if (a === b) {
1152      return typeof a === 'undefined' ? a : true;
1153    }
1154
1155    return typeof a === 'undefined' || typeof b === 'undefined';
1156  }
1157
1158  function ternary(a, b) {
1159    if (typeof a === 'undefined') {
1160      return b;
1161    }
1162    if (typeof b === 'undefined') {
1163      return a;
1164    }
1165
1166    return a && b;
1167  }
1168
1169  Drupal.behaviors.states = {
1170    attach: function attach(context, settings) {
1171      var $states = $(context).find('[data-drupal-states]');
1172      var il = $states.length;
1173
1174      var _loop = function _loop(i) {
1175        var config = JSON.parse($states[i].getAttribute('data-drupal-states'));
1176        Object.keys(config || {}).forEach(function (state) {
1177          new states.Dependent({
1178            element: $($states[i]),
1179            state: states.State.sanitize(state),
1180            constraints: config[state]
1181          });
1182        });
1183      };
1184
1185      for (var i = 0; i < il; i++) {
1186        _loop(i);
1187      }
1188
1189      while (states.postponed.length) {
1190        states.postponed.shift()();
1191      }
1192    }
1193  };
1194
1195  states.Dependent = function (args) {
1196    var _this = this;
1197
1198    $.extend(this, { values: {}, oldValue: null }, args);
1199
1200    this.dependees = this.getDependees();
1201    Object.keys(this.dependees || {}).forEach(function (selector) {
1202      _this.initializeDependee(selector, _this.dependees[selector]);
1203    });
1204  };
1205
1206  states.Dependent.comparisons = {
1207    RegExp: function RegExp(reference, value) {
1208      return reference.test(value);
1209    },
1210    Function: function Function(reference, value) {
1211      return reference(value);
1212    },
1213    Number: function Number(reference, value) {
1214      return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value);
1215    }
1216  };
1217
1218  states.Dependent.prototype = {
1219    initializeDependee: function initializeDependee(selector, dependeeStates) {
1220      var _this2 = this;
1221
1222      this.values[selector] = {};
1223
1224      Object.keys(dependeeStates).forEach(function (i) {
1225        var state = dependeeStates[i];
1226
1227        if ($.inArray(state, dependeeStates) === -1) {
1228          return;
1229        }
1230
1231        state = states.State.sanitize(state);
1232
1233        _this2.values[selector][state.name] = null;
1234
1235        $(selector).on('state:' + state, { selector: selector, state: state }, function (e) {
1236          _this2.update(e.data.selector, e.data.state, e.value);
1237        });
1238
1239        new states.Trigger({ selector: selector, state: state });
1240      });
1241    },
1242    compare: function compare(reference, selector, state) {
1243      var value = this.values[selector][state.name];
1244      if (reference.constructor.name in states.Dependent.comparisons) {
1245        return states.Dependent.comparisons[reference.constructor.name](reference, value);
1246      }
1247
1248      return _compare2(reference, value);
1249    },
1250    update: function update(selector, state, value) {
1251      if (value !== this.values[selector][state.name]) {
1252        this.values[selector][state.name] = value;
1253        this.reevaluate();
1254      }
1255    },
1256    reevaluate: function reevaluate() {
1257      var value = this.verifyConstraints(this.constraints);
1258
1259      if (value !== this.oldValue) {
1260        this.oldValue = value;
1261
1262        value = invert(value, this.state.invert);
1263
1264        this.element.trigger({
1265          type: 'state:' + this.state,
1266          value: value,
1267          trigger: true
1268        });
1269      }
1270    },
1271    verifyConstraints: function verifyConstraints(constraints, selector) {
1272      var result = void 0;
1273      if ($.isArray(constraints)) {
1274        var hasXor = $.inArray('xor', constraints) === -1;
1275        var len = constraints.length;
1276        for (var i = 0; i < len; i++) {
1277          if (constraints[i] !== 'xor') {
1278            var constraint = this.checkConstraints(constraints[i], selector, i);
1279
1280            if (constraint && (hasXor || result)) {
1281              return hasXor;
1282            }
1283            result = result || constraint;
1284          }
1285        }
1286      } else if ($.isPlainObject(constraints)) {
1287          for (var n in constraints) {
1288            if (constraints.hasOwnProperty(n)) {
1289              result = ternary(result, this.checkConstraints(constraints[n], selector, n));
1290
1291              if (result === false) {
1292                return false;
1293              }
1294            }
1295          }
1296        }
1297      return result;
1298    },
1299    checkConstraints: function checkConstraints(value, selector, state) {
1300      if (typeof state !== 'string' || /[0-9]/.test(state[0])) {
1301        state = null;
1302      } else if (typeof selector === 'undefined') {
1303        selector = state;
1304        state = null;
1305      }
1306
1307      if (state !== null) {
1308        state = states.State.sanitize(state);
1309        return invert(this.compare(value, selector, state), state.invert);
1310      }
1311
1312      return this.verifyConstraints(value, selector);
1313    },
1314    getDependees: function getDependees() {
1315      var cache = {};
1316
1317      var _compare = this.compare;
1318      this.compare = function (reference, selector, state) {
1319        (cache[selector] || (cache[selector] = [])).push(state.name);
1320      };
1321
1322      this.verifyConstraints(this.constraints);
1323
1324      this.compare = _compare;
1325
1326      return cache;
1327    }
1328  };
1329
1330  states.Trigger = function (args) {
1331    $.extend(this, args);
1332
1333    if (this.state in states.Trigger.states) {
1334      this.element = $(this.selector);
1335
1336      if (!this.element.data('trigger:' + this.state)) {
1337        this.initialize();
1338      }
1339    }
1340  };
1341
1342  states.Trigger.prototype = {
1343    initialize: function initialize() {
1344      var _this3 = this;
1345
1346      var trigger = states.Trigger.states[this.state];
1347
1348      if (typeof trigger === 'function') {
1349        trigger.call(window, this.element);
1350      } else {
1351        Object.keys(trigger || {}).forEach(function (event) {
1352          _this3.defaultTrigger(event, trigger[event]);
1353        });
1354      }
1355
1356      this.element.data('trigger:' + this.state, true);
1357    },
1358    defaultTrigger: function defaultTrigger(event, valueFn) {
1359      var oldValue = valueFn.call(this.element);
1360
1361      this.element.on(event, $.proxy(function (e) {
1362        var value = valueFn.call(this.element, e);
1363
1364        if (oldValue !== value) {
1365          this.element.trigger({
1366            type: 'state:' + this.state,
1367            value: value,
1368            oldValue: oldValue
1369          });
1370          oldValue = value;
1371        }
1372      }, this));
1373
1374      states.postponed.push($.proxy(function () {
1375        this.element.trigger({
1376          type: 'state:' + this.state,
1377          value: oldValue,
1378          oldValue: null
1379        });
1380      }, this));
1381    }
1382  };
1383
1384  states.Trigger.states = {
1385    empty: {
1386      keyup: function keyup() {
1387        return this.val() === '';
1388      }
1389    },
1390
1391    checked: {
1392      change: function change() {
1393        var checked = false;
1394        this.each(function () {
1395          checked = $(this).prop('checked');
1396
1397          return !checked;
1398        });
1399        return checked;
1400      }
1401    },
1402
1403    value: {
1404      keyup: function keyup() {
1405        if (this.length > 1) {
1406          return this.filter(':checked').val() || false;
1407        }
1408        return this.val();
1409      },
1410      change: function change() {
1411        if (this.length > 1) {
1412          return this.filter(':checked').val() || false;
1413        }
1414        return this.val();
1415      }
1416    },
1417
1418    collapsed: {
1419      collapsed: function collapsed(e) {
1420        return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]');
1421      }
1422    }
1423  };
1424
1425  states.State = function (state) {
1426    this.pristine = state;
1427    this.name = state;
1428
1429    var process = true;
1430    do {
1431      while (this.name.charAt(0) === '!') {
1432        this.name = this.name.substring(1);
1433        this.invert = !this.invert;
1434      }
1435
1436      if (this.name in states.State.aliases) {
1437        this.name = states.State.aliases[this.name];
1438      } else {
1439        process = false;
1440      }
1441    } while (process);
1442  };
1443
1444  states.State.sanitize = function (state) {
1445    if (state instanceof states.State) {
1446      return state;
1447    }
1448
1449    return new states.State(state);
1450  };
1451
1452  states.State.aliases = {
1453    enabled: '!disabled',
1454    invisible: '!visible',
1455    invalid: '!valid',
1456    untouched: '!touched',
1457    optional: '!required',
1458    filled: '!empty',
1459    unchecked: '!checked',
1460    irrelevant: '!relevant',
1461    expanded: '!collapsed',
1462    open: '!collapsed',
1463    closed: 'collapsed',
1464    readwrite: '!readonly'
1465  };
1466
1467  states.State.prototype = {
1468    invert: false,
1469
1470    toString: function toString() {
1471      return this.name;
1472    }
1473  };
1474
1475  var $document = $(document);
1476  $document.on('state:disabled', function (e) {
1477    if (e.trigger) {
1478      $(e.target).prop('disabled', e.value).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value).find('select, input, textarea').prop('disabled', e.value);
1479    }
1480  });
1481
1482  $document.on('state:required', function (e) {
1483    if (e.trigger) {
1484      if (e.value) {
1485        var label = 'label' + (e.target.id ? '[for=' + e.target.id + ']' : '');
1486        var $label = $(e.target).attr({ required: 'required', 'aria-required': 'aria-required' }).closest('.js-form-item, .js-form-wrapper').find(label);
1487
1488        if (!$label.hasClass('js-form-required').length) {
1489          $label.addClass('js-form-required form-required');
1490        }
1491      } else {
1492        $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required');
1493      }
1494    }
1495  });
1496
1497  $document.on('state:visible', function (e) {
1498    if (e.trigger) {
1499      $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value);
1500    }
1501  });
1502
1503  $document.on('state:checked', function (e) {
1504    if (e.trigger) {
1505      $(e.target).prop('checked', e.value);
1506    }
1507  });
1508
1509  $document.on('state:collapsed', function (e) {
1510    if (e.trigger) {
1511      if ($(e.target).is('[open]') === e.value) {
1512        $(e.target).find('> summary').trigger('click');
1513      }
1514    }
1515  });
1516})(jQuery, Drupal);;
1517/**
1518 * @file
1519 * Extends core/misc/states.js.
1520 */
1521(function($) {
1522
1523  // Unbind core state.js from document first so we can then override below.
1524  $(document).unbind('state:disabled');
1525
1526  /**
1527   * Global state change handlers. These are bound to "document" to cover all
1528   * elements whose state changes. Events sent to elements within the page
1529   * bubble up to these handlers. We use this system so that themes and modules
1530   * can override these state change handlers for particular parts of a page.
1531   */
1532  $(document).bind('state:disabled', function(e) {
1533    // Only act when this change was triggered by a dependency and not by the
1534    // element monitoring itself.
1535    if (e.trigger) {
1536      $(e.target)
1537        .attr('disabled', e.value)
1538        .closest('.form-item, .form-submit, .form-wrapper').toggleClass('form-disabled', e.value)
1539        .find(':input').attr('disabled', e.value);
1540
1541      // Note: WebKit nightlies don't reflect that change correctly.
1542      // See https://bugs.webkit.org/show_bug.cgi?id=23789
1543    }
1544  });
1545
1546})(jQuery);
1547;
1548/**
1549 * @file
1550 * JavaScript behaviors for custom webform #states.
1551 */
1552
1553(function ($, Drupal) {
1554
1555  'use strict';
1556
1557  Drupal.webform = Drupal.webform || {};
1558  Drupal.webform.states = Drupal.webform.states || {};
1559  Drupal.webform.states.slideDown = Drupal.webform.states.slideDown || {};
1560  Drupal.webform.states.slideDown.duration = 'slow';
1561  Drupal.webform.states.slideUp = Drupal.webform.states.slideUp || {};
1562  Drupal.webform.states.slideUp.duration = 'fast';
1563
1564  /**
1565   * Check if an element has a specified data attribute.
1566   *
1567   * @param {string} data
1568   *   The data attribute name.
1569   *
1570   * @return {boolean}
1571   *   TRUE if an element has a specified data attribute.
1572   */
1573  $.fn.hasData = function (data) {
1574    return (typeof this.data(data) !== 'undefined');
1575  };
1576
1577  /**
1578   * Check if element is within the webform or not.
1579   *
1580   * @return {boolean}
1581   *   TRUE if element is within the webform.
1582   */
1583  $.fn.isWebform = function () {
1584    return $(this).closest('form[id^="webform"]').length ? true : false;
1585  };
1586
1587  // The change event is triggered by cut-n-paste and select menus.
1588  // Issue #2445271: #states element empty check not triggered on mouse
1589  // based paste.
1590  // @see https://www.drupal.org/node/2445271
1591  Drupal.states.Trigger.states.empty.change = function change() {
1592    return this.val() === '';
1593  };
1594
1595  // Apply solution included in #1962800 patch.
1596  // Issue #1962800: Form #states not working with literal integers as
1597  // values in IE11.
1598  // @see https://www.drupal.org/project/drupal/issues/1962800
1599  // @see https://www.drupal.org/files/issues/core-states-not-working-with-integers-ie11_1962800_46.patch
1600  //
1601  // This issue causes pattern, less than, and greater than support to break.
1602  // @see https://www.drupal.org/project/webform/issues/2981724
1603  var states = Drupal.states;
1604  Drupal.states.Dependent.prototype.compare = function compare(reference, selector, state) {
1605    var value = this.values[selector][state.name];
1606
1607    var name = reference.constructor.name;
1608    if (!name) {
1609      name = $.type(reference);
1610
1611      name = name.charAt(0).toUpperCase() + name.slice(1);
1612    }
1613    if (name in states.Dependent.comparisons) {
1614      return states.Dependent.comparisons[name](reference, value);
1615    }
1616
1617    if (reference.constructor.name in states.Dependent.comparisons) {
1618      return states.Dependent.comparisons[reference.constructor.name](reference, value);
1619    }
1620
1621    return _compare2(reference, value);
1622  };
1623  function _compare2(a, b) {
1624    if (a === b) {
1625      return typeof a === 'undefined' ? a : true;
1626    }
1627
1628    return typeof a === 'undefined' || typeof b === 'undefined';
1629  }
1630
1631  // Adds pattern, less than, and greater than support to #state API.
1632  // @see http://drupalsun.com/julia-evans/2012/03/09/extending-form-api-states-regular-expressions
1633  Drupal.states.Dependent.comparisons.Object = function (reference, value) {
1634    if ('pattern' in reference) {
1635      return (new RegExp(reference['pattern'])).test(value);
1636    }
1637    else if ('!pattern' in reference) {
1638      return !((new RegExp(reference['!pattern'])).test(value));
1639    }
1640    else if ('less' in reference) {
1641      return (value !== '' && parseFloat(reference['less']) > parseFloat(value));
1642    }
1643    else if ('greater' in reference) {
1644      return (value !== '' && parseFloat(reference['greater']) < parseFloat(value));
1645    }
1646    else {
1647      return reference.indexOf(value) !== false;
1648    }
1649  };
1650
1651  var $document = $(document);
1652
1653  $document.on('state:required', function (e) {
1654    if (e.trigger && $(e.target).isWebform()) {
1655      var $target = $(e.target);
1656      // Fix #required file upload.
1657      // @see Issue #2860529: Conditional required File upload field don't work.
1658      if (e.value) {
1659        $target.find('input[type="file"]').attr({'required': 'required', 'aria-required': 'true'});
1660      }
1661      else {
1662        $target.find('input[type="file"]').removeAttr('required aria-required');
1663      }
1664
1665      // Fix required label for checkboxes and radios.
1666      // @see Issue #2938414: Checkboxes don't support #states required
1667      // @see Issue #2731991: Setting required on radios marks all options required.
1668      // @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset.
1669      // Fix #required for fieldsets.
1670      // @see Issue #2977569: Hidden fieldsets that become visible with conditional logic cannot be made required.
1671      if ($target.is('.js-webform-type-radios, .js-webform-type-checkboxes, fieldset')) {
1672        if (e.value) {
1673          $target.find('legend span.fieldset-legend:not(.visually-hidden)').addClass('js-form-required form-required');
1674        }
1675        else {
1676          $target.find('legend span.fieldset-legend:not(.visually-hidden)').removeClass('js-form-required form-required');
1677        }
1678      }
1679
1680      // Fix #required for radios.
1681      // @see Issue #2856795: If radio buttons are required but not filled form is nevertheless submitted.
1682      if ($target.is('.js-webform-type-radios, .js-form-type-webform-radios-other')) {
1683        if (e.value) {
1684          $target.find('input[type="radio"]').attr({'required': 'required', 'aria-required': 'true'});
1685        }
1686        else {
1687          $target.find('input[type="radio"]').removeAttr('required aria-required');
1688        }
1689      }
1690
1691      // Fix #required for checkboxes.
1692      // @see Issue #2938414: Checkboxes don't support #states required.
1693      // @see checkboxRequiredhandler
1694      if ($target.is('.js-webform-type-checkboxes, .js-form-type-webform-checkboxes-other')) {
1695        var $checkboxes = $target.find('input[type="checkbox"]');
1696        if (e.value) {
1697          // Bind the event handler and add custom HTML5 required validation
1698          // to all checkboxes.
1699          $checkboxes.bind('click', checkboxRequiredhandler);
1700          if (!$checkboxes.is(':checked')) {
1701            $checkboxes.attr({'required': 'required', 'aria-required': 'true'});
1702          }
1703        }
1704        else {
1705          // Remove custom HTML5 required validation from all checkboxes
1706          // and unbind the event handler.
1707          $checkboxes
1708            .removeAttr('required aria-required')
1709            .unbind('click', checkboxRequiredhandler);
1710        }
1711      }
1712
1713      // Issue #2986017: Fieldsets shouldn't have required attribute.
1714      if ($target.is('fieldset')) {
1715        $target.removeAttr('required aria-required');
1716      }
1717    }
1718
1719  });
1720
1721  $document.on('state:readonly', function (e) {
1722    if (e.trigger && $(e.target).isWebform()) {
1723      $(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);
1724    }
1725  });
1726
1727  $document.on('state:visible state:visible-slide', function (e) {
1728    if (e.trigger && $(e.target).isWebform()) {
1729      if (e.value) {
1730        $(':input', e.target).addBack().each(function () {
1731          restoreValueAndRequired(this);
1732          triggerEventHandlers(this);
1733        });
1734      }
1735      else {
1736        // @see https://www.sitepoint.com/jquery-function-clear-form-data/
1737        $(':input', e.target).addBack().each(function () {
1738          backupValueAndRequired(this);
1739          clearValueAndRequired(this);
1740          triggerEventHandlers(this);
1741        });
1742      }
1743    }
1744  });
1745
1746  $document.bind('state:visible-slide', function (e) {
1747    if (e.trigger && $(e.target).isWebform()) {
1748      var effect = e.value ? 'slideDown' : 'slideUp';
1749      var duration = Drupal.webform.states[effect].duration;
1750      $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper')[effect](duration);
1751    }
1752  });
1753  Drupal.states.State.aliases['invisible-slide'] = '!visible-slide';
1754
1755  $document.on('state:disabled', function (e) {
1756    if (e.trigger && $(e.target).isWebform()) {
1757      // Make sure disabled property is set before triggering webform:disabled.
1758      // Copied from: core/misc/states.js
1759      $(e.target)
1760        .prop('disabled', e.value)
1761        .closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value)
1762        .find('select, input, textarea, button').prop('disabled', e.value);
1763
1764      // Trigger webform:disabled.
1765      $(e.target).trigger('webform:disabled')
1766        .find('select, input, textarea, button').trigger('webform:disabled');
1767    }
1768  });
1769
1770  /**
1771   * Trigger custom HTML5 multiple checkboxes validation.
1772   *
1773   * @see https://stackoverflow.com/a/37825072/145846
1774   */
1775  function checkboxRequiredhandler() {
1776    var $checkboxes = $(this).closest('.js-webform-type-checkboxes, .js-form-type-webform-checkboxes-other').find('input[type="checkbox"]');
1777    if ($checkboxes.is(':checked')) {
1778      $checkboxes.removeAttr('required aria-required');
1779    }
1780    else {
1781      $checkboxes.attr({'required': 'required', 'aria-required': 'true'});
1782    }
1783  }
1784
1785  /**
1786   * Trigger an input's event handlers.
1787   *
1788   * @param {element} input
1789   *   An input.
1790   */
1791  function triggerEventHandlers(input) {
1792    var $input = $(input);
1793    var type = input.type;
1794    var tag = input.tagName.toLowerCase();
1795    // Add 'webform.states' as extra parameter to event handlers.
1796    // @see Drupal.behaviors.webformUnsaved
1797    var extraParameters = ['webform.states'];
1798    if (type === 'checkbox' || type === 'radio') {
1799      $input
1800        .trigger('change', extraParameters)
1801        .trigger('blur', extraParameters);
1802    }
1803    else if (tag === 'select') {
1804      $input
1805        .trigger('change', extraParameters)
1806        .trigger('blur', extraParameters);
1807    }
1808    else if (type !== 'submit' && type !== 'button' && type !== 'file') {
1809      $input
1810        .trigger('input', extraParameters)
1811        .trigger('change', extraParameters)
1812        .trigger('keydown', extraParameters)
1813        .trigger('keyup', extraParameters)
1814        .trigger('blur', extraParameters);
1815    }
1816  }
1817
1818  /**
1819   * Backup an input's current value and required attribute
1820   *
1821   * @param {element} input
1822   *   An input.
1823   */
1824  function backupValueAndRequired(input) {
1825    var $input = $(input);
1826    var type = input.type;
1827    var tag = input.tagName.toLowerCase(); // Normalize case.
1828
1829    // Backup required.
1830    if ($input.prop('required') && !$input.hasData('webform-required')) {
1831      $input.data('webform-required', true);
1832    }
1833
1834    // Backup value.
1835    if (!$input.hasData('webform-value')) {
1836      if (type === 'checkbox' || type === 'radio') {
1837        $input.data('webform-value', $input.prop('checked'));
1838      }
1839      else if (tag === 'select') {
1840        var values = [];
1841        $input.find('option:selected').each(function (i, option) {
1842          values[i] = option.value;
1843        });
1844        $input.data('webform-value', values);
1845      }
1846      else if (type !== 'submit' && type !== 'button') {
1847        $input.data('webform-value', input.value);
1848      }
1849    }
1850  }
1851
1852  /**
1853   * Restore an input's value and required attribute.
1854   *
1855   * @param {element} input
1856   *   An input.
1857   */
1858  function restoreValueAndRequired(input) {
1859    var $input = $(input);
1860
1861    // Restore value.
1862    var value = $input.data('webform-value');
1863    if (typeof value !== 'undefined') {
1864      var type = input.type;
1865      var tag = input.tagName.toLowerCase(); // Normalize case.
1866
1867      if (type === 'checkbox' || type === 'radio') {
1868        $input.prop('checked', value);
1869      }
1870      else if (tag === 'select') {
1871        $.each(value, function (i, option_value) {
1872          $input.find("option[value='" + option_value + "']").prop('selected', true);
1873        });
1874      }
1875      else if (type !== 'submit' && type !== 'button') {
1876        input.value = value;
1877      }
1878      $input.removeData('webform-value');
1879    }
1880
1881    // Restore required.
1882    var required = $input.data('webform-required');
1883    if (typeof required !== 'undefined') {
1884      if (required) {
1885        $input.prop('required', true);
1886      }
1887      $input.removeData('webform-required');
1888    }
1889  }
1890
1891  /**
1892   * Clear an input's value and required attributes.
1893   *
1894   * @param {element} input
1895   *   An input.
1896   */
1897  function clearValueAndRequired(input) {
1898    var $input = $(input);
1899
1900    // Check for #states no clear attribute.
1901    // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/
1902    if ($input.closest('[data-webform-states-no-clear]').length) {
1903      return;
1904    }
1905
1906    // Clear value.
1907    var type = input.type;
1908    var tag = input.tagName.toLowerCase(); // Normalize case.
1909    if (type === 'checkbox' || type === 'radio') {
1910      $input.prop('checked', false);
1911    }
1912    else if (tag === 'select') {
1913      if ($input.find('option[value=""]').length) {
1914        $input.val('');
1915      }
1916      else {
1917        input.selectedIndex = -1;
1918      }
1919    }
1920    else if (type !== 'submit' && type !== 'button') {
1921      input.value = (type === 'color') ? '#000000' : '';
1922    }
1923
1924    // Clear required.
1925    $input.prop('required', false);
1926  }
1927
1928})(jQuery, Drupal);
1929;
1930/**
1931 * @file
1932 * JavaScript behaviors for custom webform #states.
1933 */
1934
1935(function ($, Drupal) {
1936
1937  'use strict';
1938
1939  $(document).on('state:required', function (e) {
1940    if (e.trigger && $(e.target).isWebform()) {
1941      var $target = $(e.target);
1942
1943      // @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset.
1944      // Fix #required for fieldsets.
1945      if ($target.is('.js-form-wrapper.panel')) {
1946        if (e.value) {
1947          $target.find('.panel-heading .panel-title').addClass('js-form-required form-required');
1948        }
1949        else {
1950          $target.find('.panel-heading .panel-title').removeClass('js-form-required form-required');
1951        }
1952      }
1953
1954    }
1955  });
1956
1957})(jQuery, Drupal);
1958;
1959/**
1960 * @file
1961 * Bootstrap Popovers.
1962 */
1963
1964var Drupal = Drupal || {};
1965
1966(function ($, Drupal, Bootstrap) {
1967  "use strict";
1968
1969  var $document = $(document);
1970
1971  /**
1972   * Extend the Bootstrap Popover plugin constructor class.
1973   */
1974  Bootstrap.extendPlugin('popover', function (settings) {
1975    return {
1976      DEFAULTS: {
1977        animation: !!settings.popover_animation,
1978        autoClose: !!settings.popover_auto_close,
1979        enabled: settings.popover_enabled,
1980        html: !!settings.popover_html,
1981        placement: settings.popover_placement,
1982        selector: settings.popover_selector,
1983        trigger: settings.popover_trigger,
1984        title: settings.popover_title,
1985        content: settings.popover_content,
1986        delay: parseInt(settings.popover_delay, 10),
1987        container: settings.popover_container
1988      }
1989    };
1990  });
1991
1992  /**
1993   * Bootstrap Popovers.
1994   *
1995   * @todo This should really be properly delegated if selector option is set.
1996   */
1997  Drupal.behaviors.bootstrapPopovers = {
1998    $activePopover: null,
1999    attach: function (context) {
2000      // Immediately return if popovers are not available.
2001      if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) {
2002        return;
2003      }
2004
2005      var _this = this;
2006
2007      $document
2008        .on('show.bs.popover', '[data-toggle=popover]', function () {
2009          var $trigger = $(this);
2010          var popover = $trigger.data('bs.popover');
2011
2012          // Only keep track of clicked triggers that we're manually handling.
2013          if (popover.options.originalTrigger === 'click') {
2014            if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($trigger)) {
2015              _this.$activePopover.popover('hide');
2016            }
2017            _this.$activePopover = $trigger;
2018          }
2019        })
2020        // Unfortunately, :focusable is only made available when using jQuery
2021        // UI. While this would be the most semantic pseudo selector to use
2022        // here, jQuery UI may not always be loaded. Instead, just use :visible
2023        // here as this just needs some sort of selector here. This activates
2024        // delegate binding to elements in jQuery so it can work it's bubbling
2025        // focus magic since elements don't really propagate their focus events.
2026        // @see https://www.drupal.org/project/bootstrap/issues/3013236
2027        .on('focus.bs.popover', ':visible', function (e) {
2028          var $target = $(e.target);
2029          if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($target) && !$target.closest('.popover.in')[0]) {
2030            _this.$activePopover.popover('hide');
2031            _this.$activePopover = null;
2032          }
2033        })
2034        .on('click.bs.popover', function (e) {
2035          var $target = $(e.target);
2036          if (_this.$activePopover && _this.getOption('autoClose') && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) {
2037            _this.$activePopover.popover('hide');
2038            _this.$activePopover = null;
2039          }
2040        })
2041        .on('keyup.bs.popover', function (e) {
2042          if (_this.$activePopover && _this.getOption('autoClose') && e.which === 27) {
2043            _this.$activePopover.popover('hide');
2044            _this.$activePopover = null;
2045          }
2046        })
2047      ;
2048
2049      var elements = $(context).find('[data-toggle=popover]').toArray();
2050      for (var i = 0; i < elements.length; i++) {
2051        var $element = $(elements[i]);
2052        var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, $element.data());
2053
2054        // Store the original trigger.
2055        options.originalTrigger = options.trigger;
2056
2057        // If the trigger is "click", then we'll handle it manually here.
2058        if (options.trigger === 'click') {
2059          options.trigger = 'manual';
2060        }
2061
2062        // Retrieve content from a target element.
2063        var target = options.target || $element.is('a[href^="#"]') && $element.attr('href');
2064        var $target = $document.find(target).clone();
2065        if (!options.content && $target[0]) {
2066          $target.removeClass('visually-hidden hidden').removeAttr('aria-hidden');
2067          options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || '';
2068        }
2069
2070        // Initialize the popover.
2071        $element.popover(options);
2072
2073        // Handle clicks manually.
2074        if (options.originalTrigger === 'click') {
2075          // To ensure the element is bound multiple times, remove any
2076          // previously set event handler before adding another one.
2077          $element
2078            .off('click.drupal.bootstrap.popover')
2079            .on('click.drupal.bootstrap.popover', function (e) {
2080              $(this).popover('toggle');
2081              e.preventDefault();
2082              e.stopPropagation();
2083            })
2084          ;
2085        }
2086      }
2087    },
2088    detach: function (context) {
2089      // Immediately return if popovers are not available.
2090      if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) {
2091        return;
2092      }
2093
2094      // Destroy all popovers.
2095      $(context).find('[data-toggle="popover"]')
2096        .off('click.drupal.bootstrap.popover')
2097        .popover('destroy')
2098      ;
2099    },
2100    getOption: function(name, defaultValue, element) {
2101      var $element = element ? $(element) : this.$activePopover;
2102      var options = $.extend(true, {}, $.fn.popover.Constructor.DEFAULTS, ($element && $element.data('bs.popover') || {}).options);
2103      if (options[name] !== void 0) {
2104        return options[name];
2105      }
2106      return defaultValue !== void 0 ? defaultValue : void 0;
2107    }
2108  };
2109
2110})(window.jQuery, window.Drupal, window.Drupal.bootstrap);
2111;

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.