PageSourceSearch

https://www.ckequinehospital.com/sites/default/files/js/js_gStaST1BNTsRHEA0BwoTZpRJ3a8ckc0kKj0DI6D-p70.js

js ckequinehospital.com collected 2026-09-27 01:57:34 UTC 78,475 bytes, 2,408 lines download raw bytes

1+function(i,t,e){"use strict";var s={size:{min:.1,max:10,default:1},shrink:{min:.2,max:1,default:.8},regrow:{min:.2,max:1,default:.8},minRows:{min:1,max:99,default:1},maxRows:{min:1,max:99,default:2},prefixReserve:{min:0,max:.8,default:.3},prefixHide:{min:.1,max:10,default:2},alignRight:{type:"boolean",default:!1}},n=function(){var i=t.fn.jquery.split(".");return 1==i[0]&&i[1]<8}();i.rrssbConfigAll=function(i){t(".rrssb").each(function(){t(this).rrssbConfig(i)})},t.fn.rrssbConfig=function(i){if(!t(this).data("settings")||i){var e={};for(var n in s)e[n]=s[n].default,i&&("boolean"==s[n].type?e[n]=Boolean(i[n]):isNaN(parseFloat(i[n]))||(e[n]=Math.min(s[n].max,Math.max(s[n].min,i[n]))));t(this).data("settings",e),h.call(this)}};var r,a=function(){t(".rrssb").each(h)},h=function(){var i=t(this).data("orig");i||(i=function(){var i=t(".rrssb-prefix",this),e=i.length?i.clone().css({visibility:"hidden","white-space":"nowrap",display:"inline"}).appendTo(this):null;t("ul").contents().filter(function(){return this.nodeType===Node.TEXT_NODE}).remove();var s={width:0,buttons:0,height:t("li",this).innerHeight(),fontSize:parseFloat(t(this).css("font-size")),prefixWidth:e?e.innerWidth():0};return t("li",this).each(function(){s.width=Math.max(s.width,t(this).innerWidth()),s.buttons++}),t(this).data("orig",s),e&&e.remove(),s}.call(this));var e=t(this).data("settings"),s=i.width*e.size,r=i.buttons,a=t(this).innerWidth()-1,h=a<s*e.shrink?"":s;n?t("li",this).width(h):t("li",this).innerWidth(h);var o=a/e.shrink,l=i.prefixWidth*e.size;l>o*e.prefixHide?(l=0,t(".rrssb-prefix",this).css("display","none")):t(".rrssb-prefix",this).css("display","");var c=l<=a*e.prefixReserve?o-l:o,f=Math.floor(c/s);f*e.maxRows<r?(t(this).addClass("no-label"),s=i.height*e.size,f=Math.max(1,Math.floor(c/s))):t(this).removeClass("no-label");var d=e.minRows>1?Math.max(1,Math.ceil(r/(e.minRows-1))-1):r;f=Math.min(f,d),f=Math.ceil(r/Math.ceil(r/f)),d=Math.ceil(r/Math.ceil(r/d));var u=Math.floor(1e4/f)/100;t("li",this).css("max-width",u+"%");var m=s*f+l;m>o&&(m-=l,l=0);var p=f<d?e.regrow:1,g=Math.min(p,a/m),b=i.fontSize*e.size*g*.98;if(t(this).css("font-size",b+"px"),l){var x=Math.floor(1e4*l/m)/100;t(".rrssb-buttons",this).css("padding-left",x+"%"),t(".rrssb-prefix",this).css("position","absolute");var v=Math.ceil(r/f)*i.height/i.fontSize;t(".rrssb-prefix",this).css("line-height",v+"em")}else t(".rrssb-buttons",this).css("padding-left",""),t(".rrssb-prefix",this).css("position",""),t(".rrssb-prefix",this).css("line-height","");var w=e.alignRight?"padding-left":"padding-right";if(g>=.999*p){var M=Math.floor(1e4*(a-m*g*1.02)/a)/100;t(this).css(w,M+"%")}else t(this).css(w,"")},o=function(i){r&&clearTimeout(r),r=setTimeout(a,i||200)};t(document).ready(function(){t(".rrssb-buttons a.popup").click(function(e){!function(t,e,s,n){var r=void 0!==i.screenLeft?i.screenLeft:screen.left,a=void 0!==i.screenTop?i.screenTop:screen.top,h=(i.innerWidth?i.innerWidth:document.documentElement.clientWidth?document.documentElement.clientWidth:screen.width)/2-s/2+r,o=(i.innerHeight?i.innerHeight:document.documentElement.clientHeight?document.documentElement.clientHeight:screen.height)/3-n/3+a,l=i.open(t,e,"scrollbars=yes, width="+s+", height="+n+", top="+o+", left="+h);l&&l.focus&&l.focus()}(t(this).attr("href"),t(this).find(".rrssb-text").html(),580,470),e.preventDefault()}),t(i).resize(o),t(document).ready(function(){rrssbConfigAll()})})}(window,jQuery);;
2/**
3 * @file
4 * The RRSSB Drupal Behavior to configure settings.
5 */
6
7(function ($) {
8  'use strict';
9
10  Drupal.behaviors.rrssb = {
11    attach: function (context, settings) {
12      for (var buttonSet in settings.rrssb) {
13        $('.rrssb-bs-' + buttonSet).each(function(){
14          $(this).rrssbConfig(settings.rrssb[buttonSet]);
15        });
16      }
17    }
18  };
19})(jQuery);
20;
21/**
22* DO NOT EDIT THIS FILE.
23* See the following change record for more information,
24* https://www.drupal.org/node/2815083
25* @preserve
26**/
27
28Drupal.debounce = function (func, wait, immediate) {
29  var timeout = void 0;
30  var result = void 0;
31  return function () {
32    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
33      args[_key] = arguments[_key];
34    }
35
36    var context = this;
37    var later = function later() {
38      timeout = null;
39      if (!immediate) {
40        result = func.apply(context, args);
41      }
42    };
43    var callNow = immediate && !timeout;
44    clearTimeout(timeout);
45    timeout = setTimeout(later, wait);
46    if (callNow) {
47      result = func.apply(context, args);
48    }
49    return result;
50  };
51};;
52/**
53* DO NOT EDIT THIS FILE.
54* See the following change record for more information,
55* https://www.drupal.org/node/2815083
56* @preserve
57**/
58
59(function ($, Drupal, debounce) {
60  $.fn.drupalGetSummary = function () {
61    var callback = this.data('summaryCallback');
62    return this[0] && callback ? $.trim(callback(this[0])) : '';
63  };
64
65  $.fn.drupalSetSummary = function (callback) {
66    var self = this;
67
68    if (typeof callback !== 'function') {
69      var val = callback;
70      callback = function callback() {
71        return val;
72      };
73    }
74
75    return this.data('summaryCallback', callback).off('formUpdated.summary').on('formUpdated.summary', function () {
76      self.trigger('summaryUpdated');
77    }).trigger('summaryUpdated');
78  };
79
80  Drupal.behaviors.formSingleSubmit = {
81    attach: function attach() {
82      function onFormSubmit(e) {
83        var $form = $(e.currentTarget);
84        var formValues = $form.serialize();
85        var previousValues = $form.attr('data-drupal-form-submit-last');
86        if (previousValues === formValues) {
87          e.preventDefault();
88        } else {
89          $form.attr('data-drupal-form-submit-last', formValues);
90        }
91      }
92
93      $('body').once('form-single-submit').on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit);
94    }
95  };
96
97  function triggerFormUpdated(element) {
98    $(element).trigger('formUpdated');
99  }
100
101  function fieldsList(form) {
102    var $fieldList = $(form).find('[name]').map(function (index, element) {
103      return element.getAttribute('id');
104    });
105
106    return $.makeArray($fieldList);
107  }
108
109  Drupal.behaviors.formUpdated = {
110    attach: function attach(context) {
111      var $context = $(context);
112      var contextIsForm = $context.is('form');
113      var $forms = (contextIsForm ? $context : $context.find('form')).once('form-updated');
114      var formFields = void 0;
115
116      if ($forms.length) {
117        $.makeArray($forms).forEach(function (form) {
118          var events = 'change.formUpdated input.formUpdated ';
119          var eventHandler = debounce(function (event) {
120            triggerFormUpdated(event.target);
121          }, 300);
122          formFields = fieldsList(form).join(',');
123
124          form.setAttribute('data-drupal-form-fields', formFields);
125          $(form).on(events, eventHandler);
126        });
127      }
128
129      if (contextIsForm) {
130        formFields = fieldsList(context).join(',');
131
132        var currentFields = $(context).attr('data-drupal-form-fields');
133
134        if (formFields !== currentFields) {
135          triggerFormUpdated(context);
136        }
137      }
138    },
139    detach: function detach(context, settings, trigger) {
140      var $context = $(context);
141      var contextIsForm = $context.is('form');
142      if (trigger === 'unload') {
143        var $forms = (contextIsForm ? $context : $context.find('form')).removeOnce('form-updated');
144        if ($forms.length) {
145          $.makeArray($forms).forEach(function (form) {
146            form.removeAttribute('data-drupal-form-fields');
147            $(form).off('.formUpdated');
148          });
149        }
150      }
151    }
152  };
153
154  Drupal.behaviors.fillUserInfoFromBrowser = {
155    attach: function attach(context, settings) {
156      var userInfo = ['name', 'mail', 'homepage'];
157      var $forms = $('[data-user-info-from-browser]').once('user-info-from-browser');
158      if ($forms.length) {
159        userInfo.forEach(function (info) {
160          var $element = $forms.find('[name=' + info + ']');
161          var browserData = localStorage.getItem('Drupal.visitor.' + info);
162          var emptyOrDefault = $element.val() === '' || $element.attr('data-drupal-default-value') === $element.val();
163          if ($element.length && emptyOrDefault && browserData) {
164            $element.val(browserData);
165          }
166        });
167      }
168      $forms.on('submit', function () {
169        userInfo.forEach(function (info) {
170          var $element = $forms.find('[name=' + info + ']');
171          if ($element.length) {
172            localStorage.setItem('Drupal.visitor.' + info, $element.val());
173          }
174        });
175      });
176    }
177  };
178
179  var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e) {
180    var url = void 0;
181    if (e.type === 'click') {
182      url = e.currentTarget.location ? e.currentTarget.location : e.currentTarget;
183    } else {
184      url = window.location;
185    }
186    var hash = url.hash.substr(1);
187    if (hash) {
188      var $target = $('#' + hash);
189      $('body').trigger('formFragmentLinkClickOrHashChange', [$target]);
190
191      setTimeout(function () {
192        return $target.trigger('focus');
193      }, 300);
194    }
195  };
196
197  var debouncedHandleFragmentLinkClickOrHashChange = debounce(handleFragmentLinkClickOrHashChange, 300, true);
198
199  $(window).on('hashchange.form-fragment', debouncedHandleFragmentLinkClickOrHashChange);
200
201  $(document).on('click.form-fragment', 'a[href*="#"]', debouncedHandleFragmentLinkClickOrHashChange);
202})(jQuery, Drupal, Drupal.debounce);;
203/**
204 * @file
205 * Webform behaviors.
206 */
207
208(function ($, Drupal) {
209
210  'use strict';
211
212  // Trigger Drupal's attaching of behaviors after the page is
213  // completely loaded.
214  // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button
215  // @see https://stackoverflow.com/questions/20899274/how-to-refresh-page-on-back-button-click/20899422#20899422
216  var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase()));
217  if (isChrome) {
218    // Track back button in navigation.
219    // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button
220    var backButton = false;
221    if (window.performance) {
222      var navEntries = window.performance.getEntriesByType('navigation');
223      if (navEntries.length > 0 && navEntries[0].type === 'back_forward') {
224        backButton = true;
225      }
226      else if (window.performance.navigation
227        && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) {
228        backButton = true;
229      }
230    }
231
232    // If the back button is pressed, delay Drupal's attaching of behaviors.
233    if (backButton) {
234      var attachBehaviors = Drupal.attachBehaviors;
235      Drupal.attachBehaviors = function (context, settings) {
236        setTimeout(function (context, settings) {
237          attachBehaviors(context, settings);
238        }, 300);
239      };
240    }
241  }
242
243})(jQuery, Drupal);
244;
245/**
246* DO NOT EDIT THIS FILE.
247* See the following change record for more information,
248* https://www.drupal.org/node/2815083
249* @preserve
250**/
251
252(function ($, Drupal) {
253  var states = {
254    postponed: []
255  };
256
257  Drupal.states = states;
258
259  function invert(a, invertState) {
260    return invertState && typeof a !== 'undefined' ? !a : a;
261  }
262
263  function _compare2(a, b) {
264    if (a === b) {
265      return typeof a === 'undefined' ? a : true;
266    }
267
268    return typeof a === 'undefined' || typeof b === 'undefined';
269  }
270
271  function ternary(a, b) {
272    if (typeof a === 'undefined') {
273      return b;
274    }
275    if (typeof b === 'undefined') {
276      return a;
277    }
278
279    return a && b;
280  }
281
282  Drupal.behaviors.states = {
283    attach: function attach(context, settings) {
284      var $states = $(context).find('[data-drupal-states]');
285      var il = $states.length;
286
287      var _loop = function _loop(i) {
288        var config = JSON.parse($states[i].getAttribute('data-drupal-states'));
289        Object.keys(config || {}).forEach(function (state) {
290          new states.Dependent({
291            element: $($states[i]),
292            state: states.State.sanitize(state),
293            constraints: config[state]
294          });
295        });
296      };
297
298      for (var i = 0; i < il; i++) {
299        _loop(i);
300      }
301
302      while (states.postponed.length) {
303        states.postponed.shift()();
304      }
305    }
306  };
307
308  states.Dependent = function (args) {
309    var _this = this;
310
311    $.extend(this, { values: {}, oldValue: null }, args);
312
313    this.dependees = this.getDependees();
314    Object.keys(this.dependees || {}).forEach(function (selector) {
315      _this.initializeDependee(selector, _this.dependees[selector]);
316    });
317  };
318
319  states.Dependent.comparisons = {
320    RegExp: function RegExp(reference, value) {
321      return reference.test(value);
322    },
323    Function: function Function(reference, value) {
324      return reference(value);
325    },
326    Number: function Number(reference, value) {
327      return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value);
328    }
329  };
330
331  states.Dependent.prototype = {
332    initializeDependee: function initializeDependee(selector, dependeeStates) {
333      var _this2 = this;
334
335      this.values[selector] = {};
336
337      Object.keys(dependeeStates).forEach(function (i) {
338        var state = dependeeStates[i];
339
340        if ($.inArray(state, dependeeStates) === -1) {
341          return;
342        }
343
344        state = states.State.sanitize(state);
345
346        _this2.values[selector][state.name] = null;
347
348        $(selector).on('state:' + state, { selector: selector, state: state }, function (e) {
349          _this2.update(e.data.selector, e.data.state, e.value);
350        });
351
352        new states.Trigger({ selector: selector, state: state });
353      });
354    },
355    compare: function compare(reference, selector, state) {
356      var value = this.values[selector][state.name];
357      if (reference.constructor.name in states.Dependent.comparisons) {
358        return states.Dependent.comparisons[reference.constructor.name](reference, value);
359      }
360
361      return _compare2(reference, value);
362    },
363    update: function update(selector, state, value) {
364      if (value !== this.values[selector][state.name]) {
365        this.values[selector][state.name] = value;
366        this.reevaluate();
367      }
368    },
369    reevaluate: function reevaluate() {
370      var value = this.verifyConstraints(this.constraints);
371
372      if (value !== this.oldValue) {
373        this.oldValue = value;
374
375        value = invert(value, this.state.invert);
376
377        this.element.trigger({
378          type: 'state:' + this.state,
379          value: value,
380          trigger: true
381        });
382      }
383    },
384    verifyConstraints: function verifyConstraints(constraints, selector) {
385      var result = void 0;
386      if ($.isArray(constraints)) {
387        var hasXor = $.inArray('xor', constraints) === -1;
388        var len = constraints.length;
389        for (var i = 0; i < len; i++) {
390          if (constraints[i] !== 'xor') {
391            var constraint = this.checkConstraints(constraints[i], selector, i);
392
393            if (constraint && (hasXor || result)) {
394              return hasXor;
395            }
396            result = result || constraint;
397          }
398        }
399      } else if ($.isPlainObject(constraints)) {
400          for (var n in constraints) {
401            if (constraints.hasOwnProperty(n)) {
402              result = ternary(result, this.checkConstraints(constraints[n], selector, n));
403
404              if (result === false) {
405                return false;
406              }
407            }
408          }
409        }
410      return result;
411    },
412    checkConstraints: function checkConstraints(value, selector, state) {
413      if (typeof state !== 'string' || /[0-9]/.test(state[0])) {
414        state = null;
415      } else if (typeof selector === 'undefined') {
416        selector = state;
417        state = null;
418      }
419
420      if (state !== null) {
421        state = states.State.sanitize(state);
422        return invert(this.compare(value, selector, state), state.invert);
423      }
424
425      return this.verifyConstraints(value, selector);
426    },
427    getDependees: function getDependees() {
428      var cache = {};
429
430      var _compare = this.compare;
431      this.compare = function (reference, selector, state) {
432        (cache[selector] || (cache[selector] = [])).push(state.name);
433      };
434
435      this.verifyConstraints(this.constraints);
436
437      this.compare = _compare;
438
439      return cache;
440    }
441  };
442
443  states.Trigger = function (args) {
444    $.extend(this, args);
445
446    if (this.state in states.Trigger.states) {
447      this.element = $(this.selector);
448
449      if (!this.element.data('trigger:' + this.state)) {
450        this.initialize();
451      }
452    }
453  };
454
455  states.Trigger.prototype = {
456    initialize: function initialize() {
457      var _this3 = this;
458
459      var trigger = states.Trigger.states[this.state];
460
461      if (typeof trigger === 'function') {
462        trigger.call(window, this.element);
463      } else {
464        Object.keys(trigger || {}).forEach(function (event) {
465          _this3.defaultTrigger(event, trigger[event]);
466        });
467      }
468
469      this.element.data('trigger:' + this.state, true);
470    },
471    defaultTrigger: function defaultTrigger(event, valueFn) {
472      var oldValue = valueFn.call(this.element);
473
474      this.element.on(event, $.proxy(function (e) {
475        var value = valueFn.call(this.element, e);
476
477        if (oldValue !== value) {
478          this.element.trigger({
479            type: 'state:' + this.state,
480            value: value,
481            oldValue: oldValue
482          });
483          oldValue = value;
484        }
485      }, this));
486
487      states.postponed.push($.proxy(function () {
488        this.element.trigger({
489          type: 'state:' + this.state,
490          value: oldValue,
491          oldValue: null
492        });
493      }, this));
494    }
495  };
496
497  states.Trigger.states = {
498    empty: {
499      keyup: function keyup() {
500        return this.val() === '';
501      }
502    },
503
504    checked: {
505      change: function change() {
506        var checked = false;
507        this.each(function () {
508          checked = $(this).prop('checked');
509
510          return !checked;
511        });
512        return checked;
513      }
514    },
515
516    value: {
517      keyup: function keyup() {
518        if (this.length > 1) {
519          return this.filter(':checked').val() || false;
520        }
521        return this.val();
522      },
523      change: function change() {
524        if (this.length > 1) {
525          return this.filter(':checked').val() || false;
526        }
527        return this.val();
528      }
529    },
530
531    collapsed: {
532      collapsed: function collapsed(e) {
533        return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]');
534      }
535    }
536  };
537
538  states.State = function (state) {
539    this.pristine = state;
540    this.name = state;
541
542    var process = true;
543    do {
544      while (this.name.charAt(0) === '!') {
545        this.name = this.name.substring(1);
546        this.invert = !this.invert;
547      }
548
549      if (this.name in states.State.aliases) {
550        this.name = states.State.aliases[this.name];
551      } else {
552        process = false;
553      }
554    } while (process);
555  };
556
557  states.State.sanitize = function (state) {
558    if (state instanceof states.State) {
559      return state;
560    }
561
562    return new states.State(state);
563  };
564
565  states.State.aliases = {
566    enabled: '!disabled',
567    invisible: '!visible',
568    invalid: '!valid',
569    untouched: '!touched',
570    optional: '!required',
571    filled: '!empty',
572    unchecked: '!checked',
573    irrelevant: '!relevant',
574    expanded: '!collapsed',
575    open: '!collapsed',
576    closed: 'collapsed',
577    readwrite: '!readonly'
578  };
579
580  states.State.prototype = {
581    invert: false,
582
583    toString: function toString() {
584      return this.name;
585    }
586  };
587
588  var $document = $(document);
589  $document.on('state:disabled', function (e) {
590    if (e.trigger) {
591      $(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);
592    }
593  });
594
595  $document.on('state:required', function (e) {
596    if (e.trigger) {
597      if (e.value) {
598        var label = 'label' + (e.target.id ? '[for=' + e.target.id + ']' : '');
599        var $label = $(e.target).attr({ required: 'required', 'aria-required': 'true' }).closest('.js-form-item, .js-form-wrapper').find(label);
600
601        if (!$label.hasClass('js-form-required').length) {
602          $label.addClass('js-form-required form-required');
603        }
604      } else {
605        $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required');
606      }
607    }
608  });
609
610  $document.on('state:visible', function (e) {
611    if (e.trigger) {
612      $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value);
613    }
614  });
615
616  $document.on('state:checked', function (e) {
617    if (e.trigger) {
618      $(e.target).prop('checked', e.value);
619    }
620  });
621
622  $document.on('state:collapsed', function (e) {
623    if (e.trigger) {
624      if ($(e.target).is('[open]') === e.value) {
625        $(e.target).find('> summary').trigger('click');
626      }
627    }
628  });
629})(jQuery, Drupal);;
630/**
631 * @file
632 * JavaScript behaviors for custom webform #states.
633 */
634
635(function ($, Drupal) {
636
637  'use strict';
638
639  Drupal.webform = Drupal.webform || {};
640  Drupal.webform.states = Drupal.webform.states || {};
641  Drupal.webform.states.slideDown = Drupal.webform.states.slideDown || {};
642  Drupal.webform.states.slideDown.duration = 'slow';
643  Drupal.webform.states.slideUp = Drupal.webform.states.slideUp || {};
644  Drupal.webform.states.slideUp.duration = 'fast';
645
646  /* ************************************************************************ */
647  // jQuery functions.
648  /* ************************************************************************ */
649
650  /**
651   * Check if an element has a specified data attribute.
652   *
653   * @param {string} data
654   *   The data attribute name.
655   *
656   * @return {boolean}
657   *   TRUE if an element has a specified data attribute.
658   */
659  $.fn.hasData = function (data) {
660    return (typeof this.data(data) !== 'undefined');
661  };
662
663  /**
664   * Check if element is within the webform or not.
665   *
666   * @return {boolean}
667   *   TRUE if element is within the webform.
668   */
669  $.fn.isWebform = function () {
670    return $(this).closest('form.webform-submission-form, form[id^="webform"], form[data-is-webform]').length ? true : false;
671  };
672
673  /**
674   * Check if element is to be treated as a webform element.
675   *
676   * @return {boolean}
677   *   TRUE if element is to be treated as a webform element.
678   */
679  $.fn.isWebformElement = function () {
680    return ($(this).isWebform() || $(this).closest('[data-is-webform-element]').length) ? true : false;
681  };
682
683  /* ************************************************************************ */
684  // Trigger.
685  /* ************************************************************************ */
686
687  // The change event is triggered by cut-n-paste and select menus.
688  // Issue #2445271: #states element empty check not triggered on mouse
689  // based paste.
690  // @see https://www.drupal.org/node/2445271
691  Drupal.states.Trigger.states.empty.change = function change() {
692    return this.val() === '';
693  };
694
695  /* ************************************************************************ */
696  // Dependents.
697  /* ************************************************************************ */
698
699
700  // Apply solution included in #1962800 patch.
701  // Issue #1962800: Form #states not working with literal integers as
702  // values in IE11.
703  // @see https://www.drupal.org/project/drupal/issues/1962800
704  // @see https://www.drupal.org/files/issues/core-states-not-working-with-integers-ie11_1962800_46.patch
705  //
706  // This issue causes pattern, less than, and greater than support to break.
707  // @see https://www.drupal.org/project/webform/issues/2981724
708  var states = Drupal.states;
709  Drupal.states.Dependent.prototype.compare = function compare(reference, selector, state) {
710    var value = this.values[selector][state.name];
711
712    var name = reference.constructor.name;
713    if (!name) {
714      name = $.type(reference);
715
716      name = name.charAt(0).toUpperCase() + name.slice(1);
717    }
718    if (name in states.Dependent.comparisons) {
719      return states.Dependent.comparisons[name](reference, value);
720    }
721
722    if (reference.constructor.name in states.Dependent.comparisons) {
723      return states.Dependent.comparisons[reference.constructor.name](reference, value);
724    }
725
726    return _compare2(reference, value);
727  };
728  function _compare2(a, b) {
729    if (a === b) {
730      return typeof a === 'undefined' ? a : true;
731    }
732
733    return typeof a === 'undefined' || typeof b === 'undefined';
734  }
735
736  // Adds pattern, less than, and greater than support to #state API.
737  // @see http://drupalsun.com/julia-evans/2012/03/09/extending-form-api-states-regular-expressions
738  Drupal.states.Dependent.comparisons.Object = function (reference, value) {
739    if ('pattern' in reference) {
740      return (new RegExp(reference['pattern'])).test(value);
741    }
742    else if ('!pattern' in reference) {
743      return !((new RegExp(reference['!pattern'])).test(value));
744    }
745    else if ('less' in reference) {
746      return (value !== '' && parseFloat(reference['less']) > parseFloat(value));
747    }
748    else if ('less_equal' in reference) {
749      return (value !== '' && parseFloat(reference['less_equal']) >= parseFloat(value));
750    }
751    else if ('greater' in reference) {
752      return (value !== '' && parseFloat(reference['greater']) < parseFloat(value));
753    }
754    else if ('greater_equal' in reference) {
755      return (value !== '' && parseFloat(reference['greater_equal']) <= parseFloat(value));
756    }
757    else if ('between' in reference || '!between' in reference) {
758      if (value === '') {
759        return false;
760      }
761
762      var between = reference['between'] || reference['!between'];
763      var betweenParts = between.split(':');
764      var greater = betweenParts[0];
765      var less = (typeof betweenParts[1] !== 'undefined') ? betweenParts[1] : null;
766      var isGreaterThan = (greater === null || greater === '' || parseFloat(value) >= parseFloat(greater));
767      var isLessThan = (less === null || less === '' || parseFloat(value) <= parseFloat(less));
768      var result = (isGreaterThan && isLessThan);
769      return (reference['!between']) ? !result : result;
770    }
771    else {
772      return reference.indexOf(value) !== false;
773    }
774  };
775
776  /* ************************************************************************ */
777  // States events.
778  /* ************************************************************************ */
779
780  var $document = $(document);
781
782  $document.on('state:required', function (e) {
783    if (e.trigger && $(e.target).isWebformElement()) {
784      var $target = $(e.target);
785      // Fix #required file upload.
786      // @see Issue #2860529: Conditional required File upload field don't work.
787      toggleRequired($target.find('input[type="file"]'), e.value);
788
789      // Fix #required for radios and likert.
790      // @see Issue #2856795: If radio buttons are required but not filled form is nevertheless submitted.
791      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')) {
792        $target.toggleClass('required', e.value);
793        toggleRequired($target.find('input[type="radio"]'), e.value);
794      }
795
796      // Fix #required for checkboxes.
797      // @see Issue #2938414: Checkboxes don't support #states required.
798      // @see checkboxRequiredhandler
799      if ($target.is('.js-form-type-checkboxes, .js-form-type-webform-checkboxes-other, .js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other')) {
800        $target.toggleClass('required', e.value);
801        var $checkboxes = $target.find('input[type="checkbox"]');
802        if (e.value) {
803          // Add event handler.
804          $checkboxes.on('click', statesCheckboxesRequiredEventHandler);
805          // Initialize and add required attribute.
806          checkboxesRequired($target);
807        }
808        else {
809          // Remove event handler.
810          $checkboxes.off('click', statesCheckboxesRequiredEventHandler);
811          // Remove required attribute.
812          toggleRequired($checkboxes, false);
813        }
814      }
815
816      // Fix #required for tableselect.
817      // @see Issue #3212581: Table select does not trigger client side validation
818      if ($target.is('.js-webform-tableselect')) {
819        $target.toggleClass('required', e.value);
820        var isMultiple = $target.is('[multiple]');
821        if (isMultiple) {
822          // Checkboxes.
823          var $tbody = $target.find('tbody');
824          var $checkboxes = $tbody.find('input[type="checkbox"]');
825          copyRequireMessage($target, $checkboxes);
826          if (e.value) {
827            $checkboxes.on('click change', statesCheckboxesRequiredEventHandler);
828            checkboxesRequired($tbody);
829          }
830          else {
831            $checkboxes.off('click change ', statesCheckboxesRequiredEventHandler);
832            toggleRequired($tbody, false);
833          }
834        }
835        else {
836          // Radios.
837          var $radios = $target.find('input[type="radio"]');
838          copyRequireMessage($target, $radios);
839          toggleRequired($radios, e.value);
840        }
841      }
842
843      // Fix required label for elements without the for attribute.
844      // @see Issue #3145300: Conditional Visible Select Other not working.
845      if ($target.is('.js-form-type-webform-select-other, .js-webform-type-webform-select-other')) {
846        var $select = $target.find('select');
847        toggleRequired($select, e.value);
848        copyRequireMessage($target, $select);
849      }
850      if ($target.find('> label:not([for])').length) {
851        $target.find('> label').toggleClass('js-form-required form-required', e.value);
852      }
853
854      // Fix required label for checkboxes and radios.
855      // @see Issue #2938414: Checkboxes don't support #states required
856      // @see Issue #2731991: Setting required on radios marks all options required.
857      // @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset.
858      // Fix #required for fieldsets.
859      // @see Issue #2977569: Hidden fieldsets that become visible with conditional logic cannot be made required.
860      if ($target.is('.js-webform-type-radios, .js-webform-type-checkboxes, fieldset')) {
861        $target.find('legend span.fieldset-legend:not(.visually-hidden)').toggleClass('js-form-required form-required', e.value);
862      }
863
864      // Issue #2986017: Fieldsets shouldn't have required attribute.
865      if ($target.is('fieldset')) {
866        $target.removeAttr('required aria-required');
867      }
868    }
869  });
870
871  $document.on('state:checked', function (e) {
872    if (e.trigger) {
873      $(e.target).trigger('change');
874    }
875  });
876
877  $document.on('state:readonly', function (e) {
878    if (e.trigger && $(e.target).isWebformElement()) {
879      $(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);
880
881      // Trigger webform:readonly.
882      $(e.target).trigger('webform:readonly')
883        .find('select, input, textarea, button').trigger('webform:readonly');
884    }
885  });
886
887  $document.on('state:visible state:visible-slide', function (e) {
888    if (e.trigger && $(e.target).isWebformElement()) {
889      if (e.value) {
890        $(':input', e.target).addBack().each(function () {
891          restoreValueAndRequired(this);
892          triggerEventHandlers(this);
893        });
894      }
895      else {
896        // @see https://www.sitepoint.com/jquery-function-clear-form-data/
897        $(':input', e.target).addBack().each(function () {
898          backupValueAndRequired(this);
899          clearValueAndRequired(this);
900          triggerEventHandlers(this);
901        });
902      }
903    }
904  });
905
906  $document.on('state:visible-slide', function (e) {
907    if (e.trigger && $(e.target).isWebformElement()) {
908      var effect = e.value ? 'slideDown' : 'slideUp';
909      var duration = Drupal.webform.states[effect].duration;
910      $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper')[effect](duration);
911    }
912  });
913  Drupal.states.State.aliases['invisible-slide'] = '!visible-slide';
914
915  $document.on('state:disabled', function (e) {
916    if (e.trigger && $(e.target).isWebformElement()) {
917      // Make sure disabled property is set before triggering webform:disabled.
918      // Copied from: core/misc/states.js
919      $(e.target)
920        .prop('disabled', e.value)
921        .closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value)
922        .find('select, input, textarea, button').prop('disabled', e.value);
923
924      // Never disable hidden file[fids] because the existing values will
925      // be completely lost when the webform is submitted.
926      var fileElements = $(e.target)
927        .find(':input[type="hidden"][name$="[fids]"]');
928      if (fileElements.length) {
929        // Remove 'disabled' attribute from fieldset which will block
930        // all disabled elements from being submitted.
931        if ($(e.target).is('fieldset')) {
932          $(e.target).prop('disabled', false);
933        }
934        fileElements.removeAttr('disabled');
935      }
936
937      // Trigger webform:disabled.
938      $(e.target).trigger('webform:disabled')
939        .find('select, input, textarea, button').trigger('webform:disabled');
940    }
941  });
942
943  /* ************************************************************************ */
944  // Behaviors.
945  /* ************************************************************************ */
946
947  /**
948   * Adds HTML5 validation to required checkboxes.
949   *
950   * @type {Drupal~behavior}
951   *
952   * @see https://www.drupal.org/project/webform/issues/3068998
953   */
954  Drupal.behaviors.webformCheckboxesRequired = {
955    attach: function (context) {
956      $('.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)
957        .once('webform-checkboxes-required')
958        .each(function () {
959          var $element = $(this);
960          $element.find('input[type="checkbox"]').on('click', statesCheckboxesRequiredEventHandler);
961          setTimeout(function () {checkboxesRequired($element);});
962        });
963    }
964  };
965
966  /**
967   * Adds HTML5 validation to required radios.
968   *
969   * @type {Drupal~behavior}
970   *
971   * @see https://www.drupal.org/project/webform/issues/2856795
972   */
973  Drupal.behaviors.webformRadiosRequired = {
974    attach: function (context) {
975      $('.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)
976        .once('webform-radios-required')
977        .each(function () {
978          var $element = $(this);
979          setTimeout(function () {radiosRequired($element);});
980        });
981    }
982  };
983
984 /**
985   * Adds HTML5 validation to required table select.
986   *
987   * @type {Drupal~behavior}
988   *
989   * @see https://www.drupal.org/project/webform/issues/2856795
990   */
991  Drupal.behaviors.webformTableSelectRequired = {
992    attach: function (context) {
993      $('.js-webform-tableselect.required', context)
994        .once('webform-tableselect-required')
995        .each(function () {
996          var $element = $(this);
997          var $tbody = $element.find('tbody');
998          var isMultiple = $element.is('[multiple]');
999
1000          if (isMultiple) {
1001            // Check all checkbox triggers checkbox 'change' event on
1002            // select and deselect all.
1003            // @see Drupal.tableSelect
1004            $tbody.find('input[type="checkbox"]').on('click change', function () {
1005              checkboxesRequired($tbody);
1006            });
1007          }
1008
1009          setTimeout(function () {
1010            isMultiple ? checkboxesRequired($tbody) : radiosRequired($element);
1011          });
1012        });
1013    }
1014  };
1015
1016  /**
1017   * Add HTML5 multiple checkboxes required validation.
1018   *
1019   * @param {jQuery} $element
1020   *   An jQuery object containing HTML5 radios.
1021   *
1022   * @see https://stackoverflow.com/a/37825072/145846
1023   */
1024  function checkboxesRequired($element) {
1025    var $firstCheckbox = $element.find('input[type="checkbox"]').first();
1026    var isChecked = $element.find('input[type="checkbox"]').is(':checked');
1027    toggleRequired($firstCheckbox, !isChecked);
1028    copyRequireMessage($element, $firstCheckbox);
1029  }
1030
1031  /**
1032   * Add HTML5 radios required validation.
1033   *
1034   * @param {jQuery} $element
1035   *   An jQuery object containing HTML5 radios.
1036   *
1037   * @see https://www.drupal.org/project/webform/issues/2856795
1038   */
1039  function radiosRequired($element) {
1040    var $radios = $element.find('input[type="radio"]');
1041    var isRequired = $element.hasClass('required');
1042    toggleRequired($radios, isRequired);
1043    copyRequireMessage($element, $radios);
1044  }
1045
1046  /* ************************************************************************ */
1047  // Event handlers.
1048  /* ************************************************************************ */
1049
1050  /**
1051   * Trigger #states API HTML5 multiple checkboxes required validation.
1052   *
1053   * @see https://stackoverflow.com/a/37825072/145846
1054   */
1055  function statesCheckboxesRequiredEventHandler() {
1056    var $element = $(this).closest('.js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other');
1057    checkboxesRequired($element);
1058  }
1059
1060  /**
1061   * Trigger an input's event handlers.
1062   *
1063   * @param {element} input
1064   *   An input.
1065   */
1066  function triggerEventHandlers(input) {
1067    var $input = $(input);
1068    var type = input.type;
1069    var tag = input.tagName.toLowerCase();
1070    // Add 'webform.states' as extra parameter to event handlers.
1071    // @see Drupal.behaviors.webformUnsaved
1072    var extraParameters = ['webform.states'];
1073    if (type === 'checkbox' || type === 'radio') {
1074      $input
1075        .trigger('change', extraParameters)
1076        .trigger('blur', extraParameters);
1077    }
1078    else if (tag === 'select') {
1079      // Do not trigger the onchange event for Address element's country code
1080      // when it is initialized.
1081      // @see \Drupal\address\Element\Country
1082      if ($input.closest('.webform-type-address').length) {
1083        if (!$input.data('webform-states-address-initialized')
1084          && $input.attr('autocomplete') === 'country'
1085          && $input.val() === $input.find("option[selected]").attr('value')) {
1086          return;
1087        }
1088        $input.data('webform-states-address-initialized', true);
1089      }
1090
1091      $input
1092        .trigger('change', extraParameters)
1093        .trigger('blur', extraParameters);
1094    }
1095    else if (type !== 'submit' && type !== 'button' && type !== 'file') {
1096      // Make sure input mask is removed and then reset when value is restored.
1097      // @see https://www.drupal.org/project/webform/issues/3124155
1098      // @see https://www.drupal.org/project/webform/issues/3202795
1099      var hasInputMask = ($.fn.inputmask && $input.hasClass('js-webform-input-mask'));
1100      hasInputMask && $input.inputmask('remove');
1101
1102      $input
1103        .trigger('input', extraParameters)
1104        .trigger('change', extraParameters)
1105        .trigger('keydown', extraParameters)
1106        .trigger('keyup', extraParameters)
1107        .trigger('blur', extraParameters);
1108
1109      hasInputMask && $input.inputmask();
1110    }
1111  }
1112
1113  /* ************************************************************************ */
1114  // Backup and restore value functions.
1115  /* ************************************************************************ */
1116
1117  /**
1118   * Backup an input's current value and required attribute
1119   *
1120   * @param {element} input
1121   *   An input.
1122   */
1123  function backupValueAndRequired(input) {
1124    var $input = $(input);
1125    var type = input.type;
1126    var tag = input.tagName.toLowerCase(); // Normalize case.
1127
1128    // Backup required.
1129    if ($input.prop('required') && !$input.hasData('webform-required')) {
1130      $input.data('webform-required', true);
1131    }
1132
1133    // Backup value.
1134    if (!$input.hasData('webform-value')) {
1135      if (type === 'checkbox' || type === 'radio') {
1136        $input.data('webform-value', $input.prop('checked'));
1137      }
1138      else if (tag === 'select') {
1139        var values = [];
1140        $input.find('option:selected').each(function (i, option) {
1141          values[i] = option.value;
1142        });
1143        $input.data('webform-value', values);
1144      }
1145      else if (type !== 'submit' && type !== 'button') {
1146        $input.data('webform-value', input.value);
1147      }
1148    }
1149  }
1150
1151  /**
1152   * Restore an input's value and required attribute.
1153   *
1154   * @param {element} input
1155   *   An input.
1156   */
1157  function restoreValueAndRequired(input) {
1158    var $input = $(input);
1159
1160    // Restore value.
1161    var value = $input.data('webform-value');
1162    if (typeof value !== 'undefined') {
1163      var type = input.type;
1164      var tag = input.tagName.toLowerCase(); // Normalize case.
1165
1166      if (type === 'checkbox' || type === 'radio') {
1167        $input.prop('checked', value);
1168      }
1169      else if (tag === 'select') {
1170        $.each(value, function (i, option_value) {
1171          // Prevent "Syntax error, unrecognized expression" error by
1172          // escaping single quotes.
1173          // @see https://forum.jquery.com/topic/escape-characters-prior-to-using-selector
1174          option_value = option_value.replace(/'/g, "\\\'");
1175          $input.find("option[value='" + option_value + "']").prop('selected', true);
1176        });
1177      }
1178      else if (type !== 'submit' && type !== 'button') {
1179        input.value = value;
1180      }
1181      $input.removeData('webform-value');
1182    }
1183
1184    // Restore required.
1185    var required = $input.data('webform-required');
1186    if (typeof required !== 'undefined') {
1187      if (required) {
1188        $input.prop('required', true);
1189      }
1190      $input.removeData('webform-required');
1191    }
1192  }
1193
1194  /**
1195   * Clear an input's value and required attributes.
1196   *
1197   * @param {element} input
1198   *   An input.
1199   */
1200  function clearValueAndRequired(input) {
1201    var $input = $(input);
1202
1203    // Check for #states no clear attribute.
1204    // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/
1205    if ($input.closest('[data-webform-states-no-clear]').length) {
1206      return;
1207    }
1208
1209    // Clear value.
1210    var type = input.type;
1211    var tag = input.tagName.toLowerCase(); // Normalize case.
1212    if (type === 'checkbox' || type === 'radio') {
1213      $input.prop('checked', false);
1214    }
1215    else if (tag === 'select') {
1216      if ($input.find('option[value=""]').length) {
1217        $input.val('');
1218      }
1219      else {
1220        input.selectedIndex = -1;
1221      }
1222    }
1223    else if (type !== 'submit' && type !== 'button') {
1224      input.value = (type === 'color') ? '#000000' : '';
1225    }
1226
1227    // Clear required.
1228    $input.prop('required', false);
1229  }
1230
1231  /* ************************************************************************ */
1232  // Helper functions.
1233  /* ************************************************************************ */
1234
1235  /**
1236   * Toggle an input's required attributes.
1237   *
1238   * @param {element} $input
1239   *   An input.
1240   * @param {boolean} required
1241   *   Is input required.
1242   */
1243  function toggleRequired($input, required) {
1244    var isCheckboxOrRadio = ($input.attr('type') === 'radio' || $input.attr('type') === 'checkbox');
1245    if (required) {
1246      if (isCheckboxOrRadio) {
1247        $input.attr({'required': 'required'});
1248      }
1249      else {
1250        $input.attr({'required': 'required', 'aria-required': 'true'});
1251      }
1252    }
1253    else {
1254      if (isCheckboxOrRadio) {
1255        $input.removeAttr('required');
1256      }
1257      else {
1258        $input.removeAttr('required aria-required');
1259      }
1260    }
1261  }
1262
1263  /**
1264   * Copy the clientside_validation.module's message.
1265   *
1266   * @param {jQuery} $source
1267   *   The source element.
1268   * @param {jQuery} $destination
1269   *   The destination element.
1270   */
1271  function copyRequireMessage($source, $destination) {
1272    if ($source.attr('data-msg-required')) {
1273      $destination.attr('data-msg-required', $source.attr('data-msg-required'));
1274    }
1275  }
1276
1277})(jQuery, Drupal);
1278;
1279/**
1280 * @file
1281 * JavaScript behaviors for webforms.
1282 */
1283
1284(function ($, Drupal) {
1285
1286  'use strict';
1287
1288  /**
1289   * Remove single submit event listener.
1290   *
1291   * @type {Drupal~behavior}
1292   *
1293   * @prop {Drupal~behaviorAttach} attach
1294   *   Attaches the behavior for removing single submit event listener.
1295   *
1296   * @see Drupal.behaviors.formSingleSubmit
1297   */
1298  Drupal.behaviors.webformRemoveFormSingleSubmit = {
1299    attach: function attach() {
1300      function onFormSubmit(e) {
1301        var $form = $(e.currentTarget);
1302        $form.removeAttr('data-drupal-form-submit-last');
1303      }
1304      $('body')
1305        .once('webform-single-submit')
1306        .on('submit.singleSubmit', 'form.webform-remove-single-submit', onFormSubmit);
1307    }
1308  };
1309
1310  /**
1311   * Prevent webform autosubmit on wizard pages.
1312   *
1313   * @type {Drupal~behavior}
1314   *
1315   * @prop {Drupal~behaviorAttach} attach
1316   *   Attaches the behavior for disabling webform autosubmit.
1317   *   Wizard pages need to be progressed with the Previous or Next buttons,
1318   *   not by pressing Enter.
1319   */
1320  Drupal.behaviors.webformDisableAutoSubmit = {
1321    attach: function (context) {
1322      // Not using context so that inputs loaded via Ajax will have autosubmit
1323      // disabled.
1324      // @see http://stackoverflow.com/questions/11235622/jquery-disable-form-submit-on-enter
1325      $('.js-webform-disable-autosubmit input')
1326        .not(':button, :submit, :reset, :image, :file')
1327        .once('webform-disable-autosubmit')
1328        .on('keyup keypress', function (e) {
1329          if (e.which === 13) {
1330            e.preventDefault();
1331            return false;
1332          }
1333        });
1334    }
1335  };
1336
1337  /**
1338   * Custom required and pattern validation error messages.
1339   *
1340   * @type {Drupal~behavior}
1341   *
1342   * @prop {Drupal~behaviorAttach} attach
1343   *   Attaches the behavior for the webform custom required and pattern
1344   *   validation error messages.
1345   *
1346   * @see http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message
1347   **/
1348  Drupal.behaviors.webformRequiredError = {
1349    attach: function (context) {
1350      $(context).find(':input[data-webform-required-error], :input[data-webform-pattern-error]').once('webform-required-error')
1351        .on('invalid', function () {
1352          this.setCustomValidity('');
1353          if (this.valid) {
1354            return;
1355          }
1356
1357          if (this.validity.patternMismatch && $(this).attr('data-webform-pattern-error')) {
1358            this.setCustomValidity($(this).attr('data-webform-pattern-error'));
1359          }
1360          else if (this.validity.valueMissing && $(this).attr('data-webform-required-error')) {
1361            this.setCustomValidity($(this).attr('data-webform-required-error'));
1362          }
1363        })
1364        .on('input change', function () {
1365          // Find all related elements by name and reset custom validity.
1366          // This specifically applies to required radios and checkboxes.
1367          var name = $(this).attr('name');
1368          $(this.form).find(':input[name="' + name + '"]').each(function () {
1369            this.setCustomValidity('');
1370          });
1371        });
1372    }
1373  };
1374
1375  // When #state:required is triggered we need to reset the target elements
1376  // custom validity.
1377  $(document).on('state:required', function (e) {
1378    $(e.target).filter('[data-webform-required-error]')
1379      .each(function () {this.setCustomValidity('');});
1380  });
1381
1382})(jQuery, Drupal);
1383;
1384/**
1385* DO NOT EDIT THIS FILE.
1386* See the following change record for more information,
1387* https://www.drupal.org/node/2815083
1388* @preserve
1389**/
1390
1391(function (Drupal, debounce) {
1392  var liveElement = void 0;
1393  var announcements = [];
1394
1395  Drupal.behaviors.drupalAnnounce = {
1396    attach: function attach(context) {
1397      if (!liveElement) {
1398        liveElement = document.createElement('div');
1399        liveElement.id = 'drupal-live-announce';
1400        liveElement.className = 'visually-hidden';
1401        liveElement.setAttribute('aria-live', 'polite');
1402        liveElement.setAttribute('aria-busy', 'false');
1403        document.body.appendChild(liveElement);
1404      }
1405    }
1406  };
1407
1408  function announce() {
1409    var text = [];
1410    var priority = 'polite';
1411    var announcement = void 0;
1412
1413    var il = announcements.length;
1414    for (var i = 0; i < il; i++) {
1415      announcement = announcements.pop();
1416      text.unshift(announcement.text);
1417
1418      if (announcement.priority === 'assertive') {
1419        priority = 'assertive';
1420      }
1421    }
1422
1423    if (text.length) {
1424      liveElement.innerHTML = '';
1425
1426      liveElement.setAttribute('aria-busy', 'true');
1427
1428      liveElement.setAttribute('aria-live', priority);
1429
1430      liveElement.innerHTML = text.join('\n');
1431
1432      liveElement.setAttribute('aria-busy', 'false');
1433    }
1434  }
1435
1436  Drupal.announce = function (text, priority) {
1437    announcements.push({
1438      text: text,
1439      priority: priority
1440    });
1441
1442    return debounce(announce, 200)();
1443  };
1444})(Drupal, Drupal.debounce);;
1445/**
1446 * @file
1447 * JavaScript behaviors for details element.
1448 */
1449
1450(function ($, Drupal) {
1451
1452  'use strict';
1453
1454  Drupal.webform = Drupal.webform || {};
1455  Drupal.webform.detailsToggle = Drupal.webform.detailsToggle || {};
1456  Drupal.webform.detailsToggle.options = Drupal.webform.detailsToggle.options || {};
1457
1458  /**
1459   * Attach handler to toggle details open/close state.
1460   *
1461   * @type {Drupal~behavior}
1462   */
1463  Drupal.behaviors.webformDetailsToggle = {
1464    attach: function (context) {
1465      $('.js-webform-details-toggle', context).once('webform-details-toggle').each(function () {
1466        var $form = $(this);
1467        var $tabs = $form.find('.webform-tabs');
1468
1469        // Get only the main details elements and ignore all nested details.
1470        var selector = ($tabs.length) ? '.webform-tab' : '.js-webform-details-toggle, .webform-elements';
1471        var $details = $form.find('details').filter(function () {
1472          var $parents = $(this).parentsUntil(selector);
1473          return ($parents.find('details').length === 0);
1474        });
1475
1476        // Toggle is only useful when there are two or more details elements.
1477        if ($details.length < 2) {
1478          return;
1479        }
1480
1481        var options = $.extend({
1482          button: '<button type="button" class="webform-details-toggle-state"></button>'
1483        }, Drupal.webform.detailsToggle.options);
1484
1485        // Create toggle buttons.
1486        var $toggle = $(options.button)
1487          .attr('title', Drupal.t('Toggle details widget state.'))
1488          .on('click', function (e) {
1489            // Get details that are not vertical tabs pane.
1490            var $details = $form.find('details:not(.vertical-tabs__pane)');
1491            var open;
1492            if (Drupal.webform.detailsToggle.isFormDetailsOpen($form)) {
1493              $details.removeAttr('open');
1494              open = 0;
1495            }
1496            else {
1497              $details.attr('open', 'open');
1498              open = 1;
1499            }
1500            Drupal.webform.detailsToggle.setDetailsToggleLabel($form);
1501
1502            // Set the saved states for all the details elements.
1503            // @see webform.element.details.save.js
1504            if (Drupal.webformDetailsSaveGetName) {
1505              $details.each(function () {
1506                // Note: Drupal.webformDetailsSaveGetName checks if localStorage
1507                // exists and is enabled.
1508                // @see webform.element.details.save.js
1509                var name = Drupal.webformDetailsSaveGetName($(this));
1510                if (name) {
1511                  localStorage.setItem(name, open);
1512                }
1513              });
1514            }
1515          })
1516          .wrap('<div class="webform-details-toggle-state-wrapper"></div>')
1517          .parent();
1518
1519        if ($tabs.length) {
1520          // Add toggle state before the tabs.
1521          $tabs.find('.item-list:first-child').eq(0).before($toggle);
1522        }
1523        else {
1524          // Add toggle state link to first details element.
1525          $details.eq(0).before($toggle);
1526        }
1527
1528        Drupal.webform.detailsToggle.setDetailsToggleLabel($form);
1529      });
1530    }
1531  };
1532
1533  /**
1534   * Determine if a webform's details are all opened.
1535   *
1536   * @param {jQuery} $form
1537   *   A webform.
1538   *
1539   * @return {boolean}
1540   *   TRUE if a webform's details are all opened.
1541   */
1542  Drupal.webform.detailsToggle.isFormDetailsOpen = function ($form) {
1543    return ($form.find('details[open]').length === $form.find('details').length);
1544  };
1545
1546  /**
1547   * Set a webform's details toggle state widget label.
1548   *
1549   * @param {jQuery} $form
1550   *   A webform.
1551   */
1552  Drupal.webform.detailsToggle.setDetailsToggleLabel = function ($form) {
1553    var isOpen = Drupal.webform.detailsToggle.isFormDetailsOpen($form);
1554
1555    var label = (isOpen) ? Drupal.t('Collapse all') : Drupal.t('Expand all');
1556    $form.find('.webform-details-toggle-state').html(label);
1557
1558    var text = (isOpen) ? Drupal.t('All details have been expanded.') : Drupal.t('All details have been collapsed.');
1559    Drupal.announce(text);
1560  };
1561
1562})(jQuery, Drupal);
1563;
1564/**
1565* DO NOT EDIT THIS FILE.
1566* See the following change record for more information,
1567* https://www.drupal.org/node/2815083
1568* @preserve
1569**/
1570
1571(function ($, Drupal) {
1572  Drupal.behaviors.detailsAria = {
1573    attach: function attach() {
1574      $('body').once('detailsAria').on('click.detailsAria', 'summary', function (event) {
1575        var $summary = $(event.currentTarget);
1576        var open = $(event.currentTarget.parentNode).attr('open') === 'open' ? 'false' : 'true';
1577
1578        $summary.attr({
1579          'aria-expanded': open,
1580          'aria-pressed': open
1581        });
1582      });
1583    }
1584  };
1585})(jQuery, Drupal);;
1586/**
1587* DO NOT EDIT THIS FILE.
1588* See the following change record for more information,
1589* https://www.drupal.org/node/2815083
1590* @preserve
1591**/
1592
1593(function ($, Modernizr, Drupal) {
1594  function CollapsibleDetails(node) {
1595    this.$node = $(node);
1596    this.$node.data('details', this);
1597
1598    var anchor = window.location.hash && window.location.hash !== '#' ? ', ' + window.location.hash : '';
1599    if (this.$node.find('.error' + anchor).length) {
1600      this.$node.attr('open', true);
1601    }
1602
1603    this.setupSummary();
1604
1605    this.setupLegend();
1606  }
1607
1608  $.extend(CollapsibleDetails, {
1609    instances: []
1610  });
1611
1612  $.extend(CollapsibleDetails.prototype, {
1613    setupSummary: function setupSummary() {
1614      this.$summary = $('<span class="summary"></span>');
1615      this.$node.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)).trigger('summaryUpdated');
1616    },
1617    setupLegend: function setupLegend() {
1618      var $legend = this.$node.find('> summary');
1619
1620      $('<span class="details-summary-prefix visually-hidden"></span>').append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show')).prependTo($legend).after(document.createTextNode(' '));
1621
1622      $('<a class="details-title"></a>').attr('href', '#' + this.$node.attr('id')).prepend($legend.contents()).appendTo($legend);
1623
1624      $legend.append(this.$summary).on('click', $.proxy(this.onLegendClick, this));
1625    },
1626    onLegendClick: function onLegendClick(e) {
1627      this.toggle();
1628      e.preventDefault();
1629    },
1630    onSummaryUpdated: function onSummaryUpdated() {
1631      var text = $.trim(this.$node.drupalGetSummary());
1632      this.$summary.html(text ? ' (' + text + ')' : '');
1633    },
1634    toggle: function toggle() {
1635      var _this = this;
1636
1637      var isOpen = !!this.$node.attr('open');
1638      var $summaryPrefix = this.$node.find('> summary span.details-summary-prefix');
1639      if (isOpen) {
1640        $summaryPrefix.html(Drupal.t('Show'));
1641      } else {
1642        $summaryPrefix.html(Drupal.t('Hide'));
1643      }
1644
1645      setTimeout(function () {
1646        _this.$node.attr('open', !isOpen);
1647      }, 0);
1648    }
1649  });
1650
1651  Drupal.behaviors.collapse = {
1652    attach: function attach(context) {
1653      if (Modernizr.details) {
1654        return;
1655      }
1656      var $collapsibleDetails = $(context).find('details').once('collapse').addClass('collapse-processed');
1657      if ($collapsibleDetails.length) {
1658        for (var i = 0; i < $collapsibleDetails.length; i++) {
1659          CollapsibleDetails.instances.push(new CollapsibleDetails($collapsibleDetails[i]));
1660        }
1661      }
1662    }
1663  };
1664
1665  var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e, $target) {
1666    $target.parents('details').not('[open]').find('> summary').trigger('click');
1667  };
1668
1669  $('body').on('formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange);
1670
1671  Drupal.CollapsibleDetails = CollapsibleDetails;
1672})(jQuery, Modernizr, Drupal);;
1673/*!
1674 * Signature Pad v2.3.0
1675 * https://github.com/szimek/signature_pad
1676 *
1677 * Copyright 2017 Szymon Nowak
1678 * Released under the MIT license
1679 *
1680 * The main idea and some parts of the code (e.g. drawing variable width Bézier curve) are taken from:
1681 * http://corner.squareup.com/2012/07/smoother-signatures.html
1682 *
1683 * Implementation of interpolation using cubic Bézier curves is taken from:
1684 * http://benknowscode.wordpress.com/2012/09/14/path-interpolation-using-cubic-bezier-and-control-point-estimation-in-javascript
1685 *
1686 * Algorithm for approximated length of a Bézier curve is taken from:
1687 * http://www.lemoda.net/maths/bezier-length/index.html
1688 *
1689 */
1690
1691(function (global, factory) {
1692	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
1693	typeof define === 'function' && define.amd ? define(factory) :
1694	(global.SignaturePad = factory());
1695}(this, (function () { 'use strict';
1696
1697function Point(x, y, time) {
1698  this.x = x;
1699  this.y = y;
1700  this.time = time || new Date().getTime();
1701}
1702
1703Point.prototype.velocityFrom = function (start) {
1704  return this.time !== start.time ? this.distanceTo(start) / (this.time - start.time) : 1;
1705};
1706
1707Point.prototype.distanceTo = function (start) {
1708  return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2));
1709};
1710
1711Point.prototype.equals = function (other) {
1712  return this.x === other.x && this.y === other.y && this.time === other.time;
1713};
1714
1715function Bezier(startPoint, control1, control2, endPoint) {
1716  this.startPoint = startPoint;
1717  this.control1 = control1;
1718  this.control2 = control2;
1719  this.endPoint = endPoint;
1720}
1721
1722// Returns approximated length.
1723Bezier.prototype.length = function () {
1724  var steps = 10;
1725  var length = 0;
1726  var px = void 0;
1727  var py = void 0;
1728
1729  for (var i = 0; i <= steps; i += 1) {
1730    var t = i / steps;
1731    var cx = this._point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x);
1732    var cy = this._point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y);
1733    if (i > 0) {
1734      var xdiff = cx - px;
1735      var ydiff = cy - py;
1736      length += Math.sqrt(xdiff * xdiff + ydiff * ydiff);
1737    }
1738    px = cx;
1739    py = cy;
1740  }
1741
1742  return length;
1743};
1744
1745/* eslint-disable no-multi-spaces, space-in-parens */
1746Bezier.prototype._point = function (t, start, c1, c2, end) {
1747  return start * (1.0 - t) * (1.0 - t) * (1.0 - t) + 3.0 * c1 * (1.0 - t) * (1.0 - t) * t + 3.0 * c2 * (1.0 - t) * t * t + end * t * t * t;
1748};
1749
1750/* eslint-disable */
1751
1752// http://stackoverflow.com/a/27078401/815507
1753function throttle(func, wait, options) {
1754  var context, args, result;
1755  var timeout = null;
1756  var previous = 0;
1757  if (!options) options = {};
1758  var later = function later() {
1759    previous = options.leading === false ? 0 : Date.now();
1760    timeout = null;
vendor: 1,009 bytes, lines 1761-1793
1761    result = func.apply(context, args);
1762    if (!timeout) context = args = null;
1763  };
1764  return function () {
1765    var now = Date.now();
1766    if (!previous && options.leading === false) previous = now;
1767    var remaining = wait - (now - previous);
1768    context = this;
1769    args = arguments;
1770    if (remaining <= 0 || remaining > wait) {
1771      if (timeout) {
1772        clearTimeout(timeout);
1773        timeout = null;
1774      }
1775      previous = now;
1776      result = func.apply(context, args);
1777      if (!timeout) context = args = null;
1778    } else if (!timeout && options.trailing !== false) {
1779      timeout = setTimeout(later, remaining);
1780    }
1781    return result;
1782  };
1783}
1784
1785function SignaturePad(canvas, options) {
1786  var self = this;
1787  var opts = options || {};
1788
1789  this.velocityFilterWeight = opts.velocityFilterWeight || 0.7;
1790  this.minWidth = opts.minWidth || 0.5;
1791  this.maxWidth = opts.maxWidth || 2.5;
1792  this.throttle = 'throttle' in opts ? opts.throttle : 16; // in miliseconds
1793  this.minDistance = opts.minDistance ||
vendor: 10,574 bytes, lines 1793-2167
1793 5;
1794
1795  if (this.throttle) {
1796    this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle);
1797  } else {
1798    this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate;
1799  }
1800
1801  this.dotSize = opts.dotSize || function () {
1802    return (this.minWidth + this.maxWidth) / 2;
1803  };
1804  this.penColor = opts.penColor || 'black';
1805  this.backgroundColor = opts.backgroundColor || 'rgba(0,0,0,0)';
1806  this.onBegin = opts.onBegin;
1807  this.onEnd = opts.onEnd;
1808
1809  this._canvas = canvas;
1810  this._ctx = canvas.getContext('2d');
1811  this.clear();
1812
1813  // We need add these inline so they are available to unbind while still having
1814  // access to 'self' we could use _.bind but it's not worth adding a dependency.
1815  this._handleMouseDown = function (event) {
1816    if (event.which === 1) {
1817      self._mouseButtonDown = true;
1818      self._strokeBegin(event);
1819    }
1820  };
1821
1822  this._handleMouseMove = function (event) {
1823    if (self._mouseButtonDown) {
1824      self._strokeMoveUpdate(event);
1825    }
1826  };
1827
1828  this._handleMouseUp = function (event) {
1829    if (event.which === 1 && self._mouseButtonDown) {
1830      self._mouseButtonDown = false;
1831      self._strokeEnd(event);
1832    }
1833  };
1834
1835  this._handleTouchStart = function (event) {
1836    if (event.targetTouches.length === 1) {
1837      var touch = event.changedTouches[0];
1838      self._strokeBegin(touch);
1839    }
1840  };
1841
1842  this._handleTouchMove = function (event) {
1843    // Prevent scrolling.
1844    event.preventDefault();
1845
1846    var touch = event.targetTouches[0];
1847    self._strokeMoveUpdate(touch);
1848  };
1849
1850  this._handleTouchEnd = function (event) {
1851    var wasCanvasTouched = event.target === self._canvas;
1852    if (wasCanvasTouched) {
1853      event.preventDefault();
1854      self._strokeEnd(event);
1855    }
1856  };
1857
1858  // Enable mouse and touch event handlers
1859  this.on();
1860}
1861
1862// Public methods
1863SignaturePad.prototype.clear = function () {
1864  var ctx = this._ctx;
1865  var canvas = this._canvas;
1866
1867  ctx.fillStyle = this.backgroundColor;
1868  ctx.clearRect(0, 0, canvas.width, canvas.height);
1869  ctx.fillRect(0, 0, canvas.width, canvas.height);
1870
1871  this._data = [];
1872  this._reset();
1873  this._isEmpty = true;
1874};
1875
1876SignaturePad.prototype.fromDataURL = function (dataUrl) {
1877  var _this = this;
1878
1879  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1880
1881  var image = new Image();
1882  var ratio = options.ratio || window.devicePixelRatio || 1;
1883  var width = options.width || this._canvas.width / ratio;
1884  var height = options.height || this._canvas.height / ratio;
1885
1886  this._reset();
1887  image.src = dataUrl;
1888  image.onload = function () {
1889    _this._ctx.drawImage(image, 0, 0, width, height);
1890  };
1891  this._isEmpty = false;
1892};
1893
1894SignaturePad.prototype.toDataURL = function (type) {
1895  var _canvas;
1896
1897  switch (type) {
1898    case 'image/svg+xml':
1899      return this._toSVG();
1900    default:
1901      for (var _len = arguments.length, options = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1902        options[_key - 1] = arguments[_key];
1903      }
1904
1905      return (_canvas = this._canvas).toDataURL.apply(_canvas, [type].concat(options));
1906  }
1907};
1908
1909SignaturePad.prototype.on = function () {
1910  this._handleMouseEvents();
1911  this._handleTouchEvents();
1912};
1913
1914SignaturePad.prototype.off = function () {
1915  this._canvas.removeEventListener('mousedown', this._handleMouseDown);
1916  this._canvas.removeEventListener('mousemove', this._handleMouseMove);
1917  document.removeEventListener('mouseup', this._handleMouseUp);
1918
1919  this._canvas.removeEventListener('touchstart', this._handleTouchStart);
1920  this._canvas.removeEventListener('touchmove', this._handleTouchMove);
1921  this._canvas.removeEventListener('touchend', this._handleTouchEnd);
1922};
1923
1924SignaturePad.prototype.isEmpty = function () {
1925  return this._isEmpty;
1926};
1927
1928// Private methods
1929SignaturePad.prototype._strokeBegin = function (event) {
1930  this._data.push([]);
1931  this._reset();
1932  this._strokeUpdate(event);
1933
1934  if (typeof this.onBegin === 'function') {
1935    this.onBegin(event);
1936  }
1937};
1938
1939SignaturePad.prototype._strokeUpdate = function (event) {
1940  var x = event.clientX;
1941  var y = event.clientY;
1942
1943  var point = this._createPoint(x, y);
1944  var lastPointGroup = this._data[this._data.length - 1];
1945  var lastPoint = lastPointGroup && lastPointGroup[lastPointGroup.length - 1];
1946  var isLastPointTooClose = lastPoint && point.distanceTo(lastPoint) < this.minDistance;
1947
1948  // Skip this point if it's too close to the previous one
1949  if (!(lastPoint && isLastPointTooClose)) {
1950    var _addPoint = this._addPoint(point),
1951        curve = _addPoint.curve,
1952        widths = _addPoint.widths;
1953
1954    if (curve && widths) {
1955      this._drawCurve(curve, widths.start, widths.end);
1956    }
1957
1958    this._data[this._data.length - 1].push({
1959      x: point.x,
1960      y: point.y,
1961      time: point.time,
1962      color: this.penColor
1963    });
1964  }
1965};
1966
1967SignaturePad.prototype._strokeEnd = function (event) {
1968  var canDrawCurve = this.points.length > 2;
1969  var point = this.points[0]; // Point instance
1970
1971  if (!canDrawCurve && point) {
1972    this._drawDot(point);
1973  }
1974
1975  if (point) {
1976    var lastPointGroup = this._data[this._data.length - 1];
1977    var lastPoint = lastPointGroup[lastPointGroup.length - 1]; // plain object
1978
1979    // When drawing a dot, there's only one point in a group, so without this check
1980    // such group would end up with exactly the same 2 points.
1981    if (!point.equals(lastPoint)) {
1982      lastPointGroup.push({
1983        x: point.x,
1984        y: point.y,
1985        time: point.time,
1986        color: this.penColor
1987      });
1988    }
1989  }
1990
1991  if (typeof this.onEnd === 'function') {
1992    this.onEnd(event);
1993  }
1994};
1995
1996SignaturePad.prototype._handleMouseEvents = function () {
1997  this._mouseButtonDown = false;
1998
1999  this._canvas.addEventListener('mousedown', this._handleMouseDown);
2000  this._canvas.addEventListener('mousemove', this._handleMouseMove);
2001  document.addEventListener('mouseup', this._handleMouseUp);
2002};
2003
2004SignaturePad.prototype._handleTouchEvents = function () {
2005  // Pass touch events to canvas element on mobile IE11 and Edge.
2006  this._canvas.style.msTouchAction = 'none';
2007  this._canvas.style.touchAction = 'none';
2008
2009  this._canvas.addEventListener('touchstart', this._handleTouchStart);
2010  this._canvas.addEventListener('touchmove', this._handleTouchMove);
2011  this._canvas.addEventListener('touchend', this._handleTouchEnd);
2012};
2013
2014SignaturePad.prototype._reset = function () {
2015  this.points = [];
2016  this._lastVelocity = 0;
2017  this._lastWidth = (this.minWidth + this.maxWidth) / 2;
2018  this._ctx.fillStyle = this.penColor;
2019};
2020
2021SignaturePad.prototype._createPoint = function (x, y, time) {
2022  var rect = this._canvas.getBoundingClientRect();
2023
2024  return new Point(x - rect.left, y - rect.top, time || new Date().getTime());
2025};
2026
2027SignaturePad.prototype._addPoint = function (point) {
2028  var points = this.points;
2029  var tmp = void 0;
2030
2031  points.push(point);
2032
2033  if (points.length > 2) {
2034    // To reduce the initial lag make it work with 3 points
2035    // by copying the first point to the beginning.
2036    if (points.length === 3) points.unshift(points[0]);
2037
2038    tmp = this._calculateCurveControlPoints(points[0], points[1], points[2]);
2039    var c2 = tmp.c2;
2040    tmp = this._calculateCurveControlPoints(points[1], points[2], points[3]);
2041    var c3 = tmp.c1;
2042    var curve = new Bezier(points[1], c2, c3, points[2]);
2043    var widths = this._calculateCurveWidths(curve);
2044
2045    // Remove the first element from the list,
2046    // so that we always have no more than 4 points in points array.
2047    points.shift();
2048
2049    return { curve: curve, widths: widths };
2050  }
2051
2052  return {};
2053};
2054
2055SignaturePad.prototype._calculateCurveControlPoints = function (s1, s2, s3) {
2056  var dx1 = s1.x - s2.x;
2057  var dy1 = s1.y - s2.y;
2058  var dx2 = s2.x - s3.x;
2059  var dy2 = s2.y - s3.y;
2060
2061  var m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 };
2062  var m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.y) / 2.0 };
2063
2064  var l1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
2065  var l2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
2066
2067  var dxm = m1.x - m2.x;
2068  var dym = m1.y - m2.y;
2069
2070  var k = l2 / (l1 + l2);
2071  var cm = { x: m2.x + dxm * k, y: m2.y + dym * k };
2072
2073  var tx = s2.x - cm.x;
2074  var ty = s2.y - cm.y;
2075
2076  return {
2077    c1: new Point(m1.x + tx, m1.y + ty),
2078    c2: new Point(m2.x + tx, m2.y + ty)
2079  };
2080};
2081
2082SignaturePad.prototype._calculateCurveWidths = function (curve) {
2083  var startPoint = curve.startPoint;
2084  var endPoint = curve.endPoint;
2085  var widths = { start: null, end: null };
2086
2087  var velocity = this.velocityFilterWeight * endPoint.velocityFrom(startPoint) + (1 - this.velocityFilterWeight) * this._lastVelocity;
2088
2089  var newWidth = this._strokeWidth(velocity);
2090
2091  widths.start = this._lastWidth;
2092  widths.end = newWidth;
2093
2094  this._lastVelocity = velocity;
2095  this._lastWidth = newWidth;
2096
2097  return widths;
2098};
2099
2100SignaturePad.prototype._strokeWidth = function (velocity) {
2101  return Math.max(this.maxWidth / (velocity + 1), this.minWidth);
2102};
2103
2104SignaturePad.prototype._drawPoint = function (x, y, size) {
2105  var ctx = this._ctx;
2106
2107  ctx.moveTo(x, y);
2108  ctx.arc(x, y, size, 0, 2 * Math.PI, false);
2109  this._isEmpty = false;
2110};
2111
2112SignaturePad.prototype._drawCurve = function (curve, startWidth, endWidth) {
2113  var ctx = this._ctx;
2114  var widthDelta = endWidth - startWidth;
2115  var drawSteps = Math.floor(curve.length());
2116
2117  ctx.beginPath();
2118
2119  for (var i = 0; i < drawSteps; i += 1) {
2120    // Calculate the Bezier (x, y) coordinate for this step.
2121    var t = i / drawSteps;
2122    var tt = t * t;
2123    var ttt = tt * t;
2124    var u = 1 - t;
2125    var uu = u * u;
2126    var uuu = uu * u;
2127
2128    var x = uuu * curve.startPoint.x;
2129    x += 3 * uu * t * curve.control1.x;
2130    x += 3 * u * tt * curve.control2.x;
2131    x += ttt * curve.endPoint.x;
2132
2133    var y = uuu * curve.startPoint.y;
2134    y += 3 * uu * t * curve.control1.y;
2135    y += 3 * u * tt * curve.control2.y;
2136    y += ttt * curve.endPoint.y;
2137
2138    var width = startWidth + ttt * widthDelta;
2139    this._drawPoint(x, y, width);
2140  }
2141
2142  ctx.closePath();
2143  ctx.fill();
2144};
2145
2146SignaturePad.prototype._drawDot = function (point) {
2147  var ctx = this._ctx;
2148  var width = typeof this.dotSize === 'function' ? this.dotSize() : this.dotSize;
2149
2150  ctx.beginPath();
2151  this._drawPoint(point.x, point.y, width);
2152  ctx.closePath();
2153  ctx.fill();
2154};
2155
2156SignaturePad.prototype._fromData = function (pointGroups, drawCurve, drawDot) {
2157  for (var i = 0; i < pointGroups.length; i += 1) {
2158    var group = pointGroups[i];
2159
2160    if (group.length > 1) {
2161      for (var j = 0; j < group.length; j += 1) {
2162        var rawPoint = group[j];
2163        var point = new Point(rawPoint.x, rawPoint.y, rawPoint.time);
2164        var color = rawPoint.color;
2165
2166        if (j === 0) {
2167          // First point in a group. Nothing to draw yet.
2168          this._reset();
2169          this._addPoint(point);
2170        } else if (j !== group.length - 1) {
2171          // Middle point in a group.
2172          var _addPoint2 = this._addPoint(point),
2173              curve = _addPoint2.curve,
2174              widths = _addPoint2.widths;
2175
2176          if (curve && widths) {
2177            drawCurve(curve, widths, color);
2178          }
2179        } else {
2180          // Last point in a group. Do nothing.
2181        }
2182      }
2183    } else {
2184      this._reset();
2185      var _rawPoint = group[0];
2186      drawDot(_rawPoint);
2187    }
2188  }
2189};
2190
2191SignaturePad.prototype._toSVG = function () {
2192  var _this2 = this;
2193
2194  var pointGroups = this._data;
2195  var canvas = this._canvas;
2196  var ratio = Math.max(window.devicePixelRatio || 1, 1);
2197  var minX = 0;
2198  var minY = 0;
2199  var maxX = canvas.width / ratio;
2200  var maxY = canvas.height / ratio;
2201  var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
2202
2203  svg.setAttributeNS(null, 'width', canvas.width);
2204  svg.setAttributeNS(null, 'height', canvas.height);
2205
2206  this._fromData(pointGroups, function (curve, widths, color) {
2207    var path = document.createElement('path');
2208
2209    // Need to check curve for NaN values, these pop up when drawing
2210    // lines on the canvas that are not continuous. E.g. Sharp corners
2211    // or stopping mid-stroke and than continuing without lifting mouse.
2212    if (!isNaN(curve.control1.x) && !isNaN(curve.control1.y) && !isNaN(curve.control2.x) && !isNaN(curve.control2.y)) {
2213      var attr = 'M ' + curve.startPoint.x.toFixed(3) + ',' + curve.startPoint.y.toFixed(3) + ' ' + ('C ' + curve.control1.x.toFixed(3) + ',' + curve.control1.y.toFixed(3) + ' ') + (curve.control2.x.toFixed(3) + ',' + curve.control2.y.toFixed(3) + ' ') + (curve.endPoint.x.toFixed(3) + ',' + curve.endPoint.y.toFixed(3));
2214
2215      path.setAttribute('d', attr);
2216      path.setAttribute('stroke-width', (widths.end * 2.25).toFixed(3));
2217      path.setAttribute('stroke', color);
2218      path.setAttribute('fill', 'none');
2219      path.setAttribute('stroke-linecap', 'round');
2220
2221      svg.appendChild(path);
2222    }
2223  }, function (rawPoint) {
2224    var circle = document.createElement('circle');
2225    var dotSize = typeof _this2.dotSize === 'function' ? _this2.dotSize() : _this2.dotSize;
2226    circle.setAttribute('r', dotSize);
2227    circle.setAttribute('cx', rawPoint.x);
2228    circle.setAttribute('cy', rawPoint.y);
2229    circle.setAttribute('fill', rawPoint.color);
2230
2231    svg.appendChild(circle);
2232  });
2233
2234  var prefix = 'data:image/svg+xml;base64,';
2235  var header = '<svg' + ' xmlns="http://www.w3.org/2000/svg"' + ' xmlns:xlink="http://www.w3.org/1999/xlink"' + (' viewBox="' + minX + ' ' + minY + ' ' + maxX + ' ' + maxY + '"') + (' width="' + maxX + '"') + (' height="' + maxY + '"') + '>';
2236  var body = svg.innerHTML;
2237
2238  // IE hack for missing innerHTML property on SVGElement
2239  if (body === undefined) {
2240    var dummy = document.createElement('dummy');
2241    var nodes = svg.childNodes;
2242    dummy.innerHTML = '';
2243
2244    for (var i = 0; i < nodes.length; i += 1) {
2245      dummy.appendChild(nodes[i].cloneNode(true));
2246    }
2247
2248    body = dummy.innerHTML;
2249  }
2250
2251  var footer = '</svg>';
2252  var data = header + body + footer;
2253
2254  return prefix + btoa(data);
2255};
2256
2257SignaturePad.prototype.fromData = function (pointGroups) {
2258  var _this3 = this;
2259
2260  this.clear();
2261
2262  this._fromData(pointGroups, function (curve, widths) {
2263    return _this3._drawCurve(curve, widths.start, widths.end);
2264  }, function (rawPoint) {
2265    return _this3._drawDot(rawPoint);
2266  });
2267
2268  this._data = pointGroups;
2269};
2270
2271SignaturePad.prototype.toData = function () {
2272  return this._data;
2273};
2274
2275return SignaturePad;
2276
2277})));
2278;
2279/**
2280 * @file
2281 * JavaScript behaviors for signature pad integration.
2282 */
2283
2284(function ($, Drupal, debounce) {
2285
2286  'use strict';
2287
2288  // @see https://github.com/szimek/signature_pad#options
2289  Drupal.webform = Drupal.webform || {};
2290  Drupal.webform.signaturePad = Drupal.webform.signaturePad || {};
2291  Drupal.webform.signaturePad.options = Drupal.webform.signaturePad.options || {};
2292
2293  /**
2294   * Initialize signature element.
2295   *
2296   * @type {Drupal~behavior}
2297   */
2298  Drupal.behaviors.webformSignature = {
2299    attach: function (context) {
2300      if (!window.SignaturePad) {
2301        return;
2302      }
2303
2304      $(context).find('input.js-webform-signature').once('webform-signature').each(function () {
2305        var $input = $(this);
2306        var value = $input.val();
2307        var $wrapper = $input.parent();
2308        var $canvas = $wrapper.find('canvas');
2309        var $button = $wrapper.find(':button, :submit');
2310        var canvas = $canvas[0];
2311
2312        var refresh = function () {
2313          // Set dimensions.
2314          $canvas.attr('width', $wrapper.width());
2315          $canvas.attr('height', $wrapper.width() / 3);
2316          // Set signature.
2317          signaturePad.clear();
2318          var value = $input.val();
2319          if (value) {
2320            signaturePad.fromDataURL(value);
2321          }
2322        };
2323
2324        // Initialize signature canvas.
2325        var options = $.extend({
2326          onEnd: function () {
2327            $input.val(signaturePad.toDataURL());
2328          }
2329        }, Drupal.webform.signaturePad.options);
2330        var signaturePad = new SignaturePad(canvas, options);
2331
2332        // Disable the signature pad when input is disabled or readonly.
2333        if ($input.is(':disabled') || $input.is('[readonly]')) {
2334          signaturePad.off();
2335          $button.hide();
2336        }
2337
2338        // Set resize handler.
2339        $(window).on('resize', debounce(refresh, 10));
2340
2341        // Set reset handler.
2342        $button.on('click', function () {
2343          signaturePad.clear();
2344          $input.val('');
2345          $(this).trigger('blur');
2346          return false;
2347        });
2348
2349        // Input onchange clears signature pad if value is empty.
2350        // Onchange events handlers are triggered when a webform is
2351        // hidden or shown.
2352        // @see webform.states.js
2353        // @see triggerEventHandlers()
2354        $input.on('change', function () {
2355          setTimeout(refresh, 1);
2356        });
2357
2358        // Turn signature pad off/on when the input
2359        // is disabled/readonly/enabled.
2360        // @see webform.states.js
2361        $input.on('webform:disabled webform:readonly', function () {
2362          if ($input.is(':disabled') || $input.is('[readonly]')) {
2363            signaturePad.off();
2364            $button.hide();
2365          }
2366          else {
2367            signaturePad.on();
2368            $button.show();
2369          }
2370        });
2371
2372        // Make sure that the signature pad is initialized.
2373        setTimeout(refresh, 1);
2374      });
2375    }
2376  };
2377
2378})(jQuery, Drupal, Drupal.debounce);
2379;
2380/**
2381 * @file
2382 * JavaScript behaviors for select menu.
2383 */
2384
2385(function ($, Drupal) {
2386
2387  'use strict';
2388
2389  /**
2390   * Disable select menu options using JavaScript.
2391   *
2392   * @type {Drupal~behavior}
2393   */
2394  Drupal.behaviors.webformSelectOptionsDisabled = {
2395    attach: function (context) {
2396      $('select[data-webform-select-options-disabled]', context).once('webform-select-options-disabled').each(function () {
2397        var $select = $(this);
2398        var disabled = $select.attr('data-webform-select-options-disabled').split(/\s*,\s*/);
2399        $select.find('option').filter(function isDisabled() {
2400          return ($.inArray(this.value, disabled) !== -1);
2401        }).attr('disabled', 'disabled');
2402      });
2403    }
2404  };
2405
2406
2407})(jQuery, Drupal);
2408;

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.