PageSourceSearch

https://tcatharriman.edu/sites/default/files/js/js_ml0FUZ5nVwxYYs0XjnbSAQgjY1U7RSxANXuT_n5zWak.js

js tcatharriman.edu collected 2026-09-28 09:20:19 UTC 35,927 bytes, 981 lines download raw bytes

1/**
2 * @file
3 * Colorbox module init js.
4 */
5
6(function ($) {
7
8Drupal.behaviors.initColorbox = {
9  attach: function (context, settings) {
10    if (!$.isFunction($('a, area, input', context).colorbox) || typeof settings.colorbox === 'undefined') {
11      return;
12    }
13
14    if (settings.colorbox.mobiledetect && window.matchMedia) {
15      // Disable Colorbox for small screens.
16      var mq = window.matchMedia("(max-device-width: " + settings.colorbox.mobiledevicewidth + ")");
17      if (mq.matches) {
18        return;
19      }
20    }
21
22    // Use "data-colorbox-gallery" if set otherwise use "rel".
23    settings.colorbox.rel = function () {
24      if ($(this).data('colorbox-gallery')) {
25        return $(this).data('colorbox-gallery');
26      }
27      else {
28        return $(this).attr('rel');
29      }
30    };
31
32    $('.colorbox', context)
33      .once('init-colorbox').each(function(){
34        // Only images are supported for the "colorbox" class.
35        // The "photo" setting forces the href attribute to be treated as an image.
36        var extendParams = {
37          photo: true
38        };
39        // If a title attribute is supplied, sanitize it.
40        var title = $(this).attr('title');
41        if (typeof title === 'undefined') {
42          title = this.dataset.cboxTitle;
43        }
44        if (title) {
45          extendParams.title = Drupal.colorbox.sanitizeMarkup(title);
46        }
47        $(this).colorbox($.extend({}, settings.colorbox, extendParams));
48
49        // Only allow http or https protocol in hrefs.
50        var href = $(this).attr('href');
51        var protocolRegex = /^(https?)/;
52        if (href && href.substring(0, 1) !== '/') {
53          var protocol = href.split(':')[0];
54          // Use a regex to match http or https protocol.
55          if (!protocolRegex.test(protocol)) {
56            $(this).removeAttr('href');
57          }
58        }
59        var dataHref = this.dataset.cboxHref;
60        if (dataHref && dataHref.substring(0, 1) !== '/') {
61          var dataProtocol = dataHref.split(':')[0];
62          if (!protocolRegex.test(dataProtocol)) {
63            delete this.dataset.cboxHref;
64          }
65        }
66
67        // Since the sanitized title has been passed to colorbox settings,
68        // delete the unsanitized data-cbox-title attribute.
69        delete this.dataset.cboxTitle;
70
71        // Disallow dangerous data attributes.
72        delete this.dataset.cboxIframeAttrs;
73
74        // Sanitize other data attributes.
75        var sanitizeDataList = ['cboxNext', 'cboxPrevious', 'cboxCurrent',
76          'cboxClose', 'cboxSlideshowstop', 'cboxSlideshowstart',
77          'cboxXhrError', 'cboxImgerror', 'cboxHtml'
78        ];
79        for (var a of sanitizeDataList) {
80          if (this.dataset.hasOwnProperty(a)) {
81            this.dataset[a] = Drupal.colorbox.sanitizeMarkup(this.dataset[a]);
82          }
83        }
84      });
85
86    $(context).bind('cbox_complete', function () {
87      Drupal.attachBehaviors($('#cboxLoadedContent'));
88    });
89  }
90};
91
92// Create colorbox namespace if it doesn't exist.
93if (!Drupal.hasOwnProperty('colorbox')) {
94  Drupal.colorbox = {};
95}
96
97/**
98 * Global function to allow sanitizing captions and control strings.
99 *
100 * @param markup
101 *   String containing potential markup.
102 * @return @string
103 *  Sanitized string with potentially dangerous markup removed.
104 */
105Drupal.colorbox.sanitizeMarkup = function(markup) {
106  // If DOMPurify installed, allow some HTML. Otherwise, treat as plain text.
107  if (typeof DOMPurify !== 'undefined') {
108    var purifyConfig = {
109      ALLOWED_TAGS: [
110        'a',
111        'b',
112        'strong',
113        'i',
114        'em',
115        'u',
116        'cite',
117        'code',
118        'br'
119      ],
120      ALLOWED_ATTR: [
121        'href',
122        'hreflang',
123        'title',
124        'target'
125      ]
126    }
127    if (Drupal.settings.hasOwnProperty('dompurify_custom_config')) {
128      purifyConfig = Drupal.settings.dompurify_custom_config;
129    }
130    return DOMPurify.sanitize(markup, purifyConfig);
131  }
132  else {
133    return Drupal.checkPlain(markup);
134  }
135}
136
137})(jQuery);
138;
139/**
140 * @file
141 * Colorbox module style js.
142 */
143
144(function ($) {
145
146Drupal.behaviors.initColorboxDefaultStyle = {
147  attach: function (context, settings) {
148    $(context).bind('cbox_complete', function () {
149      // Only run if there is a title.
150      if ($('#cboxTitle:empty', context).length == false) {
151        $('#cboxLoadedContent img', context).bind('mouseover', function () {
152          $('#cboxTitle', context).slideDown();
153        });
154        $('#cboxOverlay', context).bind('mouseover', function () {
155          $('#cboxTitle', context).slideUp();
156        });
157      }
158      else {
159        $('#cboxTitle', context).hide();
160      }
161    });
162  }
163};
164
165})(jQuery);
166;
167(function ($) {
168
169  Drupal.behaviors.captcha = {
170    attach: function (context) {
171
172      // Turn off autocompletion for the CAPTCHA response field.
173      // We do it here with JavaScript (instead of directly in the markup)
174      // because this autocomplete attribute is not standard and
175      // it would break (X)HTML compliance.
176      $("#edit-captcha-response").attr("autocomplete", "off");
177
178    }
179  };
180
181  Drupal.behaviors.captchaAdmin = {
182    attach: function (context) {
183      // Add onclick handler to checkbox for adding a CAPTCHA description
184      // so that the textfields for the CAPTCHA description are hidden
185      // when no description should be added.
186      // @todo: div.form-item-captcha-description depends on theming, maybe
187      // it's better to add our own wrapper with id (instead of a class).
188      $("#edit-captcha-add-captcha-description").click(function() {
189        if ($("#edit-captcha-add-captcha-description").is(":checked")) {
190          // Show the CAPTCHA description textfield(s).
191          $("div.form-item-captcha-description").show('slow');
192        }
193        else {
194          // Hide the CAPTCHA description textfield(s).
195          $("div.form-item-captcha-description").hide('slow');
196        }
197      });
198      // Hide the CAPTCHA description textfields if option is disabled on page load.
199      if (!$("#edit-captcha-add-captcha-description").is(":checked")) {
200        $("div.form-item-captcha-description").hide();
201      }
202    }
203
204  };
205
206})(jQuery);
207;
208(function ($) {
209
210Drupal.behaviors.textarea = {
211  attach: function (context, settings) {
212    $('.form-textarea-wrapper.resizable', context).once('textarea', function () {
213      var staticOffset = null;
214      var textarea = $(this).addClass('resizable-textarea').find('textarea');
215      var grippie = $('<div class="grippie"></div>').mousedown(startDrag);
216
217      grippie.insertAfter(textarea);
218
219      function startDrag(e) {
220        staticOffset = textarea.height() - e.pageY;
221        textarea.css('opacity', 0.25);
222        $(document).mousemove(performDrag).mouseup(endDrag);
223        return false;
224      }
225
226      function performDrag(e) {
227        textarea.height(Math.max(32, staticOffset + e.pageY) + 'px');
228        return false;
229      }
230
231      function endDrag(e) {
232        $(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag);
233        textarea.css('opacity', 1);
234      }
235    });
236  }
237};
238
239})(jQuery);
240;
241/**
242 * @file
243 * JavaScript behaviors for the front-end display of webforms.
244 */
245
246(function ($) {
247
248  "use strict";
249
250  Drupal.behaviors.webform = Drupal.behaviors.webform || {};
251
252  Drupal.behaviors.webform.attach = function (context) {
253    // Calendar datepicker behavior.
254    Drupal.webform.datepicker(context);
255
256    // Conditional logic.
257    if (Drupal.settings.webform && Drupal.settings.webform.conditionals) {
258      Drupal.webform.conditional(context);
259    }
260  };
261
262  Drupal.webform = Drupal.webform || {};
263
264  Drupal.webform.datepicker = function (context) {
265    $('div.webform-datepicker').each(function () {
266      var $webformDatepicker = $(this);
267      var $calendar = $webformDatepicker.find('input.webform-calendar');
268
269      // Ensure the page we're on actually contains a datepicker.
270      if ($calendar.length == 0) {
271        return;
272      }
273
274      var startDate = $calendar[0].className.replace(/.*webform-calendar-start-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
275      var endDate = $calendar[0].className.replace(/.*webform-calendar-end-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
276      var firstDay = $calendar[0].className.replace(/.*webform-calendar-day-(\d).*/, '$1');
277      // Convert date strings into actual Date objects.
278      startDate = new Date(startDate[0], startDate[1] - 1, startDate[2]);
279      endDate = new Date(endDate[0], endDate[1] - 1, endDate[2]);
280
281      // Ensure that start comes before end for datepicker.
282      if (startDate > endDate) {
283        var laterDate = startDate;
284        startDate = endDate;
285        endDate = laterDate;
286      }
287
288      var startYear = startDate.getFullYear();
289      var endYear = endDate.getFullYear();
290
291      // Set up the jQuery datepicker element.
292      $calendar.datepicker({
293        dateFormat: 'yy-mm-dd',
294        yearRange: startYear + ':' + endYear,
295        firstDay: parseInt(firstDay),
296        minDate: startDate,
297        maxDate: endDate,
298        onSelect: function (dateText, inst) {
299          var date = dateText.split('-');
300          $webformDatepicker.find('select.year, input.year').val(+date[0]).trigger('change');
301          $webformDatepicker.find('select.month').val(+date[1]).trigger('change');
302          $webformDatepicker.find('select.day').val(+date[2]).trigger('change');
303        },
304        beforeShow: function (input, inst) {
305          // Get the select list values.
306          var year = $webformDatepicker.find('select.year, input.year').val();
307          var month = $webformDatepicker.find('select.month').val();
308          var day = $webformDatepicker.find('select.day').val();
309
310          // If empty, default to the current year/month/day in the popup.
311          var today = new Date();
312          year = year ? year : today.getFullYear();
313          month = month ? month : today.getMonth() + 1;
314          day = day ? day : today.getDate();
315
316          // Make sure that the default year fits in the available options.
317          year = (year < startYear || year > endYear) ? startYear : year;
318
319          // jQuery UI Datepicker will read the input field and base its date
320          // off of that, even though in our case the input field is a button.
321          $(input).val(year + '-' + month + '-' + day);
322        }
323      });
324
325      // Prevent the calendar button from submitting the form.
326      $calendar.click(function (event) {
327        // This event is triggered also when pressing enter when the focus is on
328        // previous webform components, but we only want to do something when
329        // we are on the calendar component. By checking the event client x/y
330        // position we known if it was the user clicking. For keyboard navigators
331        // simply the focus handles the date picker so we don't have to do
332        // anything special for them.
333        if (event.clientX !== 0 && event.clientY !== 0) {
334          // Focus is only necessary for Safari. But it has no impact on other
335          // browsers.
336          $(this).focus();
337          event.preventDefault();
338        }
339      });
340
341      // Clear date on backspace or delete.
342      $calendar.keyup(function (e) {
343        if (e.keyCode == 8 || e.keyCode == 46) {
344          $.datepicker._clearDate(this);
345        }
346      });
347    });
348  };
349
350  Drupal.webform.conditional = function (context) {
351    // Add the bindings to each webform on the page.
352    $.each(Drupal.settings.webform.conditionals, function (formKey, settings) {
353      var $form = $('.' + formKey + ':not(.webform-conditional-processed)');
354      $form.each(function (index, currentForm) {
355        var $currentForm = $(currentForm);
356        $currentForm.addClass('webform-conditional-processed');
357        $currentForm.bind('change', {'settings': settings}, Drupal.webform.conditionalCheck);
358
359        // Trigger all the elements that cause conditionals on this form.
360        Drupal.webform.doConditions($currentForm, settings);
361      });
362    });
363  };
364
365  /**
366   * Event handler to respond to field changes in a form.
367   *
368   * This event is bound to the entire form, not individual fields.
369   */
370  Drupal.webform.conditionalCheck = function (e) {
371    var $triggerElement = $(e.target).closest('.webform-component');
372    if (!$triggerElement.length) {
373      return;
374    }
375    var $form = $triggerElement.closest('form');
376    var triggerElementKey = $triggerElement.attr('class').match(/webform-component--[^ ]+/)[0];
377    var settings = e.data.settings;
378    if (settings.sourceMap[triggerElementKey]) {
379      Drupal.webform.doConditions($form, settings);
380    }
381  };
382
383  /**
384   * Processes all conditional.
385   */
386  Drupal.webform.doConditions = function ($form, settings) {
387
388    var stackPointer;
389    var resultStack;
390
391    /**
392     * Initializes an execution stack for a conditional group's rules.
393     *
394     * Also initializes sub-conditional rules.
395     */
396    function executionStackInitialize(andor) {
397      stackPointer = -1;
398      resultStack = [];
399      executionStackPush(andor);
400    }
401
402    /**
403     * Starts a new subconditional for the given and/or operator.
404     */
405    function executionStackPush(andor) {
406      resultStack[++stackPointer] = {
407        results: [],
408        andor: andor,
409      };
410    }
411
412    /**
413     * Adds a rule's result to the current sub-conditional.
414     */
415    function executionStackAccumulate(result) {
416      resultStack[stackPointer]['results'].push(result);
417    }
418
419    /**
420     * Finishes a sub-conditional and adds the result to the parent stack frame.
421     */
422    function executionStackPop() {
423      // Calculate the and/or result.
424      var stackFrame = resultStack[stackPointer];
425      // Pop stack and protect against stack underflow.
426      stackPointer = Math.max(0, stackPointer - 1);
427      var $conditionalResults = stackFrame['results'];
428      var filteredResults = $.map($conditionalResults, function (val) {
429        return val ? val : null;
430      });
431      return stackFrame['andor'] === 'or'
432                ? filteredResults.length > 0
433                : filteredResults.length === $conditionalResults.length;
434    }
435
436    // Track what has been set/hidden for each target component's elements.
437    // Hidden elements must be disabled because if they are required and don't
438    // have a value, they will prevent submission due to html5 validation.
439    // Each execution of the conditionals adds a temporary class
440    // webform-disabled-flag so that elements hidden or set can be disabled and
441    // also be prevented from being re-enabled by another conditional (such as a
442    // parent fieldset). After processing conditionals, this temporary class
443    // must be removed in preparation for the next execution of the
444    // conditionals.
445    $.each(settings.ruleGroups, function (rgid_key, rule_group) {
446      var ruleGroup = settings.ruleGroups[rgid_key];
447
448      // Perform the comparison callback and build the results for this group.
449      executionStackInitialize(ruleGroup['andor']);
450      $.each(ruleGroup['rules'], function (m, rule) {
451        switch (rule['source_type']) {
452          case 'component':
453            var elementKey = rule['source'];
454            var element = $form.find('.' + elementKey)[0];
455            var existingValue = settings.values[elementKey] ? settings.values[elementKey] : null;
456            executionStackAccumulate(window['Drupal']['webform'][rule.callback](element, existingValue, rule['value']));
457            break;
458
459          case 'conditional_start':
460            executionStackPush(rule['andor']);
461            break;
462
463          case 'conditional_end':
464            executionStackAccumulate(executionStackPop());
465            break;
466        }
467      });
468      var conditionalResult = executionStackPop();
469
470      $.each(ruleGroup['actions'], function (aid, action) {
471        var $target = $form.find('.' + action['target']);
472        var actionResult = action['invert'] ? !conditionalResult : conditionalResult;
473        switch (action['action']) {
474          case 'show':
475            var changed = actionResult != Drupal.webform.isVisible($target);
476            if (actionResult) {
477              $target.find('.webform-conditional-disabled:not(.webform-disabled-flag)')
478                .removeClass('webform-conditional-disabled')
479                .webformProp('disabled', false);
480              $target
481                .removeClass('webform-conditional-hidden')
482                .show();
483              $form.find('.chosen-disabled').prev().trigger('chosen:updated.chosen');
484            }
485            else {
486              $target
487                .hide()
488                .addClass('webform-conditional-hidden')
489                .find(':input')
490                  .addClass('webform-conditional-disabled webform-disabled-flag')
491                  .webformProp('disabled', true);
492            }
493            if (changed && $target.is('tr')) {
494              Drupal.webform.restripeTable($target.closest('table').first());
495            }
496            break;
497
498          case 'require':
499            var $requiredSpan = $target.find('.form-required, .form-optional').first();
500            if (actionResult != $requiredSpan.hasClass('form-required')) {
501              var $targetInputElements = $target.find("input:text,textarea,input[type='email'],select,input:radio,input:checkbox,input:file");
502              // Rather than hide the required tag, remove it so that other
503              // jQuery can respond via Drupal behaviors.
504              Drupal.detachBehaviors($requiredSpan);
505              $targetInputElements
506                .webformProp('required', actionResult)
507                .toggleClass('required', actionResult);
508              if (actionResult) {
509                $requiredSpan.replaceWith('<span class="form-required" title="' + Drupal.t('This field is required.') + '">*</span>');
510              }
511              else {
512                $requiredSpan.replaceWith('<span class="form-optional"></span>');
513              }
514              Drupal.attachBehaviors($requiredSpan);
515            }
516            break;
517
518          case 'set':
519            var $texts = $target.find("input:text,textarea,input[type='email']");
520            var $selects = $target.find('select,select option,input:radio,input:checkbox');
521            var $markups = $target.filter('.webform-component-markup');
522            if (actionResult) {
523              var multiple = $.map(action['argument'].split(','), $.trim);
524              $selects
525                .webformVal(multiple)
526                .webformProp('disabled', true)
527                  .addClass('webform-disabled-flag');
528              $texts
529                .val([action['argument']])
530                .webformProp('readonly', true)
531                .addClass('webform-disabled-flag');
532              // A special case is made for markup. It is sanitized with
533              // filter_xss_admin on the server. otherwise text() should be used
534              // to avoid an XSS vulnerability. text() however would preclude
535              // the use of tags like <strong> or <a>.
536              $markups.html(action['argument']);
537            }
538            else {
539              $selects.not('.webform-disabled-flag')
540                .webformProp('disabled', false);
541              $texts.not('.webform-disabled-flag')
542                .webformProp('readonly', false);
543              // Markup not set? Then restore original markup as provided in
544              // the attribute data-webform-markup.
545              $markups.each(function () {
546                var $this = $(this);
547                var original = $this.data('webform-markup');
548                if (original !== undefined) {
549                  $this.html(original);
550                }
551              });
552            }
553            break;
554        }
555      }); // End look on each action for one conditional.
556    }); // End loop on each conditional.
557
558    $form.find('.webform-disabled-flag').removeClass('webform-disabled-flag');
559  };
560
561  /**
562   * Event handler to prevent propagation of events.
563   *
564   * Typically click for disabling radio and checkboxes.
565   */
566  Drupal.webform.stopEvent = function () {
567    return false;
568  };
569
570  Drupal.webform.conditionalOperatorStringEqual = function (element, existingValue, ruleValue) {
571    var returnValue = false;
572    var currentValue = Drupal.webform.stringValue(element, existingValue);
573    $.each(currentValue, function (n, value) {
574      if (value.toLowerCase() === ruleValue.toLowerCase()) {
575        returnValue = true;
576        return false; // break.
577      }
578    });
579    return returnValue;
580  };
581
582  Drupal.webform.conditionalOperatorStringNotEqual = function (element, existingValue, ruleValue) {
583    var found = false;
584    var currentValue = Drupal.webform.stringValue(element, existingValue);
585    $.each(currentValue, function (n, value) {
586      if (value.toLowerCase() === ruleValue.toLowerCase()) {
587        found = true;
588      }
589    });
590    return !found;
591  };
592
593  Drupal.webform.conditionalOperatorStringContains = function (element, existingValue, ruleValue) {
594    var returnValue = false;
595    var currentValue = Drupal.webform.stringValue(element, existingValue);
596    $.each(currentValue, function (n, value) {
597      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
598        returnValue = true;
599        return false; // break.
600      }
601    });
602    return returnValue;
603  };
604
605  Drupal.webform.conditionalOperatorStringDoesNotContain = function (element, existingValue, ruleValue) {
606    var found = false;
607    var currentValue = Drupal.webform.stringValue(element, existingValue);
608    $.each(currentValue, function (n, value) {
609      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
610        found = true;
611      }
612    });
613    return !found;
614  };
615
616  Drupal.webform.conditionalOperatorStringBeginsWith = function (element, existingValue, ruleValue) {
617    var returnValue = false;
618    var currentValue = Drupal.webform.stringValue(element, existingValue);
619    $.each(currentValue, function (n, value) {
620      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) === 0) {
621        returnValue = true;
622        return false; // break.
623      }
624    });
625    return returnValue;
626  };
627
628  Drupal.webform.conditionalOperatorStringEndsWith = function (element, existingValue, ruleValue) {
629    var returnValue = false;
630    var currentValue = Drupal.webform.stringValue(element, existingValue);
631    $.each(currentValue, function (n, value) {
632      if (value.toLowerCase().lastIndexOf(ruleValue.toLowerCase()) === value.length - ruleValue.length) {
633        returnValue = true;
634        return false; // break.
635      }
636    });
637    return returnValue;
638  };
639
640  Drupal.webform.conditionalOperatorStringEmpty = function (element, existingValue, ruleValue) {
641    var currentValue = Drupal.webform.stringValue(element, existingValue);
642    var returnValue = true;
643    $.each(currentValue, function (n, value) {
644      if (value !== '') {
645        returnValue = false;
646        return false; // break.
647      }
648    });
649    return returnValue;
650  };
651
652  Drupal.webform.conditionalOperatorStringNotEmpty = function (element, existingValue, ruleValue) {
653    return !Drupal.webform.conditionalOperatorStringEmpty(element, existingValue, ruleValue);
654  };
655
656  Drupal.webform.conditionalOperatorSelectGreaterThan = function (element, existingValue, ruleValue) {
657    var currentValue = Drupal.webform.stringValue(element, existingValue);
658    return Drupal.webform.compare_select(currentValue[0], ruleValue, element) > 0;
659  };
660
661  Drupal.webform.conditionalOperatorSelectGreaterThanEqual = function (element, existingValue, ruleValue) {
662    var currentValue = Drupal.webform.stringValue(element, existingValue);
663    var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
664    return comparison > 0 || comparison === 0;
665  };
666
667  Drupal.webform.conditionalOperatorSelectLessThan = function (element, existingValue, ruleValue) {
668    var currentValue = Drupal.webform.stringValue(element, existingValue);
669    return Drupal.webform.compare_select(currentValue[0], ruleValue, element) < 0;
670  };
671
672  Drupal.webform.conditionalOperatorSelectLessThanEqual = function (element, existingValue, ruleValue) {
673    var currentValue = Drupal.webform.stringValue(element, existingV
673alue);
674    var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
675    return comparison < 0 || comparison === 0;
676  };
677
678  Drupal.webform.conditionalOperatorNumericEqual = function (element, existingValue, ruleValue) {
679    // See float comparison: http://php.net/manual/en/language.types.float.php
680    var currentValue = Drupal.webform.stringValue(element, existingValue);
681    var epsilon = 0.000001;
682    // An empty string does not match any number.
683    return currentValue[0] === '' ? false : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) < epsilon);
684  };
685
686  Drupal.webform.conditionalOperatorNumericNotEqual = function (element, existingValue, ruleValue) {
687    // See float comparison: http://php.net/manual/en/language.types.float.php
688    var currentValue = Drupal.webform.stringValue(element, existingValue);
689    var epsilon = 0.000001;
690    // An empty string does not match any number.
691    return currentValue[0] === '' ? true : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) >= epsilon);
692  };
693
694  Drupal.webform.conditionalOperatorNumericGreaterThan = function (element, existingValue, ruleValue) {
695    var currentValue = Drupal.webform.stringValue(element, existingValue);
696    return parseFloat(currentValue[0]) > parseFloat(ruleValue);
697  };
698
699  Drupal.webform.conditionalOperatorNumericGreaterThanEqual = function (element, existingValue, ruleValue) {
700    return Drupal.webform.conditionalOperatorNumericGreaterThan(element, existingValue, ruleValue) ||
701           Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
702  };
703
704  Drupal.webform.conditionalOperatorNumericLessThan = function (element, existingValue, ruleValue) {
705    var currentValue = Drupal.webform.stringValue(element, existingValue);
706    return parseFloat(currentValue[0]) < parseFloat(ruleValue);
707  };
708
709  Drupal.webform.conditionalOperatorNumericLessThanEqual = function (element, existingValue, ruleValue) {
710    return Drupal.webform.conditionalOperatorNumericLessThan(element, existingValue, ruleValue) ||
711           Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
712  };
713
714  Drupal.webform.conditionalOperatorDateEqual = function (element, existingValue, ruleValue) {
715    var currentValue = Drupal.webform.dateValue(element, existingValue);
716    return currentValue === ruleValue;
717  };
718
719  Drupal.webform.conditionalOperatorDateNotEqual = function (element, existingValue, ruleValue) {
720    return !Drupal.webform.conditionalOperatorDateEqual(element, existingValue, ruleValue);
721  };
722
723  Drupal.webform.conditionalOperatorDateBefore = function (element, existingValue, ruleValue) {
724    var currentValue = Drupal.webform.dateValue(element, existingValue);
725    return (currentValue !== false) && currentValue < ruleValue;
726  };
727
728  Drupal.webform.conditionalOperatorDateBeforeEqual = function (element, existingValue, ruleValue) {
729    var currentValue = Drupal.webform.dateValue(element, existingValue);
730    return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
731  };
732
733  Drupal.webform.conditionalOperatorDateAfter = function (element, existingValue, ruleValue) {
734    var currentValue = Drupal.webform.dateValue(element, existingValue);
735    return (currentValue !== false) && currentValue > ruleValue;
736  };
737
738  Drupal.webform.conditionalOperatorDateAfterEqual = function (element, existingValue, ruleValue) {
739    var currentValue = Drupal.webform.dateValue(element, existingValue);
740    return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
741  };
742
743  Drupal.webform.conditionalOperatorTimeEqual = function (element, existingValue, ruleValue) {
744    var currentValue = Drupal.webform.timeValue(element, existingValue);
745    return currentValue === ruleValue;
746  };
747
748  Drupal.webform.conditionalOperatorTimeNotEqual = function (element, existingValue, ruleValue) {
749    return !Drupal.webform.conditionalOperatorTimeEqual(element, existingValue, ruleValue);
750  };
751
752  Drupal.webform.conditionalOperatorTimeBefore = function (element, existingV
752alue, ruleValue) {
753    // Date and time operators intentionally exclusive for "before".
754    var currentValue = Drupal.webform.timeValue(element, existingValue);
755    return (currentValue !== false) && (currentValue < ruleValue);
756  };
757
758  Drupal.webform.conditionalOperatorTimeBeforeEqual = function (element, existingValue, ruleValue) {
759    // Date and time operators intentionally exclusive for "before".
760    var currentValue = Drupal.webform.timeValue(element, existingValue);
761    return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
762  };
763
764  Drupal.webform.conditionalOperatorTimeAfter = function (element, existingValue, ruleValue) {
765    // Date and time operators intentionally inclusive for "after".
766    var currentValue = Drupal.webform.timeValue(element, existingValue);
767    return (currentValue !== false) && (currentValue > ruleValue);
768  };
769
770  Drupal.webform.conditionalOperatorTimeAfterEqual = function (element, existingValue, ruleValue) {
771    // Date and time operators intentionally inclusive for "after".
772    var currentValue = Drupal.webform.timeValue(element, existingValue);
773    return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
774  };
775
776  /**
777   * Utility function to compare values of a select component.
778   *
779   * @param string a
780   *   First select option key to compare
781   * @param string b
782   *   Second select option key to compare
783   * @param array options
784   *   Associative array where the a and b are within the keys
785   *
786   * @return integer based upon position of $a and $b in $options
787   *   -N if $a above (<) $b
788   *   0 if $a = $b
789   *   +N if $a is below (>) $b
790   */
791  Drupal.webform.compare_select = function (a, b, element) {
792    var optionList = [];
793    $('option,input:radio,input:checkbox', element).each(function () {
794      optionList.push($(this).val());
795    });
796    var a_position = optionList.indexOf(a);
797    var b_position = optionList.indexOf(b);
798    return (a_position < 0 || b_position < 0) ? null : a_position - b_position;
799  };
800
801  /**
802   * Utility to return current visibility.
803   *
804   * Uses actual visibility, except for hidden components which use the applied
805   * disabled class.
806   */
807  Drupal.webform.isVisible = function ($element) {
808    return $element.hasClass('webform-component-hidden')
809              ? !$element.find('input').first().hasClass('webform-conditional-disabled')
810              : $element.closest('.webform-conditional-hidden').length == 0;
811  };
812
813  /**
814   * Function to get a string value from a select/radios/text/etc. field.
815   */
816  Drupal.webform.stringValue = function (element, existingValue) {
817    var value = [];
818    if (element) {
819      var $element = $(element);
820      if (Drupal.webform.isVisible($element)) {
821        // Checkboxes and radios.
822        $element.find('input[type=checkbox]:checked,input[type=radio]:checked').each(function () {
823          value.push(this.value);
824        });
825        // Select lists.
826        if (!value.length) {
827          var selectValue = $element.find('select').val();
828          if (selectValue) {
829            if ($.isArray(selectValue)) {
830              value = selectValue;
831            }
832            else {
833              value.push(selectValue);
834            }
835          }
836        }
837        // Simple text fields. This check is done last so that the select list
838        // in select-or-other fields comes before the "other" text field.
839        if (!value.length) {
840          $element.find('input:not([type=checkbox],[type=radio]),textarea').each(function () {
841            value.push(this.value);
842          });
843        }
844      }
845    }
846    else {
847      switch ($.type(existingValue)) {
848        case 'array':
849          value = existingValue;
850          break;
851
852        case 'string':
853          value.push(existingValue);
854          break;
855      }
856    }
857    return value;
858  };
859
860  /**
861   * Utility function to calculate a second-based timestamp from a time field.
862   */
863  Drupal.webform.dateValue = function (element, existingValue) {
864    var value = false;
865    if (element) {
866      var $element = $(element);
867      if (Drupal.webform.isVisible($element)) {
868        var day = $element.find('[name*=day]').val();
869        var month = $element.find('[name*=month]').val();
870        var year = $element.find('[name*=year]').val();
871        // Months are 0 indexed in JavaScript.
872        if (month) {
873          month--;
874        }
875        if (year !== '' && month !== '' && day !== '') {
876          value = Date.UTC(year, month, day) / 1000;
877        }
878      }
879    }
880    else {
881      if ($.type(existingValue) === 'array' && existingValue.length) {
882        existingValue = existingValue[0];
883      }
884      if ($.type(existingValue) === 'string') {
885        existingValue = existingV
885alue.split('-');
886      }
887      if (existingValue.length === 3) {
888        value = Date.UTC(existingValue[0], existingValue[1], existingValue[2]) / 1000;
889      }
890    }
891    return value;
892  };
893
894  /**
895   * Utility function to calculate a millisecond timestamp from a time field.
896   */
897  Drupal.webform.timeValue = function (element, existingValue) {
898    var value = false;
899    if (element) {
900      var $element = $(element);
901      if (Drupal.webform.isVisible($element)) {
902        var hour = $element.find('[name*=hour]').val();
903        var minute = $element.find('[name*=minute]').val();
904        var ampm = $element.find('[name*=ampm]:checked').val();
905
906        // Convert to integers if set.
907        hour = (hour === '') ? hour : parseInt(hour);
908        minute = (minute === '') ? minute : parseInt(minute);
909
910        if (hour !== '') {
911          hour = (hour < 12 && ampm == 'pm') ? hour + 12 : hour;
912          hour = (hour === 12 && ampm == 'am') ? 0 : hour;
913        }
914        if (hour !== '' && minute !== '') {
915          value = Date.UTC(1970, 0, 1, hour, minute) / 1000;
916        }
917      }
918    }
919    else {
920      if ($.type(existingValue) === 'array' && existingValue.length) {
921        existingValue = existingValue[0];
922      }
923      if ($.type(existingValue) === 'string') {
924        existingValue = existingValue.split(':');
925      }
926      if (existingValue.length >= 2) {
927        value = Date.UTC(1970, 0, 1, existingValue[0], existingValue[1]) / 1000;
928      }
929    }
930    return value;
931  };
932
933  /**
934   * Make a prop shim for jQuery < 1.9.
935   */
936  $.fn.webformProp = $.fn.webformProp || function (name, value) {
937    if (value) {
938      return $.fn.prop ? this.prop(name, true) : this.attr(name, true);
939    }
940    else {
941      return $.fn.prop ? this.prop(name, false) : this.removeAttr(name);
942    }
943  };
944
945  /**
946   * Make a multi-valued val() function.
947   *
948   * This is for setting checkboxes, radios, and select elements.
949   */
950  $.fn.webformVal = function (values) {
951    this.each(function () {
952      var $this = $(this);
953      var value = $this.val();
954      var on = $.inArray($this.val(), values) != -1;
955      if (this.nodeName == 'OPTION') {
956        $this.webformProp('selected', on ? value : false);
957      }
958      else {
959        $this.val(on ? [value] : false);
960      }
961    });
962    return this;
963  };
964
965  /**
966   * Given a table's DOM element, restripe the odd/even classes.
967   */
968  Drupal.webform.restripeTable = function (table) {
969    // :even and :odd are reversed because jQuery counts from 0 and
970    // we count from 1, so we're out of sync.
971    // Match immediate children of the parent element to allow nesting.
972    $('> tbody > tr, > tr', table)
973      .filter(':visible:odd').filter('.odd')
974        .removeClass('odd').addClass('even')
975      .end().end()
976      .filter(':visible:even').filter('.even')
977        .removeClass('even').addClass('odd');
978  };
979
980})(jQuery);
981;

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.