PageSourceSearch

https://irwinemc.com/sites/default/files/js/js_ZCoJcpSArP3QjetaEJqyMcx3OjI5kyj26ATHQIkpIbQ.js

js irwinemc.com collected 2026-10-05 19:53:25 UTC 62,870 bytes, 1,584 lines download raw bytes

1(function (Drupal) {
2
3  /**
4   * Command to attach data using jQuery's data API.
5   *
6   * @param {Drupal.Ajax} [ajax]
7   *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
8   * @param {object} response
9   *   The response from the Ajax request.
10   * @param {string} response.event_name
11   *   The event name
12   * @param {object} response.data
13   *   The value of the event.
14   */
15  Drupal.AjaxCommands.prototype.gtagEvent = function (ajax, response) {
16    gtag('event', response.event_name, response.data)
17  }
18})(Drupal);
19;
20function ctSetCookie(cookies)
21{
22
23  let useCookies, useAltCookies
24
25  if ('undefined' !== typeof ct_use_cookies) {
26    useCookies = ct_use_cookies;
27  } else {
28    useCookies = false;
29  }
30
31  if ('undefined' !== typeof ct_use_alt_cookies) {
32    useAltCookies = ct_use_alt_cookies;
33  } else {
34    useAltCookies = false
35  }
36
37  if (useCookies) {
38    if (useAltCookies && useAltCookies === 1) {
39      let xhr = new XMLHttpRequest();
40
41      let json = JSON.stringify(cookies);
42
43      xhr.open("POST", '/admin/config/cleantalk/set_alt_cookies')
44      xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
45
46      xhr.send(json);
47    } else {
48      cookies.forEach(
49        function (e) {
50          let ctSecure = location.protocol === "https:" ? "; secure" : "";
51          document.cookie = e.name + "=" + encodeURIComponent(e.value) + "; path=/; expires=0; samesite=lax" + ctSecure;
52        }
53      )
54    }
55  }
56}
57;
58var d = new Date(),
59    ctTimeMs = new Date().getTime(),
60    ctMouseEventTimerFlag = true, //Reading interval flag
61    ctMouseData = "[",
62    ctMouseDataCounter = 0,
63    ctScrollCollected = false,
64    ctEventTokenInterval = null;
65
66ctSetCookie(
67    [
68    {
69        'name' : 'ct_check_js',
70        'value' : ct_check_js_val
71    },
72    {
73        'name' : 'ct_ps_timestamp',
74        'value' : Math.floor(new Date().getTime()/1000)
75    },
76    {
77        'name' : 'ct_fkp_timestamp',
78        'value' : '0'
79    },
80    {
81        'name' : 'ct_pointer_data',
82        'value' : '0'
83    },
84    {
85        'name' : 'ct_timezone',
86        'value' : d.getTimezoneOffset()/60*(-1)
87    },
88    {
89        'name' : 'apbct_antibot',
90        'value' : drupal_ac_antibot_cookie_value
91    },
92    {
93        'name' : 'ct_has_scrolled',
94        'value' : false
95    }
96    ]
97);
98
99//Reading interval
100
101var ctMouseReadInterval = setInterval(
102    function () {
103        ctMouseEventTimerFlag = true;
104    }, 150
105);
106
107//Writting interval
108
109var ctMouseWriteDataInterval = setInterval(
110    function () {
111        if(typeof ct_use_alt_cookies !== "undefined" && ct_use_alt_cookies === 1) {
112            return;
113        }
114        var ctMouseDataToSend = ctMouseData.slice(0,-1).concat("]");
115        ctSetCookie(
116            [
117            {
118                'name' : 'ct_pointer_data',
119                'value' : ctMouseDataToSend
120            }
121            ]
122        );
123    }, 1200
124);
125
126//Stop observing function
127
128function ctMouseStopData()
129{
130    if(typeof window.addEventListener == "function") {
131        window.removeEventListener("mousemove", ctFunctionMouseMove);
132    } else {
133        window.detachEvent("onmousemove", ctFunctionMouseMove);
134    }
135    clearInterval(ctMouseReadInterval);
136    clearInterval(ctMouseWriteDataInterval);
137}
138
139//Logging mouse position each 300 ms
140
141var ctFunctionMouseMove = function output(event)
142{
143    if (ctMouseEventTimerFlag == true) {
144        var mouseDate = new Date();
145        ctMouseData += "[" + Math.round(event.pageY) + "," + Math.round(event.pageX) + "," + Math.round(mouseDate.getTime() - ctTimeMs) + "],";
146        ctMouseDataCounter++;
147        ctMouseEventTimerFlag = false;
148        if(ctMouseDataCounter >= 100) {
149            ctMouseStopData();
150        }
151    }
152};
153
154/**
155 * Set scrolling cookie
156 */
157function ctSetHasScrolled()
158{
159    if(! ctScrollCollected ) {
160        ctSetCookie(
161            [
162            {
163                'name' : 'ct_has_scrolled',
164                'value' : true
165            }
166            ]
167        );
168        ctScrollCollected = true;
169    }
170}
171
172//Stop key listening function
173
174function ctKeyStopStopListening()
175{
176    if (typeof window.addEventListener == "function") {
177        window.removeEventListener("mousedown", ctFunctionFirstKey);
178        window.removeEventListener("keydown", ctFunctionFirstKey);
179    }
180    else {
181        window.detachEvent("mousedown", ctFunctionFirstKey);
182        window.detachEvent("keydown", ctFunctionFirstKey);
183    }
184}
185
186//Writing first key press timestamp
187
188var ctFunctionFirstKey = function output(event)
189{
190    var KeyTimestamp = Math.floor(new Date().getTime()/1000);
191    ctSetCookie(
192        [
193        {
194            'name' : 'ct_fkp_timestamp',
195            'value' : KeyTimestamp
196        }
197        ]
198    );
199    ctKeyStopStopListening();
200};
201
202if (typeof window.addEventListener == "function") {
203    window.addEventListener("mousemove", ctFunctionMouseMove);
204    window.addEventListener("mousedown", ctFunctionFirstKey);
205    window.addEventListener("keydown", ctFunctionFirstKey);
206    window.addEventListener("scroll", ctSetHasScrolled);
207}
208else {
209    window.attachEvent("onmousemove", ctFunctionMouseMove);
210    window.attachEvent("mousedown", ctFunctionFirstKey);
211    window.attachEvent("keydown", ctFunctionFirstKey);
212    window.attachEvent("scroll", ctSetHasScrolled);
213}
214
215function apbct_collect_visible_fields( form )
216{
217
218    // Get only fields
219    var inputs = [],
220        inputs_visible = '',
221        inputs_visible_count = 0,
222        inputs_invisible = '',
223        inputs_invisible_count = 0,
224        inputs_with_duplicate_names = [];
225
226    for(var key in form.elements){
227        if(!isNaN(+key)) {
228            inputs[key] = form.elements[key];
229        }
230    }
231
232    // Filter fields
233    inputs = inputs.filter(
234        function (elem) {
235
236            // Filter already added fields
237            if(inputs_with_duplicate_names.indexOf(elem.getAttribute('name')) !== -1 ) {
238                return false;
239            }
240            // Filter inputs with same names for type == radio
241            if(-1 !== ['radio', 'checkbox'].indexOf(elem.getAttribute("type"))) {
242                inputs_with_duplicate_names.push(elem.getAttribute('name'));
243                return false;
244            }
245            return true;
246        }
247    );
248
249    // Visible fields
250    inputs.forEach(
251        function (elem, i, elements) {
252            // Unnecessary fields
253            if(elem.getAttribute("type")         === "submit"  // type == submit
254                || elem.getAttribute('name')         === null
255                || elem.getAttribute('name')         === 'ct_checkjs'
256            ) {
257                return;
258            }
259            // Invisible fields
260            if(getComputedStyle(elem).display    === "none"    // hidden
261                || getComputedStyle(elem).visibility === "hidden"  // hidden
262                || getComputedStyle(elem).opacity    === "0"       // hidden
263                || elem.getAttribute("type")         === "hidden" // type == hidden
264            ) {
265                if(elem.classList.contains("wp-editor-area") ) {
266                    inputs_visible += " " + elem.getAttribute("name");
267                    inputs_visible_count++;
268                } else {
269                    inputs_invisible += " " + elem.getAttribute("name");
270                    inputs_invisible_count++;
271                }
272            }
273            // Visible fields
274            else {
275                inputs_visible += " " + elem.getAttribute("name");
276                inputs_visible_count++;
277            }
278
279        }
280    );
281
282    inputs_invisible = inputs_invisible.trim();
283    inputs_visible = inputs_visible.trim();
284
285    return {
286        visible_fields : inputs_visible,
287        visible_fields_count : inputs_visible_count,
288        invisible_fields : inputs_invisible,
289        invisible_fields_count : inputs_invisible_count,
290    }
291
292}
293
294function apbct_visible_fields_set_cookie( visible_fields_collection )
295{
296    var collection = typeof visible_fields_collection === 'object' && visible_fields_collection !== null ?  visible_fields_collection : {};
297
298    ctSetCookie(
299        [
300        {
301            'name' : 'apbct_visible_fields',
302            'value' : JSON.stringify(collection)
303        }
304        ]
305    )
306}
307
308// Event token handler class. Get token and save it to the alternative sessions.
309
310class EventTokenHandler {
311
312  constructor(use_alt_cookies_option) {
313    this.token = null;
314    this.lsSavedFlagName = 'event_token_saved_to_alt_sessions';
315    this.lsEVentTokenName = 'bot_detector_event_token';
316    this.intervalValue = 1500;
317    this.init(use_alt_cookies_option);
318  }
319
320  init(use_alt_cookies_option){
321    if ('undefined' !== typeof use_alt_cookies_option && use_alt_cookies_option) {
322      this.setNotSavedFlag();
323      this.startListenTokenLS();
324    }
325  }
326
327
328  setSavedFlag()
329  {
330    localStorage.setItem(this.lsSavedFlagName, '1');
331  }
332
333  setNotSavedFlag()
334  {
335    localStorage.setItem(this.lsSavedFlagName, '0');
336  }
337
338  isSaved()
339  {
340    let event_token_saved = localStorage.getItem(this.lsSavedFlagName);
341    return event_token_saved !== null && event_token_saved !== undefined && event_token_saved === '1';
342  }
343
344  getEventToken()
345  {
346    let event_token = localStorage.getItem(this.lsEVentTokenName);
347    try {
348      event_token = event_token !== null ? JSON.parse(event_token) : false;
349    } catch (e) {
350      return false;
351    }
352    event_token = event_token.hasOwnProperty('value') ? event_token.value : false;
353    if (typeof event_token === 'string' && event_token.length === 64) {
354      return event_token;
355    }
356    return false;
357  }
358
359  setEventTokenCookie()
360  {
361    if (typeof this.token === 'string' && this.token.length === 64) {
362      ctSetCookie(
363        [
364          {
365            'name': 'apbct_event_token',
366            'value': this.token
367          }
368        ]
369      )
370    }
371  }
372
373  stopListenTokenLS()
374  {
375    clearInterval(this.intervalID);
376  }
377
378  startListenTokenLS()
379  {
380    this.intervalID = setInterval( this.intervalRun, this.intervalValue, this)
381  }
382
383  intervalRun(handler)
384  {
385    if ( !handler.isSaved() ) {
386      handler.token = handler.getEventToken();
387      if ( handler.token  ) {
388        handler.setEventTokenCookie();
389        handler.setSavedFlag();
390        handler.stopListenTokenLS();
391      }
392    }
393  }
394}
395
396//Collect event token
397new EventTokenHandler(ct_use_alt_cookies);
398;
399/**
400 * @file
401 * Bootstrap Popovers.
402 */
403
404var Drupal = Drupal || {};
405
406(function ($, Drupal, Bootstrap) {
407  "use strict";
408
409  var $document = $(document);
410
411  /**
412   * Extend the Bootstrap Popover plugin constructor class.
413   */
414  Bootstrap.extendPlugin('popover', function (settings) {
415    return {
416      DEFAULTS: {
417        animation: !!settings.popover_animation,
418        autoClose: !!settings.popover_auto_close,
419        enabled: settings.popover_enabled,
420        html: !!settings.popover_html,
421        placement: settings.popover_placement,
422        selector: settings.popover_selector,
423        trigger: settings.popover_trigger,
424        title: settings.popover_title,
425        content: settings.popover_content,
426        delay: parseInt(settings.popover_delay, 10),
427        container: settings.popover_container
428      }
429    };
430  });
431
432  /**
433   * Bootstrap Popovers.
434   *
435   * @todo This should really be properly delegated if selector option is set.
436   */
437  Drupal.behaviors.bootstrapPopovers = {
438    $activePopover: null,
439    attach: function (context) {
440      // Immediately return if popovers are not available.
441      if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) {
442        return;
443      }
444
445      var _this = this;
446
447      $document
448        .on('show.bs.popover', '[data-toggle=popover]', function () {
449          var $trigger = $(this);
450          var popover = $trigger.data('bs.popover');
451
452          // Only keep track of clicked triggers that we're manually handling.
453          if (popover.options.originalTrigger === 'click') {
454            if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($trigger)) {
455              _this.$activePopover.popover('hide');
456            }
457            _this.$activePopover = $trigger;
458          }
459        })
460        // Unfortunately, :focusable is only made available when using jQuery
461        // UI. While this would be the most semantic pseudo selector to use
462        // here, jQuery UI may not always be loaded. Instead, just use :visible
463        // here as this just needs some sort of selector here. This activates
464        // delegate binding to elements in jQuery so it can work it's bubbling
465        // focus magic since elements don't really propagate their focus events.
466        // @see https://www.drupal.org/project/bootstrap/issues/3013236
467        .on('focus.bs.popover', ':visible', function (e) {
468          var $target = $(e.target);
469          if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($target) && !$target.closest('.popover.in')[0]) {
470            _this.$activePopover.popover('hide');
471            _this.$activePopover = null;
472          }
473        })
474        .on('click.bs.popover', function (e) {
475          var $target = $(e.target);
476          if (_this.$activePopover && _this.getOption('autoClose') && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) {
477            _this.$activePopover.popover('hide');
478            _this.$activePopover = null;
479          }
480        })
481        .on('keyup.bs.popover', function (e) {
482          if (_this.$activePopover && _this.getOption('autoClose') && e.which === 27) {
483            _this.$activePopover.popover('hide');
484            _this.$activePopover = null;
485          }
486        })
487      ;
488
489      var elements = $(context).find('[data-toggle=popover]').toArray();
490      for (var i = 0; i < elements.length; i++) {
491        var $element = $(elements[i]);
492        var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, $element.data());
493
494        // Store the original trigger.
495        options.originalTrigger = options.trigger;
496
497        // If the trigger is "click", then we'll handle it manually here.
498        if (options.trigger === 'click') {
499          options.trigger = 'manual';
500        }
501
502        // Retrieve content from a target element.
503        var target = options.target || $element.is('a[href^="#"]') && $element.attr('href');
504        var $target = $document.find(target).clone();
505        if (!options.content && $target[0]) {
506          $target.removeClass('visually-hidden hidden').removeAttr('aria-hidden');
507          options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || '';
508        }
509
510        // Initialize the popover.
511        $element.popover(options);
512
513        // Handle clicks manually.
514        if (options.originalTrigger === 'click') {
515          // To ensure the element is bound multiple times, remove any
516          // previously set event handler before adding another one.
517          $element
518            .off('click.drupal.bootstrap.popover')
519            .on('click.drupal.bootstrap.popover', function (e) {
520              $(this).popover('toggle');
521              e.preventDefault();
522              e.stopPropagation();
523            })
524          ;
525        }
526      }
527    },
528    detach: function (context) {
529      // Immediately return if popovers are not available.
530      if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) {
531        return;
532      }
533
534      // Destroy all popovers.
535      $(context).find('[data-toggle="popover"]')
536        .off('click.drupal.bootstrap.popover')
537        .popover('destroy')
538      ;
539    },
540    getOption: function(name, defaultValue, element) {
541      var $element = element ? $(element) : this.$activePopover;
542      var options = $.extend(true, {}, $.fn.popover.Constructor.DEFAULTS, ($element && $element.data('bs.popover') || {}).options);
543      if (options[name] !== void 0) {
544        return options[name];
545      }
546      return defaultValue !== void 0 ? defaultValue : void 0;
547    }
548  };
549
550})(window.jQuery, window.Drupal, window.Drupal.bootstrap);
551;
552/**
553 * @file
554 * Bootstrap Tooltips.
555 */
556
557var Drupal = Drupal || {};
558
559(function ($, Drupal, Bootstrap) {
560  "use strict";
561
562  /**
563   * Extend the Bootstrap Tooltip plugin constructor class.
564   */
565  Bootstrap.extendPlugin('tooltip', function (settings) {
566    return {
567      DEFAULTS: {
568        animation: !!settings.tooltip_animation,
569        enabled: settings.tooltip_enabled,
570        html: !!settings.tooltip_html,
571        placement: settings.tooltip_placement,
572        selector: settings.tooltip_selector,
573        trigger: settings.tooltip_trigger,
574        delay: parseInt(settings.tooltip_delay, 10),
575        container: settings.tooltip_container
576      }
577    };
578  });
579
580  /**
581   * Bootstrap Tooltips.
582   *
583   * @todo This should really be properly delegated if selector option is set.
584   */
585  Drupal.behaviors.bootstrapTooltips = {
586    attach: function (context) {
587      // Immediately return if tooltips are not available.
588      if (!$.fn.tooltip || !$.fn.tooltip.Constructor.DEFAULTS.enabled) {
589        return;
590      }
591
592      var elements = $(context).find('[data-toggle="tooltip"]').toArray();
593      for (var i = 0; i < elements.length; i++) {
594        var $element = $(elements[i]);
595        var options = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, $element.data());
596        $element.tooltip(options);
597      }
598    },
599    detach: function (context) {
600      // Immediately return if tooltips are not available.
601      if (!$.fn.tooltip || !$.fn.tooltip.Constructor.DEFAULTS.enabled) {
602        return;
603      }
604
605      // Destroy all tooltips.
606      $(context).find('[data-toggle="tooltip"]').tooltip('destroy');
607    }
608  };
609
610})(window.jQuery, window.Drupal, window.Drupal.bootstrap);
611;
612/*!
613 * jQuery Form Plugin
614 * version: 4.3.0
615 * Requires jQuery v1.7.2 or later
616 * Project repository: https://github.com/jquery-form/form
617
618 * Copyright 2017 Kevin Morris
619 * Copyright 2006 M. Alsup
620
621 * Dual licensed under the LGPL-2.1+ or MIT licenses
622 * https://github.com/jquery-form/form#license
623
624 * This library is free software; you can redistribute it and/or
625 * modify it under the terms of the GNU Lesser General Public
vendor: 16,397 bytes, lines 626-633
626 * License as published by the Free Software Foundation; either
627 * version 2.1 of the License, or (at your option) any later version.
628 * This library is distributed in the hope that it will be useful,
629 * but WITHOUT ANY WARRANTY; without even the implied warranty of
630 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
631 * Lesser General Public License for more details.
632 */
633!function(r){"function"==typeof define&&define.amd?define(["jquery"],r):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),r(t),t}:r(jQuery)}(function(q){"use strict";var m=/\r?\n/g,S={};S.fileapi=void 0!==q('<input type="file">').get(0).files,S.formdata=void 0!==window.FormData;var _=!!q.fn.prop;function o(e){var t=e.data;e.isDefaultPrevented()||(e.preventDefault(),q(e.target).closest("form").ajaxSubmit(t))}function i(e){var t=e.target,r=q(t);if(!r.is("[type=submit],[type=image]")){var a=r.closest("[type=submit]");if(0===a.length)return;t=a[0]}var n,o=t.form;"image"===(o.clk=t).type&&(void 0!==e.offsetX?(o.clk_x=e.offsetX,o.clk_y=e.offsetY):"function"==typeof q.fn.offset?(n=r.offset(),o.clk_x=e.pageX-n.left,o.clk_y=e.pageY-n.top):(o.clk_x=e.pageX-t.offsetLeft,o.clk_y=e.pageY-t.offsetTop)),setTimeout(function(){o.clk=o.clk_x=o.clk_y=null},100)}function N(){var e;q.fn.ajaxSubmit.debug&&(e="[jquery.form] "+Array.prototype.join.call(arguments,""),window.console&&window.console.log?window.console.log(e):window.opera&&window.opera.postError&&window.opera.postError(e))}q.fn.attr2=function(){if(!_)return this.attr.apply(this,arguments);var e=this.prop.apply(this,arguments);return e&&e.jquery||"string"==typeof e?e:this.attr.apply(this,arguments)},q.fn.ajaxSubmit=function(M,e,t,r){if(!this.length)return N("ajaxSubmit: skipping submit process - no element selected"),this;var O,a,n,o,X=this;"function"==typeof M?M={success:M}:"string"==typeof M||!1===M&&0<arguments.length?(M={url:M,data:e,dataType:t},"function"==typeof r&&(M.success=r)):void 0===M&&(M={}),O=M.method||M.type||this.attr2("method"),n=(n=(n="string"==typeof(a=M.url||this.attr2("action"))?q.trim(a):"")||window.location.href||"")&&(n.match(/^([^#]+)/)||[])[1],o=/(MSIE|Trident)/.test(navigator.userAgent||"")&&/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",M=q.extend(!0,{url:n,success:q.ajaxSettings.success,type:O||q.ajaxSettings.type,iframeSrc:o},M);var i={};if(this.trigger("form-pre-serialize",[this,M,i]),i.veto)return N("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(M.beforeSerialize&&!1===M.beforeSerialize(this,M))return N("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var s=M.traditional;void 0===s&&(s=q.ajaxSettings.traditional);var u,c,C=[],l=this.formToArray(M.semantic,C,M.filtering);if(M.data&&(c=q.isFunction(M.data)?M.data(l):M.data,M.extraData=c,u=q.param(c,s)),M.beforeSubmit&&!1===M.beforeSubmit(l,this,M))return N("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[l,this,M,i]),i.veto)return N("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var f=q.param(l,s);u&&(f=f?f+"&"+u:u),"GET"===M.type.toUpperCase()?(M.url+=(0<=M.url.indexOf("?")?"&":"?")+f,M.data=null):M.data=f;var d,m,p,h=[];M.resetForm&&h.push(function(){X.resetForm()}),M.clearForm&&h.push(function(){X.clearForm(M.includeHidden)}),!M.dataType&&M.target?(d=M.success||function(){},h.push(function(e,t,r){var a=arguments,n=M.replaceTarget?"replaceWith":"html";q(M.target)[n](e).each(function(){d.apply(this,a)})})):M.success&&(q.isArray(M.success)?q.merge(h,M.success):h.push(M.success)),M.success=function(e,t,r){for(var a=M.context||this,n=0,o=h.length;n<o;n++)h[n].apply(a,[e,t,r||X,X])},M.error&&(m=M.error,M.error=function(e,t,r){var a=M.context||this;m.apply(a,[e,t,r,X])}),M.complete&&(p=M.complete,M.complete=function(e,t){var r=M.context||this;p.apply(r,[e,t,X])});var v=0<q("input[type=file]:enabled",this).filter(function(){return""!==q(this).val()}).length,g="multipart/form-data",x=X.attr("enctype")===g||X.attr("encoding")===g,y=S.fileapi&&S.formdata;N("fileAPI :"+y);var b,T=(v||x)&&!y;!1!==M.iframe&&(M.iframe||T)?M.closeKeepAlive?q.get(M.closeKeepAlive,function(){b=w(l)}):b=w(l):b=(v||x)&&y?function(e){for(var r=new FormData,t=0;t<e.length;t++)r.append(e[t].name,e[t].value);if(M.extraData){var a=function(e){var t,r,a=q.param(e,M.traditional).split("&"),n=a.length,o=[];for(t=0;t<n;t++)a[t]=a[t].replace(/\+/g," "),r=a[t].split("="),o.push([decodeURIComponent(r[0]),decodeURIComponent(r[1])]);return o}(M.extraData);for(t=0;t<a.length;t++)a[t]&&r.append(a[t][0],a[t][1])}M.data=null;var n=q.extend(!0,{},q.ajaxSettings,M,{contentType:!1,processData:!1,cache:!1,type:O||"POST"});M.uploadProgress&&(n.xhr=function(){var e=q.ajaxSettings.xhr();return e.upload&&e.upload.addEventListener("progress",function(e){var t=0,r=e.loaded||e.position,a=e.total;e.lengthComputable&&(t=Math.ceil(r/a*100)),M.uploadProgress(e,r,a,t)},!1),e});n.data=null;var o=n.beforeSend;return n.beforeSend=function(e,t){M.formData?t.data=M.formData:t.data=r,o&&o.call(this,e,t)},q.ajax(n)}(l):q.ajax(M),X.removeData("jqxhr").data("jqxhr",b);for(var j=0;j<C.length;j++)C[j]=null;return this.trigger("form-submit-notify",[this,M]),this;function w(e){var t,r,l,f,o,d,m,p,a,n,h,v,i=X[0],g=q.Deferred();if(g.abort=function(e){p.abort(e)},e)for(r=0;r<C.length;r++)t=q(C[r]),_?t.prop("disabled",!1):t.removeAttr("disabled");(l=q.extend(!0,{},q.ajaxSettings,M)).context=l.context||l,o="jqFormIO"+(new Date).getTime();var s=i.ownerDocument,u=X.closest("body");if(l.iframeTarget?(n=(d=q(l.iframeTarget,s)).attr2("name"))?o=n:d.attr2("name",o):(d=q('<iframe name="'+o+'" src="'+l.iframeSrc+'" />',s)).css({position:"absolute",top:"-1000px",left:"-1000px"}),m=d[0],p={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(e){var t="timeout"===e?"timeout":"aborted";N("aborting upload... "+t),this.aborted=1;try{m.contentWindow.document.execCommand&&m.contentWindow.document.execCommand("Stop")}catch(e){}d.attr("src",l.iframeSrc),p.error=t,l.error&&l.error.call(l.context,p,t,e),f&&q.event.trigger("ajaxError",[p,l,t]),l.complete&&l.complete.call(l.context,p,t)}},(f=l.global)&&0==q.active++&&q.event.trigger("ajaxStart"),f&&q.event.trigger("ajaxSend",[p,l]),l.beforeSend&&!1===l.beforeSend.call(l.context,p,l))return l.global&&q.active--,g.reject(),g;if(p.aborted)return g.reject(),g;(a=i.clk)&&(n=a.name)&&!a.disabled&&(l.extraData=l.extraData||{},l.extraData[n]=a.value,"image"===a.type&&(l.extraData[n+".x"]=i.clk_x,l.extraData[n+".y"]=i.clk_y));var x=1,y=2;function b(t){var r=null;try{t.contentWindow&&(r=t.contentWindow.document)}catch(e){N("cannot get iframe.contentWindow document: "+e)}if(r)return r;try{r=t.contentDocument?t.contentDocument:t.document}catch(e){N("cannot get iframe.contentDocument: "+e),r=t.document}return r}var c=q("meta[name=csrf-token]").attr("content"),T=q("meta[name=csrf-param]").attr("content");function j(){var e=X.attr2("target"),t=X.attr2("action"),r=X.attr("enctype")||X.attr("encoding")||"multipart/form-data";i.setAttribute("target",o),O&&!/post/i.test(O)||i.setAttribute("method","POST"),t!==l.url&&i.setAttribute("action",l.url),l.skipEncodingOverride||O&&!/post/i.test(O)||X.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"}),l.timeout&&(v=setTimeout(function(){h=!0,A(x)},l.timeout));var a=[];try{if(l.extraData)for(var n in l.extraData)l.extraData.hasOwnProperty(n)&&(q.isPlainObject(l.extraData[n])&&l.extraData[n].hasOwnProperty("name")&&l.extraData[n].hasOwnProperty("value")?a.push(q('<input type="hidden" name="'+l.extraData[n].name+'">',s).val(l.extraData[n].value).appendTo(i)[0]):a.push(q('<input type="hidden" name="'+n+'">',s).val(l.extraData[n]).appendTo(i)[0]));l.iframeTarget||d.appendTo(u),m.attachEvent?m.attachEvent("onload",A):m.addEventListener("load",A,!1),setTimeout(function e(){try{var t=b(m).readyState;N("state = "+t),t&&"uninitialized"===t.toLowerCase()&&setTimeout(e,50)}catch(e){N("Server abort: ",e," (",e.name,")"),A(y),v&&clearTimeout(v),v=void 0}},15);try{i.submit()}catch(e){document.createElement("form").submit.apply(i)}}finally{i.setAttribute("action",t),i.setAttribute("enctype",r),e?i.setAttribute("target",e):X.removeAttr("target"),q(a).remove()}}T&&c&&(l.extraData=l.extraData||{},l.extraData[T]=c),l.forceSync?j():setTimeout(j,10);var w,S,k,D=50;function A(e){if(!p.aborted&&!k){if((S=b(m))||(N("cannot access response document"),e=y),e===x&&p)return p.abort("timeout"),void g.reject(p,"timeout");if(e===y&&p)return p.abort("server abort"),void g.reject(p,"error","server abort");if(S&&S.location.href!==l.iframeSrc||h){m.detachEvent?m.detachEvent("onload",A):m.removeEventListener("load",A,!1);var t,r="success";try{if(h)throw"timeout";var a="xml"===l.dataType||S.XMLDocument||q.isXMLDoc(S);if(N("isXml="+a),!a&&window.opera&&(null===S.body||!S.body.innerHTML)&&--D)return N("requeing onLoad callback, DOM not available"),void setTimeout(A,250);var n=S.body?S.body:S.documentElement;p.responseText=n?n.innerHTML:null,p.responseXML=S.XMLDocument?S.XMLDocument:S,a&&(l.dataType="xml"),p.getResponseHeader=function(e){return{"content-type":l.dataType}[e.toLowerCase()]},n&&(p.status=Number(n.getAttribute("status"))||p.status,p.statusText=n.getAttribute("statusText")||p.statusText);var o,i,s,u=(l.dataType||"").toLowerCase(),c=/(json|script|text)/.test(u);c||l.textarea?(o=S.getElementsByTagName("textarea")[0])?(p.responseText=o.value,p.status=Number(o.getAttribute("status"))||p.status,p.statusText=o.getAttribute("statusText")||p.statusText):c&&(i=S.getElementsByTagName("pre")[0],s=S.getElementsByTagName("body")[0],i?p.responseText=i.textContent?i.textContent:i.innerText:s&&(p.responseText=s.textContent?s.textContent:s.innerText)):"xml"===u&&!p.responseXML&&p.responseText&&(p.responseXML=F(p.responseText));try{w=E(p,u,l)}catch(e){r="parsererror",p.error=t=e||r}}catch(e){N("error caught: ",e),r="error",p.error=t=e||r}p.aborted&&(N("upload aborted"),r=null),p.status&&(r=200<=p.status&&p.status<300||304===p.status?"success":"error"),"success"===r?(l.success&&l.success.call(l.context,w,"success",p),g.resolve(p.responseText,"success",p),f&&q.event.trigger("ajaxSuccess",[p,l])):r&&(void 0===t&&(t=p.statusText),l.error&&l.error.call(l.context,p,r,t),g.reject(p,"error",t),f&&q.event.trigger("ajaxError",[p,l,t])),f&&q.event.trigger("ajaxComplete",[p,l]),f&&!--q.active&&q.event.trigger("ajaxStop"),l.complete&&l.complete.call(l.context,p,r),k=!0,l.timeout&&clearTimeout(v),setTimeout(function(){l.iframeTarget?d.attr("src",l.iframeSrc):d.remove(),p.responseXML=null},100)}}}var F=q.parseXML||function(e,t){return window.ActiveXObject?((t=new ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e)):t=(new DOMParser).parseFromString(e,"text/xml"),t&&t.documentElement&&"parsererror"!==t.documentElement.nodeName?t:null},L=q.parseJSON||function(e){return window.eval("("+e+")")},E=function(e,t,r){var a=e.getResponseHeader("content-type")||"",n=("xml"===t||!t)&&0<=a.indexOf("xml"),o=n?e.responseXML:e.responseText;return n&&"parsererror"===o.documentElement.nodeName&&q.error&&q.error("parsererror"),r&&r.dataFilter&&(o=r.dataFilter(o,t)),"string"==typeof o&&(("json"===t||!t)&&0<=a.indexOf("json")?o=L(o):("script"===t||!t)&&0<=a.indexOf("javascript")&&q.globalEval(o)),o};return g}},q.fn.ajaxForm=function(e,t,r,a){if(("string"==typeof e||!1===e&&0<arguments.length)&&(e={url:e,data:t,dataType:r},"function"==typeof a&&(e.success=a)),(e=e||{}).delegation=e.delegation&&q.isFunction(q.fn.on),e.delegation||0!==this.length)return e.delegation?(q(document).off("submit.form-plugin",this.selector,o).off("click.form-plugin",this.selector,i).on("submit.form-plugin",this.selector,e,o).on("click.form-plugin",this.selector,e,i),this):(e.beforeFormUnbind&&e.beforeFormUnbind(this,e),this.ajaxFormUnbind().on("submit.form-plugin",e,o).on("click.form-plugin",e,i));var n={s:this.selector,c:this.context};return!q.isReady&&n.s?(N("DOM not ready, queuing ajaxForm"),q(function(){q(n.s,n.c).ajaxForm(e)})):N("terminating; zero elements found by selector"+(q.isReady?"":" (DOM not ready)")),this},q.fn.ajaxFormUnbind=function(){return this.off("submit.form-plugin click.form-plugin")},q.fn.formToArray=function(e,t,r){var a=[];if(0===this.length)return a;var n,o,i,s,u,c,l,f,d,m,p=this[0],h=this.attr("id"),v=(v=e||void 0===p.elements?p.getElementsByTagName("*"):p.elements)&&q.makeArray(v);if(h&&(e||/(Edge|Trident)\//.test(navigator.userAgent))&&(n=q(':input[form="'+h+'"]').get()).length&&(v=(v||[]).concat(n)),!v||!v.length)return a;for(q.isFunction(r)&&(v=q.map(v,r)),o=0,c=v.length;o<c;o++)if((m=(u=v[o]).name)&&!u.disabled)if(e&&p.clk&&"image"===u.type)p.clk===u&&(a.push({name:m,value:q(u).val(),type:u.type}),a.push({name:m+".x",value:p.clk_x},{name:m+".y",value:p.clk_y}));else if((s=q.fieldValue(u,!0))&&s.constructor===Array)for(t&&t.push(u),i=0,l=s.length;i<l;i++)a.push({name:m,value:s[i]});else if(S.fileapi&&"file"===u.type){t&&t.push(u);var g=u.files;if(g.length)for(i=0;i<g.length;i++)a.push({name:m,value:g[i],type:u.type});else a.push({name:m,value:"",type:u.type})}else null!=s&&(t&&t.push(u),a.push({name:m,value:s,type:u.type,required:u.required}));return e||!p.clk||(m=(d=(f=q(p.clk))[0]).name)&&!d.disabled&&"image"===d.type&&(a.push({name:m,value:f.val()}),a.push({name:m+".x",value:p.clk_x},{name:m+".y",value:p.clk_y})),a},q.fn.formSerialize=function(e){return q.param(this.formToArray(e))},q.fn.fieldSerialize=function(n){var o=[];return this.each(function(){var e=this.name;if(e){var t=q.fieldValue(this,n);if(t&&t.constructor===Array)for(var r=0,a=t.length;r<a;r++)o.push({name:e,value:t[r]});else null!=t&&o.push({name:this.name,value:t})}}),q.param(o)},q.fn.fieldValue=function(e){for(var t=[],r=0,a=this.length;r<a;r++){var n=this[r],o=q.fieldValue(n,e);null==o||o.constructor===Array&&!o.length||(o.constructor===Array?q.merge(t,o):t.push(o))}return t},q.fieldValue=function(e,t){var r=e.name,a=e.type,n=e.tagName.toLowerCase();if(void 0===t&&(t=!0),t&&(!r||e.disabled||"reset"===a||"button"===a||("checkbox"===a||"radio"===a)&&!e.checked||("submit"===a||"image"===a)&&e.form&&e.form.clk!==e||"select"===n&&-1===e.selectedIndex))return null;if("select"!==n)return q(e).val().replace(m,"\r\n");var o=e.selectedIndex;if(o<0)return null;for(var i=[],s=e.options,u="select-one"===a,c=u?o+1:s.length,l=u?o:0;l<c;l++){var f=s[l];if(f.selected&&!f.disabled){var d=(d=f.value)||(f.attributes&&f.attributes.value&&!f.attributes.value.specified?f.text:f.value);if(u)return d;i.push(d)}}return i},q.fn.clearForm=function(e){return this.each(function(){q("input,select,textarea",this).clearFields(e)})},q.fn.clearFields=q.fn.clearInputs=function(r){var a=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var e=this.type,t=this.tagName.toLowerCase();a.test(e)||"textarea"===t?this.value="":"checkbox"===e||"radio"===e?this.checked=!1:"select"===t?this.selectedIndex=-1:"file"===e?/MSIE/.test(navigator.userAgent)?q(this).replaceWith(q(this).clone(!0)):q(this).val(""):r&&(!0===r&&/hidden/.test(e)||"string"==typeof r&&q(this).is(r))&&(this.value="")})},q.fn.resetForm=function(){return this.each(function(){var t=q(this),e=this.tagName.toLowerCase();switch(e){case"input":this.checked=this.defaultChecked;case"textarea":return this.value=this.defaultValue,!0;case"option":case"optgroup":var r=t.parents("select");return r.length&&r[0].multiple?"option"===e?this.selected=this.defaultSelected:t.find("option").resetForm():r.resetForm(),!0;case"select":return t.find("option").each(function(e){if(this.selected=this.defaultSelected,this.defaultSelected&&!t[0].multiple)return t[0].selectedIndex=e,!1}),!0;case"label":var a=q(t.attr("for")),n=t.find("input,select,textarea");return a[0]&&n.unshift(a[0]),n.resetForm(),!0;case"form":return"function"!=typeof this.reset&&("object"!=typeof this.reset||this.reset.nodeType)||this.reset(),!0;default:return t.find("form,input,label,select,textarea").resetForm(),!0}})},q.fn.enable=function(e){return void 0===e&&(e=!0),this.each(function(){this.disabled=!e})},q.fn.selected=function(r){return void 0===r&&(r=!0),this.each(function(){var e,t=this.t
633ype;"checkbox"===t||"radio"===t?this.checked=r:"option"===this.tagName.toLowerCase()&&(e=q(this).parent("select"),r&&e[0]&&"select-one"===e[0].type&&e.find("option").selected(!1),this.selected=r)})},q.fn.ajaxSubmit.debug=!1});
634
635;
636/**
637* DO NOT EDIT THIS FILE.
638* See the following change record for more information,
639* https://www.drupal.org/node/2815083
640* @preserve
641**/
642(function ($, Drupal, drupalSettings) {
643  Drupal.Views = {};
644  Drupal.Views.parseQueryString = function (query) {
645    var args = {};
646    var pos = query.indexOf('?');
647    if (pos !== -1) {
648      query = query.substring(pos + 1);
649    }
650    var pair;
651    var pairs = query.split('&');
652    for (var i = 0; i < pairs.length; i++) {
653      pair = pairs[i].split('=');
654      if (pair[0] !== 'q' && pair[1]) {
655        args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
656      }
657    }
658    return args;
659  };
660  Drupal.Views.parseViewArgs = function (href, viewPath) {
661    var returnObj = {};
662    var path = Drupal.Views.getPath(href);
663    var viewHref = Drupal.url(viewPath).substring(drupalSettings.path.baseUrl.length);
664    if (viewHref && path.substring(0, viewHref.length + 1) === "".concat(viewHref, "/")) {
665      returnObj.view_args = decodeURIComponent(path.substring(viewHref.length + 1, path.length));
666      returnObj.view_path = path;
667    }
668    return returnObj;
669  };
670  Drupal.Views.pathPortion = function (href) {
671    var protocol = window.location.protocol;
672    if (href.substring(0, protocol.length) === protocol) {
673      href = href.substring(href.indexOf('/', protocol.length + 2));
674    }
675    return href;
676  };
677  Drupal.Views.getPath = function (href) {
678    href = Drupal.Views.pathPortion(href);
679    href = href.substring(drupalSettings.path.baseUrl.length, href.length);
680    if (href.substring(0, 3) === '?q=') {
681      href = href.substring(3, href.length);
682    }
683    var chars = ['#', '?', '&'];
684    for (var i = 0; i < chars.length; i++) {
685      if (href.indexOf(chars[i]) > -1) {
686        href = href.substr(0, href.indexOf(chars[i]));
687      }
688    }
689    return href;
690  };
691})(jQuery, Drupal, drupalSettings);;
692/**
693* DO NOT EDIT THIS FILE.
694* See the following change record for more information,
695* https://www.drupal.org/node/2815083
696* @preserve
697**/
698(function ($, Drupal, drupalSettings) {
699  Drupal.behaviors.ViewsAjaxView = {};
700  Drupal.behaviors.ViewsAjaxView.attach = function (context, settings) {
701    if (settings && settings.views && settings.views.ajaxViews) {
702      var ajaxViews = settings.views.ajaxViews;
703      Object.keys(ajaxViews || {}).forEach(function (i) {
704        Drupal.views.instances[i] = new Drupal.views.ajaxView(ajaxViews[i]);
705      });
706    }
707  };
708  Drupal.behaviors.ViewsAjaxView.detach = function (context, settings, trigger) {
709    if (trigger === 'unload') {
710      if (settings && settings.views && settings.views.ajaxViews) {
711        var ajaxViews = settings.views.ajaxViews;
712        Object.keys(ajaxViews || {}).forEach(function (i) {
713          var selector = ".js-view-dom-id-".concat(ajaxViews[i].view_dom_id);
714          if ($(selector, context).length) {
715            delete Drupal.views.instances[i];
716            delete settings.views.ajaxViews[i];
717          }
718        });
719      }
720    }
721  };
722  Drupal.views = {};
723  Drupal.views.instances = {};
724  Drupal.views.ajaxView = function (settings) {
725    var selector = ".js-view-dom-id-".concat(settings.view_dom_id);
726    this.$view = $(selector);
727    var ajaxPath = drupalSettings.views.ajax_path;
728    if (ajaxPath.constructor.toString().indexOf('Array') !== -1) {
729      ajaxPath = ajaxPath[0];
730    }
731    var queryString = window.location.search || '';
732    if (queryString !== '') {
733      queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, '');
734      if (queryString !== '') {
735        queryString = (/\?/.test(ajaxPath) ? '&' : '?') + queryString;
736      }
737    }
738    this.element_settings = {
739      url: ajaxPath + queryString,
740      submit: settings,
741      setClick: true,
742      event: 'click',
743      selector: selector,
744      progress: {
745        type: 'fullscreen'
746      }
747    };
748    this.settings = settings;
749    this.$exposed_form = $("form#views-exposed-form-".concat(settings.view_name.replace(/_/g, '-'), "-").concat(settings.view_display_id.replace(/_/g, '-')));
750    once('exposed-form', this.$exposed_form).forEach($.proxy(this.attachExposedFormAjax, this));
751    once('ajax-pager', this.$view.filter($.proxy(this.filterNestedViews, this))).forEach($.proxy(this.attachPagerAjax, this));
752    var selfSettings = $.extend({}, this.element_settings, {
753      event: 'RefreshView',
754      base: this.selector,
755      element: this.$view.get(0)
756    });
757    this.refreshViewAjax = Drupal.ajax(selfSettings);
758  };
759  Drupal.views.ajaxView.prototype.attachExposedFormAjax = function () {
760    var that = this;
761    this.exposedFormAjax = [];
762    $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form).not('[data-drupal-selector=edit-reset]').each(function (index) {
763      var selfSettings = $.extend({}, that.element_settings, {
764        base: $(this).attr('id'),
765        element: this
766      });
767      that.exposedFormAjax[index] = Drupal.ajax(selfSettings);
768    });
769  };
770  Drupal.views.ajaxView.prototype.filterNestedViews = function () {
771    return !this.$view.parents('.view').length;
772  };
773  Drupal.views.ajaxView.prototype.attachPagerAjax = function () {
774    this.$view.find('ul.js-pager__items > li > a, th.views-field a, .attachment .views-summary a').each($.proxy(this.attachPagerLinkAjax, this));
775  };
776  Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function (id, link) {
777    var $link = $(link);
778    var viewData = {};
779    var href = $link.attr('href');
780    $.extend(viewData, this.settings, Drupal.Views.parseQueryString(href), Drupal.Views.parseViewArgs(href, this.settings.view_base_path));
781    var selfSettings = $.extend({}, this.element_settings, {
782      submit: viewData,
783      base: false,
784      element: link
785    });
786    this.pagerAjax = Drupal.ajax(selfSettings);
787  };
788  Drupal.AjaxCommands.prototype.viewsScrollTop = function (ajax, response) {
789    var offset = $(response.selector).offset();
790    var scrollTarget = response.selector;
791    while ($(scrollTarget).scrollTop() === 0 && $(scrollTarget).parent()) {
792      scrollTarget = $(scrollTarget).parent();
793    }
794    if (offset.top - 10 < $(scrollTarget).scrollTop()) {
795      $(scrollTarget).animate({
796        scrollTop: offset.top - 10
797      }, 500);
798    }
799  };
800})(jQuery, Drupal, drupalSettings);;
801/**
802 * @file
803 * Extends core ajax_view.js.
804 */
805
806(function ($, Drupal) {
807  'use strict';
808
809  /**
810   * @method
811   */
812  Drupal.views.ajaxView.prototype.attachExposedFormAjax = function () {
813    var that = this;
814    this.exposedFormAjax = [];
815    $('button[type=submit], input[type=submit], input[type=image]', this.$exposed_form).not('[data-drupal-selector=edit-reset]').each(function (index) {
816      var self_settings = $.extend({}, that.element_settings, {
817        base: $(this).attr('id'),
818        element: this
819      });
820      that.exposedFormAjax[index] = Drupal.ajax(self_settings);
821    });
822  };
823
824})(jQuery, Drupal);
825;
826((Drupal) => {
827  'use strict';
828
829  /**
830   * Factory for generating alert classes for different callback styles.
831   *
832   * Each alert style's ticker class is responsible for registering its type
833   * with this factory.
834   *
835   * @type {{get(*): *, register(*, *): this}}
836   */
837  Drupal.alertFactory = (function () {
838
839    /**
840     * Object of factory callbacks for each alert type, keyed by their
841     * respective alert style names.
842     *
843     * @type {{}}
844     */
845    let callbacks = {};
846
847    /**
848     * Return a factory object for registering and retrieving ticker classes.
849     */
850    return {
851
852      /**
853       * Register's an alert style's factory callback.
854       *
855       * @param {string} type
856       *  The name of the alert style for which to register a factory callback.
857       * @param {function} callback
858       *  The callback to invoke for generating an alert display class for this
859       *  alert style.
860       * @returns {Drupal.alertFactory}
861       *  Reference to self.
862       */
863      register(type, callback) {
864        if (typeof callback === 'function') {
865          callbacks[type] = callback;
866        }
867        return this;
868      },
869
870      /**
871       * Returns the factory callback for the specified alert style.
872       *
873       * @param {string} type
874       *  The name of the alert style for which to return a factory callback.
875       * @returns {function}
876       *  The factory callback that will return the ticker class for the
877       *  specified ticker style.
878       */
879      get(type) {
880        return callbacks[type];
881      }
882    }
883  })();
884})(Drupal);
885;
886((Drupal, undefined) => {
887  'use strict';
888
889  /**
890   * Represents a single, ticker-style alerts display.
891   */
892  class AlertsTicker {
893
894    /**
895     * If TRUE, the current ticker is actively running.
896     *
897     * @type {boolean}
898     */
899    #running = false;
900
901    /**
902     * Index of the alert that is currently displayed or will be displayed when
903     * the ticker starts.
904     *
905     * @type {number}
906     */
907    #current = 0;
908
909    /**
910     * The ID of the currently running setTimeout() invocation.
911     *
912     * @type {int}
913     */
914    #timeoutId;
915
916    /**
917     * Reference to the promise chain that controls the ticker animations.
918     *
919     * @type {Promise}
920     */
921    animationChain;
922
923    /**
924     * True if the next/prev pagers should do nothing (e.g. if the ticker is
925     * currently advancing to the next alert item).
926     *
927     * @type {boolean}
928     */
929    pagerLocked = false;
930
931    /**
932     * Constructs a new AlertsTicker object.
933     *
934     * @param {HTMLElement} ticker
935     *  Reference to the outermost element that represents this ticker display.
936     * @param {{}} selectors
937     *  Object of selectors for identifying:
938     *    - The element that acts as the direct container for the individual
939     *      alert items.
940     *    - The counter element.
941     *    - The clickable element to display the previous alert.
942     *    - The clickable element to display the next alert.
943     * @param {{}} alerts
944     *  An object whose keys are HTML IDs that identify individual alert items,
945     *  and whose values are each objects containing the following configuration
946     *  data per alert item:
947     *    - delay: The number of milliseconds that a given alert item should be
948     *      displayed before advancing to the next alert item.
949     */
950    constructor(ticker, selectors, alerts, ) {
951      this.ticker = ticker;
952      this.container = document.querySelector(selectors.container);
953      this.counter = document.querySelector(selectors.counter);
954      this.pager = {
955        'prev': document.querySelector(selectors.prev),
956        'next': document.querySelector(selectors.next)
957      };
958
959      /**
960       * Set up AlertItem objects, each with doubly-linked references.
961       */
962      this.alerts = [];
963      Object.keys(alerts).forEach(id => {
964        const
965          alert = new AlertItem(id, alerts[id], this),
966          sequence = this.alerts.push(alert)
967        ;
968        alert.sequence = sequence;
969        if (sequence > 1) {
970          // Create linked references between immediate siblings.
971          const prev = this.alerts[sequence - 2];
972          alert.prev = prev;
973          prev.next = alert;
974        }
975      });
976      // Make the associations circular.
977      this.alerts[ this.#lastIndex() ].next = this.alerts[0];
978      this.alerts[0].prev = this.alerts[ this.#lastIndex() ];
979
980      /**
981       * Set up prev/next event handlers.
982       */
983      this.pager.next.onclick = e => {
984        if (this.pagerLocked) {
985          return;
986        }
987        this.animationChain = this.animationChain
988          .then(() => this.cancel())
989          .then(() => this.#doAdvance());
990      }
991      this.pager.prev.onclick = e => {
992        if (this.pagerLocked) {
993          return;
994        }
995        this.animationChain = this.animationChain
996          .then(() => this.cancel())
997          .then(() => this.#doAdvance(true));
998      }
999    }
1000
1001    /**
1002     * Returns a reference to the current alert item.
1003     *
1004     * @returns {AlertItem}
1005     */
1006    current () {
1007      return this.alerts[this.#current];
1008    }
1009
1010    /**
1011     * Advances the current marker to the next alert item in sequence and
1012     * returns a reference to that alert item.
1013     *
1014     * @returns {AlertItem}
1015     */
1016    next () {
1017      this.#current = (this.#current < this.#lastIndex())
1018        ? this.#current + 1
1019        : 0;
1020      return this.current();
1021    }
1022
1023    /**
1024     * Advances the current marker to the previous alert item in sequence and
1025     * returns a reference to that alert item.
1026     *
1027     * @returns {AlertItem}
1028     */
1029    prev () {
1030      this.#current = (this.#current > 0)
1031        ? this.#current - 1
1032        : this.#lastIndex();
1033      return this.current();
1034    }
1035
1036    /**
1037     * Calls .next() or .prev(), based on the value of reverse, and returns the
1038     * resultant value.
1039     *
1040     * @param reverse
1041     *  TRUE if .prev() should be returned. Otherwise, .next() will be returned.
1042     * @returns {AlertItem}
1043     *  Reference to the newly queued AlertItem.
1044     */
1045    #page (reverse = false) {
1046      return reverse ? this.prev() : this.next();
1047    }
1048
1049    /**
1050     * Begin the ticker animation sequence.
1051     *
1052     * @returns {AlertsTicker}
1053     *  Reference to self.
1054     */
1055    start () {
1056      if (this.#running) {
1057        return this;
1058      }
1059      this.animationChain = new Promise((resolve, reject) => {
1060        this.current().display()
1061        resolve(this);
1062      }).then(() => this.advance());
1063      this.#running = true;
1064      return this;
1065    }
1066
1067    /**
1068     * Sets an animation timer for the next ticker transition and returns the
1069     * promise that will resolve when the timer expires.
1070     *
1071     * @returns {Promise<unknown>}
1072     *  A promise that resolves when the timer expires.
1073     */
1074    advance () {
1075      return new Promise((resolve, reject) => {
1076        this.#timeoutId = setTimeout(() => {
1077          this.#doAdvance();
1078          return resolve(this.current());
1079        }, this.current().settings.delay)
1080      });
1081    }
1082
1083    /**
1084     * Returns a promise that resolves by hiding the current alert and advancing
1085     * the next alert into the display.
1086     *
1087     * @param reverse
1088     *  True if the previous alert should be advanced. Otherwise, the next alert
1089     *  will advance.
1090     * @returns {Promise<unknown>}
1091     *  A promise that resolves once the transition sequence has been inited.
1092     */
1093    #doAdvance (reverse = false) {
1094      return new Promise((resolve, reject) => {
1095        this.current().hide(reverse)
1096          .then(() => this.#page(reverse).display(reverse))
1097          .then(() => this.advance());
1098        resolve(this.current());
1099      });
1100    }
1101
1102    /**
1103     * Clears the current setTimeout() invocation and returns an immediately
1104     * resolved promise.
1105     *
1106     * @returns {Promise<unknown>}
1107     */
1108    cancel () {
1109      clearTimeout(this.#timeoutId);
1110      return new Promise((resolve, reject) => {
1111        resolve(this.current());
1112      });
1113    }
1114
1115    /**
1116     * Returns an immediately resolved promise that sets the current pager
1117     * sequence value in the ticker's pager.
1118     *
1119     * @returns {AlertsTicker}
1120     *  Reference to self.
1121     */
1122    setSequence () {
1123      this.counter.textContent = this.current().sequence
1124      return this;
1125    }
1126
1127    /**
1128     * Returns the ordinal index number that represents the last alert in the
1129     * alerts[] property array.
1130     *
1131     * @returns {number}
1132     */
1133    #lastIndex () {
1134      return this.alerts.length - 1;
1135    }
1136
1137  }
1138
1139  /**
1140   * Represents a single alert display item.
1141   */
1142  class AlertItem {
1143
1144    /**
1145     * The render classes to apply to the alert item's element on every class
1146     * name change.
1147     *
1148     * @type {[]}
1149     */
1150    #baseClasses = [];
1151
1152    /**
1153     * The sequence number of this alert item.
1154     *
1155     * @type {number}
1156     */
1157    sequence;
1158
1159    /**
1160     * Reference to the AlertItem that precedes this AlertItem in the sequence.
1161     *
1162     * @type {AlertItem}
1163     */
1164    prev;
1165
1166    /**
1167     * Reference to the AlertItem that follows this AlertItem in the sequence.
1168     *
1169     * @type {AlertItem}
1170     */
1171    next;
1172
1173    /**
1174     * Constructs a new AlertItem object.
1175     *
1176     * @param {string} id
1177     *  The HTML ID of the element that this alert item represents.
1178     * @param {[]} settings
1179     *  An object of settings, with the following key/value pairs:
1180     *    - delay: The number of milliseconds to display this Alert before
1181     *      cycling to the next alert in sequence.
1182     * @param {AlertsTicker} parent
1183     *  Reference to the parent ticker object.
1184     */
1185    constructor(id, settings, parent) {
1186      this.parent = parent;
1187      this.id = id;
1188      this.element = document.getElementById(id);
1189      this.settings = settings;
1190      this.oscillator = new Oscillator(
1191        this.parent.container,
1192        this.element.querySelector('.alert-message'),
1193        this.settings.delay
1194      );
1195      this.#baseClasses = this
1196        .element.className
1197        .replace('hidden', '')
1198        .split(' ');
1199      this.#baseClasses.push('animate__animated');
1200    }
1201
1202    /**
1203     * Animates this alert item entering the display container from the left.
1204     *
1205     * @param reverse
1206     *  If true, the animation enters from the right.
1207     * @returns {Promise}
1208     *  Reference to self.
1209     */
1210    display (reverse = false) {
1211      return new Promise((resolve, reject) => {
1212        this.element.addEventListener('animationend', () => {
1213          this.reset();
1214          this.parent.pagerLocked = false;
1215          return resolve(this);
1216        }, {once: true});
1217        this.parent.pagerLocked = true;
1218        this.element.className = this.#concatClasses(Animation.getShow(reverse));
1219        this.parent.setSequence();
1220        this.oscillator
1221          .animate()
1222          .monitorResize();
1223      });
1224    }
1225
1226    /**
1227     * Animates this alert item exiting the display container to the right.
1228     *
1229     * @param reverse
1230     *  If true, the animation exits to the left.
1231     * @returns {Promise}
1232     *  Reference to self.
1233     */
1234    hide (reverse = false) {
1235      return new Promise((resolve, reject) => {
1236        this.element.addEventListener('animationend', () => {
1237          this.parent.pagerLocked = false;
1238          return resolve(this);
1239        }, {once: true});
1240        this.parent.pagerLocked = true;
1241        this.element.className = this
1242          .#concatClasses(Animation.getHide(reverse)).concat(' animate__fast');
1243        this.oscillator.clear();
1244      });
1245    }
1246
1247    /**
1248     * Resets this AlertItem's element's class string to this alert's base
1249     * classes.
1250     *
1251     * @returns {AlertItem}
1252     *  Reference to self.
1253     */
1254    reset () {
1255      this.element.className = this.#baseClasses.join(' ');
1256      return this;
1257    }
1258
1259    /**
1260     * Returns the classes to apply based on the specified operation.
1261     *
1262     * @param {string} op_class
1263     *  The operation class to concatenate with the base classes.
1264     * @returns {string}
1265     *  Returns the space-delimited list of classes to apply.
1266     */
1267    #concatClasses (op_class) {
1268      return this.#baseClasses.concat(op_class).join(' ');
1269    }
1270
1271  }
1272
1273  /**
1274   * Static class that acts as a canonical enum for animation classes.
1275   *
1276   * @see library.animate.css in cwb_alerts.libraries.yml
1277   */
1278  class Animation {
1279    static ShowNext = new Animation('animate__fadeInLeftBig');
1280    static ShowPrev = new Animation('animate__fadeInRightBig');
1281    static HideNext = new Animation('animate__fadeOutRightBig');
1282    static HidePrev = new Animation('animate__fadeOutLeftBig');
1283
1284    constructor (name) {
1285      this.name = name;
1286    }
1287
1288    /**
1289     * Returns the class to animate an alert item into the ticker display from
1290     * the left.
1291     *
1292     * @param reverse
1293     *  True if the ticker should animate in from the right.
1294     * @returns {string}
1295     */
1296    static getShow (reverse = false) {
1297      return reverse ? Animation.ShowPrev.name : Animation.ShowNext.name
1298    }
1299
1300    /**
1301     * Returns the class to animate an alert item out of the ticker display to
1302     * the right.
1303     *
1304     * @param reverse
1305     *  True if the ticker should animate out to the left.
1306     * @returns {string}
1307     */
1308    static getHide (reverse = false) {
1309      return reverse ? Animation.HidePrev.name : Animation.HideNext.name;
1310    }
1311
1312  }
1313
1314  /**
1315   * An object for managing alert messages that are longer than their container.
1316   * When an alert message is detected to be longer than its enclosing element,
1317   * it will be horizontally oscillated back and forth.
1318   */
1319  class Oscillator {
1320
1321    /**
1322     * Amount of overflow, in pixels, that needs to be oscillated.
1323     *
1324     * @type {number}
1325     */
1326    #overflow;
1327
1328    /**
1329     * The transition time for each oscillation.
1330     *
1331     * @type {number}
1332     */
1333    #animationSpeed;
1334
1335    /**
1336     * The original CSS transition value for this oscillator's element.
1337     *
1338     * @type {string}
1339     */
1340    #originalTransition;
1341
1342    /**
1343     * The original CSS margin-left value for this oscillator's element.
1344     *
1345     * @type {string}
1346     */
1347    #originalMarginLeft;
1348
1349    /**
1350     * A canvas object that provides a computational manifold that does not
1351     * result in DOM reflow.
1352     *
1353     * @type {HTMLCanvasElement}
1354     */
1355    #canvas = document.createElement("canvas");
1356
1357    /**
1358     * Constructs a new oscillator object.
1359     *
1360     * @param {HTMLElement} textContainer
1361     *  Reference to the element that acts as the enclosing container for all
1362     *  alerts.
1363     * @param {HTMLElement} textElement
1364     *  Reference to a specific element whose content should be oscillated
1365     *  within the enclosing container.
1366     * @param {number} delay
1367     *  The number of seconds that this alert will be displayed.
1368     */
1369    constructor (textContainer, textElement, delay) {
1370      this.container = textContainer;
1371      this.element = textElement;
1372      this.delay = delay;
1373      this.#originalTransition = this.element.style.transition;
1374      this.#originalMarginLeft = this.element.style.marginLeft;
1375    }
1376
1377    /**
1378     * Returns the CSS computed value for a specific CSS style.
1379     *
1380     * @param {string} property
1381     *  The name of the CSS property whose computed value should be returned.
1382     * @returns {string}
1383     *  The computed CSS value.
1384     */
1385    #getComputedStyle (property) {
1386      return window.getComputedStyle(this.element, null)
1387        .getPropertyValue(property);
1388    }
1389
1390    /**
1391     * Returns a canvas context whose font has been set to the same as the
1392     * current text element.
1393     *
1394     * @returns {CanvasRenderingContext2D}
1395     *  Canvas rendering context.
1396     */
1397    #getFontContext () {
1398      const context = this.#canvas.getContext("2d");
1399      context.font = this.#getComputedStyle('font');
1400      return context;
1401    }
1402
1403    /**
1404     * Returns the width, in pixels, of the container element.
1405     *
1406     * @returns {number}
1407     *  The pixel width of the container element.
1408     */
1409    getContainerWidth () {
1410      return this.container.offsetWidth;
1411    }
1412
1413    /**
1414     * Returns the width, in pixels, of the text element's text content.
1415     *
1416     * @returns {number}
1417     *  The pixel width of the text element's text content.
1418     */
1419    getTextWidth () {
1420      const context = this.#getFontContext();
1421      const metrics = context.measureText(this.element.textContent);
1422      return metrics.width;
1423    }
1424
1425    /**
1426     * Returns the number of pixels difference between the container element and
1427     * the text element. Positive values indicate surplus space in the
1428     * container; negative values indicate overflowing text.
1429     *
1430     * @returns {number}
1431     *  The number of pixels difference between container and text element
1432     *  width.
1433     */
1434    overflow () {
1435      return this.getContainerWidth() - this.getTextWidth();
1436    }
1437
1438    /**
1439     * Detects any text overflow and animates an oscillation of necessary.
1440     *
1441     * @returns {Oscillator}
1442     *  Reference to self.
1443     */
1444    animate () {
1445      this.#calculate();
1446      if (this.#overflow >= 0) {
1447        return this;
1448      }
1449      const delay = '0.5'; //Math.min(2, this.#animationSpeed);
1450      this.element.style.transition = this
1451        .#originalTransition
1452        .concat(` margin-left ${this.#animationSpeed}s ease-in-out 2s`);
1453      this.element.style.marginLeft = this.#getMarginLeft(this.element.direction);
1454      this.toggleOscillation = e => {
1455        e.target.direction *= -1;
1456        e.target.style.marginLeft = this.#getMarginLeft(e.target.direction);
1457      };
1458      this.element.addEventListener('transitionend', this.toggleOscillation);
1459      return this;
1460    }
1461
1462    /**
1463     * Invokes a window resize event listener in order that will respond to
1464     * resize events be re-calculating the overflow and transition time.
1465     *
1466     * @returns {Oscillator}
1467     *  Reference to self.
1468     */
1469    monitorResize () {
1470      this.listenResize = Drupal.debounce(() => {
1471        this.element.removeEventListener('transitionend', this.toggleOscillation);
1472        this.animate();
1473      }, 300);
1474      window.addEventListener('resize', this.listenResize);
1475      return this;
1476    }
1477
1478    /**
1479     * Clears all oscillation animations for this container/text element pair.
1480     *
1481     * @returns {Oscillator}
1482     *  Reference to self.
1483     */
1484    clear () {
1485      this.element.style.transition = this.#originalTransition;
1486      this.element.style.marginLeft = this.#originalMarginLeft;
1487      this.element.direction = 1;
1488      this.element.removeEventListener('transitionend', this.toggleOscillation);
1489      window.removeEventListener('resize', this.listenResize)
1490      return this;
1491    }
1492
1493    /**
1494     * Calculates the overflow and animation speed and stores those values in
1495     * private local properties.
1496     *
1497     * @returns {Oscillator}
1498     *  Reference ot self.
1499     */
1500    #calculate () {
1501      this.#overflow = Math.min(this.overflow() - this.#totalPadding(), 0);
1502      if (this.#overflow >= 0) {
1503        return this;
1504      }
1505      this.#animationSpeed = Math.min(Math.max(
1506        (this.delay / 1000) - 3,
1507      1), 10);
1508      return this;
1509    }
1510
1511    /**
1512     * Returns an appropriate margin left values based on the direction of
1513     * oscillation.
1514     *
1515     * @param {number} direction
1516     *  A value of 1 for the initial oscillation direction (left to right), or
1517     *  -1 for the reverse oscillation (right to left).
1518     * @returns {string}
1519     *  A valid CSS value for the margin-left property.
1520     */
1521    #getMarginLeft (direction = 1) {
1522      return direction > 0 ? `${this.#overflow}px` : '0';
1523    }
1524
1525    /**
1526     * Returns the total width of the text element's left and right padding.
1527     *
1528     * @returns {number}
1529     *  Number of total pixels of left and right padding.
1530     */
1531    #totalPadding () {
1532      return parseInt(this.#getComputedStyle('padding-left'))
1533        + parseInt(this.#getComputedStyle('padding-right'));
1534    }
1535
1536    /**
1537     * Returns the current font size for the text element.
1538     *
1539     * @returns {number}
1540     *  The pixel size of the text element's font.
1541     */
1542    #fontSize () {
1543      return parseInt(this.#getComputedStyle('font-size'));
1544    }
1545
1546  }
1547
1548  // Register the AlertsTicker class with the alertFactory.
1549  Drupal.alertFactory
1550    .register('ticker', (ticker, selectors, alerts) => {
1551      return new AlertsTicker(ticker, selectors, alerts);
1552    });
1553})(Drupal);
1554;
1555(function ($, undefined) {
1556  'use strict';
1557
1558  /**
1559   * Attach ticker alerts behavior.
1560   *
1561   * @type {Drupal~behavior}
1562   *
1563   * @prop {Drupal~behaviorAttach} attach
1564   *  Initializes the ticker's operation for each instance on page.
1565   *
1566   */
1567  Drupal.behaviors.cwb_alerts_ticker = {
1568    attach: function (context, settings) {
1569      $('body').once('cwb-alerts-ticker').each(function () {
1570        const
1571          _settings = settings.cwb_alerts_ticker,
1572          selectors = _settings.selectors,
1573          alerts = _settings.data.alerts
1574        ;
1575        $(selectors.ticker, context).each(function () {
1576          const alerts_ticker = Drupal.alertFactory
1577            .get('ticker')(this, selectors, alerts);
1578          alerts_ticker.start();
1579        });
1580      });
1581    }
1582  }
1583})(jQuery);
1584;

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.