PageSourceSearch

https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/global.js?v=9

js bafin.de collected 2026-10-01 08:50:48 UTC 587,338 bytes, 18,112 lines download raw bytes

1'use strict';
2
3  var ISPREVIEW = false;
4        /* Start variables_LABELS */
5                var CONSENT_LABEL = 'Aktivierung erforderlich';
6    var CONSENT_DESCRIPTION = 'Drittanbieter-Inhalte';
7    var CONSENT_TEXT = 'Wir möchten Sie darauf hinweisen, dass nach der Aktivierung Daten an Drittanbieter übermittelt werden.';
8    var CONSENT_BUTTON = 'Ich akzeptiere';
9
10        /* Ende variables_LABELS */
11        /* Start variables_IMG */
12                var image_url_mejs_controls = 'https://www.bafin.de/SiteGlobals/Frontend/Images/icons/mediaelement/mejs-controls.svg?__blob=normal&v=1';
13    var image_url_mejs_a11y_icons = 'https://www.bafin.de/SiteGlobals/Frontend/Images/icons/mediaelement/mejs-a11y-icons.svg?__blob=normal&v=1';
14
15        /* Ende variables_IMG */
16
17var json_url_sliderNavigation = 'https://www.bafin.de/DE/hidden_node.html?view=slidernavigation';
18var hideSecondLevelPrimary = false;
19
20var cms = cms || {};
21
22cms.jsComponents = {
23    config: {},
24    definitions: {
25        bundle_animate_number: {
26            scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_animate_number.js?v=1' ]
27        },
28        bundle_datatables: {
29            scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_datatables.js?v=1' ]
30        },
31        bundle_multimedia: {
32            scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_multimedia.js?v=1' ]
33        },
34        bundle_echarts: {
35            scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_echarts.js?v=1' ]
36        },
37        bundle_slideshow: {
38            scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_slideshow.js?v=1' ]
39        },
40    }
41};
42    /* Start jquery */
43        /*!
44 * jQuery JavaScript Library v3.7.1
45 * https://jquery.com/
46 *
47 * Copyright OpenJS Foundation and other contributors
48 * Released under the MIT license
49 * https://jquery.org/license
50 *
51 * Date: 2023-08-28T13:37Z
52 */"use strict";
53(function (global, factory) {
54
55  "use strict";
56
57  if (typeof module === "object" && typeof module.exports === "object") {
58
59    // For CommonJS and CommonJS-like environments where a proper `window`
60    // is present, execute the factory and get jQuery.
61    // For environments that do not have a `window` with a `document`
62    // (such as Node.js), expose a factory as module.exports.
63    // This accentuates the need for the creation of a real `window`.
64    // e.g. var jQuery = require("jquery")(window);
65    // See ticket trac-14549 for more info.
66    module.exports = global.document ?
67    factory(global, true) :
68    function (w) {
69      if (!w.document) {
70        throw new Error("jQuery requires a window with a document");
71      }
72      return factory(w);
73    };
74  } else {
75    factory(global);
76  }
77
78  // Pass this if window is not defined yet
79})(typeof window !== "undefined" ? window : void 0, function (window, noGlobal) {
80
81  // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
82  // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
83  // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
84  // enough that all such attempts are guarded in a try block.
85  "use strict";
86
87  var arr = [];
88
89  var getProto = Object.getPrototypeOf;
90
91  var slice = arr.slice;
92
93  var flat = arr.flat ? function (array) {
94    return arr.flat.call(array);
95  } : function (array) {
96    return arr.concat.apply([], array);
97  };
98
99
100  var push = arr.push;
101
102  var indexOf = arr.indexOf;
103
104  var class2type = {};
105
106  var toString = class2type.toString;
107
108  var hasOwn = class2type.hasOwnProperty;
109
110  var fnToString = hasOwn.toString;
111
112  var ObjectFunctionString = fnToString.call(Object);
113
114  var support = {};
115
116  var isFunction = function isFunction(obj) {
117
118    // Support: Chrome <=57, Firefox <=52
119    // In some browsers, typeof returns "function" for HTML <object> elements
120    // (i.e., `typeof document.createElement( "object" ) === "function"`).
121    // We don't want to classify *any* DOM node as a function.
vendor: 63,123 bytes, lines 122-2131
122    // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
123    // Plus for old WebKit, typeof returns "function" for HTML collections
124    // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
125    return typeof obj === "function" && typeof obj.nodeType !== "number" &&
126    typeof obj.item !== "function";
127  };
128
129
130  var isWindow = function isWindow(obj) {
131    return obj != null && obj === obj.window;
132  };
133
134
135  var document = window.document;
136
137
138
139  var preservedScriptAttributes = {
140    type: true,
141    src: true,
142    nonce: true,
143    noModule: true
144  };
145
146  function DOMEval(code, node, doc) {
147    doc = doc || document;
148
149    var i,val,
150      script = doc.createElement("script");
151
152    script.text = code;
153    if (node) {
154      for (i in preservedScriptAttributes) {
155
156        // Support: Firefox 64+, Edge 18+
157        // Some browsers don't support the "nonce" property on scripts.
158        // On the other hand, just using `getAttribute` is not enough as
159        // the `nonce` attribute is reset to an empty string whenever it
160        // becomes browsing-context connected.
161        // See https://github.com/whatwg/html/issues/2369
162        // See https://html.spec.whatwg.org/#nonce-attributes
163        // The `node.getAttribute` check was added for the sake of
164        // `jQuery.globalEval` so that it can fake a nonce-containing node
165        // via an object.
166        val = node[i] || node.getAttribute && node.getAttribute(i);
167        if (val) {
168          script.setAttribute(i, val);
169        }
170      }
171    }
172    doc.head.appendChild(script).parentNode.removeChild(script);
173  }
174
175
176  function toType(obj) {
177    if (obj == null) {
178      return obj + "";
179    }
180
181    // Support: Android <=2.3 only (functionish RegExp)
182    return typeof obj === "object" || typeof obj === "function" ?
183    class2type[toString.call(obj)] || "object" :
184    typeof obj;
185  }
186  /* global Symbol */
187  // Defining this global in .eslintrc.json would create a danger of using the global
188  // unguarded in another place, it seems safer to define global only for this module
189
190
191
192  var version = "3.7.1",
193
194    rhtmlSuffix = /HTML$/i,
195
196    // Define a local copy of jQuery
197    jQuery = function (selector, context) {
198
199      // The jQuery object is actually just the init constructor 'enhanced'
200      // Need init if jQuery is called (just allow error to be thrown if not included)
201      return new jQuery.fn.init(selector, context);
202    };
203
204  jQuery.fn = jQuery.prototype = {
205
206    // The current version of jQuery being used
207    jquery: version,
208
209    constructor: jQuery,
210
211    // The default length of a jQuery object is 0
212    length: 0,
213
214    toArray: function () {
215      return slice.call(this);
216    },
217
218    // Get the Nth element in the matched element set OR
219    // Get the whole matched element set as a clean array
220    get: function (num) {
221
222      // Return all the elements in a clean array
223      if (num == null) {
224        return slice.call(this);
225      }
226
227      // Return just the one element from the set
228      return num < 0 ? this[num + this.length] : this[num];
229    },
230
231    // Take an array of elements and push it onto the stack
232    // (returning the new matched element set)
233    pushStack: function (elems) {
234
235      // Build a new jQuery matched element set
236      var ret = jQuery.merge(this.constructor(), elems);
237
238      // Add the old object onto the stack (as a reference)
239      ret.prevObject = this;
240
241      // Return the newly-formed element set
242      return ret;
243    },
244
245    // Execute a callback for every element in the matched set.
246    each: function (callback) {
247      return jQuery.each(this, callback);
248    },
249
250    map: function (callback) {
251      return this.pushStack(jQuery.map(this, function (elem, i) {
252        return callback.call(elem, i, elem);
253      }));
254    },
255
256    slice: function () {
257      return this.pushStack(slice.apply(this, arguments));
258    },
259
260    first: function () {
261      return this.eq(0);
262    },
263
264    last: function () {
265      return this.eq(-1);
266    },
267
268    even: function () {
269      return this.pushStack(jQuery.grep(this, function (_elem, i) {
270        return (i + 1) % 2;
271      }));
272    },
273
274    odd: function () {
275      return this.pushStack(jQuery.grep(this, function (_elem, i) {
276        return i % 2;
277      }));
278    },
279
280    eq: function (i) {
281      var len = this.length,
282        j = +i + (i < 0 ? len : 0);
283      return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
284    },
285
286    end: function () {
287      return this.prevObject || this.constructor();
288    },
289
290    // For internal use only.
291    // Behaves like an Array's method, not like a jQuery method.
292    push: push,
293    sort: arr.sort,
294    splice: arr.splice
295  };
296
297  jQuery.extend = jQuery.fn.extend = function () {
298    var options,name,src,copy,copyIsArray,clone,
299      target = arguments[0] || {},
300      i = 1,
301      length = arguments.length,
302      deep = false;
303
304    // Handle a deep copy situation
305    if (typeof target === "boolean") {
306      deep = target;
307
308      // Skip the boolean and the target
309      target = arguments[i] || {};
310      i++;
311    }
312
313    // Handle case when target is a string or something (possible in deep copy)
314    if (typeof target !== "object" && !isFunction(target)) {
315      target = {};
316    }
317
318    // Extend jQuery itself if only one argument is passed
319    if (i === length) {
320      target = this;
321      i--;
322    }
323
324    for (; i < length; i++) {
325
326      // Only deal with non-null/undefined values
327      if ((options = arguments[i]) != null) {
328
329        // Extend the base object
330        for (name in options) {
331          copy = options[name];
332
333          // Prevent Object.prototype pollution
334          // Prevent never-ending loop
335          if (name === "__proto__" || target === copy) {
336            continue;
337          }
338
339          // Recurse if we're merging plain objects or arrays
340          if (deep && copy && (jQuery.isPlainObject(copy) || (
341          copyIsArray = Array.isArray(copy)))) {
342            src = target[name];
343
344            // Ensure proper type for the source value
345            if (copyIsArray && !Array.isArray(src)) {
346              clone = [];
347            } else if (!copyIsArray && !jQuery.isPlainObject(src)) {
348              clone = {};
349            } else {
350              clone = src;
351            }
352            copyIsArray = false;
353
354            // Never move original objects, clone them
355            target[name] = jQuery.extend(deep, clone, copy);
356
357            // Don't bring in undefined values
358          } else if (copy !== undefined) {
359            target[name] = copy;
360          }
361        }
362      }
363    }
364
365    // Return the modified object
366    return target;
367  };
368
369  jQuery.extend({
370
371    // Unique for each copy of jQuery on the page
372    expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
373
374    // Assume jQuery is ready without the ready module
375    isReady: true,
376
377    error: function (msg) {
378      throw new Error(msg);
379    },
380
381    noop: function () {},
382
383    isPlainObject: function (obj) {
384      var proto, Ctor;
385
386      // Detect obvious negatives
387      // Use toString instead of jQuery.type to catch host objects
388      if (!obj || toString.call(obj) !== "[object Object]") {
389        return false;
390      }
391
392      proto = getProto(obj);
393
394      // Objects with no prototype (e.g., `Object.create( null )`) are plain
395      if (!proto) {
396        return true;
397      }
398
399      // Objects with prototype are plain iff they were constructed by a global Object function
400      Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
401      return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
402    },
403
404    isEmptyObject: function (obj) {
405      var name;
406
407      for (name in obj) {
408        return false;
409      }
410      return true;
411    },
412
413    // Evaluates a script in a provided context; falls back to the global one
414    // if not specified.
415    globalEval: function (code, options, doc) {
416      DOMEval(code, { nonce: options && options.nonce }, doc);
417    },
418
419    each: function (obj, callback) {
420      var length,i = 0;
421
422      if (isArrayLike(obj)) {
423        length = obj.length;
424        for (; i < length; i++) {
425          if (callback.call(obj[i], i, obj[i]) === false) {
426            break;
427          }
428        }
429      } else {
430        for (i in obj) {
431          if (callback.call(obj[i], i, obj[i]) === false) {
432            break;
433          }
434        }
435      }
436
437      return obj;
438    },
439
440
441    // Retrieve the text value of an array of DOM nodes
442    text: function (elem) {
443      var node,
444        ret = "",
445        i = 0,
446        nodeType = elem.nodeType;
447
448      if (!nodeType) {
449
450        // If no nodeType, this is expected to be an array
451        while (node = elem[i++]) {
452
453          // Do not traverse comment nodes
454          ret += jQuery.text(node);
455        }
456      }
457      if (nodeType === 1 || nodeType === 11) {
458        return elem.textContent;
459      }
460      if (nodeType === 9) {
461        return elem.documentElement.textContent;
462      }
463      if (nodeType === 3 || nodeType === 4) {
464        return elem.nodeValue;
465      }
466
467      // Do not include comment or processing instruction nodes
468
469      return ret;
470    },
471
472    // results is for internal usage only
473    makeArray: function (arr, results) {
474      var ret = results || [];
475
476      if (arr != null) {
477        if (isArrayLike(Object(arr))) {
478          jQuery.merge(ret,
479          typeof arr === "string" ?
480          [arr] : arr
481          );
482        } else {
483          push.call(ret, arr);
484        }
485      }
486
487      return ret;
488    },
489
490    inArray: function (elem, arr, i) {
491      return arr == null ? -1 : indexOf.call(arr, elem, i);
492    },
493
494    isXMLDoc: function (elem) {
495      var namespace = elem && elem.namespaceURI,
496        docElem = elem && (elem.ownerDocument || elem).documentElement;
497
498      // Assume HTML when documentElement doesn't yet exist, such as inside
499      // document fragments.
500      return !rhtmlSuffix.test(namespace || docElem && docElem.nodeName || "HTML");
501    },
502
503    // Support: Android <=4.0 only, PhantomJS 1 only
504    // push.apply(_, arraylike) throws on ancient WebKit
505    merge: function (first, second) {
506      var len = +second.length,
507        j = 0,
508        i = first.length;
509
510      for (; j < len; j++) {
511        first[i++] = second[j];
512      }
513
514      first.length = i;
515
516      return first;
517    },
518
519    grep: function (elems, callback, invert) {
520      var callbackInverse,
521        matches = [],
522        i = 0,
523        length = elems.length,
524        callbackExpect = !invert;
525
526      // Go through the array, only saving the items
527      // that pass the validator function
528      for (; i < length; i++) {
529        callbackInverse = !callback(elems[i], i);
530        if (callbackInverse !== callbackExpect) {
531          matches.push(elems[i]);
532        }
533      }
534
535      return matches;
536    },
537
538    // arg is for internal usage only
539    map: function (elems, callback, arg) {
540      var length,value,
541        i = 0,
542        ret = [];
543
544      // Go through the array, translating each of the items to their new values
545      if (isArrayLike(elems)) {
546        length = elems.length;
547        for (; i < length; i++) {
548          value = callback(elems[i], i, arg);
549
550          if (value != null) {
551            ret.push(value);
552          }
553        }
554
555        // Go through every key on the object,
556      } else {
557        for (i in elems) {
558          value = callback(elems[i], i, arg);
559
560          if (value != null) {
561            ret.push(value);
562          }
563        }
564      }
565
566      // Flatten any nested arrays
567      return flat(ret);
568    },
569
570    // A global GUID counter for objects
571    guid: 1,
572
573    // jQuery.support is not used in Core but other projects attach their
574    // properties to it so it needs to exist.
575    support: support
576  });
577
578  if (typeof Symbol === "function") {
579    jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
580  }
581
582  // Populate the class2type map
583  jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),
584  function (_i, name) {
585    class2type["[object " + name + "]"] = name.toLowerCase();
586  });
587
588  function isArrayLike(obj) {
589
590    // Support: real iOS 8.2 only (not reproducible in simulator)
591    // `in` check used to prevent JIT error (gh-2145)
592    // hasOwn isn't used here due to false negatives
593    // regarding Nodelist length in IE
594    var length = !!obj && "length" in obj && obj.length,
595      type = toType(obj);
596
597    if (isFunction(obj) || isWindow(obj)) {
598      return false;
599    }
600
601    return type === "array" || length === 0 ||
602    typeof length === "number" && length > 0 && length - 1 in obj;
603  }
604
605
606  function nodeName(elem, name) {
607
608    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
609
610  }
611  var pop = arr.pop;
612
613
614  var sort = arr.sort;
615
616
617  var splice = arr.splice;
618
619
620  var whitespace = "[\\x20\\t\\r\\n\\f]";
621
622
623  var rtrimCSS = new RegExp(
624    "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
625    "g"
626  );
627
628
629
630
631  // Note: an element does not contain itself
632  jQuery.contains = function (a, b) {
633    var bup = b && b.parentNode;
634
635    return a === bup || !!(bup && bup.nodeType === 1 && (
636
637    // Support: IE 9 - 11+
638    // IE doesn't have `contains` on SVG.
639    a.contains ?
640    a.contains(bup) :
641    a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
642
643  };
644
645
646
647
648  // CSS string/identifier serialization
649  // https://drafts.csswg.org/cssom/#common-serializing-idioms
650  var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
651
652  function fcssescape(ch, asCodePoint) {
653    if (asCodePoint) {
654
655      // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
656      if (ch === "\0") {
657        return "\uFFFD";
658      }
659
660      // Control characters and (dependent upon position) numbers get escaped as code points
661      return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
662    }
663
664    // Other potentially-special ASCII characters get backslash-escaped
665    return "\\" + ch;
666  }
667
668  jQuery.escapeSelector = function (sel) {
669    return (sel + "").replace(rcssescape, fcssescape);
670  };
671
672
673
674
675  var preferredDoc = document,
676    pushNative = push;
677
678  (function () {
679
680    var i,
681      Expr,
682      outermostContext,
683      sortInput,
684      hasDuplicate,
685      push = pushNative,
686
687      // Local document vars
688      document,
689      documentElement,
690      documentIsHTML,
691      rbuggyQSA,
692      matches,
693
694      // Instance-specific data
695      expando = jQuery.expando,
696      dirruns = 0,
697      done = 0,
698      classCache = createCache(),
699      tokenCache = createCache(),
700      compilerCache = createCache(),
701      nonnativeSelectorCache = createCache(),
702      sortOrder = function (a, b) {
703        if (a === b) {
704          hasDuplicate = true;
705        }
706        return 0;
707      },
708
709      booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" +
710      "loop|multiple|open|readonly|required|scoped",
711
712      // Regular expressions
713
714      // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
715      identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
716      "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
717
718      // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors
719      attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
720
721      // Operator (capture 2)
722      "*([*^$|!~]?=)" + whitespace +
723
724      // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
725      "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
726      whitespace + "*\\]",
727
728      pseudos = ":(" + identifier + ")(?:\\((" +
729
730      // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
731      // 1. quoted (capture 3; capture 4 or capture 5)
732      "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
733
734      // 2. simple (capture 6)
735      "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
736
737      // 3. anything else (capture 2)
738      ".*" +
739      ")\\)|)",
740
741      // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
742      rwhitespace = new RegExp(whitespace + "+", "g"),
743
744      rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
745      rleadingCombinator = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" +
746      whitespace + "*"),
747      rdescend = new RegExp(whitespace + "|>"),
748
749      rpseudo = new RegExp(pseudos),
750      ridentifier = new RegExp("^" + identifier + "$"),
751
752      matchExpr = {
753        ID: new RegExp("^#(" + identifier + ")"),
754        CLASS: new RegExp("^\\.(" + identifier + ")"),
755        TAG: new RegExp("^(" + identifier + "|[*])"),
756        ATTR: new RegExp("^" + attributes),
757        PSEUDO: new RegExp("^" + pseudos),
758        CHILD: new RegExp(
759          "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
760          whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
761          whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
762        bool: new RegExp("^(?:" + booleans + ")$", "i"),
763
764        // For use in libraries implementing .is()
765        // We use this for POS matching in `select`
766        needsContext: new RegExp("^" + whitespace +
767        "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
768        "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
769      },
770
771      rinputs = /^(?:input|select|textarea|button)$/i,
772      rheader = /^h\d$/i,
773
774      // Easily-parseable/retrievable ID or TAG or CLASS selectors
775      rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
776
777      rsibling = /[+~]/,
778
779      // CSS escapes
780      // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
781      runescape = new RegExp("\\\\[\\da-fA-F]{1,6}" + whitespace +
782      "?|\\\\([^\\r\\n\\f])", "g"),
783      funescape = function (escape, nonHex) {
784        var high = "0x" + escape.slice(1) - 0x10000;
785
786        if (nonHex) {
787
788          // Strip the backslash prefix from a non-hex escape sequence
789          return nonHex;
790        }
791
792        // Replace a hexadecimal escape sequence with the encoded Unicode code point
793        // Support: IE <=11+
794        // For values outside the Basic Multilingual Plane (BMP), manually construct a
795        // surrogate pair
796        return high < 0 ?
797        String.fromCharCode(high + 0x10000) :
798        String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
799      },
800
801      // Used for iframes; see `setDocument`.
802      // Support: IE 9 - 11+, Edge 12 - 18+
803      // Removing the function wrapper causes a "Permission Denied"
804      // error in IE/Edge.
805      unloadHandler = function () {
806        setDocument();
807      },
808
809      inDisabledFieldset = addCombinator(
810        function (elem) {
811          return elem.disabled === true && nodeName(elem, "fieldset");
812        },
813        { dir: "parentNode", next: "legend" }
814      );
815
816    // Support: IE <=9 only
817    // Accessing document.activeElement can throw unexpectedly
818    // https://bugs.jquery.com/ticket/13393
819    function safeActiveElement() {
820      try {
821        return document.activeElement;
822      } catch (err) {}
823    }
824
825    // Optimize for push.apply( _, NodeList )
826    try {
827      push.apply(
828        arr = slice.call(preferredDoc.childNodes),
829        preferredDoc.childNodes
830      );
831
832      // Support: Android <=4.0
833      // Detect silently failing push.apply
834      // eslint-disable-next-line no-unused-expressions
835      arr[preferredDoc.childNodes.length].nodeType;
836    } catch (e) {
837      push = {
838        apply: function (target, els) {
839          pushNative.apply(target, slice.call(els));
840        },
841        call: function (target) {
842          pushNative.apply(target, slice.call(arguments, 1));
843        }
844      };
845    }
846
847    function find(selector, context, results, seed) {
848      var m,i,elem,nid,match,groups,newSelector,
849        newContext = context && context.ownerDocument,
850
851        // nodeType defaults to 9, since context defaults to document
852        nodeType = context ? context.nodeType : 9;
853
854      results = results || [];
855
856      // Return early from calls with invalid selector or context
857      if (typeof selector !== "string" || !selector ||
858      nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
859
860        return results;
861      }
862
863      // Try to shortcut find operations (as opposed to filters) in HTML documents
864      if (!seed) {
865        setDocument(context);
866        context = context || document;
867
868        if (documentIsHTML) {
869
870          // If the selector is sufficiently simple, try using a "get*By*" DOM method
871          // (excepting DocumentFragment context, where the methods don't exist)
872          if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
873
874            // ID selector
875            if (m = match[1]) {
876
877              // Document context
878              if (nodeType === 9) {
879                if (elem = context.getElementById(m)) {
880
881                  // Support: IE 9 only
882                  // getElementById can match elements by name instead of ID
883                  if (elem.id === m) {
884                    push.call(results, elem);
885                    return results;
886                  }
887                } else {
888                  return results;
889                }
890
891                // Element context
892              } else {
893
894                // Support: IE 9 only
895                // getElementById can match elements by name instead of ID
896                if (newContext && (elem = newContext.getElementById(m)) &&
897                find.contains(context, elem) &&
898                elem.id === m) {
899
900                  push.call(results, elem);
901                  return results;
902                }
903              }
904
905              // Type selector
906            } else if (match[2]) {
907              push.apply(results, context.getElementsByTagName(selector));
908              return results;
909
910              // Class selector
911            } else if ((m = match[3]) && context.getElementsByClassName) {
912              push.apply(results, context.getElementsByClassName(m));
913              return results;
914            }
915          }
916
917          // Take advantage of querySelectorAll
918          if (!nonnativeSelectorCache[selector + " "] && (
919          !rbuggyQSA || !rbuggyQSA.test(selector))) {
920
921            newSelector = selector;
922            newContext = context;
923
924            // qSA considers elements outside a scoping root when evaluating child or
925            // descendant combinators, which is not what we want.
926            // In such cases, we work around the behavior by prefixing every selector in the
927            // list with an ID selector referencing the scope context.
928            // The technique has to be used as well when a leading combinator is used
929            // as such selectors are not recognized by querySelectorAll.
930            // Thanks to Andrew Dupont for this technique.
931            if (nodeType === 1 && (
932            rdescend.test(selector) || rleadingCombinator.test(selector))) {
933
934              // Expand context for sibling selectors
935              newContext = rsibling.test(selector) && testContext(context.parentNode) ||
936              context;
937
938              // We can use :scope instead of the ID hack if the browser
939              // supports it & if we're not changing the context.
940              // Support: IE 11+, Edge 17 - 18+
941              // IE/Edge sometimes throw a "Permission denied" error when
942              // strict-comparing two documents; shallow comparisons work.
943              // eslint-disable-next-line eqeqeq
944              if (newContext != context || !support.scope) {
945
946                // Capture the context ID, setting it first if necessary
947                if (nid = context.getAttribute("id")) {
948                  nid = jQuery.escapeSelector(nid);
949                } else {
950                  context.setAttribute("id", nid = expando);
951                }
952              }
953
954              // Prefix every selector in the list
955              groups = tokenize(selector);
956              i = groups.length;
957              while (i--) {
958                groups[i] = (nid ? "#" + nid : ":scope") + " " +
959                toSelector(groups[i]);
960              }
961              newSelector = groups.join(",");
962            }
963
964            try {
965              push.apply(results,
966              newContext.querySelectorAll(newSelector)
967              );
968              return results;
969            } catch (qsaError) {
970              nonnativeSelectorCache(selector, true);
971            } finally {
972              if (nid === expando) {
973                context.removeAttribute("id");
974              }
975            }
976          }
977        }
978      }
979
980      // All others
981      return select(selector.replace(rtrimCSS, "$1"), context, results, seed);
982    }
983
984    /**
985     * Create key-value caches of limited size
986     * @returns {function(string, object)} Returns the Object data after storing it on itself with
987     *  property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
988     *  deleting the oldest entry
989     */
990    function createCache() {
991      var keys = [];
992
993      function cache(key, value) {
994
995        // Use (key + " ") to avoid collision with native prototype properties
996        // (see https://github.com/jquery/sizzle/issues/157)
997        if (keys.push(key + " ") > Expr.cacheLength) {
998
999          // Only keep the most recent entries
1000          delete cache[keys.shift()];
1001        }
1002        return cache[key + " "] = value;
1003      }
1004      return cache;
1005    }
1006
1007    /**
1008     * Mark a function for special use by jQuery selector module
1009     * @param {Function} fn The function to mark
1010     */
1011    function markFunction(fn) {
1012      fn[expando] = true;
1013      return fn;
1014    }
1015
1016    /**
1017     * Support testing using an element
1018     * @param {Function} fn Passed the created element and returns a boolean result
1019     */
1020    function assert(fn) {
1021      var el = document.createElement("fieldset");
1022
1023      try {
1024        return !!fn(el);
1025      } catch (e) {
1026        return false;
1027      } finally {
1028
1029        // Remove from its parent by default
1030        if (el.parentNode) {
1031          el.parentNode.removeChild(el);
1032        }
1033
1034        // release memory in IE
1035        el = null;
1036      }
1037    }
1038
1039    /**
1040     * Returns a function to use in pseudos for input types
1041     * @param {String} type
1042     */
1043    function createInputPseudo(type) {
1044      return function (elem) {
1045        return nodeName(elem, "input") && elem.type === type;
1046      };
1047    }
1048
1049    /**
1050     * Returns a function to use in pseudos for buttons
1051     * @param {String} type
1052     */
1053    function createButtonPseudo(type) {
1054      return function (elem) {
1055        return (nodeName(elem, "input") || nodeName(elem, "button")) &&
1056        elem.type === type;
1057      };
1058    }
1059
1060    /**
1061     * Returns a function to use in pseudos for :enabled/:disabled
1062     * @param {Boolean} disabled true for :disabled; false for :enabled
1063     */
1064    function createDisabledPseudo(disabled) {
1065
1066      // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1067      return function (elem) {
1068
1069        // Only certain elements can match :enabled or :disabled
1070        // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1071        // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1072        if ("form" in elem) {
1073
1074          // Check for inherited disabledness on relevant non-disabled elements:
1075          // * listed form-associated elements in a disabled fieldset
1076          //   https://html.spec.whatwg.org/multipage/forms.html#category-listed
1077          //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1078          // * option elements in a disabled optgroup
1079          //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1080          // All such elements have a "form" property.
1081          if (elem.parentNode && elem.disabled === false) {
1082
1083            // Option elements defer to a parent optgroup if present
1084            if ("label" in elem) {
1085              if ("label" in elem.parentNode) {
1086                return elem.parentNode.disabled === disabled;
1087              } else {
1088                return elem.disabled === disabled;
1089              }
1090            }
1091
1092            // Support: IE 6 - 11+
1093            // Use the isDisabled shortcut property to check for disabled fieldset ancestors
1094            return elem.isDisabled === disabled ||
1095
1096            // Where there is no isDisabled, check manually
1097            elem.isDisabled !== !disabled &&
1098            inDisabledFieldset(elem) === disabled;
1099          }
1100
1101          return elem.disabled === disabled;
1102
1103          // Try to winnow out elements that can't be disabled before trusting the disabled property.
1104          // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1105          // even exist on them, let alone have a boolean value.
1106        } else if ("label" in elem) {
1107          return elem.disabled === disabled;
1108        }
1109
1110        // Remaining elements are neither :enabled nor :disabled
1111        return false;
1112      };
1113    }
1114
1115    /**
1116     * Returns a function to use in pseudos for positionals
1117     * @param {Function} fn
1118     */
1119    function createPositionalPseudo(fn) {
1120      return markFunction(function (argument) {
1121        argument = +argument;
1122        return markFunction(function (seed, matches) {
1123          var j,
1124            matchIndexes = fn([], seed.length, argument),
1125            i = matchIndexes.length;
1126
1127          // Match elements found at the specified indexes
1128          while (i--) {
1129            if (seed[j = matchIndexes[i]]) {
1130              seed[j] = !(matches[j] = seed[j]);
1131            }
1132          }
1133        });
1134      });
1135    }
1136
1137    /**
1138     * Checks a node for validity as a jQuery selector context
1139     * @param {Element|Object=} context
1140     * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1141     */
1142    function testContext(context) {
1143      return context && typeof context.getElementsByTagName !== "undefined" && context;
1144    }
1145
1146    /**
1147     * Sets document-related variables once based on the current document
1148     * @param {Element|Object} [node] An element or document object to use to set the document
1149     * @returns {Object} Returns the current document
1150     */
1151    function setDocument(node) {
1152      var subWindow,
1153        doc = node ? node.ownerDocument || node : preferredDoc;
1154
1155      // Return early if doc is invalid or already selected
1156      // Support: IE 11+, Edge 17 - 18+
1157      // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1158      // two documents; shallow comparisons work.
1159      // eslint-disable-next-line eqeqeq
1160      if (doc == document || doc.nodeType !== 9 || !doc.documentElement) {
1161        return document;
1162      }
1163
1164      // Update global variables
1165      document = doc;
1166      documentElement = document.documentElement;
1167      documentIsHTML = !jQuery.isXMLDoc(document);
1168
1169      // Support: iOS 7 only, IE 9 - 11+
1170      // Older browsers didn't support unprefixed `matches`.
1171      matches = documentElement.matches ||
1172      documentElement.webkitMatchesSelector ||
1173      documentElement.msMatchesSelector;
1174
1175      // Support: IE 9 - 11+, Edge 12 - 18+
1176      // Accessing iframe documents after unload throws "permission denied" errors
1177      // (see trac-13936).
1178      // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,
1179      // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.
1180      if (documentElement.msMatchesSelector &&
1181
1182      // Support: IE 11+, Edge 17 - 18+
1183      // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1184      // two documents; shallow comparisons work.
1185      // eslint-disable-next-line eqeqeq
1186      preferredDoc != document && (
1187      subWindow = document.defaultView) && subWindow.top !== subWindow) {
1188
1189        // Support: IE 9 - 11+, Edge 12 - 18+
1190        subWindow.addEventListener("unload", unloadHandler);
1191      }
1192
1193      // Support: IE <10
1194      // Check if getElementById returns elements by name
1195      // The broken getElementById methods don't pick up programmatically-set names,
1196      // so use a roundabout getElementsByName test
1197      support.getById = assert(function (el) {
1198        documentElement.appendChild(el).id = jQuery.expando;
1199        return !document.getElementsByName ||
1200        !document.getElementsByName(jQuery.expando).length;
1201      });
1202
1203      // Support: IE 9 only
1204      // Check to see if it's possible to do matchesSelector
1205      // on a disconnected node.
1206      support.disconnectedMatch = assert(function (el) {
1207        return matches.call(el, "*");
1208      });
1209
1210      // Support: IE 9 - 11+, Edge 12 - 18+
1211      // IE/Edge don't support the :scope pseudo-class.
1212      support.scope = assert(function () {
1213        return document.querySelectorAll(":scope");
1214      });
1215
1216      // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only
1217      // Make sure the `:has()` argument is parsed unforgivingly.
1218      // We include `*` in the test to detect buggy implementations that are
1219      // _selectively_ forgiving (specifically when the list includes at least
1220      // one valid selector).
1221      // Note that we treat complete lack of support for `:has()` as if it were
1222      // spec-compliant support, which is fine because use of `:has()` in such
1223      // environments will fail in the qSA path and fall back to jQuery traversal
1224      // anyway.
1225      support.cssHas = assert(function () {
1226        try {
1227          document.querySelector(":has(*,:jqfake)");
1228          return false;
1229        } catch (e) {
1230          return true;
1231        }
1232      });
1233
1234      // ID filter and find
1235      if (support.getById) {
1236        Expr.filter.ID = function (id) {
1237          var attrId = id.replace(runescape, funescape);
1238          return function (elem) {
1239            return elem.getAttribute("id") === attrId;
1240          };
1241        };
1242        Expr.find.ID = function (id, context) {
1243          if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1244            var elem = context.getElementById(id);
1245            return elem ? [elem] : [];
1246          }
1247        };
1248      } else {
1249        Expr.filter.ID = function (id) {
1250          var attrId = id.replace(runescape, funescape);
1251          return function (elem) {
1252            var node = typeof elem.getAttributeNode !== "undefined" &&
1253            elem.getAttributeNode("id");
1254            return node && node.value === attrId;
1255          };
1256        };
1257
1258        // Support: IE 6 - 7 only
1259        // getElementById is not reliable as a find shortcut
1260        Expr.find.ID = function (id, context) {
1261          if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1262            var node,i,elems,
1263              elem = context.getElementById(id);
1264
1265            if (elem) {
1266
1267              // Verify the id attribute
1268              node = elem.getAttributeNode("id");
1269              if (node && node.value === id) {
1270                return [elem];
1271              }
1272
1273              // Fall back on getElementsByName
1274              elems = context.getElementsByName(id);
1275              i = 0;
1276              while (elem = elems[i++]) {
1277                node = elem.getAttributeNode("id");
1278                if (node && node.value === id) {
1279                  return [elem];
1280                }
1281              }
1282            }
1283
1284            return [];
1285          }
1286        };
1287      }
1288
1289      // Tag
1290      Expr.find.TAG = function (tag, context) {
1291        if (typeof context.getElementsByTagName !== "undefined") {
1292          return context.getElementsByTagName(tag);
1293
1294          // DocumentFragment nodes don't have gEBTN
1295        } else {
1296          return context.querySelectorAll(tag);
1297        }
1298      };
1299
1300      // Class
1301      Expr.find.CLASS = function (className, context) {
1302        if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
1303          return context.getElementsByClassName(className);
1304        }
1305      };
1306
1307      /* QSA/matchesSelector
1308      ---------------------------------------------------------------------- */
1309
1310      // QSA and matchesSelector support
1311
1312      rbuggyQSA = [];
1313
1314      // Build QSA regex
1315      // Regex strategy adopted from Diego Perini
1316      assert(function (el) {
1317
1318        var input;
1319
1320        documentElement.appendChild(el).innerHTML =
1321        "<a id='" + expando + "' href='' disabled='disabled'></a>" +
1322        "<select id='" + expando + "-\r\\' disabled='disabled'>" +
1323        "<option selected=''></option></select>";
1324
1325        // Support: iOS <=7 - 8 only
1326        // Boolean attributes and "value" are not treated correctly in some XML documents
1327        if (!el.querySelectorAll("[selected]").length) {
1328          rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
1329        }
1330
1331        // Support: iOS <=7 - 8 only
1332        if (!el.querySelectorAll("[id~=" + expando + "-]").length) {
1333          rbuggyQSA.push("~=");
1334        }
1335
1336        // Support: iOS 8 only
1337        // https://bugs.webkit.org/show_bug.cgi?id=136851
1338        // In-page `selector#id sibling-combinator selector` fails
1339        if (!el.querySelectorAll("a#" + expando + "+*").length) {
1340          rbuggyQSA.push(".#.+[+~]");
1341        }
1342
1343        // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
1344        // In some of the document kinds, these selectors wouldn't work natively.
1345        // This is probably OK but for backwards compatibility we want to maintain
1346        // handling them through jQuery traversal in jQuery 3.x.
1347        if (!el.querySelectorAll(":checked").length) {
1348          rbuggyQSA.push(":checked");
1349        }
1350
1351        // Support: Windows 8 Native Apps
1352        // The type and name attributes are restricted during .innerHTML assignment
1353        input = document.createElement("input");
1354        input.setAttribute("type", "hidden");
1355        el.appendChild(input).setAttribute("name", "D");
1356
1357        // Support: IE 9 - 11+
1358        // IE's :disabled selector does not pick up the children of disabled fieldsets
1359        // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
1360        // In some of the document kinds, these selectors wouldn't work natively.
1361        // This is probably OK but for backwards compatibility we want to maintain
1362        // handling them through jQuery traversal in jQuery 3.x.
1363        documentElement.appendChild(el).disabled = true;
1364        if (el.querySelectorAll(":disabled").length !== 2) {
1365          rbuggyQSA.push(":enabled", ":disabled");
1366        }
1367
1368        // Support: IE 11+, Edge 15 - 18+
1369        // IE 11/Edge don't find elements on a `[name='']` query in some cases.
1370        // Adding a temporary attribute to the document before the selection works
1371        // around the issue.
1372        // Interestingly, IE 10 & older don't seem to have the issue.
1373        input = document.createElement("input");
1374        input.setAttribute("name", "");
1375        el.appendChild(input);
1376        if (!el.querySelectorAll("[name='']").length) {
1377          rbuggyQSA.push("\\[" + whitespace + "*name" + whitespace + "*=" +
1378          whitespace + "*(?:''|\"\")");
1379        }
1380      });
1381
1382      if (!support.cssHas) {
1383
1384        // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
1385        // Our regular `try-catch` mechanism fails to detect natively-unsupported
1386        // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`)
1387        // in browsers that parse the `:has()` argument as a forgiving selector list.
1388        // https://drafts.csswg.org/selectors/#relational now requires the argument
1389        // to be parsed unforgivingly, but browsers have not yet fully adjusted.
1390        rbuggyQSA.push(":has");
1391      }
1392
1393      rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
1394
1395      /* Sorting
1396      ---------------------------------------------------------------------- */
1397
1398      // Document order sorting
1399      sortOrder = function (a, b) {
1400
1401        // Flag for duplicate removal
1402        if (a === b) {
1403          hasDuplicate = true;
1404          return 0;
1405        }
1406
1407        // Sort on method existence if only one input has compareDocumentPosition
1408        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1409        if (compare) {
1410          return compare;
1411        }
1412
1413        // Calculate position if both inputs belong to the same document
1414        // Support: IE 11+, Edge 17 - 18+
1415        // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1416        // two documents; shallow comparisons work.
1417        // eslint-disable-next-line eqeqeq
1418        compare = (a.ownerDocument || a) == (b.ownerDocument || b) ?
1419        a.compareDocumentPosition(b) :
1420
1421        // Otherwise we know they are disconnected
1422        1;
1423
1424        // Disconnected nodes
1425        if (compare & 1 ||
1426        !support.sortDetached && b.compareDocumentPosition(a) === compare) {
1427
1428          // Choose the first element that is related to our preferred document
1429          // Support: IE 11+, Edge 17 - 18+
1430          // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1431          // two documents; shallow comparisons work.
1432          // eslint-disable-next-line eqeqeq
1433          if (a === document || a.ownerDocument == preferredDoc &&
1434          find.contains(preferredDoc, a)) {
1435            return -1;
1436          }
1437
1438          // Support: IE 11+, Edge 17 - 18+
1439          // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1440          // two documents; shallow comparisons work.
1441          // eslint-disable-next-line eqeqeq
1442          if (b === document || b.ownerDocument == preferredDoc &&
1443          find.contains(preferredDoc, b)) {
1444            return 1;
1445          }
1446
1447          // Maintain original order
1448          return sortInput ?
1449          indexOf.call(sortInput, a) - indexOf.call(sortInput, b) :
1450          0;
1451        }
1452
1453        return compare & 4 ? -1 : 1;
1454      };
1455
1456      return document;
1457    }
1458
1459    find.matches = function (expr, elements) {
1460      return find(expr, null, null, elements);
1461    };
1462
1463    find.matchesSelector = function (elem, expr) {
1464      setDocument(elem);
1465
1466      if (documentIsHTML &&
1467      !nonnativeSelectorCache[expr + " "] && (
1468      !rbuggyQSA || !rbuggyQSA.test(expr))) {
1469
1470        try {
1471          var ret = matches.call(elem, expr);
1472
1473          // IE 9's matchesSelector returns false on disconnected nodes
1474          if (ret || support.disconnectedMatch ||
1475
1476          // As well, disconnected nodes are said to be in a document
1477          // fragment in IE 9
1478          elem.document && elem.document.nodeType !== 11) {
1479            return ret;
1480          }
1481        } catch (e) {
1482          nonnativeSelectorCache(expr, true);
1483        }
1484      }
1485
1486      return find(expr, document, null, [elem]).length > 0;
1487    };
1488
1489    find.contains = function (context, elem) {
1490
1491      // Set document vars if needed
1492      // Support: IE 11+, Edge 17 - 18+
1493      // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1494      // two documents; shallow comparisons work.
1495      // eslint-disable-next-line eqeqeq
1496      if ((context.ownerDocument || context) != document) {
1497        setDocument(context);
1498      }
1499      return jQuery.contains(context, elem);
1500    };
1501
1502
1503    find.attr = function (elem, name) {
1504
1505      // Set document vars if needed
1506      // Support: IE 11+, Edge 17 - 18+
1507      // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1508      // two documents; shallow comparisons work.
1509      // eslint-disable-next-line eqeqeq
1510      if ((elem.ownerDocument || elem) != document) {
1511        setDocument(elem);
1512      }
1513
1514      var fn = Expr.attrHandle[name.toLowerCase()],
1515
1516        // Don't get fooled by Object.prototype properties (see trac-13807)
1517        val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ?
1518        fn(elem, name, !documentIsHTML) :
1519        undefined;
1520
1521      if (val !== undefined) {
1522        return val;
1523      }
1524
1525      return elem.getAttribute(name);
1526    };
1527
1528    find.error = function (msg) {
1529      throw new Error("Syntax error, unrecognized expression: " + msg);
1530    };
1531
1532    /**
1533     * Document sorting and removing duplicates
1534     * @param {ArrayLike} results
1535     */
1536    jQuery.uniqueSort = function (results) {
1537      var elem,
1538        duplicates = [],
1539        j = 0,
1540        i = 0;
1541
1542      // Unless we *know* we can detect duplicates, assume their presence
1543      //
1544      // Support: Android <=4.0+
1545      // Testing for detecting duplicates is unpredictable so instead assume we can't
1546      // depend on duplicate detection in all browsers without a stable sort.
1547      hasDuplicate = !support.sortStable;
1548      sortInput = !support.sortStable && slice.call(results, 0);
1549      sort.call(results, sortOrder);
1550
1551      if (hasDuplicate) {
1552        while (elem = results[i++]) {
1553          if (elem === results[i]) {
1554            j = duplicates.push(i);
1555          }
1556        }
1557        while (j--) {
1558          splice.call(results, duplicates[j], 1);
1559        }
1560      }
1561
1562      // Clear input after sorting to release objects
1563      // See https://github.com/jquery/sizzle/pull/225
1564      sortInput = null;
1565
1566      return results;
1567    };
1568
1569    jQuery.fn.uniqueSort = function () {
1570      return this.pushStack(jQuery.uniqueSort(slice.apply(this)));
1571    };
1572
1573    Expr = jQuery.expr = {
1574
1575      // Can be adjusted by the user
1576      cacheLength: 50,
1577
1578      createPseudo: markFunction,
1579
1580      match: matchExpr,
1581
1582      attrHandle: {},
1583
1584      find: {},
1585
1586      relative: {
1587        ">": { dir: "parentNode", first: true },
1588        " ": { dir: "parentNode" },
1589        "+": { dir: "previousSibling", first: true },
1590        "~": { dir: "previousSibling" }
1591      },
1592
1593      preFilter: {
1594        ATTR: function (match) {
1595          match[1] = match[1].replace(runescape, funescape);
1596
1597          // Move the given value to match[3] whether quoted or unquoted
1598          match[3] = (match[3] || match[4] || match[5] || "").
1599          replace(runescape, funescape);
1600
1601          if (match[2] === "~=") {
1602            match[3] = " " + match[3] + " ";
1603          }
1604
1605          return match.slice(0, 4);
1606        },
1607
1608        CHILD: function (match) {
1609
1610          /* matches from matchExpr["CHILD"]
1611            1 type (only|nth|...)
1612            2 what (child|of-type)
1613            3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1614            4 xn-component of xn+y argument ([+-]?\d*n|)
1615            5 sign of xn-component
1616            6 x of xn-component
1617            7 sign of y-component
1618            8 y of y-component
1619          */
1620          match[1] = match[1].toLowerCase();
1621
1622          if (match[1].slice(0, 3) === "nth") {
1623
1624            // nth-* requires argument
1625            if (!match[3]) {
1626              find.error(match[0]);
1627            }
1628
1629            // numeric x and y parameters for Expr.filter.CHILD
1630            // remember that false/true cast respectively to 0/1
1631            match[4] = +(match[4] ?
1632            match[5] + (match[6] || 1) :
1633            2 * (match[3] === "even" || match[3] === "odd"));
1634
1635            match[5] = +(match[7] + match[8] || match[3] === "odd");
1636
1637            // other types prohibit arguments
1638          } else if (match[3]) {
1639            find.error(match[0]);
1640          }
1641
1642          return match;
1643        },
1644
1645        PSEUDO: function (match) {
1646          var excess,
1647            unquoted = !match[6] && match[2];
1648
1649          if (matchExpr.CHILD.test(match[0])) {
1650            return null;
1651          }
1652
1653          // Accept quoted arguments as-is
1654          if (match[3]) {
1655            match[2] = match[4] || match[5] || "";
1656
1657            // Strip excess characters from unquoted arguments
1658          } else if (unquoted && rpseudo.test(unquoted) && (
1659
1660          // Get excess from tokenize (recursively)
1661          excess = tokenize(unquoted, true)) && (
1662
1663          // advance to the next closing parenthesis
1664          excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
1665
1666            // excess is a negative index
1667            match[0] = match[0].slice(0, excess);
1668            match[2] = unquoted.slice(0, excess);
1669          }
1670
1671          // Return only captures needed by the pseudo filter method (type and argument)
1672          return match.slice(0, 3);
1673        }
1674      },
1675
1676      filter: {
1677
1678        TAG: function (nodeNameSelector) {
1679          var expectedNodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
1680          return nodeNameSelector === "*" ?
1681          function () {
1682            return true;
1683          } :
1684          function (elem) {
1685            return nodeName(elem, expectedNodeName);
1686          };
1687        },
1688
1689        CLASS: function (className) {
1690          var pattern = classCache[className + " "];
1691
1692          return pattern ||
1693          (pattern = new RegExp("(^|" + whitespace + ")" + className +
1694          "(" + whitespace + "|$)")) &&
1695          classCache(className, function (elem) {
1696            return pattern.test(
1697              typeof elem.className === "string" && elem.className ||
1698              typeof elem.getAttribute !== "undefined" &&
1699              elem.getAttribute("class") ||
1700              ""
1701            );
1702          });
1703        },
1704
1705        ATTR: function (name, operator, check) {
1706          return function (elem) {
1707            var result = find.attr(elem, name);
1708
1709            if (result == null) {
1710              return operator === "!=";
1711            }
1712            if (!operator) {
1713              return true;
1714            }
1715
1716            result += "";
1717
1718            if (operator === "=") {
1719              return result === check;
1720            }
1721            if (operator === "!=") {
1722              return result !== check;
1723            }
1724            if (operator === "^=") {
1725              return check && result.indexOf(check) === 0;
1726            }
1727            if (operator === "*=") {
1728              return check && result.indexOf(check) > -1;
1729            }
1730            if (operator === "$=") {
1731              return check && result.slice(-check.length) === check;
1732            }
1733            if (operator === "~=") {
1734              return (" " + result.replace(rwhitespace, " ") + " ").
1735              indexOf(check) > -1;
1736            }
1737            if (operator === "|=") {
1738              return result === check || result.slice(0, check.length + 1) === check + "-";
1739            }
1740
1741            return false;
1742          };
1743        },
1744
1745        CHILD: function (type, what, _argument, first, last) {
1746          var simple = type.slice(0, 3) !== "nth",
1747            forward = type.slice(-4) !== "last",
1748            ofType = what === "of-type";
1749
1750          return first === 1 && last === 0 ?
1751
1752          // Shortcut for :nth-*(n)
1753          function (elem) {
1754            return !!elem.parentNode;
1755          } :
1756
1757          function (elem, _context, xml) {
1758            var cache,outerCache,node,nodeIndex,start,
1759              dir = simple !== forward ? "nextSibling" : "previousSibling",
1760              parent = elem.parentNode,
1761              name = ofType && elem.nodeName.toLowerCase(),
1762              useCache = !xml && !ofType,
1763              diff = false;
1764
1765            if (parent) {
1766
1767              // :(first|last|only)-(child|of-type)
1768              if (simple) {
1769                while (dir) {
1770                  node = elem;
1771                  while (node = node[dir]) {
1772                    if (ofType ?
1773                    nodeName(node, name) :
1774                    node.nodeType === 1) {
1775
1776                      return false;
1777                    }
1778                  }
1779
1780                  // Reverse direction for :only-* (if we haven't yet done so)
1781                  start = dir = type === "only" && !start && "nextSibling";
1782                }
1783                return true;
1784              }
1785
1786              start = [forward ? parent.firstChild : parent.lastChild];
1787
1788              // non-xml :nth-child(...) stores cache data on `parent`
1789              if (forward && useCache) {
1790
1791                // Seek `elem` from a previously-cached index
1792                outerCache = parent[expando] || (parent[expando] = {});
1793                cache = outerCache[type] || [];
1794                nodeIndex = cache[0] === dirruns && cache[1];
1795                diff = nodeIndex && cache[2];
1796                node = nodeIndex && parent.childNodes[nodeIndex];
1797
1798                while (node = ++nodeIndex && node && node[dir] || (
1799
1800                // Fallback to seeking `elem` from the start
1801                diff = nodeIndex = 0) || start.pop()) {
1802
1803                  // When found, cache indexes on `parent` and break
1804                  if (node.nodeType === 1 && ++diff && node === elem) {
1805                    outerCache[type] = [dirruns, nodeIndex, diff];
1806                    break;
1807                  }
1808                }
1809
1810              } else {
1811
1812                // Use previously-cached element index if available
1813                if (useCache) {
1814                  outerCache = elem[expando] || (elem[expando] = {});
1815                  cache = outerCache[type] || [];
1816                  nodeIndex = cache[0] === dirruns && cache[1];
1817                  diff = nodeIndex;
1818                }
1819
1820                // xml :nth-child(...)
1821                // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1822                if (diff === false) {
1823
1824                  // Use the same loop as above to seek `elem` from the start
1825                  while (node = ++nodeIndex && node && node[dir] || (
1826                  diff = nodeIndex = 0) || start.pop()) {
1827
1828                    if ((ofType ?
1829                    nodeName(node, name) :
1830                    node.nodeType === 1) &&
1831                    ++diff) {
1832
1833                      // Cache the index of each encountered element
1834                      if (useCache) {
1835                        outerCache = node[expando] || (
1836                        node[expando] = {});
1837                        outerCache[type] = [dirruns, diff];
1838                      }
1839
1840                      if (node === elem) {
1841                        break;
1842                      }
1843                    }
1844                  }
1845                }
1846              }
1847
1848              // Incorporate the offset, then check against cycle size
1849              diff -= last;
1850              return diff === first || diff % first === 0 && diff / first >= 0;
1851            }
1852          };
1853        },
1854
1855        PSEUDO: function (pseudo, argument) {
1856
1857          // pseudo-class names are case-insensitive
1858          // https://www.w3.org/TR/selectors/#pseudo-classes
1859          // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1860          // Remember that setFilters inherits from pseudos
1861          var args,
1862            fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] ||
1863            find.error("unsupported pseudo: " + pseudo);
1864
1865          // The user may use createPseudo to indicate that
1866          // arguments are needed to create the filter function
1867          // just as jQuery does
1868          if (fn[expando]) {
1869            return fn(argument);
1870          }
1871
1872          // But maintain support for old signatures
1873          if (fn.length > 1) {
1874            args = [pseudo, pseudo, "", argument];
1875            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ?
1876            markFunction(function (seed, matches) {
1877              var idx,
1878                matched = fn(seed, argument),
1879                i = matched.length;
1880              while (i--) {
1881                idx = indexOf.call(seed, matched[i]);
1882                seed[idx] = !(matches[idx] = matched[i]);
1883              }
1884            }) :
1885            function (elem) {
1886              return fn(elem, 0, args);
1887            };
1888          }
1889
1890          return fn;
1891        }
1892      },
1893
1894      pseudos: {
1895
1896        // Potentially complex pseudos
1897        not: markFunction(function (selector) {
1898
1899          // Trim the selector passed to compile
1900          // to avoid treating leading and trailing
1901          // spaces as combinators
1902          var input = [],
1903            results = [],
1904            matcher = compile(selector.replace(rtrimCSS, "$1"));
1905
1906          return matcher[expando] ?
1907          markFunction(function (seed, matches, _context, xml) {
1908            var elem,
1909              unmatched = matcher(seed, null, xml, []),
1910              i = seed.length;
1911
1912            // Match elements unmatched by `matcher`
1913            while (i--) {
1914              if (elem = unmatched[i]) {
1915                seed[i] = !(matches[i] = elem);
1916              }
1917            }
1918          }) :
1919          function (elem, _context, xml) {
1920            input[0] = elem;
1921            matcher(input, null, xml, results);
1922
1923            // Don't keep the element
1924            // (see https://github.com/jquery/sizzle/issues/299)
1925            input[0] = null;
1926            return !results.pop();
1927          };
1928        }),
1929
1930        has: markFunction(function (selector) {
1931          return function (elem) {
1932            return find(selector, elem).length > 0;
1933          };
1934        }),
1935
1936        contains: markFunction(function (text) {
1937          text = text.replace(runescape, funescape);
1938          return function (elem) {
1939            return (elem.textContent || jQuery.text(elem)).indexOf(text) > -1;
1940          };
1941        }),
1942
1943        // "Whether an element is represented by a :lang() selector
1944        // is based solely on the element's language value
1945        // being equal to the identifier C,
1946        // or beginning with the identifier C immediately followed by "-".
1947        // The matching of C against the element's language value is performed case-insensitively.
1948        // The identifier C does not have to be a valid language name."
1949        // https://www.w3.org/TR/selectors/#lang-pseudo
1950        lang: markFunction(function (lang) {
1951
1952          // lang value must be a valid identifier
1953          if (!ridentifier.test(lang || "")) {
1954            find.error("unsupported lang: " + lang);
1955          }
1956          lang = lang.replace(runescape, funescape).toLowerCase();
1957          return function (elem) {
1958            var elemLang;
1959            do {
1960              if (elemLang = documentIsHTML ?
1961              elem.lang :
1962              elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
1963
1964                elemLang = elemLang.toLowerCase();
1965                return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
1966              }
1967            } while ((elem = elem.parentNode) && elem.nodeType === 1);
1968            return false;
1969          };
1970        }),
1971
1972        // Miscellaneous
1973        target: function (elem) {
1974          var hash = window.location && window.location.hash;
1975          return hash && hash.slice(1) === elem.id;
1976        },
1977
1978        root: function (elem) {
1979          return elem === documentElement;
1980        },
1981
1982        focus: function (elem) {
1983          return elem === safeActiveElement() &&
1984          document.hasFocus() &&
1985          !!(elem.type || elem.href || ~elem.tabIndex);
1986        },
1987
1988        // Boolean properties
1989        enabled: createDisabledPseudo(false),
1990        disabled: createDisabledPseudo(true),
1991
1992        checked: function (elem) {
1993
1994          // In CSS3, :checked should return both checked and selected elements
1995          // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1996          return nodeName(elem, "input") && !!elem.checked ||
1997          nodeName(elem, "option") && !!elem.selected;
1998        },
1999
2000        selected: function (elem) {
2001
2002          // Support: IE <=11+
2003          // Accessing the selectedIndex property
2004          // forces the browser to treat the default option as
2005          // selected when in an optgroup.
2006          if (elem.parentNode) {
2007            // eslint-disable-next-line no-unused-expressions
2008            elem.parentNode.selectedIndex;
2009          }
2010
2011          return elem.selected === true;
2012        },
2013
2014        // Contents
2015        empty: function (elem) {
2016
2017          // https://www.w3.org/TR/selectors/#empty-pseudo
2018          // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2019          //   but not by others (comment: 8; processing instruction: 7; etc.)
2020          // nodeType < 6 works because attributes (2) do not appear as children
2021          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
2022            if (elem.nodeType < 6) {
2023              return false;
2024            }
2025          }
2026          return true;
2027        },
2028
2029        parent: function (elem) {
2030          return !Expr.pseudos.empty(elem);
2031        },
2032
2033        // Element/input types
2034        header: function (elem) {
2035          return rheader.test(elem.nodeName);
2036        },
2037
2038        input: function (elem) {
2039          return rinputs.test(elem.nodeName);
2040        },
2041
2042        button: function (elem) {
2043          return nodeName(elem, "input") && elem.type === "button" ||
2044          nodeName(elem, "button");
2045        },
2046
2047        text: function (elem) {
2048          var attr;
2049          return nodeName(elem, "input") && elem.type === "text" && (
2050
2051          // Support: IE <10 only
2052          // New HTML5 attribute values (e.g., "search") appear
2053          // with elem.type === "text"
2054          (attr = elem.getAttribute("type")) == null ||
2055          attr.toLowerCase() === "text");
2056        },
2057
2058        // Position-in-collection
2059        first: createPositionalPseudo(function () {
2060          return [0];
2061        }),
2062
2063        last: createPositionalPseudo(function (_matchIndexes, length) {
2064          return [length - 1];
2065        }),
2066
2067        eq: createPositionalPseudo(function (_matchIndexes, length, argument) {
2068          return [argument < 0 ? argument + length : argument];
2069        }),
2070
2071        even: createPositionalPseudo(function (matchIndexes, length) {
2072          var i = 0;
2073          for (; i < length; i += 2) {
2074            matchIndexes.push(i);
2075          }
2076          return matchIndexes;
2077        }),
2078
2079        odd: createPositionalPseudo(function (matchIndexes, length) {
2080          var i = 1;
2081          for (; i < length; i += 2) {
2082            matchIndexes.push(i);
2083          }
2084          return matchIndexes;
2085        }),
2086
2087        lt: createPositionalPseudo(function (matchIndexes, length, argument) {
2088          var i;
2089
2090          if (argument < 0) {
2091            i = argument + length;
2092          } else if (argument > length) {
2093            i = length;
2094          } else {
2095            i = argument;
2096          }
2097
2098          for (; --i >= 0;) {
2099            matchIndexes.push(i);
2100          }
2101          return matchIndexes;
2102        }),
2103
2104        gt: createPositionalPseudo(function (matchIndexes, length, argument) {
2105          var i = argument < 0 ? argument + length : argument;
2106          for (; ++i < length;) {
2107            matchIndexes.push(i);
2108          }
2109          return matchIndexes;
2110        })
2111      }
2112    };
2113
2114    Expr.pseudos.nth = Expr.pseudos.eq;
2115
2116    // Add button/input type pseudos
2117    for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) {
2118      Expr.pseudos[i] = createInputPseudo(i);
2119    }
2120    for (i in { submit: true, reset: true }) {
2121      Expr.pseudos[i] = createButtonPseudo(i);
2122    }
2123
2124    // Easy API for creating new setFilters
2125    function setFilters() {}
2126    setFilters.prototype = Expr.filters = Expr.pseudos;
2127    Expr.setFilters = new setFilters();
2128
2129    function tokenize(selector, parseOnly) {
2130      var matched,match,tokens,type,
2131        soFar,groups,preFilters,
2132        cached = tokenCache[selector + " "];
2133
2134      if (cached) {
2135        return parseOnly ? 0 : cached.slice(0);
2136      }
2137
2138      soFar = selector;
2139      groups = [];
2140      preFilters = Expr.preFilter;
2141
2142      while (soFar) {
2143
2144        // Comma and first run
2145        if (!matched || (match = rcomma.exec(soFar))) {
2146          if (match) {
2147
2148            // Don't consume trailing commas as valid
2149            soFar = soFar.slice(match[0].length) || soFar;
2150          }
2151          groups.push(tokens = []);
2152        }
2153
2154        matched = false;
2155
2156        // Combinators
2157        if (match = rleadingCombinator.exec(soFar)) {
2158          matched = match.shift();
2159          tokens.push({
2160            value: matched,
2161
2162            // Cast descendant combinators to space
2163            type: match[0].replace(rtrimCSS, " ")
2164          });
2165          soFar = soFar.slice(matched.length);
2166        }
2167
2168        // Filters
2169        for (type in Expr.filter) {
2170          if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (
2171          match = preFilters[type](match)))) {
2172            matched = match.shift();
2173            tokens.push({
2174              value: matched,
2175              type: type,
2176              matches: match
2177            });
2178            soFar = soFar.slice(matched.length);
2179          }
2180        }
2181
2182        if (!matched) {
2183          break;
2184        }
2185      }
2186
2187      // Return the length of the invalid excess
2188      // if we're just parsing
2189      // Otherwise, throw an error or return tokens
2190      if (parseOnly) {
2191        return soFar.length;
2192      }
2193
2194      return soFar ?
2195      find.error(selector) :
2196
2197      // Cache the tokens
2198      tokenCache(selector, groups).slice(0);
2199    }
2200
2201    function toSelector(tokens) {
2202      var i = 0,
2203        len = tokens.length,
2204        selector = "";
2205      for (; i < len; i++) {
2206        selector += tokens[i].value;
2207      }
2208      return selector;
2209    }
2210
2211    function addCombinator(matcher, combinator, base) {
2212      var dir = combinator.dir,
2213        skip = combinator.next,
2214        key = skip || dir,
2215        checkNonElements = base && key === "parentNode",
2216        doneName = done++;
2217
2218      return combinator.first ?
2219
2220      // Check against closest ancestor/preceding element
2221      function (elem, context, xml) {
2222        while (elem = elem[dir]) {
2223          if (elem.nodeType === 1 || checkNonElements) {
2224            return matcher(elem, context, xml);
2225          }
2226        }
2227        return false;
2228      } :
2229
2230      // Check against all ancestor/preceding elements
2231      function (elem, context, xml) {
2232        var oldCache,outerCache,
2233          newCache = [dirruns, doneName];
2234
2235        // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2236        if (xml) {
2237          while (elem = elem[dir]) {
2238            if (elem.nodeType === 1 || checkNonElements) {
2239              if (matcher(elem, context, xml)) {
2240                return true;
2241              }
2242            }
2243          }
2244        } else {
2245          while (elem = elem[dir]) {
2246            if (elem.nodeType === 1 || checkNonElements) {
2247              outerCache = elem[expando] || (elem[expando] = {});
2248
2249              if (skip && nodeName(elem, skip)) {
2250                elem = elem[dir] || elem;
2251              } else if ((oldCache = outerCache[key]) &&
2252              oldCache[0] === dirruns && oldCache[1] === doneName) {
2253
2254                // Assign to newCache so results back-propagate to previous elements
2255                return newCache[2] = oldCache[2];
2256              } else {
2257
2258                // Reuse newcache so results back-propagate to previous elements
2259                outerCache[key] = newCache;
2260
2261                // A match means we're done; a fail means we have to keep checking
2262                if (newCache[2] = matcher(elem, context, xml)) {
2263                  return true;
2264                }
2265              }
2266            }
2267          }
2268        }
2269        return false;
2270      };
2271    }
2272
2273    function elementMatcher(matchers) {
2274      return matchers.length > 1 ?
2275      function (elem, context, xml) {
2276        var i = matchers.length;
2277        while (i--) {
2278          if (!matchers[i](elem, context, xml)) {
2279            return false;
vendor: 4,211 bytes, lines 2280-2420
2280          }
2281        }
2282        return true;
2283      } :
2284      matchers[0];
2285    }
2286
2287    function multipleContexts(selector, contexts, results) {
2288      var i = 0,
2289        len = contexts.length;
2290      for (; i < len; i++) {
2291        find(selector, contexts[i], results);
2292      }
2293      return results;
2294    }
2295
2296    function condense(unmatched, map, filter, context, xml) {
2297      var elem,
2298        newUnmatched = [],
2299        i = 0,
2300        len = unmatched.length,
2301        mapped = map != null;
2302
2303      for (; i < len; i++) {
2304        if (elem = unmatched[i]) {
2305          if (!filter || filter(elem, context, xml)) {
2306            newUnmatched.push(elem);
2307            if (mapped) {
2308              map.push(i);
2309            }
2310          }
2311        }
2312      }
2313
2314      return newUnmatched;
2315    }
2316
2317    function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
2318      if (postFilter && !postFilter[expando]) {
2319        postFilter = setMatcher(postFilter);
2320      }
2321      if (postFinder && !postFinder[expando]) {
2322        postFinder = setMatcher(postFinder, postSelector);
2323      }
2324      return markFunction(function (seed, results, context, xml) {
2325        var temp,i,elem,matcherOut,
2326          preMap = [],
2327          postMap = [],
2328          preexisting = results.length,
2329
2330          // Get initial elements from seed or context
2331          elems = seed ||
2332          multipleContexts(selector || "*",
2333          context.nodeType ? [context] : context, []),
2334
2335          // Prefilter to get matcher input, preserving a map for seed-results synchronization
2336          matcherIn = preFilter && (seed || !selector) ?
2337          condense(elems, preMap, preFilter, context, xml) :
2338          elems;
2339
2340        if (matcher) {
2341
2342          // If we have a postFinder, or filtered seed, or non-seed postFilter
2343          // or preexisting results,
2344          matcherOut = postFinder || (seed ? preFilter : preexisting || postFilter) ?
2345
2346          // ...intermediate processing is necessary
2347          [] :
2348
2349          // ...otherwise use results directly
2350          results;
2351
2352          // Find primary matches
2353          matcher(matcherIn, matcherOut, context, xml);
2354        } else {
2355          matcherOut = matcherIn;
2356        }
2357
2358        // Apply postFilter
2359        if (postFilter) {
2360          temp = condense(matcherOut, postMap);
2361          postFilter(temp, [], context, xml);
2362
2363          // Un-match failing elements by moving them back to matcherIn
2364          i = temp.length;
2365          while (i--) {
2366            if (elem = temp[i]) {
2367              matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
2368            }
2369          }
2370        }
2371
2372        if (seed) {
2373          if (postFinder || preFilter) {
2374            if (postFinder) {
2375
2376              // Get the final matcherOut by condensing this intermediate into postFinder contexts
2377              temp = [];
2378              i = matcherOut.length;
2379              while (i--) {
2380                if (elem = matcherOut[i]) {
2381
2382                  // Restore matcherIn since elem is not yet a final match
2383                  temp.push(matcherIn[i] = elem);
2384                }
2385              }
2386              postFinder(null, matcherOut = [], temp, xml);
2387            }
2388
2389            // Move matched elements from seed to results to keep them synchronized
2390            i = matcherOut.length;
2391            while (i--) {
2392              if ((elem = matcherOut[i]) &&
2393              (temp = postFinder ? indexOf.call(seed, elem) : preMap[i]) > -1) {
2394
2395                seed[temp] = !(results[temp] = elem);
2396              }
2397            }
2398          }
2399
2400          // Add elements to results, through postFinder if defined
2401        } else {
2402          matcherOut = condense(
2403            matcherOut === results ?
2404            matcherOut.splice(preexisting, matcherOut.length) :
2405            matcherOut
2406          );
2407          if (postFinder) {
2408            postFinder(null, results, matcherOut, xml);
2409          } else {
2410            push.apply(results, matcherOut);
2411          }
2412        }
2413      });
2414    }
2415
2416    function matcherFromTokens(tokens) {
2417      var checkContext,matcher,j,
2418        len = tokens.length,
2419        leadingRelative = Expr.relative[tokens[0].type],
2420        implicitRelative = leadingRelative || Expr.relative[" "],
vendor: 9,994 bytes, lines 2421-2696
2421        i = leadingRelative ? 1 : 0,
2422
2423        // The foundational matcher ensures that elements are reachable from top-level context(s)
2424        matchContext = addCombinator(function (elem) {
2425          return elem === checkContext;
2426        }, implicitRelative, true),
2427        matchAnyContext = addCombinator(function (elem) {
2428          return indexOf.call(checkContext, elem) > -1;
2429        }, implicitRelative, true),
2430        matchers = [function (elem, context, xml) {
2431
2432          // Support: IE 11+, Edge 17 - 18+
2433          // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2434          // two documents; shallow comparisons work.
2435          // eslint-disable-next-line eqeqeq
2436          var ret = !leadingRelative && (xml || context != outermostContext) || (
2437          (checkContext = context).nodeType ?
2438          matchContext(elem, context, xml) :
2439          matchAnyContext(elem, context, xml));
2440
2441          // Avoid hanging onto element
2442          // (see https://github.com/jquery/sizzle/issues/299)
2443          checkContext = null;
2444          return ret;
2445        }];
2446
2447      for (; i < len; i++) {
2448        if (matcher = Expr.relative[tokens[i].type]) {
2449          matchers = [addCombinator(elementMatcher(matchers), matcher)];
2450        } else {
2451          matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
2452
2453          // Return special upon seeing a positional matcher
2454          if (matcher[expando]) {
2455
2456            // Find the next relative operator (if any) for proper handling
2457            j = ++i;
2458            for (; j < len; j++) {
2459              if (Expr.relative[tokens[j].type]) {
2460                break;
2461              }
2462            }
2463            return setMatcher(
2464              i > 1 && elementMatcher(matchers),
2465              i > 1 && toSelector(
2466
2467                // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2468                tokens.slice(0, i - 1).
2469                concat({ value: tokens[i - 2].type === " " ? "*" : "" })
2470              ).replace(rtrimCSS, "$1"),
2471              matcher,
2472              i < j && matcherFromTokens(tokens.slice(i, j)),
2473              j < len && matcherFromTokens(tokens = tokens.slice(j)),
2474              j < len && toSelector(tokens)
2475            );
2476          }
2477          matchers.push(matcher);
2478        }
2479      }
2480
2481      return elementMatcher(matchers);
2482    }
2483
2484    function matcherFromGroupMatchers(elementMatchers, setMatchers) {
2485      var bySet = setMatchers.length > 0,
2486        byElement = elementMatchers.length > 0,
2487        superMatcher = function (seed, context, xml, results, outermost) {
2488          var elem,j,matcher,
2489            matchedCount = 0,
2490            i = "0",
2491            unmatched = seed && [],
2492            setMatched = [],
2493            contextBackup = outermostContext,
2494
2495            // We must always have either seed elements or outermost context
2496            elems = seed || byElement && Expr.find.TAG("*", outermost),
2497
2498            // Use integer dirruns iff this is the outermost matcher
2499            dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1,
2500            len = elems.length;
2501
2502          if (outermost) {
2503
2504            // Support: IE 11+, Edge 17 - 18+
2505            // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2506            // two documents; shallow comparisons work.
2507            // eslint-disable-next-line eqeqeq
2508            outermostContext = context == document || context || outermost;
2509          }
2510
2511          // Add elements passing elementMatchers directly to results
2512          // Support: iOS <=7 - 9 only
2513          // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching
2514          // elements by id. (see trac-14142)
2515          for (; i !== len && (elem = elems[i]) != null; i++) {
2516            if (byElement && elem) {
2517              j = 0;
2518
2519              // Support: IE 11+, Edge 17 - 18+
2520              // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2521              // two documents; shallow comparisons work.
2522              // eslint-disable-next-line eqeqeq
2523              if (!context && elem.ownerDocument != document) {
2524                setDocument(elem);
2525                xml = !documentIsHTML;
2526              }
2527              while (matcher = elementMatchers[j++]) {
2528                if (matcher(elem, context || document, xml)) {
2529                  push.call(results, elem);
2530                  break;
2531                }
2532              }
2533              if (outermost) {
2534                dirruns = dirrunsUnique;
2535              }
2536            }
2537
2538            // Track unmatched elements for set filters
2539            if (bySet) {
2540
2541              // They will have gone through all possible matchers
2542              if (elem = !matcher && elem) {
2543                matchedCount--;
2544              }
2545
2546              // Lengthen the array for every element, matched or not
2547              if (seed) {
2548                unmatched.push(elem);
2549              }
2550            }
2551          }
2552
2553          // `i` is now the count of elements visited above, and adding it to `matchedCount`
2554          // makes the latter nonnegative.
2555          matchedCount += i;
2556
2557          // Apply set filters to unmatched elements
2558          // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2559          // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2560          // no element matchers and no seed.
2561          // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2562          // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2563          // numerically zero.
2564          if (bySet && i !== matchedCount) {
2565            j = 0;
2566            while (matcher = setMatchers[j++]) {
2567              matcher(unmatched, setMatched, context, xml);
2568            }
2569
2570            if (seed) {
2571
2572              // Reintegrate element matches to eliminate the need for sorting
2573              if (matchedCount > 0) {
2574                while (i--) {
2575                  if (!(unmatched[i] || setMatched[i])) {
2576                    setMatched[i] = pop.call(results);
2577                  }
2578                }
2579              }
2580
2581              // Discard index placeholder values to get only actual matches
2582              setMatched = condense(setMatched);
2583            }
2584
2585            // Add matches to results
2586            push.apply(results, setMatched);
2587
2588            // Seedless set matches succeeding multiple successful matchers stipulate sorting
2589            if (outermost && !seed && setMatched.length > 0 &&
2590            matchedCount + setMatchers.length > 1) {
2591
2592              jQuery.uniqueSort(results);
2593            }
2594          }
2595
2596          // Override manipulation of globals by nested matchers
2597          if (outermost) {
2598            dirruns = dirrunsUnique;
2599            outermostContext = contextBackup;
2600          }
2601
2602          return unmatched;
2603        };
2604
2605      return bySet ?
2606      markFunction(superMatcher) :
2607      superMatcher;
2608    }
2609
2610    function compile(selector, match /* Internal Use Only */) {
2611      var i,
2612        setMatchers = [],
2613        elementMatchers = [],
2614        cached = compilerCache[selector + " "];
2615
2616      if (!cached) {
2617
2618        // Generate a function of recursive functions that can be used to check each element
2619        if (!match) {
2620          match = tokenize(selector);
2621        }
2622        i = match.length;
2623        while (i--) {
2624          cached = matcherFromTokens(match[i]);
2625          if (cached[expando]) {
2626            setMatchers.push(cached);
2627          } else {
2628            elementMatchers.push(cached);
2629          }
2630        }
2631
2632        // Cache the compiled function
2633        cached = compilerCache(selector,
2634        matcherFromGroupMatchers(elementMatchers, setMatchers));
2635
2636        // Save selector and tokenization
2637        cached.selector = selector;
2638      }
2639      return cached;
2640    }
2641
2642    /**
2643     * A low-level selection function that works with jQuery's compiled
2644     *  selector functions
2645     * @param {String|Function} selector A selector or a pre-compiled
2646     *  selector function built with jQuery selector compile
2647     * @param {Element} context
2648     * @param {Array} [results]
2649     * @param {Array} [seed] A set of elements to match against
2650     */
2651    function select(selector, context, results, seed) {
2652      var i,tokens,token,type,find,
2653        compiled = typeof selector === "function" && selector,
2654        match = !seed && tokenize(selector = compiled.selector || selector);
2655
2656      results = results || [];
2657
2658      // Try to minimize operations if there is only one selector in the list and no seed
2659      // (the latter of which guarantees us context)
2660      if (match.length === 1) {
2661
2662        // Reduce context if the leading compound selector is an ID
2663        tokens = match[0] = match[0].slice(0);
2664        if (tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2665        context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
2666
2667          context = (Expr.find.ID(
2668            token.matches[0].replace(runescape, funescape),
2669            context
2670          ) || [])[0];
2671          if (!context) {
2672            return results;
2673
2674            // Precompiled matchers will still verify ancestry, so step up a level
2675          } else if (compiled) {
2676            context = context.parentNode;
2677          }
2678
2679          selector = selector.slice(tokens.shift().value.length);
2680        }
2681
2682        // Fetch a seed set for right-to-left matching
2683        i = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
2684        while (i--) {
2685          token = tokens[i];
2686
2687          // Abort if we hit a combinator
2688          if (Expr.relative[type = token.type]) {
2689            break;
2690          }
2691          if (find = Expr.find[type]) {
2692
2693            // Search, expanding context for leading sibling combinators
2694            if (seed = find(
2695              token.matches[0].replace(runescape, funescape),
2696              rsibling.test(tokens[0].type) &&
vendor: 41,994 bytes, lines 2697-4145
2697              testContext(context.parentNode) || context
2698            )) {
2699
2700              // If seed is empty or no tokens remain, we can return early
2701              tokens.splice(i, 1);
2702              selector = seed.length && toSelector(tokens);
2703              if (!selector) {
2704                push.apply(results, seed);
2705                return results;
2706              }
2707
2708              break;
2709            }
2710          }
2711        }
2712      }
2713
2714      // Compile and execute a filtering function if one is not provided
2715      // Provide `match` to avoid retokenization if we modified the selector above
2716      (compiled || compile(selector, match))(
2717        seed,
2718        context,
2719        !documentIsHTML,
2720        results,
2721        !context || rsibling.test(selector) && testContext(context.parentNode) || context
2722      );
2723      return results;
2724    }
2725
2726    // One-time assignments
2727
2728    // Support: Android <=4.0 - 4.1+
2729    // Sort stability
2730    support.sortStable = expando.split("").sort(sortOrder).join("") === expando;
2731
2732    // Initialize against the default document
2733    setDocument();
2734
2735    // Support: Android <=4.0 - 4.1+
2736    // Detached nodes confoundingly follow *each other*
2737    support.sortDetached = assert(function (el) {
2738
2739      // Should return 1, but returns 4 (following)
2740      return el.compareDocumentPosition(document.createElement("fieldset")) & 1;
2741    });
2742
2743    jQuery.find = find;
2744
2745    // Deprecated
2746    jQuery.expr[":"] = jQuery.expr.pseudos;
2747    jQuery.unique = jQuery.uniqueSort;
2748
2749    // These have always been private, but they used to be documented as part of
2750    // Sizzle so let's maintain them for now for backwards compatibility purposes.
2751    find.compile = compile;
2752    find.select = select;
2753    find.setDocument = setDocument;
2754    find.tokenize = tokenize;
2755
2756    find.escape = jQuery.escapeSelector;
2757    find.getText = jQuery.text;
2758    find.isXML = jQuery.isXMLDoc;
2759    find.selectors = jQuery.expr;
2760    find.support = jQuery.support;
2761    find.uniqueSort = jQuery.uniqueSort;
2762
2763    /* eslint-enable */
2764
2765  })();
2766
2767
2768  var dir = function (elem, dir, until) {
2769    var matched = [],
2770      truncate = until !== undefined;
2771
2772    while ((elem = elem[dir]) && elem.nodeType !== 9) {
2773      if (elem.nodeType === 1) {
2774        if (truncate && jQuery(elem).is(until)) {
2775          break;
2776        }
2777        matched.push(elem);
2778      }
2779    }
2780    return matched;
2781  };
2782
2783
2784  var siblings = function (n, elem) {
2785    var matched = [];
2786
2787    for (; n; n = n.nextSibling) {
2788      if (n.nodeType === 1 && n !== elem) {
2789        matched.push(n);
2790      }
2791    }
2792
2793    return matched;
2794  };
2795
2796
2797  var rneedsContext = jQuery.expr.match.needsContext;
2798
2799  var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;
2800
2801
2802
2803  // Implement the identical functionality for filter and not
2804  function winnow(elements, qualifier, not) {
2805    if (isFunction(qualifier)) {
2806      return jQuery.grep(elements, function (elem, i) {
2807        return !!qualifier.call(elem, i, elem) !== not;
2808      });
2809    }
2810
2811    // Single element
2812    if (qualifier.nodeType) {
2813      return jQuery.grep(elements, function (elem) {
2814        return elem === qualifier !== not;
2815      });
2816    }
2817
2818    // Arraylike of elements (jQuery, arguments, Array)
2819    if (typeof qualifier !== "string") {
2820      return jQuery.grep(elements, function (elem) {
2821        return indexOf.call(qualifier, elem) > -1 !== not;
2822      });
2823    }
2824
2825    // Filtered directly for both simple and complex selectors
2826    return jQuery.filter(qualifier, elements, not);
2827  }
2828
2829  jQuery.filter = function (expr, elems, not) {
2830    var elem = elems[0];
2831
2832    if (not) {
2833      expr = ":not(" + expr + ")";
2834    }
2835
2836    if (elems.length === 1 && elem.nodeType === 1) {
2837      return jQuery.find.matchesSelector(elem, expr) ? [elem] : [];
2838    }
2839
2840    return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
2841      return elem.nodeType === 1;
2842    }));
2843  };
2844
2845  jQuery.fn.extend({
2846    find: function (selector) {
2847      var i,ret,
2848        len = this.length,
2849        self = this;
2850
2851      if (typeof selector !== "string") {
2852        return this.pushStack(jQuery(selector).filter(function () {
2853          for (i = 0; i < len; i++) {
2854            if (jQuery.contains(self[i], this)) {
2855              return true;
2856            }
2857          }
2858        }));
2859      }
2860
2861      ret = this.pushStack([]);
2862
2863      for (i = 0; i < len; i++) {
2864        jQuery.find(selector, self[i], ret);
2865      }
2866
2867      return len > 1 ? jQuery.uniqueSort(ret) : ret;
2868    },
2869    filter: function (selector) {
2870      return this.pushStack(winnow(this, selector || [], false));
2871    },
2872    not: function (selector) {
2873      return this.pushStack(winnow(this, selector || [], true));
2874    },
2875    is: function (selector) {
2876      return !!winnow(
2877        this,
2878
2879        // If this is a positional/relative selector, check membership in the returned set
2880        // so $("p:first").is("p:last") won't return true for a doc with two "p".
2881        typeof selector === "string" && rneedsContext.test(selector) ?
2882        jQuery(selector) :
2883        selector || [],
2884        false
2885      ).length;
2886    }
2887  });
2888
2889
2890  // Initialize a jQuery object
2891
2892
2893  // A central reference to the root jQuery(document)
2894  var rootjQuery,
2895
2896    // A simple way to check for HTML strings
2897    // Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521)
2898    // Strict HTML recognition (trac-11290: must start with <)
2899    // Shortcut simple #id case for speed
2900    rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
2901
2902    init = jQuery.fn.init = function (selector, context, root) {
2903      var match, elem;
2904
2905      // HANDLE: $(""), $(null), $(undefined), $(false)
2906      if (!selector) {
2907        return this;
2908      }
2909
2910      // Method init() accepts an alternate rootjQuery
2911      // so migrate can support jQuery.sub (gh-2101)
2912      root = root || rootjQuery;
2913
2914      // Handle HTML strings
2915      if (typeof selector === "string") {
2916        if (selector[0] === "<" &&
2917        selector[selector.length - 1] === ">" &&
2918        selector.length >= 3) {
2919
2920          // Assume that strings that start and end with <> are HTML and skip the regex check
2921          match = [null, selector, null];
2922
2923        } else {
2924          match = rquickExpr.exec(selector);
2925        }
2926
2927        // Match html or make sure no context is specified for #id
2928        if (match && (match[1] || !context)) {
2929
2930          // HANDLE: $(html) -> $(array)
2931          if (match[1]) {
2932            context = context instanceof jQuery ? context[0] : context;
2933
2934            // Option to run scripts is true for back-compat
2935            // Intentionally let the error be thrown if parseHTML is not present
2936            jQuery.merge(this, jQuery.parseHTML(
2937              match[1],
2938              context && context.nodeType ? context.ownerDocument || context : document,
2939              true
2940            ));
2941
2942            // HANDLE: $(html, props)
2943            if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
2944              for (match in context) {
2945
2946                // Properties of context are called as methods if possible
2947                if (isFunction(this[match])) {
2948                  this[match](context[match]);
2949
2950                  // ...and otherwise set as attributes
2951                } else {
2952                  this.attr(match, context[match]);
2953                }
2954              }
2955            }
2956
2957            return this;
2958
2959            // HANDLE: $(#id)
2960          } else {
2961            elem = document.getElementById(match[2]);
2962
2963            if (elem) {
2964
2965              // Inject the element directly into the jQuery object
2966              this[0] = elem;
2967              this.length = 1;
2968            }
2969            return this;
2970          }
2971
2972          // HANDLE: $(expr, $(...))
2973        } else if (!context || context.jquery) {
2974          return (context || root).find(selector);
2975
2976          // HANDLE: $(expr, context)
2977          // (which is just equivalent to: $(context).find(expr)
2978        } else {
2979          return this.constructor(context).find(selector);
2980        }
2981
2982        // HANDLE: $(DOMElement)
2983      } else if (selector.nodeType) {
2984        this[0] = selector;
2985        this.length = 1;
2986        return this;
2987
2988        // HANDLE: $(function)
2989        // Shortcut for document ready
2990      } else if (isFunction(selector)) {
2991        return root.ready !== undefined ?
2992        root.ready(selector) :
2993
2994        // Execute immediately if ready is not present
2995        selector(jQuery);
2996      }
2997
2998      return jQuery.makeArray(selector, this);
2999    };
3000
3001  // Give the init function the jQuery prototype for later instantiation
3002  init.prototype = jQuery.fn;
3003
3004  // Initialize central reference
3005  rootjQuery = jQuery(document);
3006
3007
3008  var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3009
3010    // Methods guaranteed to produce a unique set when starting from a unique set
3011    guaranteedUnique = {
3012      children: true,
3013      contents: true,
3014      next: true,
3015      prev: true
3016    };
3017
3018  jQuery.fn.extend({
3019    has: function (target) {
3020      var targets = jQuery(target, this),
3021        l = targets.length;
3022
3023      return this.filter(function () {
3024        var i = 0;
3025        for (; i < l; i++) {
3026          if (jQuery.contains(this, targets[i])) {
3027            return true;
3028          }
3029        }
3030      });
3031    },
3032
3033    closest: function (selectors, context) {
3034      var cur,
3035        i = 0,
3036        l = this.length,
3037        matched = [],
3038        targets = typeof selectors !== "string" && jQuery(selectors);
3039
3040      // Positional selectors never match, since there's no _selection_ context
3041      if (!rneedsContext.test(selectors)) {
3042        for (; i < l; i++) {
3043          for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
3044
3045            // Always skip document fragments
3046            if (cur.nodeType < 11 && (targets ?
3047            targets.index(cur) > -1 :
3048
3049            // Don't pass non-elements to jQuery#find
3050            cur.nodeType === 1 &&
3051            jQuery.find.matchesSelector(cur, selectors))) {
3052
3053              matched.push(cur);
3054              break;
3055            }
3056          }
3057        }
3058      }
3059
3060      return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
3061    },
3062
3063    // Determine the position of an element within the set
3064    index: function (elem) {
3065
3066      // No argument, return index in parent
3067      if (!elem) {
3068        return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;
3069      }
3070
3071      // Index in selector
3072      if (typeof elem === "string") {
3073        return indexOf.call(jQuery(elem), this[0]);
3074      }
3075
3076      // Locate the position of the desired element
3077      return indexOf.call(this,
3078
3079      // If it receives a jQuery object, the first element is used
3080      elem.jquery ? elem[0] : elem
3081      );
3082    },
3083
3084    add: function (selector, context) {
3085      return this.pushStack(
3086        jQuery.uniqueSort(
3087          jQuery.merge(this.get(), jQuery(selector, context))
3088        )
3089      );
3090    },
3091
3092    addBack: function (selector) {
3093      return this.add(selector == null ?
3094      this.prevObject : this.prevObject.filter(selector)
3095      );
3096    }
3097  });
3098
3099  function sibling(cur, dir) {
3100    while ((cur = cur[dir]) && cur.nodeType !== 1) {}
3101    return cur;
3102  }
3103
3104  jQuery.each({
3105    parent: function (elem) {
3106      var parent = elem.parentNode;
3107      return parent && parent.nodeType !== 11 ? parent : null;
3108    },
3109    parents: function (elem) {
3110      return dir(elem, "parentNode");
3111    },
3112    parentsUntil: function (elem, _i, until) {
3113      return dir(elem, "parentNode", until);
3114    },
3115    next: function (elem) {
3116      return sibling(elem, "nextSibling");
3117    },
3118    prev: function (elem) {
3119      return sibling(elem, "previousSibling");
3120    },
3121    nextAll: function (elem) {
3122      return dir(elem, "nextSibling");
3123    },
3124    prevAll: function (elem) {
3125      return dir(elem, "previousSibling");
3126    },
3127    nextUntil: function (elem, _i, until) {
3128      return dir(elem, "nextSibling", until);
3129    },
3130    prevUntil: function (elem, _i, until) {
3131      return dir(elem, "previousSibling", until);
3132    },
3133    siblings: function (elem) {
3134      return siblings((elem.parentNode || {}).firstChild, elem);
3135    },
3136    children: function (elem) {
3137      return siblings(elem.firstChild);
3138    },
3139    contents: function (elem) {
3140      if (elem.contentDocument != null &&
3141
3142      // Support: IE 11+
3143      // <object> elements with no `data` attribute has an object
3144      // `contentDocument` with a `null` prototype.
3145      getProto(elem.contentDocument)) {
3146
3147        return elem.contentDocument;
3148      }
3149
3150      // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3151      // Treat the template element as a regular one in browsers that
3152      // don't support it.
3153      if (nodeName(elem, "template")) {
3154        elem = elem.content || elem;
3155      }
3156
3157      return jQuery.merge([], elem.childNodes);
3158    }
3159  }, function (name, fn) {
3160    jQuery.fn[name] = function (until, selector) {
3161      var matched = jQuery.map(this, fn, until);
3162
3163      if (name.slice(-5) !== "Until") {
3164        selector = until;
3165      }
3166
3167      if (selector && typeof selector === "string") {
3168        matched = jQuery.filter(selector, matched);
3169      }
3170
3171      if (this.length > 1) {
3172
3173        // Remove duplicates
3174        if (!guaranteedUnique[name]) {
3175          jQuery.uniqueSort(matched);
3176        }
3177
3178        // Reverse order for parents* and prev-derivatives
3179        if (rparentsprev.test(name)) {
3180          matched.reverse();
3181        }
3182      }
3183
3184      return this.pushStack(matched);
3185    };
3186  });
3187  var rnothtmlwhite = /[^\x20\t\r\n\f]+/g;
3188
3189
3190
3191  // Convert String-formatted options into Object-formatted ones
3192  function createOptions(options) {
3193    var object = {};
3194    jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) {
3195      object[flag] = true;
3196    });
3197    return object;
3198  }
3199
3200  /*
3201   * Create a callback list using the following parameters:
3202   *
3203   *  options: an optional list of space-separated options that will change how
3204   *      the callback list behaves or a more traditional option object
3205   *
3206   * By default a callback list will act like an event callback list and can be
3207   * "fired" multiple times.
3208   *
3209   * Possible options:
3210   *
3211   *  once:      will ensure the callback list can only be fired once (like a Deferred)
3212   *
3213   *  memory:      will keep track of previous values and will call any callback added
3214   *          after the list has been fired right away with the latest "memorized"
3215   *          values (like a Deferred)
3216   *
3217   *  unique:      will ensure a callback can only be added once (no duplicate in the list)
3218   *
3219   *  stopOnFalse:  interrupt callings when a callback returns false
3220   *
3221   */
3222  jQuery.Callbacks = function (options) {
3223
3224    // Convert options from String-formatted to Object-formatted if needed
3225    // (we check in cache first)
3226    options = typeof options === "string" ?
3227    createOptions(options) :
3228    jQuery.extend({}, options);
3229
3230    var // Flag to know if list is currently firing
3231      firing,
3232
3233      // Last fire value for non-forgettable lists
3234      memory,
3235
3236      // Flag to know if list was already fired
3237      fired,
3238
3239      // Flag to prevent firing
3240      locked,
3241
3242      // Actual callback list
3243      list = [],
3244
3245      // Queue of execution data for repeatable lists
3246      queue = [],
3247
3248      // Index of currently firing callback (modified by add/remove as needed)
3249      firingIndex = -1,
3250
3251      // Fire callbacks
3252      fire = function () {
3253
3254        // Enforce single-firing
3255        locked = locked || options.once;
3256
3257        // Execute callbacks for all pending executions,
3258        // respecting firingIndex overrides and runtime changes
3259        fired = firing = true;
3260        for (; queue.length; firingIndex = -1) {
3261          memory = queue.shift();
3262          while (++firingIndex < list.length) {
3263
3264            // Run callback and check for early termination
3265            if (list[firingIndex].apply(memory[0], memory[1]) === false &&
3266            options.stopOnFalse) {
3267
3268              // Jump to end and forget the data so .add doesn't re-fire
3269              firingIndex = list.length;
3270              memory = false;
3271            }
3272          }
3273        }
3274
3275        // Forget the data if we're done with it
3276        if (!options.memory) {
3277          memory = false;
3278        }
3279
3280        firing = false;
3281
3282        // Clean up if we're done firing for good
3283        if (locked) {
3284
3285          // Keep an empty list if we have data for future add calls
3286          if (memory) {
3287            list = [];
3288
3289            // Otherwise, this object is spent
3290          } else {
3291            list = "";
3292          }
3293        }
3294      },
3295
3296      // Actual Callbacks object
3297      self = {
3298
3299        // Add a callback or a collection of callbacks to the list
3300        add: function () {
3301          if (list) {
3302
3303            // If we have memory from a past run, we should fire after adding
3304            if (memory && !firing) {
3305              firingIndex = list.length - 1;
3306              queue.push(memory);
3307            }
3308
3309            (function add(args) {
3310              jQuery.each(args, function (_, arg) {
3311                if (isFunction(arg)) {
3312                  if (!options.unique || !self.has(arg)) {
3313                    list.push(arg);
3314                  }
3315                } else if (arg && arg.length && toType(arg) !== "string") {
3316
3317                  // Inspect recursively
3318                  add(arg);
3319                }
3320              });
3321            })(arguments);
3322
3323            if (memory && !firing) {
3324              fire();
3325            }
3326          }
3327          return this;
3328        },
3329
3330        // Remove a callback from the list
3331        remove: function () {
3332          jQuery.each(arguments, function (_, arg) {
3333            var index;
3334            while ((index = jQuery.inArray(arg, list, index)) > -1) {
3335              list.splice(index, 1);
3336
3337              // Handle firing indexes
3338              if (index <= firingIndex) {
3339                firingIndex--;
3340              }
3341            }
3342          });
3343          return this;
3344        },
3345
3346        // Check if a given callback is in the list.
3347        // If no argument is given, return whether or not list has callbacks attached.
3348        has: function (fn) {
3349          return fn ?
3350          jQuery.inArray(fn, list) > -1 :
3351          list.length > 0;
3352        },
3353
3354        // Remove all callbacks from the list
3355        empty: function () {
3356          if (list) {
3357            list = [];
3358          }
3359          return this;
3360        },
3361
3362        // Disable .fire and .add
3363        // Abort any current/pending executions
3364        // Clear all callbacks and values
3365        disable: function () {
3366          locked = queue = [];
3367          list = memory = "";
3368          return this;
3369        },
3370        disabled: function () {
3371          return !list;
3372        },
3373
3374        // Disable .fire
3375        // Also disable .add unless we have memory (since it would have no effect)
3376        // Abort any pending executions
3377        lock: function () {
3378          locked = queue = [];
3379          if (!memory && !firing) {
3380            list = memory = "";
3381          }
3382          return this;
3383        },
3384        locked: function () {
3385          return !!locked;
3386        },
3387
3388        // Call all callbacks with the given context and arguments
3389        fireWith: function (context, args) {
3390          if (!locked) {
3391            args = args || [];
3392            args = [context, args.slice ? args.slice() : args];
3393            queue.push(args);
3394            if (!firing) {
3395              fire();
3396            }
3397          }
3398          return this;
3399        },
3400
3401        // Call all the callbacks with the given arguments
3402        fire: function () {
3403          self.fireWith(this, arguments);
3404          return this;
3405        },
3406
3407        // To know if the callbacks have already been called at least once
3408        fired: function () {
3409          return !!fired;
3410        }
3411      };
3412
3413    return self;
3414  };
3415
3416
3417  function Identity(v) {
3418    return v;
3419  }
3420  function Thrower(ex) {
3421    throw ex;
3422  }
3423
3424  function adoptValue(value, resolve, reject, noValue) {
3425    var method;
3426
3427    try {
3428
3429      // Check for promise aspect first to privilege synchronous behavior
3430      if (value && isFunction(method = value.promise)) {
3431        method.call(value).done(resolve).fail(reject);
3432
3433        // Other thenables
3434      } else if (value && isFunction(method = value.then)) {
3435        method.call(value, resolve, reject);
3436
3437        // Other non-thenables
3438      } else {
3439
3440        // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3441        // * false: [ value ].slice( 0 ) => resolve( value )
3442        // * true: [ value ].slice( 1 ) => resolve()
3443        resolve.apply(undefined, [value].slice(noValue));
3444      }
3445
3446      // For Promises/A+, convert exceptions into rejections
3447      // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3448      // Deferred#then to conditionally suppress rejection.
3449    } catch (value) {
3450
3451      // Support: Android 4.0 only
3452      // Strict mode functions invoked without .call/.apply get global-object context
3453      reject.apply(undefined, [value]);
3454    }
3455  }
3456
3457  jQuery.extend({
3458
3459    Deferred: function (func) {
3460      var tuples = [
3461
3462        // action, add listener, callbacks,
3463        // ... .then handlers, argument index, [final state]
3464        ["notify", "progress", jQuery.Callbacks("memory"),
3465        jQuery.Callbacks("memory"), 2],
3466        ["resolve", "done", jQuery.Callbacks("once memory"),
3467        jQuery.Callbacks("once memory"), 0, "resolved"],
3468        ["reject", "fail", jQuery.Callbacks("once memory"),
3469        jQuery.Callbacks("once memory"), 1, "rejected"]],
3470
3471        state = "pending",
3472        promise = {
3473          state: function () {
3474            return state;
3475          },
3476          always: function () {
3477            deferred.done(arguments).fail(arguments);
3478            return this;
3479          },
3480          "catch": function (fn) {
3481            return promise.then(null, fn);
3482          },
3483
3484          // Keep pipe for back-compat
3485          pipe: function /* fnDone, fnFail, fnProgress */ () {
3486            var fns = arguments;
3487
3488            return jQuery.Deferred(function (newDefer) {
3489              jQuery.each(tuples, function (_i, tuple) {
3490
3491                // Map tuples (progress, done, fail) to arguments (done, fail, progress)
3492                var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]];
3493
3494                // deferred.progress(function() { bind to newDefer or newDefer.notify })
3495                // deferred.done(function() { bind to newDefer or newDefer.resolve })
3496                // deferred.fail(function() { bind to newDefer or newDefer.reject })
3497                deferred[tuple[1]](function () {
3498                  var returned = fn && fn.apply(this, arguments);
3499                  if (returned && isFunction(returned.promise)) {
3500                    returned.promise().
3501                    progress(newDefer.notify).
3502                    done(newDefer.resolve).
3503                    fail(newDefer.reject);
3504                  } else {
3505                    newDefer[tuple[0] + "With"](
3506                      this,
3507                      fn ? [returned] : arguments
3508                    );
3509                  }
3510                });
3511              });
3512              fns = null;
3513            }).promise();
3514          },
3515          then: function (onFulfilled, onRejected, onProgress) {
3516            var maxDepth = 0;
3517            function resolve(depth, deferred, handler, special) {
3518              return function () {
3519                var that = this,
3520                  args = arguments,
3521                  mightThrow = function () {
3522                    var returned, then;
3523
3524                    // Support: Promises/A+ section 2.3.3.3.3
3525                    // https://promisesaplus.com/#point-59
3526                    // Ignore double-resolution attempts
3527                    if (depth < maxDepth) {
3528                      return;
3529                    }
3530
3531                    returned = handler.apply(that, args);
3532
3533                    // Support: Promises/A+ section 2.3.1
3534                    // https://promisesaplus.com/#point-48
3535                    if (returned === deferred.promise()) {
3536                      throw new TypeError("Thenable self-resolution");
3537                    }
3538
3539                    // Support: Promises/A+ sections 2.3.3.1, 3.5
3540                    // https://promisesaplus.com/#point-54
3541                    // https://promisesaplus.com/#point-75
3542                    // Retrieve `then` only once
3543                    then = returned && (
3544
3545                    // Support: Promises/A+ section 2.3.4
3546                    // https://promisesaplus.com/#point-64
3547                    // Only check objects and functions for thenability
3548                    typeof returned === "object" ||
3549                    typeof returned === "function") &&
3550                    returned.then;
3551
3552                    // Handle a returned thenable
3553                    if (isFunction(then)) {
3554
3555                      // Special processors (notify) just wait for resolution
3556                      if (special) {
3557                        then.call(
3558                          returned,
3559                          resolve(maxDepth, deferred, Identity, special),
3560                          resolve(maxDepth, deferred, Thrower, special)
3561                        );
3562
3563                        // Normal processors (resolve) also hook into progress
3564                      } else {
3565
3566                        // ...and disregard older resolution values
3567                        maxDepth++;
3568
3569                        then.call(
3570                          returned,
3571                          resolve(maxDepth, deferred, Identity, special),
3572                          resolve(maxDepth, deferred, Thrower, special),
3573                          resolve(maxDepth, deferred, Identity,
3574                          deferred.notifyWith)
3575                        );
3576                      }
3577
3578                      // Handle all other returned values
3579                    } else {
3580
3581                      // Only substitute handlers pass on context
3582                      // and multiple values (non-spec behavior)
3583                      if (handler !== Identity) {
3584                        that = undefined;
3585                        args = [returned];
3586                      }
3587
3588                      // Process the value(s)
3589                      // Default process is resolve
3590                      (special || deferred.resolveWith)(that, args);
3591                    }
3592                  },
3593
3594                  // Only normal processors (resolve) catch and reject exceptions
3595                  process = special ?
3596                  mightThrow :
3597                  function () {
3598                    try {
3599                      mightThrow();
3600                    } catch (e) {
3601
3602                      if (jQuery.Deferred.exceptionHook) {
3603                        jQuery.Deferred.exceptionHook(e,
3604                        process.error);
3605                      }
3606
3607                      // Support: Promises/A+ section 2.3.3.3.4.1
3608                      // https://promisesaplus.com/#point-61
3609                      // Ignore post-resolution exceptions
3610                      if (depth + 1 >= maxDepth) {
3611
3612                        // Only substitute handlers pass on context
3613                        // and multiple values (non-spec behavior)
3614                        if (handler !== Thrower) {
3615                          that = undefined;
3616                          args = [e];
3617                        }
3618
3619                        deferred.rejectWith(that, args);
3620                      }
3621                    }
3622                  };
3623
3624                // Support: Promises/A+ section 2.3.3.3.1
3625                // https://promisesaplus.com/#point-57
3626                // Re-resolve promises immediately to dodge false rejection from
3627                // subsequent errors
3628                if (depth) {
3629                  process();
3630                } else {
3631
3632                  // Call an optional hook to record the error, in case of exception
3633                  // since it's otherwise lost when execution goes async
3634                  if (jQuery.Deferred.getErrorHook) {
3635                    process.error = jQuery.Deferred.getErrorHook();
3636
3637                    // The deprecated alias of the above. While the name suggests
3638                    // returning the stack, not an error instance, jQuery just passes
3639                    // it directly to `console.warn` so both will work; an instance
3640                    // just better cooperates with source maps.
3641                  } else if (jQuery.Deferred.getStackHook) {
3642                    process.error = jQuery.Deferred.getStackHook();
3643                  }
3644                  window.setTimeout(process);
3645                }
3646              };
3647            }
3648
3649            return jQuery.Deferred(function (newDefer) {
3650
3651              // progress_handlers.add( ... )
3652              tuples[0][3].add(
3653                resolve(
3654                  0,
3655                  newDefer,
3656                  isFunction(onProgress) ?
3657                  onProgress :
3658                  Identity,
3659                  newDefer.notifyWith
3660                )
3661              );
3662
3663              // fulfilled_handlers.add( ... )
3664              tuples[1][3].add(
3665                resolve(
3666                  0,
3667                  newDefer,
3668                  isFunction(onFulfilled) ?
3669                  onFulfilled :
3670                  Identity
3671                )
3672              );
3673
3674              // rejected_handlers.add( ... )
3675              tuples[2][3].add(
3676                resolve(
3677                  0,
3678                  newDefer,
3679                  isFunction(onRejected) ?
3680                  onRejected :
3681                  Thrower
3682                )
3683              );
3684            }).promise();
3685          },
3686
3687          // Get a promise for this deferred
3688          // If obj is provided, the promise aspect is added to the object
3689          promise: function (obj) {
3690            return obj != null ? jQuery.extend(obj, promise) : promise;
3691          }
3692        },
3693        deferred = {};
3694
3695      // Add list-specific methods
3696      jQuery.each(tuples, function (i, tuple) {
3697        var list = tuple[2],
3698          stateString = tuple[5];
3699
3700        // promise.progress = list.add
3701        // promise.done = list.add
3702        // promise.fail = list.add
3703        promise[tuple[1]] = list.add;
3704
3705        // Handle state
3706        if (stateString) {
3707          list.add(
3708            function () {
3709
3710              // state = "resolved" (i.e., fulfilled)
3711              // state = "rejected"
3712              state = stateString;
3713            },
3714
3715            // rejected_callbacks.disable
3716            // fulfilled_callbacks.disable
3717            tuples[3 - i][2].disable,
3718
3719            // rejected_handlers.disable
3720            // fulfilled_handlers.disable
3721            tuples[3 - i][3].disable,
3722
3723            // progress_callbacks.lock
3724            tuples[0][2].lock,
3725
3726            // progress_handlers.lock
3727            tuples[0][3].lock
3728          );
3729        }
3730
3731        // progress_handlers.fire
3732        // fulfilled_handlers.fire
3733        // rejected_handlers.fire
3734        list.add(tuple[3].fire);
3735
3736        // deferred.notify = function() { deferred.notifyWith(...) }
3737        // deferred.resolve = function() { deferred.resolveWith(...) }
3738        // deferred.reject = function() { deferred.rejectWith(...) }
3739        deferred[tuple[0]] = function () {
3740          deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments);
3741          return this;
3742        };
3743
3744        // deferred.notifyWith = list.fireWith
3745        // deferred.resolveWith = list.fireWith
3746        // deferred.rejectWith = list.fireWith
3747        deferred[tuple[0] + "With"] = list.fireWith;
3748      });
3749
3750      // Make the deferred a promise
3751      promise.promise(deferred);
3752
3753      // Call given func if any
3754      if (func) {
3755        func.call(deferred, deferred);
3756      }
3757
3758      // All done!
3759      return deferred;
3760    },
3761
3762    // Deferred helper
3763    when: function (singleValue) {
3764      var
3765
3766        // count of uncompleted subordinates
3767        remaining = arguments.length,
3768
3769        // count of unprocessed arguments
3770        i = remaining,
3771
3772        // subordinate fulfillment data
3773        resolveContexts = Array(i),
3774        resolveValues = slice.call(arguments),
3775
3776        // the primary Deferred
3777        primary = jQuery.Deferred(),
3778
3779        // subordinate callback factory
3780        updateFunc = function (i) {
3781          return function (value) {
3782            resolveContexts[i] = this;
3783            resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value;
3784            if (! --remaining) {
3785              primary.resolveWith(resolveContexts, resolveValues);
3786            }
3787          };
3788        };
3789
3790      // Single- and empty arguments are adopted like Promise.resolve
3791      if (remaining <= 1) {
3792        adoptValue(singleValue, primary.done(updateFunc(i)).resolve, primary.reject,
3793        !remaining);
3794
3795        // Use .then() to unwrap secondary thenables (cf. gh-3000)
3796        if (primary.state() === "pending" ||
3797        isFunction(resolveValues[i] && resolveValues[i].then)) {
3798
3799          return primary.then();
3800        }
3801      }
3802
3803      // Multiple arguments are aggregated like Promise.all array elements
3804      while (i--) {
3805        adoptValue(resolveValues[i], updateFunc(i), primary.reject);
3806      }
3807
3808      return primary.promise();
3809    }
3810  });
3811
3812
3813  // These usually indicate a programmer mistake during development,
3814  // warn about them ASAP rather than swallowing them by default.
3815  var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
3816
3817  // If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error
3818  // captured before the async barrier to get the original error cause
3819  // which may otherwise be hidden.
3820  jQuery.Deferred.exceptionHook = function (error, asyncError) {
3821
3822    // Support: IE 8 - 9 only
3823    // Console exists when dev tools are open, which can happen at any time
3824    if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {
3825      window.console.warn("jQuery.Deferred exception: " + error.message,
3826      error.stack, asyncError);
3827    }
3828  };
3829
3830
3831
3832
3833  jQuery.readyException = function (error) {
3834    window.setTimeout(function () {
3835      throw error;
3836    });
3837  };
3838
3839
3840
3841
3842  // The deferred used on DOM ready
3843  var readyList = jQuery.Deferred();
3844
3845  jQuery.fn.ready = function (fn) {
3846
3847    readyList.
3848    then(fn)
3849
3850    // Wrap jQuery.readyException in a function so that the lookup
3851    // happens at the time of error handling instead of callback
3852    // registration.
3853    .catch(function (error) {
3854      jQuery.readyException(error);
3855    });
3856
3857    return this;
3858  };
3859
3860  jQuery.extend({
3861
3862    // Is the DOM ready to be used? Set to true once it occurs.
3863    isReady: false,
3864
3865    // A counter to track how many items to wait for before
3866    // the ready event fires. See trac-6781
3867    readyWait: 1,
3868
3869    // Handle when the DOM is ready
3870    ready: function (wait) {
3871
3872      // Abort if there are pending holds or we're already ready
3873      if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
3874        return;
3875      }
3876
3877      // Remember that the DOM is ready
3878      jQuery.isReady = true;
3879
3880      // If a normal DOM Ready event fired, decrement, and wait if need be
3881      if (wait !== true && --jQuery.readyWait > 0) {
3882        return;
3883      }
3884
3885      // If there are functions bound, to execute
3886      readyList.resolveWith(document, [jQuery]);
3887    }
3888  });
3889
3890  jQuery.ready.then = readyList.then;
3891
3892  // The ready event handler and self cleanup method
3893  function completed() {
3894    document.removeEventListener("DOMContentLoaded", completed);
3895    window.removeEventListener("load", completed);
3896    jQuery.ready();
3897  }
3898
3899  // Catch cases where $(document).ready() is called
3900  // after the browser event has already occurred.
3901  // Support: IE <=9 - 10 only
3902  // Older IE sometimes signals "interactive" too soon
3903  if (document.readyState === "complete" ||
3904  document.readyState !== "loading" && !document.documentElement.doScroll) {
3905
3906    // Handle it asynchronously to allow scripts the opportunity to delay ready
3907    window.setTimeout(jQuery.ready);
3908
3909  } else {
3910
3911    // Use the handy event callback
3912    document.addEventListener("DOMContentLoaded", completed);
3913
3914    // A fallback to window.onload, that will always work
3915    window.addEventListener("load", completed);
3916  }
3917
3918
3919
3920
3921  // Multifunctional method to get and set values of a collection
3922  // The value/s can optionally be executed if it's a function
3923  var access = function (elems, fn, key, value, chainable, emptyGet, raw) {
3924    var i = 0,
3925      len = elems.length,
3926      bulk = key == null;
3927
3928    // Sets many values
3929    if (toType(key) === "object") {
3930      chainable = true;
3931      for (i in key) {
3932        access(elems, fn, i, key[i], true, emptyGet, raw);
3933      }
3934
3935      // Sets one value
3936    } else if (value !== undefined) {
3937      chainable = true;
3938
3939      if (!isFunction(value)) {
3940        raw = true;
3941      }
3942
3943      if (bulk) {
3944
3945        // Bulk operations run against the entire set
3946        if (raw) {
3947          fn.call(elems, value);
3948          fn = null;
3949
3950          // ...except when executing function values
3951        } else {
3952          bulk = fn;
3953          fn = function (elem, _key, value) {
3954            return bulk.call(jQuery(elem), value);
3955          };
3956        }
3957      }
3958
3959      if (fn) {
3960        for (; i < len; i++) {
3961          fn(
3962            elems[i], key, raw ?
3963            value :
3964            value.call(elems[i], i, fn(elems[i], key))
3965          );
3966        }
3967      }
3968    }
3969
3970    if (chainable) {
3971      return elems;
3972    }
3973
3974    // Gets
3975    if (bulk) {
3976      return fn.call(elems);
3977    }
3978
3979    return len ? fn(elems[0], key) : emptyGet;
3980  };
3981
3982
3983  // Matches dashed string for camelizing
3984  var rmsPrefix = /^-ms-/,
3985    rdashAlpha = /-([a-z])/g;
3986
3987  // Used by camelCase as callback to replace()
3988  function fcamelCase(_all, letter) {
3989    return letter.toUpperCase();
3990  }
3991
3992  // Convert dashed to camelCase; used by the css and data modules
3993  // Support: IE <=9 - 11, Edge 12 - 15
3994  // Microsoft forgot to hump their vendor prefix (trac-9572)
3995  function camelCase(string) {
3996    return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
3997  }
3998  var acceptData = function (owner) {
3999
4000    // Accepts only:
4001    //  - Node
4002    //    - Node.ELEMENT_NODE
4003    //    - Node.DOCUMENT_NODE
4004    //  - Object
4005    //    - Any
4006    return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType;
4007  };
4008
4009
4010
4011
4012  function Data() {
4013    this.expando = jQuery.expando + Data.uid++;
4014  }
4015
4016  Data.uid = 1;
4017
4018  Data.prototype = {
4019
4020    cache: function (owner) {
4021
4022      // Check if the owner object already has a cache
4023      var value = owner[this.expando];
4024
4025      // If not, create one
4026      if (!value) {
4027        value = {};
4028
4029        // We can accept data for non-element nodes in modern browsers,
4030        // but we should not, see trac-8335.
4031        // Always return an empty object.
4032        if (acceptData(owner)) {
4033
4034          // If it is a node unlikely to be stringify-ed or looped over
4035          // use plain assignment
4036          if (owner.nodeType) {
4037            owner[this.expando] = value;
4038
4039            // Otherwise secure it in a non-enumerable property
4040            // configurable must be true to allow the property to be
4041            // deleted when data is removed
4042          } else {
4043            Object.defineProperty(owner, this.expando, {
4044              value: value,
4045              configurable: true
4046            });
4047          }
4048        }
4049      }
4050
4051      return value;
4052    },
4053    set: function (owner, data, value) {
4054      var prop,
4055        cache = this.cache(owner);
4056
4057      // Handle: [ owner, key, value ] args
4058      // Always use camelCase key (gh-2257)
4059      if (typeof data === "string") {
4060        cache[camelCase(data)] = value;
4061
4062        // Handle: [ owner, { properties } ] args
4063      } else {
4064
4065        // Copy the properties one-by-one to the cache object
4066        for (prop in data) {
4067          cache[camelCase(prop)] = data[prop];
4068        }
4069      }
4070      return cache;
4071    },
4072    get: function (owner, key) {
4073      return key === undefined ?
4074      this.cache(owner) :
4075
4076      // Always use camelCase key (gh-2257)
4077      owner[this.expando] && owner[this.expando][camelCase(key)];
4078    },
4079    access: function (owner, key, value) {
4080
4081      // In cases where either:
4082      //
4083      //   1. No key was specified
4084      //   2. A string key was specified, but no value provided
4085      //
4086      // Take the "read" path and allow the get method to determine
4087      // which value to return, respectively either:
4088      //
4089      //   1. The entire cache object
4090      //   2. The data stored at the key
4091      //
4092      if (key === undefined ||
4093      key && typeof key === "string" && value === undefined) {
4094
4095        return this.get(owner, key);
4096      }
4097
4098      // When the key is not a string, or both a key and value
4099      // are specified, set or extend (existing objects) with either:
4100      //
4101      //   1. An object of properties
4102      //   2. A key and value
4103      //
4104      this.set(owner, key, value);
4105
4106      // Since the "set" path can have two possible entry points
4107      // return the expected data based on which path was taken[*]
4108      return value !== undefined ? value : key;
4109    },
4110    remove: function (owner, key) {
4111      var i,
4112        cache = owner[this.expando];
4113
4114      if (cache === undefined) {
4115        return;
4116      }
4117
4118      if (key !== undefined) {
4119
4120        // Support array or space separated string of keys
4121        if (Array.isArray(key)) {
4122
4123          // If key is an array of keys...
4124          // We always set camelCase keys, so remove that.
4125          key = key.map(camelCase);
4126        } else {
4127          key = camelCase(key);
4128
4129          // If a key with the spaces exists, use it.
4130          // Otherwise, create an array by matching non-whitespace
4131          key = key in cache ?
4132          [key] :
4133          key.match(rnothtmlwhite) || [];
4134        }
4135
4136        i = key.length;
4137
4138        while (i--) {
4139          delete cache[key[i]];
4140        }
4141      }
4142
4143      // Remove the expando if there's no more data
4144      if (key === undefined || jQuery.isEmptyObject(cache)) {
4145
vendor: 8,628 bytes, lines 4146-4471
4146        // Support: Chrome <=35 - 45
4147        // Webkit & Blink performance suffers when deleting properties
4148        // from DOM nodes, so set to undefined instead
4149        // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4150        if (owner.nodeType) {
4151          owner[this.expando] = undefined;
4152        } else {
4153          delete owner[this.expando];
4154        }
4155      }
4156    },
4157    hasData: function (owner) {
4158      var cache = owner[this.expando];
4159      return cache !== undefined && !jQuery.isEmptyObject(cache);
4160    }
4161  };
4162  var dataPriv = new Data();
4163
4164  var dataUser = new Data();
4165
4166
4167
4168  //  Implementation Summary
4169  //
4170  //  1. Enforce API surface and semantic compatibility with 1.9.x branch
4171  //  2. Improve the module's maintainability by reducing the storage
4172  //    paths to a single mechanism.
4173  //  3. Use the same single mechanism to support "private" and "user" data.
4174  //  4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4175  //  5. Avoid exposing implementation details on user objects (eg. expando properties)
4176  //  6. Provide a clear path for implementation upgrade to WeakMap in 2014
4177
4178  var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4179    rmultiDash = /[A-Z]/g;
4180
4181  function getData(data) {
4182    if (data === "true") {
4183      return true;
4184    }
4185
4186    if (data === "false") {
4187      return false;
4188    }
4189
4190    if (data === "null") {
4191      return null;
4192    }
4193
4194    // Only convert to a number if it doesn't change the string
4195    if (data === +data + "") {
4196      return +data;
4197    }
4198
4199    if (rbrace.test(data)) {
4200      return JSON.parse(data);
4201    }
4202
4203    return data;
4204  }
4205
4206  function dataAttr(elem, key, data) {
4207    var name;
4208
4209    // If nothing was found internally, try to fetch any
4210    // data from the HTML5 data-* attribute
4211    if (data === undefined && elem.nodeType === 1) {
4212      name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();
4213      data = elem.getAttribute(name);
4214
4215      if (typeof data === "string") {
4216        try {
4217          data = getData(data);
4218        } catch (e) {}
4219
4220        // Make sure we set the data so it isn't changed later
4221        dataUser.set(elem, key, data);
4222      } else {
4223        data = undefined;
4224      }
4225    }
4226    return data;
4227  }
4228
4229  jQuery.extend({
4230    hasData: function (elem) {
4231      return dataUser.hasData(elem) || dataPriv.hasData(elem);
4232    },
4233
4234    data: function (elem, name, data) {
4235      return dataUser.access(elem, name, data);
4236    },
4237
4238    removeData: function (elem, name) {
4239      dataUser.remove(elem, name);
4240    },
4241
4242    // TODO: Now that all calls to _data and _removeData have been replaced
4243    // with direct calls to dataPriv methods, these can be deprecated.
4244    _data: function (elem, name, data) {
4245      return dataPriv.access(elem, name, data);
4246    },
4247
4248    _removeData: function (elem, name) {
4249      dataPriv.remove(elem, name);
4250    }
4251  });
4252
4253  jQuery.fn.extend({
4254    data: function (key, value) {
4255      var i,name,data,
4256        elem = this[0],
4257        attrs = elem && elem.attributes;
4258
4259      // Gets all values
4260      if (key === undefined) {
4261        if (this.length) {
4262          data = dataUser.get(elem);
4263
4264          if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {
4265            i = attrs.length;
4266            while (i--) {
4267
4268              // Support: IE 11 only
4269              // The attrs elements can be null (trac-14894)
4270              if (attrs[i]) {
4271                name = attrs[i].name;
4272                if (name.indexOf("data-") === 0) {
4273                  name = camelCase(name.slice(5));
4274                  dataAttr(elem, name, data[name]);
4275                }
4276              }
4277            }
4278            dataPriv.set(elem, "hasDataAttrs", true);
4279          }
4280        }
4281
4282        return data;
4283      }
4284
4285      // Sets multiple values
4286      if (typeof key === "object") {
4287        return this.each(function () {
4288          dataUser.set(this, key);
4289        });
4290      }
4291
4292      return access(this, function (value) {
4293        var data;
4294
4295        // The calling jQuery object (element matches) is not empty
4296        // (and therefore has an element appears at this[ 0 ]) and the
4297        // `value` parameter was not undefined. An empty jQuery object
4298        // will result in `undefined` for elem = this[ 0 ] which will
4299        // throw an exception if an attempt to read a data cache is made.
4300        if (elem && value === undefined) {
4301
4302          // Attempt to get data from the cache
4303          // The key will always be camelCased in Data
4304          data = dataUser.get(elem, key);
4305          if (data !== undefined) {
4306            return data;
4307          }
4308
4309          // Attempt to "discover" the data in
4310          // HTML5 custom data-* attrs
4311          data = dataAttr(elem, key);
4312          if (data !== undefined) {
4313            return data;
4314          }
4315
4316          // We tried really hard, but the data doesn't exist.
4317          return;
4318        }
4319
4320        // Set the data...
4321        this.each(function () {
4322
4323          // We always store the camelCased key
4324          dataUser.set(this, key, value);
4325        });
4326      }, null, value, arguments.length > 1, null, true);
4327    },
4328
4329    removeData: function (key) {
4330      return this.each(function () {
4331        dataUser.remove(this, key);
4332      });
4333    }
4334  });
4335
4336
4337  jQuery.extend({
4338    queue: function (elem, type, data) {
4339      var queue;
4340
4341      if (elem) {
4342        type = (type || "fx") + "queue";
4343        queue = dataPriv.get(elem, type);
4344
4345        // Speed up dequeue by getting out quickly if this is just a lookup
4346        if (data) {
4347          if (!queue || Array.isArray(data)) {
4348            queue = dataPriv.access(elem, type, jQuery.makeArray(data));
4349          } else {
4350            queue.push(data);
4351          }
4352        }
4353        return queue || [];
4354      }
4355    },
4356
4357    dequeue: function (elem, type) {
4358      type = type || "fx";
4359
4360      var queue = jQuery.queue(elem, type),
4361        startLength = queue.length,
4362        fn = queue.shift(),
4363        hooks = jQuery._queueHooks(elem, type),
4364        next = function () {
4365          jQuery.dequeue(elem, type);
4366        };
4367
4368      // If the fx queue is dequeued, always remove the progress sentinel
4369      if (fn === "inprogress") {
4370        fn = queue.shift();
4371        startLength--;
4372      }
4373
4374      if (fn) {
4375
4376        // Add a progress sentinel to prevent the fx queue from being
4377        // automatically dequeued
4378        if (type === "fx") {
4379          queue.unshift("inprogress");
4380        }
4381
4382        // Clear up the last queue stop function
4383        delete hooks.stop;
4384        fn.call(elem, next, hooks);
4385      }
4386
4387      if (!startLength && hooks) {
4388        hooks.empty.fire();
4389      }
4390    },
4391
4392    // Not public - generate a queueHooks object, or return the current one
4393    _queueHooks: function (elem, type) {
4394      var key = type + "queueHooks";
4395      return dataPriv.get(elem, key) || dataPriv.access(elem, key, {
4396        empty: jQuery.Callbacks("once memory").add(function () {
4397          dataPriv.remove(elem, [type + "queue", key]);
4398        })
4399      });
4400    }
4401  });
4402
4403  jQuery.fn.extend({
4404    queue: function (type, data) {
4405      var setter = 2;
4406
4407      if (typeof type !== "string") {
4408        data = type;
4409        type = "fx";
4410        setter--;
4411      }
4412
4413      if (arguments.length < setter) {
4414        return jQuery.queue(this[0], type);
4415      }
4416
4417      return data === undefined ?
4418      this :
4419      this.each(function () {
4420        var queue = jQuery.queue(this, type, data);
4421
4422        // Ensure a hooks for this queue
4423        jQuery._queueHooks(this, type);
4424
4425        if (type === "fx" && queue[0] !== "inprogress") {
4426          jQuery.dequeue(this, type);
4427        }
4428      });
4429    },
4430    dequeue: function (type) {
4431      return this.each(function () {
4432        jQuery.dequeue(this, type);
4433      });
4434    },
4435    clearQueue: function (type) {
4436      return this.queue(type || "fx", []);
4437    },
4438
4439    // Get a promise resolved when queues of a certain type
4440    // are emptied (fx is the type by default)
4441    promise: function (type, obj) {
4442      var tmp,
4443        count = 1,
4444        defer = jQuery.Deferred(),
4445        elements = this,
4446        i = this.length,
4447        resolve = function () {
4448          if (! --count) {
4449            defer.resolveWith(elements, [elements]);
4450          }
4451        };
4452
4453      if (typeof type !== "string") {
4454        obj = type;
4455        type = undefined;
4456      }
4457      type = type || "fx";
4458
4459      while (i--) {
4460        tmp = dataPriv.get(elements[i], type + "queueHooks");
4461        if (tmp && tmp.empty) {
4462          count++;
4463          tmp.empty.add(resolve);
4464        }
4465      }
4466      resolve();
4467      return defer.promise(obj);
4468    }
4469  });
4470  var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
4471
vendor: 4,324 bytes, lines 4472-4624
4472  var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");
4473
4474
4475  var cssExpand = ["Top", "Right", "Bottom", "Left"];
4476
4477  var documentElement = document.documentElement;
4478
4479
4480
4481  var isAttached = function (elem) {
4482      return jQuery.contains(elem.ownerDocument, elem);
4483    },
4484    composed = { composed: true };
4485
4486  // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
4487  // Check attachment across shadow DOM boundaries when possible (gh-3504)
4488  // Support: iOS 10.0-10.2 only
4489  // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
4490  // leading to errors. We need to check for `getRootNode`.
4491  if (documentElement.getRootNode) {
4492    isAttached = function (elem) {
4493      return jQuery.contains(elem.ownerDocument, elem) ||
4494      elem.getRootNode(composed) === elem.ownerDocument;
4495    };
4496  }
4497  var isHiddenWithinTree = function (elem, el) {
4498
4499    // isHiddenWithinTree might be called from jQuery#filter function;
4500    // in that case, element will be second argument
4501    elem = el || elem;
4502
4503    // Inline style trumps all
4504    return elem.style.display === "none" ||
4505    elem.style.display === "" &&
4506
4507    // Otherwise, check computed style
4508    // Support: Firefox <=43 - 45
4509    // Disconnected elements can have computed display: none, so first confirm that elem is
4510    // in the document.
4511    isAttached(elem) &&
4512
4513    jQuery.css(elem, "display") === "none";
4514  };
4515
4516
4517
4518  function adjustCSS(elem, prop, valueParts, tween) {
4519    var adjusted,scale,
4520      maxIterations = 20,
4521      currentValue = tween ?
4522      function () {
4523        return tween.cur();
4524      } :
4525      function () {
4526        return jQuery.css(elem, prop, "");
4527      },
4528      initial = currentValue(),
4529      unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
4530
4531      // Starting value computation is required for potential unit mismatches
4532      initialInUnit = elem.nodeType && (
4533      jQuery.cssNumber[prop] || unit !== "px" && +initial) &&
4534      rcssNum.exec(jQuery.css(elem, prop));
4535
4536    if (initialInUnit && initialInUnit[3] !== unit) {
4537
4538      // Support: Firefox <=54
4539      // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
4540      initial = initial / 2;
4541
4542      // Trust units reported by jQuery.css
4543      unit = unit || initialInUnit[3];
4544
4545      // Iteratively approximate from a nonzero starting point
4546      initialInUnit = +initial || 1;
4547
4548      while (maxIterations--) {
4549
4550        // Evaluate and update our best guess (doubling guesses that zero out).
4551        // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
4552        jQuery.style(elem, prop, initialInUnit + unit);
4553        if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) {
4554          maxIterations = 0;
4555        }
4556        initialInUnit = initialInUnit / scale;
4557
4558      }
4559
4560      initialInUnit = initialInUnit * 2;
4561      jQuery.style(elem, prop, initialInUnit + unit);
4562
4563      // Make sure we update the tween properties later on
4564      valueParts = valueParts || [];
4565    }
4566
4567    if (valueParts) {
4568      initialInUnit = +initialInUnit || +initial || 0;
4569
4570      // Apply relative offset (+=/-=) if specified
4571      adjusted = valueParts[1] ?
4572      initialInUnit + (valueParts[1] + 1) * valueParts[2] :
4573      +valueParts[2];
4574      if (tween) {
4575        tween.unit = unit;
4576        tween.start = initialInUnit;
4577        tween.end = adjusted;
4578      }
4579    }
4580    return adjusted;
4581  }
4582
4583
4584  var defaultDisplayMap = {};
4585
4586  function getDefaultDisplay(elem) {
4587    var temp,
4588      doc = elem.ownerDocument,
4589      nodeName = elem.nodeName,
4590      display = defaultDisplayMap[nodeName];
4591
4592    if (display) {
4593      return display;
4594    }
4595
4596    temp = doc.body.appendChild(doc.createElement(nodeName));
4597    display = jQuery.css(temp, "display");
4598
4599    temp.parentNode.removeChild(temp);
4600
4601    if (display === "none") {
4602      display = "block";
4603    }
4604    defaultDisplayMap[nodeName] = display;
4605
4606    return display;
4607  }
4608
4609  function showHide(elements, show) {
4610    var display,elem,
4611      values = [],
4612      index = 0,
4613      length = elements.length;
4614
4615    // Determine new display value for elements that need to change
4616    for (; index < length; index++) {
4617      elem = elements[index];
4618      if (!elem.style) {
4619        continue;
4620      }
4621
4622      display = elem.style.display;
4623      if (show) {
4624
vendor: 2,216 bytes, lines 4625-4701
4625        // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4626        // check is required in this first loop unless we have a nonempty display value (either
4627        // inline or about-to-be-restored)
4628        if (display === "none") {
4629          values[index] = dataPriv.get(elem, "display") || null;
4630          if (!values[index]) {
4631            elem.style.display = "";
4632          }
4633        }
4634        if (elem.style.display === "" && isHiddenWithinTree(elem)) {
4635          values[index] = getDefaultDisplay(elem);
4636        }
4637      } else {
4638        if (display !== "none") {
4639          values[index] = "none";
4640
4641          // Remember what we're overwriting
4642          dataPriv.set(elem, "display", display);
4643        }
4644      }
4645    }
4646
4647    // Set the display of the elements in a second loop to avoid constant reflow
4648    for (index = 0; index < length; index++) {
4649      if (values[index] != null) {
4650        elements[index].style.display = values[index];
4651      }
4652    }
4653
4654    return elements;
4655  }
4656
4657  jQuery.fn.extend({
4658    show: function () {
4659      return showHide(this, true);
4660    },
4661    hide: function () {
4662      return showHide(this);
4663    },
4664    toggle: function (state) {
4665      if (typeof state === "boolean") {
4666        return state ? this.show() : this.hide();
4667      }
4668
4669      return this.each(function () {
4670        if (isHiddenWithinTree(this)) {
4671          jQuery(this).show();
4672        } else {
4673          jQuery(this).hide();
4674        }
4675      });
4676    }
4677  });
4678  var rcheckableType = /^(?:checkbox|radio)$/i;
4679
4680  var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i;
4681
4682  var rscriptType = /^$|^module$|\/(?:java|ecma)script/i;
4683
4684
4685
4686  (function () {
4687    var fragment = document.createDocumentFragment(),
4688      div = fragment.appendChild(document.createElement("div")),
4689      input = document.createElement("input");
4690
4691    // Support: Android 4.0 - 4.3 only
4692    // Check state lost if the name is set (trac-11217)
4693    // Support: Windows Web Apps (WWA)
4694    // `name` and `type` must use .setAttribute for WWA (trac-14901)
4695    input.setAttribute("type", "radio");
4696    input.setAttribute("checked", "checked");
4697    input.setAttribute("name", "t");
4698
4699    div.appendChild(input);
4700
4701    // Support: Android <=4.1 only
vendor: 10,689 bytes, lines 4702-5076
4702    // Older WebKit doesn't clone checked state correctly in fragments
4703    support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;
4704
4705    // Support: IE <=11 only
4706    // Make sure textarea (and checkbox) defaultValue is properly cloned
4707    div.innerHTML = "<textarea>x</textarea>";
4708    support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
4709
4710    // Support: IE <=9 only
4711    // IE <=9 replaces <option> tags with their contents when inserted outside of
4712    // the select element.
4713    div.innerHTML = "<option></option>";
4714    support.option = !!div.lastChild;
4715  })();
4716
4717
4718  // We have to close these tags to support XHTML (trac-13200)
4719  var wrapMap = {
4720
4721    // XHTML parsers do not magically insert elements in the
4722    // same way that tag soup parsers do. So we cannot shorten
4723    // this by omitting <tbody> or other required elements.
4724    thead: [1, "<table>", "</table>"],
4725    col: [2, "<table><colgroup>", "</colgroup></table>"],
4726    tr: [2, "<table><tbody>", "</tbody></table>"],
4727    td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
4728
4729    _default: [0, "", ""]
4730  };
4731
4732  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4733  wrapMap.th = wrapMap.td;
4734
4735  // Support: IE <=9 only
4736  if (!support.option) {
4737    wrapMap.optgroup = wrapMap.option = [1, "<select multiple='multiple'>", "</select>"];
4738  }
4739
4740
4741  function getAll(context, tag) {
4742
4743    // Support: IE <=9 - 11 only
4744    // Use typeof to avoid zero-argument method invocation on host objects (trac-15151)
4745    var ret;
4746
4747    if (typeof context.getElementsByTagName !== "undefined") {
4748      ret = context.getElementsByTagName(tag || "*");
4749
4750    } else if (typeof context.querySelectorAll !== "undefined") {
4751      ret = context.querySelectorAll(tag || "*");
4752
4753    } else {
4754      ret = [];
4755    }
4756
4757    if (tag === undefined || tag && nodeName(context, tag)) {
4758      return jQuery.merge([context], ret);
4759    }
4760
4761    return ret;
4762  }
4763
4764
4765  // Mark scripts as having already been evaluated
4766  function setGlobalEval(elems, refElements) {
4767    var i = 0,
4768      l = elems.length;
4769
4770    for (; i < l; i++) {
4771      dataPriv.set(
4772        elems[i],
4773        "globalEval",
4774        !refElements || dataPriv.get(refElements[i], "globalEval")
4775      );
4776    }
4777  }
4778
4779
4780  var rhtml = /<|&#?\w+;/;
4781
4782  function buildFragment(elems, context, scripts, selection, ignored) {
4783    var elem,tmp,tag,wrap,attached,j,
4784      fragment = context.createDocumentFragment(),
4785      nodes = [],
4786      i = 0,
4787      l = elems.length;
4788
4789    for (; i < l; i++) {
4790      elem = elems[i];
4791
4792      if (elem || elem === 0) {
4793
4794        // Add nodes directly
4795        if (toType(elem) === "object") {
4796
4797          // Support: Android <=4.0 only, PhantomJS 1 only
4798          // push.apply(_, arraylike) throws on ancient WebKit
4799          jQuery.merge(nodes, elem.nodeType ? [elem] : elem);
4800
4801          // Convert non-html into a text node
4802        } else if (!rhtml.test(elem)) {
4803          nodes.push(context.createTextNode(elem));
4804
4805          // Convert html into DOM nodes
4806        } else {
4807          tmp = tmp || fragment.appendChild(context.createElement("div"));
4808
4809          // Deserialize a standard representation
4810          tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
4811          wrap = wrapMap[tag] || wrapMap._default;
4812          tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];
4813
4814          // Descend through wrappers to the right content
4815          j = wrap[0];
4816          while (j--) {
4817            tmp = tmp.lastChild;
4818          }
4819
4820          // Support: Android <=4.0 only, PhantomJS 1 only
4821          // push.apply(_, arraylike) throws on ancient WebKit
4822          jQuery.merge(nodes, tmp.childNodes);
4823
4824          // Remember the top-level container
4825          tmp = fragment.firstChild;
4826
4827          // Ensure the created nodes are orphaned (trac-12392)
4828          tmp.textContent = "";
4829        }
4830      }
4831    }
4832
4833    // Remove wrapper from fragment
4834    fragment.textContent = "";
4835
4836    i = 0;
4837    while (elem = nodes[i++]) {
4838
4839      // Skip elements already in the context collection (trac-4087)
4840      if (selection && jQuery.inArray(elem, selection) > -1) {
4841        if (ignored) {
4842          ignored.push(elem);
4843        }
4844        continue;
4845      }
4846
4847      attached = isAttached(elem);
4848
4849      // Append to fragment
4850      tmp = getAll(fragment.appendChild(elem), "script");
4851
4852      // Preserve script evaluation history
4853      if (attached) {
4854        setGlobalEval(tmp);
4855      }
4856
4857      // Capture executables
4858      if (scripts) {
4859        j = 0;
4860        while (elem = tmp[j++]) {
4861          if (rscriptType.test(elem.type || "")) {
4862            scripts.push(elem);
4863          }
4864        }
4865      }
4866    }
4867
4868    return fragment;
4869  }
4870
4871
4872  var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4873
4874  function returnTrue() {
4875    return true;
4876  }
4877
4878  function returnFalse() {
4879    return false;
4880  }
4881
4882  function on(elem, types, selector, data, fn, one) {
4883    var origFn, type;
4884
4885    // Types can be a map of types/handlers
4886    if (typeof types === "object") {
4887
4888      // ( types-Object, selector, data )
4889      if (typeof selector !== "string") {
4890
4891        // ( types-Object, data )
4892        data = data || selector;
4893        selector = undefined;
4894      }
4895      for (type in types) {
4896        on(elem, type, selector, data, types[type], one);
4897      }
4898      return elem;
4899    }
4900
4901    if (data == null && fn == null) {
4902
4903      // ( types, fn )
4904      fn = selector;
4905      data = selector = undefined;
4906    } else if (fn == null) {
4907      if (typeof selector === "string") {
4908
4909        // ( types, selector, fn )
4910        fn = data;
4911        data = undefined;
4912      } else {
4913
4914        // ( types, data, fn )
4915        fn = data;
4916        data = selector;
4917        selector = undefined;
4918      }
4919    }
4920    if (fn === false) {
4921      fn = returnFalse;
4922    } else if (!fn) {
4923      return elem;
4924    }
4925
4926    if (one === 1) {
4927      origFn = fn;
4928      fn = function (event) {
4929
4930        // Can use an empty set, since event contains the info
4931        jQuery().off(event);
4932        return origFn.apply(this, arguments);
4933      };
4934
4935      // Use same guid so caller can remove using origFn
4936      fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
4937    }
4938    return elem.each(function () {
4939      jQuery.event.add(this, types, fn, data, selector);
4940    });
4941  }
4942
4943  /*
4944   * Helper functions for managing events -- not part of the public interface.
4945   * Props to Dean Edwards' addEvent library for many of the ideas.
4946   */
4947  jQuery.event = {
4948
4949    global: {},
4950
4951    add: function (elem, types, handler, data, selector) {
4952
4953      var handleObjIn,eventHandle,tmp,
4954        events,t,handleObj,
4955        special,handlers,type,namespaces,origType,
4956        elemData = dataPriv.get(elem);
4957
4958      // Only attach events to objects that accept data
4959      if (!acceptData(elem)) {
4960        return;
4961      }
4962
4963      // Caller can pass in an object of custom data in lieu of the handler
4964      if (handler.handler) {
4965        handleObjIn = handler;
4966        handler = handleObjIn.handler;
4967        selector = handleObjIn.selector;
4968      }
4969
4970      // Ensure that invalid selectors throw exceptions at attach time
4971      // Evaluate against documentElement in case elem is a non-element node (e.g., document)
4972      if (selector) {
4973        jQuery.find.matchesSelector(documentElement, selector);
4974      }
4975
4976      // Make sure that the handler has a unique ID, used to find/remove it later
4977      if (!handler.guid) {
4978        handler.guid = jQuery.guid++;
4979      }
4980
4981      // Init the element's event structure and main handler, if this is the first
4982      if (!(events = elemData.events)) {
4983        events = elemData.events = Object.create(null);
4984      }
4985      if (!(eventHandle = elemData.handle)) {
4986        eventHandle = elemData.handle = function (e) {
4987
4988          // Discard the second event of a jQuery.event.trigger() and
4989          // when an event is called after a page has unloaded
4990          return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
4991          jQuery.event.dispatch.apply(elem, arguments) : undefined;
4992        };
4993      }
4994
4995      // Handle multiple events separated by a space
4996      types = (types || "").match(rnothtmlwhite) || [""];
4997      t = types.length;
4998      while (t--) {
4999        tmp = rtypenamespace.exec(types[t]) || [];
5000        type = origType = tmp[1];
5001        namespaces = (tmp[2] || "").split(".").sort();
5002
5003        // There *must* be a type, no attaching namespace-only handlers
5004        if (!type) {
5005          continue;
5006        }
5007
5008        // If event changes its type, use the special event handlers for the changed type
5009        special = jQuery.event.special[type] || {};
5010
5011        // If selector defined, determine special event api type, otherwise given type
5012        type = (selector ? special.delegateType : special.bindType) || type;
5013
5014        // Update special based on newly reset type
5015        special = jQuery.event.special[type] || {};
5016
5017        // handleObj is passed to all event handlers
5018        handleObj = jQuery.extend({
5019          type: type,
5020          origType: origType,
5021          data: data,
5022          handler: handler,
5023          guid: handler.guid,
5024          selector: selector,
5025          needsContext: selector && jQuery.expr.match.needsContext.test(selector),
5026          namespace: namespaces.join(".")
5027        }, handleObjIn);
5028
5029        // Init the event handler queue if we're the first
5030        if (!(handlers = events[type])) {
5031          handlers = events[type] = [];
5032          handlers.delegateCount = 0;
5033
5034          // Only use addEventListener if the special events handler returns false
5035          if (!special.setup ||
5036          special.setup.call(elem, data, namespaces, eventHandle) === false) {
5037
5038            if (elem.addEventListener) {
5039              elem.addEventListener(type, eventHandle);
5040            }
5041          }
5042        }
5043
5044        if (special.add) {
5045          special.add.call(elem, handleObj);
5046
5047          if (!handleObj.handler.guid) {
5048            handleObj.handler.guid = handler.guid;
5049          }
5050        }
5051
5052        // Add to the element's handler list, delegates in front
5053        if (selector) {
5054          handlers.splice(handlers.delegateCount++, 0, handleObj);
5055        } else {
5056          handlers.push(handleObj);
5057        }
5058
5059        // Keep track of which events have ever been used, for event optimization
5060        jQuery.event.global[type] = true;
5061      }
5062
5063    },
5064
5065    // Detach an event or set of events from an element
5066    remove: function (elem, types, handler, selector, mappedTypes) {
5067
5068      var j,origCount,tmp,
5069        events,t,handleObj,
5070        special,handlers,type,namespaces,origType,
5071        elemData = dataPriv.hasData(elem) && dataPriv.get(elem);
5072
5073      if (!elemData || !(events = elemData.events)) {
5074        return;
5075      }
5076
vendor: 4,614 bytes, lines 5077-5215
5077      // Once for each type.namespace in types; type may be omitted
5078      types = (types || "").match(rnothtmlwhite) || [""];
5079      t = types.length;
5080      while (t--) {
5081        tmp = rtypenamespace.exec(types[t]) || [];
5082        type = origType = tmp[1];
5083        namespaces = (tmp[2] || "").split(".").sort();
5084
5085        // Unbind all events (on this namespace, if provided) for the element
5086        if (!type) {
5087          for (type in events) {
5088            jQuery.event.remove(elem, type + types[t], handler, selector, true);
5089          }
5090          continue;
5091        }
5092
5093        special = jQuery.event.special[type] || {};
5094        type = (selector ? special.delegateType : special.bindType) || type;
5095        handlers = events[type] || [];
5096        tmp = tmp[2] &&
5097        new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
5098
5099        // Remove matching events
5100        origCount = j = handlers.length;
5101        while (j--) {
5102          handleObj = handlers[j];
5103
5104          if ((mappedTypes || origType === handleObj.origType) && (
5105          !handler || handler.guid === handleObj.guid) && (
5106          !tmp || tmp.test(handleObj.namespace)) && (
5107          !selector || selector === handleObj.selector ||
5108          selector === "**" && handleObj.selector)) {
5109            handlers.splice(j, 1);
5110
5111            if (handleObj.selector) {
5112              handlers.delegateCount--;
5113            }
5114            if (special.remove) {
5115              special.remove.call(elem, handleObj);
5116            }
5117          }
5118        }
5119
5120        // Remove generic event handler if we removed something and no more handlers exist
5121        // (avoids potential for endless recursion during removal of special event handlers)
5122        if (origCount && !handlers.length) {
5123          if (!special.teardown ||
5124          special.teardown.call(elem, namespaces, elemData.handle) === false) {
5125
5126            jQuery.removeEvent(elem, type, elemData.handle);
5127          }
5128
5129          delete events[type];
5130        }
5131      }
5132
5133      // Remove data and the expando if it's no longer used
5134      if (jQuery.isEmptyObject(events)) {
5135        dataPriv.remove(elem, "handle events");
5136      }
5137    },
5138
5139    dispatch: function (nativeEvent) {
5140
5141      var i,j,ret,matched,handleObj,handlerQueue,
5142        args = new Array(arguments.length),
5143
5144        // Make a writable jQuery.Event from the native event object
5145        event = jQuery.event.fix(nativeEvent),
5146
5147        handlers = (
5148        dataPriv.get(this, "events") || Object.create(null))[
5149        event.type] || [],
5150        special = jQuery.event.special[event.type] || {};
5151
5152      // Use the fix-ed jQuery.Event rather than the (read-only) native event
5153      args[0] = event;
5154
5155      for (i = 1; i < arguments.length; i++) {
5156        args[i] = arguments[i];
5157      }
5158
5159      event.delegateTarget = this;
5160
5161      // Call the preDispatch hook for the mapped type, and let it bail if desired
5162      if (special.preDispatch && special.preDispatch.call(this, event) === false) {
5163        return;
5164      }
5165
5166      // Determine handlers
5167      handlerQueue = jQuery.event.handlers.call(this, event, handlers);
5168
5169      // Run delegates first; they may want to stop propagation beneath us
5170      i = 0;
5171      while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
5172        event.currentTarget = matched.elem;
5173
5174        j = 0;
5175        while ((handleObj = matched.handlers[j++]) &&
5176        !event.isImmediatePropagationStopped()) {
5177
5178          // If the event is namespaced, then each handler is only invoked if it is
5179          // specially universal or its namespaces are a superset of the event's.
5180          if (!event.rnamespace || handleObj.namespace === false ||
5181          event.rnamespace.test(handleObj.namespace)) {
5182
5183            event.handleObj = handleObj;
5184            event.data = handleObj.data;
5185
5186            ret = ((jQuery.event.special[handleObj.origType] || {}).handle ||
5187            handleObj.handler).apply(matched.elem, args);
5188
5189            if (ret !== undefined) {
5190              if ((event.result = ret) === false) {
5191                event.preventDefault();
5192                event.stopPropagation();
5193              }
5194            }
5195          }
5196        }
5197      }
5198
5199      // Call the postDispatch hook for the mapped type
5200      if (special.postDispatch) {
5201        special.postDispatch.call(this, event);
5202      }
5203
5204      return event.result;
5205    },
5206
5207    handlers: function (event, handlers) {
5208      var i,handleObj,sel,matchedHandlers,matchedSelectors,
5209        handlerQueue = [],
5210        delegateCount = handlers.delegateCount,
5211        cur = event.target;
5212
5213      // Find delegate handlers
5214      if (delegateCount &&
5215
vendor: 66,008 bytes, lines 5216-7320
5216      // Support: IE <=9
5217      // Black-hole SVG <use> instance trees (trac-13180)
5218      cur.nodeType &&
5219
5220      // Support: Firefox <=42
5221      // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5222      // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5223      // Support: IE 11 only
5224      // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5225      !(event.type === "click" && event.button >= 1)) {
5226
5227        for (; cur !== this; cur = cur.parentNode || this) {
5228
5229          // Don't check non-elements (trac-13208)
5230          // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)
5231          if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) {
5232            matchedHandlers = [];
5233            matchedSelectors = {};
5234            for (i = 0; i < delegateCount; i++) {
5235              handleObj = handlers[i];
5236
5237              // Don't conflict with Object.prototype properties (trac-13203)
5238              sel = handleObj.selector + " ";
5239
5240              if (matchedSelectors[sel] === undefined) {
5241                matchedSelectors[sel] = handleObj.needsContext ?
5242                jQuery(sel, this).index(cur) > -1 :
5243                jQuery.find(sel, this, null, [cur]).length;
5244              }
5245              if (matchedSelectors[sel]) {
5246                matchedHandlers.push(handleObj);
5247              }
5248            }
5249            if (matchedHandlers.length) {
5250              handlerQueue.push({ elem: cur, handlers: matchedHandlers });
5251            }
5252          }
5253        }
5254      }
5255
5256      // Add the remaining (directly-bound) handlers
5257      cur = this;
5258      if (delegateCount < handlers.length) {
5259        handlerQueue.push({ elem: cur, handlers: handlers.slice(delegateCount) });
5260      }
5261
5262      return handlerQueue;
5263    },
5264
5265    addProp: function (name, hook) {
5266      Object.defineProperty(jQuery.Event.prototype, name, {
5267        enumerable: true,
5268        configurable: true,
5269
5270        get: isFunction(hook) ?
5271        function () {
5272          if (this.originalEvent) {
5273            return hook(this.originalEvent);
5274          }
5275        } :
5276        function () {
5277          if (this.originalEvent) {
5278            return this.originalEvent[name];
5279          }
5280        },
5281
5282        set: function (value) {
5283          Object.defineProperty(this, name, {
5284            enumerable: true,
5285            configurable: true,
5286            writable: true,
5287            value: value
5288          });
5289        }
5290      });
5291    },
5292
5293    fix: function (originalEvent) {
5294      return originalEvent[jQuery.expando] ?
5295      originalEvent :
5296      new jQuery.Event(originalEvent);
5297    },
5298
5299    special: {
5300      load: {
5301
5302        // Prevent triggered image.load events from bubbling to window.load
5303        noBubble: true
5304      },
5305      click: {
5306
5307        // Utilize native event to ensure correct state for checkable inputs
5308        setup: function (data) {
5309
5310          // For mutual compressibility with _default, replace `this` access with a local var.
5311          // `|| data` is dead code meant only to preserve the variable through minification.
5312          var el = this || data;
5313
5314          // Claim the first handler
5315          if (rcheckableType.test(el.type) &&
5316          el.click && nodeName(el, "input")) {
5317
5318            // dataPriv.set( el, "click", ... )
5319            leverageNative(el, "click", true);
5320          }
5321
5322          // Return false to allow normal processing in the caller
5323          return false;
5324        },
5325        trigger: function (data) {
5326
5327          // For mutual compressibility with _default, replace `this` access with a local var.
5328          // `|| data` is dead code meant only to preserve the variable through minification.
5329          var el = this || data;
5330
5331          // Force setup before triggering a click
5332          if (rcheckableType.test(el.type) &&
5333          el.click && nodeName(el, "input")) {
5334
5335            leverageNative(el, "click");
5336          }
5337
5338          // Return non-false to allow normal event-path propagation
5339          return true;
5340        },
5341
5342        // For cross-browser consistency, suppress native .click() on links
5343        // Also prevent it if we're currently inside a leveraged native-event stack
5344        _default: function (event) {
5345          var target = event.target;
5346          return rcheckableType.test(target.type) &&
5347          target.click && nodeName(target, "input") &&
5348          dataPriv.get(target, "click") ||
5349          nodeName(target, "a");
5350        }
5351      },
5352
5353      beforeunload: {
5354        postDispatch: function (event) {
5355
5356          // Support: Firefox 20+
5357          // Firefox doesn't alert if the returnValue field is not set.
5358          if (event.result !== undefined && event.originalEvent) {
5359            event.originalEvent.returnValue = event.result;
5360          }
5361        }
5362      }
5363    }
5364  };
5365
5366  // Ensure the presence of an event listener that handles manually-triggered
5367  // synthetic events by interrupting progress until reinvoked in response to
5368  // *native* events that it fires directly, ensuring that state changes have
5369  // already occurred before other listeners are invoked.
5370  function leverageNative(el, type, isSetup) {
5371
5372    // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add
5373    if (!isSetup) {
5374      if (dataPriv.get(el, type) === undefined) {
5375        jQuery.event.add(el, type, returnTrue);
5376      }
5377      return;
5378    }
5379
5380    // Register the controller as a special universal handler for all event namespaces
5381    dataPriv.set(el, type, false);
5382    jQuery.event.add(el, type, {
5383      namespace: false,
5384      handler: function (event) {
5385        var result,
5386          saved = dataPriv.get(this, type);
5387
5388        if (event.isTrigger & 1 && this[type]) {
5389
5390          // Interrupt processing of the outer synthetic .trigger()ed event
5391          if (!saved) {
5392
5393            // Store arguments for use when handling the inner native event
5394            // There will always be at least one argument (an event object), so this array
5395            // will not be confused with a leftover capture object.
5396            saved = slice.call(arguments);
5397            dataPriv.set(this, type, saved);
5398
5399            // Trigger the native event and capture its result
5400            this[type]();
5401            result = dataPriv.get(this, type);
5402            dataPriv.set(this, type, false);
5403
5404            if (saved !== result) {
5405
5406              // Cancel the outer synthetic event
5407              event.stopImmediatePropagation();
5408              event.preventDefault();
5409
5410              return result;
5411            }
5412
5413            // If this is an inner synthetic event for an event with a bubbling surrogate
5414            // (focus or blur), assume that the surrogate already propagated from triggering
5415            // the native event and prevent that from happening again here.
5416            // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
5417            // bubbling surrogate propagates *after* the non-bubbling base), but that seems
5418            // less bad than duplication.
5419          } else if ((jQuery.event.special[type] || {}).delegateType) {
5420            event.stopPropagation();
5421          }
5422
5423          // If this is a native event triggered above, everything is now in order
5424          // Fire an inner synthetic event with the original arguments
5425        } else if (saved) {
5426
5427          // ...and capture the result
5428          dataPriv.set(this, type, jQuery.event.trigger(
5429            saved[0],
5430            saved.slice(1),
5431            this
5432          ));
5433
5434          // Abort handling of the native event by all jQuery handlers while allowing
5435          // native handlers on the same element to run. On target, this is achieved
5436          // by stopping immediate propagation just on the jQuery event. However,
5437          // the native event is re-wrapped by a jQuery one on each level of the
5438          // propagation so the only way to stop it for jQuery is to stop it for
5439          // everyone via native `stopPropagation()`. This is not a problem for
5440          // focus/blur which don't bubble, but it does also stop click on checkboxes
5441          // and radios. We accept this limitation.
5442          event.stopPropagation();
5443          event.isImmediatePropagationStopped = returnTrue;
5444        }
5445      }
5446    });
5447  }
5448
5449  jQuery.removeEvent = function (elem, type, handle) {
5450
5451    // This "if" is needed for plain objects
5452    if (elem.removeEventListener) {
5453      elem.removeEventListener(type, handle);
5454    }
5455  };
5456
5457  jQuery.Event = function (src, props) {
5458
5459    // Allow instantiation without the 'new' keyword
5460    if (!(this instanceof jQuery.Event)) {
5461      return new jQuery.Event(src, props);
5462    }
5463
5464    // Event object
5465    if (src && src.type) {
5466      this.originalEvent = src;
5467      this.type = src.type;
5468
5469      // Events bubbling up the document may have been marked as prevented
5470      // by a handler lower down the tree; reflect the correct value.
5471      this.isDefaultPrevented = src.defaultPrevented ||
5472      src.defaultPrevented === undefined &&
5473
5474      // Support: Android <=2.3 only
5475      src.returnValue === false ?
5476      returnTrue :
5477      returnFalse;
5478
5479      // Create target properties
5480      // Support: Safari <=6 - 7 only
5481      // Target should not be a text node (trac-504, trac-13143)
5482      this.target = src.target && src.target.nodeType === 3 ?
5483      src.target.parentNode :
5484      src.target;
5485
5486      this.currentTarget = src.currentTarget;
5487      this.relatedTarget = src.relatedTarget;
5488
5489      // Event type
5490    } else {
5491      this.type = src;
5492    }
5493
5494    // Put explicitly provided properties onto the event object
5495    if (props) {
5496      jQuery.extend(this, props);
5497    }
5498
5499    // Create a timestamp if incoming event doesn't have one
5500    this.timeStamp = src && src.timeStamp || Date.now();
5501
5502    // Mark it as fixed
5503    this[jQuery.expando] = true;
5504  };
5505
5506  // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5507  // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5508  jQuery.Event.prototype = {
5509    constructor: jQuery.Event,
5510    isDefaultPrevented: returnFalse,
5511    isPropagationStopped: returnFalse,
5512    isImmediatePropagationStopped: returnFalse,
5513    isSimulated: false,
5514
5515    preventDefault: function () {
5516      var e = this.originalEvent;
5517
5518      this.isDefaultPrevented = returnTrue;
5519
5520      if (e && !this.isSimulated) {
5521        e.preventDefault();
5522      }
5523    },
5524    stopPropagation: function () {
5525      var e = this.originalEvent;
5526
5527      this.isPropagationStopped = returnTrue;
5528
5529      if (e && !this.isSimulated) {
5530        e.stopPropagation();
5531      }
5532    },
5533    stopImmediatePropagation: function () {
5534      var e = this.originalEvent;
5535
5536      this.isImmediatePropagationStopped = returnTrue;
5537
5538      if (e && !this.isSimulated) {
5539        e.stopImmediatePropagation();
5540      }
5541
5542      this.stopPropagation();
5543    }
5544  };
5545
5546  // Includes all common event props including KeyEvent and MouseEvent specific props
5547  jQuery.each({
5548    altKey: true,
5549    bubbles: true,
5550    cancelable: true,
5551    changedTouches: true,
5552    ctrlKey: true,
5553    detail: true,
5554    eventPhase: true,
5555    metaKey: true,
5556    pageX: true,
5557    pageY: true,
5558    shiftKey: true,
5559    view: true,
5560    "char": true,
5561    code: true,
5562    charCode: true,
5563    key: true,
5564    keyCode: true,
5565    button: true,
5566    buttons: true,
5567    clientX: true,
5568    clientY: true,
5569    offsetX: true,
5570    offsetY: true,
5571    pointerId: true,
5572    pointerType: true,
5573    screenX: true,
5574    screenY: true,
5575    targetTouches: true,
5576    toElement: true,
5577    touches: true,
5578    which: true
5579  }, jQuery.event.addProp);
5580
5581  jQuery.each({ focus: "focusin", blur: "focusout" }, function (type, delegateType) {
5582
5583    function focusMappedHandler(nativeEvent) {
5584      if (document.documentMode) {
5585
5586        // Support: IE 11+
5587        // Attach a single focusin/focusout handler on the document while someone wants
5588        // focus/blur. This is because the former are synchronous in IE while the latter
5589        // are async. In other browsers, all those handlers are invoked synchronously.
5590
5591        // `handle` from private data would already wrap the event, but we need
5592        // to change the `type` here.
5593        var handle = dataPriv.get(this, "handle"),
5594          event = jQuery.event.fix(nativeEvent);
5595        event.type = nativeEvent.type === "focusin" ? "focus" : "blur";
5596        event.isSimulated = true;
5597
5598        // First, handle focusin/focusout
5599        handle(nativeEvent);
5600
5601        // ...then, handle focus/blur
5602        //
5603        // focus/blur don't bubble while focusin/focusout do; simulate the former by only
5604        // invoking the handler at the lower level.
5605        if (event.target === event.currentTarget) {
5606
5607          // The setup part calls `leverageNative`, which, in turn, calls
5608          // `jQuery.event.add`, so event handle will already have been set
5609          // by this point.
5610          handle(event);
5611        }
5612      } else {
5613
5614        // For non-IE browsers, attach a single capturing handler on the document
5615        // while someone wants focusin/focusout.
5616        jQuery.event.simulate(delegateType, nativeEvent.target,
5617        jQuery.event.fix(nativeEvent));
5618      }
5619    }
5620
5621    jQuery.event.special[type] = {
5622
5623      // Utilize native event if possible so blur/focus sequence is correct
5624      setup: function () {
5625
5626        var attaches;
5627
5628        // Claim the first handler
5629        // dataPriv.set( this, "focus", ... )
5630        // dataPriv.set( this, "blur", ... )
5631        leverageNative(this, type, true);
5632
5633        if (document.documentMode) {
5634
5635          // Support: IE 9 - 11+
5636          // We use the same native handler for focusin & focus (and focusout & blur)
5637          // so we need to coordinate setup & teardown parts between those events.
5638          // Use `delegateType` as the key as `type` is already used by `leverageNative`.
5639          attaches = dataPriv.get(this, delegateType);
5640          if (!attaches) {
5641            this.addEventListener(delegateType, focusMappedHandler);
5642          }
5643          dataPriv.set(this, delegateType, (attaches || 0) + 1);
5644        } else {
5645
5646          // Return false to allow normal processing in the caller
5647          return false;
5648        }
5649      },
5650      trigger: function () {
5651
5652        // Force setup before trigger
5653        leverageNative(this, type);
5654
5655        // Return non-false to allow normal event-path propagation
5656        return true;
5657      },
5658
5659      teardown: function () {
5660        var attaches;
5661
5662        if (document.documentMode) {
5663          attaches = dataPriv.get(this, delegateType) - 1;
5664          if (!attaches) {
5665            this.removeEventListener(delegateType, focusMappedHandler);
5666            dataPriv.remove(this, delegateType);
5667          } else {
5668            dataPriv.set(this, delegateType, attaches);
5669          }
5670        } else {
5671
5672          // Return false to indicate standard teardown should be applied
5673          return false;
5674        }
5675      },
5676
5677      // Suppress native focus or blur if we're currently inside
5678      // a leveraged native-event stack
5679      _default: function (event) {
5680        return dataPriv.get(event.target, type);
5681      },
5682
5683      delegateType: delegateType
5684    };
5685
5686    // Support: Firefox <=44
5687    // Firefox doesn't have focus(in | out) events
5688    // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
5689    //
5690    // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
5691    // focus(in | out) events fire after focus & blur events,
5692    // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
5693    // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
5694    //
5695    // Support: IE 9 - 11+
5696    // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch,
5697    // attach a single handler for both events in IE.
5698    jQuery.event.special[delegateType] = {
5699      setup: function () {
5700
5701        // Handle: regular nodes (via `this.ownerDocument`), window
5702        // (via `this.document`) & document (via `this`).
5703        var doc = this.ownerDocument || this.document || this,
5704          dataHolder = document.documentMode ? this : doc,
5705          attaches = dataPriv.get(dataHolder, delegateType);
5706
5707        // Support: IE 9 - 11+
5708        // We use the same native handler for focusin & focus (and focusout & blur)
5709        // so we need to coordinate setup & teardown parts between those events.
5710        // Use `delegateType` as the key as `type` is already used by `leverageNative`.
5711        if (!attaches) {
5712          if (document.documentMode) {
5713            this.addEventListener(delegateType, focusMappedHandler);
5714          } else {
5715            doc.addEventListener(type, focusMappedHandler, true);
5716          }
5717        }
5718        dataPriv.set(dataHolder, delegateType, (attaches || 0) + 1);
5719      },
5720      teardown: function () {
5721        var doc = this.ownerDocument || this.document || this,
5722          dataHolder = document.documentMode ? this : doc,
5723          attaches = dataPriv.get(dataHolder, delegateType) - 1;
5724
5725        if (!attaches) {
5726          if (document.documentMode) {
5727            this.removeEventListener(delegateType, focusMappedHandler);
5728          } else {
5729            doc.removeEventListener(type, focusMappedHandler, true);
5730          }
5731          dataPriv.remove(dataHolder, delegateType);
5732        } else {
5733          dataPriv.set(dataHolder, delegateType, attaches);
5734        }
5735      }
5736    };
5737  });
5738
5739  // Create mouseenter/leave events using mouseover/out and event-time checks
5740  // so that event delegation works in jQuery.
5741  // Do the same for pointerenter/pointerleave and pointerover/pointerout
5742  //
5743  // Support: Safari 7 only
5744  // Safari sends mouseenter too often; see:
5745  // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5746  // for the description of the bug (it existed in older Chrome versions as well).
5747  jQuery.each({
5748    mouseenter: "mouseover",
5749    mouseleave: "mouseout",
5750    pointerenter: "pointerover",
5751    pointerleave: "pointerout"
5752  }, function (orig, fix) {
5753    jQuery.event.special[orig] = {
5754      delegateType: fix,
5755      bindType: fix,
5756
5757      handle: function (event) {
5758        var ret,
5759          target = this,
5760          related = event.relatedTarget,
5761          handleObj = event.handleObj;
5762
5763        // For mouseenter/leave call the handler if related is outside the target.
5764        // NB: No relatedTarget if the mouse left/entered the browser window
5765        if (!related || related !== target && !jQuery.contains(target, related)) {
5766          event.type = handleObj.origType;
5767          ret = handleObj.handler.apply(this, arguments);
5768          event.type = fix;
5769        }
5770        return ret;
5771      }
5772    };
5773  });
5774
5775  jQuery.fn.extend({
5776
5777    on: function (types, selector, data, fn) {
5778      return on(this, types, selector, data, fn);
5779    },
5780    one: function (types, selector, data, fn) {
5781      return on(this, types, selector, data, fn, 1);
5782    },
5783    off: function (types, selector, fn) {
5784      var handleObj, type;
5785      if (types && types.preventDefault && types.handleObj) {
5786
5787        // ( event )  dispatched jQuery.Event
5788        handleObj = types.handleObj;
5789        jQuery(types.delegateTarget).off(
5790          handleObj.namespace ?
5791          handleObj.origType + "." + handleObj.namespace :
5792          handleObj.origType,
5793          handleObj.selector,
5794          handleObj.handler
5795        );
5796        return this;
5797      }
5798      if (typeof types === "object") {
5799
5800        // ( types-object [, selector] )
5801        for (type in types) {
5802          this.off(type, selector, types[type]);
5803        }
5804        return this;
5805      }
5806      if (selector === false || typeof selector === "function") {
5807
5808        // ( types [, fn] )
5809        fn = selector;
5810        selector = undefined;
5811      }
5812      if (fn === false) {
5813        fn = returnFalse;
5814      }
5815      return this.each(function () {
5816        jQuery.event.remove(this, types, fn, selector);
5817      });
5818    }
5819  });
5820
5821
5822  var
5823
5824    // Support: IE <=10 - 11, Edge 12 - 13 only
5825    // In IE/Edge using regex groups here causes severe slowdowns.
5826    // See https://connect.microsoft.com/IE/feedback/details/1736512/
5827    rnoInnerhtml = /<script|<style|<link/i,
5828
5829    // checked="checked" or checked
5830    rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5831
5832    rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g;
5833
5834  // Prefer a tbody over its parent table for containing new rows
5835  function manipulationTarget(elem, content) {
5836    if (nodeName(elem, "table") &&
5837    nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) {
5838
5839      return jQuery(elem).children("tbody")[0] || elem;
5840    }
5841
5842    return elem;
5843  }
5844
5845  // Replace/restore the type attribute of script elements for safe DOM manipulation
5846  function disableScript(elem) {
5847    elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
5848    return elem;
5849  }
5850  function restoreScript(elem) {
5851    if ((elem.type || "").slice(0, 5) === "true/") {
5852      elem.type = elem.type.slice(5);
5853    } else {
5854      elem.removeAttribute("type");
5855    }
5856
5857    return elem;
5858  }
5859
5860  function cloneCopyEvent(src, dest) {
5861    var i, l, type, pdataOld, udataOld, udataCur, events;
5862
5863    if (dest.nodeType !== 1) {
5864      return;
5865    }
5866
5867    // 1. Copy private data: events, handlers, etc.
5868    if (dataPriv.hasData(src)) {
5869      pdataOld = dataPriv.get(src);
5870      events = pdataOld.events;
5871
5872      if (events) {
5873        dataPriv.remove(dest, "handle events");
5874
5875        for (type in events) {
5876          for (i = 0, l = events[type].length; i < l; i++) {
5877            jQuery.event.add(dest, type, events[type][i]);
5878          }
5879        }
5880      }
5881    }
5882
5883    // 2. Copy user data
5884    if (dataUser.hasData(src)) {
5885      udataOld = dataUser.access(src);
5886      udataCur = jQuery.extend({}, udataOld);
5887
5888      dataUser.set(dest, udataCur);
5889    }
5890  }
5891
5892  // Fix IE bugs, see support tests
5893  function fixInput(src, dest) {
5894    var nodeName = dest.nodeName.toLowerCase();
5895
5896    // Fails to persist the checked state of a cloned checkbox or radio button.
5897    if (nodeName === "input" && rcheckableType.test(src.type)) {
5898      dest.checked = src.checked;
5899
5900      // Fails to return the selected option to the default selected state when cloning options
5901    } else if (nodeName === "input" || nodeName === "textarea") {
5902      dest.defaultValue = src.defaultValue;
5903    }
5904  }
5905
5906  function domManip(collection, args, callback, ignored) {
5907
5908    // Flatten any nested arrays
5909    args = flat(args);
5910
5911    var fragment,first,scripts,hasScripts,node,doc,
5912      i = 0,
5913      l = collection.length,
5914      iNoClone = l - 1,
5915      value = args[0],
5916      valueIsFunction = isFunction(value);
5917
5918    // We can't cloneNode fragments that contain checked, in WebKit
5919    if (valueIsFunction ||
5920    l > 1 && typeof value === "string" &&
5921    !support.checkClone && rchecked.test(value)) {
5922      return collection.each(function (index) {
5923        var self = collection.eq(index);
5924        if (valueIsFunction) {
5925          args[0] = value.call(this, index, self.html());
5926        }
5927        domManip(self, args, callback, ignored);
5928      });
5929    }
5930
5931    if (l) {
5932      fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);
5933      first = fragment.firstChild;
5934
5935      if (fragment.childNodes.length === 1) {
5936        fragment = first;
5937      }
5938
5939      // Require either new content or an interest in ignored elements to invoke the callback
5940      if (first || ignored) {
5941        scripts = jQuery.map(getAll(fragment, "script"), disableScript);
5942        hasScripts = scripts.length;
5943
5944        // Use the original fragment for the last item
5945        // instead of the first because it can end up
5946        // being emptied incorrectly in certain situations (trac-8070).
5947        for (; i < l; i++) {
5948          node = fragment;
5949
5950          if (i !== iNoClone) {
5951            node = jQuery.clone(node, true, true);
5952
5953            // Keep references to cloned scripts for later restoration
5954            if (hasScripts) {
5955
5956              // Support: Android <=4.0 only, PhantomJS 1 only
5957              // push.apply(_, arraylike) throws on ancient WebKit
5958              jQuery.merge(scripts, getAll(node, "script"));
5959            }
5960          }
5961
5962          callback.call(collection[i], node, i);
5963        }
5964
5965        if (hasScripts) {
5966          doc = scripts[scripts.length - 1].ownerDocument;
5967
5968          // Re-enable scripts
5969          jQuery.map(scripts, restoreScript);
5970
5971          // Evaluate executable scripts on first document insertion
5972          for (i = 0; i < hasScripts; i++) {
5973            node = scripts[i];
5974            if (rscriptType.test(node.type || "") &&
5975            !dataPriv.access(node, "globalEval") &&
5976            jQuery.contains(doc, node)) {
5977
5978              if (node.src && (node.type || "").toLowerCase() !== "module") {
5979
5980                // Optional AJAX dependency, but won't run scripts if not present
5981                if (jQuery._evalUrl && !node.noModule) {
5982                  jQuery._evalUrl(node.src, {
5983                    nonce: node.nonce || node.getAttribute("nonce")
5984                  }, doc);
5985                }
5986              } else {
5987
5988                // Unwrap a CDATA section containing script contents. This shouldn't be
5989                // needed as in XML documents they're already not visible when
5990                // inspecting element contents and in HTML documents they have no
5991                // meaning but we're preserving that logic for backwards compatibility.
5992                // This will be removed completely in 4.0. See gh-4904.
5993                DOMEval(node.textContent.replace(rcleanScript, ""), node, doc);
5994              }
5995            }
5996          }
5997        }
5998      }
5999    }
6000
6001    return collection;
6002  }
6003
6004  function remove(elem, selector, keepData) {
6005    var node,
6006      nodes = selector ? jQuery.filter(selector, elem) : elem,
6007      i = 0;
6008
6009    for (; (node = nodes[i]) != null; i++) {
6010      if (!keepData && node.nodeType === 1) {
6011        jQuery.cleanData(getAll(node));
6012      }
6013
6014      if (node.parentNode) {
6015        if (keepData && isAttached(node)) {
6016          setGlobalEval(getAll(node, "script"));
6017        }
6018        node.parentNode.removeChild(node);
6019      }
6020    }
6021
6022    return elem;
6023  }
6024
6025  jQuery.extend({
6026    htmlPrefilter: function (html) {
6027      return html;
6028    },
6029
6030    clone: function (elem, dataAndEvents, deepDataAndEvents) {
6031      var i,l,srcElements,destElements,
6032        clone = elem.cloneNode(true),
6033        inPage = isAttached(elem);
6034
6035      // Fix IE cloning issues
6036      if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) &&
6037      !jQuery.isXMLDoc(elem)) {
6038
6039        // We eschew jQuery#find here for performance reasons:
6040        // https://jsperf.com/getall-vs-sizzle/2
6041        destElements = getAll(clone);
6042        srcElements = getAll(elem);
6043
6044        for (i = 0, l = srcElements.length; i < l; i++) {
6045          fixInput(srcElements[i], destElements[i]);
6046        }
6047      }
6048
6049      // Copy the events from the original to the clone
6050      if (dataAndEvents) {
6051        if (deepDataAndEvents) {
6052          srcElements = srcElements || getAll(elem);
6053          destElements = destElements || getAll(clone);
6054
6055          for (i = 0, l = srcElements.length; i < l; i++) {
6056            cloneCopyEvent(srcElements[i], destElements[i]);
6057          }
6058        } else {
6059          cloneCopyEvent(elem, clone);
6060        }
6061      }
6062
6063      // Preserve script evaluation history
6064      destElements = getAll(clone, "script");
6065      if (destElements.length > 0) {
6066        setGlobalEval(destElements, !inPage && getAll(elem, "script"));
6067      }
6068
6069      // Return the cloned set
6070      return clone;
6071    },
6072
6073    cleanData: function (elems) {
6074      var data,elem,type,
6075        special = jQuery.event.special,
6076        i = 0;
6077
6078      for (; (elem = elems[i]) !== undefined; i++) {
6079        if (acceptData(elem)) {
6080          if (data = elem[dataPriv.expando]) {
6081            if (data.events) {
6082              for (type in data.events) {
6083                if (special[type]) {
6084                  jQuery.event.remove(elem, type);
6085
6086                  // This is a shortcut to avoid jQuery.event.remove's overhead
6087                } else {
6088                  jQuery.removeEvent(elem, type, data.handle);
6089                }
6090              }
6091            }
6092
6093            // Support: Chrome <=35 - 45+
6094            // Assign undefined instead of using delete, see Data#remove
6095            elem[dataPriv.expando] = undefined;
6096          }
6097          if (elem[dataUser.expando]) {
6098
6099            // Support: Chrome <=35 - 45+
6100            // Assign undefined instead of using delete, see Data#remove
6101            elem[dataUser.expando] = undefined;
6102          }
6103        }
6104      }
6105    }
6106  });
6107
6108  jQuery.fn.extend({
6109    detach: function (selector) {
6110      return remove(this, selector, true);
6111    },
6112
6113    remove: function (selector) {
6114      return remove(this, selector);
6115    },
6116
6117    text: function (value) {
6118      return access(this, function (value) {
6119        return value === undefined ?
6120        jQuery.text(this) :
6121        this.empty().each(function () {
6122          if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
6123            this.textContent = value;
6124          }
6125        });
6126      }, null, value, arguments.length);
6127    },
6128
6129    append: function () {
6130      return domManip(this, arguments, function (elem) {
6131        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
6132          var target = manipulationTarget(this, elem);
6133          target.appendChild(elem);
6134        }
6135      });
6136    },
6137
6138    prepend: function () {
6139      return domManip(this, arguments, function (elem) {
6140        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
6141          var target = manipulationTarget(this, elem);
6142          target.insertBefore(elem, target.firstChild);
6143        }
6144      });
6145    },
6146
6147    before: function () {
6148      return domManip(this, arguments, function (elem) {
6149        if (this.parentNode) {
6150          this.parentNode.insertBefore(elem, this);
6151        }
6152      });
6153    },
6154
6155    after: function () {
6156      return domManip(this, arguments, function (elem) {
6157        if (this.parentNode) {
6158          this.parentNode.insertBefore(elem, this.nextSibling);
6159        }
6160      });
6161    },
6162
6163    empty: function () {
6164      var elem,
6165        i = 0;
6166
6167      for (; (elem = this[i]) != null; i++) {
6168        if (elem.nodeType === 1) {
6169
6170          // Prevent memory leaks
6171          jQuery.cleanData(getAll(elem, false));
6172
6173          // Remove any remaining nodes
6174          elem.textContent = "";
6175        }
6176      }
6177
6178      return this;
6179    },
6180
6181    clone: function (dataAndEvents, deepDataAndEvents) {
6182      dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6183      deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6184
6185      return this.map(function () {
6186        return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
6187      });
6188    },
6189
6190    html: function (value) {
6191      return access(this, function (value) {
6192        var elem = this[0] || {},
6193          i = 0,
6194          l = this.length;
6195
6196        if (value === undefined && elem.nodeType === 1) {
6197          return elem.innerHTML;
6198        }
6199
6200        // See if we can take a shortcut and just use innerHTML
6201        if (typeof value === "string" && !rnoInnerhtml.test(value) &&
6202        !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
6203
6204          value = jQuery.htmlPrefilter(value);
6205
6206          try {
6207            for (; i < l; i++) {
6208              elem = this[i] || {};
6209
6210              // Remove element nodes and prevent memory leaks
6211              if (elem.nodeType === 1) {
6212                jQuery.cleanData(getAll(elem, false));
6213                elem.innerHTML = value;
6214              }
6215            }
6216
6217            elem = 0;
6218
6219            // If using innerHTML throws an exception, use the fallback method
6220          } catch (e) {}
6221        }
6222
6223        if (elem) {
6224          this.empty().append(value);
6225        }
6226      }, null, value, arguments.length);
6227    },
6228
6229    replaceWith: function () {
6230      var ignored = [];
6231
6232      // Make the changes, replacing each non-ignored context element with the new content
6233      return domManip(this, arguments, function (elem) {
6234        var parent = this.parentNode;
6235
6236        if (jQuery.inArray(this, ignored) < 0) {
6237          jQuery.cleanData(getAll(this));
6238          if (parent) {
6239            parent.replaceChild(elem, this);
6240          }
6241        }
6242
6243        // Force callback invocation
6244      }, ignored);
6245    }
6246  });
6247
6248  jQuery.each({
6249    appendTo: "append",
6250    prependTo: "prepend",
6251    insertBefore: "before",
6252    insertAfter: "after",
6253    replaceAll: "replaceWith"
6254  }, function (name, original) {
6255    jQuery.fn[name] = function (selector) {
6256      var elems,
6257        ret = [],
6258        insert = jQuery(selector),
6259        last = insert.length - 1,
6260        i = 0;
6261
6262      for (; i <= last; i++) {
6263        elems = i === last ? this : this.clone(true);
6264        jQuery(insert[i])[original](elems);
6265
6266        // Support: Android <=4.0 only, PhantomJS 1 only
6267        // .get() because push.apply(_, arraylike) throws on ancient WebKit
6268        push.apply(ret, elems.get());
6269      }
6270
6271      return this.pushStack(ret);
6272    };
6273  });
6274  var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
6275
6276  var rcustomProp = /^--/;
6277
6278
6279  var getStyles = function (elem) {
6280
6281    // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150)
6282    // IE throws on elements created in popups
6283    // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6284    var view = elem.ownerDocument.defaultView;
6285
6286    if (!view || !view.opener) {
6287      view = window;
6288    }
6289
6290    return view.getComputedStyle(elem);
6291  };
6292
6293  var swap = function (elem, options, callback) {
6294    var ret,name,
6295      old = {};
6296
6297    // Remember the old values, and insert the new ones
6298    for (name in options) {
6299      old[name] = elem.style[name];
6300      elem.style[name] = options[name];
6301    }
6302
6303    ret = callback.call(elem);
6304
6305    // Revert the old values
6306    for (name in options) {
6307      elem.style[name] = old[name];
6308    }
6309
6310    return ret;
6311  };
6312
6313
6314  var rboxStyle = new RegExp(cssExpand.join("|"), "i");
6315
6316
6317
6318  (function () {
6319
6320    // Executing both pixelPosition & boxSizingReliable tests require only one layout
6321    // so they're executed at the same time to save the second computation.
6322    function computeStyleTests() {
6323
6324      // This is a singleton, we need to execute it only once
6325      if (!div) {
6326        return;
6327      }
6328
6329      container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
6330      "margin-top:1px;padding:0;border:0";
6331      div.style.cssText =
6332      "position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
6333      "margin:auto;border:1px;padding:1px;" +
6334      "width:60%;top:1%";
6335      documentElement.appendChild(container).appendChild(div);
6336
6337      var divStyle = window.getComputedStyle(div);
6338      pixelPositionVal = divStyle.top !== "1%";
6339
6340      // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6341      reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12;
6342
6343      // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
6344      // Some styles come back with percentage values, even though they shouldn't
6345      div.style.right = "60%";
6346      pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36;
6347
6348      // Support: IE 9 - 11 only
6349      // Detect misreporting of content dimensions for box-sizing:border-box elements
6350      boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36;
6351
6352      // Support: IE 9 only
6353      // Detect overflow:scroll screwiness (gh-3699)
6354      // Support: Chrome <=64
6355      // Don't get tricked when zoom affects offsetWidth (gh-4029)
6356      div.style.position = "absolute";
6357      scrollboxSizeVal = roundPixelMeasures(div.offsetWidth / 3) === 12;
6358
6359      documentElement.removeChild(container);
6360
6361      // Nullify the div so it wouldn't be stored in the memory and
6362      // it will also be a sign that checks already performed
6363      div = null;
6364    }
6365
6366    function roundPixelMeasures(measure) {
6367      return Math.round(parseFloat(measure));
6368    }
6369
6370    var pixelPositionVal,boxSizingReliableVal,scrollboxSizeVal,pixelBoxStylesVal,
6371      reliableTrDimensionsVal,reliableMarginLeftVal,
6372      container = document.createElement("div"),
6373      div = document.createElement("div");
6374
6375    // Finish early in limited (non-browser) environments
6376    if (!div.style) {
6377      return;
6378    }
6379
6380    // Support: IE <=9 - 11 only
6381    // Style of cloned element affects source element cloned (trac-8908)
6382    div.style.backgroundClip = "content-box";
6383    div.cloneNode(true).style.backgroundClip = "";
6384    support.clearCloneStyle = div.style.backgroundClip === "content-box";
6385
6386    jQuery.extend(support, {
6387      boxSizingReliable: function () {
6388        computeStyleTests();
6389        return boxSizingReliableVal;
6390      },
6391      pixelBoxStyles: function () {
6392        computeStyleTests();
6393        return pixelBoxStylesVal;
6394      },
6395      pixelPosition: function () {
6396        computeStyleTests();
6397        return pixelPositionVal;
6398      },
6399      reliableMarginLeft: function () {
6400        computeStyleTests();
6401        return reliableMarginLeftVal;
6402      },
6403      scrollboxSize: function () {
6404        computeStyleTests();
6405        return scrollboxSizeVal;
6406      },
6407
6408      // Support: IE 9 - 11+, Edge 15 - 18+
6409      // IE/Edge misreport `getComputedStyle` of table rows with width/height
6410      // set in CSS while `offset*` properties report correct values.
6411      // Behavior in IE 9 is more subtle than in newer versions & it passes
6412      // some versions of this test; make sure not to make it pass there!
6413      //
6414      // Support: Firefox 70+
6415      // Only Firefox includes border widths
6416      // in computed dimensions. (gh-4529)
6417      reliableTrDimensions: function () {
6418        var table, tr, trChild, trStyle;
6419        if (reliableTrDimensionsVal == null) {
6420          table = document.createElement("table");
6421          tr = document.createElement("tr");
6422          trChild = document.createElement("div");
6423
6424          table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
6425          tr.style.cssText = "box-sizing:content-box;border:1px solid";
6426
6427          // Support: Chrome 86+
6428          // Height set through cssText does not get applied.
6429          // Computed height then comes back as 0.
6430          tr.style.height = "1px";
6431          trChild.style.height = "9px";
6432
6433          // Support: Android 8 Chrome 86+
6434          // In our bodyBackground.html iframe,
6435          // display for all div elements is set to "inline",
6436          // which causes a problem only in Android 8 Chrome 86.
6437          // Ensuring the div is `display: block`
6438          // gets around this issue.
6439          trChild.style.display = "block";
6440
6441          documentElement.
6442          appendChild(table).
6443          appendChild(tr).
6444          appendChild(trChild);
6445
6446          trStyle = window.getComputedStyle(tr);
6447          reliableTrDimensionsVal = parseInt(trStyle.height, 10) +
6448          parseInt(trStyle.borderTopWidth, 10) +
6449          parseInt(trStyle.borderBottomWidth, 10) === tr.offsetHeight;
6450
6451          documentElement.removeChild(table);
6452        }
6453        return reliableTrDimensionsVal;
6454      }
6455    });
6456  })();
6457
6458
6459  function curCSS(elem, name, computed) {
6460    var width,minWidth,maxWidth,ret,
6461      isCustomProp = rcustomProp.test(name),
6462
6463      // Support: Firefox 51+
6464      // Retrieving style before computed somehow
6465      // fixes an issue with getting wrong values
6466      // on detached elements
6467      style = elem.style;
6468
6469    computed = computed || getStyles(elem);
6470
6471    // getPropertyValue is needed for:
6472    //   .css('filter') (IE 9 only, trac-12537)
6473    //   .css('--customProperty) (gh-3144)
6474    if (computed) {
6475
6476      // Support: IE <=9 - 11+
6477      // IE only supports `"float"` in `getPropertyValue`; in computed styles
6478      // it's only available as `"cssFloat"`. We no longer modify properties
6479      // sent to `.css()` apart from camelCasing, so we need to check both.
6480      // Normally, this would create difference in behavior: if
6481      // `getPropertyValue` returns an empty string, the value returned
6482      // by `.css()` would be `undefined`. This is usually the case for
6483      // disconnected elements. However, in IE even disconnected elements
6484      // with no styles return `"none"` for `getPropertyValue( "float" )`
6485      ret = computed.getPropertyValue(name) || computed[name];
6486
6487      if (isCustomProp && ret) {
6488
6489        // Support: Firefox 105+, Chrome <=105+
6490        // Spec requires trimming whitespace for custom properties (gh-4926).
6491        // Firefox only trims leading whitespace. Chrome just collapses
6492        // both leading & trailing whitespace to a single space.
6493        //
6494        // Fall back to `undefined` if empty string returned.
6495        // This collapses a missing definition with property defined
6496        // and set to an empty string but there's no standard API
6497        // allowing us to differentiate them without a performance penalty
6498        // and returning `undefined` aligns with older jQuery.
6499        //
6500        // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED
6501        // as whitespace while CSS does not, but this is not a problem
6502        // because CSS preprocessing replaces them with U+000A LINE FEED
6503        // (which *is* CSS whitespace)
6504        // https://www.w3.org/TR/css-syntax-3/#input-preprocessing
6505        ret = ret.replace(rtrimCSS, "$1") || undefined;
6506      }
6507
6508      if (ret === "" && !isAttached(elem)) {
6509        ret = jQuery.style(elem, name);
6510      }
6511
6512      // A tribute to the "awesome hack by Dean Edwards"
6513      // Android Browser returns percentage for some values,
6514      // but width seems to be reliably pixels.
6515      // This is against the CSSOM draft spec:
6516      // https://drafts.csswg.org/cssom/#resolved-values
6517      if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) {
6518
6519        // Remember the original values
6520        width = style.width;
6521        minWidth = style.minWidth;
6522        maxWidth = style.maxWidth;
6523
6524        // Put in the new values to get a computed value out
6525        style.minWidth = style.maxWidth = style.width = ret;
6526        ret = computed.width;
6527
6528        // Revert the changed values
6529        style.width = width;
6530        style.minWidth = minWidth;
6531        style.maxWidth = maxWidth;
6532      }
6533    }
6534
6535    return ret !== undefined ?
6536
6537    // Support: IE <=9 - 11 only
6538    // IE returns zIndex value as an integer.
6539    ret + "" :
6540    ret;
6541  }
6542
6543
6544  function addGetHookIf(conditionFn, hookFn) {
6545
6546    // Define the hook, we'll check on the first run if it's really needed.
6547    return {
6548      get: function () {
6549        if (conditionFn()) {
6550
6551          // Hook not needed (or it's not possible to use it due
6552          // to missing dependency), remove it.
6553          delete this.get;
6554          return;
6555        }
6556
6557        // Hook needed; redefine it so that the support test is not executed again.
6558        return (this.get = hookFn).apply(this, arguments);
6559      }
6560    };
6561  }
6562
6563
6564  var cssPrefixes = ["Webkit", "Moz", "ms"],
6565    emptyStyle = document.createElement("div").style,
6566    vendorProps = {};
6567
6568  // Return a vendor-prefixed property or undefined
6569  function vendorPropName(name) {
6570
6571    // Check for vendor prefixed names
6572    var capName = name[0].toUpperCase() + name.slice(1),
6573      i = cssPrefixes.length;
6574
6575    while (i--) {
6576      name = cssPrefixes[i] + capName;
6577      if (name in emptyStyle) {
6578        return name;
6579      }
6580    }
6581  }
6582
6583  // Return a potentially-mapped jQuery.cssProps or vendor prefixed property
6584  function finalPropName(name) {
6585    var final = jQuery.cssProps[name] || vendorProps[name];
6586
6587    if (final) {
6588      return final;
6589    }
6590    if (name in emptyStyle) {
6591      return name;
6592    }
6593    return vendorProps[name] = vendorPropName(name) || name;
6594  }
6595
6596
6597  var
6598
6599    // Swappable if display is none or starts with table
6600    // except "table", "table-cell", or "table-caption"
6601    // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6602    rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6603    cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6604    cssNormalTransform = {
6605      letterSpacing: "0",
6606      fontWeight: "400"
6607    };
6608
6609  function setPositiveNumber(_elem, value, subtract) {
6610
6611    // Any relative (+/-) values have already been
6612    // normalized at this point
6613    var matches = rcssNum.exec(value);
6614    return matches ?
6615
6616    // Guard against undefined "subtract", e.g., when used as in cssHooks
6617    Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") :
6618    value;
6619  }
6620
6621  function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) {
6622    var i = dimension === "width" ? 1 : 0,
6623      extra = 0,
6624      delta = 0,
6625      marginDelta = 0;
6626
6627    // Adjustment may not be necessary
6628    if (box === (isBorderBox ? "border" : "content")) {
6629      return 0;
6630    }
6631
6632    for (; i < 4; i += 2) {
6633
6634      // Both box models exclude margin
6635      // Count margin delta separately to only add it after scroll gutter adjustment.
6636      // This is needed to make negative margins work with `outerHeight( true )` (gh-3982).
6637      if (box === "margin") {
6638        marginDelta += jQuery.css(elem, box + cssExpand[i], true, styles);
6639      }
6640
6641      // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
6642      if (!isBorderBox) {
6643
6644        // Add padding
6645        delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
6646
6647        // For "border" or "margin", add border
6648        if (box !== "padding") {
6649          delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6650
6651          // But still keep track of it otherwise
6652        } else {
6653          extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6654        }
6655
6656        // If we get here with a border-box (content + padding + border), we're seeking "content" or
6657        // "padding" or "margin"
6658      } else {
6659
6660        // For "content", subtract padding
6661        if (box === "content") {
6662          delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
6663        }
6664
6665        // For "content" or "padding", subtract border
6666        if (box !== "margin") {
6667          delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6668        }
6669      }
6670    }
6671
6672    // Account for positive content-box scroll gutter when requested by providing computedVal
6673    if (!isBorderBox && computedVal >= 0) {
6674
6675      // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
6676      // Assuming integer scroll gutter, subtract the rest and round down
6677      delta += Math.max(0, Math.ceil(
6678        elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] -
6679        computedVal -
6680        delta -
6681        extra -
6682        0.5
6683
6684        // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
6685        // Use an explicit zero to avoid NaN (gh-3964)
6686      )) || 0;
6687    }
6688
6689    return delta + marginDelta;
6690  }
6691
6692  function getWidthOrHeight(elem, dimension, extra) {
6693
6694    // Start with computed style
6695    var styles = getStyles(elem),
6696
6697      // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
6698      // Fake content-box until we know it's needed to know the true value.
6699      boxSizingNeeded = !support.boxSizingReliable() || extra,
6700      isBorderBox = boxSizingNeeded &&
6701      jQuery.css(elem, "boxSizing", false, styles) === "border-box",
6702      valueIsBorderBox = isBorderBox,
6703
6704      val = curCSS(elem, dimension, styles),
6705      offsetProp = "offset" + dimension[0].toUpperCase() + dimension.slice(1);
6706
6707    // Support: Firefox <=54
6708    // Return a confounding non-pixel value or feign ignorance, as appropriate.
6709    if (rnumnonpx.test(val)) {
6710      if (!extra) {
6711        return val;
6712      }
6713      val = "auto";
6714    }
6715
6716
6717    // Support: IE 9 - 11 only
6718    // Use offsetWidth/offsetHeight for when box sizing is unreliable.
6719    // In those cases, the computed value can be trusted to be border-box.
6720    if ((!support.boxSizingReliable() && isBorderBox ||
6721
6722    // Support: IE 10 - 11+, Edge 15 - 18+
6723    // IE/Edge misreport `getComputedStyle` of table rows with width/height
6724    // set in CSS while `offset*` properties report correct values.
6725    // Interestingly, in some cases IE 9 doesn't suffer from this issue.
6726    !support.reliableTrDimensions() && nodeName(elem, "tr") ||
6727
6728    // Fall back to offsetWidth/offsetHeight when value is "auto"
6729    // This happens for inline elements with no explicit setting (gh-3571)
6730    val === "auto" ||
6731
6732    // Support: Android <=4.1 - 4.3 only
6733    // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
6734    !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") &&
6735
6736    // Make sure the element is visible & connected
6737    elem.getClientRects().length) {
6738
6739      isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box";
6740
6741      // Where available, offsetWidth/offsetHeight approximate border box dimensions.
6742      // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
6743      // retrieved value as a content box dimension.
6744      valueIsBorderBox = offsetProp in elem;
6745      if (valueIsBorderBox) {
6746        val = elem[offsetProp];
6747      }
6748    }
6749
6750    // Normalize "" and auto
6751    val = parseFloat(val) || 0;
6752
6753    // Adjust for the element's box model
6754    return val +
6755    boxModelAdjustment(
6756      elem,
6757      dimension,
6758      extra || (isBorderBox ? "border" : "content"),
6759      valueIsBorderBox,
6760      styles,
6761
6762      // Provide the current computed size to request scroll gutter calculation (gh-3589)
6763      val
6764    ) +
6765    "px";
6766  }
6767
6768  jQuery.extend({
6769
6770    // Add in style property hooks for overriding the default
6771    // behavior of getting and setting a style property
6772    cssHooks: {
6773      opacity: {
6774        get: function (elem, computed) {
6775          if (computed) {
6776
6777            // We should always get a number back from opacity
6778            var ret = curCSS(elem, "opacity");
6779            return ret === "" ? "1" : ret;
6780          }
6781        }
6782      }
6783    },
6784
6785    // Don't automatically add "px" to these possibly-unitless properties
6786    cssNumber: {
6787      animationIterationCount: true,
6788      aspectRatio: true,
6789      borderImageSlice: true,
6790      columnCount: true,
6791      flexGrow: true,
6792      flexShrink: true,
6793      fontWeight: true,
6794      gridArea: true,
6795      gridColumn: true,
6796      gridColumnEnd: true,
6797      gridColumnStart: true,
6798      gridRow: true,
6799      gridRowEnd: true,
6800      gridRowStart: true,
6801      lineHeight: true,
6802      opacity: true,
6803      order: true,
6804      orphans: true,
6805      scale: true,
6806      widows: true,
6807      zIndex: true,
6808      zoom: true,
6809
6810      // SVG-related
6811      fillOpacity: true,
6812      floodOpacity: true,
6813      stopOpacity: true,
6814      strokeMiterlimit: true,
6815      strokeOpacity: true
6816    },
6817
6818    // Add in properties whose names you wish to fix before
6819    // setting or getting the value
6820    cssProps: {},
6821
6822    // Get and set the style property on a DOM Node
6823    style: function (elem, name, value, extra) {
6824
6825      // Don't set styles on text and comment nodes
6826      if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
6827        return;
6828      }
6829
6830      // Make sure that we're working with the right name
6831      var ret,type,hooks,
6832        origName = camelCase(name),
6833        isCustomProp = rcustomProp.test(name),
6834        style = elem.style;
6835
6836      // Make sure that we're working with the right name. We don't
6837      // want to query the value if it is a CSS custom property
6838      // since they are user-defined.
6839      if (!isCustomProp) {
6840        name = finalPropName(origName);
6841      }
6842
6843      // Gets hook for the prefixed version, then unprefixed version
6844      hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
6845
6846      // Check if we're setting a value
6847      if (value !== undefined) {
6848        type = typeof value;
6849
6850        // Convert "+=" or "-=" to relative numbers (trac-7345)
6851        if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {
6852          value = adjustCSS(elem, name, ret);
6853
6854          // Fixes bug trac-9237
6855          type = "number";
6856        }
6857
6858        // Make sure that null and NaN values aren't set (trac-7116)
6859        if (value == null || value !== value) {
6860          return;
6861        }
6862
6863        // If a number was passed in, add the unit (except for certain CSS properties)
6864        // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
6865        // "px" to a few hardcoded values.
6866        if (type === "number" && !isCustomProp) {
6867          value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px");
6868        }
6869
6870        // background-* props affect original clone's values
6871        if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
6872          style[name] = "inherit";
6873        }
6874
6875        // If a hook was provided, use that value, otherwise just set the specified value
6876        if (!hooks || !("set" in hooks) ||
6877        (value = hooks.set(elem, value, extra)) !== undefined) {
6878
6879          if (isCustomProp) {
6880            style.setProperty(name, value);
6881          } else {
6882            style[name] = value;
6883          }
6884        }
6885
6886      } else {
6887
6888        // If a hook was provided get the non-computed value from there
6889        if (hooks && "get" in hooks &&
6890        (ret = hooks.get(elem, false, extra)) !== undefined) {
6891
6892          return ret;
6893        }
6894
6895        // Otherwise just get the value from the style object
6896        return style[name];
6897      }
6898    },
6899
6900    css: function (elem, name, extra, styles) {
6901      var val,num,hooks,
6902        origName = camelCase(name),
6903        isCustomProp = rcustomProp.test(name);
6904
6905      // Make sure that we're working with the right name. We don't
6906      // want to modify the value if it is a CSS custom property
6907      // since they are user-defined.
6908      if (!isCustomProp) {
6909        name = finalPropName(origName);
6910      }
6911
6912      // Try prefixed name followed by the unprefixed name
6913      hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
6914
6915      // If a hook was provided get the computed value from there
6916      if (hooks && "get" in hooks) {
6917        val = hooks.get(elem, true, extra);
6918      }
6919
6920      // Otherwise, if a way to get the computed value exists, use that
6921      if (val === undefined) {
6922        val = curCSS(elem, name, styles);
6923      }
6924
6925      // Convert "normal" to computed value
6926      if (val === "normal" && name in cssNormalTransform) {
6927        val = cssNormalTransform[name];
6928      }
6929
6930      // Make numeric if forced or a qualifier was provided and val looks numeric
6931      if (extra === "" || extra) {
6932        num = parseFloat(val);
6933        return extra === true || isFinite(num) ? num || 0 : val;
6934      }
6935
6936      return val;
6937    }
6938  });
6939
6940  jQuery.each(["height", "width"], function (_i, dimension) {
6941    jQuery.cssHooks[dimension] = {
6942      get: function (elem, computed, extra) {
6943        if (computed) {
6944
6945          // Certain elements can have dimension info if we invisibly show them
6946          // but it must have a current display style that would benefit
6947          return rdisplayswap.test(jQuery.css(elem, "display")) && (
6948
6949          // Support: Safari 8+
6950          // Table columns in Safari have non-zero offsetWidth & zero
6951          // getBoundingClientRect().width unless display is changed.
6952          // Support: IE <=11 only
6953          // Running getBoundingClientRect on a disconnected node
6954          // in IE throws an error.
6955          !elem.getClientRects().length || !elem.getBoundingClientRect().width) ?
6956          swap(elem, cssShow, function () {
6957            return getWidthOrHeight(elem, dimension, extra);
6958          }) :
6959          getWidthOrHeight(elem, dimension, extra);
6960        }
6961      },
6962
6963      set: function (elem, value, extra) {
6964        var matches,
6965          styles = getStyles(elem),
6966
6967          // Only read styles.position if the test has a chance to fail
6968          // to avoid forcing a reflow.
6969          scrollboxSizeBuggy = !support.scrollboxSize() &&
6970          styles.position === "absolute",
6971
6972          // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
6973          boxSizingNeeded = scrollboxSizeBuggy || extra,
6974          isBorderBox = boxSizingNeeded &&
6975          jQuery.css(elem, "boxSizing", false, styles) === "border-box",
6976          subtract = extra ?
6977          boxModelAdjustment(
6978            elem,
6979            dimension,
6980            extra,
6981            isBorderBox,
6982            styles
6983          ) :
6984          0;
6985
6986        // Account for unreliable border-box dimensions by comparing offset* to computed and
6987        // faking a content-box to get border and padding (gh-3699)
6988        if (isBorderBox && scrollboxSizeBuggy) {
6989          subtract -= Math.ceil(
6990            elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] -
6991            parseFloat(styles[dimension]) -
6992            boxModelAdjustment(elem, dimension, "border", false, styles) -
6993            0.5
6994          );
6995        }
6996
6997        // Convert to pixels if value adjustment is needed
6998        if (subtract && (matches = rcssNum.exec(value)) &&
6999        (matches[3] || "px") !== "px") {
7000
7001          elem.style[dimension] = value;
7002          value = jQuery.css(elem, dimension);
7003        }
7004
7005        return setPositiveNumber(elem, value, subtract);
7006      }
7007    };
7008  });
7009
7010  jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft,
7011  function (elem, computed) {
7012    if (computed) {
7013      return (parseFloat(curCSS(elem, "marginLeft")) ||
7014      elem.getBoundingClientRect().left -
7015      swap(elem, { marginLeft: 0 }, function () {
7016        return elem.getBoundingClientRect().left;
7017      })) +
7018      "px";
7019    }
7020  }
7021  );
7022
7023  // These hooks are used by animate to expand properties
7024  jQuery.each({
7025    margin: "",
7026    padding: "",
7027    border: "Width"
7028  }, function (prefix, suffix) {
7029    jQuery.cssHooks[prefix + suffix] = {
7030      expand: function (value) {
7031        var i = 0,
7032          expanded = {},
7033
7034          // Assumes a single number if not a string
7035          parts = typeof value === "string" ? value.split(" ") : [value];
7036
7037        for (; i < 4; i++) {
7038          expanded[prefix + cssExpand[i] + suffix] =
7039          parts[i] || parts[i - 2] || parts[0];
7040        }
7041
7042        return expanded;
7043      }
7044    };
7045
7046    if (prefix !== "margin") {
7047      jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
7048    }
7049  });
7050
7051  jQuery.fn.extend({
7052    css: function (name, value) {
7053      return access(this, function (elem, name, value) {
7054        var styles,len,
7055          map = {},
7056          i = 0;
7057
7058        if (Array.isArray(name)) {
7059          styles = getStyles(elem);
7060          len = name.length;
7061
7062          for (; i < len; i++) {
7063            map[name[i]] = jQuery.css(elem, name[i], false, styles);
7064          }
7065
7066          return map;
7067        }
7068
7069        return value !== undefined ?
7070        jQuery.style(elem, name, value) :
7071        jQuery.css(elem, name);
7072      }, name, value, arguments.length > 1);
7073    }
7074  });
7075
7076
7077  function Tween(elem, options, prop, end, easing) {
7078    return new Tween.prototype.init(elem, options, prop, end, easing);
7079  }
7080  jQuery.Tween = Tween;
7081
7082  Tween.prototype = {
7083    constructor: Tween,
7084    init: function (elem, options, prop, end, easing, unit) {
7085      this.elem = elem;
7086      this.prop = prop;
7087      this.easing = easing || jQuery.easing._default;
7088      this.options = options;
7089      this.start = this.now = this.cur();
7090      this.end = end;
7091      this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
7092    },
7093    cur: function () {
7094      var hooks = Tween.propHooks[this.prop];
7095
7096      return hooks && hooks.get ?
7097      hooks.get(this) :
7098      Tween.propHooks._default.get(this);
7099    },
7100    run: function (percent) {
7101      var eased,
7102        hooks = Tween.propHooks[this.prop];
7103
7104      if (this.options.duration) {
7105        this.pos = eased = jQuery.easing[this.easing](
7106          percent, this.options.duration * percent, 0, 1, this.options.duration
7107        );
7108      } else {
7109        this.pos = eased = percent;
7110      }
7111      this.now = (this.end - this.start) * eased + this.start;
7112
7113      if (this.options.step) {
7114        this.options.step.call(this.elem, this.now, this);
7115      }
7116
7117      if (hooks && hooks.set) {
7118        hooks.set(this);
7119      } else {
7120        Tween.propHooks._default.set(this);
7121      }
7122      return this;
7123    }
7124  };
7125
7126  Tween.prototype.init.prototype = Tween.prototype;
7127
7128  Tween.propHooks = {
7129    _default: {
7130      get: function (tween) {
7131        var result;
7132
7133        // Use a property on the element directly when it is not a DOM element,
7134        // or when there is no matching style property that exists.
7135        if (tween.elem.nodeType !== 1 ||
7136        tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) {
7137          return tween.elem[tween.prop];
7138        }
7139
7140        // Passing an empty string as a 3rd parameter to .css will automatically
7141        // attempt a parseFloat and fallback to a string if the parse fails.
7142        // Simple values such as "10px" are parsed to Float;
7143        // complex values such as "rotate(1rad)" are returned as-is.
7144        result = jQuery.css(tween.elem, tween.prop, "");
7145
7146        // Empty strings, null, undefined and "auto" are converted to 0.
7147        return !result || result === "auto" ? 0 : result;
7148      },
7149      set: function (tween) {
7150
7151        // Use step hook for back compat.
7152        // Use cssHook if its there.
7153        // Use .style if available and use plain properties where available.
7154        if (jQuery.fx.step[tween.prop]) {
7155          jQuery.fx.step[tween.prop](tween);
7156        } else if (tween.elem.nodeType === 1 && (
7157        jQuery.cssHooks[tween.prop] ||
7158        tween.elem.style[finalPropName(tween.prop)] != null)) {
7159          jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
7160        } else {
7161          tween.elem[tween.prop] = tween.now;
7162        }
7163      }
7164    }
7165  };
7166
7167  // Support: IE <=9 only
7168  // Panic based approach to setting things on disconnected nodes
7169  Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7170    set: function (tween) {
7171      if (tween.elem.nodeType && tween.elem.parentNode) {
7172        tween.elem[tween.prop] = tween.now;
7173      }
7174    }
7175  };
7176
7177  jQuery.easing = {
7178    linear: function (p) {
7179      return p;
7180    },
7181    swing: function (p) {
7182      return 0.5 - Math.cos(p * Math.PI) / 2;
7183    },
7184    _default: "swing"
7185  };
7186
7187  jQuery.fx = Tween.prototype.init;
7188
7189  // Back compat <1.8 extension point
7190  jQuery.fx.step = {};
7191
7192
7193
7194
7195  var
7196    fxNow,inProgress,
7197    rfxtypes = /^(?:toggle|show|hide)$/,
7198    rrun = /queueHooks$/;
7199
7200  function schedule() {
7201    if (inProgress) {
7202      if (document.hidden === false && window.requestAnimationFrame) {
7203        window.requestAnimationFrame(schedule);
7204      } else {
7205        window.setTimeout(schedule, jQuery.fx.interval);
7206      }
7207
7208      jQuery.fx.tick();
7209    }
7210  }
7211
7212  // Animations created synchronously will run synchronously
7213  function createFxNow() {
7214    window.setTimeout(function () {
7215      fxNow = undefined;
7216    });
7217    return fxNow = Date.now();
7218  }
7219
7220  // Generate parameters to create a standard animation
7221  function genFx(type, includeWidth) {
7222    var which,
7223      i = 0,
7224      attrs = { height: type };
7225
7226    // If we include width, step value is 1 to do all cssExpand values,
7227    // otherwise step value is 2 to skip over Left and Right
7228    includeWidth = includeWidth ? 1 : 0;
7229    for (; i < 4; i += 2 - includeWidth) {
7230      which = cssExpand[i];
7231      attrs["margin" + which] = attrs["padding" + which] = type;
7232    }
7233
7234    if (includeWidth) {
7235      attrs.opacity = attrs.width = type;
7236    }
7237
7238    return attrs;
7239  }
7240
7241  function createTween(value, prop, animation) {
7242    var tween,
7243      collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]),
7244      index = 0,
7245      length = collection.length;
7246    for (; index < length; index++) {
7247      if (tween = collection[index].call(animation, prop, value)) {
7248
7249        // We're done with this property
7250        return tween;
7251      }
7252    }
7253  }
7254
7255  function defaultPrefilter(elem, props, opts) {
7256    var prop,value,toggle,hooks,oldfire,propTween,restoreDisplay,display,
7257      isBox = "width" in props || "height" in props,
7258      anim = this,
7259      orig = {},
7260      style = elem.style,
7261      hidden = elem.nodeType && isHiddenWithinTree(elem),
7262      dataShow = dataPriv.get(elem, "fxshow");
7263
7264    // Queue-skipping animations hijack the fx hooks
7265    if (!opts.queue) {
7266      hooks = jQuery._queueHooks(elem, "fx");
7267      if (hooks.unqueued == null) {
7268        hooks.unqueued = 0;
7269        oldfire = hooks.empty.fire;
7270        hooks.empty.fire = function () {
7271          if (!hooks.unqueued) {
7272            oldfire();
7273          }
7274        };
7275      }
7276      hooks.unqueued++;
7277
7278      anim.always(function () {
7279
7280        // Ensure the complete handler is called before this completes
7281        anim.always(function () {
7282          hooks.unqueued--;
7283          if (!jQuery.queue(elem, "fx").length) {
7284            hooks.empty.fire();
7285          }
7286        });
7287      });
7288    }
7289
7290    // Detect show/hide animations
7291    for (prop in props) {
7292      value = props[prop];
7293      if (rfxtypes.test(value)) {
7294        delete props[prop];
7295        toggle = toggle || value === "toggle";
7296        if (value === (hidden ? "hide" : "show")) {
7297
7298          // Pretend to be hidden if this is a "show" and
7299          // there is still data from a stopped show/hide
7300          if (value === "show" && dataShow && dataShow[prop] !== undefined) {
7301            hidden = true;
7302
7303            // Ignore all other no-op show/hide data
7304          } else {
7305            continue;
7306          }
7307        }
7308        orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
7309      }
7310    }
7311
7312    // Bail out if this is a no-op like .hide().hide()
7313    propTween = !jQuery.isEmptyObject(props);
7314    if (!propTween && jQuery.isEmptyObject(orig)) {
7315      return;
7316    }
7317
7318    // Restrict "overflow" and "display" styles during box animations
7319    if (isBox && elem.nodeType === 1) {
7320
vendor: 3,446 bytes, lines 7321-7432
7321      // Support: IE <=9 - 11, Edge 12 - 15
7322      // Record all 3 overflow attributes because IE does not infer the shorthand
7323      // from identically-valued overflowX and overflowY and Edge just mirrors
7324      // the overflowX value there.
7325      opts.overflow = [style.overflow, style.overflowX, style.overflowY];
7326
7327      // Identify a display type, preferring old show/hide data over the CSS cascade
7328      restoreDisplay = dataShow && dataShow.display;
7329      if (restoreDisplay == null) {
7330        restoreDisplay = dataPriv.get(elem, "display");
7331      }
7332      display = jQuery.css(elem, "display");
7333      if (display === "none") {
7334        if (restoreDisplay) {
7335          display = restoreDisplay;
7336        } else {
7337
7338          // Get nonempty value(s) by temporarily forcing visibility
7339          showHide([elem], true);
7340          restoreDisplay = elem.style.display || restoreDisplay;
7341          display = jQuery.css(elem, "display");
7342          showHide([elem]);
7343        }
7344      }
7345
7346      // Animate inline elements as inline-block
7347      if (display === "inline" || display === "inline-block" && restoreDisplay != null) {
7348        if (jQuery.css(elem, "float") === "none") {
7349
7350          // Restore the original display value at the end of pure show/hide animations
7351          if (!propTween) {
7352            anim.done(function () {
7353              style.display = restoreDisplay;
7354            });
7355            if (restoreDisplay == null) {
7356              display = style.display;
7357              restoreDisplay = display === "none" ? "" : display;
7358            }
7359          }
7360          style.display = "inline-block";
7361        }
7362      }
7363    }
7364
7365    if (opts.overflow) {
7366      style.overflow = "hidden";
7367      anim.always(function () {
7368        style.overflow = opts.overflow[0];
7369        style.overflowX = opts.overflow[1];
7370        style.overflowY = opts.overflow[2];
7371      });
7372    }
7373
7374    // Implement show/hide animations
7375    propTween = false;
7376    for (prop in orig) {
7377
7378      // General show/hide setup for this element animation
7379      if (!propTween) {
7380        if (dataShow) {
7381          if ("hidden" in dataShow) {
7382            hidden = dataShow.hidden;
7383          }
7384        } else {
7385          dataShow = dataPriv.access(elem, "fxshow", { display: restoreDisplay });
7386        }
7387
7388        // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
7389        if (toggle) {
7390          dataShow.hidden = !hidden;
7391        }
7392
7393        // Show elements before animating them
7394        if (hidden) {
7395          showHide([elem], true);
7396        }
7397
7398        /* eslint-disable no-loop-func */
7399
7400        anim.done(function () {
7401
7402          /* eslint-enable no-loop-func */
7403
7404          // The final step of a "hide" animation is actually hiding the element
7405          if (!hidden) {
7406            showHide([elem]);
7407          }
7408          dataPriv.remove(elem, "fxshow");
7409          for (prop in orig) {
7410            jQuery.style(elem, prop, orig[prop]);
7411          }
7412        });
7413      }
7414
7415      // Per-property setup
7416      propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
7417      if (!(prop in dataShow)) {
7418        dataShow[prop] = propTween.start;
7419        if (hidden) {
7420          propTween.end = propTween.start;
7421          propTween.start = 0;
7422        }
7423      }
7424    }
7425  }
7426
7427  function propFilter(props, specialEasing) {
7428    var index, name, easing, value, hooks;
7429
7430    // camelCase, specialEasing and expand cssHook pass
7431    for (index in props) {
7432      name = camelCase(index);
vendor: 45,328 bytes, lines 7433-9093
7433      easing = specialEasing[name];
7434      value = props[index];
7435      if (Array.isArray(value)) {
7436        easing = value[1];
7437        value = props[index] = value[0];
7438      }
7439
7440      if (index !== name) {
7441        props[name] = value;
7442        delete props[index];
7443      }
7444
7445      hooks = jQuery.cssHooks[name];
7446      if (hooks && "expand" in hooks) {
7447        value = hooks.expand(value);
7448        delete props[name];
7449
7450        // Not quite $.extend, this won't overwrite existing keys.
7451        // Reusing 'index' because we have the correct "name"
7452        for (index in value) {
7453          if (!(index in props)) {
7454            props[index] = value[index];
7455            specialEasing[index] = easing;
7456          }
7457        }
7458      } else {
7459        specialEasing[name] = easing;
7460      }
7461    }
7462  }
7463
7464  function Animation(elem, properties, options) {
7465    var result,
7466      stopped,
7467      index = 0,
7468      length = Animation.prefilters.length,
7469      deferred = jQuery.Deferred().always(function () {
7470
7471        // Don't match elem in the :animated selector
7472        delete tick.elem;
7473      }),
7474      tick = function () {
7475        if (stopped) {
7476          return false;
7477        }
7478        var currentTime = fxNow || createFxNow(),
7479          remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
7480
7481          // Support: Android 2.3 only
7482          // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497)
7483          temp = remaining / animation.duration || 0,
7484          percent = 1 - temp,
7485          index = 0,
7486          length = animation.tweens.length;
7487
7488        for (; index < length; index++) {
7489          animation.tweens[index].run(percent);
7490        }
7491
7492        deferred.notifyWith(elem, [animation, percent, remaining]);
7493
7494        // If there's more to do, yield
7495        if (percent < 1 && length) {
7496          return remaining;
7497        }
7498
7499        // If this was an empty animation, synthesize a final progress notification
7500        if (!length) {
7501          deferred.notifyWith(elem, [animation, 1, 0]);
7502        }
7503
7504        // Resolve the animation and report its conclusion
7505        deferred.resolveWith(elem, [animation]);
7506        return false;
7507      },
7508      animation = deferred.promise({
7509        elem: elem,
7510        props: jQuery.extend({}, properties),
7511        opts: jQuery.extend(true, {
7512          specialEasing: {},
7513          easing: jQuery.easing._default
7514        }, options),
7515        originalProperties: properties,
7516        originalOptions: options,
7517        startTime: fxNow || createFxNow(),
7518        duration: options.duration,
7519        tweens: [],
7520        createTween: function (prop, end) {
7521          var tween = jQuery.Tween(elem, animation.opts, prop, end,
7522          animation.opts.specialEasing[prop] || animation.opts.easing);
7523          animation.tweens.push(tween);
7524          return tween;
7525        },
7526        stop: function (gotoEnd) {
7527          var index = 0,
7528
7529            // If we are going to the end, we want to run all the tweens
7530            // otherwise we skip this part
7531            length = gotoEnd ? animation.tweens.length : 0;
7532          if (stopped) {
7533            return this;
7534          }
7535          stopped = true;
7536          for (; index < length; index++) {
7537            animation.tweens[index].run(1);
7538          }
7539
7540          // Resolve when we played the last frame; otherwise, reject
7541          if (gotoEnd) {
7542            deferred.notifyWith(elem, [animation, 1, 0]);
7543            deferred.resolveWith(elem, [animation, gotoEnd]);
7544          } else {
7545            deferred.rejectWith(elem, [animation, gotoEnd]);
7546          }
7547          return this;
7548        }
7549      }),
7550      props = animation.props;
7551
7552    propFilter(props, animation.opts.specialEasing);
7553
7554    for (; index < length; index++) {
7555      result = Animation.prefilters[index].call(animation, elem, props, animation.opts);
7556      if (result) {
7557        if (isFunction(result.stop)) {
7558          jQuery._queueHooks(animation.elem, animation.opts.queue).stop =
7559          result.stop.bind(result);
7560        }
7561        return result;
7562      }
7563    }
7564
7565    jQuery.map(props, createTween, animation);
7566
7567    if (isFunction(animation.opts.start)) {
7568      animation.opts.start.call(elem, animation);
7569    }
7570
7571    // Attach callbacks from options
7572    animation.
7573    progress(animation.opts.progress).
7574    done(animation.opts.done, animation.opts.complete).
7575    fail(animation.opts.fail).
7576    always(animation.opts.always);
7577
7578    jQuery.fx.timer(
7579      jQuery.extend(tick, {
7580        elem: elem,
7581        anim: animation,
7582        queue: animation.opts.queue
7583      })
7584    );
7585
7586    return animation;
7587  }
7588
7589  jQuery.Animation = jQuery.extend(Animation, {
7590
7591    tweeners: {
7592      "*": [function (prop, value) {
7593        var tween = this.createTween(prop, value);
7594        adjustCSS(tween.elem, prop, rcssNum.exec(value), tween);
7595        return tween;
7596      }]
7597    },
7598
7599    tweener: function (props, callback) {
7600      if (isFunction(props)) {
7601        callback = props;
7602        props = ["*"];
7603      } else {
7604        props = props.match(rnothtmlwhite);
7605      }
7606
7607      var prop,
7608        index = 0,
7609        length = props.length;
7610
7611      for (; index < length; index++) {
7612        prop = props[index];
7613        Animation.tweeners[prop] = Animation.tweeners[prop] || [];
7614        Animation.tweeners[prop].unshift(callback);
7615      }
7616    },
7617
7618    prefilters: [defaultPrefilter],
7619
7620    prefilter: function (callback, prepend) {
7621      if (prepend) {
7622        Animation.prefilters.unshift(callback);
7623      } else {
7624        Animation.prefilters.push(callback);
7625      }
7626    }
7627  });
7628
7629  jQuery.speed = function (speed, easing, fn) {
7630    var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
7631      complete: fn || !fn && easing ||
7632      isFunction(speed) && speed,
7633      duration: speed,
7634      easing: fn && easing || easing && !isFunction(easing) && easing
7635    };
7636
7637    // Go to the end state if fx are off
7638    if (jQuery.fx.off) {
7639      opt.duration = 0;
7640
7641    } else {
7642      if (typeof opt.duration !== "number") {
7643        if (opt.duration in jQuery.fx.speeds) {
7644          opt.duration = jQuery.fx.speeds[opt.duration];
7645
7646        } else {
7647          opt.duration = jQuery.fx.speeds._default;
7648        }
7649      }
7650    }
7651
7652    // Normalize opt.queue - true/undefined/null -> "fx"
7653    if (opt.queue == null || opt.queue === true) {
7654      opt.queue = "fx";
7655    }
7656
7657    // Queueing
7658    opt.old = opt.complete;
7659
7660    opt.complete = function () {
7661      if (isFunction(opt.old)) {
7662        opt.old.call(this);
7663      }
7664
7665      if (opt.queue) {
7666        jQuery.dequeue(this, opt.queue);
7667      }
7668    };
7669
7670    return opt;
7671  };
7672
7673  jQuery.fn.extend({
7674    fadeTo: function (speed, to, easing, callback) {
7675
7676      // Show any hidden elements after setting opacity to 0
7677      return this.filter(isHiddenWithinTree).css("opacity", 0).show()
7678
7679      // Animate to the value specified
7680      .end().animate({ opacity: to }, speed, easing, callback);
7681    },
7682    animate: function (prop, speed, easing, callback) {
7683      var empty = jQuery.isEmptyObject(prop),
7684        optall = jQuery.speed(speed, easing, callback),
7685        doAnimation = function () {
7686
7687          // Operate on a copy of prop so per-property easing won't be lost
7688          var anim = Animation(this, jQuery.extend({}, prop), optall);
7689
7690          // Empty animations, or finishing resolves immediately
7691          if (empty || dataPriv.get(this, "finish")) {
7692            anim.stop(true);
7693          }
7694        };
7695
7696      doAnimation.finish = doAnimation;
7697
7698      return empty || optall.queue === false ?
7699      this.each(doAnimation) :
7700      this.queue(optall.queue, doAnimation);
7701    },
7702    stop: function (type, clearQueue, gotoEnd) {
7703      var stopQueue = function (hooks) {
7704        var stop = hooks.stop;
7705        delete hooks.stop;
7706        stop(gotoEnd);
7707      };
7708
7709      if (typeof type !== "string") {
7710        gotoEnd = clearQueue;
7711        clearQueue = type;
7712        type = undefined;
7713      }
7714      if (clearQueue) {
7715        this.queue(type || "fx", []);
7716      }
7717
7718      return this.each(function () {
7719        var dequeue = true,
7720          index = type != null && type + "queueHooks",
7721          timers = jQuery.timers,
7722          data = dataPriv.get(this);
7723
7724        if (index) {
7725          if (data[index] && data[index].stop) {
7726            stopQueue(data[index]);
7727          }
7728        } else {
7729          for (index in data) {
7730            if (data[index] && data[index].stop && rrun.test(index)) {
7731              stopQueue(data[index]);
7732            }
7733          }
7734        }
7735
7736        for (index = timers.length; index--;) {
7737          if (timers[index].elem === this && (
7738          type == null || timers[index].queue === type)) {
7739
7740            timers[index].anim.stop(gotoEnd);
7741            dequeue = false;
7742            timers.splice(index, 1);
7743          }
7744        }
7745
7746        // Start the next in the queue if the last step wasn't forced.
7747        // Timers currently will call their complete callbacks, which
7748        // will dequeue but only if they were gotoEnd.
7749        if (dequeue || !gotoEnd) {
7750          jQuery.dequeue(this, type);
7751        }
7752      });
7753    },
7754    finish: function (type) {
7755      if (type !== false) {
7756        type = type || "fx";
7757      }
7758      return this.each(function () {
7759        var index,
7760          data = dataPriv.get(this),
7761          queue = data[type + "queue"],
7762          hooks = data[type + "queueHooks"],
7763          timers = jQuery.timers,
7764          length = queue ? queue.length : 0;
7765
7766        // Enable finishing flag on private data
7767        data.finish = true;
7768
7769        // Empty the queue first
7770        jQuery.queue(this, type, []);
7771
7772        if (hooks && hooks.stop) {
7773          hooks.stop.call(this, true);
7774        }
7775
7776        // Look for any active animations, and finish them
7777        for (index = timers.length; index--;) {
7778          if (timers[index].elem === this && timers[index].queue === type) {
7779            timers[index].anim.stop(true);
7780            timers.splice(index, 1);
7781          }
7782        }
7783
7784        // Look for any animations in the old queue and finish them
7785        for (index = 0; index < length; index++) {
7786          if (queue[index] && queue[index].finish) {
7787            queue[index].finish.call(this);
7788          }
7789        }
7790
7791        // Turn off finishing flag
7792        delete data.finish;
7793      });
7794    }
7795  });
7796
7797  jQuery.each(["toggle", "show", "hide"], function (_i, name) {
7798    var cssFn = jQuery.fn[name];
7799    jQuery.fn[name] = function (speed, easing, callback) {
7800      return speed == null || typeof speed === "boolean" ?
7801      cssFn.apply(this, arguments) :
7802      this.animate(genFx(name, true), speed, easing, callback);
7803    };
7804  });
7805
7806  // Generate shortcuts for custom animations
7807  jQuery.each({
7808    slideDown: genFx("show"),
7809    slideUp: genFx("hide"),
7810    slideToggle: genFx("toggle"),
7811    fadeIn: { opacity: "show" },
7812    fadeOut: { opacity: "hide" },
7813    fadeToggle: { opacity: "toggle" }
7814  }, function (name, props) {
7815    jQuery.fn[name] = function (speed, easing, callback) {
7816      return this.animate(props, speed, easing, callback);
7817    };
7818  });
7819
7820  jQuery.timers = [];
7821  jQuery.fx.tick = function () {
7822    var timer,
7823      i = 0,
7824      timers = jQuery.timers;
7825
7826    fxNow = Date.now();
7827
7828    for (; i < timers.length; i++) {
7829      timer = timers[i];
7830
7831      // Run the timer and safely remove it when done (allowing for external removal)
7832      if (!timer() && timers[i] === timer) {
7833        timers.splice(i--, 1);
7834      }
7835    }
7836
7837    if (!timers.length) {
7838      jQuery.fx.stop();
7839    }
7840    fxNow = undefined;
7841  };
7842
7843  jQuery.fx.timer = function (timer) {
7844    jQuery.timers.push(timer);
7845    jQuery.fx.start();
7846  };
7847
7848  jQuery.fx.interval = 13;
7849  jQuery.fx.start = function () {
7850    if (inProgress) {
7851      return;
7852    }
7853
7854    inProgress = true;
7855    schedule();
7856  };
7857
7858  jQuery.fx.stop = function () {
7859    inProgress = null;
7860  };
7861
7862  jQuery.fx.speeds = {
7863    slow: 600,
7864    fast: 200,
7865
7866    // Default speed
7867    _default: 400
7868  };
7869
7870
7871  // Based off of the plugin by Clint Helfers, with permission.
7872  jQuery.fn.delay = function (time, type) {
7873    time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
7874    type = type || "fx";
7875
7876    return this.queue(type, function (next, hooks) {
7877      var timeout = window.setTimeout(next, time);
7878      hooks.stop = function () {
7879        window.clearTimeout(timeout);
7880      };
7881    });
7882  };
7883
7884
7885  (function () {
7886    var input = document.createElement("input"),
7887      select = document.createElement("select"),
7888      opt = select.appendChild(document.createElement("option"));
7889
7890    input.type = "checkbox";
7891
7892    // Support: Android <=4.3 only
7893    // Default value for a checkbox should be "on"
7894    support.checkOn = input.value !== "";
7895
7896    // Support: IE <=11 only
7897    // Must access selectedIndex to make default options select
7898    support.optSelected = opt.selected;
7899
7900    // Support: IE <=11 only
7901    // An input loses its value after becoming a radio
7902    input = document.createElement("input");
7903    input.value = "t";
7904    input.type = "radio";
7905    support.radioValue = input.value === "t";
7906  })();
7907
7908
7909  var boolHook,
7910    attrHandle = jQuery.expr.attrHandle;
7911
7912  jQuery.fn.extend({
7913    attr: function (name, value) {
7914      return access(this, jQuery.attr, name, value, arguments.length > 1);
7915    },
7916
7917    removeAttr: function (name) {
7918      return this.each(function () {
7919        jQuery.removeAttr(this, name);
7920      });
7921    }
7922  });
7923
7924  jQuery.extend({
7925    attr: function (elem, name, value) {
7926      var ret,hooks,
7927        nType = elem.nodeType;
7928
7929      // Don't get/set attributes on text, comment and attribute nodes
7930      if (nType === 3 || nType === 8 || nType === 2) {
7931        return;
7932      }
7933
7934      // Fallback to prop when attributes are not supported
7935      if (typeof elem.getAttribute === "undefined") {
7936        return jQuery.prop(elem, name, value);
7937      }
7938
7939      // Attribute hooks are determined by the lowercase version
7940      // Grab necessary hook if one is defined
7941      if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
7942        hooks = jQuery.attrHooks[name.toLowerCase()] || (
7943        jQuery.expr.match.bool.test(name) ? boolHook : undefined);
7944      }
7945
7946      if (value !== undefined) {
7947        if (value === null) {
7948          jQuery.removeAttr(elem, name);
7949          return;
7950        }
7951
7952        if (hooks && "set" in hooks &&
7953        (ret = hooks.set(elem, value, name)) !== undefined) {
7954          return ret;
7955        }
7956
7957        elem.setAttribute(name, value + "");
7958        return value;
7959      }
7960
7961      if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
7962        return ret;
7963      }
7964
7965      ret = jQuery.find.attr(elem, name);
7966
7967      // Non-existent attributes return null, we normalize to undefined
7968      return ret == null ? undefined : ret;
7969    },
7970
7971    attrHooks: {
7972      type: {
7973        set: function (elem, value) {
7974          if (!support.radioValue && value === "radio" &&
7975          nodeName(elem, "input")) {
7976            var val = elem.value;
7977            elem.setAttribute("type", value);
7978            if (val) {
7979              elem.value = val;
7980            }
7981            return value;
7982          }
7983        }
7984      }
7985    },
7986
7987    removeAttr: function (elem, value) {
7988      var name,
7989        i = 0,
7990
7991        // Attribute names can contain non-HTML whitespace characters
7992        // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
7993        attrNames = value && value.match(rnothtmlwhite);
7994
7995      if (attrNames && elem.nodeType === 1) {
7996        while (name = attrNames[i++]) {
7997          elem.removeAttribute(name);
7998        }
7999      }
8000    }
8001  });
8002
8003  // Hooks for boolean attributes
8004  boolHook = {
8005    set: function (elem, value, name) {
8006      if (value === false) {
8007
8008        // Remove boolean attributes when set to false
8009        jQuery.removeAttr(elem, name);
8010      } else {
8011        elem.setAttribute(name, name);
8012      }
8013      return name;
8014    }
8015  };
8016
8017  jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (_i, name) {
8018    var getter = attrHandle[name] || jQuery.find.attr;
8019
8020    attrHandle[name] = function (elem, name, isXML) {
8021      var ret,handle,
8022        lowercaseName = name.toLowerCase();
8023
8024      if (!isXML) {
8025
8026        // Avoid an infinite loop by temporarily removing this function from the getter
8027        handle = attrHandle[lowercaseName];
8028        attrHandle[lowercaseName] = ret;
8029        ret = getter(elem, name, isXML) != null ?
8030        lowercaseName :
8031        null;
8032        attrHandle[lowercaseName] = handle;
8033      }
8034      return ret;
8035    };
8036  });
8037
8038
8039
8040
8041  var rfocusable = /^(?:input|select|textarea|button)$/i,
8042    rclickable = /^(?:a|area)$/i;
8043
8044  jQuery.fn.extend({
8045    prop: function (name, value) {
8046      return access(this, jQuery.prop, name, value, arguments.length > 1);
8047    },
8048
8049    removeProp: function (name) {
8050      return this.each(function () {
8051        delete this[jQuery.propFix[name] || name];
8052      });
8053    }
8054  });
8055
8056  jQuery.extend({
8057    prop: function (elem, name, value) {
8058      var ret,hooks,
8059        nType = elem.nodeType;
8060
8061      // Don't get/set properties on text, comment and attribute nodes
8062      if (nType === 3 || nType === 8 || nType === 2) {
8063        return;
8064      }
8065
8066      if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
8067
8068        // Fix name and attach hooks
8069        name = jQuery.propFix[name] || name;
8070        hooks = jQuery.propHooks[name];
8071      }
8072
8073      if (value !== undefined) {
8074        if (hooks && "set" in hooks &&
8075        (ret = hooks.set(elem, value, name)) !== undefined) {
8076          return ret;
8077        }
8078
8079        return elem[name] = value;
8080      }
8081
8082      if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
8083        return ret;
8084      }
8085
8086      return elem[name];
8087    },
8088
8089    propHooks: {
8090      tabIndex: {
8091        get: function (elem) {
8092
8093          // Support: IE <=9 - 11 only
8094          // elem.tabIndex doesn't always return the
8095          // correct value when it hasn't been explicitly set
8096          // Use proper attribute retrieval (trac-12072)
8097          var tabindex = jQuery.find.attr(elem, "tabindex");
8098
8099          if (tabindex) {
8100            return parseInt(tabindex, 10);
8101          }
8102
8103          if (
8104          rfocusable.test(elem.nodeName) ||
8105          rclickable.test(elem.nodeName) &&
8106          elem.href)
8107          {
8108            return 0;
8109          }
8110
8111          return -1;
8112        }
8113      }
8114    },
8115
8116    propFix: {
8117      "for": "htmlFor",
8118      "class": "className"
8119    }
8120  });
8121
8122  // Support: IE <=11 only
8123  // Accessing the selectedIndex property
8124  // forces the browser to respect setting selected
8125  // on the option
8126  // The getter ensures a default option is selected
8127  // when in an optgroup
8128  // eslint rule "no-unused-expressions" is disabled for this code
8129  // since it considers such accessions noop
8130  if (!support.optSelected) {
8131    jQuery.propHooks.selected = {
8132      get: function (elem) {
8133
8134        /* eslint no-unused-expressions: "off" */
8135
8136        var parent = elem.parentNode;
8137        if (parent && parent.parentNode) {
8138          parent.parentNode.selectedIndex;
8139        }
8140        return null;
8141      },
8142      set: function (elem) {
8143
8144        /* eslint no-unused-expressions: "off" */
8145
8146        var parent = elem.parentNode;
8147        if (parent) {
8148          parent.selectedIndex;
8149
8150          if (parent.parentNode) {
8151            parent.parentNode.selectedIndex;
8152          }
8153        }
8154      }
8155    };
8156  }
8157
8158  jQuery.each([
8159  "tabIndex",
8160  "readOnly",
8161  "maxLength",
8162  "cellSpacing",
8163  "cellPadding",
8164  "rowSpan",
8165  "colSpan",
8166  "useMap",
8167  "frameBorder",
8168  "contentEditable"],
8169  function () {
8170    jQuery.propFix[this.toLowerCase()] = this;
8171  });
8172
8173
8174
8175
8176  // Strip and collapse whitespace according to HTML spec
8177  // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
8178  function stripAndCollapse(value) {
8179    var tokens = value.match(rnothtmlwhite) || [];
8180    return tokens.join(" ");
8181  }
8182
8183
8184  function getClass(elem) {
8185    return elem.getAttribute && elem.getAttribute("class") || "";
8186  }
8187
8188  function classesToArray(value) {
8189    if (Array.isArray(value)) {
8190      return value;
8191    }
8192    if (typeof value === "string") {
8193      return value.match(rnothtmlwhite) || [];
8194    }
8195    return [];
8196  }
8197
8198  jQuery.fn.extend({
8199    addClass: function (value) {
8200      var classNames, cur, curValue, className, i, finalValue;
8201
8202      if (isFunction(value)) {
8203        return this.each(function (j) {
8204          jQuery(this).addClass(value.call(this, j, getClass(this)));
8205        });
8206      }
8207
8208      classNames = classesToArray(value);
8209
8210      if (classNames.length) {
8211        return this.each(function () {
8212          curValue = getClass(this);
8213          cur = this.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";
8214
8215          if (cur) {
8216            for (i = 0; i < classNames.length; i++) {
8217              className = classNames[i];
8218              if (cur.indexOf(" " + className + " ") < 0) {
8219                cur += className + " ";
8220              }
8221            }
8222
8223            // Only assign if different to avoid unneeded rendering.
8224            finalValue = stripAndCollapse(cur);
8225            if (curValue !== finalValue) {
8226              this.setAttribute("class", finalValue);
8227            }
8228          }
8229        });
8230      }
8231
8232      return this;
8233    },
8234
8235    removeClass: function (value) {
8236      var classNames, cur, curValue, className, i, finalValue;
8237
8238      if (isFunction(value)) {
8239        return this.each(function (j) {
8240          jQuery(this).removeClass(value.call(this, j, getClass(this)));
8241        });
8242      }
8243
8244      if (!arguments.length) {
8245        return this.attr("class", "");
8246      }
8247
8248      classNames = classesToArray(value);
8249
8250      if (classNames.length) {
8251        return this.each(function () {
8252          curValue = getClass(this);
8253
8254          // This expression is here for better compressibility (see addClass)
8255          cur = this.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";
8256
8257          if (cur) {
8258            for (i = 0; i < classNames.length; i++) {
8259              className = classNames[i];
8260
8261              // Remove *all* instances
8262              while (cur.indexOf(" " + className + " ") > -1) {
8263                cur = cur.replace(" " + className + " ", " ");
8264              }
8265            }
8266
8267            // Only assign if different to avoid unneeded rendering.
8268            finalValue = stripAndCollapse(cur);
8269            if (curValue !== finalValue) {
8270              this.setAttribute("class", finalValue);
8271            }
8272          }
8273        });
8274      }
8275
8276      return this;
8277    },
8278
8279    toggleClass: function (value, stateVal) {
8280      var classNames,className,i,self,
8281        type = typeof value,
8282        isValidValue = type === "string" || Array.isArray(value);
8283
8284      if (isFunction(value)) {
8285        return this.each(function (i) {
8286          jQuery(this).toggleClass(
8287            value.call(this, i, getClass(this), stateVal),
8288            stateVal
8289          );
8290        });
8291      }
8292
8293      if (typeof stateVal === "boolean" && isValidValue) {
8294        return stateVal ? this.addClass(value) : this.removeClass(value);
8295      }
8296
8297      classNames = classesToArray(value);
8298
8299      return this.each(function () {
8300        if (isValidValue) {
8301
8302          // Toggle individual class names
8303          self = jQuery(this);
8304
8305          for (i = 0; i < classNames.length; i++) {
8306            className = classNames[i];
8307
8308            // Check each className given, space separated list
8309            if (self.hasClass(className)) {
8310              self.removeClass(className);
8311            } else {
8312              self.addClass(className);
8313            }
8314          }
8315
8316          // Toggle whole class name
8317        } else if (value === undefined || type === "boolean") {
8318          className = getClass(this);
8319          if (className) {
8320
8321            // Store className if set
8322            dataPriv.set(this, "__className__", className);
8323          }
8324
8325          // If the element has a class name or if we're passed `false`,
8326          // then remove the whole classname (if there was one, the above saved it).
8327          // Otherwise bring back whatever was previously saved (if anything),
8328          // falling back to the empty string if nothing was stored.
8329          if (this.setAttribute) {
8330            this.setAttribute("class",
8331            className || value === false ?
8332            "" :
8333            dataPriv.get(this, "__className__") || ""
8334            );
8335          }
8336        }
8337      });
8338    },
8339
8340    hasClass: function (selector) {
8341      var className,elem,
8342        i = 0;
8343
8344      className = " " + selector + " ";
8345      while (elem = this[i++]) {
8346        if (elem.nodeType === 1 &&
8347        (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) {
8348          return true;
8349        }
8350      }
8351
8352      return false;
8353    }
8354  });
8355
8356
8357
8358
8359  var rreturn = /\r/g;
8360
8361  jQuery.fn.extend({
8362    val: function (value) {
8363      var hooks,ret,valueIsFunction,
8364        elem = this[0];
8365
8366      if (!arguments.length) {
8367        if (elem) {
8368          hooks = jQuery.valHooks[elem.type] ||
8369          jQuery.valHooks[elem.nodeName.toLowerCase()];
8370
8371          if (hooks &&
8372          "get" in hooks &&
8373          (ret = hooks.get(elem, "value")) !== undefined)
8374          {
8375            return ret;
8376          }
8377
8378          ret = elem.value;
8379
8380          // Handle most common string cases
8381          if (typeof ret === "string") {
8382            return ret.replace(rreturn, "");
8383          }
8384
8385          // Handle cases where value is null/undef or number
8386          return ret == null ? "" : ret;
8387        }
8388
8389        return;
8390      }
8391
8392      valueIsFunction = isFunction(value);
8393
8394      return this.each(function (i) {
8395        var val;
8396
8397        if (this.nodeType !== 1) {
8398          return;
8399        }
8400
8401        if (valueIsFunction) {
8402          val = value.call(this, i, jQuery(this).val());
8403        } else {
8404          val = value;
8405        }
8406
8407        // Treat null/undefined as ""; convert numbers to string
8408        if (val == null) {
8409          val = "";
8410
8411        } else if (typeof val === "number") {
8412          val += "";
8413
8414        } else if (Array.isArray(val)) {
8415          val = jQuery.map(val, function (value) {
8416            return value == null ? "" : value + "";
8417          });
8418        }
8419
8420        hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];
8421
8422        // If set returns undefined, fall back to normal setting
8423        if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
8424          this.value = val;
8425        }
8426      });
8427    }
8428  });
8429
8430  jQuery.extend({
8431    valHooks: {
8432      option: {
8433        get: function (elem) {
8434
8435          var val = jQuery.find.attr(elem, "value");
8436          return val != null ?
8437          val :
8438
8439          // Support: IE <=10 - 11 only
8440          // option.text throws exceptions (trac-14686, trac-14858)
8441          // Strip and collapse whitespace
8442          // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8443          stripAndCollapse(jQuery.text(elem));
8444        }
8445      },
8446      select: {
8447        get: function (elem) {
8448          var value,option,i,
8449            options = elem.options,
8450            index = elem.selectedIndex,
8451            one = elem.type === "select-one",
8452            values = one ? null : [],
8453            max = one ? index + 1 : options.length;
8454
8455          if (index < 0) {
8456            i = max;
8457
8458          } else {
8459            i = one ? index : 0;
8460          }
8461
8462          // Loop through all the selected options
8463          for (; i < max; i++) {
8464            option = options[i];
8465
8466            // Support: IE <=9 only
8467            // IE8-9 doesn't update selected after form reset (trac-2551)
8468            if ((option.selected || i === index) &&
8469
8470            // Don't return options that are disabled or in a disabled optgroup
8471            !option.disabled && (
8472            !option.parentNode.disabled ||
8473            !nodeName(option.parentNode, "optgroup"))) {
8474
8475              // Get the specific value for the option
8476              value = jQuery(option).val();
8477
8478              // We don't need an array for one selects
8479              if (one) {
8480                return value;
8481              }
8482
8483              // Multi-Selects return an array
8484              values.push(value);
8485            }
8486          }
8487
8488          return values;
8489        },
8490
8491        set: function (elem, value) {
8492          var optionSet,option,
8493            options = elem.options,
8494            values = jQuery.makeArray(value),
8495            i = options.length;
8496
8497          while (i--) {
8498            option = options[i];
8499
8500            /* eslint-disable no-cond-assign */
8501
8502            if (option.selected =
8503            jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1)
8504            {
8505              optionSet = true;
8506            }
8507
8508            /* eslint-enable no-cond-assign */
8509          }
8510
8511          // Force browsers to behave consistently when non-matching value is set
8512          if (!optionSet) {
8513            elem.selectedIndex = -1;
8514          }
8515          return values;
8516        }
8517      }
8518    }
8519  });
8520
8521  // Radios and checkboxes getter/setter
8522  jQuery.each(["radio", "checkbox"], function () {
8523    jQuery.valHooks[this] = {
8524      set: function (elem, value) {
8525        if (Array.isArray(value)) {
8526          return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1;
8527        }
8528      }
8529    };
8530    if (!support.checkOn) {
8531      jQuery.valHooks[this].get = function (elem) {
8532        return elem.getAttribute("value") === null ? "on" : elem.value;
8533      };
8534    }
8535  });
8536
8537
8538
8539
8540  // Return jQuery for attributes-only inclusion
8541  var location = window.location;
8542
8543  var nonce = { guid: Date.now() };
8544
8545  var rquery = /\?/;
8546
8547
8548
8549  // Cross-browser xml parsing
8550  jQuery.parseXML = function (data) {
8551    var xml, parserErrorElem;
8552    if (!data || typeof data !== "string") {
8553      return null;
8554    }
8555
8556    // Support: IE 9 - 11 only
8557    // IE throws on parseFromString with invalid input.
8558    try {
8559      xml = new window.DOMParser().parseFromString(data, "text/xml");
8560    } catch (e) {}
8561
8562    parserErrorElem = xml && xml.getElementsByTagName("parsererror")[0];
8563    if (!xml || parserErrorElem) {
8564      jQuery.error("Invalid XML: " + (
8565      parserErrorElem ?
8566      jQuery.map(parserErrorElem.childNodes, function (el) {
8567        return el.textContent;
8568      }).join("\n") :
8569      data)
8570      );
8571    }
8572    return xml;
8573  };
8574
8575
8576  var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
8577    stopPropagationCallback = function (e) {
8578      e.stopPropagation();
8579    };
8580
8581  jQuery.extend(jQuery.event, {
8582
8583    trigger: function (event, data, elem, onlyHandlers) {
8584
8585      var i,cur,tmp,bubbleType,ontype,handle,special,lastElement,
8586        eventPath = [elem || document],
8587        type = hasOwn.call(event, "type") ? event.type : event,
8588        namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
8589
8590      cur = lastElement = tmp = elem = elem || document;
8591
8592      // Don't do events on text and comment nodes
8593      if (elem.nodeType === 3 || elem.nodeType === 8) {
8594        return;
8595      }
8596
8597      // focus/blur morphs to focusin/out; ensure we're not firing them right now
8598      if (rfocusMorph.test(type + jQuery.event.triggered)) {
8599        return;
8600      }
8601
8602      if (type.indexOf(".") > -1) {
8603
8604        // Namespaced trigger; create a regexp to match event type in handle()
8605        namespaces = type.split(".");
8606        type = namespaces.shift();
8607        namespaces.sort();
8608      }
8609      ontype = type.indexOf(":") < 0 && "on" + type;
8610
8611      // Caller can pass in a jQuery.Event object, Object, or just an event type string
8612      event = event[jQuery.expando] ?
8613      event :
8614      new jQuery.Event(type, typeof event === "object" && event);
8615
8616      // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8617      event.isTrigger = onlyHandlers ? 2 : 3;
8618      event.namespace = namespaces.join(".");
8619      event.rnamespace = event.namespace ?
8620      new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") :
8621      null;
8622
8623      // Clean up the event in case it is being reused
8624      event.result = undefined;
8625      if (!event.target) {
8626        event.target = elem;
8627      }
8628
8629      // Clone any incoming data and prepend the event, creating the handler arg list
8630      data = data == null ?
8631      [event] :
8632      jQuery.makeArray(data, [event]);
8633
8634      // Allow special events to draw outside the lines
8635      special = jQuery.event.special[type] || {};
8636      if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
8637        return;
8638      }
8639
8640      // Determine event propagation path in advance, per W3C events spec (trac-9951)
8641      // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724)
8642      if (!onlyHandlers && !special.noBubble && !isWindow(elem)) {
8643
8644        bubbleType = special.delegateType || type;
8645        if (!rfocusMorph.test(bubbleType + type)) {
8646          cur = cur.parentNode;
8647        }
8648        for (; cur; cur = cur.parentNode) {
8649          eventPath.push(cur);
8650          tmp = cur;
8651        }
8652
8653        // Only add window if we got to document (e.g., not plain obj or detached DOM)
8654        if (tmp === (elem.ownerDocument || document)) {
8655          eventPath.push(tmp.defaultView || tmp.parentWindow || window);
8656        }
8657      }
8658
8659      // Fire handlers on the event path
8660      i = 0;
8661      while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
8662        lastElement = cur;
8663        event.type = i > 1 ?
8664        bubbleType :
8665        special.bindType || type;
8666
8667        // jQuery handler
8668        handle = (dataPriv.get(cur, "events") || Object.create(null))[event.type] &&
8669        dataPriv.get(cur, "handle");
8670        if (handle) {
8671          handle.apply(cur, data);
8672        }
8673
8674        // Native handler
8675        handle = ontype && cur[ontype];
8676        if (handle && handle.apply && acceptData(cur)) {
8677          event.result = handle.apply(cur, data);
8678          if (event.result === false) {
8679            event.preventDefault();
8680          }
8681        }
8682      }
8683      event.type = type;
8684
8685      // If nobody prevented the default action, do it now
8686      if (!onlyHandlers && !event.isDefaultPrevented()) {
8687
8688        if ((!special._default ||
8689        special._default.apply(eventPath.pop(), data) === false) &&
8690        acceptData(elem)) {
8691
8692          // Call a native DOM method on the target with the same name as the event.
8693          // Don't do default actions on window, that's where global variables be (trac-6170)
8694          if (ontype && isFunction(elem[type]) && !isWindow(elem)) {
8695
8696            // Don't re-trigger an onFOO event when we call its FOO() method
8697            tmp = elem[ontype];
8698
8699            if (tmp) {
8700              elem[ontype] = null;
8701            }
8702
8703            // Prevent re-triggering of the same event, since we already bubbled it above
8704            jQuery.event.triggered = type;
8705
8706            if (event.isPropagationStopped()) {
8707              lastElement.addEventListener(type, stopPropagationCallback);
8708            }
8709
8710            elem[type]();
8711
8712            if (event.isPropagationStopped()) {
8713              lastElement.removeEventListener(type, stopPropagationCallback);
8714            }
8715
8716            jQuery.event.triggered = undefined;
8717
8718            if (tmp) {
8719              elem[ontype] = tmp;
8720            }
8721          }
8722        }
8723      }
8724
8725      return event.result;
8726    },
8727
8728    // Piggyback on a donor event to simulate a different one
8729    // Used only for `focus(in | out)` events
8730    simulate: function (type, elem, event) {
8731      var e = jQuery.extend(
8732        new jQuery.Event(),
8733        event,
8734        {
8735          type: type,
8736          isSimulated: true
8737        }
8738      );
8739
8740      jQuery.event.trigger(e, null, elem);
8741    }
8742
8743  });
8744
8745  jQuery.fn.extend({
8746
8747    trigger: function (type, data) {
8748      return this.each(function () {
8749        jQuery.event.trigger(type, data, this);
8750      });
8751    },
8752    triggerHandler: function (type, data) {
8753      var elem = this[0];
8754      if (elem) {
8755        return jQuery.event.trigger(type, data, elem, true);
8756      }
8757    }
8758  });
8759
8760
8761  var
8762    rbracket = /\[\]$/,
8763    rCRLF = /\r?\n/g,
8764    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8765    rsubmittable = /^(?:input|select|textarea|keygen)/i;
8766
8767  function buildParams(prefix, obj, traditional, add) {
8768    var name;
8769
8770    if (Array.isArray(obj)) {
8771
8772      // Serialize array item.
8773      jQuery.each(obj, function (i, v) {
8774        if (traditional || rbracket.test(prefix)) {
8775
8776          // Treat each array item as a scalar.
8777          add(prefix, v);
8778
8779        } else {
8780
8781          // Item is non-scalar (array or object), encode its numeric index.
8782          buildParams(
8783            prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]",
8784            v,
8785            traditional,
8786            add
8787          );
8788        }
8789      });
8790
8791    } else if (!traditional && toType(obj) === "object") {
8792
8793      // Serialize object item.
8794      for (name in obj) {
8795        buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
8796      }
8797
8798    } else {
8799
8800      // Serialize scalar item.
8801      add(prefix, obj);
8802    }
8803  }
8804
8805  // Serialize an array of form elements or a set of
8806  // key/values into a query string
8807  jQuery.param = function (a, traditional) {
8808    var prefix,
8809      s = [],
8810      add = function (key, valueOrFunction) {
8811
8812        // If value is a function, invoke it and use its return value
8813        var value = isFunction(valueOrFunction) ?
8814        valueOrFunction() :
8815        valueOrFunction;
8816
8817        s[s.length] = encodeURIComponent(key) + "=" +
8818        encodeURIComponent(value == null ? "" : value);
8819      };
8820
8821    if (a == null) {
8822      return "";
8823    }
8824
8825    // If an array was passed in, assume that it is an array of form elements.
8826    if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {
8827
8828      // Serialize the form elements
8829      jQuery.each(a, function () {
8830        add(this.name, this.value);
8831      });
8832
8833    } else {
8834
8835      // If traditional, encode the "old" way (the way 1.3.2 or older
8836      // did it), otherwise encode params recursively.
8837      for (prefix in a) {
8838        buildParams(prefix, a[prefix], traditional, add);
8839      }
8840    }
8841
8842    // Return the resulting serialization
8843    return s.join("&");
8844  };
8845
8846  jQuery.fn.extend({
8847    serialize: function () {
8848      return jQuery.param(this.serializeArray());
8849    },
8850    serializeArray: function () {
8851      return this.map(function () {
8852
8853        // Can add propHook for "elements" to filter or add form elements
8854        var elements = jQuery.prop(this, "elements");
8855        return elements ? jQuery.makeArray(elements) : this;
8856      }).filter(function () {
8857        var type = this.type;
8858
8859        // Use .is( ":disabled" ) so that fieldset[disabled] works
8860        return this.name && !jQuery(this).is(":disabled") &&
8861        rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (
8862        this.checked || !rcheckableType.test(type));
8863      }).map(function (_i, elem) {
8864        var val = jQuery(this).val();
8865
8866        if (val == null) {
8867          return null;
8868        }
8869
8870        if (Array.isArray(val)) {
8871          return jQuery.map(val, function (val) {
8872            return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
8873          });
8874        }
8875
8876        return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
8877      }).get();
8878    }
8879  });
8880
8881
8882  var
8883    r20 = /%20/g,
8884    rhash = /#.*$/,
8885    rantiCache = /([?&])_=[^&]*/,
8886    rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
8887
8888    // trac-7653, trac-8125, trac-8152: local protocol detection
8889    rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8890    rnoContent = /^(?:GET|HEAD)$/,
8891    rprotocol = /^\/\//,
8892
8893    /* Prefilters
8894     * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8895     * 2) These are called:
8896     *    - BEFORE asking for a transport
8897     *    - AFTER param serialization (s.data is a string if s.processData is true)
8898     * 3) key is the dataType
8899     * 4) the catchall symbol "*" can be used
8900     * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8901     */
8902    prefilters = {},
8903
8904    /* Transports bindings
8905     * 1) key is the dataType
8906     * 2) the catchall symbol "*" can be used
8907     * 3) selection will start with transport dataType and THEN go to "*" if needed
8908     */
8909    transports = {},
8910
8911    // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression
8912    allTypes = "*/".concat("*"),
8913
8914    // Anchor tag for parsing the document origin
8915    originAnchor = document.createElement("a");
8916
8917  originAnchor.href = location.href;
8918
8919  // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8920  function addToPrefiltersOrTransports(structure) {
8921
8922    // dataTypeExpression is optional and defaults to "*"
8923    return function (dataTypeExpression, func) {
8924
8925      if (typeof dataTypeExpression !== "string") {
8926        func = dataTypeExpression;
8927        dataTypeExpression = "*";
8928      }
8929
8930      var dataType,
8931        i = 0,
8932        dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || [];
8933
8934      if (isFunction(func)) {
8935
8936        // For each dataType in the dataTypeExpression
8937        while (dataType = dataTypes[i++]) {
8938
8939          // Prepend if requested
8940          if (dataType[0] === "+") {
8941            dataType = dataType.slice(1) || "*";
8942            (structure[dataType] = structure[dataType] || []).unshift(func);
8943
8944            // Otherwise append
8945          } else {
8946            (structure[dataType] = structure[dataType] || []).push(func);
8947          }
8948        }
8949      }
8950    };
8951  }
8952
8953  // Base inspection function for prefilters and transports
8954  function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
8955
8956    var inspected = {},
8957      seekingTransport = structure === transports;
8958
8959    function inspect(dataType) {
8960      var selected;
8961      inspected[dataType] = true;
8962      jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
8963        var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
8964        if (typeof dataTypeOrTransport === "string" &&
8965        !seekingTransport && !inspected[dataTypeOrTransport]) {
8966
8967          options.dataTypes.unshift(dataTypeOrTransport);
8968          inspect(dataTypeOrTransport);
8969          return false;
8970        } else if (seekingTransport) {
8971          return !(selected = dataTypeOrTransport);
8972        }
8973      });
8974      return selected;
8975    }
8976
8977    return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
8978  }
8979
8980  // A special extend for ajax options
8981  // that takes "flat" options (not to be deep extended)
8982  // Fixes trac-9887
8983  function ajaxExtend(target, src) {
8984    var key,deep,
8985      flatOptions = jQuery.ajaxSettings.flatOptions || {};
8986
8987    for (key in src) {
8988      if (src[key] !== undefined) {
8989        (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key];
8990      }
8991    }
8992    if (deep) {
8993      jQuery.extend(true, target, deep);
8994    }
8995
8996    return target;
8997  }
8998
8999  /* Handles responses to an ajax request:
9000   * - finds the right dataType (mediates between content-type and expected dataType)
9001   * - returns the corresponding response
9002   */
9003  function ajaxHandleResponses(s, jqXHR, responses) {
9004
9005    var ct,type,finalDataType,firstDataType,
9006      contents = s.contents,
9007      dataTypes = s.dataTypes;
9008
9009    // Remove auto dataType and get content-type in the process
9010    while (dataTypes[0] === "*") {
9011      dataTypes.shift();
9012      if (ct === undefined) {
9013        ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
9014      }
9015    }
9016
9017    // Check if we're dealing with a known content-type
9018    if (ct) {
9019      for (type in contents) {
9020        if (contents[type] && contents[type].test(ct)) {
9021          dataTypes.unshift(type);
9022          break;
9023        }
9024      }
9025    }
9026
9027    // Check to see if we have a response for the expected dataType
9028    if (dataTypes[0] in responses) {
9029      finalDataType = dataTypes[0];
9030    } else {
9031
9032      // Try convertible dataTypes
9033      for (type in responses) {
9034        if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
9035          finalDataType = type;
9036          break;
9037        }
9038        if (!firstDataType) {
9039          firstDataType = type;
9040        }
9041      }
9042
9043      // Or just use first one
9044      finalDataType = finalDataType || firstDataType;
9045    }
9046
9047    // If we found a dataType
9048    // We add the dataType to the list if needed
9049    // and return the corresponding response
9050    if (finalDataType) {
9051      if (finalDataType !== dataTypes[0]) {
9052        dataTypes.unshift(finalDataType);
9053      }
9054      return responses[finalDataType];
9055    }
9056  }
9057
9058  /* Chain conversions given the request and the original response
9059   * Also sets the responseXXX fields on the jqXHR instance
9060   */
9061  function ajaxConvert(s, response, jqXHR, isSuccess) {
9062    var conv2,current,conv,tmp,prev,
9063      converters = {},
9064
9065      // Work with a copy of dataTypes in case we need to modify it for conversion
9066      dataTypes = s.dataTypes.slice();
9067
9068    // Create converters map with lowercased keys
9069    if (dataTypes[1]) {
9070      for (conv in s.converters) {
9071        converters[conv.toLowerCase()] = s.converters[conv];
9072      }
9073    }
9074
9075    current = dataTypes.shift();
9076
9077    // Convert to each sequential dataType
9078    while (current) {
9079
9080      if (s.responseFields[current]) {
9081        jqXHR[s.responseFields[current]] = response;
9082      }
9083
9084      // Apply the dataFilter if provided
9085      if (!prev && isSuccess && s.dataFilter) {
9086        response = s.dataFilter(response, s.dataType);
9087      }
9088
9089      prev = current;
9090      current = dataTypes.shift();
9091
9092      if (current) {
9093
vendor: 8,893 bytes, lines 9094-9407
9094        // There's only work to do if current dataType is non-auto
9095        if (current === "*") {
9096
9097          current = prev;
9098
9099          // Convert response if prev dataType is non-auto and differs from current
9100        } else if (prev !== "*" && prev !== current) {
9101
9102          // Seek a direct converter
9103          conv = converters[prev + " " + current] || converters["* " + current];
9104
9105          // If none found, seek a pair
9106          if (!conv) {
9107            for (conv2 in converters) {
9108
9109              // If conv2 outputs current
9110              tmp = conv2.split(" ");
9111              if (tmp[1] === current) {
9112
9113                // If prev can be converted to accepted input
9114                conv = converters[prev + " " + tmp[0]] ||
9115                converters["* " + tmp[0]];
9116                if (conv) {
9117
9118                  // Condense equivalence converters
9119                  if (conv === true) {
9120                    conv = converters[conv2];
9121
9122                    // Otherwise, insert the intermediate dataType
9123                  } else if (converters[conv2] !== true) {
9124                    current = tmp[0];
9125                    dataTypes.unshift(tmp[1]);
9126                  }
9127                  break;
9128                }
9129              }
9130            }
9131          }
9132
9133          // Apply converter (if not an equivalence)
9134          if (conv !== true) {
9135
9136            // Unless errors are allowed to bubble, catch and return them
9137            if (conv && s.throws) {
9138              response = conv(response);
9139            } else {
9140              try {
9141                response = conv(response);
9142              } catch (e) {
9143                return {
9144                  state: "parsererror",
9145                  error: conv ? e : "No conversion from " + prev + " to " + current
9146                };
9147              }
9148            }
9149          }
9150        }
9151      }
9152    }
9153
9154    return { state: "success", data: response };
9155  }
9156
9157  jQuery.extend({
9158
9159    // Counter for holding the number of active queries
9160    active: 0,
9161
9162    // Last-Modified header cache for next request
9163    lastModified: {},
9164    etag: {},
9165
9166    ajaxSettings: {
9167      url: location.href,
9168      type: "GET",
9169      isLocal: rlocalProtocol.test(location.protocol),
9170      global: true,
9171      processData: true,
9172      async: true,
9173      contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9174
9175      /*
9176      timeout: 0,
9177      data: null,
9178      dataType: null,
9179      username: null,
9180      password: null,
9181      cache: null,
9182      throws: false,
9183      traditional: false,
9184      headers: {},
9185      */
9186
9187      accepts: {
9188        "*": allTypes,
9189        text: "text/plain",
9190        html: "text/html",
9191        xml: "application/xml, text/xml",
9192        json: "application/json, text/javascript"
9193      },
9194
9195      contents: {
9196        xml: /\bxml\b/,
9197        html: /\bhtml/,
9198        json: /\bjson\b/
9199      },
9200
9201      responseFields: {
9202        xml: "responseXML",
9203        text: "responseText",
9204        json: "responseJSON"
9205      },
9206
9207      // Data converters
9208      // Keys separate source (or catchall "*") and destination types with a single space
9209      converters: {
9210
9211        // Convert anything to text
9212        "* text": String,
9213
9214        // Text to html (true = no transformation)
9215        "text html": true,
9216
9217        // Evaluate text as a json expression
9218        "text json": JSON.parse,
9219
9220        // Parse text as xml
9221        "text xml": jQuery.parseXML
9222      },
9223
9224      // For options that shouldn't be deep extended:
9225      // you can add your own custom options here if
9226      // and when you create one that shouldn't be
9227      // deep extended (see ajaxExtend)
9228      flatOptions: {
9229        url: true,
9230        context: true
9231      }
9232    },
9233
9234    // Creates a full fledged settings object into target
9235    // with both ajaxSettings and settings fields.
9236    // If target is omitted, writes into ajaxSettings.
9237    ajaxSetup: function (target, settings) {
9238      return settings ?
9239
9240      // Building a settings object
9241      ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
9242
9243      // Extending ajaxSettings
9244      ajaxExtend(jQuery.ajaxSettings, target);
9245    },
9246
9247    ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
9248    ajaxTransport: addToPrefiltersOrTransports(transports),
9249
9250    // Main method
9251    ajax: function (url, options) {
9252
9253      // If url is an object, simulate pre-1.5 signature
9254      if (typeof url === "object") {
9255        options = url;
9256        url = undefined;
9257      }
9258
9259      // Force options to be an object
9260      options = options || {};
9261
9262      var transport,
9263
9264        // URL without anti-cache param
9265        cacheURL,
9266
9267        // Response headers
9268        responseHeadersString,
9269        responseHeaders,
9270
9271        // timeout handle
9272        timeoutTimer,
9273
9274        // Url cleanup var
9275        urlAnchor,
9276
9277        // Request state (becomes false upon send and true upon completion)
9278        completed,
9279
9280        // To know if global events are to be dispatched
9281        fireGlobals,
9282
9283        // Loop variable
9284        i,
9285
9286        // uncached part of the url
9287        uncached,
9288
9289        // Create the final options object
9290        s = jQuery.ajaxSetup({}, options),
9291
9292        // Callbacks context
9293        callbackContext = s.context || s,
9294
9295        // Context for global events is callbackContext if it is a DOM node or jQuery collection
9296        globalEventContext = s.context && (
9297        callbackContext.nodeType || callbackContext.jquery) ?
9298        jQuery(callbackContext) :
9299        jQuery.event,
9300
9301        // Deferreds
9302        deferred = jQuery.Deferred(),
9303        completeDeferred = jQuery.Callbacks("once memory"),
9304
9305        // Status-dependent callbacks
9306        statusCode = s.statusCode || {},
9307
9308        // Headers (they are sent all at once)
9309        requestHeaders = {},
9310        requestHeadersNames = {},
9311
9312        // Default abort message
9313        strAbort = "canceled",
9314
9315        // Fake xhr
9316        jqXHR = {
9317          readyState: 0,
9318
9319          // Builds headers hashtable if needed
9320          getResponseHeader: function (key) {
9321            var match;
9322            if (completed) {
9323              if (!responseHeaders) {
9324                responseHeaders = {};
9325                while (match = rheaders.exec(responseHeadersString)) {
9326                  responseHeaders[match[1].toLowerCase() + " "] =
9327                  (responseHeaders[match[1].toLowerCase() + " "] || []).
9328                  concat(match[2]);
9329                }
9330              }
9331              match = responseHeaders[key.toLowerCase() + " "];
9332            }
9333            return match == null ? null : match.join(", ");
9334          },
9335
9336          // Raw string
9337          getAllResponseHeaders: function () {
9338            return completed ? responseHeadersString : null;
9339          },
9340
9341          // Caches the header
9342          setRequestHeader: function (name, value) {
9343            if (completed == null) {
9344              name = requestHeadersNames[name.toLowerCase()] =
9345              requestHeadersNames[name.toLowerCase()] || name;
9346              requestHeaders[name] = value;
9347            }
9348            return this;
9349          },
9350
9351          // Overrides response content-type header
9352          overrideMimeType: function (type) {
9353            if (completed == null) {
9354              s.mimeType = type;
9355            }
9356            return this;
9357          },
9358
9359          // Status-dependent callbacks
9360          statusCode: function (map) {
9361            var code;
9362            if (map) {
9363              if (completed) {
9364
9365                // Execute the appropriate callbacks
9366                jqXHR.always(map[jqXHR.status]);
9367              } else {
9368
9369                // Lazy-add the new callbacks in a way that preserves old ones
9370                for (code in map) {
9371                  statusCode[code] = [statusCode[code], map[code]];
9372                }
9373              }
9374            }
9375            return this;
9376          },
9377
9378          // Cancel the request
9379          abort: function (statusText) {
9380            var finalText = statusText || strAbort;
9381            if (transport) {
9382              transport.abort(finalText);
9383            }
9384            done(0, finalText);
9385            return this;
9386          }
9387        };
9388
9389      // Attach deferreds
9390      deferred.promise(jqXHR);
9391
9392      // Add protocol if not provided (prefilters might expect it)
9393      // Handle falsy url in the settings object (trac-10093: consistency with old signature)
9394      // We also use the url parameter if available
9395      s.url = ((url || s.url || location.href) + "").
9396      replace(rprotocol, location.protocol + "//");
9397
9398      // Alias method option to type as per ticket trac-12004
9399      s.type = options.method || options.type || s.method || s.type;
9400
9401      // Extract dataTypes list
9402      s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""];
9403
9404      // A cross-domain request is in order when the origin doesn't match the current origin.
9405      if (s.crossDomain == null) {
9406        urlAnchor = document.createElement("a");
9407
vendor: 23,119 bytes, lines 9408-10189
9408        // Support: IE <=8 - 11, Edge 12 - 15
9409        // IE throws exception on accessing the href property if url is malformed,
9410        // e.g. http://example.com:80x/
9411        try {
9412          urlAnchor.href = s.url;
9413
9414          // Support: IE <=8 - 11 only
9415          // Anchor's host property isn't correctly set when s.url is relative
9416          urlAnchor.href = urlAnchor.href;
9417          s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9418          urlAnchor.protocol + "//" + urlAnchor.host;
9419        } catch (e) {
9420
9421          // If there is an error parsing the URL, assume it is crossDomain,
9422          // it can be rejected by the transport if it is invalid
9423          s.crossDomain = true;
9424        }
9425      }
9426
9427      // Convert data if not already a string
9428      if (s.data && s.processData && typeof s.data !== "string") {
9429        s.data = jQuery.param(s.data, s.traditional);
9430      }
9431
9432      // Apply prefilters
9433      inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
9434
9435      // If request was aborted inside a prefilter, stop there
9436      if (completed) {
9437        return jqXHR;
9438      }
9439
9440      // We can fire global events as of now if asked to
9441      // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)
9442      fireGlobals = jQuery.event && s.global;
9443
9444      // Watch for a new set of requests
9445      if (fireGlobals && jQuery.active++ === 0) {
9446        jQuery.event.trigger("ajaxStart");
9447      }
9448
9449      // Uppercase the type
9450      s.type = s.type.toUpperCase();
9451
9452      // Determine if request has content
9453      s.hasContent = !rnoContent.test(s.type);
9454
9455      // Save the URL in case we're toying with the If-Modified-Since
9456      // and/or If-None-Match header later on
9457      // Remove hash to simplify url manipulation
9458      cacheURL = s.url.replace(rhash, "");
9459
9460      // More options handling for requests with no content
9461      if (!s.hasContent) {
9462
9463        // Remember the hash so we can put it back
9464        uncached = s.url.slice(cacheURL.length);
9465
9466        // If data is available and should be processed, append data to url
9467        if (s.data && (s.processData || typeof s.data === "string")) {
9468          cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data;
9469
9470          // trac-9682: remove data so that it's not used in an eventual retry
9471          delete s.data;
9472        }
9473
9474        // Add or update anti-cache param if needed
9475        if (s.cache === false) {
9476          cacheURL = cacheURL.replace(rantiCache, "$1");
9477          uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce.guid++ +
9478          uncached;
9479        }
9480
9481        // Put hash and anti-cache on the URL that will be requested (gh-1732)
9482        s.url = cacheURL + uncached;
9483
9484        // Change '%20' to '+' if this is encoded form body content (gh-2658)
9485      } else if (s.data && s.processData &&
9486      (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) {
9487        s.data = s.data.replace(r20, "+");
9488      }
9489
9490      // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9491      if (s.ifModified) {
9492        if (jQuery.lastModified[cacheURL]) {
9493          jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
9494        }
9495        if (jQuery.etag[cacheURL]) {
9496          jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
9497        }
9498      }
9499
9500      // Set the correct header, if data is being sent
9501      if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
9502        jqXHR.setRequestHeader("Content-Type", s.contentType);
9503      }
9504
9505      // Set the Accepts header for the server, depending on the dataType
9506      jqXHR.setRequestHeader(
9507        "Accept",
9508        s.dataTypes[0] && s.accepts[s.dataTypes[0]] ?
9509        s.accepts[s.dataTypes[0]] + (
9510        s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") :
9511        s.accepts["*"]
9512      );
9513
9514      // Check for headers option
9515      for (i in s.headers) {
9516        jqXHR.setRequestHeader(i, s.headers[i]);
9517      }
9518
9519      // Allow custom headers/mimetypes and early abort
9520      if (s.beforeSend && (
9521      s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) {
9522
9523        // Abort if not done already and return
9524        return jqXHR.abort();
9525      }
9526
9527      // Aborting is no longer a cancellation
9528      strAbort = "abort";
9529
9530      // Install callbacks on deferreds
9531      completeDeferred.add(s.complete);
9532      jqXHR.done(s.success);
9533      jqXHR.fail(s.error);
9534
9535      // Get transport
9536      transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
9537
9538      // If no transport, we auto-abort
9539      if (!transport) {
9540        done(-1, "No Transport");
9541      } else {
9542        jqXHR.readyState = 1;
9543
9544        // Send global event
9545        if (fireGlobals) {
9546          globalEventContext.trigger("ajaxSend", [jqXHR, s]);
9547        }
9548
9549        // If request was aborted inside ajaxSend, stop there
9550        if (completed) {
9551          return jqXHR;
9552        }
9553
9554        // Timeout
9555        if (s.async && s.timeout > 0) {
9556          timeoutTimer = window.setTimeout(function () {
9557            jqXHR.abort("timeout");
9558          }, s.timeout);
9559        }
9560
9561        try {
9562          completed = false;
9563          transport.send(requestHeaders, done);
9564        } catch (e) {
9565
9566          // Rethrow post-completion exceptions
9567          if (completed) {
9568            throw e;
9569          }
9570
9571          // Propagate others as results
9572          done(-1, e);
9573        }
9574      }
9575
9576      // Callback for when everything is done
9577      function done(status, nativeStatusText, responses, headers) {
9578        var isSuccess,success,error,response,modified,
9579          statusText = nativeStatusText;
9580
9581        // Ignore repeat invocations
9582        if (completed) {
9583          return;
9584        }
9585
9586        completed = true;
9587
9588        // Clear timeout if it exists
9589        if (timeoutTimer) {
9590          window.clearTimeout(timeoutTimer);
9591        }
9592
9593        // Dereference transport for early garbage collection
9594        // (no matter how long the jqXHR object will be used)
9595        transport = undefined;
9596
9597        // Cache response headers
9598        responseHeadersString = headers || "";
9599
9600        // Set readyState
9601        jqXHR.readyState = status > 0 ? 4 : 0;
9602
9603        // Determine if successful
9604        isSuccess = status >= 200 && status < 300 || status === 304;
9605
9606        // Get response data
9607        if (responses) {
9608          response = ajaxHandleResponses(s, jqXHR, responses);
9609        }
9610
9611        // Use a noop converter for missing script but not if jsonp
9612        if (!isSuccess &&
9613        jQuery.inArray("script", s.dataTypes) > -1 &&
9614        jQuery.inArray("json", s.dataTypes) < 0) {
9615          s.converters["text script"] = function () {};
9616        }
9617
9618        // Convert no matter what (that way responseXXX fields are always set)
9619        response = ajaxConvert(s, response, jqXHR, isSuccess);
9620
9621        // If successful, handle type chaining
9622        if (isSuccess) {
9623
9624          // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9625          if (s.ifModified) {
9626            modified = jqXHR.getResponseHeader("Last-Modified");
9627            if (modified) {
9628              jQuery.lastModified[cacheURL] = modified;
9629            }
9630            modified = jqXHR.getResponseHeader("etag");
9631            if (modified) {
9632              jQuery.etag[cacheURL] = modified;
9633            }
9634          }
9635
9636          // if no content
9637          if (status === 204 || s.type === "HEAD") {
9638            statusText = "nocontent";
9639
9640            // if not modified
9641          } else if (status === 304) {
9642            statusText = "notmodified";
9643
9644            // If we have data, let's convert it
9645          } else {
9646            statusText = response.state;
9647            success = response.data;
9648            error = response.error;
9649            isSuccess = !error;
9650          }
9651        } else {
9652
9653          // Extract error from statusText and normalize for non-aborts
9654          error = statusText;
9655          if (status || !statusText) {
9656            statusText = "error";
9657            if (status < 0) {
9658              status = 0;
9659            }
9660          }
9661        }
9662
9663        // Set data for the fake xhr object
9664        jqXHR.status = status;
9665        jqXHR.statusText = (nativeStatusText || statusText) + "";
9666
9667        // Success/Error
9668        if (isSuccess) {
9669          deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
9670        } else {
9671          deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
9672        }
9673
9674        // Status-dependent callbacks
9675        jqXHR.statusCode(statusCode);
9676        statusCode = undefined;
9677
9678        if (fireGlobals) {
9679          globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError",
9680          [jqXHR, s, isSuccess ? success : error]);
9681        }
9682
9683        // Complete
9684        completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
9685
9686        if (fireGlobals) {
9687          globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
9688
9689          // Handle the global AJAX counter
9690          if (! --jQuery.active) {
9691            jQuery.event.trigger("ajaxStop");
9692          }
9693        }
9694      }
9695
9696      return jqXHR;
9697    },
9698
9699    getJSON: function (url, data, callback) {
9700      return jQuery.get(url, data, callback, "json");
9701    },
9702
9703    getScript: function (url, callback) {
9704      return jQuery.get(url, undefined, callback, "script");
9705    }
9706  });
9707
9708  jQuery.each(["get", "post"], function (_i, method) {
9709    jQuery[method] = function (url, data, callback, type) {
9710
9711      // Shift arguments if data argument was omitted
9712      if (isFunction(data)) {
9713        type = type || callback;
9714        callback = data;
9715        data = undefined;
9716      }
9717
9718      // The url can be an options object (which then must have .url)
9719      return jQuery.ajax(jQuery.extend({
9720        url: url,
9721        type: method,
9722        dataType: type,
9723        data: data,
9724        success: callback
9725      }, jQuery.isPlainObject(url) && url));
9726    };
9727  });
9728
9729  jQuery.ajaxPrefilter(function (s) {
9730    var i;
9731    for (i in s.headers) {
9732      if (i.toLowerCase() === "content-type") {
9733        s.contentType = s.headers[i] || "";
9734      }
9735    }
9736  });
9737
9738
9739  jQuery._evalUrl = function (url, options, doc) {
9740    return jQuery.ajax({
9741      url: url,
9742
9743      // Make this explicit, since user can override this through ajaxSetup (trac-11264)
9744      type: "GET",
9745      dataType: "script",
9746      cache: true,
9747      async: false,
9748      global: false,
9749
9750      // Only evaluate the response if it is successful (gh-4126)
9751      // dataFilter is not invoked for failure responses, so using it instead
9752      // of the default converter is kludgy but it works.
9753      converters: {
9754        "text script": function () {}
9755      },
9756      dataFilter: function (response) {
9757        jQuery.globalEval(response, options, doc);
9758      }
9759    });
9760  };
9761
9762
9763  jQuery.fn.extend({
9764    wrapAll: function (html) {
9765      var wrap;
9766
9767      if (this[0]) {
9768        if (isFunction(html)) {
9769          html = html.call(this[0]);
9770        }
9771
9772        // The elements to wrap the target around
9773        wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
9774
9775        if (this[0].parentNode) {
9776          wrap.insertBefore(this[0]);
9777        }
9778
9779        wrap.map(function () {
9780          var elem = this;
9781
9782          while (elem.firstElementChild) {
9783            elem = elem.firstElementChild;
9784          }
9785
9786          return elem;
9787        }).append(this);
9788      }
9789
9790      return this;
9791    },
9792
9793    wrapInner: function (html) {
9794      if (isFunction(html)) {
9795        return this.each(function (i) {
9796          jQuery(this).wrapInner(html.call(this, i));
9797        });
9798      }
9799
9800      return this.each(function () {
9801        var self = jQuery(this),
9802          contents = self.contents();
9803
9804        if (contents.length) {
9805          contents.wrapAll(html);
9806
9807        } else {
9808          self.append(html);
9809        }
9810      });
9811    },
9812
9813    wrap: function (html) {
9814      var htmlIsFunction = isFunction(html);
9815
9816      return this.each(function (i) {
9817        jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html);
9818      });
9819    },
9820
9821    unwrap: function (selector) {
9822      this.parent(selector).not("body").each(function () {
9823        jQuery(this).replaceWith(this.childNodes);
9824      });
9825      return this;
9826    }
9827  });
9828
9829
9830  jQuery.expr.pseudos.hidden = function (elem) {
9831    return !jQuery.expr.pseudos.visible(elem);
9832  };
9833  jQuery.expr.pseudos.visible = function (elem) {
9834    return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
9835  };
9836
9837
9838
9839
9840  jQuery.ajaxSettings.xhr = function () {
9841    try {
9842      return new window.XMLHttpRequest();
9843    } catch (e) {}
9844  };
9845
9846  var xhrSuccessStatus = {
9847
9848      // File protocol always yields status code 0, assume 200
9849      0: 200,
9850
9851      // Support: IE <=9 only
9852      // trac-1450: sometimes IE returns 1223 when it should be 204
9853      1223: 204
9854    },
9855    xhrSupported = jQuery.ajaxSettings.xhr();
9856
9857  support.cors = !!xhrSupported && "withCredentials" in xhrSupported;
9858  support.ajax = xhrSupported = !!xhrSupported;
9859
9860  jQuery.ajaxTransport(function (options) {
9861    var callback, errorCallback;
9862
9863    // Cross domain only allowed if supported through XMLHttpRequest
9864    if (support.cors || xhrSupported && !options.crossDomain) {
9865      return {
9866        send: function (headers, complete) {
9867          var i,
9868            xhr = options.xhr();
9869
9870          xhr.open(
9871            options.type,
9872            options.url,
9873            options.async,
9874            options.username,
9875            options.password
9876          );
9877
9878          // Apply custom fields if provided
9879          if (options.xhrFields) {
9880            for (i in options.xhrFields) {
9881              xhr[i] = options.xhrFields[i];
9882            }
9883          }
9884
9885          // Override mime type if needed
9886          if (options.mimeType && xhr.overrideMimeType) {
9887            xhr.overrideMimeType(options.mimeType);
9888          }
9889
9890          // X-Requested-With header
9891          // For cross-domain requests, seeing as conditions for a preflight are
9892          // akin to a jigsaw puzzle, we simply never set it to be sure.
9893          // (it can always be set on a per-request basis or even using ajaxSetup)
9894          // For same-domain requests, won't change header if already provided.
9895          if (!options.crossDomain && !headers["X-Requested-With"]) {
9896            headers["X-Requested-With"] = "XMLHttpRequest";
9897          }
9898
9899          // Set headers
9900          for (i in headers) {
9901            xhr.setRequestHeader(i, headers[i]);
9902          }
9903
9904          // Callback
9905          callback = function (type) {
9906            return function () {
9907              if (callback) {
9908                callback = errorCallback = xhr.onload =
9909                xhr.onerror = xhr.onabort = xhr.ontimeout =
9910                xhr.onreadystatechange = null;
9911
9912                if (type === "abort") {
9913                  xhr.abort();
9914                } else if (type === "error") {
9915
9916                  // Support: IE <=9 only
9917                  // On a manual native abort, IE9 throws
9918                  // errors on any property access that is not readyState
9919                  if (typeof xhr.status !== "number") {
9920                    complete(0, "error");
9921                  } else {
9922                    complete(
9923
9924                      // File: protocol always yields status 0; see trac-8605, trac-14207
9925                      xhr.status,
9926                      xhr.statusText
9927                    );
9928                  }
9929                } else {
9930                  complete(
9931                    xhrSuccessStatus[xhr.status] || xhr.status,
9932                    xhr.statusText,
9933
9934                    // Support: IE <=9 only
9935                    // IE9 has no XHR2 but throws on binary (trac-11426)
9936                    // For XHR2 non-text, let the caller handle it (gh-2498)
9937                    (xhr.responseType || "text") !== "text" ||
9938                    typeof xhr.responseText !== "string" ?
9939                    { binary: xhr.response } :
9940                    { text: xhr.responseText },
9941                    xhr.getAllResponseHeaders()
9942                  );
9943                }
9944              }
9945            };
9946          };
9947
9948          // Listen to events
9949          xhr.onload = callback();
9950          errorCallback = xhr.onerror = xhr.ontimeout = callback("error");
9951
9952          // Support: IE 9 only
9953          // Use onreadystatechange to replace onabort
9954          // to handle uncaught aborts
9955          if (xhr.onabort !== undefined) {
9956            xhr.onabort = errorCallback;
9957          } else {
9958            xhr.onreadystatechange = function () {
9959
9960              // Check readyState before timeout as it changes
9961              if (xhr.readyState === 4) {
9962
9963                // Allow onerror to be called first,
9964                // but that will not handle a native abort
9965                // Also, save errorCallback to a variable
9966                // as xhr.onerror cannot be accessed
9967                window.setTimeout(function () {
9968                  if (callback) {
9969                    errorCallback();
9970                  }
9971                });
9972              }
9973            };
9974          }
9975
9976          // Create the abort callback
9977          callback = callback("abort");
9978
9979          try {
9980
9981            // Do send the request (this may raise an exception)
9982            xhr.send(options.hasContent && options.data || null);
9983          } catch (e) {
9984
9985            // trac-14683: Only rethrow if this hasn't been notified as an error yet
9986            if (callback) {
9987              throw e;
9988            }
9989          }
9990        },
9991
9992        abort: function () {
9993          if (callback) {
9994            callback();
9995          }
9996        }
9997      };
9998    }
9999  });
10000
10001
10002
10003
10004  // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
10005  jQuery.ajaxPrefilter(function (s) {
10006    if (s.crossDomain) {
10007      s.contents.script = false;
10008    }
10009  });
10010
10011  // Install script dataType
10012  jQuery.ajaxSetup({
10013    accepts: {
10014      script: "text/javascript, application/javascript, " +
10015      "application/ecmascript, application/x-ecmascript"
10016    },
10017    contents: {
10018      script: /\b(?:java|ecma)script\b/
10019    },
10020    converters: {
10021      "text script": function (text) {
10022        jQuery.globalEval(text);
10023        return text;
10024      }
10025    }
10026  });
10027
10028  // Handle cache's special case and crossDomain
10029  jQuery.ajaxPrefilter("script", function (s) {
10030    if (s.cache === undefined) {
10031      s.cache = false;
10032    }
10033    if (s.crossDomain) {
10034      s.type = "GET";
10035    }
10036  });
10037
10038  // Bind script tag hack transport
10039  jQuery.ajaxTransport("script", function (s) {
10040
10041    // This transport only deals with cross domain or forced-by-attrs requests
10042    if (s.crossDomain || s.scriptAttrs) {
10043      var script, callback;
10044      return {
10045        send: function (_, complete) {
10046          script = jQuery("<script>").
10047          attr(s.scriptAttrs || {}).
10048          prop({ charset: s.scriptCharset, src: s.url }).
10049          on("load error", callback = function (evt) {
10050            script.remove();
10051            callback = null;
10052            if (evt) {
10053              complete(evt.type === "error" ? 404 : 200, evt.type);
10054            }
10055          });
10056
10057          // Use native DOM manipulation to avoid our domManip AJAX trickery
10058          document.head.appendChild(script[0]);
10059        },
10060        abort: function () {
10061          if (callback) {
10062            callback();
10063          }
10064        }
10065      };
10066    }
10067  });
10068
10069
10070
10071
10072  var oldCallbacks = [],
10073    rjsonp = /(=)\?(?=&|$)|\?\?/;
10074
10075  // Default jsonp settings
10076  jQuery.ajaxSetup({
10077    jsonp: "callback",
10078    jsonpCallback: function () {
10079      var callback = oldCallbacks.pop() || jQuery.expando + "_" + nonce.guid++;
10080      this[callback] = true;
10081      return callback;
10082    }
10083  });
10084
10085  // Detect, normalize options and install callbacks for jsonp requests
10086  jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {
10087
10088    var callbackName,overwritten,responseContainer,
10089      jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ?
10090      "url" :
10091      typeof s.data === "string" &&
10092      (s.contentType || "").
10093      indexOf("application/x-www-form-urlencoded") === 0 &&
10094      rjsonp.test(s.data) && "data");
10095
10096
10097    // Handle iff the expected data type is "jsonp" or we have a parameter to set
10098    if (jsonProp || s.dataTypes[0] === "jsonp") {
10099
10100      // Get callback name, remembering preexisting value associated with it
10101      callbackName = s.jsonpCallback = isFunction(s.jsonpCallback) ?
10102      s.jsonpCallback() :
10103      s.jsonpCallback;
10104
10105      // Insert callback into url or form data
10106      if (jsonProp) {
10107        s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
10108      } else if (s.jsonp !== false) {
10109        s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
10110      }
10111
10112      // Use data converter to retrieve json after script execution
10113      s.converters["script json"] = function () {
10114        if (!responseContainer) {
10115          jQuery.error(callbackName + " was not called");
10116        }
10117        return responseContainer[0];
10118      };
10119
10120      // Force json dataType
10121      s.dataTypes[0] = "json";
10122
10123      // Install callback
10124      overwritten = window[callbackName];
10125      window[callbackName] = function () {
10126        responseContainer = arguments;
10127      };
10128
10129      // Clean-up function (fires after converters)
10130      jqXHR.always(function () {
10131
10132        // If previous value didn't exist - remove it
10133        if (overwritten === undefined) {
10134          jQuery(window).removeProp(callbackName);
10135
10136          // Otherwise restore preexisting value
10137        } else {
10138          window[callbackName] = overwritten;
10139        }
10140
10141        // Save back as free
10142        if (s[callbackName]) {
10143
10144          // Make sure that re-using the options doesn't screw things around
10145          s.jsonpCallback = originalSettings.jsonpCallback;
10146
10147          // Save the callback name for future use
10148          oldCallbacks.push(callbackName);
10149        }
10150
10151        // Call if it was a function and we have a response
10152        if (responseContainer && isFunction(overwritten)) {
10153          overwritten(responseContainer[0]);
10154        }
10155
10156        responseContainer = overwritten = undefined;
10157      });
10158
10159      // Delegate to script
10160      return "script";
10161    }
10162  });
10163
10164
10165
10166
10167  // Support: Safari 8 only
10168  // In Safari 8 documents created via document.implementation.createHTMLDocument
10169  // collapse sibling forms: the second one becomes a child of the first one.
10170  // Because of that, this security measure has to be disabled in Safari 8.
10171  // https://bugs.webkit.org/show_bug.cgi?id=137337
10172  support.createHTMLDocument = function () {
10173    var body = document.implementation.createHTMLDocument("").body;
10174    body.innerHTML = "<form></form><form></form>";
10175    return body.childNodes.length === 2;
10176  }();
10177
10178
10179  // Argument "data" should be string of html
10180  // context (optional): If specified, the fragment will be created in this context,
10181  // defaults to document
10182  // keepScripts (optional): If true, will include scripts passed in the html string
10183  jQuery.parseHTML = function (data, context, keepScripts) {
10184    if (typeof data !== "string") {
10185      return [];
10186    }
10187    if (typeof context === "boolean") {
10188      keepScripts = context;
10189      context = false;
vendor: 5,097 bytes, lines 10190-10378
10190    }
10191
10192    var base, parsed, scripts;
10193
10194    if (!context) {
10195
10196      // Stop scripts or inline event handlers from being executed immediately
10197      // by using document.implementation
10198      if (support.createHTMLDocument) {
10199        context = document.implementation.createHTMLDocument("");
10200
10201        // Set the base href for the created document
10202        // so any parsed elements with URLs
10203        // are based on the document's URL (gh-2965)
10204        base = context.createElement("base");
10205        base.href = document.location.href;
10206        context.head.appendChild(base);
10207      } else {
10208        context = document;
10209      }
10210    }
10211
10212    parsed = rsingleTag.exec(data);
10213    scripts = !keepScripts && [];
10214
10215    // Single tag
10216    if (parsed) {
10217      return [context.createElement(parsed[1])];
10218    }
10219
10220    parsed = buildFragment([data], context, scripts);
10221
10222    if (scripts && scripts.length) {
10223      jQuery(scripts).remove();
10224    }
10225
10226    return jQuery.merge([], parsed.childNodes);
10227  };
10228
10229
10230  /**
10231   * Load a url into a page
10232   */
10233  jQuery.fn.load = function (url, params, callback) {
10234    var selector,type,response,
10235      self = this,
10236      off = url.indexOf(" ");
10237
10238    if (off > -1) {
10239      selector = stripAndCollapse(url.slice(off));
10240      url = url.slice(0, off);
10241    }
10242
10243    // If it's a function
10244    if (isFunction(params)) {
10245
10246      // We assume that it's the callback
10247      callback = params;
10248      params = undefined;
10249
10250      // Otherwise, build a param string
10251    } else if (params && typeof params === "object") {
10252      type = "POST";
10253    }
10254
10255    // If we have elements to modify, make the request
10256    if (self.length > 0) {
10257      jQuery.ajax({
10258        url: url,
10259
10260        // If "type" variable is undefined, then "GET" method will be used.
10261        // Make value of this field explicit since
10262        // user can override it through ajaxSetup method
10263        type: type || "GET",
10264        dataType: "html",
10265        data: params
10266      }).done(function (responseText) {
10267
10268        // Save response for use in complete callback
10269        response = arguments;
10270
10271        self.html(selector ?
10272
10273        // If a selector was specified, locate the right elements in a dummy div
10274        // Exclude scripts to avoid IE 'Permission Denied' errors
10275        jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
10276
10277        // Otherwise use the full result
10278        responseText);
10279
10280        // If the request succeeds, this function gets "data", "status", "jqXHR"
10281        // but they are ignored because response was set above.
10282        // If it fails, this function gets "jqXHR", "status", "error"
10283      }).always(callback && function (jqXHR, status) {
10284        self.each(function () {
10285          callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
10286        });
10287      });
10288    }
10289
10290    return this;
10291  };
10292
10293
10294
10295
10296  jQuery.expr.pseudos.animated = function (elem) {
10297    return jQuery.grep(jQuery.timers, function (fn) {
10298      return elem === fn.elem;
10299    }).length;
10300  };
10301
10302
10303
10304
10305  jQuery.offset = {
10306    setOffset: function (elem, options, i) {
10307      var curPosition,curLeft,curCSSTop,curTop,curOffset,curCSSLeft,calculatePosition,
10308        position = jQuery.css(elem, "position"),
10309        curElem = jQuery(elem),
10310        props = {};
10311
10312      // Set position first, in-case top/left are set even on static elem
10313      if (position === "static") {
10314        elem.style.position = "relative";
10315      }
10316
10317      curOffset = curElem.offset();
10318      curCSSTop = jQuery.css(elem, "top");
10319      curCSSLeft = jQuery.css(elem, "left");
10320      calculatePosition = (position === "absolute" || position === "fixed") &&
10321      (curCSSTop + curCSSLeft).indexOf("auto") > -1;
10322
10323      // Need to be able to calculate position if either
10324      // top or left is auto and position is either absolute or fixed
10325      if (calculatePosition) {
10326        curPosition = curElem.position();
10327        curTop = curPosition.top;
10328        curLeft = curPosition.left;
10329
10330      } else {
10331        curTop = parseFloat(curCSSTop) || 0;
10332        curLeft = parseFloat(curCSSLeft) || 0;
10333      }
10334
10335      if (isFunction(options)) {
10336
10337        // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10338        options = options.call(elem, i, jQuery.extend({}, curOffset));
10339      }
10340
10341      if (options.top != null) {
10342        props.top = options.top - curOffset.top + curTop;
10343      }
10344      if (options.left != null) {
10345        props.left = options.left - curOffset.left + curLeft;
10346      }
10347
10348      if ("using" in options) {
10349        options.using.call(elem, props);
10350
10351      } else {
10352        curElem.css(props);
10353      }
10354    }
10355  };
10356
10357  jQuery.fn.extend({
10358
10359    // offset() relates an element's border box to the document origin
10360    offset: function (options) {
10361
10362      // Preserve chaining for setter
10363      if (arguments.length) {
10364        return options === undefined ?
10365        this :
10366        this.each(function (i) {
10367          jQuery.offset.setOffset(this, options, i);
10368        });
10369      }
10370
10371      var rect,win,
10372        elem = this[0];
10373
10374      if (!elem) {
10375        return;
10376      }
10377
10378      // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
vendor: 5,057 bytes, lines 10379-10520
10379      // Support: IE <=11 only
10380      // Running getBoundingClientRect on a
10381      // disconnected node in IE throws an error
10382      if (!elem.getClientRects().length) {
10383        return { top: 0, left: 0 };
10384      }
10385
10386      // Get document-relative position by adding viewport scroll to viewport-relative gBCR
10387      rect = elem.getBoundingClientRect();
10388      win = elem.ownerDocument.defaultView;
10389      return {
10390        top: rect.top + win.pageYOffset,
10391        left: rect.left + win.pageXOffset
10392      };
10393    },
10394
10395    // position() relates an element's margin box to its offset parent's padding box
10396    // This corresponds to the behavior of CSS absolute positioning
10397    position: function () {
10398      if (!this[0]) {
10399        return;
10400      }
10401
10402      var offsetParent,offset,doc,
10403        elem = this[0],
10404        parentOffset = { top: 0, left: 0 };
10405
10406      // position:fixed elements are offset from the viewport, which itself always has zero offset
10407      if (jQuery.css(elem, "position") === "fixed") {
10408
10409        // Assume position:fixed implies availability of getBoundingClientRect
10410        offset = elem.getBoundingClientRect();
10411
10412      } else {
10413        offset = this.offset();
10414
10415        // Account for the *real* offset parent, which can be the document or its root element
10416        // when a statically positioned element is identified
10417        doc = elem.ownerDocument;
10418        offsetParent = elem.offsetParent || doc.documentElement;
10419        while (offsetParent && (
10420        offsetParent === doc.body || offsetParent === doc.documentElement) &&
10421        jQuery.css(offsetParent, "position") === "static") {
10422
10423          offsetParent = offsetParent.parentNode;
10424        }
10425        if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) {
10426
10427          // Incorporate borders into its offset, since they are outside its content origin
10428          parentOffset = jQuery(offsetParent).offset();
10429          parentOffset.top += jQuery.css(offsetParent, "borderTopWidth", true);
10430          parentOffset.left += jQuery.css(offsetParent, "borderLeftWidth", true);
10431        }
10432      }
10433
10434      // Subtract parent offsets and element margins
10435      return {
10436        top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
10437        left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
10438      };
10439    },
10440
10441    // This method will return documentElement in the following cases:
10442    // 1) For the element inside the iframe without offsetParent, this method will return
10443    //    documentElement of the parent window
10444    // 2) For the hidden or detached element
10445    // 3) For body or html element, i.e. in case of the html node - it will return itself
10446    //
10447    // but those exceptions were never presented as a real life use-cases
10448    // and might be considered as more preferable results.
10449    //
10450    // This logic, however, is not guaranteed and can change at any point in the future
10451    offsetParent: function () {
10452      return this.map(function () {
10453        var offsetParent = this.offsetParent;
10454
10455        while (offsetParent && jQuery.css(offsetParent, "position") === "static") {
10456          offsetParent = offsetParent.offsetParent;
10457        }
10458
10459        return offsetParent || documentElement;
10460      });
10461    }
10462  });
10463
10464  // Create scrollLeft and scrollTop methods
10465  jQuery.each({ scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function (method, prop) {
10466    var top = "pageYOffset" === prop;
10467
10468    jQuery.fn[method] = function (val) {
10469      return access(this, function (elem, method, val) {
10470
10471        // Coalesce documents and windows
10472        var win;
10473        if (isWindow(elem)) {
10474          win = elem;
10475        } else if (elem.nodeType === 9) {
10476          win = elem.defaultView;
10477        }
10478
10479        if (val === undefined) {
10480          return win ? win[prop] : elem[method];
10481        }
10482
10483        if (win) {
10484          win.scrollTo(
10485            !top ? val : win.pageXOffset,
10486            top ? val : win.pageYOffset
10487          );
10488
10489        } else {
10490          elem[method] = val;
10491        }
10492      }, method, val, arguments.length);
10493    };
10494  });
10495
10496  // Support: Safari <=7 - 9.1, Chrome <=37 - 49
10497  // Add the top/left cssHooks using jQuery.fn.position
10498  // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10499  // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10500  // getComputedStyle returns percent when specified for top/left/bottom/right;
10501  // rather than make the css module depend on the offset module, just check for it here
10502  jQuery.each(["top", "left"], function (_i, prop) {
10503    jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition,
10504    function (elem, computed) {
10505      if (computed) {
10506        computed = curCSS(elem, prop);
10507
10508        // If curCSS returns percentage, fallback to offset
10509        return rnumnonpx.test(computed) ?
10510        jQuery(elem).position()[prop] + "px" :
10511        computed;
10512      }
10513    }
10514    );
10515  });
10516
10517
10518  // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10519  jQuery.each({ Height: "height", Width: "width" }, function (name, type) {
10520    jQuery.each({
10521      padding: "inner" + name,
10522      content: type,
10523      "": "outer" + name
10524    }, function (defaultExtra, funcName) {
10525
10526      // Margin is only for outerHeight, outerWidth
10527      jQuery.fn[funcName] = function (margin, value) {
10528        var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
10529          extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
10530
10531        return access(this, function (elem, type, value) {
10532          var doc;
10533
10534          if (isWindow(elem)) {
10535
10536            // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10537            return funcName.indexOf("outer") === 0 ?
10538            elem["inner" + name] :
10539            elem.document.documentElement["client" + name];
10540          }
10541
10542          // Get document width or height
10543          if (elem.nodeType === 9) {
10544            doc = elem.documentElement;
10545
10546            // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10547            // whichever is greatest
10548            return Math.max(
10549              elem.body["scroll" + name], doc["scroll" + name],
10550              elem.body["offset" + name], doc["offset" + name],
10551              doc["client" + name]
10552            );
10553          }
10554
10555          return value === undefined ?
10556
10557          // Get width or height on the element, requesting but not forcing parseFloat
10558          jQuery.css(elem, type, extra) :
10559
10560          // Set width or height on the element
10561          jQuery.style(elem, type, value, extra);
10562        }, type, chainable ? margin : undefined, chainable);
10563      };
10564    });
10565  });
10566
10567
10568  jQuery.each([
10569  "ajaxStart",
10570  "ajaxStop",
10571  "ajaxComplete",
10572  "ajaxError",
10573  "ajaxSuccess",
10574  "ajaxSend"],
10575  function (_i, type) {
10576    jQuery.fn[type] = function (fn) {
10577      return this.on(type, fn);
10578    };
10579  });
10580
10581
10582
10583
10584  jQuery.fn.extend({
10585
10586    bind: function (types, data, fn) {
10587      return this.on(types, null, data, fn);
10588    },
10589    unbind: function (types, fn) {
10590      return this.off(types, null, fn);
10591    },
10592
10593    delegate: function (selector, types, data, fn) {
10594      return this.on(types, selector, data, fn);
10595    },
10596    undelegate: function (selector, types, fn) {
10597
10598      // ( namespace ) or ( selector, types [, fn] )
10599      return arguments.length === 1 ?
10600      this.off(selector, "**") :
10601      this.off(types, selector || "**", fn);
10602    },
10603
10604    hover: function (fnOver, fnOut) {
10605      return this.
10606      on("mouseenter", fnOver).
10607      on("mouseleave", fnOut || fnOver);
10608    }
10609  });
10610
10611  jQuery.each(
10612    ("blur focus focusin focusout resize scroll click dblclick " +
10613    "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
10614    "change select submit keydown keypress keyup contextmenu").split(" "),
10615    function (_i, name) {
10616
10617      // Handle event binding
10618      jQuery.fn[name] = function (data, fn) {
10619        return arguments.length > 0 ?
10620        this.on(name, null, data, fn) :
10621        this.trigger(name);
10622      };
10623    }
10624  );
10625
10626
10627
10628
10629  // Support: Android <=4.0 only
10630  // Make sure we trim BOM and NBSP
10631  // Require that the "whitespace run" starts from a non-whitespace
10632  // to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position.
10633  var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;
10634
10635  // Bind a function to a context, optionally partially applying any
10636  // arguments.
10637  // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
10638  // However, it is not slated for removal any time soon
10639  jQuery.proxy = function (fn, context) {
10640    var tmp, args, proxy;
10641
10642    if (typeof context === "string") {
10643      tmp = fn[context];
10644      context = fn;
10645      fn = tmp;
10646    }
10647
10648    // Quick check to determine if target is callable, in the spec
10649    // this throws a TypeError, but we will just return undefined.
10650    if (!isFunction(fn)) {
10651      return undefined;
10652    }
10653
10654    // Simulated bind
10655    args = slice.call(arguments, 2);
10656    proxy = function () {
10657      return fn.apply(context || this, args.concat(slice.call(arguments)));
10658    };
10659
10660    // Set the guid of unique handler to the same of original handler, so it can be removed
10661    proxy.guid = fn.guid = fn.guid || jQuery.guid++;
10662
10663    return proxy;
10664  };
10665
10666  jQuery.holdReady = function (hold) {
10667    if (hold) {
10668      jQuery.readyWait++;
10669    } else {
10670      jQuery.ready(true);
10671    }
10672  };
10673  jQuery.isArray = Array.isArray;
10674  jQuery.parseJSON = JSON.parse;
10675  jQuery.nodeName = nodeName;
10676  jQuery.isFunction = isFunction;
10677  jQuery.isWindow = isWindow;
10678  jQuery.camelCase = camelCase;
10679  jQuery.type = toType;
10680
10681  jQuery.now = Date.now;
10682
10683  jQuery.isNumeric = function (obj) {
10684
10685    // As of jQuery 3.0, isNumeric is limited to
10686    // strings and numbers (primitives or objects)
10687    // that can be coerced to finite numbers (gh-2662)
10688    var type = jQuery.type(obj);
10689    return (type === "number" || type === "string") &&
10690
10691    // parseFloat NaNs numeric-cast false positives ("")
10692    // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
10693    // subtraction forces infinities to NaN
10694    !isNaN(obj - parseFloat(obj));
10695  };
10696
10697  jQuery.trim = function (text) {
10698    return text == null ?
10699    "" :
10700    (text + "").replace(rtrim, "$1");
10701  };
10702
10703
10704
10705  // Register as a named AMD module, since jQuery can be concatenated with other
10706  // files that may use define, but not via a proper concatenation script that
10707  // understands anonymous AMD modules. A named AMD is safest and most robust
10708  // way to register. Lowercase jquery is used because AMD module names are
10709  // derived from file names, and jQuery is normally delivered in a lowercase
10710  // file name. Do this after creating the global so that if an AMD module wants
10711  // to call noConflict to hide this version of jQuery, it will work.
10712
10713  // Note that for maximum portability, libraries that are not jQuery should
10714  // declare themselves as anonymous modules, and avoid setting a global if an
10715  // AMD loader is present. jQuery is a special case. For more information, see
10716  // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10717
10718  if (typeof define === "function" && define.amd) {
10719    define("jquery", [], function () {
10720      return jQuery;
10721    });
10722  }
10723
10724
10725
10726
10727  var
10728
10729    // Map over jQuery in case of overwrite
10730    _jQuery = window.jQuery,
10731
10732    // Map over the $ in case of overwrite
10733    _$ = window.$;
10734
10735  jQuery.noConflict = function (deep) {
10736    if (window.$ === jQuery) {
10737      window.$ = _$;
10738    }
10739
10740    if (deep && window.jQuery === jQuery) {
10741      window.jQuery = _jQuery;
10742    }
10743
10744    return jQuery;
10745  };
10746
10747  // Expose jQuery and $ identifiers, even in AMD
10748  // (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)
10749  // and CommonJS for browser emulators (trac-13566)
10750  if (typeof noGlobal === "undefined") {
10751    window.jQuery = window.$ = jQuery;
10752  }
10753
10754
10755
10756
10757  return jQuery;
10758});
10759
10760    /* Ende jquery */
10761    /* Start tracking */
10762        "use strict";var _paq=_paq||[];function matomoConsentFunction(){var t=$("body").attr("data-tracking-site-id"),e=document.createElement("script");_paq.push(["setConsentGiven"]),/^\d+$/u.test(t)&&0===$("#cmsMatomoScript").length&&(_paq.push(["disableCookies"]),_paq.push(["requireConsent"]),_paq.push(["setDocumentTitle",`${document.domain}/${document.title}`]),_paq.push(["trackPageView"]),_paq.push(["enableLinkTracking"]),_paq.push(["setTrackerUrl","//piwik.itzbund.de/js/"]),_paq.push(["setSiteId",Number(t)]),e.id="cmsMatomoScript",e.type="text/javascript",e.async=!0,e.defer=!0,e.src="//piwik.itzbund.de/js/",document.head.appendChild(e))}function matomoRejectFunction(){_paq.push(["forgetConsentGiven"])}function setConsent(){document.cookie.match(/matomoTracking=true/u)?matomoConsentFunction():matomoRejectFunction()}setConsent(),$("#cookiebanner").on("afterClose",function(){setConsent()});
10763
10764    /* Ende tracking */
10765    /* Start cms_aria */
10766        /*! --GSBDocStart
10767 * @name: @cms/cms_aria
10768 * @version: 2.0.0
10769 * @description: A toggle mechanism for aria attributes
10770 * --CMSDocEnd
10771*/"use strict";
10772var cms;
10773cms = cms || {};
10774(function ($, cms) {
10775  // Entry point into lib, is called by module.
10776  cms.aria = function aria(el, options, params) {// Creates, initializes and returns an instance of a cms_aria Module
10777    var base = Object.create(aria.prototype); // Instance of aria-object is used in.
10778    base.$el = $(el);
10779    base.el = el;
10780    base.moduleName = "cms.aria";
10781    base.$el.data(base.moduleName, base);
10782    base.options = $.extend({}, cms.aria.defaultOptions, options);
10783    base.init(el, options, params);
10784    return base;
10785  };
10786
10787  cms.aria.prototype = {
10788    /**
10789     * @method generateID
10790     * @desc generiert eine ID aus einer Zufallszahl und dessen toString result mit der Basis 36
10791     */
10792    generateID: function () {
10793      // Math.random should be unique because of its seeding algorithm.
10794      // Convert it to base 36 (numbers + letters), and grab the first 9 characters
10795      // after the decimal.
10796      return '_' + Math.random().toString(36).substr(2, 9);
10797    },
10798
10799    // Initializes elements with starting values.
10800    setInitialValues: function () {
10801      var base = this;
10802
10803      // Closes every Element in "Types" as default init.
10804      Object.keys(base.types).forEach(function (typeName) {
10805        var type = this[typeName];
10806        base.applyToggle(type, typeName, 1);
10807        type.prop('cms_aria_index', function (index) {return index;});
10808      }, base.types);
10809
10810      // Applies Initializing Functions, Values as defined in Module "Aria-Initialize-Object" to elements.
10811      base.initial.forEach(function (statement) {
10812        var typeName = statement._type,
10813          type = base.types[typeName];
10814        Object.keys(statement).forEach(function (attrName) {
10815          var attrValue = statement[attrName];
10816          if (attrName === "_type") {
10817
10818            //ignore
10819          } else if (attrName === "class") {
10820            //ignore
10821          } else if (typeof attrValue === "function") {type.each(function (i, el) {
10822              $(el).attr(attrName, attrValue.call(base, base, i, attrName)); // <-  If Initialize contains Function on Key, it is called
10823            }); //      and it's return value assigned to element. (HTML-Tag)
10824          } else {
10825            type.attr(attrName, attrValue); // <- Value assigned to element.
10826          }
10827        });
10828      });
10829    },
10830
10831    // Sets the Options to the values given by Module.
10832    init: function (_, __, params) {// Gets "Types" (Class Names), "Initials" (Initial Values) and "Toggles" (Values for 'open' and 'close)
10833      this.types = params.types;
10834      this.initial = params.initial;
10835      this.toggles = params.toggles;
10836      this.setInitialValues();
10837    },
10838
10839    // Gets the by the current toggle value of an element and returns those as object of attributes.
10840    getToggleValues: function (object, index) {
10841      var values = {};
10842      Object.keys(object || {}).forEach(function (key) {
10843        if (key !== "class" && key !== "style") {
10844          values[key] = object[key][index];
10845        }
10846      });
10847      return values;
10848    },
10849
10850    // Applies the toggle changes defined by the module it is used by.
10851    applyToggle: function ($elements, typeName, index) {
10852      var base = this,
10853        toggles = base.toggles[typeName] || {},
10854        classes = toggles["class"] || [];
10855      $elements.attr(base.getToggleValues(toggles, index)); // <- Gets toggle values defined by the cms_module it is used by and applies them to current element
10856      $elements.removeClass(classes[index === 0 ? 1 : 0]); // <- Specifically deals with class changes of html elements.
10857      $elements.addClass(classes[index]); //     Which are treated different than other HTML-Tag properties.
10858    },
10859
10860    // Is called when the aria status of an element should be changed/updated.
10861    updateAria: function (elem, open, singleOpen) {
10862      var base = this,
10863        index = elem['cms_aria_index'];
10864      if (!open || singleOpen) {
10865        Object.keys(base.types).forEach(function (typeName) {
10866          var type = base.types[typeName];
10867          base.applyToggle($(type[index]), typeName, open ? 0 : 1);
10868        });
10869      } else {
10870        Object.keys(base.types).forEach(function (typeName) {
10871          var type = base.types[typeName];
10872          $(type).each(function (idx) {
10873            if (index === idx) {
10874              // Toggles Element that should be opened to open, in regard to aria toggle
10875              base.applyToggle($(type[idx]), typeName, 0);
10876            } else {
10877              // Toggles Element that should be closed to closed, in regard to aria toggle
10878              base.applyToggle($(type[idx]), typeName, 1);
10879            }
10880          });
10881        });
10882      }
10883    }
10884  };
10885
10886  cms.aria.defaultOptions = {
10887
10888    //options
10889  };})(jQuery, cms);
10890
10891    /* Ende cms_aria */
10892    /* Start cms_makeCMSModule */
10893        /*! --GSBDocStart
10894 * @name: @cms/cms_makeCMSModule
10895 * @version: 3.0.1
10896 * @description: JS-Modul-Factory
10897 * --CMSDocEnd
10898*/"use strict";
10899var cms;
10900cms = cms || {};
10901(function ($, cms) {
10902
10903  /* @example
10904   * function module(){}
10905   * var $;
10906   * set($, ['cms', 'foo', 'bar'], module);
10907   * $.cms && $.cms.foo && $.cms.foo.bar === module //true
10908   */
10909  function set(object, namespace, value) {// Build name space recursively and adds the "module(el, userOptions, ...additionalParameters)"
10910    var i,l = namespace.length - 1, // function to last ID of given namespace. Skips existing IDs, adds empty object for none existing.
10911      property,last = namespace[l];
10912    for (i = 0; i < l; i++) {
10913      property = namespace[i];
10914      object[property] = object[property] || {};
10915      object = object[property];
10916    }
10917    object[last] = value;
10918  }
10919  /* @example
10920   * var $ = {
10921   *   cms: {
10922   *     foo: {
10923   *       bar: function(x){
10924   *         return x;
10925   *       }
10926   *     }
10927   *   }
10928   * };
10929   * apply($, ['cms', 'foo', 'bar'], ['baz']) === 'baz' //true
10930   */
10931  function apply(object, namespace, args) {// Descents recursively through namespace and calls last ID if it contains a function.
10932    var i,l = namespace.length - 1, // Should be "module(el, userOptions, ...additionalParameters)" function.
10933      property,last = namespace[l];
10934    for (i = 0; i < l; i++) {
10935      property = namespace[i];
10936      object = object && object[property];
10937    }
10938    if (typeof object[last] === "function") {
10939      object[last].apply(object, args);
10940    }
10941  }
10942
10943  // Adds meta properties to the module template. Currently: eventName and moduleName as identifier.
10944  function enhance(fullName, namespace, template) {//returns an "enhanced" copy of a template
10945    return $.extend(true, {
10946      eventName: namespace.slice().reverse().join('.'),
10947      moduleName: fullName,
10948      generateID: function () {
10949        // Math.random should be unique because of its seeding algorithm.
10950        // Convert it to base 36 (numbers + letters), and grab the first 9 characters
10951        // after the decimal.
10952        return '_' + Math.random().toString(36).substr(2, 9);
10953      },
10954      sharedBetweenInstances: {
10955        instanceCount: 0
10956      }
10957    }, template);
10958  }
10959
10960  // Is called in each Module respectively. Registers the Modules build process to the jQuery Prototype. Adds a shortcut to execute
10961  // initialization of module to a list jQuery objects.
10962  cms.makeCMSModule = function makeCMSModule(fullName, template) {
10963    var namespace = fullName.split('.');
10964
10965    // A function to initialize an instance of a module inside a jQuery object.
10966    function module(el, userOptions, ...additionalParameters) {
10967      var base = $.extend({}, template);
10968      base.el = el;
10969      base.$el = $(el);
10970      base.options = $.extend(true, {}, template.defaultOptions, userOptions);
10971      base.$el.data(namespace.join('.'), base);
10972      base.sharedBetweenInstances.instanceCount++;
10973      base.instanceNamespace = '.instance' + base.sharedBetweenInstances.instanceCount + '.' + base.eventName;
10974      base.init(el, userOptions, ...additionalParameters);
10975    }
10976
10977    template = enhance(fullName, namespace, template);
10978
10979    module.defaultOptions = template.defaultOptions || {};
10980
10981    set($, namespace, module);
10982
10983    // Applies the apply function to every jQuery-Element in a list if that element doesn't contain a module already or the given module
10984    // has the option "force" set to true.
10985    // Is called in init by "snake_cased" module name. $('.my-selector').cms_my_module.
10986    $.fn[namespace.join('_')] = function (userOptions, ...additionalParameters) {
10987      $(this).each(function (i, el) {
10988        if (!$(el).data(namespace.join('.')) || userOptions && userOptions.force) {//Is not occupied or is force true?
10989          apply($, namespace, [el, userOptions, ...additionalParameters]);
10990        }
10991      });
10992      return this;
10993    };
10994  };
10995})(jQuery, cms);
10996
10997    /* Ende cms_makeCMSModule */
10998    /* Start cms_requireCMSComponent */
10999        /*! --GSBDocStart
11000 * @name: @cms/cms_requireCMSComponent
11001 * @version: 3.0.0
11002 * @description: Lib um Javascript-Ressourcen als Bündel nachzuladen wenn diese gebraucht werden. Zielsetzung: Verringerung von Ladezeiten
11003 * --CMSDocEnd
11004*/"use strict";
11005var cms;
11006cms = cms || {};
11007(function ($, cms) {
11008  const state = {
11009    instanceCount: 0,
11010    promises: {}
11011  };
11012
11013  function requireGenericCMSComponent(componentName, instanceName) {
11014    const promiseArray = createScriptTags(cms.jsComponents.definitions[componentName].scriptList, instanceName);
11015    return Promise.all(promiseArray);
11016  }
11017
11018  function createScriptTags(scriptList, instanceName) {
11019    const promiseArray = [];
11020    scriptList.forEach((scriptPath) => {
11021      promiseArray.push(createScriptTag(scriptPath));
11022    });
11023    return promiseArray;
11024  }
11025
11026  /**
11027   * Creates a Script Tag, appends and executes it.
11028   * While creating a new Promise or waiting for a previou Promise the Script has already been requested.
11029   *
11030   * @param scriptPath the Path of the script used for the src Attribute
11031   * @param instanceName the name of this instance used for logging
11032   * @returns {Promise<unknown>} a promise that ensures that the Script is ready to use when resolved
11033   */
11034  function createScriptTag(scriptPath, instanceName) {
11035    let promise;
11036    if (state.promises[scriptPath]) {
11037      promise = state.promises[scriptPath];
11038    } else {
11039      promise = new Promise(function (resolve, reject) {
11040        const $script = $('<script></script>').attr('src', scriptPath).attr('charSet', 'UTF-8');
11041        $script.
11042        prop('async', false).
11043        on('load', function () {
11044          resolve({ scriptPath, action: 'DOM load' });
11045        });
11046        document.body.appendChild($script[0]);
11047
11048      });
11049      state.promises[scriptPath] = promise;
11050    }
11051    return promise;
11052  }
11053
11054  cms.requireCMSComponent = function (componentName, $el) {
11055    const instanceName = 'cms.requireCMSComponent-' + state.instanceCount++;
11056    const deferred = $.Deferred();
11057    let error;
11058
11059    if (cms.jsComponents.definitions[componentName]) {
11060      if (!$el || !$el.length) {
11061        error = new Error('Elemente nicht im DOM gefunden. CMS-Komponente wird nicht geladen');
11062        deferred.reject(error);
11063      } else {
11064        requireGenericCMSComponent(componentName, instanceName).
11065        then(() => deferred.resolve($el)).
11066        catch((err) => {
11067          deferred.reject(err);
11068          console.error(instanceName, `CMS-Komponente ${componentName} für Elemente`, $el,
11069          'konnte nicht eingebunden werden, es gab folgenden Fehler', err);
11070        });
11071      }
11072    } else {
11073      console.error(instanceName, `CMS-Komponente ${componentName} ist nicht definiert, und kann daher nicht eingebunden werden`);
11074    }
11075
11076    return deferred;
11077  };
11078
11079})(jQuery, cms);
11080
11081    /* Ende cms_requireCMSComponent */
11082    /* Start cms_responsiveListener */
11083        /*! --GSBDocStart
11084 * @name: @cms/cms_responsive_listener
11085 * @version: 3.1.0
11086 * @description: Diese Bibliothek wird zur Unterstützung von responsiven Breakpoints in GSB Modulen verwendet.
11087 * --CMSDocEnd
11088*/"use strict";
11089(function ($) {
11090  if (!$.cms) {
11091    $.cms = {};
11092  }
11093
11094
11095  $.cms.responsiveListener = function (pluginBase) {
11096    var base = this;
11097    this.base = base;
11098    this.pluginBase = pluginBase;
11099
11100    // Add a reverse reference to the DOM object
11101    this.base.breakpoints = [];
11102    this.base.breakpointSettings = [];
11103    this.base.activeBreakpoint = null;
11104    this.base.windowWidth = 0;
11105
11106    base.init = function () {
11107      //Da die Lib keine eigenen Options hat, Options vom Plugin holen
11108      base.options = pluginBase.options;
11109      base.originalOptions = base.options;
11110      this.base.options = base.options;
11111      this.base.originalOptions = base.originalOptions;
11112      base.initResponsive();
11113      base.checkResponsive();
11114      base.initEvents();
11115    };
11116
11117
11118    /**
11119     * Initialisiert die Events.
11120     */
11121    $.cms.responsiveListener.prototype.initEvents = function () {
11122      var $window = $(window),
11123        onResize = function () {
11124          if ($(window).width() !== base.windowWidth) {
11125            clearTimeout(base.windowDelay);
11126            base.windowDelay = window.setTimeout(function () {
11127              base.windowWidth = $(window).width();
11128              base.checkResponsive();
11129            }, 100);
11130          }
11131        };
11132      $window.on('resize', onResize);
11133      $window.on('orientationchange', function () {
11134        base.checkResponsive();
11135      });
11136    };
11137
11138    // Run initializer
11139    base.init();
11140  };
11141
11142
11143  /**
11144   * Initialisiert die Datenstrukturen fuer die responsiven Ueberpruefungen.
11145   */
11146  $.cms.responsiveListener.prototype.initResponsive = function () {
11147    var breakpoint,
11148      responsiveSettings = this.base.options.responsive || null;
11149
11150    if (responsiveSettings && responsiveSettings.length > -1) {
11151      for (breakpoint in responsiveSettings) {
11152        if (responsiveSettings.hasOwnProperty(breakpoint)) {
11153          if (typeof responsiveSettings[breakpoint].breakpoint === 'string') {
11154            const emBreakPoint = parseInt(responsiveSettings[breakpoint].breakpoint) * (parseInt(window.getComputedStyle($('html')[0], null).getPropertyValue('font-size')) / 0.625);
11155            this.base.breakpoints.push(emBreakPoint);
11156            // Save with pixelValue as propertyname and not the original em-string.
11157            // Computed Properties are used to identify the breakpointSettings for the targetBreakp
11157oint, which is used as the propertyname and is always in Pixel.
11158            this.base.breakpointSettings[emBreakPoint] = responsiveSettings[breakpoint];
11159          } else {
11160            this.base.breakpoints.push(responsiveSettings[breakpoint].breakpoint);
11161            this.base.breakpointSettings[responsiveSettings[breakpoint].breakpoint] = responsiveSettings[breakpoint];
11162          }
11163        }
11164      }
11165      this.base.breakpoints.sort(function (a, b) {
11166        return b - a;
11167      });
11168    }
11169  };
11170
11171
11172  /**
11173   * Ueberprueft, ob eine Aenderung der Einstellungen durchgefuehrt werden muss. Dies ist dann der Fall, wenn
11174   * sich  die Breite des Viewports(window-Objekt) geaendert hat und mindestens einen der angegebenen Breakpoints
11175   * unterschreitet. Ausschlaggebend fuer die Aenderungen ist der letzte konfigurierte Breakpoint, dessen Breite
11176   * unterschritten wird.
11177   *
11178   */
11179  $.cms.responsiveListener.prototype.checkResponsive = function () {
11180    var breakpoint,
11181      targetBreakpoint,
11182      respondToWidth = $(window).width();
11183
11184    // Case: "responsive : [{...},{...}]" value of the given options is not empty.
11185    if (this.base.originalOptions.responsive &&
11186    this.base.originalOptions.responsive.length > -1 &&
11187    this.base.originalOptions.responsive !== null) {
11188
11189      targetBreakpoint = null;
11190
11191      // Resets the options to original if the window width is greater than the greatest breakpoint.
11192      if (this.base.activeBreakpoint !== null && respondToWidth >= this.base.breakpoints[0]) {
11193        this.base.activeBreakpoint = null;
11194        this.pluginBase.options = this.base.originalOptions;
11195      }
11196
11197      // Looks for the first breakpoint value greater than the screen width.
11198      for (breakpoint in this.base.breakpoints) {
11199        if (this.base.breakpoints.hasOwnProperty(breakpoint)) {
11200          if (respondToWidth < this.base.breakpoints[breakpoint]) {
11201            targetBreakpoint = this.base.breakpoints[breakpoint];
11202            this.base.highestResolution = false;
11203          }
11204        }
11205      }
11206
11207      // In case no breakpoint value is larger than the current window width, terminate.
11208      if (this.base.highestResolution) {
11209        return;
11210      }
11211
11212      if (targetBreakpoint !== null) {
11213        if (this.base.activeBreakpoint !== null) {// Case: targetBreakpoint was found and a breakpoint is already active.
11214          if (targetBreakpoint !== this.base.activeBreakpoint) {// Merges breakpoint specific options and plugin options to the options that should currently apply.
11215            this.base.activeBreakpoint = targetBreakpoint;
11216            this.pluginBase.options = $.extend({},
11217            this.base.originalOptions,
11218            this.base.breakpointSettings[targetBreakpoint]);
11219            this.base.triggerRefresh();
11220          }
11221        } else {// Case: targetBreakpoint was found and no breakpoint is active
11222          this.base.activeBreakpoint = targetBreakpoint;
11223          this.pluginBase.options = $.extend({},
11224          this.base.originalOptions,
11225          this.base.breakpointSettings[targetBreakpoint]);
11226          this.base.triggerRefresh();
11227        }
11228      } else {
11229        if (this.base.activeBreakpoint !== null) {// Case: targetBreakpoint was NOT found but a breakpoint is active
11230          this.base.activeBreakpoint = null;
11231          this.base.options = this.base.originalOptions;
11232          this.base.triggerRefresh();
11233        } else {// Case: targetBreakpoint was NOT found and no breakpoint is active
11234          this.base.highestResolution = true;
11235          this.base.triggerRefresh();
11236        }
11237      }
11238    } else if (this.base.originalOptions.onRefresh &&
11239    this.base.originalOptions.onRefresh.length > -1 &&
11240    this.base.originalOptions.onRefresh !== null) {// Case: Only base options but not the "responsive: [{...},{...}]" Array filled.
11241      if (this.base.highestResolution) {
11242        return;
11243      }
11244      this.base.triggerRefresh();
11245      this.base.highestResolution = true;
11246    }
11247  };
11248
11249
11250  /**
11251   * Loest die Aktualisierung des Scripts aus.
11252   */
11253  $.cms.responsiveListener.prototype.triggerRefresh = function () {
11254    if (typeof this.pluginBase.options.onRefresh === 'function') {
11255      this.pluginBase.options.onRefresh.call(this.pluginBase);
11256    }
11257  };
11258
11259  $.fn.cms_responsiveListener = function (pluginBase) {
11260    return this.each(function () {
11261      new $.cms.responsiveListener(pluginBase);
11262    });
11263  };
11264})(jQuery);
11265
11266    /* Ende cms_responsiveListener */
11267    /* Start cms_checkDependencies */
11268        /*! --GSBDocStart
11269 * @name: @gsb/gsb_check_dependencies
11270 * @version: 1.0.1
11271 * @description: Lib to execute code that depends on other internal modules - only if that module has already been loaded
11272 * --GSBDocEnd
11273*/"use strict";
11274var gsb;
11275gsb = gsb || {};
11276//uses gsb.warn and gsb.error
11277//needs to be loaded AFTER jquery
11278(function ($) {
11279  "use strict";
11280  function checkDependencies(dependencyNames, callback) {
11281    var allOK = true;
11282    dependencyNames.forEach(function (name) {
11283      var propertyName,
11284        dependency,
11285        warning;
11286      //future-proofing: initially, we will only support GSB Modules
11287      if (/^gsb\./.test(name)) {
11288        propertyName = String(name).replace(/\./g, '_');
11289        dependency = $.fn[propertyName];
11290        warning = "Callback dependent on module '" + name + "' detected, but module could not be found.";
11291      }
11292      if (dependency === undefined || dependency === null) {
11293        allOK = false;
11294        if (warning && (typeof gsb_logDependenciesWarning !== 'undefined' ? gsb_logDependenciesWarning : true)) {
11295          gsb.warn(warning);
11296        } else if (!warning) {
11297          gsb.error("Callback dependent on module '" + name + "' detected, but the module's type could not be determined from its name.");
11298        }
11299      }
11300    });
11301    if (allOK) {
11302      /* future-proofing: callback 'arguments' and 'this' may be specified whenever
11303       *                  we decide on a concept that can handle modules which are
11304       *                  not jQuery-plugins (and ideally, one that can handle both)
11305       */
11306      callback.call(null);
11307    }
11308  }
11309
11310  gsb.checkDependencies = checkDependencies;
11311})(jQuery);
11312
11313    /* Ende cms_checkDependencies */
11314    /* Start js.cookie */
11315        "use strict"; /*! js-cookie v3.0.5 | MIT */
11316;
11317(function (global, factory) {
11318  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
11319  typeof define === 'function' && define.amd ? define(factory) : (
11320  global = typeof globalThis !== 'undefined' ? globalThis : global || self, function () {
11321    var current = global.Cookies;
11322    var exports = global.Cookies = factory();
11323    exports.noConflict = function () {global.Cookies = current;return exports;};
11324  }());
11325})(void 0, function () {'use strict';
11326
11327  /* eslint-disable no-var */
11328  function assign(target) {
11329    for (var i = 1; i < arguments.length; i++) {
11330      var source = arguments[i];
11331      for (var key in source) {
11332        target[key] = source[key];
11333      }
11334    }
11335    return target;
11336  }
11337  /* eslint-enable no-var */
11338
11339  /* eslint-disable no-var */
11340  var defaultConverter = {
11341    read: function (value) {
11342      if (value[0] === '"') {
11343        value = value.slice(1, -1);
11344      }
11345      return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
11346    },
11347    write: function (value) {
11348      return encodeURIComponent(value).replace(
11349        /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
11350        decodeURIComponent
11351      );
11352    }
11353  };
11354  /* eslint-enable no-var */
11355
11356  /* eslint-disable no-var */
11357
11358  function init(converter, defaultAttributes) {
11359    function set(name, value, attributes) {
11360      if (typeof document === 'undefined') {
11361        return;
11362      }
11363
11364      attributes = assign({}, defaultAttributes, attributes);
11365
11366      if (typeof attributes.expires === 'number') {
11367        attributes.expires = new Date(Date.now() + attributes.expires * 864e5);
11368      }
11369      if (attributes.expires) {
11370        attributes.expires = attributes.expires.toUTCString();
11371      }
11372
11373      name = encodeURIComponent(name).
11374      replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).
11375      replace(/[()]/g, escape);
11376
11377      var stringifiedAttributes = '';
11378      for (var attributeName in attributes) {
11379        if (!attributes[attributeName]) {
11380          continue;
11381        }
11382
11383        stringifiedAttributes += '; ' + attributeName;
11384
11385        if (attributes[attributeName] === true) {
11386          continue;
11387        }
11388
11389        // Considers RFC 6265 section 5.2:
11390        // ...
11391        // 3.  If the remaining unparsed-attributes contains a %x3B (";")
11392        //     character:
11393        // Consume the characters of the unparsed-attributes up to,
11394        // not including, the first %x3B (";") character.
11395        // ...
11396        stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];
11397      }
11398
11399      return document.cookie =
11400      name + '=' + converter.write(value, name) + stringifiedAttributes;
11401    }
11402
11403    function get(name) {
11404      if (typeof document === 'undefined' || arguments.length && !name) {
11405        return;
11406      }
11407
11408      // To prevent the for loop in the first place assign an empty array
11409      // in case there are no cookies at all.
11410      var cookies = document.cookie ? document.cookie.split('; ') : [];
11411      var jar = {};
11412      for (var i = 0; i < cookies.length; i++) {
11413        var parts = cookies[i].split('=');
11414        var value = parts.slice(1).join('=');
11415
11416        try {
11417          var found = decodeURIComponent(parts[0]);
11418          jar[found] = converter.read(value, found);
11419
11420          if (name === found) {
11421            break;
11422          }
11423        } catch (e) {}
11424      }
11425
11426      return name ? jar[name] : jar;
11427    }
11428
11429    return Object.create(
11430      {
11431        set,
11432        get,
11433        remove: function (name, attributes) {
11434          set(
11435            name,
11436            '',
11437            assign({}, attributes, {
11438              expires: -1
11439            })
11440          );
11441        },
11442        withAttributes: function (attributes) {
11443          return init(this.converter, assign({}, this.attributes, attributes));
11444        },
11445        withConverter: function (converter) {
11446          return init(assign({}, this.converter, converter), this.attributes);
11447        }
11448      },
11449      {
11450        attributes: { value: Object.freeze(defaultAttributes) },
11451        converter: { value: Object.freeze(converter) }
11452      }
11453    );
11454  }
11455
11456  var api = init(defaultConverter, { path: '/' });
11457  /* eslint-enable no-var */
11458
11459  return api;
11460
11461});
11462
11463    /* Ende js.cookie */
11464(function cmsJavaScriptModules(){ //prevents "use strict" statement from "leaking"
11465    /* Start cms_autosuggest */
11466        /*! --GSBDocStart
11467 * @name: @cms/cms_autosuggest
11468 * @version: 6.0.0
11469 * @description: Module for accessible autocompletion in search forms
11470 * --CMSDocEnd
11471*/"use strict";
11472cms.makeCMSModule("cms.autosuggest", {
11473  init: function (el, options, actionUrl) {
11474    const base = this;
11475
11476    // BoxCounter
11477    base.boxNumber = ++base.allInstances.boxCount;
11478    // Such-Textfeld
11479    const selectors = base.options.selectors;
11480    base.$input = base.$el.find(selectors.input).first();
11481    base.$submit = base.$el.find(selectors.submit).first();
11482    if (base.$submit.length === 0) {
11483      base.$submit = base.$el.find('input[type=image]:first');
11484    }
11485    // Aktuelle Anfrage
11486    base.reqQuery = false;
11487    // Anfragen Cachen
11488    base.queries = [];
11489    // Aktuelle Position
11490    base.activeIndex = NaN;
11491
11492    if (base.options.mode === "fetch") {
11493      // eslint-disable-next-line no-param-reassign -- Kompatibilität mit alten Aufruf beihalten
11494      actionUrl = base.$el.attr('data-autosuggest-form') || actionUrl;
11495
11496      if (!actionUrl) {
11497        throw new Error("Das Attribut data-autosuggest-form muss auf dem Basis-Element gesetzt werden");
11498      }
11499
11500      base.actionUrl = actionUrl;
11501    } else if (base.options.mode === "datalist") {
11502      const optionListId = base.$input.attr('list');
11503      if (!optionListId) {
11504        throw new Error("Das Attribut list muss auf dem Input-Element gesetzt werden");
11505      }
11506      const optionList = optionListId ? base.$el.find(`#${optionListId}`) : $();
11507      if (optionListId && optionList.length < 1) {
11508        throw new Error("Das Datalist-Element mit der ID " + optionListId + " existiert nicht");
11509      }
11510      const categoryListId = optionList.attr('data-type-label-list-id');
11511      const categoryList = categoryListId ? base.$el.find(`#${categoryListId}`) : $();
11512      if (categoryListId && categoryList.length < 1) {
11513        throw new Error("Das Datalist-Element mit der ID " + categoryListId + " existiert nicht");
11514      }
11515      base.$input.removeAttr('list');
11516
11517      base.dataList = [].reduce.call(optionList.find('option'), (data, opt) => {
11518        const optText = opt.innerText;
11519        const category = opt.getAttribute('data-type-label');
11520        const pairs = data[category] || [];
11521        data[category] = pairs.concat([{
11522          name: optText,
11523          value: opt.value
11524        }]).sort((a, b) => a.name - b.name);
11525
11526        return data;
11527      }, {});
11528
11529      base.options.typeLabels = [].reduce.call(categoryList.find('option'), (labels, opt) => {
11530        labels[opt.value] = opt.innerText;
11531        return labels;
11532      }, {});
11533    }
11534
11535    // AutoSuggest-Box vorbereiten und positionieren
11536    if (base.options.markup.box) {
11537      base.$box = $(base.options.markup.box).
11538      insertAfter(base.$input);
11539      const description = base.$el.attr('data-autosuggest-box-description');
11540      if (typeof description !== "undefined") {
11541        const descId = base.generateID();
11542        $("<span></span>").
11543        text(description).
11544        addClass(base.options.classes.description).
11545        attr({
11546          id: descId,
11547          hidden: 'hidden'
11548        }).
11549        insertAfter(base.$input);
11550        base.$box.attr('aria-describedby', descId);
11551      } else {
11552        throw new Error("Attribut data-autosuggest-box-description muss auf dem Basis-Element gesetzt werden");
11553      }
11554    } else if (base.options.selectors.box) {
11555      base.$box = base.$el.find(base.options.selectors.box);
11556    }
11557    base.$box.
11558    attr({
11559      id: base.$box.attr("id") || `searchAutoSuggestBox${base.boxNumber}`,
11560      hidden: 'hidden'
11561    });
11562
11563    // Browser-Auto-Vervollständigung deaktivieren
11564    base.$input.attr('autocomplete', 'off');
11565
11566    base.makeAccessible();
11567    base.bindEvents();
11568  },
11569  allInstances: {
11570    boxCount: 0
11571  },
11572  makeAccessible: function () {
11573    const base = this;
11574
11575    base.$input.attr({
11576      'role': base.$input.attr('role') || 'combobox',
11577      'aria-haspopup': 'listbox',
11578      'aria-owns': base.$box.attr('id'),
11579      'aria-expanded': 'false',
11580      'aria-autocomplete': 'list',
11581      'aria-activedescendant': null,
11582      'aria-controls': base.$box.attr('id')
11583    });
11584
11585    base.$labels = $(base.$input.prop('labels')).each(function () {
11586      const $label = $(this);
11587      $label.attr('id', $label.attr('id') || base.generateID());
11588    });
11589    const labelList = base.$labels.toArray().map(function (label) {
11590      return $(label).attr('id');
11591    }).join(' ');
11592
11593    base.$box.attr({
11594      role: base.$box.attr('role') || 'listbox',
11595      'aria-labelledby': labelList || null
11596    });
11597  },
11598  bindEvents: function () {
11599    const base = this;
11600
11601    // Tastaturbefehle abfangen
11602    base.$input.on('keydown', base, base.onKeyDown);
11603
11604    // Bubbling von Mousedown-Event verhindern (Kompatibilität mit cms_simple_toggle)
11605    base.$input.on('mousedown', (ev) => ev.stopPropagation());
11606
11607    // Bei Eingabe von mehr als zwei Zeichen Liste abrufen
11608    base.$input.on('keyup', base, base.onKeyUp);
11609
11610    base.$el.on(`close.${base.eventName}`, base, function (ev) {
11611      ev.stopPropagation();
11612      ev.data.showSuggestionBox(false);
11613    });
11614    base.$el.on(`open.${base.eventName}`, base, function (ev) {
11615      ev.stopPropagation();
11616      ev.data.showSuggestionBox(true);
11617    });
11618
11619    base.$el.
11620    on(`notEnoughCharacters.${base.eventName} noResults.${base.eventName}`, base, function (ev) {
11621      ev.stopPropagation();
11622      ev.data.$el.trigger(`close.${base.eventName}`, base);
11623    }).
11624    on(`showResults.${base.eventName}`, base, function (ev) {
11625      ev.stopPropagation();
11626      ev.data.$el.trigger(`open.${base.eventName}`, base);
11627    });
11628    base.$el.on(`focusout.${base.eventName}`, base, function (ev) {
11629      ev.data.$el.trigger(`close.${base.eventName}`, base);
11630    });
11631    base.$box.on('mousedown', function (ev) {
11632      ev.stopPropagation();
11633      ev.preventDefault();
11634    });
11635    if (base.options.mode === "datalist" && base.options.datalist.openOnFocus) {
11636      base.$el.on(`focusin.${base.eventName}`, base, function (ev) {
11637        ev.data.$input.trigger('keyup', base);
11638        ev.data.$el.trigger(`showResults.${base.eventName}`, base);
11639      });
11640    }
11641  },
11642  onKeyDown: function (ev) {
11643    const base = ev.data;
11644    let trigger = false,
11645      activeOpt,
11646      link;
11647    switch (ev.key) {
11648      case "Enter":
11649        trigger = true;
11650        break;
11651      case "Down": // IE/Edge
11652      case "ArrowDown":
11653        ev.preventDefault();
11654        base.selectNextSuggestion();
11655        break;
11656      case "Up": // IE/Edge
11657      case "ArrowUp":
11658        ev.preventDefault();
11659        base.selectPrevSuggestion();
11660        break;
11661      case "Esc": // IE/Edge
11662      case "Escape":
11663        if (!base.$box.is('[hidden]')) {
11664          base.showSuggestionBox(false);
11665          ev.stopPropagation();
11666        }
11667        break;
11668      default:break;
11669    }
11670    if (trigger) {
11671      activeOpt = base.$box.find('[role=option]').eq(base.activeIndex);
11672      if (activeOpt && activeOpt.length > 0) {
11673        base.$input.val(activeOpt.first().attr('data-input'));
11674      }
11675      if (base.options.submitOnSelect) {
11676        if (activeOpt.is(`.${base.options.classes.hasLink}`)) {
11677          ev.preventDefault(); //prevent form submission
11678          //jQuery does not call the native .click() on <a> elements
11679          link = activeOpt.find('a')[0];
11680          if (link && typeof link.click === "function") {
11681            link.click();
11682          }
11683        } else {
11684          base.triggerSubmit(activeOpt);
11685        }
11686      } else if (activeOpt.length > 0) {
11687        ev.preventDefault();
11688      }
11689      ev.data.$el.trigger(`close.${base.eventName}`, base);
11690    }
11691  },
11692  onKeyUp: function (ev) {
11693    const base = ev.data;
11694    let go = true;
11695    switch (ev.key) {
11696      case "Enter":
11697        return;
11698      case "Esc": // IE/Edge
11699      case "Escape":
11700        return;
11701      case "Down": // IE/Edge
11702      case "ArrowDown":
11703      case "Up": // IE/Edge
11704      case "ArrowUp":
11705        go = !base.$box.is(':visible');
11706        break;
11707      default:break;
11708    }
11709
11710    if (go) {
11711      if (base.options.mode === "datalist") {
11712        if (base.$input.val().length >= base.options.minInputLength || base.options.datalist.openOnFocus) {
11713          base.filterListData(base.$input.val());
11714        } else {
11715          base.$el.trigger(`notEnoughCharacters.${base.eventName}`, base);
11716        }
11717      } else if (base.options.mode === "fetch") {
11718        if (base.$input.val().length >= base.options.minInputLength) {
11719          base.query(base.$input.val());
11720        } else {
11721          base.$el.trigger(`notEnoughCharacters.${base.eventName}`, base);
11722        }
11723      }
11724    }
11725  },
11726  filterListData: function (value) {
11727    const base = this,
11728      queryResult = {};
11729
11730    if (typeof value === "string") {
11731      Object.entries(base.dataList).forEach(([key, pairs]) => {
11732        const matchingPairs = pairs.filter((pair) => base.options.datalist.filter(pair, value));
11733        if (matchingPairs.length) {
11734          queryResult[key] = matchingPairs;
11735        }
11736      });
11737    }
11738
11739    base.showSuggestions(queryResult);
11740  },
11741  query: function (value) {
11742    const base = this;
11743    base.reqQuery = value;
11744    if (typeof base.queries[base.reqQuery] === "undefined") {
11745      $.ajax({
11746        url: base.actionUrl,
11747        dataType: 'json',
11748        data: {
11749          'userQuery': value
11750        },
11751        error: function (jqXHR, textStatus, errorThrown) {
11752          // eslint-disable-next-line no-console -- Explizite Fehlerausgabe
11753          console.error(`AutoSuggest.base.query() > error=AJAX Fehler beim Abruf der JSON-Resource ${base.actionUrl}: ${textStatus} :: ${errorThrown}`);
11754        },
11755        success: function (data) {
11756          base.queries[value] = data;
11757          if (base.reqQuery === value) {
11758            base.showSuggestions(data);
11759          }
11760        }
11761      });
11762    } else {
11763      base.showSuggestions(base.queries[base.reqQuery]);
11764    }
11765  },
11766  showSuggestions: function (data) {
11767    const base = this;
11768    let count = 0;
11769    const createSublist = Boolean(base.options.markup.typedOption);
11770    base.$box.empty();
11771    Object.keys(data).forEach(function (typeName) {
11772      const typeLabel = base.options.typeLabels[typeName],
11773        typedData = data[typeName] || [];
11774      let optionContainer,
11775        optionLabel,
11776        typedOption,
11777        dummy;
11778      if (typeLabel && typedData.length) {
11779        if (createSublist) {
11780          dummy = $("<div/>");
11781          typedOption = $(base.options.markup.typedOption).appendTo(dummy);
11782          optionLabel = dummy.find(base.options.selectors.typeLabel).
11783          attr({
11784            "id": optionLabel ? optionLabel.attr("id") || base.generateID() : base.generateID(),
11785            "data-cms-suggestion-type": typeName
11786          }).
11787          text(typeLabel);
11788          optionContainer = dummy.find(base.options.selectors.typedContainer).
11789          attr({
11790            'aria-labelledby': optionLabel.attr('id') || null,
11791            'data-cms-suggestion-type': typeName
11792          });
11793
11794          typedOption.appendTo(base.$box);
11795        } else {
11796          optionContainer = base.$el.find(base.options.selectors.typedContainer).
11797          filter(`[data-cms-suggestion-type="${typeName}"]`);
11798          if (data[typeName].length) {
11799            optionContainer.empty();
11800          }
11801        }
11802      }
11803      if (!optionContainer || !optionContainer.length) {
11804        optionContainer = base.$box;
11805      }
11806      data[typeName].forEach(function (suggestion, index) {
11807        let option;
11808        if (suggestion) {
11809          count++;
11810          option = $(base.options.markup.option);
11811          option.html(base.options.markup.optionInner.call(base, suggestion, base.reqQuery));
11812          option.attr({
11813            "data-input": suggestion.name,
11814            id: option.attr("id") || base.generateID(),
11815            role: "option"
11816          });
11817
11818          if (suggestion.link) {
11819            option.addClass('has-link');
11820            option.wrapInner($("<a/>").attr({
11821              href: suggestion.link,
11822              tabindex: -1
11823            }));
11824          }
11825          option.on('click', base, base.onSuggestionClick);
11826          option.appendTo(optionContainer);
11827        }
11828      });
11829    });
11830    if (count > 0) {
11831      base.$el.trigger(`showResults.${base.eventName}`, base);
11832    } else {
11833      base.$el.trigger(`noResults.${base.eventName}`, base);
11834    }
11835  },
11836  onSuggestionClick: function (ev) {
11837    const base = ev.data,
11838      opt = $(ev.currentTarget);
11839    if (!opt.is(`.${base.options.classes.hasLink}`)) {
11840      ev.preventDefault(); // if old markup is used (not recommended)
11841      base.$input.val(opt.attr('data-input'));
11842      if (base.options.submitOnSelect) {
11843        base.triggerSubmit(opt);
11844      }
11845      base.$el.trigger(`close.${base.eventName}`, base);
11846    }
11847  },
11848  showSuggestionBox: function (show) {
11849    const base = this;
11850
11851    if (show) {
11852      if (!base.specialTrigger(`beforeShow.${base.eventName}`)) {
11853        return;
11854      }
11855      base.$input.attr("aria-expanded", "true");
11856      base.$box.add(base.$el.find(base.options.selectors.description)).
11857      attr({
11858        hidden: null,
11859        'aria-hidden': null
11860      });
11861      let boxOffsetTop = base.$box.offset().top - $(window).scrollTop();
11862      base.$box.css({ maxHeight: 'calc(100vh - ' + boxOffsetTop + 'px)', overflow: 'auto' });
11863    } else {
11864      if (!base.specialTrigger(`beforeHide.${base.eventName}`)) {
11865        return;
11866      }
11867      base.$input.attr("aria-expanded", "false");
11868      base.$box.add(base.$el.find(base.options.selectors.description)).
11869      attr({
11870        hidden: 'hidden',
11871        'aria-hidden': null
11872      });
11873    }
11874
11875    base.activeIndex = NaN;
11876    base.$input.attr("aria-activedescendant", null);
11877  },
11878  selectNextSuggestion: function () {
11879    const base = this,
11880      n = base.$box.find('[role=option]').length; // the number of suggestions
11881    if (n > 0) {
11882      if (isNaN(base.activeIndex) || base.activeIndex >= n - 1) {
11883        base.activeIndex = 0;
11884      } else if (base.activeIndex < n - 1) {
11885        base.activeIndex++;
11886      }
11887      base.selectSuggestion();
11888    }
11889  },
11890  selectPrevSuggestion: function () {
11891    const base = this,
11892      n = base.$box.find('[role=option]').length;
11893    if (n > 0) {
11894      if (isNaN(base.activeIndex) || base.activeIndex <= 0) {
11895        base.activeIndex = n - 1;
11896      } else if (base.activeIndex > 0) {
11897        base.activeIndex--;
11898      }
11899      base.selectSuggestion();
11900    }
11901  },
11902  selectSuggestion: function () {
11903    const base = this,
11904      suggestions = base.$box.find('[role=option]'),
11905      activeSuggestion = suggestions.eq(base.activeIndex);
11906    suggestions.
11907    removeClass('active').
11908    attr('aria-selected', 'false');
11909    activeSuggestion.
11910    addClass('active').
11911    attr('aria-selected', 'true');
11912    base.$input.attr({
11913      'aria-activedescendant': activeSuggestion.attr('id')
11914    });
11915
11916    if (!base.isInVisibleSuggestionBox(activeSuggestion)) {
11917      $(activeSuggestion)[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
11918    }
11919  },
11920  isInVisibleSuggestionBox: function (element) {
11921    const base = this;
11922    let isInVisibleSuggestionBox;
11923    const elementHeight = $(element).outerHeight();
11924    const elementTop = $(element).offset().top;
11925    const elementBottom = elementTop + elementHeight;
11926    const boxHeight = base.$box.outerHeight();
11927    const boxTop = base.$box.offset().top;
11928    const boxBottom = boxTop + boxHeight;
11929    if (elementHeight >= boxHeight) {
11930      isInVisibleSuggestionBox = elementBottom - 1 / 2 * elementHeight < boxBottom && elementTop + 1 / 2 * elementHeight > boxTop;
11931    } else {
11932      isInVisibleSuggestionBox = elementBottom < boxBottom && elementTop > boxTop;
11933    }
11934    return isInVisibleSuggestionBox;
11935  },
11936  triggerSubmit: function (activeSuggestion) {
11937    const base = this;
11938    if (activeSuggestion && activeSuggestion.length > 0) {
11939      if (base.$submit.length > 0) {
11940        base.$submit.click();
11941      } else {
11942        const form = base.$input.prop('form');
11943        if (form) {
11944          form.submit();
11945        }
11946      }
11947    }
11948  },
11949  // triggers event on base.$el
11950  // returns false if event is cancelled
11951  specialTrigger: function (evStr, ev) {
11952    const base = this;
11953    let namespaces = evStr.split('.');
11954    const type = namespaces.shift();
11955    namespaces = namespaces.sort();
11956    // eslint-disable-next-line new-cap -- Event ist Teil von jQuery
11957    const event = $.Event(type, {
11958      namespace: namespaces.join('.'),
11959      relatedEvent: ev || null
11960    });
11961    base.$el.trigger(event, base);
11962    return !event.isDefaultPrevented();
11963  },
11964  defaultOptions: {
11965    mode: "fetch",
11966    datalist: {
11967      filter: function (pair, value) {
11968        const lcValue = value.toLowerCase();
11969        return typeof pair.value === "string" && pair.value.toLowerCase().indexOf(lcValue) !== -1;
11970      },
11971      openOnFocus: false
11972    },
11973    minInputLength: 2,
11974    submitOnSelect: true,
11975    typeLabels: {},
11976    selectors: {
11977      box: null,
11978      description: '.js-autosuggest-description',
11979      input: "input[type=text], input[type=search]",
11980      submit: "input[type=submit], button[type=submit]",
11981      typeLabel: ".c-autosuggest__headline",
11982      typedContainer: ".c-autosuggest__sublist"
11983    },
11984    markup: {
11985      box: "<ul class='c-autosuggest__list'></ul>",
11986      option: "<li class='c-autosuggest__item'></li>",
11987      optionInner: function (suggestion) {
11988        return suggestion.name;
11989      },
11990      typedOption:
11991      "<li class='c-autosuggest__item'><h3 class='c-autosuggest__headline'></h3><ul class='c-autosuggest__sublist'></ul></li>"
11992    },
11993    classes: {
11994      description: 'c-autosuggest__description js-autosuggest-description',
11995      hasLink: 'has-link'
11996    }
11997  }
11998});
11999
12000    /* Ende cms_autosuggest */
12001    /* Start cms_cookiebanner */
12002        /*! --GSBDocStart
12003 * @name: @cms/cms_cookiebanner
12004 * @version: 3.1.0
12005 * @description: Das neue Cookiebanner:
12006 * --CMSDocEnd
12007*/"use strict";
12008cms.makeCMSModule('cms.cookiebanner', {
12009  init: function () {
12010    const base = this;
12011    if (!base.isCookiesEnabled()) {
12012      return;
12013    }
12014    base.setCSSHeight(base);
12015
12016    base.el.addEventListener('open', () => base.open(base));
12017    base.el.addEventListener('close', () => base.close(base));
12018    base.el.addEventListener('consentToAll', () => base.consentToAll(base));
12019    base.el.addEventListener('rejectToAll', () => base.rejectToAll(base));
12020    // Manuelle Öffnung initialisieren
12021    document.querySelector(base.options.selectors.disableAutoOpenIfPresent)?.addEventListener('click', function () {
12022      base.el.dispatchEvent(new Event('open'));
12023    });
12024    // Automatische Öffnung initialisieren
12025    if (!document.cookie.match(`${base.options.cookies.necessary.on}`) && !document.querySelector(base.options.selectors.disableAutoOpenIfPresent)) {
12026      base.el.dispatchEvent(new Event('open'));
12027    }
12028    // Allen Zustimmen initialisieren
12029    base.el.querySelector(base.options.selectors.consentToAll)?.addEventListener('click', function () {
12030      base.el.addEventListener('afterConsentToAll', () => {
12031        base.el.dispatchEvent(new Event('close'));
12032      }, { once: true });
12033      base.el.dispatchEvent(new Event('consentToAll'));
12034    });
12035    // Allen Ablehnen initialisieren
12036    base.el.querySelector(base.options.selectors.rejectToAll)?.addEventListener('click', function () {
12037      base.el.addEventListener('afterRejectToAll', () => {
12038        base.el.dispatchEvent(new Event('close'));
12039      }, { once: true });
12040      base.el.dispatchEvent(new Event('rejectToAll'));
12041    });
12042    // Schließung initialisieren
12043    document.querySelector(base.options.selectors.close)?.addEventListener('click', function () {
12044      base.el.dispatchEvent(new Event('close'));
12045    });
12046    // Label-Wechsel initialisieren
12047    base.el.querySelectorAll(base.options.selectors.checkboxes).forEach(
12048      (el) => el.addEventListener('change', (ev) => base.change(ev.target))
12049    );
12050    // Resizes setzen die Höhe als CSS-Variable
12051    window.addEventListener('resize', () => base.setCSSHeight(base));
12052    ['change', 'toggle', 'afterOpen', 'afterClose'].forEach((eventType) => {
12053      base.el.addEventListener(eventType, () => base.setCSSHeight(base));
12054    });
12055    base.el.querySelectorAll('details').forEach((el) => el.addEventListener('toggle', () => base.setCSSHeight(base)));
12056  },
12057  //überprüft, ob der Browser Cookies erlaubt
12058  isCookiesEnabled: function () {
12059    try {
12060      document.cookie = 'cookietest=1';
12061      const ret = document.cookie.includes('cookietest=');
12062      document.cookie = 'cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT';
12063      const isBrave = !!navigator.brave;
12064      return ret && !isBrave;
12065    }
12066    catch (e) {
12067      return false;
12068    }
12069  },
12070  //Setzt einen einzelnen Cookie mit sinnvollen Standards. Ohne expires läuft der Cookie sofort ab
12071  setCookie: function (cookie,
12072  expires = 'expires=Thu, 01 Jan 1970 00:00:01 GMT',
12073  path = 'path=/',
12074  secure = 'Secure=true',
12075  sameSite = 'SameSite=Strict') {
12076    document.cookie = `${cookie}; ${expires}; ${path}; ${secure}; ${sameSite}`;
12077  },
12078  // Setzt den Cookie als String oder ruft die assoziierte Function auf
12079  setCookies: function () {
12080    const base = this;
12081    for (const [cookiename, cookiefunction] of Object.entries(base.options.cookies)) {
12082      const input = base.el.querySelector(`[data-banner-cookie-name=${cookiename}]`)?.querySelector('input');
12083      if (input && input.checked) {
12084        const cookie = cookiefunction.on;
12085        if (typeof cookie === 'function') {
12086          cookie(base);
12087        } else {
12088          if (cookie === 'matomo') {
12089            base.matomo();
12090          } else {
12091            const d = new Date();
12092            d.setTime(d.getTime() + base.options.durationInDays * 24 * 60 * 60 * 1000);
12093            const expires = `expires=${d.toUTCString()};`;
12094            base.setCookie(cookie, expires);
12095          }
12096        }
12097      } else {
12098        const cookie = cookiefunction.off;
12099        if (typeof cookie === 'function') {
12100          cookie(base);
12101        } else {
12102          if (cookie === 'matomo') {
12103            base.matomoOff();
12104          } else {
12105            base.setCookie(cookie);
12106          }
12107        }
12108      }
12109    }
12110  },
12111  // Erzeugt den Default Matomo-Token
12112  matomo: function () {
12113    const base = this;
12114    const d = new Date();
12115    d.setTime(d.getTime() + base.options.durationInDays * 24 * 60 * 60 * 1000);
12116    const expires = `expires=${d.toUTCString()};`;
12117    base.setCookie('matomoTracking=true', expires);
12118    base.setCookie('matomoConsent=true', expires);
12119  },
12120  matomoOff: function () {
12121    const base = this;
12122    base.setCookie('matomoTracking=true');
12123    base.setCookie('matomoConsent=true');
12124  },
12125  initCheckedStatus: function (base) {
12126    for (const [cookiename, cookiefunction] of Object.entries(base.options.cookies)) {
12127      const input = base.el.querySelector(`[data-banner-cookie-name=${cookiename}]`)?.querySelector('input');
12128      if (input && !input.attributes.disabled) {
12129        if (typeof cookiefunction.check === 'function') {
12130          input.checked = cookiefunction.check();
12131          input.dispatchEvent(new Event('change'));
12132        } else {
12133          if (typeof cookiefunction.on !== 'function') {
12134            if (cookiefunction.on !== 'matomo') {
12135              input.checked = document.cookie.match(`${cookiefunction.on}`);
12136              input.dispatchEvent(new Event('change'));
12137            } else {
12138              input.checked = document.cookie.match(`matomoTracking=true|matomoConsent=true`);
12139              input.dispatchEvent(new Event('change'));
12140            }
12141          }
12142        }
12143      }
12144    }
12145    base.el.querySelectorAll('input[checked]').forEach((el) => {
12146      el.checked = true;
12147    });
12148  },
12149  open: function (base) {
12150    base.el.dispatchEvent(new Event('beforeOpen'));
12151    // Input checked-Status aktualisieren
12152    base.initCheckedStatus(base);
12153    if (base.options.modal) {
12154      document.querySelector(base.options.selectors.dialog).showModal();
12155    } else {
12156      document.querySelector(base.options.selectors.dialog).show();
12157    }
12158    base.el.dispatchEvent(new Event('afterOpen'));
12159  },
12160  close: function (base) {
12161    base.el.dispatchEvent(new Event('beforeClose'));
12162    base.setCookies();
12163    base.el.close();
12164    base.el.dispatchEvent(new Event('afterClose'));
12165  },
12166  change: function (el) {
12167    el.dispatchEvent(new Event('beforeChange', { bubbles: true }));
12168    const label = document.querySelector(`[for=${el.id}],[id=${el.attributes['aria-labelledby']}]`);
12169    if (label && label.attributes['data-label-on'] && label.attributes['data-label-off']) {
12170      label.innerText = el.checked ? label.attributes['data-label-on'].value : label.attributes['data-label-off'].value;
12171    }
12172    el.dispatchEvent(new Event('afterChange', { bubbles: true }));
12173  },
12174  consentToAll: function (base) {
12175    base.el.dispatchEvent(new Event('beforeConsentToAll'));
12176    base.el.querySelectorAll(base.options.selectors.checkboxes).forEach((el) => {
12177      el.checked = true;
12178      el.dispatchEvent(new Event('change'));
12179    });
12180    base.el.dispatchEvent(new Event('afterConsentToAll'));
12181  },
12182  rejectToAll: function (base) {
12183    base.el.dispatchEvent(new Event('beforeRejectToAll'));
12184    base.el.querySelectorAll(base.options.selectors.checkboxes).forEach((el) => {
12185      el.checked = false;
12186      el.dispatchEvent(new Event('change'));
12187    });
12188    base.el.dispatchEvent(new Event('afterRejectToAll'));
12189  },
12190  setCSSHeight: function (base) {
12191    base.el.dispatchEvent(new Event('beforeSetCSSHeight'));
12192    document.querySelector('body').style.setProperty('--cookiebanner-height', `${base.el.offsetHeight}px`);
12193    base.el.dispatchEvent(new Event('afterSetCSSHeight'));
12194  },
12195  defaultOptions: {
12196    selectors: {
12197      dialog: '#cookiebanner',
12198      disableAutoOpenIfPresent: '.js-cookiebanner-opener',
12199      close: '.js-cookiebanner-button-confirm-selection',
12200      consentToAll: '.js-cookiebanner-button-consent-to-all',
12201      rejectToAll: '.js-cookiebanner-button-reject-to-all',
12202      checkboxes: 'input[type=checkbox]'
12203    },
12204    durationInDays: 30,
12205    modal: true,
12206    cookies: {
12207      necessary: {
12208        on: 'cmsbanner=closed',
12209        off: (base) => {
12210          const d = new Date();
12211          d.setTime(d.getTime() + base.options.durationInDays * 24 * 60 * 60 * 1000);
12212          const expires = `expires=${d.toUTCString()};`;
12213          base.setCookie('cmsbanner=closed', expires);
12214        }
12215      }
12216    }
12217  }
12218});
12219
12220    /* Ende cms_cookiebanner */
12221    /* Start cms_consent_reload */
12222        /**
12223 * @name cms_consent_reload
12224 * @version 1.0.0
12225 * @see {@link http://semver.org|Semantic Versioning}
12226 * @author anuebel
12227 *
12228 * @desc Lädt den eigentlichen Inhalt eines Bereichs erst dann, wenn eine Zustimmung erteilt wurde.
12229 *
12230 * Das Modul ist in Bezug auf seine nachzuladenden Inhalte agnostisch und kann daher an allen Stellen verwendet werden, wo ein Inhalt
12231 * erst nach der Zustimmung des Nutzers nachgeladen werden soll. Es müssen folgende Voraussetzungen erfüllt werden:
12232 *
12233 * 1. Ein Element ist über ein Attribut data-consent-reload-trigger-container erreichbar (initial dargestellter Bereich)
12234 * 2. Ein Element ist über ein Attribut data-consent-reload-trigger erreichbar (Auslöser für das Nachladen)
12235 * 3. Ein Element ist über ein Attribut data-consent-reload-target erreichbar
12236 * und der Wert des Attributs enthält die URL zum nachzuladenden Bereich
12237 *
12238 * Optionen:
12239 * <ul>
12240 * <li>cookieName - der Name des Session-Cookie, durch den sich die Zustimmung des Nutzers gemerkt wird(Default: cms_consent)</li>
12241 * </ul>
12242 *
12243 *
12244 * Benötigt     "js-cookie": "3.0.5",
12245 *
12246 *
12247 * @requires  {@link external:jQuery}
12248 *
12249 * @example
12250 * $('.js-consent-reload').cms_consent_reload();
12251 */"use strict";
12252cms.makeCMSModule("cms.consent_reload", {
12253  consentGiven: false,
12254  init: function () {
12255    this.$consentTriggerContainer = $(this.options.triggerContainer, this.$el);
12256    if (!this.$consentTriggerContainer.length) {
12257      cms.error('%o: Kein Trigger-Container-Element \'' + this.options.triggerContainer + '\' gefunden', this.$el);
12258      return;
12259    }
12260
12261    this.$consentTrigger = $(this.options.reloadContainer, this.$el);
12262    if (!this.$consentTrigger.length) {
12263      cms.error('%o: Kein Trigger-Element \'' + this.options.reloadContainer + '\' gefunden', this.$el);
12264      return;
12265    }
12266
12267    this.$consentTarget = $(this.options.reloadTarget, this.$el);
12268    if (!this.$consentTarget.length) {
12269      cms.error('%o: Kein Target-Element \'' + this.options.reloadTarget + '\' gefunden', this.$el);
12270      return;
12271    }
12272
12273    this.consentTargetURL = this.$consentTarget.data('consent-reload-target');
12274    if (!this.consentTargetURL) {
12275      console.error('%o: Keine URL für nachzuladendes Ziel gefunden', this.$el);
12276      return;
12277    }
12278
12279    this.consentCookieHost = this.$consentTriggerContainer.data('consent-reload-cookie-host');
12280    if (!this.consentCookieHost) {
12281      console.log('%o: Kein Cookie-Host für nachzuladendes Ziel gefunden', this.$el);
12282      return;
12283    }
12284
12285    this.completeCookieName = this.consentCookieHost ? this.options.cookieName : this.options.cookieName;
12286
12287    if (Cookies.get(this.completeCookieName)) {
12288      this.embedConsentTarget();
12289    } else {
12290      this.$el.on(`consent.${this.eventName}`, this, this.onConsent);
12291      this.$consentTrigger.on('click' + this.instanceNamespace, () => {
12292        this.$el.trigger(`consent.${this.eventName}`);
12293      });
12294    }
12295  },
12296
12297  successfulResponseCallback: function (response) {
12298    this.$consentTriggerContainer.remove();
12299    this.$consentTarget.html(response);
12300    this.$el.addClass('is-allowed-and-replaced');
12301  },
12302
12303  erroneousResponseCallback: function (jqXHR, textStatus, errorThrown) {
12304    cms.error('Fehler bei der Ermittlung des nachzuladenden Ziels: %o', errorThrown);
12305  },
12306
12307  embedConsentTarget: function () {
12308    $.ajax({
12309      url: this.consentTargetURL,
12310      success: this.successfulResponseCallback,
12311      error: this.erroneousResponseCallback,
12312      context: this
12313    });
12314  },
12315
12316  onConsent: function (ev) {
12317    const base = ev.data;
12318    ev.stopPropagation();
12319    if (!base.consentGiven) {
12320      base.consentGiven = true;
12321      base.$el.trigger(`afterConsent.${base.eventName}`);
12322      base.rememberConsentGiven();
12323      base.embedConsentTarget();
12324    }
12325  },
12326
12327  rememberConsentGiven: function () {
12328    Cookies.set(this.completeCookieName, 'accepted', { expires: 28 });
12329  },
12330
12331  defaultOptions: {
12332    cookieName: 'cms_consent',
12333    triggerContainer: '[data-consent-reload-trigger-container]',
12334    reloadContainer: '[data-consent-reload-trigger]',
12335    reloadTarget: '[data-consent-reload-target]'
12336  }
12337});
12338
12339    /* Ende cms_consent_reload */
12340    /* Start cms_dialog */
12341        /*! --GSBDocStart
12342 * @name: @cms/cms_dialog
12343 * @version: 2.2.2
12344 * @description: [//]: # (Diesen und folgende Kommentare auf keinen Fall löschen!) [//]: # (Nur so akzeptiert license-checker die Lizenz) [//]: # (SEE LICENSE IN LICENSE-INTERNAL.txt) [//]: # (https://license-internal.txt)
12345 * --CMSDocEnd
12346*/"use strict";
12347cms.makeCMSModule('cms.dialog', {
12348  init: function () {
12349    const base = this;
12350
12351    const dialog = base.el;
12352    const $dialog = base.$el;
12353    const id = $dialog.attr('id');
12354    $(`[data-dialog-open-modal=${id}]`).on('click', function () {
12355      dialog.showModal();
12356      $dialog.trigger(`afterOpen`, base);
12357    });
12358    const $popoverOpeners = $(`[data-dialog-open-popover=${id}]`).on('click', function (event) {
12359      const $opener = $(this);
12360
12361      cms.requireCMSComponent("bundle_popover", $dialog).done(function () {
12362        if ($opener.attr('aria-expanded') === 'true') {
12363          base.hidePopover(base);
12364        } else {
12365          base.showPopover(event.currentTarget, base);
12366        }
12367
12368        $dialog.trigger(`afterOpen`, base);
12369      });
12370    });
12371    if ($popoverOpeners.length) {
12372      base.initPopoverEvents(base);
12373    }
12374    $(`[data-dialog-open=${id}]`).on('click', function () {
12375      dialog.show();
12376      $dialog.trigger(`afterOpen`, base);
12377    });
12378    $(`[data-dialog-close=${id}]`).on('click', function () {
12379      dialog.close();
12380      $dialog.find(base.options.selectors.mediaElementWrapper).each((index, el) => {
12381        el.pause();
12382      });
12383      $dialog.trigger(`afterClose`, base);
12384    });
12385
12386    $dialog.on(`afterOpen${base.instanceNamespace}`, base, base.afterOpen);
12387  },
12388  afterOpen: function (event) {
12389    const base = event.data;
12390    $(this).find(base.options.selectors.slideshowsToUpdate).trigger('update.slideshow');
12391    base.options.updateCallbackAfterOpen(this);
12392  },
12393  afterClose: function (event) {
12394    const base = event.data;
12395    base.options.updateCallbackAfterClose(this);
12396  },
12397  initPopoverEvents: function (base) {
12398    const $dialog = base.$el;
12399    const id = $dialog.attr('id');
12400    const $buttons = $(`[data-dialog-open-popover=${id}]`).attr('aria-expanded', 'false');
12401    $dialog.on('keydown', (event) => {
12402      if (event.key === "Escape") {
12403        base.hidePopover(base);
12404      }
12405    }).
12406    on('focusout', (event) => {
12407      const focusedElement = event.relatedTarget;
12408      if (!$dialog.is(focusedElement) && !$dialog.find(focusedElement).length && !($buttons.find(focusedElement).length || $buttons.is(focusedElement))) {
12409        base.hidePopover(base);
12410      }
12411    });
12412    $(`[data-dialog-close=${id}]`).on('click', () => base.hidePopover(base));
12413  },
12414  updatePosition: function (button, popover) {
12415    const { autoPlacement, computePosition, shift, offset } = FloatingUIDOM;
12416
12417    computePosition(button, popover, {
12418      middleware: [
12419      autoPlacement(),
12420      offset(10),
12421      shift()]
12422
12423    }).then(({ x, y }) => {
12424      $(popover).css('--popover-position-left', `${x}px`);
12425      $(popover).css('--popover-position-top', `${y}px`);
12426    });
12427  },
12428  showPopover: function (button, base) {
12429    const { autoUpdate } = FloatingUIDOM;
12430
12431    const $dialog = base.$el;
12432    const id = $dialog.attr('id');
12433    const $buttons = $(`[data-dialog-open-popover=${id}]`);
12434    if ($buttons.attr('aria-expanded') === "false") {
12435      $buttons.attr('aria-expanded', true);
12436      $dialog.addClass(base.options.selectors.popoverIsShown);
12437      autoUpdate(button, base.el, () => base.updatePosition(button, base.el));
12438      requestAnimationFrame(() => {
12439        if ($dialog.find('[data-dialog-close]').length) {
12440          $dialog.find('[data-dialog-close]').focus();
12441        } else {
12442          $dialog.focus();
12443        }
12444        $buttons.on('focusout', (event) => {
12445          const focusedElement = event.relatedTarget;
12446          if (!$dialog.is(focusedElement) && !$dialog.find(focusedElement).length && !($buttons.find(focusedElement).length || $buttons.is(focusedElement))) {
12447            base.hidePopover(base);
12448          }
12449        });
12450      });
12451    }
12452  },
12453  hidePopover(base) {
12454    const $dialog = base.$el;
12455    const id = $dialog.attr('id');
12456    const $buttons = $(`[data-dialog-open-popover=${id}]`);
12457    $buttons.attr('aria-expanded', false);
12458    $dialog.find(base.options.selectors.mediaElementWrapper).each((index, el) => {
12459      el.pause();
12460    });
12461    $dialog.removeClass(base.options.selectors.popoverIsShown);
12462    $buttons.off('focusout');
12463    $buttons.focus();
12464  },
12465  defaultOptions: {
12466    selectors: {
12467      slideshowsToUpdate: '.js-slideshow-dialog',
12468      mediaElementWrapper: 'mediaelement-wrapper',
12469      popoverIsShown: 'popover-is-shown'
12470    },
12471    updateCallbackAfterOpen: function () {},
12472    updateCallbackAfterClose: function () {}
12473  }
12474
12475});
12476
12477    /* Ende cms_dialog */
12478    /* Start cms_dynamic_file_uploader */
12479        "use strict";cms.makeCMSModule("cms.dynamic_file_uploader", {
12480
12481  init: function () {
12482    const base = this;
12483
12484    base.fileCount = 1;
12485    base.initButtons();
12486    base.initSubmit();
12487  },
12488
12489  initButtons: function () {
12490    const base = this;
12491
12492    base.$el.find(base.options.selectors.addFileButton).on('click', function (e) {
12493      e.preventDefault();
12494
12495      const newInput = $(`
12496          <div class="${base.options.fileInputClasses}">
12497            <input type="file" name="${base.options.fileInputName}${base.fileCount}" accept="${base.options.inputAcceptValue}">
12498          </div>
12499        `);
12500      base.$el.find(base.options.selectors.fileInputsWrapper).append(newInput);
12501      base.fileCount++;
12502      base.$el.find(base.options.selectors.removeFileButton).show();
12503      if (base.fileCount >= base.options.maxFileCount) {
12504        base.$el.find(base.options.selectors.addFileButton).hide();
12505      }
12506    });
12507
12508    base.$el.find(base.options.selectors.removeFileButton).on('click', function (e) {
12509      e.preventDefault();
12510
12511      const inputs = base.$el.find(base.options.selectors.fileInput);
12512      if (inputs.length > 1) {
12513        inputs.last().remove();
12514        base.fileCount--;
12515        if (base.fileCount <= 1) {
12516          base.$el.find(base.options.selectors.removeFileButton).hide();
12517        }
12518        base.$el.find(base.options.selectors.addFileButton).show();
12519      }
12520    });
12521  },
12522
12523  initSubmit: function () {
12524    const base = this;
12525
12526    base.$el.on('submit', function (e) {
12527      e.preventDefault();
12528
12529      const $fileFieldset = base.$el.find(base.options.selectors.fileFieldset);
12530      const $errorList = base.$el.find(base.options.selectors.errorList);
12531      $errorList.empty();
12532
12533      let totalSize = 0;
12534      let hasInvalidFileType = false;
12535
12536      $(`${base.options.selectors.fileInput} input[type="file"]`).each(function () {
12537        const file = this.files[0];
12538        if (file) {
12539          totalSize += file.size;
12540          if (!base.options.allowedTypes.includes(file.type)) {
12541            $errorList.append(`<li>${FILE_UPLOAD_INVALID_FILE_TYPE} ${file.name}</li>`);
12542          }
12543        }
12544      });
12545
12546      let hasInvalidSize = totalSize > base.options.maxTotalFileSize;
12547      let hasErrors = hasInvalidFileType || hasInvalidSize;
12548      if (hasErrors) {
12549        if (hasInvalidSize) {
12550          $errorList.append(`<li>${FILE_UPLOAD_INVALID_FILE_SIZE}</li>`);
12551        }
12552        $fileFieldset.get(0).scrollIntoView({ behavior: "smooth" });
12553      } else {
12554        this.submit();
12555      }
12556    });
12557  },
12558
12559  defaultOptions: {
12560    fileInputName: 'file-',
12561    allowedTypes: ['application/pdf', 'text/plain', 'image/jpeg', 'image/png', 'image/bmp'],
12562    inputAcceptValue: 'application/pdf,text/plain,image/jpeg,image/png,image/bmp',
12563    maxTotalFileSize: 10 * 1024 * 1024, // 10 MB
12564    maxFileCount: 6, // 10 MB
12565    fileInputClasses: 'c-file-inputs__input js-file-input',
12566    selectors: {
12567      fileInputsWrapper: '.js-file-inputs-wrapper',
12568      fileInput: '.js-file-input',
12569      addFileButton: '.js-file-inputs-add-file',
12570      removeFileButton: '.js-file-inputs-remove-file',
12571      fileFieldset: '.js-file-inputs-fieldset',
12572      errorList: '.js-file-inputs-error-list'
12573    }
12574  }
12575});
12576
12577    /* Ende cms_dynamic_file_uploader */
12578    /* Start cms_fancy_selects */
12579        /*! --GSBDocStart
12580 * @name: @cms/cms_fancy_selects
12581 * @version: 5.0.0
12582 * @description: Erzeugt für jedes enthaltene `<select>` ein Widget, welches dieses `<select>` steuert.
12583 * --CMSDocEnd
12584*/"use strict";
12585cms.makeCMSModule("cms.fancy_selects", {
12586  init: function () {
12587    if (this.arePreconditionsMet()) {
12588      this.transformSelects();
12589      this.bindSelectEvents();
12590      this.bindListEvents();
12591      this.makeFancy();
12592      this.makeAccessible();
12593    }
12594  },
12595  arePreconditionsMet() {
12596    var base = this;
12597    var conditionsMet = true;
12598    var multiselectElements = [];
12599    var optgroupElements = [];
12600    var messageText;
12601
12602    base.$el.find(this.options.selectors.select).each(function (i, select) {
12603      var $select = $(select);
12604      if ($select.is('[multiple], [aria-multiselectable]') || $select.attr('size') > 1) {
12605        multiselectElements.push(select);
12606      }
12607      if ($select.find('optgroup').length) {
12608        optgroupElements.push(select);
12609      }
12610    });
12611
12612    if (multiselectElements.length) {
12613      conditionsMet = false;
12614      messageText = `${base.moduleName}: Mindestens ein verarbeitetes <select> sieht eine Mehrfachauswahl vor. `;
12615      messageText += "Diese Eigenschaft wird nicht unterstützt. Die Initialisierung des Moduls wird abgebrochen. ";
12616      messageText += "Um diesen Fehler zu beheben, muss entweder die Option selectors.select angepasst werden oder ";
12617      messageText += "die Attribute 'multiple', 'size' und 'aria-multiselectable' von den <select>s entfernt werden.";
12618      console.error(messageText, multiselectElements);
12619    }
12620
12621    if (optgroupElements.length) {
12622      conditionsMet = false;
12623      messageText = `${base.moduleName}: Mindestens ein verarbeitetes <select> enthält ein <optgroup> Element. `;
12624      messageText += "Dieses Element wird nicht unterstützt. Die Initialisierung des Moduls wird abgebrochen. ";
12625      messageText += "Um diesen Fehler zu beheben, muss entweder die Option selectors.select angepasst werden oder ";
12626      messageText += "die <optgroup> Elemente entfernt werden.";
12627      console.error(messageText, optgroupElements);
12628    }
12629
12630    return conditionsMet;
12631  },
12632  makeAccessible: function () {
12633    var base = this;
12634    base.uis.forEach(function (ui) {
12635      var listId = base.generateID(),
12636        activeDescendant = ui.opts.filter('[aria-selected=true]');
12637
12638      ui.opts.each(function () {
12639        $(this).attr('id', base.generateID());
12640      });
12641      ui.errMsg.each(function () {
12642        $(this).attr('id', $(this).attr('id') || base.generateID());
12643      });
12644      $(ui.select.prop('labels')).each(function () {
12645        $(this).attr('id', $(this).attr('id') || base.generateID());
12646      });
12647
12648      if (ui.select.attr('aria-label')) {
12649        base.addLabelTo(ui.select, ui.select.attr('aria-label'));
12650        ui.select.attr('aria-label', null);
12651      }
12652
12653      ui.list.attr({
12654        role: "listbox",
12655        id: listId,
12656        'aria-labelledby': base.getLabelIDs(ui, null) || null,
12657        'aria-describedby': base.getDescriptionIDs(ui) || null
12658      });
12659      ui.heading.attr({
12660        role: 'combobox',
12661        'aria-owns': listId,
12662        'aria-controls': listId,
12663        'aria-labelledby': base.getLabelIDs(ui, null) || null,
12664        'aria-describedby': base.getDescriptionIDs(ui) || null,
12665        'aria-haspopup': 'listbox',
12666        'aria-activedescendant': activeDescendant.attr('id') || '',
12667        'aria-required': typeof ui.select.attr('required') !== "undefined" || Boolean(ui.select.attr('aria-required')),
12668        'aria-expanded': 'false',
12669        'title': ui.select.attr('title') || null
12670      });
12671    });
12672    base.$el.trigger('initialized.' + base.eventName);
12673  },
12674  addLabelTo: function (controlElem, labelText) {
12675    var base = this,
12676      id = base.generateID(),
12677      labelledby = controlElem.attr('aria-labelledby'),
12678      ariaLabels = !labelledby ? [] : labelledby.trim().split(/\s+/),
12679      newlyCreatedLabel;
12680
12681    newlyCreatedLabel = $("<span/>").
12682    attr({
12683      id: id,
12684      hidden: 'hidden'
12685    }).
12686    text(labelText);
12687    ariaLabels.push(id);
12688
12689    controlElem.
12690    attr('aria-labelledby', ariaLabels.join(' ')).
12691    before(newlyCreatedLabel);
12692  },
12693  getLabelIDs: function (ui, activeDescendant) {
12694    var base = this,
12695      ids = {},
12696      labels = $(ui.select.prop('labels')),
12697      ariaLabels = ui.select.attr('aria-labelledby') || '';
12698    [].forEach.call(labels.add(activeDescendant), function (label) {
12699      var labelId = $(label).attr('id');
12700      if (labelId) {
12701        ids[labelId.trim()] = true;
12702      }
12703    });
12704    ariaLabels.split('\s+').forEach(function (id) {
12705      if (id) {
12706        ids[id] = true;
12707      }
12708    });
12709    return Object.keys(ids).join(' ');
12710  },
12711  getDescriptionIDs: function (ui) {
12712    var base = this,
12713      ids = {},
12714      ariaDescriptions = ui.select.attr('aria-describedby') || '';
12715    ariaDescriptions.split(/\s+/g).forEach(function (id) {
12716      if (id) {
12717        ids[id] = true;
12718      }
12719    });
12720    ui.errMsg.filter(':visible').map(function (i, msg) {
12721      var id = $(msg).attr('id') || base.generateID();
12722      ids[id] = true;
12723    });
12724    return Object.keys(ids).join(' ');
12725  },
12726  transformSelects: function () {
12727    var base = this;
12728    base.selects = base.$el.find('select');
12729    base.uis = $.map(base.selects, function (sel) {
12730      var select = $(sel),
12731        labels = $(sel.labels),
12732        originalSelectId = select.attr('id'),
12733        newSelectId = 'replacedSelect_' + originalSelectId,
12734        wrapper,heading,list,ui,
12735        i,count;
12736      select.
12737      attr('id', newSelectId).
12738      addClass(base.options.classes.replacedSelect);
12739      wrapper = $(base.options.selectors.wrapper, base.el).insertAfter(select);
12740      list = wrapper.find(base.options.selectors.list);
12741      count = select.find('option').length;
12742      for (i = 0; i < count; i++) {
12743        list.append(base.options.markup.listItem);
12744      }
12745
12746      heading = wrapper.find(base.options.selectors.heading);
12747      ui = {
12748        select: select,
12749        wrapper: wrapper,
12750        heading: heading.attr('id', originalSelectId),
12751        list: list,
12752        opts: list.find('li'),
12753        errMsg: select.siblings(base.options.selectors.errorMessage)
12754      };
12755      labels.each(function (i, label) {
12756        $(label).attr('for', newSelectId);
12757      });
12758
12759      base.transformOptions(ui);
12760      base.updateValidityStatus(ui);
12761      return ui;
12762    });
12763  },
12764  transformOptions: function (ui) {
12765    var base = this,
12766      select = ui.select,
12767      options = select.find('option'),
12768      selectedIndex = select.prop('selectedIndex'),
12769      selectedOption = options.eq(selectedIndex > -1 ? selectedIndex : NaN),
12770      heading = ui.heading,
12771      list = ui.list;
12772    heading.text(selectedOption.text());
12773    options.each(function (i) {
12774      var opt = $(this),
12775        isSelected = opt.is(selectedOption);
12776      ui.opts.eq(i).
12777      attr('role', "option").
12778      attr('aria-disabled', opt.attr('disabled') ? "true" : "false").
12779      attr('aria-selected', isSelected ? "true" : "false").
12780      attr('data-value', opt.val()).
12781      text(opt.text());
12782    });
12783  },
12784  bindListEvents: function () {
12785    var base = this;
12786    base.uis.forEach(function (ui) {
12787      ui.wrapper.
12788      on('keydown', { base: base, ui: ui }, base.arrowNavigation).
12789      on('keydown', { base: base, ui: ui }, base.closeOnEscape);
12790      ui.list.
12791      on('mousedown', base.preventFocusOut).
12792      on('mouseup', { base: base, ui: ui }, base.directSelect);
12793    });
12794  },
12795  closeOnEscape: function (ev) {
12796    if (ev.key === "Escape" || ev.key === "Esc") {
12797      ev.preventDefault();
12798      $(this).trigger('close.simple_toggle');
12799    }
12800  },
12801  arrowNavigation: function (ev) {
12802    var base = ev.data && ev.data.base,
12803      ui = ev.data && ev.data.ui,
12804      activeOption = ui.opts.filter('[aria-selected=true]'),
12805      activeIndex = ui.opts.index(activeOption),
12806      option;
12807    switch (ev.key) {
12808      case "Down":
12809      case "ArrowDown":
12810        ui.wrapper.trigger('open.simple_toggle');
12811        option = base.findOption(ui, activeIndex, 'next');
12812        break;
12813      case "Up":
12814      case "ArrowUp":
12815        ui.wrapper.trigger('open.simple_toggle');
12816        option = base.findOption(ui, activeIndex, 'prev');
12817        break;
12818      default:
12819        return;
12820    }
12821    if (option && option.length && !option.is(activeOption)) {
12822      base.selectOption(ui, option);
12823    }
12824    ev.preventDefault();
12825    ev.stopPropagation();
12826  },
12827  findOption: function (ui, activeIndex, criterion) {
12828    var base = this,
12829      opts = ui.opts,
12830      opt,
12831      i,l;
12832    if (!opts.not('[aria-disabled=true]').length) {
12833      return $();
12834    }
12835    for (i = 1, l = opts.length; i <= l; i++) {
12836      if (criterion === 'next') {
12837        opt = opts.eq((activeIndex + i) % l);
12838      } else if (criterion === 'prev') {
12839        opt = opts.eq(activeIndex - i);
12840      }
12841      if (opt.not('[aria-disabled=true]').length) {
12842        return opt;
12843      }
12844    }
12845    return $();
12846  },
12847  selectOption: function (ui, opt) {
12848    var base = this,
12849      option = $(opt),
12850      optionId = option.attr('id');
12851    ui.select.
12852    val(option.attr('data-value')).
12853    trigger('change');
12854    base.transformOptions(ui);
12855    base.scrollBoxTo(ui, option);
12856    ui.heading.
12857    attr('aria-activedescendant', optionId).
12858    focus();
12859  },
12860  scrollBoxTo: function (ui, option) {
12861    const base = this;
12862    if (ui.list.length && option.length) {
12863      base.scrollIntoViewOneLevel(ui.list[0], option[0]);
12864    }
12865  },
12866  scrollIntoViewOneLevel: function (scrollContainer, scrollChild) {
12867    const containerRect = scrollContainer.getBoundingClientRect();
12868    const childRect = scrollChild.getBoundingClientRect();
12869
12870    const bottomDiff = childRect.bottom - containerRect.bottom;
12871    const topDiff = containerRect.top - childRect.top;
12872
12873    if (bottomDiff > 0) {// child is hidden below container
12874      scrollContainer.scrollBy(0, bottomDiff);
12875    }
12876    if (topDiff > 0) {// child is hidden above container
12877      scrollContainer.scrollBy(0, -topDiff);
12878    }
12879  },
12880  directSelect: function (ev) {
12881    var base = ev.data.base,
12882      ui = ev.data.ui,
12883      opt = $(ev.target);
12884    if (opt.is(':not([aria-disabled=true])')) {
12885      base.selectOption(ui, opt);
12886    }
12887  },
12888  makeFancy: function () {
12889    var base = this;
12890
12891    base.uis.forEach(function (ui) {
12892      ui.wrapper.
12893      cms_simple_toggle({
12894        closer: '',
12895        opener: ui.heading,
12896        item: ui.list,
12897        showClass: 'is-expanded',
12898        hideClass: 'is-collapsed'
12899      }).
12900      on('focusout', base.onFocusOut)
12901      //as the "parent" widget, we don't want any of these to bubble
12902      .on('close.simple_toggle.cms open.simple_toggle.cms toggle.simple_toggle.cms', base, base.preventBubbling);
12903      ui.opts.
12904      on('mouseup', base.triggerCloseOpt);
12905      ui.heading.addClass(base.options.classes.isFancy);
12906    });
12907  },
12908  onFocusOut: function (ev) {
12909    var wrapper = $(this),
12910      rel = ev.relatedTarget;
12911    if (!rel || !wrapper.find(rel).length) {
12912      wrapper.trigger('close.simple_toggle');
12913    }
12914  },
12915  preventBubbling: function (ev) {
12916    ev.stopPropagation();
12917  },
12918  preventFocusOut: function (ev) {
12919    ev.preventDefault();
12920  },
12921  triggerCloseOpt: function (ev) {
12922    var opt = $(this);
12923    if (opt.is(':not([aria-disabled=true])')) {
12924      opt.trigger('close.simple_toggle');
12925    }
12926  },
12927  bindSelectEvents: function () {
12928    var base = this;
12929    base.uis.forEach(function (ui) {
12930      ui.select.on('invalid change', { base: base, ui: ui }, base.validate);
12931    });
12932  },
12933  validate: function (ev) {
12934    var base = ev.data.base,
12935      ui = ev.data.ui,
12936      select = ui.select[0];
12937    base.updateValidityStatus(ui);
12938    if (!select.validity.valid) {
12939      setTimeout(function () {
12940        var activeElement = $(document.activeElement),
12941          isActiveElementAfterSelect = select.compareDocumentPosition(activeElement[0]) === Node.DOCUMENT_POSITION_FOLLOWING,
12942          isActiveElementFancy = activeElement.hasClass(base.options.classes.isFancy),
12943          isActiveElementSubmit = activeElement.is('[type=submit]');
12944        if (isActiveElementSubmit || !isActiveElementFancy && isActiveElementAfterSelect) {
12945          ui.heading.focus();
12946        }
12947      }, 0);
12948    }
12949  },
12950  updateValidityStatus: function (ui) {
12951    var base = this,
12952      select = ui.select[0],
12953      errMsgs = ui.select.siblings(base.options.selectors.errorMessage),
12954      hasStickyErrorMessage;
12955    if (select.validity.valid) {
12956      hasStickyErrorMessage = Boolean(errMsgs.filter(base.options.selectors.stickyErrorMessage).length);
12957      ui.heading.attr('aria-invalid', hasStickyErrorMessage ? null : false);
12958      errMsgs.not(base.options.selectors.stickyErrorMessage).attr('aria-hidden', true);
12959    } else {
12960      ui.heading.attr('aria-invalid', true);
12961      errMsgs.not(base.options.selectors.stickyErrorMessage).attr('aria-hidden', false);
12962    }
12963    ui.heading.attr('aria-describedby', base.getDescriptionIDs(ui) || null);
12964  },
12965  defaultOptions: {
12966    cycle: true,
12967    selectors: {
12968      select: 'select',
12969      wrapper: //Markup der neuen fancy Selectbox
12970      '<div class=\'c-fancy-selects__select\'>' +
12971      '<p class=\'c-fancy-selects__heading\' tabindex=\'0\'></p>' +
12972      '<ul class=\'c-fancy-selects__list\'></ul>' +
12973      '</div>',
12974      heading: '.c-fancy-selects__heading', // Selektor des Kopfelementes, in dem der aktuell ausgewählte Eintrag angezeigt wird
12975      list: '.c-fancy-selects__list', // Selektor der Liste mit Einträgen
12976      errorMessage: '.formError, .js-clientsidevalidation-errmsg', // Selektor der Fehlermeldungen
12977      stickyErrorMessage: '.formError' // Selektor der Fehlermeldungen, bei denen aria-hidden Attribut nicht gesetzt wird
12978    },
12979    markup: {
12980      listItem: "<li class='c-fancy-selects__item'/>"
12981    },
12982    classes: {
12983      isFancy: 'js-is-fancy',
12984      replacedSelect: 'c-fancy-selects__replaced-select'
12985    }
12986  }
12987});
12988
12989    /* Ende cms_fancy_selects */
12990    /* Start cms_filter_list */
12991        'use strict';
12992cms.makeCMSModule('cms.result_list_filter', {
12993  init: function () {
12994    const base = this;
12995    base.allInstances.instCount++;
12996    base.instNS = '.inst' + base.allInstances.instCount + '.' + base.eventName;
12997    base.prepareElements();
12998    base.registerEventListeners();
12999  },
13000
13001  prepareElements: function () {
13002    const base = this;
13003    base.$input = base.$el.find(base.options.selectors.input); // should find one
13004    base.$select = base.$el.find(base.options.selectors.select); // should find one or none
13005    base.$items = base.$el.find(base.options.selectors.item);
13006    base.$resultCount = base.$el.find(base.options.selectors.resultCount); // should find one or none
13007  },
13008
13009  registerEventListeners: function () {
13010    const base = this;
13011    base.$input.on('input', base, base.handleInput);
13012    base.$select.on('change', base, base.handleSelect);
13013    base.$el.find(base.options.selectors.inputClearButton).on('click', base, base.clearInput);
13014  },
13015
13016  clearInput: function (e) {
13017    const base = e.data;
13018    const selectValue = base.$select.length ? base.$select[0].value : '';
13019    base.$input.val('');
13020    base.$el.find(base.options.selectors.inputClearButton).removeClass('is-dirty');
13021    base.$el.find(base.options.selectors.resultCount).addClass("aural");
13022    base.$el.find(base.options.selectors.item).each((index, item) => {
13023      item.innerHTML = item.innerHTML.replace(/<\/?mark>/g, '');
13024    });
13025    base.filterResultList('', selectValue);
13026    base.updateDisplay('');
13027  },
13028
13029  handleInput: function (e) {
13030    const base = e.data;
13031    const inputValue = this.value;
13032    const selectValue = base.$select.length ? base.$select[0].value : '';
13033
13034    if (inputValue !== '') {
13035      base.$el.find(base.options.selectors.inputClearButton).addClass('is-dirty');
13036    } else {
13037      base.$el.find(base.options.selectors.inputClearButton).removeClass('is-dirty');
13038      base.filterResultList(inputValue, selectValue);
13039      base.updateDisplay(inputValue);
13040    }
13041
13042    if (inputValue.length >= 3) {
13043      base.$el.find(base.options.selectors.resultCount).removeClass("aural");
13044      base.filterResultList(inputValue, selectValue);
13045      base.updateDisplay(inputValue);
13046
13047      base.$el.find(base.options.selectors.item).each((index, item) => {
13048        item.innerHTML = item.innerHTML.replace(/<\/?mark>/g, '');
13049        item.innerHTML = item.innerHTML.replace(new RegExp(inputValue + "(?=[^>]*<)", 'igm'), '<mark>$&</mark>');
13050      });
13051    } else {
13052      base.$el.find(base.options.selectors.resultCount).addClass("aural");
13053      base.$el.find(base.options.selectors.item).each((index, item) => {
13054        item.innerHTML = item.innerHTML.replace(/<\/?mark>/g, '');
13055      });
13056    }
13057  },
13058
13059  handleSelect: function (e) {
13060    const base = e.data;
13061    const selectValue = this.value;
13062    const filterValue = base.$input[0].value;
13063    base.$items.each(function (i, item) {
13064      const $item = $(item);
13065
13066      if (base.passesSelectCheck($item, selectValue) && base.passesFilterCheck($item, filterValue)) {
13067        base.showItem($item);
13068      } else {
13069        base.hideItem($item);
13070      }
13071
13072      base.removeAuralClass($item);
13073    });
13074
13075    base.updateDisplay(filterValue);
13076  },
13077
13078  passesSelectCheck: function ($item, selectValue) {
13079    const base = this;
13080    return !selectValue || selectValue === 'default' || !$item.attr(base.options.attributes.dataDocumentCategory) || $item.attr(base.options.attributes.dataDocumentCategory).toLowerCase() === selectValue.toLowerCase();
13081  },
13082
13083  updateDisplay: function (inputValue) {
13084    const base = this;
13085    const hasDisplayElements = !!base.$resultCount.length;
13086    if (hasDisplayElements) {
13087      const $clone = base.$resultCount.clone(false);
13088      $clone.find(base.options.selectors.displayCount).text(base.$items.filter('.' + base.options.classes.show).length);
13089      $clone.find(base.options.selectors.displayTerm).text(inputValue);
13090      base.$resultCount.html($clone.html());
13091    }
13092  },
13093
13094  filterResultList: function (inputValue, selectValue) {
13095    const base = this;
13096    base.$items.each(function (i, item) {
13097      const $item = $(item);
13098      base.filterItem($item, inputValue, selectValue);
13099    });
13100  },
13101
13102  filterItem: function ($item, inputValue, selectValue) {
13103    const base = this;
13104    if (base.passesFilterCheck($item, inputValue) && base.passesSelectCheck($item, selectValue)) {
13105      base.showItem($item);
13106    } else {
13107      base.hideItem($item);
13108    }
13109    base.removeAuralClass($item);
13110  },
13111
13112  passesFilterCheck: function ($item, inputValue) {
13113    const base = this;
13114    const filterTerms = $item.attr(base.options.attributes.dataFilterTerms).split(',');
13115    return !!filterTerms.filter(function (filterTerm) {
13116      return filterTerm.toLowerCase().includes(inputValue.toLowerCase());
13117    }).length;
13118  },
13119
13120  showItem: function ($item) {
13121    const base = this;
13122    $item.removeClass(base.options.classes.hide);
13123    $item.addClass(base.options.classes.show);
13124  },
13125
13126  hideItem: function ($item) {
13127    const base = this;
13128    $item.removeClass(base.options.classes.show);
13129    $item.addClass(base.options.classes.hide);
13130  },
13131
13132  removeAuralClass: function ($item) {
13133    // the lazy-showing mechanism in the init.js uses an 'aural' class for showing items and hiding items
13134    // to avoid the items we want to show we need to remove the oral class from the items we need to show
13135    // if the filter shows items that are after items that are yet hidden by the lazy-showing mechanism, the lazy-loading breaks with the current implementation
13136    // therefore it is easiest to remove the lazy-showing 'aural' class and show all results once a filter value has been used
13137    $item.removeClass('aural');
13138  },
13139
13140  allInstances: {
13141    instCount: 0
13142  },
13143
13144  defaultOptions: {
13145    attributes: {
13146      dataFilterTerms: 'data-result-list-filter-terms',
13147      dataDocumentCategory: 'data-result-list-filter-document-category'
13148    },
13149    classes: {
13150      show: 'is-shown',
13151      hide: 'is-hidden'
13152    },
13153    selectors: {
13154      item: '.js-result-list-filter-item',
13155      input: '.js-result-list-filter-input',
13156      resultCount: '.js-result-list-filter-display',
13157      displayCount: '.js-result-list-filter-display-count',
13158      displayTerm: '.js-result-list-filter-display-term',
13159      select: '.js-result-list-filter-select',
13160      inputClearButton: '.js-result-list-input-clear'
13161    }
13162
13163  }
13164});
13165
13166    /* Ende cms_filter_list */
13167    /* Start cms_flip_card */
13168        /*! --GSBDocStart
13169 * @name: @cms/cms_flip_card
13170 * @version: 3.0.0
13171 * @description: A module that handles focus and toggle for flip card components.
13172 * --CMSDocEnd
13173*/"use strict";
13174cms.makeCMSModule('cms.flip_card', {
13175  init: function () {
13176    const base = this;
13177    base.allInstances.instCount++;
13178    base.instNS = '.inst' + base.allInstances.instCount + base.eventName;
13179    base.$back = base.$el.find(base.options.selectors.back);
13180    base.$buttons = base.$el.find(base.options.selectors.buttons);
13181    base.$front = base.$el.find(base.options.selectors.front);
13182
13183    base.backupTabindexIfNecessary(base.$front.add(base.$back));
13184    base.setActive('front');
13185
13186    base.$buttons.on('click', base, base.toggleCard);
13187  },
13188
13189  setActive: function (str) {
13190    const base = this;
13191
13192    if (str === 'front') {
13193      base.$front.attr({
13194        'aria-hidden': false,
13195        'tabindex': 0
13196      });
13197      base.$back.attr({
13198        'aria-hidden': true,
13199        'tabindex': -1
13200      });
13201
13202      base.restoreTabindex(base.$front);
13203      // base.getFocusables(base.$front).attr('tabindex', 0);
13204
13205      base.backupTabindexIfNecessary(base.$back);
13206      base.getFocusables(base.$back).attr('tabindex', -1);
13207    } else if (str === 'back') {
13208      base.$back.attr({
13209        'aria-hidden': false,
13210        'tabindex': 0
13211      });
13212      base.$front.attr({
13213        'aria-hidden': true,
13214        'tabindex': -1
13215      });
13216
13217      base.restoreTabindex(base.$back);
13218      // base.getFocusables(base.$back).attr('tabindex', 0);
13219
13220      base.backupTabindexIfNecessary(base.$front);
13221      base.getFocusables(base.$front).attr('tabindex', -1);
13222    }
13223  },
13224
13225  backupTabindexIfNecessary($container) {
13226    const base = this;
13227    const backupAttr = base.options.attributes.tabindexBackup;
13228    const $focusables = base.getFocusables($container);
13229
13230    $focusables.each((i, el) => {
13231      const $el = $(el);
13232      const isNecessary = $el.attr(backupAttr) === undefined;
13233      if (isNecessary) {
13234        $el.attr(backupAttr, $el.attr('tabindex') || '');
13235      }
13236    });
13237  },
13238
13239  restoreTabindex($container) {
13240    const base = this;
13241    const backupAttr = base.options.attributes.tabindexBackup;
13242    const $focusables = base.getFocusables($container);
13243
13244    $focusables.each((i, el) => {
13245      const $el = $(el);
13246      const backupValue = $el.attr(backupAttr);
13247      if (backupValue === '') {
13248        $el.removeAttr('tabindex');
13249      } else if (backupValue !== undefined) {
13250        $el.attr('tabindex', backupValue);
13251      }
13252    });
13253  },
13254
13255  getFocusables($container) {
13256    const base = this;
13257    const focusableOptions = base.options.selectors.focusable;
13258    let $focusables = $();
13259
13260    if (focusableOptions && focusableOptions.forEach) {
13261      focusableOptions.forEach((selector) => {
13262        $focusables = $focusables.add($container.find(selector));
13263      });
13264    }
13265
13266    return $focusables;
13267  },
13268
13269  toggleCard: function (event) {
13270    const base = event.data;
13271
13272    base.$el.toggleClass(base.options.classes.flipped);
13273
13274    if (!base.$el.hasClass(base.options.classes.flipped)) {
13275      base.setActive('front');
13276      base.$front.focus();
13277    } else {
13278      base.setActive('back');
13279      base.$back.focus();
13280    }
13281  },
13282
13283  allInstances: {
13284    instCount: 0
13285  },
13286
13287  defaultOptions: {
13288    attributes: {
13289      tabindexBackup: 'data-tabindex'
13290    },
13291    classes: {
13292      flipped: 'is-flipped'
13293    },
13294    selectors: {
13295      back: '.js-flip-card-back',
13296      buttons: '.js-flip-card-button', //Buttons that shall activate the flip toggle.
13297      front: '.js-flip-card-front',
13298      // Selectors for elements within the front and back side of the card of which this module should make sure they are not
13299      // focusable and tabbable after flipping.
13300      focusable: [
13301      '[tabindex]',
13302      'a[href]',
13303      'audio',
13304      'button',
13305      'input',
13306      'select',
13307      'textarea',
13308      'video']
13309
13310    }
13311  }
13312});
13313
13314    /* Ende cms_flip_card */
13315    /* Start cms_responsivetables */
13316        /*! --GSBDocStart
13317 * @name: @cms/cms_responsivetables
13318 * @version: 7.0.0
13319 * @description: CMS-Plugin zum Wrappen von Tabellen fuer die mobile Darstellung
13320 * --CMSDocEnd
13321*/"use strict";
13322cms.makeCMSModule('cms.responsiveTables', {
13323  init: function () {
13324    const base = this;
13325
13326    base.responsiveTables = base.$el.find('table').map(function () {
13327      const $table = $(this).wrap('<div class="' + base.options.classes.responsiveTable + '"></div>');
13328      const $respTable = $table.parent();
13329      if (base.options.way === 'scroll') {
13330        $respTable.wrap('<div class="' + base.options.classes.responsiveTableWrapper + '"></div>');
13331        const $respWrapper = $respTable.parent();
13332        $respTable.on('scroll.responsivetables.cms', base, base.handleScroll); // adding scroll listener to responsiveTable
13333        base.initClasses($respWrapper, $table, base.options.copyClassesFromTableToWrapper);
13334      }
13335      base.initClasses($respTable, $table, base.options.copyClassesFromTableToInnerDiv);
13336      return $respTable[0];
13337    });
13338    base.lastResize = Date.now() - base.options.throttle;
13339    base.onResize();
13340    $(window).on('resize', base, base.onResize);
13341  },
13342
13343  initClasses: function ($element, $table, option) {
13344    if (option) {
13345      if (option.include) {
13346        $element.addClass(option.include);
13347      }
13348      if (option.inherit) {
13349        $element.addClass($table.attr('class'));
13350      }
13351      if (option.exclude) {
13352        $element.removeClass(option.exclude);
13353      }
13354    }
13355  },
13356
13357  onResize: function (ev) {
13358    const base = ev ? ev.data : this;
13359    if (Date.now() >= base.lastResize + base.options.throttle) {
13360      base.responsiveTables.trigger('scroll.responsivetables.cms');
13361      base.lastResize = Date.now();
13362    }
13363  },
13364
13365  // adds classes to <div class="responsiveTableWrapper"></div>
13366  handleScroll: function (ev) {
13367    const base = ev.data;
13368    const respElem = this;
13369    const $respWrapper = $(respElem).parent();
13370    const scrollRight = respElem.scrollWidth - respElem.clientWidth - respElem.scrollLeft;
13371    if (respElem.scrollLeft > 0) {
13372      $respWrapper.addClass(base.options.classes.scrollLeft);
13373    } else {
13374      $respWrapper.removeClass(base.options.classes.scrollLeft);
13375    }
13376    if (scrollRight > 0) {
13377      $respWrapper.addClass(base.options.classes.scrollRight);
13378    } else {
13379      $respWrapper.removeClass(base.options.classes.scrollRight);
13380    }
13381  },
13382
13383  defaultOptions: {
13384    way: 'scroll',
13385    throttle: 50,
13386    copyClassesFromTableToInnerDiv: {
13387      exclude: '',
13388      include: '',
13389      inherit: false
13390    },
13391    copyClassesFromTableToWrapper: {
13392      exclude: '',
13393      include: '',
13394      inherit: false
13395    },
13396    classes: {
13397      scrollLeft: 'is-scroll-left',
13398      scrollRight: 'is-scroll-right',
13399      responsiveTable: 'l-responsive-table__inner',
13400      responsiveTableWrapper: 'l-responsive-table'
13401    }
13402  }
13403});
13404
13405    /* Ende cms_responsivetables */
13406    /* Start cms_scroll_control */
13407        /*! --GSBDocStart
13408 * @name: @cms/cms_scroll_control
13409 * @version: 2.0.0
13410 * @description: A module that handles scrolling for anchor-links on click and on pageload 
13411 * --CMSDocEnd
13412*/"use strict";
13413cms.makeCMSModule('cms.scroll_control', {
13414
13415  init: function () {
13416    const base = this;
13417    if (base.options.scrollOnPageLoad) {
13418      base.scrollOnPageLoad();
13419    }
13420    if (base.options.scrollOnAnchorLinkClick) {
13421      base.$el.find(base.options.selectors.anchorLinks).on('click', base, base.scrollOnAnchorLinkClick);
13422    }
13423  },
13424
13425  /**
13426   * Function that triggers on page load and scrolls to the element with the id given in the link, if the url contains
13427   * an element id.
13428   **/
13429  scrollOnPageLoad: function () {
13430    const base = this;
13431    if (window.location.hash) {
13432      const $elementToScrollTo = $('#' + $.escapeSelector(window.location.hash.substring(1))).not(base.options.selectors.excludeFromScrollOnPageLoad);
13433      if ($elementToScrollTo.length) {
13434        if (history.scrollRestoration) {
13435          history.scrollRestoration = 'manual';
13436        }
13437        setTimeout(function () {
13438          base.animatedScroll($elementToScrollTo);
13439        },
13440        // if cookiebanner is visible
13441        $(base.options.selectors.cookiebanner).is(':visible') ? base.options.cookiebannerAnimationDuration + 50 : 0);
13442      }
13443    }
13444  },
13445
13446  /**
13447   * Function that that is registered to the click event of selected anchor-links.
13448   *
13449   * @param {event} e - Event that is fired on click of an anchor link.
13450   *
13451   **/
13452  scrollOnAnchorLinkClick: function (e) {
13453    const base = e.data;
13454    if (this.origin === window.location.origin && this.pathname === window.location.pathname && this.search === window.location.search) {
13455      e.preventDefault();
13456      const hash = $(e.currentTarget).attr('href');
13457      history.pushState({}, '', hash);
13458      const id = hash.substring(hash.indexOf('#'));
13459      const $elementToScrollTo = $(id.replaceAll('.', '\\.'));
13460      base.animatedScroll($elementToScrollTo);
13461    }
13462  },
13463
13464  /**
13465   * Calculates the height of all overlays, adds them and returns the result.
13466   *
13467   * @return {number} height - Height of overlays in pixel.
13468   *
13469   **/
13470  getOverlaysHeight: function () {
13471    const base = this;
13472    let height = 0;
13473    $(base.options.selectors.overlays).each(function (index, element) {
13474      height = height + $(element).outerHeight(true);
13475    });
13476    return height;
13477  },
13478
13479  /**
13480   * Scrolls to the Element $elementToScrollTo including the given offset in options.scrollOffset
13481   *
13482   * @param {object} $target - Element that should be scrolled into view.
13483   *
13484   **/
13485  animatedScroll: function ($elementToScrollTo) {
13486    const base = this;
13487    const scrollOffset = base.options.scrollOffset;
13488    let offset = 0;
13489
13490    if (typeof scrollOffset === 'number') {
13491      offset = scrollOffset || 0;
13492    } else if (typeof scrollOffset === 'function') {
13493      offset = scrollOffset.call(base, $elementToScrollTo) || 0;
13494    }
13495
13496    if ($elementToScrollTo.length > 0) {
13497      base.$el.css('scroll-behavior', 'auto'); // jquery animiertes Scrollen funktioniert nicht korrekt mit scroll-behavior: 'smooth'
13498      let overlaysHeight = base.getOverlaysHeight() + offset;
13499      base.$el.clearQueue().stop().animate({
13500        scrollTop: $elementToScrollTo.offset().top - overlaysHeight
13501      }, base.options.scrollAnimationDuration, 'linear',
13502
13503      function () {//erster Callback nach erster Scroll Animation
13504        // ensure that the last scroll event (used by e.g. cms_shrinkheader) from the previous scrolling animation has been fired and the overlaysHeight has been properly updated
13505        requestAnimationFrame(function () {
13506          overlaysHeight = base.getOverlaysHeight() + offset;
13507          base.$el.clearQueue().stop().animate({
13508            // Rescroll um Overlay Änderungen abzufangen
13509            scrollTop: $elementToScrollTo.offset().top - overlaysHeight
13510          }, base.options.scrollAnimationDuration / 2, 'linear', function () {
13511            requestAnimationFrame(function () {// zweiter Callback nach zweiter Scroll Animation
13512              base.$el.css('scroll-behavior', ''); // Scroll Verhalten Manipulation entfernen
13513              if (!$elementToScrollTo.is($('[tabindex]'))) {
13514                $elementToScrollTo.attr('tabindex', -1); // tabindex="-1" hinzufügen um das Element per Javascript fokussierbar zu machen, falls es nicht bereits einen tabindex hat
13515              }
13516              $elementToScrollTo[0].focus({ preventScroll: true }); // nicht per Browser scrollen, da wir bereits mit JavaScript an die korrekte Stelle gescrollt haben
13517            });
13518          });
13519        });
13520      });
13521    }
13522  },
13523
13524  defaultOptions: {
13525    cookiebannerAnimationDuration: 1800, // same as gsb_banner animationSpeed
13526    scrollAnimationDuration: 200,
13527    scrollOnPageLoad: true,
13528    scrollOnAnchorLinkClick: true,
13529    scrollOffset: function (referenceElement) {
13530      return 0;
13531    },
13532    selectors: {
13533      anchorLinks: 'a[href*="#"]:not(.tabs-list a,[href="#"])',
13534      excludeFromScrollOnPageLoad: '.js-accordion-hashControlled .js-accordion-entry',
13535      cookiebanner: '', // use valid selector if the cookiebanner is displayed at the top of the page, positioned relative, pushing the contents down during the animation.
13536      overlays: '.js-header.is-sticky'
13537    }
13538  }
13539});
13540
13541    /* Ende cms_scroll_control */
13542    /* Start cms_simple_toggle */
13543        /*! --GSBDocStart
13544 * @name: @cms/cms_simple_toggle
13545 * @version: 6.0.0
13546 * @description: Vielfältig einsetzbare Ein- und Ausblendefunktion
13547 * --CMSDocEnd
13548*/"use strict";
13549cms.makeCMSModule('cms.simple_toggle', {
13550  init: function () {
13551    const base = this;
13552
13553    base.closer = $(base.options.closer, base.el);
13554    base.opener = $(base.options.opener, base.el);
13555    base.openerToFocusOnClose = null;
13556    base.items = $(base.options.item, base.el);
13557    base.isOpenInitially = base.opener.hasClass(base.options.activeClass);
13558    base.isOpen = base.isOpenInitially;
13559    base.backupAttributes();
13560
13561    base.$el.cms_responsiveListener(base);
13562  },
13563
13564  initialize: function () {
13565    const base = this;
13566
13567    if (!base.options.uninit) {
13568      base.setupOpenerAndItems();
13569      base.setupEventListeners();
13570      base.insertCloser();
13571    } else {
13572      base.uninit();
13573    }
13574  },
13575
13576  backupAttributes: function () {
13577    const base = this;
13578    const openerListAttr = typeof base.options.openerListAttr === 'string' ? base.options.openerListAttr : '';
13579
13580    base.items.each(function (i, el) {
13581      const item = $(el);
13582      item.attr('data-persistent-role', item.attr('role') || '');
13583      if (openerListAttr) {
13584        item.attr('data-persistent-' + openerListAttr, item.attr(openerListAttr) || '');
13585      }
13586    });
13587
13588    base.opener.attr({
13589      'data-persistent-role': base.opener.attr('role') || '',
13590      'data-persistent-tabindex': base.opener.attr('tabindex') || '',
13591      ['data-persistent-' + base.options.openerStatusAttr]: base.opener.attr(base.options.openerStatusAttr) || '',
13592      ['data-persistent-' + base.options.itemListAttr]: base.opener.attr(base.options.itemListAttr) || ''
13593    });
13594  },
13595
13596  restoreAttributes: function () {
13597    const base = this;
13598    const openerListAttr = typeof base.options.openerListAttr === 'string' ? base.options.openerListAttr : '';
13599
13600    base.items.each(function (i, el) {
13601      const item = $(el);
13602      item.attr('role', item.attr('data-persistent-role') || null);
13603      if (openerListAttr) {
13604        item.attr(openerListAttr, item.attr('data-persistent-' + openerListAttr) || null);
13605      }
13606    });
13607
13608    base.opener.attr({
13609      role: base.opener.attr('data-persistent-role') || null,
13610      tabindex: base.opener.attr('data-persistent-tabindex') || null,
13611      [base.options.openerStatusAttr]: base.opener.attr('data-persistent-' + base.options.openerStatusAttr) || null,
13612      'aria-hidden': null,
13613      [base.options.itemListAttr]: base.opener.attr('data-persistent-' + base.options.itemListAttr) || null
13614    });
13615  },
13616
13617  setupOpenerAndItems: function () {
13618    const base = this;
13619    const openerListAttr = typeof base.options.openerListAttr === 'string' ? base.options.openerListAttr : '';
13620    const useAriaLabelledBy = openerListAttr.toLowerCase() === 'aria-labelledby';
13621    $().add(base.opener).add(base.items).each(function () {
13622      $(this).attr('id', $(this).attr('id') || base.generateID());
13623    });
13624    base.items.each(function (i, el) {
13625      const item = $(el);
13626      item.attr('role', item.attr('role') || 'region');
13627
13628      if (base.isOpen) {
13629        $(this).addClass(base.options.showClass);
13630        $(this).removeClass(base.options.hideClass);
13631      } else {
13632        $(this).addClass(base.options.hideClass);
13633        $(this).removeClass(base.options.showClass);
13634      }
13635
13636      if (!useAriaLabelledBy || !item.attr('aria-label')) {
13637        base.addIdsToAttr(item, openerListAttr, base.opener);
13638      }
13639    });
13640
13641    if (!base.opener.is('button')) {
13642      base.opener.attr('role', 'button').attr('tabindex', base.opener.attr('tabindex') || 0);
13643    }
13644    base.opener.attr(base.options.openerStatusAttr, base.isOpen);
13645    base.opener.addClass(base.isOpen ? base.options.activeClass : base.options.inactiveClass);
13646    base.items.attr('aria-hidden', !base.isOpen);
13647    base.addIdsToAttr(base.opener, base.options.itemListAttr, base.items);
13648
13649    if (base.opener.length && !$('body').find(base.opener).length) {
13650      base.$el[base.options.openerInsert](base.opener);
13651    }
13652  },
13653
13654  setupEventListeners: function () {
13655    const base = this;
13656    const namespace = base.eventName;
13657    base.$el.on(`open.${namespace}`, base, base.open);
13658    base.$el.on(`toggle.${namespace}`, base, base.openerHandler);
13659    base.$el.on(`close.${namespace}`, base, base.close);
13660    $().add(base.opener).add(base.closer).add(base.items).on(`keydown.${namespace}`, base, base.escapeHandler);
13661    base.closer.on(`click.${namespace} keydown.${namespace}`, base, base.closerHandler);
13662    base.opener.on(`click.${namespace} keydown.${namespace}`, base, base.openerHandler);
13663    if (base.options.closeOnFocusout) {
13664      base.opener.add(base.items).on(`mousedown.${namespace} focusout.${namespace}`, base, base.focusoutHandler);
13665    }
13666  },
13667
13668  insertCloser: function () {
13669    const base = this;
13670    if (base.closer.length && !$('body').find(base.closer).length) {
13671      if (base.items.length < 2) {
13672        base.items[base.options.closerInsert](base.closer);
13673      } else if (typeof base.options.closer === 'string') {
13674        base.items[base.options.closerInsert](base.options.closer);
13675      } else {
13676        base.$el[base.options.closerInsert](base.closer);
13677      }
13678    }
13679  },
13680
13681  addIdsToAttr: function ($elem, attrName, addElems) {
13682    const val = attrName ? $elem.attr(attrName) : '';
13683    const oldIds = val ? val.trim().split(/\s+/g) : [];
13684    const ids = {};
13685    if (attrName) {
13686      oldIds.forEach(function (id) {
13687        ids[id] = true;
13688      });
13689      addElems.each(function () {
13690        ids[$(this).attr('id')] = true;
13691      });
13692      $elem.attr(attrName, Object.keys(ids).join(' '));
13693    }
13694  },
13695
13696  openerHandler: function (ev) {
13697    const base = ev.data;
13698    if (!ev.key || ev.key === 'Spacebar' || ev.key === ' ' || ev.key === 'Enter') {
13699      ev.preventDefault();
13700      if (base.opener.hasClass(base.options.activeClass)) {
13701        base.close(ev);
13702      } else {
13703        base.open(ev);
13704        if ($(ev.target).is(base.opener)) {
13705          base.openerToFocusOnClose = ev.target;
13706        }
13707      }
13708    }
13709  },
13710
13711  closerHandler: function (ev) {
13712    const base = ev.data;
13713    if (!ev.key || ev.key === 'Spacebar' || ev.key === ' ' || ev.key === 'Enter') {
13714      ev.preventDefault();
13715      base.close(ev);
13716    }
13717  },
13718
13719  focusoutHandler: function (ev) {
13720    const base = ev ? ev.data : this;
13721    if (ev.type === 'mousedown') {
13722      // When the mousedown event occurs a focusout event follows.
13723      // If the mousedown event occurs on a non-focusable element, the new activeElement will be <body> which is outside the $box.
13724      ev.preventDefault(); // Kill all focusout events following the mousedown event to avoid closing the toggle item when mousedowning inside.
13725      // The suppressed possible focus change needs to be handled manually.
13726      const $closestOpener = $(ev.target).closest(base.opener);
13727      if ($closestOpener.length) {
13728        // If the clicked Element is focusable but inside the opener
13729        $closestOpener.trigger('focus'); // Set the focus on the opener
13730      } else {
13731        $(ev.target).trigger('focus'); // Set the focus to the element clicked.
13732      }
13733      // If the clicked element is focusable, it will trigger a focusout event where the new activeElement is inside opened menu.
13734      // This will be handled correctly for the focusout event.
13735      // If the clicked element is not focusable, then the focus will stay where it is and no unwanted focusout event will be triggered.
13736    } else {
13737      setTimeout(function () {
13738        if (!$(document.activeElement).closest(base.items.add(base.opener)).length) {
13739          // new activeElement is not inside the base.items
13740          base.close(null, true);
13741        }
13742      }, 0);
13743    }
13744  },
13745
13746  escapeHandler: function (ev) {
13747    const base = ev ? ev.data : this;
13748    switch (ev.key) {
13749      case 'Esc': // IE/Edge
13750      case 'Escape': // W3C
13751        ev.preventDefault();
13752        if (base.$el.find(base.items).hasClass(base.options.showClass)) {
13753          base.close(ev);
13754        }
13755        break;
13756    }
13757  },
13758
13759  open: function (ev) {
13760    const base = ev ? ev.data : this;
13761    if (ev) {
13762      ev.preventDefault();
13763      ev.stopPropagation();
13764    }
13765    if (base.specialTrigger('beforeOpen.simple_toggle.cms', ev)) {
13766      base.isOpen = true;
13767      base.opener.
13768      addClass(base.options.activeClass).
13769      removeClass(base.options.inactiveClass).
13770      attr(base.options.openerStatusAttr, 'true');
13771      base.items.
13772      addClass(base.options.showClass).
13773      removeClass(base.options.hideClass).
13774      attr('aria-hidden', 'false');
13775      base.specialTrigger('afterOpen.simple_toggle.cms', ev);
13776    }
13777  },
13778
13779  close: function (ev, preventFocusingOpener) {
13780    const base = ev ? ev.data : this;
13781    if (ev) {
13782      ev.preventDefault();
13783      ev.stopPropagation();
13784    }
13785    if (base.specialTrigger('beforeClose.simple_toggle.cms', ev)) {
13786      base.isOpen = false;
13787      base.opener.
13788      addClass(base.options.inactiveClass).
13789      removeClass(base.options.activeClass).
13790      attr(base.options.openerStatusAttr, 'false');
13791      base.items.
13792      addClass(base.options.hideClass).
13793      removeClass(base.options.showClass).
13794      attr('aria-hidden', 'true');
13795      if (base.openerToFocusOnClose) {
13796        if (!preventFocusingOpener) {
13797          $(base.openerToFocusOnClose).trigger('focus');
13798        }
13799        base.openerToFocusOnClose = null;
13800      }
13801      base.specialTrigger('afterClose.simple_toggle.cms', ev);
13802    }
13803  },
13804
13805  specialTrigger: function (evStr, ev) {
13806    var base = this,
13807      namespaces = evStr.split('.'),
13808      type = namespaces.shift(),
13809      event;
13810    namespaces = namespaces.sort();
13811    event = $.Event(type, {
13812      namespace: namespaces.join('.'),
13813      relatedEvent: ev || null
13814    });
13815    base.$el.trigger(event, base);
13816    return !event.isDefaultPrevented();
13817  },
13818
13819  uninit: function () {
13820    const base = this;
13821
13822    base.isOpen = base.isOpenInitially;
13823
13824    base.restoreAttributes();
13825
13826    base.items.
13827    removeClass(base.options.hideClass).
13828    removeClass(base.options.showClass);
13829
13830    base.opener.
13831    removeClass(base.options.activeClass).
13832    removeClass(base.options.inactiveClass);
13833
13834    const apiEvents = ['open', 'toggle', 'close'];
13835    base.$el.off(apiEvents.map((s) => s + '.' + base.eventName).join(' '));
13836
13837    const nativeEvents = ['click', 'mousedown', 'keydown', 'focusout'];
13838    const nativeEventsStr = nativeEvents.map((s) => s + '.' + base.eventName).join(' ');
13839    base.opener.off(nativeEventsStr);
13840    base.items.off(nativeEventsStr);
13841    base.closer.off(nativeEventsStr);
13842  },
13843
13844  defaultOptions: {
13845    uninit: false,
13846    item: '.js-simple-toggle-item',
13847    openerListAttr: 'aria-labelledby',
13848    showClass: 'is-shown',
13849    hideClass: 'is-hidden',
13850    opener: '.js-simple-toggle-opener',
13851    openerInsert: 'prepend',
13852    openerStatusAttr: 'aria-expanded',
13853    itemListAttr: 'aria-controls',
13854    activeClass: 'active-control',
13855    inactiveClass: 'inactive-control',
13856    closer: '.js-simple-toggle-closer', //can also be html
13857    closerInsert: 'append',
13858    closeOnFocusout: false,
13859    respondToEvents: true,
13860    onRefresh: function () {
13861      this.initialize();
13862    }
13863  }
13864});
13865
13866    /* Ende cms_simple_toggle */
13867    /* Start cms_slideshow_numbers */
13868        /*! --GSBDocStart
13869 * @name: @cms/cms_slideshow_numbers
13870 * @version: 3.0.0
13871 * @description: Wrapper-Plugin für slick.js mit BITV-Anpassungen optimiert zur Ausgabe der aktuellen "Seite"
13872 * --CMSDocEnd
13873*/"use strict";
13874cms.makeCMSModule('cms.slideshow_numbers', {
13875
13876  init: function () {
13877    const base = this;
13878    base.prepareReInitEventNamespace();
13879    const allElementsUrl = base.$el.data('href');
13880    if (allElementsUrl) {
13881      // Slides über XHR
13882      base.loadSlidesAndInitSlick(allElementsUrl);
13883    } else {
13884      // Slides im DOM
13885      if (base.hasEnoughSlides()) {
13886        base.addPlaceholderSlidesIfNecessary();
13887        base.backupAttributes();
13888        base.initSlick();
13889      } else {
13890        base.afterInit();
13891      }
13892    }
13893  },
13894
13895  prepareReInitEventNamespace: function () {
13896    const base = this;
13897    const selector = base.$el.attr('class').replace(/(^ *| +)/g, '.');
13898    const instanceIndex = $(selector).index(base.$el);
13899    base.reInitEventNamespace = selector + '-' + instanceIndex;
13900  },
13901
13902  addPlaceholderSlidesIfNecessary: function () {
13903    const base = this,
13904      slickOptions = base.options.slickOptions,
13905      breakpoints = slickOptions && slickOptions.responsive;
13906
13907    var $slider = base.$el,
13908      slidesToScroll,
13909      slidesToShow;
13910
13911    // Finde den aktuellen Breakpoint
13912    const currentBreakpointValue = Math.max.apply(null, breakpoints.map((e) => {
13913      if (!slickOptions.mobileFirst) {
13914        return $(window).width() < e.breakpoint ? e.breakpoint : 0;
13915      } else {
13916        return $(window).width() > e.breakpoint ? e.breakpoint : 0;
13917      }
13918    }));
13919
13920    const currentBreakpoint = breakpoints.find((e) => e.breakpoint === currentBreakpointValue);
13921
13922    if (typeof currentBreakpoint !== 'undefined') {
13923      slidesToScroll = currentBreakpoint.settings.slidesToScroll;
13924      slidesToShow = currentBreakpoint.settings.slidesToShow;
13925    } else if (slickOptions.slidesToShow) {
13926      slidesToScroll = slickOptions.slidesToScroll;
13927      slidesToShow = slickOptions.slidesToShow;
13928    }
13929
13930    base.$el.find('.js-slide-placeholder').remove();
13931    const $slides = $slider.children(base.options.slickOptions.slide);
13932    const slideCount = $slides.length;
13933
13934    if (slideCount > slidesToShow && slidesToScroll > 1) {
13935      let iPlaceholdersToAdd = slidesToShow - (sli
13935deCount - slidesToShow) % slidesToScroll;
13936      if (iPlaceholdersToAdd !== slidesToShow && iPlaceholdersToAdd > 0) {
13937        base.addPlaceholderSlides(iPlaceholdersToAdd);
13938      }
13939    }
13940  },
13941
13942  addPlaceholderSlides: function (iPlaceholdersToAdd) {
13943    const base = this;
13944    for (let i = 0; i < iPlaceholdersToAdd; i++) {
13945      base.$el.append('<div class="js-slide js-slide-placeholder">');
13946    }
13947  },
13948
13949  hasEnoughSlides: function () {
13950    const base = this,
13951      slickOptions = base.options.slickOptions,
13952      breakpoints = slickOptions && slickOptions.responsive;
13953    // Wenn breakpointabhängige Überprüfung angefordert ist
13954    if (!base.options.initIfNotEnoughSlides && breakpoints) {
13955      // Finde den aktuellen Breakpoint
13956      const currentBreakpointValue = Math.max.apply(null, breakpoints.map((e) => {
13957        if (!slickOptions.mobileFirst) {
13958          return $(window).width() < e.breakpoint ? e.breakpoint : 0;
13959        } else {
13960          return $(window).width() > e.breakpoint ? e.breakpoint : 0;
13961        }
13962      }));
13963
13964      const currentBreakpoint = breakpoints.find((e) => e.breakpoint === currentBreakpointValue);
13965
13966      if (typeof currentBreakpoint !== 'undefined') {
13967        return base.$el.children().length > currentBreakpoint.settings.slidesToShow;
13968      } else if (slickOptions.slidesToShow) {
13969        return base.$el.children().length > slickOptions.slidesToShow;
13970      }
13971    }
13972    return base.$el.children().length > 1;
13973  },
13974
13975
13976  /**
13977   * Lädt die anzuzeigenen Slides per XHR aus dem CMS-Content, fügt diese als Children des base.el ein und initialisiert dann slick.
13978   * @param allElementsUrl
13979   */
13980  loadSlidesAndInitSlick: function (allElementsUrl) {
13981    const base = this;
13982    $.ajax({
13983      url: allElementsUrl,
13984      context: base,
13985      success: base.onReceiveAllElements
13986    });
13987
13988  },
13989
13990  onReceiveAllElements: function (data) {
13991    const base = this;
13992    base.$el.html(data);
13993    if (base.hasEnoughSlides()) {
13994      base.addPlaceholderSlidesIfNecessary();
13995      base.initSlick();
13996    } else {
13997      base.afterInit();
13998    }
13999  },
14000
14001  afterInit: function () {
14002    const base = this;
14003    base.$el.
14004    addClass(base.options.classes.initialized).
14005    trigger('init.' + base.eventName, base);
14006  },
14007
14008  initSlick: function () {
14009    const base = this;
14010    let slickOptions = base.options.slickOptions;
14011    slickOptions = base.handleNavigationArrows(slickOptions);
14012    slickOptions = base.handleNavigationDots(slickOptions);
14013    base.$el.on('beforeChange.slick', base, base.onSlickBeforeChange).unbind('afterChange.slick').on('afterChange.slick', base, base.onSlickAfterChange).unbind('init.slick').on('init.slick', base, base.onSlickInit).unbind('breakpoint.slick').on('breakpoint.slick', base, base.onSlickBreakpoint).unbind('destroy.slick').on('destroy.slick', base, base.onSlickDestroy);
14014    base.slick = base.$el.slick(slickOptions).slick('getSlick');
14015    base.patchSlickHeightAnimation();
14016    base.patchSlickGetLeft();
14017  },
14018
14019
14020  /**
14021   * Sorgt für eine bessere Animation der Höhe, wenn adaptiveHeight true gesetzt ist.
14022   */
14023  patchSlickHeightAnimation: function () {//monkey-patch height anim in case slidesToShow > 1
14024    const base = this;
14025    $.extend(base.slick, {
14026      getActiveSlidesHeight: function () {
14027        let _ = this;
14028        if (base.options.isNavigationSlideshow) {
14029          _.recalculateActiveSlidesForNavigationSlideshow();
14030        }
14031        let activeSlides = _.$slides.filter('.slick-active');
14032        return Math.max(...activeSlides.map((i, el) => $(el).outerHeight()));
14033      },
14034      recalculateActiveSlidesForNavigationSlideshow: function () {
14035        let _ = this,
14036          activeSlides = _.$slides.filter('.slick-active');
14037        if (activeSlides.length < _.options.slidesToShow) {
14038          _.$slides.slice(-_.options.slidesToShow).addClass('slick-active');
14039        }
14040      },
14041      animateHeight: function () {
14042        let _ = this;
14043        if (_.options.adaptiveHeight === true && _.options.vertical === false) {
14044          _.$list.animate({
14045            height: _.getActiveSlidesHeight()
14046          }, _.options.speed);
14047        }
14048      },
14049      setHeight: function () {
14050        let _ = this;
14051        if (_.options.adaptiveHeight === true && _.options.vertical === false) {
14052          _.$list.css('height', _.getActiveSlidesHeight());
14053        }
14054      }
14055    });
14056
14057  },
14058
14059  /**
14060   * Verhindert das "Verschwinden" von Slides, falls slideCount <= slidesToShow
14061   */
14062  patchSlickGetLeft: function () {//monkey-patch getLeft in case slideCount <= slidesToShow
14063    const base = this,
14064      originalGetLeft = base.slick.getLeft;
14065    $.extend(base.slick, {
14066      getLeft: function () {
14067        let _ = this;
14068        if (_.slideCount <= _.options.slidesToShow) {
14069          return 0;
14070        } else {
14071          return originalGetLeft.apply(base.slick, arguments);
14072        }
14073      }
14074    });
14075
14076  },
14077
14078  patchSlickAccessibility: function (slick) {
14079    const base = this;
14080    base.slick = slick;
14081
14082    $.extend(base.slick, {
14083      initADA: function () {
14084        var _ = this;
14085        const numDotGroups = _.options.infinite ? Math.ceil(_.slideCount / _.options.slidesToScroll) : Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll) + 1;
14086        var tabControlIndexes = _.getNavigableIndexes().filter(function (val) {
14087          return val >= 0 && val < _.slideCount;
14088        });
14089
14090        _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
14091          'aria-hidden': 'true'
14092        });
14093
14094        if (_.$dots !== null) {
14095          _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function (i) {
14096            var slideControlIndex = tabControlIndexes.indexOf(i);
14097            var ariaAttributeName;
14098
14099            $(this).attr({
14100              'role': 'tabpanel',
14101              'id': 'slick-slide' + _.instanceUid + i
14102            });
14103
14104
14105            if (slideControlIndex !== -1) {
14106              ariaAttributeName = _.options.slidesToShow > 1 ? 'aria-labelledby' : 'aria-describedby';
14107              $(this).removeAttr('aria-describedby');
14108              $(this).attr(ariaAttributeName, 'slick-slide-control' + _.instanceUid + slideControlIndex);
14109            }
14110          });
14111
14112          _.$dots.attr('aria-label', base.options.tablistAriaLabel).attr('role', 'tablist').find('li').each(function (i) {
14113            var mappedSlideIndex = tabControlIndexes[i];
14114
14115            $(this).attr({
14116              'role': 'presentation'
14117            });
14118
14119
14120            $(this).find('button').first().attr({
14121              'role': 'tab',
14122              'id': 'slick-slide-control' + _.instanceUid + i,
14123              'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex,
14124              'aria-label': i + 1 + ' / ' + numDotGroups,
14125              'aria-current': 'false',
14126              'tabindex': '-1'
14127            });
14128
14129          }).eq(Math.ceil(_.currentSlide / _.options.slidesToScroll)).find('button').attr({
14130            'aria-current': 'true',
14131            'tabindex': '0'
14132          }).end();
14133        }
14134
14135        _.activateADA();
14136
14137        base.accessible();
14138      },
14139      activateADA: function () {
14140        let _ = this;
14141        const focusable = base.options.selectors.focusable;
14142        const $activeSlides = _.$slideTrack.find('.slick-active, .slick-current');
14143        $activeSlides.attr({ 'aria-hidden': 'false' });
14144        $.each($activeSlides.find(focusable).not('[disabled]').not('[aria-disabled=\'true\']'), (i, e) => {
14145          $(e).attr('tabindex', !!$(e).data('tabindex-persistent') ? $(e).data('tabindex-persistent') : 0);
14146        });
14147      }
14148    });
14149
14150
14151    base.removeTabIndexFromSlides();
14152    base.removeAriaSelectedFromDots();
14153  },
14154
14155  /**
14156   * Versteckt oder zeigt die Navigation an, abhängig davon, ob es ausreichend Slides für eine Slideshow gibt.
14157   * @param slick das Slick-Objekt
14158   */
14159  showHideNavigation: function (slick) {
14160    const base = this;
14161    const numOfChildren = base.$el.find('.slick-slide').length || base.$el.children().not(base.options.navigation.selector).length;
14162    if (!slick.unslicked && slick.options.slidesToShow < numOfChildren) {
14163      base.$el.find(base.options.navigation.selector).show();
14164      base.$el.addClass(base.options.classes.hasNavigation);
14165    } else {
14166      base.$el.find(base.options.navigation.selector).hide();
14167      base.$el.removeClass(base.options.classes.hasNavigation);
14168    }
14169  },
14170
14171  /**
14172   * Initialisiert das "cms_multimedia"-Modul, falls es in den Slides <video> oder <audio> Elemente gibt.
14173   */
14174  initMultimedia: function () {
14175    const base = this;
14176    cms.requireCMSComponent('bundle_multimedia', base.$el.find('audio, video')).
14177    done(function ($media) {
14178      $media.cms_multimedia(base.options.multimediaOptions);
14179      // base.$el.find('.js-embed-youtube').cms_embed_youtube();
14180    });
14181  },
14182
14183  handlePlayButton: function () {
14184    const base = this;
14185    const ops = base.options.navigation.autoplay;
14186
14187    if (base.options.slickOptions.autoplay && ops.createPlayButton) {
14188      let $parent = base.$el.find(base.options.navigation.selector);
14189      base.$playButton = $parent.find(ops.playButtonSelector);
14190      base.togglePlayButtonAttributes('paused', 'playing');
14191
14192      base.$playButton.
14193      on('click ', base, base.togglePlayButtonState).
14194      on('focusin focusout', (e) => e.stopPropagation());
14195      $parent.find('button').not(ops.playButtonSelector).
14196      on('focus', base, base.togglePlayButtonState);
14197
14198      base.$playButton.parent().removeAttr('hidden');
14199    } else {
14200      let $parent = base.$el.find(base.options.navigation.selector);
14201      base.$playButton = $parent.find(ops.playButtonSelector);
14202      base.$playButton.remove();
14203    }
14204  },
14205
14206  togglePlayButtonState: function (ev) {
14207    const base = ev.data;
14208    const $playButton = base.$playButton;
14209    const state = $playButton.is('.playbutton-playing') || ev.type === 'focus' ? 'playing' : 'paused';
14210    const targetState = state === 'playing' ? 'paused' : 'playing';
14211    const $pagination = base.$el.find(base.options.pagination.selector);
14212
14213    base.togglePlayButtonAttributes(state, targetState);
14214    base.$el.slick(targetState === 'playing' ? 'slickPlay' : 'slickPause');
14215    $pagination.attr('aria-live', !base.slick.paused ? 'off' : null);
14216  },
14217
14218  togglePlayButtonAttributes: function (state, targetState) {
14219    const base = this;
14220    const ops = base.options.navigation.autoplay;
14221    const $playButton = base.$playButton;
14222
14223    $playButton.
14224    removeClass('playbutton-' + state).
14225    addClass('playbutton-' + targetState).
14226    attr('aria-label', ops[targetState].title).
14227    attr('title', ops[targetState].title);
14228    $playButton.find('img').
14229    attr('src', ops[targetState].symbol).
14230    attr('alt', ops[targetState].title);
14231  },
14232
14233  /**
14234   * Setzt den Tabindex von antabbaren Elementen auf nicht sichtbaren Slides auf -1, damit diese nicht angetabbt werden können.
14235   * @param slick das Slick-Objekt
14236   */
14237  updateTabindex: function (slick) {
14238    const base = this;
14239    //Barrierefreiheit/Tabbing workaround
14240    const focusableItems = base.options.selectors.focusable;
14241    const buggedItems = base.options.selectors.bugged;
14242    if (!slick.unslicked) {
14243      slick.$slides.not('.slick-active').find(focusableItems).attr('tabindex', -1).end().find(buggedItems).hide();
14244      slick.$slides.filter('.slick-active').find(focusableItems).attr('tabindex', 0).end().find(buggedItems).show();
14245    }
14246  },
14247
14248
14249  /**
14250   * Initialisiert die Paginierung
14251   * @param slick das Slick-Objekt
14252   */
14253  updatePagination: function (slick, currentSlide) {
14254    const base = this;
14255    if (base.$el.find(base.options.pagination.selector)) {
14256      const $pagination = base.$el.find(base.options.pagination.selector);
14257
14258      $pagination.
14259      attr('role', 'status').
14260      attr('aria-atomic', true).
14261      attr('aria-live', !base.slick.paused ? 'off' : null);
14262
14263      $pagination.empty();
14264      const currentPage = (Math.floor(currentSlide / slick.options.slidesToScroll) + 1).toLocaleStr
14264ing(base.options.pagination.toLocaleStringLanguage, base.options.pagination.toLocaleStringOptions);
14265      const lastPage = (Math.ceil(slick.$slides.length / slick.options.slidesToScroll) - (slick.options.slidesToShow - slick.options.slidesToScroll)).toLocaleString(base.options.pagination.toLocaleStringLanguage, base.options.pagination.toLocaleStringOptions);
14266      if ($pagination.attr('data-wrapper-index')) {
14267        $pagination.append($($pagination.attr('data-wrapper-index')).html(currentPage));
14268      } else {
14269        $pagination.append(' ' + currentPage + ' ');
14270      }
14271      $pagination.append($($pagination.attr('data-separator')));
14272      if ($pagination.attr('data-wrapper-index')) {
14273        $pagination.append($($pagination.attr('data-wrapper-total')).html(lastPage));
14274      } else {
14275        $pagination.append(' ' + lastPage + ' ');
14276      }
14277    }
14278  },
14279
14280  /**
14281   * Setzt bzw. entfernt disabled und aria-disabled an die Arrows.
14282   * @param $arrow Selektor des Arrows
14283   */
14284  updateNavigationArrow: function ($arrow) {
14285    if ($arrow) {
14286      var $arrowButton = $arrow.is('button') ? $arrow : $arrow.find('button');
14287      if ($arrow.hasClass('slick-disabled')) {
14288        $arrowButton.prop('disabled', true);
14289      } else {
14290        $arrowButton.removeAttr('disabled');
14291      }
14292      $arrow.removeAttr('aria-disabled'); // wird von Slick automatisch gesetzt, aber für uns nicht notwendig, also wird es wieder entfernt um den DOM möglichst sauber zu halten
14293    }
14294  },
14295
14296  /**
14297   * Workaround für slider die mit einem anderen Slider durch 'asNavFor' kombiniert werden, und mit slidesToShow > 1 konfiguriert sind
14298   */
14299  updateNavigationArrowBySlideCount: function ($arrow, setDisabledPredicate) {
14300    if ($arrow) {
14301      const $arrowButton = $arrow.is('button') ? $arrow : $arrow.find('button');
14302      if (setDisabledPredicate) {
14303        $arrowButton.prop('disabled', true);
14304      } else {
14305        $arrowButton.removeAttr('disabled').removeClass('slick-disabled');
14306      }
14307      $arrow.removeAttr('aria-disabled');
14308    }
14309  },
14310
14311  /**
14312   * Führt Manipulationen an den HTML-Attributen der Navigation durch, die für die Barrierefreiheit relevant sind.
14313   * @param slick das Slick-Objekt
14314   */
14315  updateNavigation: function (slick) {
14316    const base = this;
14317    if (base.options.isNavigationSlideshow) {
14318      base.updateNavigationArrowBySlideCount(slick.$prevArrow, slick.currentSlide === 0);
14319      base.updateNavigationArrowBySlideCount(slick.$nextArrow, slick.currentSlide + 1 === slick.slideCount);
14320    } else {
14321      base.updateNavigationArrow(slick.$prevArrow);
14322      base.updateNavigationArrow(slick.$nextArrow);
14323    }
14324
14325  },
14326
14327  /**
14328   * Fügt dem Wrapper Klassen hinzu, wenn sich die Slideshow am Anfang oder am Ende befindet.
14329   * @param slick das Slick-Objekt, das Informationen über den Zustand des Karussells enthält
14330   * @param nextSlide gibt an, ob ein folgendes Slide existiert
14331   */
14332  updateSlideStatus: function (slick, nextSlide) {
14333    const base = this;
14334    const isAtStart = nextSlide === 0;
14335    if (isAtStart) {
14336      base.$el.closest(base.options.selectors.wrapper).find(base.options.selectors.removedContent).addClass(base.options.classes.isAtStart);
14337    } else {
14338      base.$el.closest(base.options.selectors.wrapper).find(base.options.selectors.removedContent).removeClass(base.options.classes.isAtStart);
14339    }
14340  },
14341
14342  /**
14343   * Initialisiert die Navigationspfeile. Diese dürfen erst nach einem etwaigen Austausch des HTML ermittelt werden,
14344   * da sie ggf. mit ersetzt werden. In diesem Fall würden ansonsten die nachgeladene Pfeile nicht initialisiert.
14345   * @param slickOptions die Optionen, die an Slick übergeben werden
14346   */
14347  handleNavigationArrows: function (slickOptions) {
14348    const base = this;
14349    var navigationArrowOptions = {
14350      nextArrow: base.$el.find(base.options.navigation.arrows.selectors.next),
14351      prevArrow: base.$el.find(base.options.navigation.arrows.selectors.prev)
14352    };
14353
14354    return $.extend(slickOptions, navigationArrowOptions);
14355  },
14356
14357  updateDotFocus: function () {
14358    const base = this;
14359    const dots = base.$el.find('.slick-dots'),
14360      activeDot = dots.find('.slick-active button'),
14361      focusedDot = dots.find('button').filter(document.activeElement);
14362    if (activeDot.length && focusedDot.length && !activeDot.is(focusedDot)) {
14363      activeDot[0].focus();
14364    }
14365  },
14366
14367  /**
14368   * Da die Navigation erst durch dieses Modul erstellt und in den DOM eingefügt wird, kann das jQuery-Element, welches der slick-Option
14369   * 'appendDots' übergeben wird, auch erst jetzt gefunden werden.
14370   * Also wird diese Option hier durch das jetzt auffindbare jQuery-Element überschrieben.
14371   * @param slickOptions die Optionen, die an Slick übergeben werden
14372   */
14373  handleNavigationDots: function (slickOptions) {
14374    const base = this;
14375    slickOptions.appendDots = base.$el.find(base.options.navigation.selector);
14376    return slickOptions;
14377  },
14378
14379  /**
14380   * non configurable fixes
14381   */
14382  accessible: function () {
14383    const base = this;
14384    base.accessibilityFix();
14385    base.cleanUpSlides();
14386    base.$el.trigger('afterAccessible.' + base.eventName, base);
14387
14388
14389  },
14390
14391  /**
14392   * Entfernt den tabindex der Slides.
14393   */
14394  removeTabIndexFromSlides: function () {
14395    const base = this;
14396    base.$el.find('.slick-slide[tabindex]').each(function (index, element) {
14397      $(element).removeAttr('tabindex');
14398    });
14399  },
14400
14401  backupAttributes: function () {
14402    const base = this;
14403    base.$el.find('[role]').addBack().not('[data-role-persistent]') // role auch für base.$el speichern
14404    .each(function (index, element) {
14405      let role = $(element).attr('role') || '';
14406      $(element).attr('data-role-persistent', role.trim() || null);
14407    });
14408    base.$el.find('[tabindex]').not('[data-tabindex-persistent]').
14409    each(function (index, element) {
14410      let tabindex = $(element).attr('tabindex') || '';
14411      $(element).attr('data-tabindex-persistent', tabindex.trim() || null);
14412    });
14413    base.$el.find('[aria-live]').not('[data-aria-live-persistent]').
14414    each(function (index, element) {
14415      let live = $(element).attr('aria-live') || '';
14416      $(element).attr('data-aria-live-persistent', live.trim() || null);
14417    });
14418  },
14419
14420  restoreAttributes: function () {
14421    const base = this;
14422    base.$el.find('[data-role-persistent]').addBack() // role auch für base.$el wiederherstellen
14423    .each(function (index, element) {
14424      $(element).attr('role', $(element).attr('data-role-persistent') || null);
14425    });
14426    base.$el.find('[data-tabindex-persistent]').
14427    each(function (index, element) {
14428      $(element).attr('tabindex', $(element).attr('data-tabindex-persistent') || null);
14429    });
14430    base.$el.find('[data-aria-live-persistent]').
14431    each(function (index, element) {
14432      $(element).attr('aria-live', $(element).attr('data-aria-live-persistent') || null);
14433    });
14434  },
14435
14436  removeAriaSelectedFromDots: function () {
14437    const base = this;
14438    const slickDotsButtons = base.$el.find('.slick-dots').find('button');
14439    slickDotsButtons.removeAttr('aria-selected');
14440  },
14441
14442  /**
14443   * Platziert die Navigation über der .slick-list im DOM.
14444   */
14445  accessibilityFix: function () {
14446    const base = this;
14447    const slickDotsButtons = base.$el.find('.slick-dots').find('button');
14448    const focusedDot = slickDotsButtons.filter(':focus');
14449    const activeDot = slickDotsButtons.filter('.slick-active *');
14450
14451    if (focusedDot.length) {
14452      if (!focusedDot.is(activeDot)) {
14453        activeDot.trigger('focus');
14454      }
14455    }
14456    base.fixNavigationDOMPlacement();
14457    base.updateAriaRoles();
14458  },
14459
14460  /**
14461   * Ergänzt am Wrapper-Element die Role list und an den Slides die Role listitem bzw. Role group
14462   */
14463  updateAriaRoles: function () {
14464    const base = this;
14465
14466    const numOfChildren = base.$el.find('.slick-slide').length || base.$el.children().not(base.options.navigation.selector).length;
14467    if (!base.slick.unslicked && base.slick.options.slidesToShow < numOfChildren) {
14468      base.$el.attr('role', 'group');
14469      base.$el.attr('aria-live', base.$el.attr('data-aria-live-persistent') || "polite");
14470    } else {
14471      base.$el.attr('role', base.$el.attr('data-role-persistent') || null);
14472    }
14473
14474    if (base.options.ariaRole === 'list') {
14475      if (base.slick.$slides.length > 1 && base.slick.options.slidesToScroll > 1) {
14476        base.slick.$slideTrack.attr('role', 'list');
14477        base.$el.find(base.options.slickOptions.slide).not('.js-slide-placeholder').attr('role', 'listitem');
14478      } else {
14479        base.slick.$slideTrack.removeAttr('role');
14480        base.$el.find(base.options.slickOptions.slide).not('.js-slide-placeholder').removeAttr('role');
14481      }
14482    }
14483    base.$el.find('.js-slide-placeholder').attr('aria-hidden', 'true');
14484  },
14485
14486  /**
14487   * Platziert das Navigationelement als erstes Kind des base.$el,
14488   * damit die semantische Reihenfolge von Navigation und .slick-list BITV-konform ist.
14489   */
14490  fixNavigationDOMPlacement: function () {
14491    const base = this;
14492    let $navigation = base.$el.find(base.options.navigation.selector);
14493    if ($navigation.length === 0) {
14494      $navigation = base.$el.siblings(base.options.navigation.selector);
14495    }
14496    if ($navigation.index()) {
14497      // Navigation muss erstes Kind der Slideshow sein
14498      $navigation.parent().prepend($navigation);
14499    }
14500  },
14501
14502  /**
14503   * Säubert die Slides von Anpassungen, falls der Slider 'unslicked' wird.
14504   * Slick fügt den Slides einige Attribute hinzu, im Falle von 'unslick' entfernt Slick diese nicht wieder.
14505   */
14506  cleanUpSlides: function () {
14507    const base = this,
14508      slick = base.slick;
14509    if (slick.unslicked) {
14510      slick.$slides.
14511      removeAttr('style').
14512      removeAttr('aria-hidden');
14513      base.restoreAttributes();
14514    }
14515  },
14516
14517  onSlickInit: function (event, slick) {
14518    const base = event.data;
14519    base.patchSlickAccessibility(slick);
14520    base.showHideNavigation(slick);
14521    base.handleNavigationArrows(slick.options);
14522    base.updateNavigation(slick);
14523    if (base.options.initializeMultimedia) {
14524      base.initMultimedia();
14525    }
14526    base.handlePlayButton(slick);
14527    base.updatePagination(slick, 0);
14528    base.updateTabindex(slick);
14529    base.updateAriaRoles(slick);
14530    base.afterInit();
14531  },
14532
14533  onSlickBreakpoint: function (event, slick) {
14534    const base = event.data;
14535    base.showHideNavigation(slick);
14536    slick.$slider.slick('unslick');
14537    base.addPlaceholderSlidesIfNecessary();
14538    base.initSlick();
14539  },
14540
14541  onSlickBeforeChange: function (event, slick, currentSlide, nextSlide) {
14542    const base = event.data;
14543
14544    base.$el.attr('aria-busy', 'true');
14545
14546    //ohne diese Anweisung kann die Höhenberechnung fehlschlagen
14547    //die "falschen" Elemente werden in updateTabindex wieder verborgen
14548    slick.$slides.find(base.options.selectors.bugged).show();
14549
14550    if (base.options.setStartClass) {
14551      base.updateSlideStatus(slick, nextSlide);
14552    }
14553  },
14554
14555  onSlickAfterChange: function (event, slick, currentSlide) {
14556    const base = event.data;
14557    base.updatePagination(slick, currentSlide);
14558    base.updateNavigation(slick);
14559    base.updateTabindex(slick);
14560    base.updateAriaRoles(slick);
14561    base.updateDotFocus();
14562
14563    base.$el.attr('aria-busy', 'false');
14564  },
14565
14566  onSlickDestroy: function (event, slick) {
14567    const base = event.data;
14568    if (!base.unslickBreakpoint) {
14569      // this will only work correctly with just 1 breakpoint that has settings: 'unslick' in the init
14570      base.unslickBreakpoint = slick.breakpointSettings.findIndex((breakpoint) => breakpoint === 'unslick');
14571      base.mobileFirst = slick.options.mobileFirst;
14572    }
14573    $(window).off('resize' + base.reInitEventNamespace, base.onSlickDestroyWindowResize).on('resize' + base.reInitEventNamespace, base, base.onSlickDestroyWindowResize);
14574  },
14575
14576  onSlickDestroyWindowResize: function (event) {
14577    const base = event.data;
14578    if (base.mobileFirst) {
14579      if ($(window).width() <= base.unslickBreakpoint && !base.$el.hasClass('slick-initialized')) {
14580        base.slick = base.$el.slick(base.options.slickOptions).slick('getSlick');
14581        $(window).off('resize' + base.reInitEventNamespace, base.onSlickDestroyWindowResize);
14582      }
14583    } else {
14584      if ($(window).width() > base.unslickBreakpoint && !base.$el.hasClass('slick-initialized')) {
14585        base.slick = base.$el.slick(base.options.slickOptions).slick('getSlick');
14586        $(window).off('resize' + base.reInitEventNamespace, base.onSlickDestroyWindowResize);
14587      }
14588    }
14589  },
14590
14591  /**
14592   * Die Standard-Optionen für das Plugin
14593   */
14594  defaultOptions: {
14595    pagination: {
14596      selector: '.js-slideshow-pagination',
14597      toLocaleStringLanguage: $('html').attr('lang'),
14598      toLocaleStringOptions: {} // https://www.w3schools.com/jsref/jsref_tolocalestring_number.asp
14599    },
14600    navigation: {
14601      selector: '.js-slideshow-navigation', // der Selector für die Navigation
14602      setStartClass: false,
14603      arrows: {
14604        selectors: {
14605          next: '.js-slideshow-navigation-next', // der Selector für den 'Weiter' Pfeil, muss den Klassen im XHR der Navigation entsprechen
14606          prev: '.js-slideshow-navigation-prev' // der Selector für den 'Zurück' Pfeil, muss den Klassen im XHR der Navigation entsprechen
14607        }
14608      },
14609      autoplay: {
14610        createPlayButton: true,
14611        playButtonSelector: '.js-slideshow-navigation-play',
14612        playing: {
14613          title: typeof PAUSE !== 'undefined' ? PAUSE : 'Animation stoppen',
14614          symbol: typeof PAUSEIMG !== 'undefined' ? PAUSEIMG : '/assets/icons/isb/close.svg'
14615        },
14616        paused: {
14617          title: typeof PLAY !== 'undefined' ? PLAY : 'Animation starten',
14618          symbol: typeof PLAYIMG !== 'undefined' ? PLAYIMG : '/assets/icons/isb/play.svg'
14619        }
14620      }
14621    },
14622    selectors: {
14623      wrapper: '.js-stage-slider', // Ein Ancestor von base.$el, in dem Element .removedContent gefunden werden kann
14624      removedContent: '.js-stage_slider-headline', // Element, das die Klasse isAtStart bekommt, wenn sich die Slideshow an Anfang befindet.
14625      focusable: 'a, [tabindex], textarea, input, select, button, video, object',
14626      bugged: 'video:not(.consent-required video), object' // Vermutung: Sind trotz tabindex === -1 fokussierbar
14627    },
14628    classes: {
14629      initialized: 'js-slideshow-initialized', // Nötig insb. dann, wenn Slick nicht aufgerufen wird, weil !hasEnoughSlides() gilt
14630      isAtStart: 'is-shown' // Die Klasse, die dem Element removedContent hinzugefügt wird, wenn sich die Slideshow an Anfang befindet.
14631    },
14632    slickOptions: {
14633      // https://github.com/kenwheeler/slick#settings verfügbare Optionen und Defaults
14634      // appendDots: wird von diesem Modul überschrieben und kann nicht durch die init.js gesetzt werden
14635      // nextArrow: wird von diesem Modul überschrieben durch options.arrowNavigation.selectors.next und kann nicht durch die init.js gesetzt werden
14636      // prevArrow: wird von diesem Modul überschrieben durch options.arrowNavigation.selectors.next und kann nicht durch die init.js gesetzt werden
14637      slide: ':not(.js-slideshow-navigation)', // Da der Navigationcontainer bei der Initialisierung von slick ein Sibling der Slides ist, muss dieser hier explizit ausgenommen werden
14638      infinite: false
14639    },
14640
14641    multimediaOptions: {}, // Optionen für die initialisierung von cms_multimedia, falls es videos in der slideshow gibt (ungetestet),
14642    initIfNotEnoughSlides: true,
14643    initializeMultimedia: true,
14644    isNavigationSlideshow: false, // Gibt an, ob es sich um eine Thumbnail-Slideshow handelt, die mit asNavFor verknüpft ist (Sonderbehandlung beim Aktivieren/Deaktivieren von Navigation-Arrows und Höhenberechnung)
14645    ariaRole: '',
14646
14647    tablistAriaLabel: typeof SHOW_PAGE !== 'undefined' ? SHOW_PAGE : 'Seite anzeigen'
14648  }
14649});
14650
14651    /* Ende cms_slideshow_numbers */
14652    /* Start cms_toggle */
14653        /*! --GSBDocStart
14654 * @name: @cms/cms_toggle
14655 * @version: 6.0.0
14656 * @description: [//]: # (Diesen und folgende Kommentare auf keinen Fall löschen!) [//]: # (Nur so akzeptiert license-checker die Lizenz) [//]: # (SEE LICENSE IN LICENSE-INTERNAL.txt) [//]: # (https://license-internal.txt)
14657 * --CMSDocEnd
14658*/"use strict";
14659cms.makeCMSModule('cms.toggle', {
14660
14661  init: function () {
14662    const base = this;
14663
14664    base.validateOptions();
14665    base.activeMode = base.options.mode;
14666
14667    if (base.options.richtext) {
14668      base.addRichtextContainer();
14669    } else {
14670      if (base.$el.data('href')) {
14671        $.get(base.$el.data('href'), function (data) {
14672          base.$el.html(data);
14673          base.onMarkupComplete();
14674        });
14675      } else {
14676        base.onMarkupComplete();
14677      }
14678    }
14679  },
14680
14681  validateOptions: function () {
14682    const base = this,
14683      breakpointOptions = base.options.responsive || [];
14684
14685    [base.options].concat(breakpointOptions).forEach((options) => {
14686      if ('accordion' in options) {
14687        throw new Error(
14688          "Die Option 'accordion' ist obsolet." +
14689          " Stattdessen muss die Option 'mode' mit Wert 'accordion' gesetzt werden." +
14690          " Diese Option ist auch in Breakpoints erlaubt."
14691        );
14692      }
14693      if ('tab' in options) {
14694        throw new Error(
14695          "Die Option 'tab' ist obsolet." +
14696          " Stattdessen muss die Option 'mode' mit Wert 'tabs' gesetzt werden." +
14697          " Diese Option ist auch in Breakpoints erlaubt."
14698        );
14699      }
14700    });
14701  },
14702
14703  findAllUsedModes: function () {
14704    const base = this,
14705      modes = {},
14706      breakpointOptions = base.options.responsive || [];
14707
14708    [base.options].concat(breakpointOptions).forEach((options) => {
14709      if (options.mode) {
14710        modes[options.mode] = true;
14711      }
14712    });
14713
14714    return Object.keys(modes);
14715  },
14716
14717  /**
14718   * @method onMarkupComplete
14719   * @desc Initialisierung des Scripts
14720   */
14721  onMarkupComplete: function () {
14722    const base = this;
14723
14724    if (!base.$el.hasClass('cms-toggle')) {
14725      if (base.activeMode !== 'none') {
14726        base.reinitToggle();
14727      }
14728
14729      base.$el.cms_responsiveListener(base);
14730    }
14731  },
14732
14733  reinitToggle: function () {
14734    const base = this;
14735
14736    if (!base.$el.hasClass('cms-toggle')) {
14737      base.$el.addClass('cms-toggle');
14738      base.addClasses();
14739      base.addClickfunction();
14740      base.makeAccessible();
14741      base.accKeyboardCtrl();
14742
14743      if (base.options.hashControlled) {
14744        base.addHashHandler();
14745      }
14746    }
14747  },
14748
14749  switchAccordingToMode: function () {
14750    const base = this;
14751
14752    base.$el.attr('data-togglemode', base.options.mode);
14753
14754    if (base.activeMode === 'none' && base.options.mode !== 'none') {
14755      base.reinitToggle();
14756    }
14757    base.activeMode = base.options.mode;
14758
14759    if (base.options.autoplay && !base.autoplayInitialized) {
14760      base.autoplay();
14761    }
14762
14763    if (base.options.autoplay) {
14764      base.autoplayStart();
14765    } else {
14766      base.autoplayStop();
14767    }
14768
14769    if (base.options.mode === 'accordion') {
14770      base.switchToAccordion();
14771    } else if (base.options.mode === 'tabs') {
14772      base.switchToTabs();
14773    } else if (base.options.mode === 'none') {
14774      base.switchToNone();
14775    }
14776  },
14777
14778
14779
14780  /**
14781   * @method addClasses
14782   * @desc Zugehörigkeit der Überschriften festlegen
14783   */
14784  addClasses: function () {
14785    var base = this;
14786
14787    let tabControls = base.$el.find(base.options.tabControls);
14788    if (tabControls.length) {
14789      let activeTabControl = tabControls.filter('.active-control');
14790      let activeTabIndex = $.inArray(activeTabControl[0], tabControls);
14791      if (activeTabIndex === -1) {
14792        activeTabIndex = 0;
14793      }
14794      tabControls.each(function (index) {
14795        $(this).addClass(base.options.switchPanelClass + index);
14796
14797        if (index === activeTabIndex) {
14798          $(this).addClass('active-control');
14799        } else {
14800          $(this).addClass('inactive-control');
14801        }
14802      });
14803      base.$el.find(base.options.elements).each(function (index) {
14804        $(this).addClass(base.options.switchPanelClass + index);
14805
14806        if (index === activeTabIndex) {
14807          $(this).addClass(base.options.panelOpenedClass);
14808        } else {
14809          $(this).addClass(base.options.panelClosedClass);
14810        }
14811      });
14812    }
14813
14814    // Accordion hat bei start geöffnete Elemente
14815    var hasOpendElements = false;
14816
14817    if (base.$el.find(base.options.heading).filter('.active-control').length > 0) {
14818      hasOpendElements = true;
14819    }
14820
14821    base.$el.find(base.options.heading).each(function () {
14822      if (!$(this).is('button') || !$(this).is('a')) {
14823        if (base.options.accordionPanelHeight) {
14824          var height = 0;
14825          $(this).next().find('>').each(function () {
14826            height += $(this).outerHeight(true);
14827          });
14828          $(this).next().height(height);
14829        }
14830
14831        if (base.options.allOpen && base.options.mode === 'accordion') {//TODO: Genauer prüfen
14832          base.show($(this).next());
14833          $(this).addClass('active-control');
14834        } else if (hasOpendElements) {
14835          if (!$(this).hasClass('active-control')) {
14836            $(this).addClass('inactive-control');
14837            base.hide($(this).next());
14838          } else {
14839            base.show($(this).next());
14840          }
14841        } else {
14842          $(this).addClass('inactive-control');
14843          base.hide($(this).next());
14844        }
14845      }
14846
14847      base.changeAccordionHeadingTitle($(this));
14848    });
14849  },
14850
14851  /**
14852   * @method addClickfunction
14853   * @desc Click Events hinzufügen
14854   */
14855  addClickfunction: function () {
14856    var base = this; // Accordion
14857
14858    base.$el.on('click.cms_toggle keydown.cms_toggle', base.options.heading, function (e) {
14859      if (e.type === 'click' || e.which === 13) {
14860        e.preventDefault();
14861        e.stopPropagation();
14862        base.clickedElem = $(this);
14863        base.changeStateAccordion();
14864        base.clickedElem = null;
14865      }
14866    }).find(base.options.accordionElementsStopPropagation).on('click.cms_toggle keydown.cms_toggle', function (e) {
14867      e.stopPropagation();
14868    });
14869
14870    base.$el.on('activateTab.cms_toggle', base.options.tabControls, function () {
14871      base.clickedElem = $(this);
14872      base.changeStateTab();
14873      $(this).focus();
14874    }); // Autoplay muss deaktiviert sein, da die Events focusin und focu
14874sout im Firefox derzeit nocht nicht implementiert
14875    // sind bzw. noch bugs enthalten
14876
14877    if (base.options.changeOnHover && !base.options.autoplay) {
14878      base.$el.on('mouseenter.cms_toggle touchend.cms_toggle', base.options.tabControls, function () {
14879        $(this).trigger('activateTab');
14880      }).on('click.cms_toggle', base.options.tabControls, function (e) {
14881        e.preventDefault();
14882        e.stopPropagation();
14883      });
14884    } else {
14885      base.$el.on('click.cms_toggle', base.options.tabControls, function (ev) {
14886        ev.preventDefault();
14887        ev.stopPropagation();
14888        $(this).trigger('activateTab');
14889      }).on('focusin.cms_toggle', base.options.tabControls, function (ev, stop) {
14890        if (ev.relatedTarget && !base.$el.find(ev.relatedTarget).length) {
14891          ev.stopPropagation();
14892          $(this).trigger('activateTab');
14893        }
14894      });
14895    }
14896  },
14897
14898  addHashHandler: function () {
14899    var base = this,
14900      initialHash = location.hash || '#',
14901      hashedElemIndex;
14902
14903    if (history.scrollRestoration) {
14904      history.scrollRestoration = 'manual';
14905    }
14906
14907    base.initialTabControl = base.$el.find(base.options.tabControls).filter('.active-control');
14908    if (!base.initialTabControl.length) {
14909      base.initialTabControl = base.initialTabControl.end().first();
14910    }
14911    base.initialAccordionHeadings = base.$el.find(base.options.heading).filter('.active-control');
14912
14913    if (initialHash !== '#') {
14914      hashedElemIndex = base.contentPanels.index(base.contentPanels.filter(initialHash));
14915      if (hashedElemIndex !== -1) {
14916        base.initialTabControl = base.tabs.eq(hashedElemIndex);
14917        base.initialAccordionHeadings = base.headings.eq(hashedElemIndex);
14918      }
14919    }
14920
14921    base.initialStatus = base.initialAccordionHeadings.length ? 'initiallyOpen' : 'closed';
14922    base.initialHash = initialHash;
14923    base.lastHash = base.initialHash;
14924    base.lastStatus = base.initialStatus;
14925    base.initialState = $.extend({}, history.state, {
14926      status: base.initialStatus,
14927      hash: base.initialHash
14928    });
14929    history.replaceState(base.initialState, document.title);
14930    $(window).on('cms-hash-push.cms_toggle', function (ev, who, hash, status) {
14931      if (base !== who && (base.lastStatus !== status || base.lastHash !== hash)) {
14932        base.onPopState(status);
14933        base.lastStatus = status;
14934        base.lastHash = hash;
14935      }
14936    }).on('popstate.cms_toggle', function (ev) {
14937      var state = history.state,
14938        status = state && state.status,
14939        hash = location.hash,
14940        hashIsValidSelector = hash && hash !== '#',
14941        contentElement;
14942      base.clickedElem = null;
14943
14944      if (hashIsValidSelector) {
14945        contentElement = base.contentPanels.filter(hash);
14946        if (contentElement.length) {
14947          base.show(contentElement);
14948        }
14949        if (status === 'closed' || status === 'opened' || status === 'initiallyOpen') {
14950          status = state.status;
14951          base.onPopState(status);
14952          base.lastStatus = status;
14953          base.lastHash = hash || '#';
14954        }
14955      }
14956    }).on('hashchange.cms_toggle', function (ev) {
14957      var url = ev.originalEvent && ev.originalEvent.newURL || '',
14958        hash = '#' + (url.split('#')[1] || '');
14959
14960      if (hash !== base.lastHash) {
14961        let contentElement = base.contentPanels.filter(hash);
14962        if (contentElement.length) {
14963          if (hash !== '#' && contentElement.is('[hidden]')) {
14964            base.changeStateHash(hash, 'opened', true);
14965            base.onPopState('opened');
14966            base.lastHash = hash;
14967          } else if (base.options.mode === 'tabs' || base.options.accordionCloseOther) {
14968            base.changeStateHash(base.lastHash, 'closed', true);
14969            base.onPopState('closed');
14970            base.lastHash = hash;
14971          }
14972        }
14973      }
14974    });
14975  },
14976
14977  getHeadingFromHash: function (hash) {
14978    var base = this,
14979      hashIsValidSelector = hash && hash !== '#',
14980      contentElement = hashIsValidSelector ? base.contentPanels.filter(hash) : $(),
14981      index = contentElement.prop('cms_aria_index');
14982    return index > -1 ? base.headings.eq(index) : $();
14983  },
14984
14985  getTabFromHash: function (hash) {
14986    var base = this,
14987      hashIsValidSelector = hash && hash !== '#',
14988      contentElement = hashIsValidSelector ? base.contentPanels.filter(hash) : $(),
14989      index = contentElement.prop('cms_aria_index');
14990    return index > -1 ? base.tabs.eq(index) : $();
14991  },
14992
14993  getHashFromLink: function (link) {
14994    var id = String(link.attr('href')).split('#')[1] || '';
14995    return '#' + id;
14996  },
14997
14998  scrollToElement: function ($elementToScrollTo) {
14999    const base = this;
15000    const $html = $('html');
15001    let offset = 0;
15002
15003    const scrollOffset = base.options.scrolling.scrollOffset;
15004
15005    if (typeof scrollOffset === 'number') {
15006      offset = scrollOffset || 0;
15007    } else if (typeof scrollOffset === 'function') {
15008      offset = scrollOffset.call(base, $elementToScrollTo) || 0;
15009    }
15010
15011    if ($elementToScrollTo.length > 0) {
15012      $html.css('scroll-behavior', 'auto'); // jquery animiertes Scrollen funktioniert nicht korrekt mit scroll-behavior: 'smooth'
15013      let overlaysHeight = base.getOverlaysHeight() + offset;
15014
15015      $html.clearQueue().stop().animate({
15016        scrollTop: $elementToScrollTo.offset().top - overlaysHeight
15017      }, base.options.scrolling.scrollAnimationDuration, 'linear',
15018
15019      function () {//erster Callback nach erster Scroll Animation
15020        // ensure that the last scroll event (used by e.g. cms_shrinkheader) from the previous scrolling animation has been fired and the overlaysHeight has been properly updated
15021        requestAnimationFrame(function () {
15022          overlaysHeight = base.getOverlaysHeight() + offset;
15023          $html.clearQueue().stop().animate({
15024            // Rescroll um Overlay Änderungen abzufangen
15025            scrollTop: $elementToScrollTo.offset().top - overlaysHeight
15026          }, base.options.scrolling.scrollAnimationDuration / 2, 'linear', function () {
15027            requestAnimationFrame(function () {// zweiter Callback nach zweiter Scroll Animation
15028              $html.css('scroll-behavior', ''); // Scroll Verhalten Manipulation entfernen
15029              if (!$elementToScrollTo.is($(base.options.tabbables))) {
15030                $elementToScrollTo.attr('tabindex', -1); // tabindex="-1" hinzufügen um das Element per Javascript fokussierbar zu machen, falls es nicht bereits einen tabindex hat
15031              }
15032              $elementToScrollTo[0].focus({ preventScroll: true }); // nicht per Browser scrollen, da wir bereits mit JavaScript an die korrekte Stelle gescrollt haben
15033            });
15034          });
15035        });
15036      });
15037    }
15038  },
15039
15040  getOverlaysHeight: function () {
15041    const base = this;
15042    let height = 0;
15043    $(base.options.scrolling.scrollOverlaySelector).each(function (index, element) {
15044      height = height + $(element).outerHeight();
15045    });
15046    return height;
15047  },
15048
15049
15050  onPopState: function (status) {
15051    var base = this,
15052      clickedElem = base.clickedElem || $(),
15053      hash,
15054      prevStatus;
15055    hash = history.state.hash;
15056    prevStatus = history.state.status;
15057    base.popStateTriggered = true;
15058
15059    if (base.options.mode === 'tabs') {
15060      if (status === 'opened' && hash !== '#') {
15061        clickedElem = base.getTabFromHash(hash);
15062      } else if (status === 'initiallyOpen' || hash === '#') {
15063        clickedElem = base.initialTabControl;
15064      }
15065      /* else {
15066      //do nothing if status === "closed" && hash !== "#"
15067      }*/
15068
15069
15070      if (clickedElem.length) {
15071        base.clickedElem = clickedElem;
15072        base.changeStateTab(Boolean(base.$el.find(document.activeElement).length));
15073      }
15074    } else if (base.options.mode === 'accordion') {
15075      if (status === 'initiallyOpen') {
15076        //only possible on first load
15077        //TODO: Open ALL initial headings, not just the first
15078        clickedElem = base.initialAccordionHeadings;
15079      } else if (status === 'opened') {
15080        if (prevStatus !== 'initiallyOpen' || !base.hasActiveTab(hash)) {
15081          clickedElem = base.getHeadingFromHash(hash);
15082        }
15083      }
15084
15085      if (clickedElem.length) {
15086        base.clickedElem = clickedElem;
15087        base.changeStateAccordion('opened');
15088        if (!base.options.scrolling.scrollToControlElementAfterOpen && base.options.hashControlled) {
15089          // scroll per JS when hashControlled when it is not automatically scrolling after opening
15090          setTimeout(function () {
15091            // wait for other accordions to properly close first, if accordionCloseOther is true
15092            base.scrollToElement(clickedElem.is('button, a') ? clickedElem : clickedElem.find(base.buttons));
15093          }, base.options.accordionCloseOther ? base.options.accordionAnimationDuration : 0);
15094        }
15095      }
15096    }
15097
15098    base.popStateTriggered = false;
15099  },
15100
15101  changeStateHash: function (newHash, status, replace) {
15102    var base = this,
15103      hash = location.hash || '#',
15104      hashLess = location.href.split('#')[0],
15105      newStatus,
15106      globalState;
15107    // backwards compatibility; not strictly necessary as outside code isn't supposed to call this
15108    if (typeof newHash !== 'string' && $(newHash).is('[href]')) {
15109      base.changeStateHash(base.getHashFromLink(newHash), ...[].slice.call(arguments, 1));
15110      return;
15111    }
15112
15113    globalState = $.extend({}, history.state);
15114    globalState.hash = newHash;
15115    globalState.status = status;
15116
15117    if (!base.popStateTriggered && !replace) {
15118      if (base.options.mode === 'tabs') {
15119        if (hash !== newHash) {
15120          history.pushState(globalState, document.title, hashLess + newHash);
15121          $(window).trigger('cms-hash-push', [base, newHash, status]);
15122          base.lastHash = newHash;
15123          base.lastStatus = status;
15124        }
15125      } else if (base.options.mode === 'accordion') {
15126        if (status === 'closed') {
15127          history.pushState(globalState, document.title, hashLess + '#');
15128          $(window).trigger('cms-hash-push', [base, '#', status]);
15129          base.lastHash = '#';
15130          base.lastStatus = status;
15131        } else {
15132          history.pushState(globalState, document.title, hashLess + newHash);
15133          $(window).trigger('cms-hash-push', [base, newHash, status]);
15134          base.lastHash = newHash;
15135          base.lastStatus = status;
15136        }
15137      }
15138    } else if (replace) {
15139      history.replaceState(globalState, document.title);
15140    }
15141  },
15142
15143  hasActiveTab: function (hash) {
15144    var base = this,
15145      tab = base.getTabFromHash(hash);
15146    return Boolean(tab.filter('.active-control').length);
15147  },
15148
15149  /**
15150   * @method changeStateAccordion
15151   * @param {Object} elem - Geklicktes Element
15152   * @desc Passt den title des headingElements je Status an (geöffnet/geschlossen)
15153   */
15154  changeAccordionHeadingTitle: function (elem) {
15155    var base = this;
15156
15157    if (elem.hasClass('active-control') && base.options.accordionHeadingTitleOpened) {
15158      elem.attr('title', base.options.accordionHeadingTitleOpened);
15159    } else if (!elem.hasClass('active-control') && base.options.accordionHeadingTitleClosed) {
15160      elem.attr('title', base.options.accordionHeadingTitleClosed);
15161    }
15162  },
15163
15164  /**
15165   * @method changeStateAccordion
15166   * @desc Open-/Close-States Accordion
15167   */
15168  changeStateAccordion: function (targetStatus) {
15169    var base = this,
15170      contentElement,
15171      button,
15172      singleOpen,
15173      status;
15174
15175    if (base.options.accordionElementToOpen) {
15176      contentElement = $(base.options.accordionElementToOpen);
15177    } else {
15178      contentElement = base.clickedElem.next();
15179    }
15180
15181    button = base.buttons.eq(contentElement.prop('cms_aria_index'))[0];
15182    singleOpen = !base.options.accordionCloseOther;
15183
15184    if (base.clickedElem.hasClass('inactive-control') || targetStatus === 'opened') {
15185      if (base.options.accordionCloseOther && !base.options.accordionElementToOpen) {
15186        var activeControl = base.$el.find(base.options.heading).not(base.clickedElem).filter('.active-control');
15187        base.animationAccordion(activeControl.next(), 'close', function () {
15188          if (base.options.scrolling.scrollToControlElementAfterOpen) {
15189            base.scrollToElement($(button));
15190          }
15191        });
15192        activeControl.removeClass('active-control').addClass('inactive-control');
15193      }
15194      if (base.clickedElem.hasClass('inactive-control')) {
15195        base.clickedElem.removeClass('inactive-control').addClass('active-control');
15196        base.animationAccordion(contentElement, 'open', function () {
15197          base.aria.updateAria(button, true, singleOpen);
15198        });
15199      }
15200      if (!base.options.accordionCloseOther && !base.options.accordionElementToOpen) {
15201        if (base.options.scrolling.scrollToControlElementAfterOpen) {
15202          base.scrollToElement($(button));
15203        }
15204      }
15205
15206      status = 'opened';
15207    } else if (!base.options.accordionCloseOther || !base.options.accordionNoClose || targetStatus === 'closed') {
15208      base.clickedElem.removeClass('active-control').addClass('inactive-control');
15209      base.animationAccordion(contentElement, 'close', function () {
15210        base.aria.updateAria(button, false, singleOpen);
15211      });
15212      status = 'closed';
15213    }
15214
15215    if (base.options.hashControlled) {
15216      if (contentElement.attr('id')) {
15217        base.changeStateHash('#' + contentElement.attr('id'), status, false);
15218      } else {
15219        console.error(base.module, 'contentElement', contentElement, 'without id inside a hash-controlled Accordion');
15220      }
15221    }
15222
15223    base.changeAccordionHeadingTitle(base.clickedElem);
15224
15225  },
15226
15227  /**
15228   * @method changeStateTab
15229   * @desc Open-/Close-States Tab
15230   */
15231  changeStateTab: function (hasFocus) {
15232    var base = this,
15233      panelToOpen = base.$el.find(base.options.tabContainer).find('.' + base.getSwitchPanelClass(base.clickedElem)),
15234      panelToClose;
15235
15236    if (base.clickedElem.hasClass('inactive-control')) {
15237      panelToClose = base.$el.find('.' + base.options.panelOpenedClass);
15238      base.aria.updateAria(base.clickedElem[0], true, false);
15239      panelToClose.removeClass(base.options.panelOpenedClass).addClass(base.options.panelClosedClass);
15240      base.$el.find(base.options.tabControls).filter('.active-control').removeClass('active-control').addClass('inactive-control');
15241      panelToOpen.removeClass(base.options.panelClosedClass).addClass(base.options.panelOpenedClass);
15242      base.clickedElem.removeClass('inactive-control').addClass('active-control');
15243      base.animationTab(panelToClose, panelToOpen);
15244      if (base.options.hashControlled) {
15245        base.changeStateHash('#' + panelToOpen.attr('id'), 'opened');
15246      }
15247    }
15248
15249    if (hasFocus) {
15250      base.clickedElem.focus();
15251    }
15252  },
15253
15254  show: function ($elements) {
15255    var base = this,
15256      customShow = base.options.show;
15257
15258    if (typeof customShow !== 'function') {
15259      $elements.show();
15260    } else {
15261      $elements.toArray().forEach(customShow);
15262    }
15263  },
15264
15265  hide: function ($elements) {
15266    var base = this,
15267      customHide = base.options.hide;
15268
15269    if (typeof customHide !== 'function') {
15270      $elements.hide();
15271    } else {
15272      $elements.toArray().forEach(customHide);
15273    }
15274  },
15275
15276  /**
15277   * @method animationAccordion
15278   * @desc Animation für OpenClose des Accordions
15279   *
15280   * @param elem {Object} Element welches animiert werden soll
15281   * @param type Art der Animation - {string} open / close
15282   */
15283  animationAccordion: function (elem, type, callback) {
15284    var base = this;
15285
15286    if (type === 'open') {
15287      elem.hide().animate({ height: 'toggle' }, { duration: base.options.accordionAnimationDuration }).promise().done(callback, function () {
15288        base.show(this);
15289
15290        if (base.options.accordionElementToOpen) {
15291          base.addA11y(elem);
15292        }
15293        base.$el.trigger('afterAnimationOpen.toggle.cms', $(elem).prev());
15294      });
15295    } else {
15296      elem.show().animate({ height: 'toggle' }, { duration: base.options.accordionAnimationDuration }).promise().done(callback, function () {
15297        base.hide(this);
15298        base.$el.trigger('afterAnimationClose.toggle.cms', $(elem).prev());
15299      });
15300    }
15301  },
15302
15303  /**
15304   * @method animationTab
15305   * @desc Animation für OpenClose des Tabs
15306   *
15307   * @param panelToClose {Object} Element welches animiert werden soll (ausblenden)
15308   * @param panelToOpen {Object} Element welches animiert werden soll (einblenden)
15309   */
15310  animationTab: function (panelToClose, panelToOpen) {
15311    var base = this;
15312
15313    if (base.options.animateTab) {
15314      panelToClose.fadeOut('slow', function () {
15315        panelToOpen.fadeIn('slow', function () {
15316          base.show(this);
15317        });
15318      });
15319    } else {
15320      base.hide(panelToClose);
15321      base.show(panelToOpen);
15322
15323      if (typeof base.options.afterChange === 'function') {
15324        base.options.afterChange.call($(this), base.$el);
15325      }
15326    }
15327  },
15328
15329  /**
15330   * @method autoplay
15331   * @desc Autoplay
15332   */
15333  autoplay: function () {
15334    var base = this;
15335
15336    if (base.$el.find('> button').length === 0) {
15337      var button = document.createElement('button');
15338      button.className = 'paused';
15339      var image = document.createElement('img');
15340      image.src = base.options.playButtonImagePlaying;
15341      image.alt = base.options.playButtonAltTextPlaying; // playbutton = base.$el.append($(button).append(image));
15342    }
15343
15344    base.playbutton = base.$el.find('button.paused');
15345    base.playbutton.on('click autoplayStart', function (e) {
15346      e.preventDefault();
15347      e.stopPropagation();
15348
15349      if (base.playbutton.hasClass('paused')) {
15350        $(this).removeClass('paused').addClass('played');
15351        base.autoplayStart();
15352        base.changeStatePlayPause(base.options.playButtonImagePlaying, base.options.playButtonAltTextPlaying);
15353        base.isPaused = false;
15354
15355        if (e.type !== 'autoplayStart') {
15356          //Damit nach Starten des Autoplays nicht nochmal autoplayStart von mouseleave aufgerufen wir
15357          base.isClicked = true;
15358        }
15359      } else {
15360        $(this).addClass('paused').removeClass('played');
15361        base.autoplayStop();
15362        base.changeStatePlayPause(base.options.playButtonImagePaused, base.options.playButtonAltTextPaused);
15363        base.isPaused = true;
15364      }
15365    });
15366
15367    // Stop bei Hover
15368    if (base.options.pauseOnHover) {
15369      base.$el.on('mouseenter mouseleave', function (e) {
15370        if (!base.isPaused) {
15371          if (e.type === 'mouseenter') {
15372            base.autoplayStop();
15373          } else {
15374            if (base.playbutton.hasClass('played') && !base.isClicked) {
15375              base.autoplayStart();
15376            }
15377
15378            base.isClicked = false;
15379          }
15380        }
15381      });
15382    }
15383
15384    //play bei start
15385    if (base.options.playOnLoad) {
15386      base.playbutton.trigger('autoplayStart');
15387    }
15388
15389    base.autoplayInitialized = true;
15390  },
15391
15392  /**
15393   * @method autoplayStart
15394   * @desc Autoplay start
15395   */
15396  autoplayStart: function () {
15397    var base = this;
15398    base.rotation = setInterval(function () {
15399      var tabControls = base.$el.find(base.options.tabControls),
15400        activeTab = tabControls.find('active-control'),
15401        activeIndex = tabControls.index(activeTab),
15402        lastIndex = tabControls.length - 1; //Wenn letzter Tab, wieder beim ersten anfangen
15403
15404      if (activeIndex >= lastIndex) {
15405        tabControls.first().click();
15406      } else {
15407        tabControls.eq(activeIndex + 1).click();
15408      }
15409    }, base.options.autoSpeed);
15410  },
15411
15412  /**
15413   * @method autoplayStop
15414   * @desc Autoplay stop
15415   */
15416  autoplayStop: function () {
15417    var base = this;
15418    clearInterval(base.rotation);
15419  },
15420
15421  makeAccessible: function () {
15422    var base = this,
15423      tabControlContainer,
15424      tabListHeading,
15425      tabs,
15426      headings,
15427      clonedHeadings,
15428      buttons,
15429      contentPanels;
15430
15431    if (!base.aria) {
15432      tabControlContainer = base.$el.find(base.options.tabControlContainer);
15433      tabListHeading = base.$el.find(base.options.tabListHeading);
15434
15435      if (!tabListHeading.length) {
15436        tabListHeading = tabControlContainer.prev(base.options.semanticHeading);
15437      }
15438
15439      tabs = base.$el.find(base.options.tabControls);
15440      headings = base.$el.find(base.options.heading);
15441      contentPanels = base.$el.find(base.options.elements);
15442
15443      if (base.findAllUsedModes().includes('tabs')) {
15444        clonedHeadings = headings.filter(base.options.semanticHeading).map(function (i, originalHeading) {
15445          const clonedHeading = $(document.createElement(originalHeading.tagName));
15446          clonedHeading.
15447          html($(originalHeading).html()).
15448          addClass(base.options.clonedHeadingClass).
15449          prependTo(contentPanels.eq(i));
15450          return clonedHeading[0];
15451        });
15452      } else {
15453        clonedHeadings = $();
15454      }
15455
15456      buttons = headings.map(function () {
15457        var heading = $(this),
15458          links,
15459          button;
15460
15461        if (!heading.is('button, a')) {
15462          links = heading.find('a');
15463          if (links.length) {
15464            button = links.first().
15465            attr('role', 'button');
15466          } else {
15467            button = $('<button/>').append(heading.contents());
15468            heading.append(button);
15469            heading.attr('data-transformedbytoggle', 'true');
15470          }
15471        } else {
15472          button = heading;
15473        }
15474
15475        return button[0];
15476      });
15477      base.tabs = tabs;
15478      base.headings = headings;
15479      base.clonedHeadings = clonedHeadings;
15480      base.contentPanels = contentPanels;
15481      base.buttons = buttons;
15482      base.aria = cms.aria(base.el, {}, $.extend({}, base.ariaParams, {
15483        types: {
15484          tabListHeading: tabListHeading,
15485          tabControlContainer: tabControlContainer,
15486          button: buttons,
15487          content: contentPanels,
15488          tab: tabs
15489        }
15490      }));
15491
15492      headings.each(function (i) {
15493        if ($(this).hasClass('active-control')) {
15494          base.aria.updateAria(buttons[i], true, true);
15495          base.show(contentPanels.eq(i));
15496        }
15497      });
15498      tabs.each(function (i) {
15499        if ($(this).hasClass('active-control')) {
15500          base.aria.updateAria(tabs[i], true, true);
15501          base.show(contentPanels.eq(i));
15502        }
15503      });
15504
15505      tabs.parentsUntil(tabControlContainer).attr('role', 'none');
15506    }
15507  },
15508
15509  ariaParams: {
15510    initial: [{
15511      _type: 'tabListHeading',
15512      id: function id(base) {
15513        return base.generateID();
15514      }
15515    }, {
15516      _type: 'tabControlContainer',
15517      role: 'tablist',
15518      'aria-labelledby': function ariaLabelledby(base) {
15519        if (base.types['tabControlContainer'].eq(0).attr('aria-label')) {
15520          return null; //delete labelledby
15521        } else if (base.types['tabControlContainer'].eq(0).attr('aria-labelledby')) {
15522          return undefined; //do nothing
15523        } else {
15524          return base.types['tabListHeading'].eq(0).attr('id') || null;
15525        }
15526      }
15527    }, {
15528      _type: 'content',
15529      role: function role(base, index) {
15530        return base.types['content'].eq(index).attr('role') || 'tabpanel';
15531      },
15532      id: function id(base, index) {
15533        return base.types['content'].eq(index).attr('id') || base.generateID();
15534      }
15535    }, {
15536      _type: 'tab',
15537      role: 'tab',
15538      id: function id(base) {
15539        return base.generateID();
15540      },
15541      'aria-controls': function ariaControls(base, index) {
15542        return base.types['content'].eq(index).attr('id');
15543      },
15544      'href': function href(base, index) {
15545        var tab = base.types['tab'].eq(index),
15546          contId = base.types['content'].eq(index).attr('id'),
15547          hashLess = location.href.split('#')[0];
15548        if (tab.is('a')) {
15549          return tab.attr('href') || hashLess + '#' + contId;
15550        } else {
15551          return null;
15552        }
15553      }
15554    }, {
15555      _type: 'button',
15556      id: function id(base) {
15557        return base.generateID();
15558      },
15559      'aria-controls': function ariaControls(base, index) {
15560        return base.types['content'].eq(index).attr('id');
15561      }
15562    }, {
15563      _type: 'content',
15564      'aria-labelledby': function ariaLabelledby(base, index) {
15565        return base.types['tab'].eq(index).attr('id') || base.types['button'].eq(index).attr('id');
15566      }
15567    }],
15568    toggles: {
15569      tab: {
15570        'aria-selected': ['true', 'false'],
15571        tabindex: [0, -1]
15572      },
15573      button: {
15574        'aria-expanded': ['true', 'false']
15575      },
15576      content: {
15577        hidden: [null, 'hidden']
15578      }
15579    }
15580  },
15581
15582  //focuses next tabbable element outside the widget
15583  focusNextTabbable: function () {
15584    var base = this,
15585      allTabbables = $(base.options.tabbables).not('[tabindex=-1]'),
15586      lastIndex = allTabbables.length - 1,
15587      tabbablesInside = base.$el.find(base.options.tabbables).not('[tabindex=-1]'),
15588      firstIndexOutside = allTabbables.index(tabbablesInside.last()) + 1;
15589    allTabbables.eq(firstIndexOutside > lastIndex ? 0 : firstIndexOutside).focus();
15590  },
15591
15592  //focuses previous tabbable element outside the widget
15593  focusPrevTabbable: function () {
15594    var base = this,
15595      allTabbables = $(base.options.tabbables).not('[tabindex=-1]'),
15596      tabbablesInside = base.$el.find(base.options.tabbables).not('[tabindex=-1]'),
15597      firstIndexOutside = allTabbables.index(tabbablesInside.first()) - 1;
15598    allTabbables.eq(firstIndexOutside < 0 ? -1 : firstIndexOutside).focus();
15599  },
15600
15601  activatePrevTab: function () {
15602    var base = this,
15603      tabs = base.tabs,
15604      activeTab = tabs.filter('.active-control'),
15605      activeIndex = tabs.index(activeTab);
15606
15607    if (activeIndex - 1 > -1) {
15608      tabs.eq(activeIndex - 1).trigger('activateTab');
15609    } else {
15610      tabs.last().trigger('activateTab');
15611    }
15612  },
15613
15614  activateNextTab: function () {
15615    var base = this,
15616      tabs = base.tabs,
15617      activeTab = tabs.filter('.active-control'),
15618      activeIndex = tabs.index(activeTab);
15619
15620    if (activeIndex + 1 < tabs.length) {
15621      tabs.eq(activeIndex + 1).trigger('activateTab');
15622    } else {
15623      tabs.first().trigger('activateTab');
15624    }
15625  },
15626
15627  onKeyTab: function (ev) {
15628    var base = ev.data;
15629    base.tabs = base.$el.find(base.options.tabControls);
15630
15631    switch (ev.key) {
15632      case 'ArrowLeft':
15633      case 'Left':
15634        // IE/Edge
15635        base.activatePrevTab();
15636        break;
15637
15638      case 'ArrowRight':
15639      case 'Right':
15640        // IE/Edge
15641        base.activateNextTab();
15642        break;
15643
15644      case 'Home':
15645        base.tabs.first().trigger('activateTab');
15646        break;
15647
15648      case 'End':
15649        base.tabs.last().trigger('activateTab');
15650        break;
15651
15652      default:
15653        //skip preventDefault etc.
15654        return;
15655    }
15656
15657    ev.stopPropagation();
15658    ev.preventDefault();
15659  },
15660
15661  tabKeyboardCtrl: function () {
15662    var base = this,
15663      eventString = 'keydown.cms_toggle';
15664    base.$el.off(eventString, base.onKeyAcc);
15665    base.$el.on(eventString, base, base.onKeyTab);
15666  },
15667
15668  refreshTab: function () {
15669    throw new Error(
15670      "refreshTab() ist obsolet." +
15671      " onRefresh() zu überschreiben ist nicht mehr nötig, um den Typ des Toggles festzulegen." +
15672      " Dies geschieht jetzt über die Option 'mode' (mit Wert 'tabs' für Tabs)." +
15673      " Diese Option ist auch in Breakpoints erlaubt."
15674    );
15675  },
15676
15677  /**
15678   * @method switchToTabs
15679   * @desc Switch to tabs mode
15680   */
15681  switchToTabs: function () {
15682    var base = this,
15683      activeTab;
15684
15685    base.contentPanels.attr('role', 'tabpanel');
15686    base.tabKeyboardCtrl();
15687
15688    if (base.options.hashControlled) {
15689      base.onPopState('opened');
15690    } else {
15691      activeTab = base.tabs.filter('[aria-selected=true]');
15692      if (activeTab.length) {
15693        base.clickedElem = activeTab;
15694        base.changeStateTab();
15695      }
15696    }
15697
15698    base.$el.find(base.options.heading).each(function () {
15699      $(this).removeAttr('aria-expanded');
15700    }); // Autoplay muss deaktiviert sein, da die Events focusin und focu
15700sout im Firefox derzeit nocht nicht implementiert
15701    // sind bzw. noch bugs enthalten
15702
15703    if (base.options.changeOnHover && !base.options.autoplay) {
15704      base.$el.on('mouseenter focus', base.options.tabControls, function (e) {
15705        base.clickedElem = $(this);
15706        base.changeStateTab();
15707      });
15708    }
15709
15710    base.hide(base.$el.find('.' + base.options.panelClosedClass));
15711    base.show(base.$el.find('.' + base.options.panelOpenedClass));
15712  },
15713
15714  focusPrevHeading: function () {
15715    var base = this,
15716      buttons = base.buttons,
15717      activeButton = buttons.filter(document.activeElement),
15718      activeIndex = buttons.index(activeButton);
15719
15720    if (activeIndex - 1 > -1) {
15721      buttons.eq(activeIndex - 1).focus();
15722    } else {
15723      buttons.last().focus();
15724    }
15725  },
15726
15727  focusNextHeading: function () {
15728    var base = this,
15729      buttons = base.buttons,
15730      activeButton = buttons.filter(document.activeElement),
15731      activeIndex = buttons.index(activeButton);
15732
15733    if (activeIndex + 1 < buttons.length) {
15734      buttons.eq(activeIndex + 1).focus();
15735    } else {
15736      buttons.first().focus();
15737    }
15738  },
15739
15740  onKeyAcc: function (ev) {
15741    var base = ev.data;
15742
15743    if (!base.options.accordionDisableKeyboardCtrl) {
15744      switch (ev.key) {
15745        case 'ArrowUp':
15746        case 'Up':
15747          // IE/Edge
15748          base.focusPrevHeading();
15749          break;
15750
15751        case 'ArrowDown':
15752        case 'Down':
15753          // IE/Edge
15754          base.focusNextHeading();
15755          break;
15756
15757        case 'Home':
15758          base.buttons.first().focus();
15759          break;
15760
15761        case 'End':
15762          base.buttons.last().focus();
15763          break;
15764
15765        default:
15766          //skip preventDefault etc.
15767          return;
15768      }
15769
15770      ev.preventDefault();
15771    }
15772  },
15773
15774  accKeyboardCtrl: function () {
15775    var base = this,
15776      eventString = 'keydown.cms_toggle';
15777    base.$el.off(eventString, base.onKeyTab); // remove listener for tabs
15778    base.$el.off(eventString, base.onKeyAcc); // avoid duplicate listener
15779    base.$el.on(eventString, base, base.onKeyAcc);
15780  },
15781
15782  refreshAccordion: function () {
15783    throw new Error(
15784      "refreshAccordion() ist obsolet." +
15785      " onRefresh() zu überschreiben ist nicht mehr nötig um den Typ des Toggles festzulegen." +
15786      " Dies geschieht jetzt über die Option 'mode' (mit Wert 'accordion' für Akkordeon)." +
15787      " Der Default-Modus in allen Größen ist 'accordion'." +
15788      " Diese Option ist auch in Breakpoints erlaubt."
15789    );
15790  },
15791
15792  /**
15793   * @method switchToAccordion
15794   * @desc  Switch to accordion mode
15795   */
15796  switchToAccordion: function () {
15797    var base = this;
15798
15799    if (base.contentPanels.is('div') || base.contentPanels.is('span')) {
15800      base.contentPanels.attr('role', 'region');
15801    }
15802    base.accKeyboardCtrl();
15803    base.$el.find(base.options.elements).each(function () {
15804      var $elem = $(this);
15805
15806      if ($elem.is('[hidden]')) {
15807        $elem.prev('.active-control').removeClass('active-control').addClass('inactive-control');
15808      } else {
15809        $elem.prev('.inactive-control').removeClass('inactive-control').addClass('active-control');
15810      }
15811    });
15812
15813    if (base.options.hashControlled) {
15814      base.onPopState('opened');
15815    }
15816
15817    base.$el.find(base.options.heading).each(function () {
15818      if ($(this).hasClass('inactive-control')) {
15819        base.hide($(this).next());
15820      }
15821    });
15822
15823    let activeDescendant = base.$el.find(document.activeElement);
15824    if (activeDescendant.length > 0) {
15825      base.tabs.each(function (i, el) {
15826        let tab = $(el);
15827        if (tab.is(activeDescendant) || tab.find(activeDescendant).length) {
15828          base.buttons.eq(tab.prop('cms_aria_index')).focus();
15829        }
15830      });
15831    }
15832  },
15833
15834  /**
15835   * @method changeStatePlayPause
15836   * @param {string} imgsrc - Imagesource-Link
15837   * @param {string} alt - Alt-Text des Images
15838   * @desc Bild tauschen für Play/Pausebutton
15839   */
15840  changeStatePlayPause: function (imgsrc, imgalt) {
15841    var base = this;
15842    var image = base.playbutton.find('img');
15843    image.prop('alt', imgalt).prop('src', imgsrc);
15844  },
15845
15846  /**
15847   * @method getSwitchPanelClass
15848   * @param {Object} elem - geklicktes Element (durchgereicht von changeState oder autoplayStart)
15849   * @desc Liefert die switch-panel Klasse des geklickten Elements
15850   */
15851  getSwitchPanelClass: function (elem) {
15852    return $.grep(elem.prop('class').split(' '), function (value) {
15853      return value.indexOf('switch-panel') > -1;
15854    });
15855  },
15856
15857  uninitAccordion: function () {
15858    throw new Error(
15859      "uninitAccordion() ist obsolet." +
15860      " uninitAccordion() aufzurufen ist nicht mehr nötig um den Typ des Toggles festzulegen." +
15861      " Dies geschieht jetzt über die Option 'mode' (mit Wert 'none' für kein Toggle)."
15862    );
15863  },
15864
15865  /**
15866   * @method switchToNone
15867   * @desc Soll den Großteil der DOM-Änderungen durch das Modul rückgängig machen.
15868   *       Die Klassen active-control und inactive-control sind davon ausgenommen.
15869   */
15870  switchToNone: function () {
15871    var base = this;
15872
15873    if (base.$el.hasClass('cms-toggle')) {
15874      base.$el.removeClass('cms-toggle');
15875      base.$el.off('.cms_toggle'); //entfernt nur namespace='.cms_toggle' Events
15876
15877      base.headings.filter(function () {
15878        return $(this).attr('data-transformedbytoggle') === 'true';
15879      }).each(function (i) {
15880        var contents = base.buttons.eq(i).contents();
15881        $(this).empty().append(contents);
15882      });
15883      base.show(base.contentPanels);
15884      base.contentPanels.removeAttr('hidden role aria-labelledby');
15885      base.$el.find(base.options.tabControlContainer).removeAttr('role');
15886      base.tabs.removeAttr('role aria-selected tabindex');
15887      base.buttons.removeAttr('aria-expanded');
15888      base.clonedHeadings.remove();
15889      base.contentPanels.removeClass(base.options.panelOpenedClass + ' ' + base.options.panelClosedClass);
15890      base.contentPanels.removeClass(function (index, className) {
15891        return className.match(base.options.switchPanelClass + "\\d*", "g");
15892      });
15893      base.aria.$el.data('cms.aria', null);
15894      base.aria = null;
15895    }
15896  },
15897
15898  destroyWidget: function () {
15899    throw new Error(
15900      "destroyWidget() ist obsolet." +
15901      " destroyWidget() nicht mehr unterstützt." +
15902      " Vermutlich genügt es die Option 'mode' (mit Wert 'none' für kein Toggle) zu setzen." +
15903      " Ein \"echtes\" destroy ist dies jedoch nicht, die Modulinstanz bleibt erhalten."
15904    );
15905  },
15906
15907  /**
15908   * @method addA11y
15909   * @desc  setzt den focus auf das erste fokussierbare Element
15910   * @param elem {jQuery} Element welches nach fokussierbaren Elementen durchsucht wird. Ist mindestens ein Element vorhanden,
15911   * wird der Fokus gesetzt
15912   * @param tabPanel {jQuery} Element auf welches gesprungen werden soll, wenn im TabContainer keiner fokussierbaren Element vorhanden sind
15913   */
15914  addA11y: function (elem, tabPanel) {
15915    var base = this;
15916    elem = elem || base.$el;
15917    var focusElements = elem.find('input,textarea,select,a,button').not(':hidden');
15918
15919    if (focusElements.length) {
15920      focusElements[0].focus();
15921      focusElements.last().keydown(function (e) {
15922      });
15923    }
15924  },
15925
15926  /**
15927   * @method addRichtextContainer
15928   * @desc Sucht in base.el nach Elementen mit den Klasse startaccordion, endaccordion und accordionheadline (konfigurierbar)
15929   * und baut die für cms_toggle benötigte Struktur um diese Elemente herum.
15930   *
15931   * Wenn alle benötigten Elemente eingebaut wurden, ruft sich das Script nochmal selbst auf; dann mit der Option richtext := false
15932   */
15933  addRichtextContainer: function () {
15934    var base = this,
15935      containers;
15936    containers = base.$el.find(base.options.richtextStart).map(function () {
15937      var startAcc = $(this),
15938        rtAccContainer = $(base.options.richtextAccordionContainer, base.el).insertBefore(startAcc),
15939        rtTabContainer = $(base.options.richtextTabControlContainer, base.el).insertBefore(startAcc),
15940        headings,
15941        wrapper;
15942      startAcc.
15943      add(startAcc.nextUntil(base.options.richtextEnd)).
15944      add(startAcc.nextAll(base.options.richtextEnd).first()).
15945      appendTo(rtAccContainer);
15946      headings = rtAccContainer.find(base.options.richtextStart).add(rtAccContainer.find(base.options.richtextControl));
15947      headings.addClass('heading').each(function (i) {
15948        var heading = $(this),
15949          nextHeading = headings.eq(i + 1);
15950        rtTabContainer.append($(base.options.richtextTabControlContainerItem).append($('<a/>').html(heading.html())));
15951        if (nextHeading.length) {
15952          heading.nextUntil(nextHeading).wrapAll('<div/>');
15953        }
15954      });
15955      rtAccContainer.find('.heading').last().nextUntil(base.options.richtextEnd).add(rtAccContainer.find(base.options.richtextEnd)).wrapAll('<div/>');
15956      wrapper = $(base.options.richtextWrapper, base.el).insertBefore(rtTabContainer);
15957
15958      let usedModes = base.findAllUsedModes();
15959      if (usedModes.includes('tabs')) {
15960        wrapper.append(rtTabContainer);
15961      } else {
15962        rtTabContainer.remove();
15963      }
15964      if (usedModes.includes('accordion')) {
15965        wrapper.append(rtAccContainer);
15966      } else {
15967        headings.remove();
15968      }
15969      return wrapper[0];
15970    });
15971    base.$el.removeData('cms.toggle');
15972    containers.cms_toggle($.extend({}, base.options, {
15973      richtext: false
15974    }));
15975  },
15976
15977  defaultOptions: {
15978    mode: 'accordion', //Möglichkeiten: accordion, tabs, none
15979    richtext: false,
15980    richtextWrapper: '<div class="richtext-accordion"/>',
15981    richtextStart: '.startaccordion',
15982    richtextControl: '.accordionheadline',
15983    richtextEnd: '.endaccordion',
15984    tabContainer: '> .tabs-container',
15985    tabControls: '> .tabs-list > li a',
15986    tabControlContainer: '> .tabs-list',
15987    richtextTabControlContainer: '<ul class="tabs-list"/>',
15988    richtextTabControlContainerItem: '<li></li>',
15989    tabListHeading: '',
15990    elements: '> .tabs-container > div',
15991    heading: '> .tabs-container > .heading',
15992    clonedHeadingClass: 'cloned-heading',
15993    switchPanelClass: 'switch-panel',
15994    panelOpenedClass: 'panel-opened',
15995    panelClosedClass: 'panel-closed',
15996    richtextAccordionContainer: '<div class="tabs-container"/>',
15997    semanticHeading: 'h1,h2,h3,h4,h5,h6',
15998    tabbables: 'a[href], area, input, button, select, textarea, audio, video, [tabindex]',
15999    accordionAnimationDuration: 400,
16000    accordionCloseOther: true,
16001    accordionNoClose: false,
16002    accordionDisableKeyboardCtrl: false,
16003    accordionPanelHeight: false,
16004    accordionElementToOpen: null,
16005    accordionElementsStopPropagation: '',
16006    hashControlled: false,
16007    autoplay: false,
16008    playButtonImagePaused: null,
16009    playButtonImagePlaying: null,
16010    playButtonAltTextPaused: typeof PLAY === 'undefined' ? 'Animation starten' : PLAY,
16011    playButtonAltTextPlaying: typeof PAUSE === 'undefined' ? 'Animation stoppen' : PAUSE,
16012    accordionHeadingTitleClosed: null,
16013    accordionHeadingTitleOpened: null,
16014    autoSpeed: '5000',
16015    playOnLoad: false,
16016    pauseOnHover: true,
16017    changeOnHover: false,
16018    allOpen: false,
16019    animateTab: false,
16020    respondToEvents: true,
16021    scrolling: {
16022      scrollOffset: function (referenceElement) {
16023        return NaN;
16024      },
16025      scrollToControlElementAfterOpen: true,
16026      scrollAnimationDuration: 300,
16027      scrollOverlaySelector: '.js-header.is-sticky'
16028    },
16029    onRefresh: function () {
16030      this.switchAccordingToMode();
16031    },
16032    responsive: []
16033  }
16034});
16035
16036    /* Ende cms_toggle */
16037    /* Start cms_tree_navigation */
16038        /*! --GSBDocStart
16039 * @name: @cms/cms_tree_navigation
16040 * @version: 7.1.0
16041 * @description: Modul für konfigurierbare Cookiebanner
16042 * --CMSDocEnd
16043*/"use strict";
16044cms.makeCMSModule('cms.tree_navigation', {
16045
16046  init: function init() {
16047    const base = this;
16048    base.preInit();
16049    base.initButtonHandlers();
16050    base.initCustomEventHandlers();
16051    base.registerMetaFixerInitialized();
16052  },
16053
16054  registerMetaFixerInitialized: function registerMetaFixerInitialized() {
16055    const base = this;
16056    base.$el.on('cms_meta_fixer_initialized', base, base.onMetaFixerInitialized);
16057  },
16058
16059  adjustFocus: function adjustFocus($anchor) {
16060    const base = this;
16061    base.$el.find(`.${base.options.classes.anchor}`).find('a, button').not(`.${base.options.buttonClasses.toggle}`).not(base.options.classes.alwaysFocusable ? `.${base.options.classes.alwaysFocusable}` : '').attr('tabindex', -1);
16062
16063    if (base.$el.hasClass(base.options.classes.show)) {
16064      // only make anything tabable when the menu is shown
16065      if ($anchor.length) {
16066        const $navigatedBackFrom = $anchor.prevObject;
16067        // add sibling on the same level, to allow multiple 'ul' on the same level
16068        $anchor = $anchor.add($anchor.siblings(`.${base.options.cssClasses.anchor_current}`));
16069        // only make the currently opened sub menu's links and it's siblings tabable
16070        const $currentOpenedSubMenuLinks = $anchor.find('a, button').filter((i, e) => !$(e).closest(`.${base.options.classes.anchor}`).hasClass(base.options.cssClasses.anchor_closed));
16071        $currentOpenedSubMenuLinks.attr('tabindex', 0);
16072
16073        // set focus
16074        if ($navigatedBackFrom) {
16075          // focus the previously opened menu opener, which opened the menu navigating back from
16076          $navigatedBackFrom.find('> button').first().attr('tabindex', 0).trigger('focus');
16077        } else {
16078          if (window.getComputedStyle($anchor[0]).transitionDuration !== '0s') {
16079            // if navigateToInner makes the menu slide in, using CSS transition
16080            // wait for the transition to end and then focus the first menu entry to avoid scrolling
16081            $anchor.one('transitionend transitioncancel', function () {
16082              $anchor.find('button,a').first().trigger('focus');
16083            });
16084          } else {
16085            $anchor.find('button,a').first().trigger('focus');
16086          }
16087        }
16088
16089        // fix Meta Navigation
16090        if (base.options.classes.metaNav) {
16091          const $metaMenuButtons = base.$el.find(`:not(.${base.options.classes.anchor_closed})`).find(`.${base.options.classes.metaNav}`).find('a, button');
16092          if ($metaMenuButtons.length) {
16093            // metaMenuButtons are visible and should be tabable
16094            $metaMenuButtons.attr('tabindex', '0');
16095          } else {
16096            base.$el.find(`.${base.options.classes.metaNav}`).find('a, button').attr('tabindex', '-1');
16097          }
16098        }
16099
16100      } else {
16101        // make everything tabbable
16102        const $allButtonsAndLinks = base.$el.find('a, button');
16103
16104        $allButtonsAndLinks.filter('[tabindex="-1"]').
16105        attr('tabindex', 0);
16106
16107        $allButtonsAndLinks.
16108        first().trigger('focus');
16109
16110      }
16111    } else {
16112      const nodes = base.$el.find(`.${base.options.classes.node}`);
16113      nodes.find('> button[disabled]').
16114      removeAttr('disabled');
16115      nodes.siblings().
16116      removeClass(base.options.cssClasses.anchor_closed);
16117
16118      base.$el.find(`.${base.options.classes.anchor}`).
16119      css('--height', '');
16120    }
16121  },
16122
16123  adjustHeight: function adjustHeight(anchor, button) {
16124    const base = this;
16125    if (base.options.mode === 'overlay') {
16126      let $anchor = $(anchor);
16127      const $openedUls = base.$el.find(`.${base.options.classes.anchor}.${base.options.cssClasses.anchor_opened}:visible`);
16128
16129      // If navigating back, switch to next ul parent
16130      if ($(button).length < 1) {
16131        $anchor = $anchor.parent().closest(`.${base.options.classes.anchor}`);
16132      }
16133
16134      let maxHeight = 0;
16135      // Find maximal natural height of an element
16136      $openedUls.css('--height', 'auto');
16137      $openedUls.each(function () {
16138        if ($(this).outerHeight(true) > maxHeight) {
16139          maxHeight = $(this).outerHeight(true);
16140        }
16141      });
16142
16143      $openedUls.each(function () {
16144        $(this).css('--height', `${maxHeight}px`);
16145        $(this).css('--overflow', 'hidden');
16146      });
16147      base.adjustFocus($anchor);
16148      base.$el.trigger('height_adjusted.tree_navigation.cms');
16149    }
16150  },
16151
16152
16153  onMetaFixerInitialized: function onMetaFixerInitialized(ev) {
16154    const base = ev.data;
16155    const nnId = $('body').data('nn');
16156    const $openElement = $(`#nn-${nnId}`);
16157    if ($openElement.length > 0) {
16158      const $uls = $openElement.parents('ul');
16159      const buttons = [];
16160      $uls.each(function () {
16161        let button = $(this).prev('button');
16162        if (button.length < 1) {
16163          button = $(this).closest(`.${base.options.classes.node}`).find('button')[0];
16164        }
16165        buttons.unshift(button);
16166      });
16167
16168      if (base.options.openSubNavForCurrentNode) {
16169        const button = $openElement.find('button').first();
16170        buttons.unshift(button);
16171      }
16172
16173      for (let i = 0; i < buttons.length; i++) {
16174        const currentButton = buttons[i];
16175        base.navigateToInner(currentButton);
16176      }
16177      base.$el.trigger('cms_tree_navigation_open_node', buttons[buttons.length]);
16178    }
16179    return $openElement;
16180  },
16181
16182  preInit: function preInit() {
16183    const base = this;
16184    const tnOptions = base.options;
16185    base.$el.cms_responsiveListener(base);
16186
16187    // initial state
16188    const initialOpen = tnOptions.states.initStateOpen;
16189    base.toggleMenuSet(initialOpen, false);
16190
16191    base.resetState();
16192
16193    if (tnOptions.optional.setMaxAnchorHeight) {
16194      let height = 0;
16195      base.$el.find(`.${tnOptions.classes.anchor}`).each(function (i, element) {
16196        const currHeight = $(element).outerHeight(true);
16197        if (currHeight > height) {
16198          height = currHeight;
16199        }
16200      });
16201      base.$el.find(`.${tnOptions.classes.anchor}`).each(function (i, element) {
16202        $(element).css('--height', `${height}px`);
16203      });
16204    }
16205
16206    // set initial aria-expanded for toggle to open the menu
16207    base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first().attr('aria-expanded', initialOpen);
16208  },
16209
16210
16211  initButtonHandlers: function initButtonHandlers() {
16212    const base = this;
16213    const tnOptions = base.options;
16214
16215    // handle menu
16216    // display
16217    base.$el.find(`.${tnOptions.buttonClasses.toggleOn}`).first().on('click', function (e) {
16218      base.toggleMenuSet(true);
16219      base.toggleClass(base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first(), true, tnOptions.cssClasses.toggleClass_opened, tnOptions.cssClasses.toggleClass_closed);
16220      base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first().attr('aria-expanded', true);
16221    });
16222    // hide
16223    base.$el.find(`.${tnOptions.buttonClasses.toggleOff}`).first().on('click', function (e) {
16224      base.toggleMenuSet(false);
16225      base.toggleClass(base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first(), false, tnOptions.cssClasses.toggleClass_opened, tnOptions.cssClasses.toggleClass_closed);
16226      base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first().attr('aria-expanded', false);
16227    });
16228    // toggle
16229    base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first().on('click.toggle.tree_navigation.cms', function (e) {
16230      const setOpen = $(base.el).hasClass(tnOptions.classes.hide);
16231      base.toggleMenuSet(setOpen);
16232      base.toggleClassesIf(base.el, tnOptions.classes.show, this, tnOptions.cssClasses.toggleClass_opened, tnOptions.cssClasses.toggleClass_closed);
16233      $(this).attr('aria-expanded', setOpen);
16234    });
16235    // navigate to inner level
16236    base.$el.find(`.${tnOptions.buttonClasses.navigateToInner}`).on('click', function (e) {
16237      base.navigateToInner(this);
16238    });
16239
16240    if (tnOptions.states.navBackButton) {
16241      // go back one level
16242      base.$el.find(`.${tnOptions.buttonClasses.navigateBack}`).on('click', function (e) {
16243        base.navigateBack(this);
16244      });
16245    }
16246  },
16247
16248  initCustomEventHandlers: function initCustomEventHandlers(base = this) {
16249    // close toggle (triggered when cms_mobile_nav_service_search is opened)
16250    $(document).on('close.toggle.tree_navigation.cms', base, function (ev, base = ev.data) {
16251      base.toggleMenuSet(false);
16252      base.toggleClassesIf(base.el, false, base.$el.find(`.${base.options.buttonClasses.toggle}`).first(), base.options.cssClasses.toggleClass_opened, base.options.cssClasses.toggleClass_closed);
16253      base.$el.find(`.${base.options.buttonClasses.toggle}`).first().attr('aria-expanded', false);
16254    });
16255  },
16256
16257  // ---------------------------------------------------
16258
16259  resetState: function resetState() {
16260    const base = this;
16261    const tnOptions = base.options;
16262    base.hideAllAnchorsButFirstLevel();
16263    // hide all nodes
16264    $(base.el).find(`.${tnOptions.classes.node}`).each(function (i, node) {
16265      $(node).removeClass(tnOptions.cssClasses.node_opened);
16266      $(node).addClass(tnOptions.cssClasses.node_closed);
16267      $(node).find('button').not(`.${tnOptions.buttonClasses.navigateBack}`).attr('aria-expanded', false); // set initial aria-expanded to false
16268    });
16269    // set all navigateToInner buttons -> closed
16270    $(base.el).find(`.${tnOptions.buttonClasses.navigateToInner}`).each(function (i, button) {
16271      $(button).removeClass(tnOptions.cssClasses.navigateToInner_opened);
16272      $(button).addClass(tnOptions.cssClasses.navigateToInner_closed);
16273    });
16274  },
16275
16276  hideAllAnchorsButFirstLevel: function hideAllAnchorsButFirstLevel() {
16277    const base = this;
16278    const tnOptions = base.options;
16279    const $firstLevelAnchors = $(base.el).find(`.${tnOptions.classes.anchor}`).filter(function (index, anchor) {
16280      return $(anchor).parent().closest(`.${tnOptions.classes.anchor}`).length === 0;
16281    });
16282    const $deeperLevelAnchors = $(base.el).find(`.${tnOptions.classes.anchor}`).not($firstLevelAnchors);
16283    $firstLevelAnchors.addClass(tnOptions.cssClasses.anchor_opened).removeClass(tnOptions.cssClasses.anchor_closed);
16284    base.setAnchorCurrentClass($firstLevelAnchors, true); // only overlay mode
16285    $deeperLevelAnchors.addClass(tnOptions.cssClasses.anchor_closed).removeClass(tnOptions.cssClasses.anchor_opened);
16286  },
16287
16288  trapFocus: function trapFocus() {
16289    const base = this;
16290    base.focusTrapIsEngaged = true;
16291    $(base.$el).add(`.${base.options.buttonClasses.toggle}`).on('focusout', base, function (e) {
16292      const base = e.data;
16293      if (base.focusTrapIsEngaged) {
16294        const triggeredByToggle = $(e.target).hasClass(base.options.buttonClasses.toggle) || $(e.target).hasClass(base.options.buttonClasses.toggleOff);
16295        if (triggeredByToggle) {
16296          if (!base.$el.find(e.relatedTarget).length) {
16297            base.focusTrapIsEngaged = false;
16298          }
16299        } else {
16300          if (!base.$el.find(e.relatedTarget).length) {
16301            base.$el.find(`.${base.options.buttonClasses.toggle}`).focus();
16302          }
16303        }
16304      } else {
16305        if (base.$el.find(e.target).length) {
16306          base.focusTrapIsEngaged = true;
16307        }
16308      }
16309    });
16310  },
16311
16312  openNode: function openNode(open, anchor, button, node) {
16313    const base = this;
16314
16315    base.setAnchor(anchor, open);
16316    base.setButton(button, open);
16317    base.setNode(node, open);
16318    base.$el.trigger('cms_tree_navigation_open_node', button);
16319  },
16320  navigateToInner: function navigateToInner(button) {
16321    const base = this;
16322    const tnOptions = base.options;
16323    let open = tnOptions.states.navOpenOnly;
16324
16325    const anchor = $(button).siblings(`.${tnOptions.classes.anchor}`);
16326    const node = $(button).parents(`.${tnOptions.classes.node}`).first();
16327
16328    if (!tnOptions.states.navOpenOnly) {
16329      open = $(node).hasClass(tnOptions.cssClasses.node_closed);
16330    }
16331
16332    if (tnOptions.mode === 'overlay') {
16333      node.siblings().addClass(tnOptions.cssClasses.anchor_closed);
16334    }
16335
16336    base.openNode(open, anchor, button, node);
16337    base.adjustHeight(anchor, button);
16338  },
16339  navigateBack: function navigateBack(backButton) {
16340    const base = this;
16341    const tnOptions = base.options;
16342
16343    const anchor = $(backButton).parents(`.${tnOptions.classes.anchor}`).first();
16344    const button = $(backButton).siblings(`.${tnOptions.buttonClasses.navigateToInner}`);
16345    const node = $(backButton).parents(`.${tnOptions.classes.node}`).first();
16346    base.$el.trigger('cms_tree_navigation_navigate_back', backButton);
16347
16348    base.setAnchor(anchor, false);
16349    base.setButton(button, false);
16350    base.setButton(anchor.siblings('button'), false);
16351    if (tnOptions.mode === 'overlay') {
16352      node.siblings().removeClass(tnOptions.cssClasses.anchor_closed);
16353    }
16354    base.setNode(node, false);
16355    base.adjustHeight(anchor, button);
16356  },
16357  toggleMenuSet: function toggleMenuSet(open, adjustFocus = true) {
16358    const base = this;
16359    const tnOptions = base.options;
16360    if (open) {
16361      base.resetState();
16362      base.$el.trigger('beforeOpen.tree_navigation.cms', base);
16363      $('body').removeClass(tnOptions.classes.bodyMenuClosed).addClass(tnOptions.classes.bodyMenuOpened);
16364      base.trapFocus(); // engage focus trap
16365      base.toggleClass($(base.el), open, tnOptions.classes.show, tnOptions.classes.hide); // show menu
16366
16367      const $anchor = base.$el.find(` > .${base.options.classes.anchor}`);
16368      const $node = $anchor.find(` > .${base.options.classes.node}`);
16369      base.adjustHeight($anchor, $node); // needed if the menu has been opened and navigated before
16370      base.$el.trigger('afterOpen.tree_navigation.cms', base);
16371    } else {
16372      base.$el.trigger('beforeClose.tree_navigation.cms', base);
16373      $('body').removeClass(tnOptions.classes.bodyMenuOpened).addClass(tnOptions.classes.bodyMenuClosed);
16374      base.hideAllAnchorsButFirstLevel();
16375
16376      // disengage focus trap
16377      base.focusTrapIsEngaged = false;
16378      $(base.$el).add(`.${base.options.buttonClasses.toggle}`).off('focusout');
16379
16380      base.toggleClass($(base.el), open, tnOptions.classes.show, tnOptions.classes.hide);
16381      base.$el.trigger('afterClose.tree_navigation.cms', base);
16382    }
16383    if (adjustFocus) {
16384      const $openElement = base.onMetaFixerInitialized({ data: base });
16385      if (base.options.mode === 'overlay') {
16386        const $focusElement = $openElement ? $openElement.closest('ul') : $(base.$el.find(`.${base.options.classes.anchor}`).first());
16387        base.adjustFocus($focusElement);
16388      }
16389    }
16390  },
16391
16392  setAnchorCurrentClass: function setAnchorCurrentClass(element, open) {
16393    const base = this;
16394    const tnOptions = base.options;
16395    if (tnOptions.mode === 'overlay') {
16396      base.$el.find(`.${tnOptions.classes.anchor}`).removeClass(tnOptions.cssClasses.anchor_current);
16397      if (open) {
16398        const $siblings = element.siblings(`.${tnOptions.classes.anchor}`);
16399        element.add($siblings).addClass(tnOptions.cssClasses.anchor_current);
16400      } else {
16401        const $parentAnchor = element.parent().closest(`.${tnOptions.classes.anchor}`);
16402        const $siblingAnchors = $parentAnchor.siblings(`.${tnOptions.classes.anchor}`);
16403        $parentAnchor.add($siblingAnchors).addClass(tnOptions.cssClasses.anchor_current);
16404      }
16405    }
16406  },
16407
16408  setAnchor: function setAnchor(element, open) {
16409    const base = this;
16410    const tnOptions = base.options;
16411    base.setAnchorCurrentClass(element, open); // only overlay mode
16412    base.toggleClass(element, open, tnOptions.cssClasses.anchor_opened, tnOptions.cssClasses.anchor_closed);
16413  },
16414  setButton: function setButton(button, open) {
16415    const base = this;
16416    const tnOptions = base.options;
16417    base.toggleClass(button, open, tnOptions.cssClasses.navigateToInner_opened, tnOptions.cssClasses.navigateToInner_closed);
16418    const $button = $(button);
16419
16420    $button.attr('aria-expanded', open);
16421
16422    if (tnOptions.mode === 'overlay') {
16423      if ($button.attr('disabled')) {
16424        $button.removeAttr('disabled');
16425      } else {
16426        $button.attr('disabled', 'true');
16427      }
16428    }
16429  },
16430  setNode: function setNode(node, open) {
16431    const base = this;
16432    const tnOptions = base.options;
16433    base.toggleClass(node, open, tnOptions.cssClasses.node_opened, tnOptions.cssClasses.node_closed);
16434  },
16435  toggleClassesIf: function toggleClassesIf(element, hasClass, thenElement, addClass, removeClass) {
16436    const base = this;
16437    base.toggleClass(thenElement, $(element).hasClass(hasClass), addClass, removeClass);
16438  },
16439
16440  // --------------------- methods ---------------------
16441  toggleClass: function toggleClass(element, condition, addClass, removeClass) {
16442    const base = this;
16443    if (condition) {
16444      base.setClass(element, condition, addClass, removeClass);
16445    } else {
16446      base.setClass(element, !condition, removeClass, addClass);
16447    }
16448  },
16449  setClass: function setClass(element, condition, addClass, removeClass) {
16450    if (condition) {
16451      $(element).addClass(addClass);
16452      $(element).removeClass(removeClass);
16453    }
16454  },
16455
16456  defaultOptions: {
16457    mode: 'explorer', // Der Modus in welchem das Modul laufen soll. Entweder 'explorer' oder 'overlay'
16458    openSubNavForCurrentNode: true, // Gibt an ob ein Navigationspunkt dessen Seite gerade angezeigt wird und welcher weitere Unterpunkte hat diese aufklappen soll
16459    // classes to set
16460    cssClasses: {
16461      toggleClass_opened: 'is-opened', // Klasse, die dem Menü-Trigger einer Menüebene hinzugefügt wird, wenn die Ebene sichtbar ist
16462      toggleClass_closed: 'is-closed', // Klasse, die dem Menü-Trigger einer Menüebene hinzugefügt wird, wenn die Ebene ausgeblendet ist
16463      navigateToInner_opened: 'is-opened', // Klasse, die den Buttons innerhalb von `classes.node` hinzugefügt wird, wenn die Ebene sichtbar ist
16464      navigateToInner_closed: 'is-closed', // Klasse, die den Buttons innerhalb von `classes.node` hinzugefügt wird, wenn die Ebene ausgeblendet ist
16465      node_opened: 'is-opened', // Klasse, die `classes.node` hinzugefügt wird, wenn die Ebene sichtbar ist
16466      node_closed: 'is-closed', // Klasse, die `classes.node` hinzugefügt wird, wenn die Ebene ausgeblendet ist
16467      anchor_opened: 'is-visible', // Klasse, die `classes.anchor` hinzugefügt wird, wenn die Ebene sichtbar ist
16468      anchor_closed: 'is-invisible', // Klasse, die `classes.anchor` hinzugefügt wird, wenn die Ebene ausgeblendet ist
16469      anchor_current: 'is-current' // Klasse, die `classes.anchor` hinzugefügt wird, wenn die Ebene im 'overlay' `mode` die gerade sichtbare Ebene ist
16470    },
16471    // dom nodes
16472    classes: {
16473      show: 'js-nav-mobile--visible', // Klasse, die base.$el hinzugefügt wird, wenn das Menü geöffnet ist
16474      hide: 'js-nav-mobile--hidden', // Klasse, die base.$el hinzugefügt wird, wenn das Menü geschlossen ist
16475      anchor: 'js-nav-mobile--list', // Menüebene (Liste)
16476      node: 'js-nav-mobile--node', // Einzelne Einträge einer Menüebene
16477      bodyMenuOpened: 'mobile-menu-opened', // Klasse, die body hinzugefügt wird, wenn das Menü geöffnet ist
16478      bodyMenuClosed: 'mobile-menu-closed', // Klasse, die body hinzugefügt wird, wenn das Menü geschlossen ist
16479      metaNav: 'js-meta-nav', // Selektor für die ul der metaNavigation im 'overlay' `mode`
16480      alwaysFocusable: '' // / Service-Navigation, die immer antabbar sein soll
16481    },
16482    buttonClasses: {
16483      toggle: 'js-nav-mobile--toggle', // Button zum Anzeigen/Ausblenden von dem Menü
16484      toggleOn: 'js-nav-mobile--toggleOn', // Button zum Anzeigen von dem Menü
16485      toggleOff: 'js-nav-mobile--toggleOff', // Button zum Ausblenden von dem Menü
16486      navigateToInner: 'js-nav-mobile--navigateToInner', // Button zum Navigieren zur nächsten Menüebene
16487      navigateBack: 'js-nav-mobile--back' // / Button zum Navigieren eine Menüebene zurück
16488    },
16489    states: {
16490      initStateOpen: false,
16491      navBackButton: true,
16492      navOpenOnly: false
16493    },
16494    path: {
16495      indicator: 'body',
16496      indicatorAttr: 'data-nn',
16497      nodePrefix: '#tn-'
16498    },
16499    optional: {
16500      setMaxAnchorHeight: false,
16501      anchorWrapper: '' // Selektor, falls `classes.anchor` kein direktes Kind vom `base.$el` ist muss diese Klasse auf den direkten parent von `classes.anchor` zeigen
16502    }
16503  }
16504});
16505
16506    /* Ende cms_tree_navigation */
16507    /* Start cms_form_element_visibility */
16508        "use strict";
16509function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
16510cms.makeCMSModule('cms.form_element_visibility', {
16511  init: function init() {
16512    var base = this,
16513        configs = base.options.configs || [];
16514    configs.forEach(function (config) {
16515      var control = $('#' + config.formElementId),
16516          valueConfigs = config.values || {},
16517          defaultValueConfig = config.defaultValue,
16518          checkedConfig = config.checked,
16519          uncheckedConfig = config.unchecked;
16520      var conditionalConfigs = [];
16521      if (defaultValueConfig) {
16522        conditionalConfigs.push(defaultValueConfig);
16523      }
16524      conditionalConfigs.push.apply(conditionalConfigs, _toConsumableArray(Object.values(valueConfigs)));
16525      if (uncheckedConfig) {
16526        conditionalConfigs.push(uncheckedConfig);
16527      }
16528      if (checkedConfig) {
16529        conditionalConfigs.push(checkedConfig);
16530      }
16531      conditionalConfigs.forEach(function (valueConfig) {
16532        var hideElements = valueConfig.hideElements || [],
16533            showElements = valueConfig.showElements || [],
16534            elementsToHide = [],
16535            elementsToShow = [];
16536        hideElements.forEach(function (selector) {
16537          elementsToHide.push.apply(elementsToHide, _toConsumableArray(base.$el.find(selector)));
16538        });
16539        showElements.forEach(function (selector) {
16540          elementsToShow.push.apply(elementsToShow, _toConsumableArray(base.$el.find(selector)));
16541        });
16542        valueConfig.elementsToHide = $(elementsToHide);
16543        valueConfig.elementsToShow = $(elementsToShow);
16544      });
16545      control.on('updateVisibility.' + base.eventName, {
16546        base: base,
16547        config: config
16548      }, base.updateVisibility).on('change', function (ev) {
16549        $(ev.currentTarget).trigger('updateVisibility.' + base.eventName);
16550      }).trigger('updateVisibility.' + base.eventName);
16551    });
16552  },
16553  updateVisibility: function updateVisibility(ev) {console.log("UPDATE VISIBILITY");
16554    var _ev$data = ev.data,
16555        base = _ev$data.base,
16556        config = _ev$data.config;
16557    var formElement = ev.target;
16558    var valueConfigs = config.values || {};
16559    var valueConfig = valueConfigs && valueConfigs[formElement.value] || config.defaultValue;
16560    if (valueConfig) {
16561      base.updateVisibilityByConfig(valueConfig);
16562    }
16563    if (formElement.checked === false && config.unchecked) {
16564      // do nothing if checked is falsy but not false
16565      base.updateVisibilityByConfig(config.unchecked);
16566    } else if (formElement.checked === true && config.checked) {
16567      base.updateVisibilityByConfig(config.checked);
16568    }
16569  },
16570  updateVisibilityByConfig: function updateVisibilityByConfig(config) {
16571    var base = this;
16572    base.hideElements(config);
16573    base.showElements(config);
16574  },
16575  hideElements: function hideElements(showHideConfig) {
16576    var base = this,
16577        ancestorSelector = showHideConfig.ancestor || base.options.selectors.ancestor;
16578    showHideConfig.elementsToHide.closest(ancestorSelector).hide();
16579  },
16580  showElements: function showElements(showHideConfig) {
16581    var base = this,
16582        ancestorSelector = showHideConfig.ancestor || base.options.selectors.ancestor;
16583    showHideConfig.elementsToShow.closest(ancestorSelector).show();
16584  },
16585  defaultOptions: {
16586    configs: [],
16587    selectors: {
16588      ancestor: '.row'
16589    }
16590  }
16591});
16592
16593    /* Ende cms_form_element_visibility */
16594    /* Start cms_form_utility_char_limit */
16595        /*! --GSBDocStart
16596 * @name: @cms/cms_form_utility
16597 * @version: 1.2.0
16598 * @description: [//]: # (Diesen und folgende Kommentare auf keinen Fall löschen!) [//]: # (Nur so akzeptiert license-checker die Lizenz) [//]: # (SEE LICENSE IN LICENSE-INTERNAL.txt) [//]: # (https://license-internal.txt)
16599 * --CMSDocEnd
16600*/"use strict";
16601cms.makeCMSModule('cms.form_utility_char_limit', {
16602  init: function () {
16603    const base = this;
16604    const textarea = base.el.querySelector(base.options.selectors.textarea);
16605    const countNow = base.el.querySelector(base.options.selectors.countNow);
16606    const countMax = base.el.querySelector(base.options.selectors.countMax);
16607    const countHint = base.el.querySelector(base.options.selectors.countHint);
16608    const statusDiv = base.el.querySelector(base.options.selectors.statusDiv);
16609    base.maxLength = parseInt(textarea.maxLength);
16610    countMax.textContent = base.maxLength;
16611    countNow.textContent = base.maxLength - textarea.value.length;
16612    let timeoutId;
16613
16614    textarea.setAttribute('aria-describedby', 'texthint');
16615
16616    // Status bei Eingabe verarbeiten:
16617    textarea.addEventListener('input', function () {
16618      const currentLength = textarea.value.length;
16619      const remainingLength = base.maxLength - currentLength;
16620      countNow.textContent = remainingLength;
16621      clearTimeout(timeoutId);
16622      if (currentLength === base.maxLength) {
16623        statusDiv.textContent = `${remainingLength} Zeichen übrig – Maximallänge erreicht!`;
16624        countHint.classList.add('max');
16625      } else if (currentLength === Math.round(base.maxLength / 2)) {
16626        statusDiv.textContent = `${remainingLength} Zeichen übrig – Halbzeit.`;
16627        countHint.classList.add('half');
16628      } else {
16629        const announceCountHint = () => {
16630          statusDiv.textContent = `${remainingLength} Zeichen übrig`;
16631        };
16632        timeoutId = setTimeout(announceCountHint, base.options.statusDelay);
16633        countHint.classList.remove('half', 'max');
16634      }
16635    });
16636
16637    // Tastatureingaben nach Erreichen des Maximum verarbeiten:
16638    textarea.addEventListener('keydown', function (e) {
16639      const currentLength = textarea.value.length;
16640      // Gegebenenfalls weitere Tasten als Ausnahmen aufführen.
16641      if (currentLength >= base.maxLength && !['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', `End`, `Home`, `PageUp`, `PageDown`, `Escape`, `Tab`, `PrintScreen`, `Insert`, `ContextMenu`, `F1`, `F2`, `F3`, `F4`, `F5`, `F6`, `F7`, `F8`, `F9`, `F10`, `F11`, `F12`, '
16641Shift', 'CapsLock', 'Control'].includes(e.key)) {
16642        setTimeout(() => {
16643          statusDiv.innerHTML = `<span id="${Date.now()}">Maximale Zeichenanzahl erreicht – weitere Eingaben werden ignoriert.</span>`;
16644        }, 1);
16645      }
16646    });
16647  },
16648  defaultOptions: {
16649    statusDelay: 750,
16650    selectors: {
16651      textarea: 'textarea',
16652      countNow: '.js-count_now',
16653      countMax: '.js-count_max',
16654      countHint: '.js-count_hint',
16655      statusDiv: '.js-count_out'
16656    }
16657  }
16658});
16659
16660    /* Ende cms_form_utility_char_limit */
16661})();
16662    /* Start connectFormElements */
16663        //Beispiel aus dem Prototypen
16664"use strict";
16665var cms;
16666cms = cms || {};
16667cms.connectFormElements = function () {
16668    console.log("CONNECT FORM ELEMENTS");
16669  $("form[name=KontaktformularBeschwerdeIF]").cms_form_element_visibility({
16670    selectors: { "ancestor": "span" },
16671    configs: [{
16672      formElementId: "f18930934g18993284d18993304i1",
16673      unchecked: {
16674        ancestor: "#beschwerde_strafanzeige",
16675        hideElements: ["#f18930934d18991786"]
16676      },
16677      checked: {
16678        ancestor: "#beschwerde_strafanzeige",
16679        hideElements: ["#f18930934d18991786"]
16680      }
16681    }, {
16682      formElementId: "f18930934g18993284d18993306i2",
16683      unchecked: {
16684        ancestor: "#beschwerde_strafanzeige",
16685        hideElements: ["#f18930934d18991786"]
16686      },
16687      checked: {
16688        ancestor: "#beschwerde_strafanzeige",
16689        showElements: ["#f18930934d18991786"]
16690      }
16691    }, {
16692      formElementId: "f18930934g18993290d18993304i1",
16693      unchecked: {
16694        ancestor: "#beschwerde_vorgang",
16695        hideElements: ["#f18930934d18991796"]
16696      },
16697      checked: {
16698        ancestor: "#beschwerde_vorgang",
16699        hideElements: ["#f18930934d18991796"]
16700      }
16701    }, {
16702      formElementId: "f18930934g18993290d18993306i2",
16703      unchecked: {
16704        ancestor: "#beschwerde_vorgang",
16705        hideElements: ["#f18930934d18991796"]
16706      },
16707      checked: {
16708        ancestor: "#beschwerde_vorgang",
16709        showElements: ["#f18930934d18991796"]
16710      }
16711    }]
16712  });
16713  $("form[name=KontaktformularFintech]").cms_form_element_visibility({
16714    selectors: { "ancestor": "span" },
16715    configs: [{
16716      formElementId: "f7881780g18388134d18388186i1",
16717      unchecked: {
16718        ancestor: "#fintech_partner_container",
16719        hideElements: ["#f7881780d7897202"]
16720      },
16721      checked: {
16722        ancestor: "#fintech_partner_container",
16723        hideElements: ["#f7881780d7897202"]
16724      }
16725    }, {
16726      formElementId: "f7881780g18388134d18388214i2",
16727      unchecked: {
16728        ancestor: "#fintech_partner_container",
16729        hideElements: ["#f7881780d7897202"]
16730      },
16731      checked: {
16732        ancestor: "#fintech_partner_container",
16733        showElements: ["#f7881780d7897202"]
16734      }
16735    }, {
16736      formElementId: "f7881780g12301186d7894900i1",
16737      unchecked: {
16738        hideElements: ["#f7881780g12301186d18382678i2", "#f7881780g12301186d18382680i3", "#f7881780g12301186d18382682i4", "#f7881780g12301186d18382684i5"]
16739      },
16740      checked: {
16741        showElements: ["#f7881780g12301186d18382678i2", "#f7881780g12301186d18382680i3", "#f7881780g12301186d18382682i4", "#f7881780g12301186d18382684i5"]
16742      }
16743    }, {
16744      formElementId: "f7881780g12301186d12271448i6",
16745      unchecked: {
16746        hideElements: ["#f7881780g12301186d18382696i7", "#f7881780g12301186d18382700i8", "#f7881780g12301186d18382702i9", "#f7881780g12301186d18382704i10", "#f7881780g12301186d18382706i11", "#f7881780g12301186d18382698i12"]
16747      },
16748      checked: {
16749        showElements: ["#f7881780g12301186d18382696i7", "#f7881780g12301186d18382700i8", "#f7881780g12301186d18382702i9", "#f7881780g12301186d18382704i10", "#f7881780g12301186d18382706i11", "#f7881780g12301186d18382698i12"]
16750      }
16751    }, {
16752      formElementId: "f7881780g12301186d18382618i18",
16753      unchecked: {
16754        hideElements: ["#f7881780g12301186d7894908i19", "#f7881780g12301186d7894910i20"]
16755      },
16756      checked: {
16757        showElements: ["#f7881780g12301186d7894908i19", "#f7881780g12301186d7894910i20"]
16758      }
16759    }, {
16760      formElementId: "f7881780g12301186d18382624i21",
16761      unchecked: {
16762        hideElements: ["#f7881780g12301186d18382724i22", "#f7881780g12301186d18382726i23", "#f7881780g12301186d18382728i24", "#f7881780g12301186d18382730i25", "#f7881780g12301186d18382732i26"]
16763      },
16764      checked: {
16765        showElements: ["#f7881780g12301186d18382724i22", "#f7881780g12301186d18382726i23", "#f7881780g12301186d18382728i24", "#f7881780g12301186d18382730i25", "#f7881780g12301186d18382732i26"]
16766      }
16767    }, {
16768      formElementId: "f18519598g18388134d18388186i1",
16769      unchecked: {
16770        ancestor: "#fintech_partner_container",
16771        hideElements: ["#f18519598d7897202"]
16772      },
16773      checked: {
16774        ancestor: "#fintech_partner_container",
16775        hideElements: ["#f18519598d7897202"]
16776      }
16777    }, {
16778      formElementId: "f18519598g18388134d18388214i2",
16779      unchecked: {
16780        ancestor: "#fintech_partner_container",
16781        hideElements: ["#f18519598d7897202"]
16782      },
16783      checked: {
16784        ancestor: "#fintech_partner_container",
16785        showElements: ["#f18519598d7897202"]
16786      }
16787    }, {
16788      formElementId: "f18519598g12301186d7894900i1",
16789      unchecked: {
16790        hideElements: ["#f18519598g12301186d18382678i2", "#f18519598g12301186d18382680i3", "#f18519598g12301186d18382682i4", "#f18519598g12301186d18382684i5"]
16791      },
16792      checked: {
16793        showElements: ["#f18519598g12301186d18382678i2", "#f18519598g12301186d18382680i3", "#f18519598g12301186d18382682i4", "#f18519598g12301186d18382684i5"]
16794      }
16795    }, {
16796      formElementId: "f18519598g12301186d12271448i6",
16797      unchecked: {
16798        hideElements: ["#f18519598g12301186d18382696i7", "#f18519598g12301186d18382700i8", "#f18519598g12301186d18382702i9", "#f18519598g12301186d18382704i10", "#f18519598g12301186d18382706i11", "#f18519598g12301186d18382698i12"]
16799      },
16800      checked: {
16801        showElements: ["#f18519598g12301186d18382696i7", "#f18519598g12301186d18382700i8", "#f18519598g12301186d18382702i9", "#f18519598g12301186d18382704i10", "#f18519598g12301186d18382706i11", "#f18519598g12301186d18382698i12"]
16802      }
16803    }, {
16804      formElementId: "f18519598g12301186d18382618i18",
16805      unchecked: {
16806        hideElements: ["#f18519598g12301186d7894908i19", "#f18519598g12301186d7894910i20"]
16807      },
16808      checked: {
16809        showElements: ["#f18519598g12301186d7894908i19", "#f18519598g12301186d7894910i20"]
16810      }
16811    }, {
16812      formElementId: "f18519598g12301186d18382624i21",
16813      unchecked: {
16814        hideElements: ["#f18519598g12301186d18382724i22", "#f18519598g12301186d18382726i23", "#f18519598g12301186d18382728i24", "#f18519598g12301186d18382730i25", "#f18519598g12301186d18382732i26"]
16815      },
16816      checked: {
16817        showElements: ["#f18519598g12301186d18382724i22", "#f18519598g12301186d18382726i23", "#f18519598g12301186d18382728i24", "#f18519598g12301186d18382730i25", "#f18519598g12301186d18382732i26"]
16818      }
16819    }]
16820  });
16821  $("form[name=KontaktformularHGS]").cms_form_element_visibility({
16822    selectors: { "ancestor": ".optional" },
16823    configs: [{
16824      formElementId: "f19667066g19666938d19673202i2",
16825      checked: {
16826        ancestor: "#Kontaktdaten",
16827        showElements: ["#f19667066d19667052"]
16828      }
16829    }, {
16830      formElementId: "f19667066g19666938d19673204i1",
16831      checked: {
16832        ancestor: "#Kontaktdaten",
16833        hideElements: ["#f19667066d19667052"]
16834      }
16835    }, {
16836      formElementId: "f19667066g19666950d19673202i2",
16837      checked: {
16838        showElements: ["#f19667066d19667012"]
16839      }
16840    }, {
16841      formElementId: "f19667066g19666950d19673204i1",
16842      checked: {
16843        hideElements: ["#f19667066d19667012"]
16844      }
16845    }, {
16846      formElementId: "f19667066g19666930d19673202i1",
16847      checked: {
16848        showElements: ["#f19667066d19666988"]
16849      }
16850    }, {
16851      formElementId: "f19667066g19666930d19573636i2",
16852      checked: {
16853        hideElements: ["#f19667066d19666988"]
16854      }
16855    }, {
16856      formElementId: "f19667066g19666946d19673202i2",
16857      checked: {
16858        showElements: ["#f19667066d19667016"]
16859      }
16860    }, {
16861      formElementId: "f19667066g19666946d19673204i1",
16862      checked: {
16863        hideElements: ["#f19667066d19667016"]
16864      }
16865    }, {
16866      formElementId: "f19667066g19666934d19673202i2",
16867      checked: {
16868        showElements: ["#f19667066d19667008"]
16869      }
16870    }, {
16871      formElementId: "f19667066g19666934d19673204i1",
16872      checked: {
16873        hideElements: ["#f19667066d19667008"]
16874      }
16875    }, {
16876      formElementId: "f19667066g19666942d19666956i1",
16877      checked: {
16878        showElements: ["#bankenaufsicht-hint", "#group_desc", "#form-contact", "#next"],
16879        hideElements: ["#versicherungsaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16880      }
16881    }, {
16882      formElementId: "f19667066g19666942d19666970i2",
16883      checked: {
16884        showElements: ["#versicherungsaufsicht-hint", "#group_desc", "#form-contact", "#next"],
16885        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16886      }
16887    }, {
16888      formElementId: "f19667066g19666942d19666972i3",
16889      checked: {
16890        showElements: ["#wertpapieraufsicht-hint", "#group_desc", "#form-contact", "#next"],
16891        hideElements: ["#bankenaufsicht-hint", "#versicherungsaufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16892      }
16893    }, {
16894      formElementId: "f19667066g19666942d19666966i4",
16895      checked: {
16896        showElements: ["#markmanipulation-hint", "#group_desc", "#form-contact", "#next"],
16897        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#versicherungsaufsicht-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16898      }
16899    }, {
16900      formElementId: "f19667066g19666942d19666962i5",
16901      checked: {
16902        showElements: ["#geldwaeschepraevention-hint", "#group_desc", "#form-contact", "#next"],
16903        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#versicherungsaufsicht-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16904      }
16905    }, {
16906      formElementId: "f19667066g19666942d19666968i6",
16907      checked: {
16908        showElements: ["#unerlaubte_geschaefte-hint", "#group_desc", "#form-contact", "#next"],
16909        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#versicherungsaufsicht-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16910      }
16911    }, {
16912      formElementId: "f19667066g19666942d19666960i7",
16913      checked: {
16914        showElements: ["#enforcement-hint", "#group_desc", "#form-contact", "#next"],
16915        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#versicherungsaufsicht-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16916      }
16917    }, {
16918      formElementId: "f19667066g19666942d19666958i8",
16919      checked: {
16920        showElements: ["#dma-hint"],
16921        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#versicherungsaufsicht-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint", "#group_desc", "#form-contact", "#next"]
16922      }
16923    }, {
16924      formElementId: "f19667066g19666942d19666954i9",
16925      checked: {
16926        showElements: ["#anderer_schwerpunkt-hint"],
16927        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#versicherungsaufsicht-hint", "#kundenbeziehung-hint", "#group_desc", "#form-contact", "#next"]
16928      },
16929    }, {
16930      formElementId: "f19667066g19666942d19666964i10",
16931      checked: {
16932        showElements: ["#kundenbeziehung-hint"],
16933        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#versicherungsaufsicht-hint", "#group_desc", "#form-contact", "#next"]
16934      }
16935    }, {
16936      formElementId: "f19704388g19666938d19673202i2",
16937      checked: {
16938        ancestor: "#Kontaktdaten",
16939        showElements: ["#f19704388d19667052"]
16940      }
16941    }, {
16942      formElementId: "f19704388g19666938d19673204i1",
16943      checked: {
16944        ancestor: "#Kontaktdaten",
16945        hideElements: ["#f19704388d19667052"]
16946      }
16947    }, {
16948      formElementId: "f19704388g19666950d19673202i2",
16949      checked: {
16950        showElements: ["#f19704388d19667012"]
16951      }
16952    }, {
16953      formElementId: "f19704388g19666950d19673204i1",
16954      checked: {
16955        hideElements: ["#f19704388d19667012"]
16956      }
16957    }, {
16958      formElementId: "f19704388g19666930d19673202i1",
16959      checked: {
16960        showElements: ["#f19704388d19666988"]
16961      }
16962    }, {
16963      formElementId: "f19704388g19666930d19573636i2",
16964      checked: {
16965        hideElements: ["#f19704388d19666988"]
16966      }
16967    }, {
16968      formElementId: "f19704388g19666946d19673202i2",
16969      checked: {
16970        showElements: ["#f19704388d19667016"]
16971      }
16972    }, {
16973      formElementId: "f19704388g19666946d19673204i1",
16974      checked: {
16975        hideElements: ["#f19704388d19667016"]
16976      }
16977    }, {
16978      formElementId: "f19704388g19666934d19673202i2",
16979      checked: {
16980        showElements: ["#f19704388d19667008"]
16981      }
16982    }, {
16983      formElementId: "f19704388g19666934d19673204i1",
16984      checked: {
16985        hideElements: ["#f19704388d19667008"]
16986      }
16987    }, {
16988      formElementId: "f19704388g19666942d19666956i1",
16989      checked: {
16990        showElements: ["#bankenaufsicht-hint", "#group_desc", "#form-contact", "#next"],
16991        hideElements: ["#versicherungsaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16992      }
16993    }, {
16994      formElementId: "f19704388g19666942d19666970i2",
16995      checked: {
16996        showElements: ["#versicherungsaufsicht-hint", "#group_desc", "#form-contact", "#next"],
16997        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
16998      }
16999    }, {
17000      formElementId: "f19704388g19666942d19666972i3",
17001      checked: {
17002        showElements: ["#wertpapieraufsicht-hint", "#group_desc", "#form-contact", "#next"],
17003        hideElements: ["#bankenaufsicht-hint", "#versicherungsaufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
17004      }
17005    }, {
17006      formElementId: "f19704388g19666942d19666966i4",
17007      checked: {
17008        showElements: ["#markmanipulation-hint", "#group_desc", "#form-contact", "#next"],
17009        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#versicherungsaufsicht-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
17010      }
17011    }, {
17012      formElementId: "f19704388g19666942d19666962i5",
17013      checked: {
17014        showElements: ["#geldwaeschepraevention-hint", "#group_desc", "#form-contact", "#next"],
17015        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#versicherungsaufsicht-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
17016      }
17017    }, {
17018      formElementId: "f19704388g19666942d19666968i6",
17019      checked: {
17020        showElements: ["#unerlaubte_geschaefte-hint", "#group_desc", "#form-contact", "#next"],
17021        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#versicherungsaufsicht-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
17022      }
17023    }, {
17024      formElementId: "f19704388g19666942d19666960i7",
17025      checked: {
17026        showElements: ["#enforcement-hint", "#group_desc", "#form-contact", "#next"],
17027        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#versicherungsaufsicht-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"]
17028      }
17029    }, {
17030      formElementId: "f19704388g19666942d19666958i8",
17031      checked: {
17032        showElements: ["#dma-hint"],
17033        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#versicherungsaufsicht-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint", "#group_desc", "#form-contact", "#next"]
17034      }
17035    }, {
17036      formElementId: "f19704388g19666942d19666954i9",
17037      checked: {
17038        showElements: ["#anderer_schwerpunkt-hint"],
17039        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#versicherungsaufsicht-hint", "#kundenbeziehung-hint", "#group_desc", "#form-contact", "#next"]
17040      }
17041    }, {
17042      formElementId: "f19704388g19666942d19666964i10",
17043      checked: {
17044        showElements: ["#kundenbeziehung-hint"],
17045        hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#versicherungsaufsicht-hint", "#group_desc", "#form-contact", "#next"]
17046      }
17047    }
17048    ]
17049  });
17050 $("form[name=Kontaktformular-Marktmanipulation]").cms_form_element_visibility({
17051    selectors: { "ancestor": ".optional" },
17052    configs: [{
17053      formElementId: "f239186g239160d241496i1",
17054      checked: {
17055        showElements: ["#Marktmanipulation_Sachverhalt-hint"],
17056        hideElements: ["#Marktmanipulation_hinweisgberschutz-hint"]
17057      }
17058    },
17059 {
17060      formElementId: "f239186g239160d241488i2",
17061      checked: {
17062        showElements: ["#Marktmanipulation_hinweisgberschutz-hint"],
17063        hideElements: ["#Marktmanipulation_Sachverhalt-hint"]
17064      }
17065    }
17066    ]
17067  });
17068 $("form[name=Kontaktformular-UnerlaubteGeschaefte]").cms_form_element_visibility({
17069    selectors: { "ancestor": ".optional" },
17070    configs: [{
17071      formElementId: "f770866g770976d770984i1",
17072      checked: {
17073        showElements: ["#Marktmanipulation_Sachverhalt-hint"],
17074        hideElements: ["#Marktmanipulation_hinweisgberschutz-hint"]
17075      }
17076    },
17077 {
17078      formElementId: "f770866g770976d770980i2",
17079      checked: {
17080        showElements: ["#Marktmanipulation_hinweisgberschutz-hint"],
17081        hideElements: ["#Marktmanipulation_Sachverhalt-hint"]
17082      }
17083    }
17084    ]
17085  });
17086};
17087cms.connectFormElements();
17088
17089    /* Ende connectFormElements */
17090    /* Start init */
17091        "use strict"; // noinspection ES6ConvertVarToLetConst, JSUnusedGlobalSymbols
17092$(function () {
17093  const $body = $('body'),$html = $('html'),
17094    $content = $('.content');
17095
17096  const minBreakpoint = 1,
17097    mediumBreakpoint = 768,
17098    largeBreakpoint = 1025,
17099    xLargeBreakpoint = 1439,
17100    xxLargeBreakpoint = 1919;
17101
17102  // header-height slim
17103  $body.css('--header-height', `${$('.js-headerheight').outerHeight()}px`);
17104  window.addEventListener('resize', () => {
17105    $body.css('--header-height', `${$('.js-headerheight').outerHeight()}px`);
17106  });
17107
17108  // Deaktivierung von Animationen für automatisierte Tests (Backstop, Cypress, ...)
17109  if (typeof document.cookie !== 'undefined' && document.cookie.match('testmode')) {
17110    $.fx.off = true;
17111    $body.addClass('no-transition');
17112  }
17113
17114  $body.addClass('js-on').removeClass('js-off');
17115
17116  // BITV: Alle Flyouts, die über hover angezeigt werden, müssen
17117  // anderweitig (hier: über Esc) schließbar sein
17118  $body.on('keydown', function (ev) {
17119    const key = ev.key;
17120    if (key === 'Esc' || key === 'Escape') {
17121      $body.trigger('closeAllFlyouts.cms');
17122    }
17123  });
17124  $body.on('closeAllFlyouts.cms', function () {
17125    $body.find('.mejs__captions-selector').not('.mejs__offscreen').
17126    addClass('mejs__offscreen');
17127    $body.find('.mejs__volume-slider').not(':hidden').
17128    hide();
17129  });
17130
17131  function getAllNextNodes(node) {
17132    const result = [];
17133    let next;
17134    while (next = node.nextSibling) {
17135      result.push(next);
17136      node = next;
17137    }
17138    return result;
17139  }
17140
17141  const randnummerAuralLabel = "Randnummer";
17142  $('.js-randnummer').each((i, nummer) => {
17143    const $nummer = $(nummer);
17144    const $content = $(document.createElement('span'));
17145    const $container = $nummer.parent();
17146    $nummer.
17147    attr({
17148      'aria-label': `${randnummerAuralLabel}: ${$nummer.text()}`,
17149      title: `${randnummerAuralLabel}: ${$nummer.text()}`
17150    }).
17151    wrapInner($(document.createElement('span')).attr('aria-hidden', 'true'));
17152    $nummer.after($content.append(getAllNextNodes(nummer)).addClass('c-randnummer__content'));
17153    $container.addClass('c-randnummer__container');
17154  });
17155
17156  const $loadNavigation = $('[data-navigation-url]');
17157  const fetchURL = $loadNavigation.data('navigation-url');
17158  if (fetchURL) {
17159    fetch(fetchURL).then((res) => res.text()).then((html) => {
17160      $loadNavigation.html(html);
17161
17162      let path = $('[data-navigation-nn-path]').data('navigation-nn-path').split('/');
17163      path.forEach((id) =>
17164      $(`[data-navigation-nn="${id}"]`).children('a, button, strong').attr("aria-current", "true")
17165      );
17166      $(`[data-navigation-nn="${path.pop()}"]`).children('a, button, strong').attr("aria-current", "page");
17167
17168      // Flyout
17169      $('.js-flyout-nav-level1-tabs-list').cms_toggle({
17170        elements: '> .js-flyout-nav-level1 .js-flyout-button-level1 + .js-flyout-level1',
17171        heading: '> .js-flyout-nav-level1 .js-flyout-button-level1',
17172        mode: 'accordion',
17173        responsive: [{
17174          breakpoint: 1026,
17175          mode: 'none'
17176        }]
17177      });
17178
17179      const $searchFlyout = $('.js-flyout-search');
17180
17181      // Suchflyout
17182      $searchFlyout.cms_simple_toggle({
17183        item: '.js-flyout-search-item',
17184        opener: '.js-flyout-search-button',
17185        closeOnFocusout: true
17186      });
17187
17188      // Flyout Level 2
17189      $('.js-flyout-nav-level2').cms_simple_toggle({
17190        item: '.js-flyout-level2',
17191        opener: '.js-flyout-button-level2',
17192        closeOnFocusout: true
17193      });
17194
17195      // Flyout Level 3
17196      $('.js-flyout-nav-level3').cms_simple_toggle({
17197        item: '.js-flyout-level3',
17198        opener: '.js-flyout-button-level3',
17199        closeOnFocusout: true
17200      });
17201
17202      // navSkip öffnet die Suche in der Primärnavigation und fokussiert das Eingabefeld
17203      $('.js-navskip-search').on('click', function (ev) {
17204        ev.preventDefault();
17205        $searchFlyout.trigger('open');
17206        $searchFlyout.find('input[type="search"]').trigger('focus');
17207      });
17208
17209      // Beim Öffnen der Suche über den Button in der Primärnavigation, setze Fokus ins Eingabefeld
17210      $searchFlyout.on('afterOpen.simple_toggle.cms', function (ev) {
17211        const menuToggle = $('.js-nav-mobile--toggle');
17212        const triggeringEvent = ev.relatedEvent;
17213        const triggeringElement = $(triggeringEvent.target).closest('button');
17214        if (menuToggle.is('[aria-expanded="true"]')) {
17215          menuToggle.click();
17216        }
17217        if (triggeringElement.is('[aria-expanded="true"]')) {
17218          $searchFlyout.find('input[type="search"]').trigger('focus');
17219        }
17220      });
17221
17222      // Mobile Navigation
17223      $('.js-nav-mobile').cms_tree_navigation({
17224        mode: 'overlay',
17225        classes: {
17226          bodyMenuOpened: 's-mobile-menu-opened',
17227          bodyMenuClosed: 's-mobile-menu-closed'
17228        }
17229      });
17230    });
17231  }
17232
17233  //Open Details if anchored element is within
17234  $(`${window.location.hash}`).parents('details').attr('open', 'open');
17235
17236  $content.cms_responsiveTables();
17237
17238  /* Scroll check for tables. */
17239  const responsiveTableClass = '.l-responsive-table';
17240  const tableContainers = document.querySelectorAll(responsiveTableClass);
17241
17242  // Add wrapper element
17243  function create_responsive_table_wrapper(table_container) {
17244    const wrapper_div = document.createElement('div');
17245    wrapper_div.classList.add('l-responsive-table__wrapper');
17246
17247    const scroll_clone_div = document.createElement('div');
17248    scroll_clone_div.classList.add('responsiveTableScrollClone');
17249    scroll_clone_div.setAttribute('tabindex', '-1');
17250    wrapper_div.appendChild(scroll_clone_div);
17251
17252    const table_clone_div = document.createElement('div');
17253    table_clone_div.classList.add('responsiveTableClone');
17254    table_clone_div.style.width = `${table_container.querySelector('table').getBoundingClientRect().width}px`;
17255    scroll_clone_div.appendChild(table_clone_div);
17256
17257    // Erstellen Sie eine Kopie des table_container, bevor Sie es entfernen
17258    const table_container_copy = table_container.cloneNode(true);
17259    wrapper_div.appendChild(table_container_copy);
17260
17261    // Ersetzen Sie das ursprüngliche table_container durch das wrapper_div
17262    table_container.parentNode.replaceChild(wrapper_div, table_container);
17263
17264    return wrapper_div;
17265  }
17266
17267  function syncScroll(element1, element2) {
17268    function scrollHandler(event) {
17269      if (event.target === element1) {
17270        element2.scrollTo(element1.scrollLeft, 0);
17271      } else {
17272        element1.scrollTo(element2.scrollLeft, 0);
17273      }
17274    }
17275
17276    $(element1).on('scroll', scrollHandler);
17277    $(element2).on('scroll', scrollHandler);
17278  }
17279
17280  function scrollState(containerSelector) {
17281    const containers = document.querySelectorAll(containerSelector);
17282    containers.forEach((element) => {
17283      if (element.scrollWidth <= element.clientWidth) {
17284        element.classList.remove('is-scroll-right', 'is-scroll-left');
17285      } else if (element.scrollLeft === 0) {
17286        element.classList.remove('is-scroll-left');
17287        element.classList.add('is-scroll-right');
17288      } else if (element.scrollLeft + element.clientWidth >= element.scrollWidth) {
17289        element.classList.remove('is-scroll-right');
17290        element.classList.add('is-scroll-left');
17291      } else {
17292        element.classList.add('is-scroll-left', 'is-scroll-right');
17293      }
17294    });
17295  }
17296
17297  document.addEventListener('DOMContentLoaded', () => {
17298    scrollState(responsiveTableClass);
17299  });
17300  window.addEventListener('resize', () => {
17301    scrollState(responsiveTableClass);
17302  });
17303
17304  // Erstelle Wrapper und synchronisiere den Scroll für jede Tabelle
17305  tableContainers.forEach((table_container) => {
17306    const wrapper = create_responsive_table_wrapper(table_container);
17307    const scroll_clone = wrapper.querySelector('.responsiveTableScrollClone');
17308    const table = wrapper.querySelector('.l-responsive-table');
17309    syncScroll(scroll_clone, table);
17310
17311    table.addEventListener('scroll', () => {
17312      scrollState(responsiveTableClass);
17313    });
17314  });
17315
17316  const $videoAudio = $('video, audio');
17317  const $notVimeo = $videoAudio.filter((index, el) => $(el).find('source[type|="video/vimeo"]').length < 1);
17318  const $vimeo = $videoAudio.filter((index, el) => $(el).find('source[type|="video/vimeo"]').length > 0);
17319
17320  cms.requireCMSComponent('bundle_multimedia', $notVimeo).done(function ($media) {
17321    $media.cms_multimedia({
17322      settings: {
17323        mediaelementplayerOptions: {
17324          iconSprite: $media.attr('data-icons-controls'),
17325          iconSpritePathA11y: $media.attr('data-icons-a11y')
17326        }
17327      }
17328    });
17329  });
17330
17331  cms.requireCMSComponent('bundle_multimedia', $vimeo).done(function ($media) {
17332    $media.cms_multimedia({
17333      settings: {
17334        mediaelementplayerOptions: {
17335          features: ''
17336        }
17337      }
17338    });
17339  });
17340
17341  const $cookiebanner = $('#cookiebanner');
17342
17343  // cookiebanner
17344  $cookiebanner.cms_cookiebanner({
17345    selectors: {
17346      dialog: '#cookiebanner'
17347    },
17348    modal: true,
17349    cookies: {
17350      neccessary: {
17351        off: () => {
17352          document.cookie = 'cmsbanner=closed; path=/';
17353        }
17354      },
17355      statistics: {
17356        on: 'matomo',
17357        off: 'matomo'
17358      }
17359    }
17360  }).on('open', updateCookieBanner).on('close', updateCookieBanner);
17361
17362  //prevent Scrolling when cookiebanner is opened
17363  updateCookieBanner();
17364
17365  function updateCookieBanner() {
17366    if ($cookiebanner.attr('open')) {
17367      $html.css({ 'overflow': 'hidden', 'scrollbar-gutter': 'stable' });
17368    } else {
17369      $html.css({ 'overflow': 'initial' });
17370    }
17371  }
17372
17373  $('.js-toc').cms_simple_toggle({
17374    item: '.js-toc__list',
17375    opener: '.js-toc__button',
17376    closeOnFocusout: true
17377  });
17378
17379  $('.js-toc-module').cms_simple_toggle({
17380    item: '> .js-toc-module__list',
17381    opener: '> .js-toc-module__button',
17382    closeOnFocusout: true
17383  });
17384
17385  // scroll service nav into view
17386  $('.c-nav-service-meta a').on('focusin', function () {
17387    if ($('.js-header').hasClass('is-sticky')) {
17388      window.scrollTo({ top: 0, behavior: 'smooth' });
17389    }
17390  });
17391
17392  // Richtext-Accordion
17393  $content.cms_toggle({
17394    richtext: true,
17395    richtextWrapper: '<div class="c-richtext-accordion"/>',
17396    richtextStart: '.js-richtext-accordion-start',
17397    richtextEnd: '.js-richtext-accordion-end',
17398    richtextControl: '.c-richtext-accordion__opener',
17399    heading: '.c-richtext-accordion__opener',
17400    responsive: null,
17401    accordionCloseOther: false
17402  }).on('afterAnimationOpen.toggle.cms', function () {
17403    var tabelWidth = $(this).find('.c-richtext-accordion table').width();
17404    $(this).find('.c-richtext-accordion .responsiveTableClone').css('width', tabelWidth);
17405  });
17406
17407  // richtext-tab-accordion
17408  $content.cms_toggle({
17409    mode: 'tabs',
17410    richtext: true,
17411    richtextWrapper: '<div class="c-richtext-tab-accordion"/>',
17412    richtextStart: '.js-richtext-tab-accordion-start',
17413    richtextEnd: '.js-richtext-tab-accordion-end',
17414    richtextControl: '.js-richtext-tab-accordion__opener',
17415    richtextTabControlContainerItem: '<li class="c-richtext-tab-accordion__item"></li>',
17416    richtextTabControlContainer: '<ul class="c-richtext-tab-accordion__list tabs-list"></ul>',
17417    responsive: [{
17418      breakpoint: largeBreakpoint,
17419      mode: 'accordion'
17420    }]
17421  });
17422
17423  // Accordions (z.B. Footer)
17424  $('.js-accordion-footer').cms_toggle({
17425    accordionCloseOther: false,
17426    elements: '.js-accordion-footer-entry',
17427    heading: '.js-accordion-footer-opener',
17428    accordionContainer: '.js-accordion-footer-container'
17429  });
17430
17431  // Accordions (z.B. Glossar)
17432  $('.js-accordion').cms_toggle({
17433    accordionCloseOther: false,
17434    elements: '.js-accordion-entry',
17435    heading: '.js-accordion-opener',
17436    accordionContainer: '.js-accordion-container'
17437  });
17438
17439  // c-related
17440  $('.js-related').cms_toggle({
17441    hashControlled: true,
17442    accordionCloseOther: false,
17443    elements: '.js-related-entry',
17444    heading: '.js-related-opener',
17445    accordionContainer: '.js-related__list'
17446  });
17447
17448  // HashControlled-Accordions (z.B. FAQList)
17449  $('.js-accordion-hashControlled').cms_toggle({
17450    hashControlled: true,
17451    accordionCloseOther: false,
17452    elements: '.js-accordion-entry',
17453    heading: '.js-accordion-opener',
17454    accordionContainer: '.js-accordion-container'
17455  });
17456
17457  // cms_toggle without hashControl
17458  $('.js-tabs').cms_toggle({
17459    mode: 'tabs',
17460    tabControls: '> .tabs-list > li button',
17461    responsive: [{
17462      breakpoint: largeBreakpoint,
17463      mode: 'accordion'
17464    }],
17465    accordionCloseOther: false
17466  });
17467
17468  //Richtext-Accordion mit OpenGraphTags versehen
17469  $('.c-richtext-accordion').each(function (i, accordion) {
17470    const $accordion = $(accordion);
17471    $accordion.attr('itemscope', '').attr('itemtype', 'https://schema.org/FAQPage');
17472    $accordion.find('.c-richtext-accordion__opener').each(function (j, el) {
17473      const question = $(el);
17474      question.find('button').attr('itemprop', 'name');
17475      question.next('div').attr('itemscope', '').attr('itemprop', 'acceptedAnswer').attr('itemtype', 'https://schema.org/Answer').
17476      find('p').first().attr('itemprop', 'text');
17477      const content = question.nextUntil('.c-richtext-accordion__opener').add(question);
17478      content.wrapAll('<div itemScope itemProp="mainEntity" itemType="https://schema.org/Question"></div>');
17479    });
17480  });
17481
17482  // Drucken
17483  $('.js-print').on('click', function (e) {
17484    e.preventDefault();
17485    window.print();
17486  });
17487
17488  // Share
17489  $('.js-share').cms_simple_toggle({
17490    opener: '.js-share-button',
17491    item: '.js-share-box',
17492    showClass: 'visible',
17493    hideClass: 'invisible',
17494    closeOnFocusout: true
17495  });
17496
17497  // AutoSuggest
17498  $('.js-autosuggest').cms_autosuggest();
17499
17500  // Suche - Facetten & Sortierung
17501  $('.js-facet, .js-sort').cms_simple_toggle();
17502
17503  // Schließt alle details/summary bei Escape
17504  document.addEventListener('keydown', function (event) {
17505    if (event.key === 'Escape') {
17506      // Alle offenen <details>-Elemente finden
17507      document.querySelectorAll('details[open]').forEach(function (details) {
17508        details.removeAttribute('open');
17509      });
17510    }
17511  });
17512
17513  // Schließt bestimmte geöffnete details/summary bei focusout
17514  document.addEventListener('focusout', function (event) {
17515    const details = event.target.closest('details.js-close-on-blur');
17516    if (!details) return;
17517
17518    setTimeout(function () {
17519      const next = document.activeElement;
17520      if (!next || !details.contains(next)) {
17521        details.removeAttribute('open');
17522      }
17523    }, 0);
17524  });
17525
17526  // scroll-control
17527  $html.cms_scroll_control({
17528    cookiebannerAnimationDuration: 900, // gsb_banner.options.animationSpeed ist auch 900
17529    scrollAnimationDuration: 600,
17530    scrollOnPageLoad: true,
17531    scrollOnAnchorLinkClick: true,
17532    scrollOffset: function () {
17533      return 100;
17534    },
17535    selectors: {
17536      anchorLinks: 'a[href*="#"]:not([href="#"]):not(.hash-controlled)',
17537      cookiebanner: '#c-cookiebanner' // Berücksichtigen des cookiebanners, verwendet cookiebannerAnimationDuration
17538    }
17539  });
17540
17541  // Formular - bei Fehlern im Formular zum ersten Fehlerlink springen
17542  const $formErrors = $('.js-error-list');
17543  if ($formErrors.length > 0) {
17544    setTimeout(function () {
17545      $formErrors.first().get(0).scrollIntoView();
17546      $($formErrors.find('a').first()).focus().select();
17547    });
17548  } else {
17549    const $errorInput = $('[aria-invalid=true]').first();
17550    if ($errorInput.length) {
17551      setTimeout(function () {
17552        $errorInput.get(0).scrollIntoView();
17553        $errorInput.focus();
17554      });
17555    }
17556  }
17557
17558  // Formular
17559  $('.js-char-count').cms_form_utility_char_limit();
17560
17561  //echarts
17562  $('.js-simple-toggle').cms_simple_toggle();
17563
17564  function eChartInit() {
17565    if (cms.chartConfigs) {
17566      cms.requireCMSComponent('bundle_echarts', $('.js-chart')).done(function ($charts) {
17567        $charts.each((i, el) => {
17568          const $chart = $(el);
17569          const variant = $chart.attr('data-chart-variant');
17570          const theme = $chart.attr('data-chart-theme');
17571          const themeDark = `${theme}-dark`;
17572
17573          if (cms.chartConfigs[variant]) {
17574            $chart.cms_echarts({
17575              libConfig: cms.chartConfigs[variant],
17576              themes: {
17577                default: theme,
17578                darkMode: themeDark
17579              }
17580            });
17581          } else {
17582            throw Error(
17583              `Keine Konfig für die Diagramm-Variante '${variant}' gefunden. Bitte prüfe,` +
17584              ' ob die Konfiguration im Browser geladen wird und' +
17585              ' ob der "Glue"-Code um den Beispiel-Code herum (a) vorhanden ist und (b) korrekt ist'
17586            );
17587          }
17588        });
17589      });
17590    }
17591  }
17592
17593  eChartInit();
17594
17595  // Slider Numbers
17596  cms.requireCMSComponent('bundle_slideshow', $('.js-carousel, .js-carousel-dialog')).done(function ($jsCarousel) {
17597    $jsCarousel.each(function () {
17598      const base = $(this);
17599      const slides = {
17600        small: Number.parseInt($(this).attr('data-small-slides')),
17601        medium: Number.parseInt($(this).attr('data-medium-slides')),
17602        large: Number.parseInt($(this).attr('data-large-slides')),
17603        xLarge: Number.parseInt($(this).attr('data-xlarge-slides')),
17604        xxLarge: Number.parseInt($(this).attr('data-xxlarge-slides'))
17605      };
17606
17607      const gap = {
17608        small: Number.parseInt($(this).attr('data-small-gap')),
17609        medium: Number.parseInt($(this).attr('data-medium-gap')),
17610        large: Number.parseInt($(this).attr('data-large-gap')),
17611        xLarge: Number.parseInt($(this).attr('data-xlarge-gap')),
17612        xxLarge: Number.parseInt($(this).attr('data-xxlarge-gap'))
17613      };
17614
17615      const autoplay = $(this).attr('data-autoplay') ? $(this).attr('data-autoplay').toLowerCase() === 'true' : false,
17616        infinite = $(this).attr('data-infinite') ? $(this).attr('data-infinite').toLowerCase() === 'true' : false;
17617
17618      const responsiveObj = {
17619        small: { breakpoint: mediumBreakpoint, settings: {} },
17620        medium: { breakpoint: largeBreakpoint, settings: {} },
17621        large: { breakpoint: xLargeBreakpoint, settings: {} },
17622        xLarge: { breakpoint: xxLargeBreakpoint, settings: {} }
17623      };
17624
17625      const responsiveArr = [];
17626      Object.keys(responsiveObj).forEach((breakpoint) => {
17627        const page = {};
17628        const trackOptions = { page: page };
17629        let shouldAddBreakpoint = !Number.isNaN(slides[breakpoint]) || !Number.isNaN(gap[breakpoint]);
17630
17631        if (!Number.isNaN(slides[breakpoint]) && !Number.isNaN(gap[breakpoint])) {
17632          page.slideCount = slides[breakpoint];
17633          page.gap = gap[breakpoint];
17634        } else if (!Number.isNaN(gap[breakpoint])) page.gap = gap[breakpoint];else
17635        if (!Number.isNaN(slides[breakpoint])) page.slideCount = slides[breakpoint];
17636
17637        // ######## Uebertrage von responsiveObj to responsiveArr, falls settings wenigstens einen Key hat
17638        if (shouldAddBreakpoint) {
17639          responsiveObj[breakpoint].settings.trackOptions = trackOptions;
17640          responsiveArr.push(responsiveObj[breakpoint]);
17641        }
17642      });
17643
17644      base.cms_carousel({
17645        trackOptions: {
17646          page: {
17647            slideCount: !Number.isNaN(slides['xxLarge']) ? slides['xxLarge'] : 1,
17648            gap: !Number.isNaN(gap['xxLarge']) ? gap['xxLarge'] : 0
17649          },
17650          behavior: {
17651            infiniteSlide: false,
17652            adaptiveTrackHeight: true
17653          }
17654        },
17655        behavior: {
17656          autoplay: autoplay
17657        },
17658        responsive: responsiveArr
17659      });
17660    });
17661  });
17662
17663  // JS Carousel for Gallery
17664  cms.requireCMSComponent('bundle_slideshow', $('.js-gallery, .js-gallery-dialog')).done(function ($galleryCarousel) {
17665    $galleryCarousel.each(function () {
17666      const base = $(this);
17667      const slides = {
17668        small: Number.parseInt($(this).attr('data-small-slides')),
17669        medium: Number.parseInt($(this).attr('data-medium-slides')),
17670        large: Number.parseInt($(this).attr('data-large-slides')),
17671        xLarge: Number.parseInt($(this).attr('data-xlarge-slides')),
17672        xxLarge: Number.parseInt($(this).attr('data-xxlarge-slides'))
17673      };
17674
17675      const gap = {
17676        small: Number.parseInt($(this).attr('data-small-gap')),
17677        medium: Number.parseInt($(this).attr('data-medium-gap')),
17678        large: Number.parseInt($(this).attr('data-large-gap')),
17679        xLarge: Number.parseInt($(this).attr('data-xlarge-gap')),
17680        xxLarge: Number.parseInt($(this).attr('data-xxlarge-gap'))
17681      };
17682
17683      const autoplay = $(this).attr('data-autoplay') ? $(this).attr('data-autoplay').toLowerCase() === 'true' : false,
17684        infinite = $(this).attr('data-infinite') ? $(this).attr('data-infinite').toLowerCase() === 'true' : false;
17685
17686      const responsiveObj = {
17687        small: { breakpoint: mediumBreakpoint, settings: {} },
17688        medium: { breakpoint: largeBreakpoint, settings: {} },
17689        large: { breakpoint: xLargeBreakpoint, settings: {} },
17690        xLarge: { breakpoint: xxLargeBreakpoint, settings: {} }
17691      };
17692
17693      const responsiveArr = [];
17694      Object.keys(responsiveObj).forEach((breakpoint) => {
17695        const page = {};
17696        const trackOptions = { page: page };
17697        let shouldAddBreakpoint = !Number.isNaN(slides[breakpoint]) || !Number.isNaN(gap[breakpoint]);
17698
17699        if (!Number.isNaN(slides[breakpoint]) && !Number.isNaN(gap[breakpoint])) {
17700          page.slideCount = slides[breakpoint];
17701          page.gap = gap[breakpoint];
17702        } else if (!Number.isNaN(gap[breakpoint])) page.gap = gap[breakpoint];else
17703        if (!Number.isNaN(slides[breakpoint])) page.slideCount = slides[breakpoint];
17704
17705        // ######## Uebertrage von responsiveObj to responsiveArr, falls settings wenigstens einen Key hat
17706        if (shouldAddBreakpoint) {
17707          responsiveObj[breakpoint].settings.trackOptions = trackOptions;
17708          responsiveArr.push(responsiveObj[breakpoint]);
17709        }
17710      });
17711
17712      base.cms_carousel({
17713        trackOptions: {
17714          page: {
17715            slideCount: !Number.isNaN(slides['xxLarge']) ? slides['xxLarge'] : 1,
17716            gap: !Number.isNaN(gap['xxLarge']) ? gap['xxLarge'] : 0
17717          },
17718          behavior: {
17719            infiniteSlide: infinite,
17720            adaptiveTrackHeight: true
17721          }
17722        },
17723        responsive: responsiveArr
17724      });
17725    });
17726
17727    $('.js-lightbox-opener').on("click", function () {
17728      const slideNumber = Number.parseInt($(this).attr('data-sli
17728de-number'));
17729      console.log(slideNumber);
17730      if (!Number.isNaN(slideNumber)) {
17731        setTimeout(() => {
17732          $('.js-gallery-dialog').trigger($.Event('goto.carousel', { movement: slideNumber }));
17733        }, 300);
17734      }
17735    });
17736
17737    $('.c-lightbox__closer, .l-carousel__button').on("click", () => {
17738      $('video').trigger('pause');
17739      $('iframe').each(function () {
17740        this.contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}', '*');
17741      });
17742    });
17743  });
17744
17745  // slideshow: for timeline
17746  cms.requireCMSComponent('bundle_slideshow', $('.js-timeline')).done(function ($jsCarousel) {
17747    $jsCarousel.each(function () {
17748      const base = $(this);
17749      const slides = {
17750        small: Number.parseInt($(this).attr('data-small-slides')),
17751        medium: Number.parseInt($(this).attr('data-medium-slides')),
17752        large: Number.parseInt($(this).attr('data-large-slides')),
17753        xLarge: Number.parseInt($(this).attr('data-xlarge-slides')),
17754        xxLarge: Number.parseInt($(this).attr('data-xxlarge-slides'))
17755      };
17756
17757      const gap = {
17758        small: Number.parseInt($(this).attr('data-small-gap')),
17759        medium: Number.parseInt($(this).attr('data-medium-gap')),
17760        large: Number.parseInt($(this).attr('data-large-gap')),
17761        xLarge: Number.parseInt($(this).attr('data-xlarge-gap')),
17762        xxLarge: Number.parseInt($(this).attr('data-xxlarge-gap'))
17763      };
17764
17765      const responsiveObj = {
17766        small: { breakpoint: mediumBreakpoint, settings: {} },
17767        medium: { breakpoint: largeBreakpoint, settings: {} },
17768        large: { breakpoint: xLargeBreakpoint, settings: {} },
17769        xLarge: { breakpoint: xxLargeBreakpoint, settings: {} }
17770      };
17771
17772      const responsiveArr = [];
17773      Object.keys(responsiveObj).forEach((breakpoint) => {
17774        const page = {};
17775        const trackOptions = { page: page };
17776        let shouldAddBreakpoint = !Number.isNaN(slides[breakpoint]) || !Number.isNaN(gap[breakpoint]);
17777
17778        if (!Number.isNaN(slides[breakpoint]) && !Number.isNaN(gap[breakpoint])) {
17779          page.slideCount = slides[breakpoint];
17780          page.gap = gap[breakpoint];
17781        } else if (!Number.isNaN(gap[breakpoint])) page.gap = gap[breakpoint];else
17782        if (!Number.isNaN(slides[breakpoint])) page.slideCount = slides[breakpoint];
17783
17784        // ######## Uebertrage von responsiveObj to responsiveArr, falls settings wenigstens einen Key hat
17785        if (shouldAddBreakpoint) {
17786          responsiveObj[breakpoint].settings.trackOptions = trackOptions;
17787          responsiveArr.push(responsiveObj[breakpoint]);
17788        }
17789      });
17790
17791      base.cms_carousel({
17792        behavior: {
17793          shouldAlwaysInit: true
17794        },
17795        trackOptions: {
17796          page: {
17797            slideCount: !Number.isNaN(slides['xxLarge']) ? slides['xxLarge'] : 1,
17798            gap: !Number.isNaN(gap['xxLarge']) ? gap['xxLarge'] : 0
17799          }
17800        },
17801        responsive: responsiveArr
17802      });
17803    });
17804  });
17805
17806  // Dialog
17807  $('dialog').not('.c-cookiebanner').cms_dialog();
17808
17809
17810  $('[data-example-client-validation]').before(
17811    $("<span></span>").
17812    addClass('js-clientsidevalidation-errmsg').
17813    append("<strong class='formError'>Pflichtfeld nicht ausgef&uuml;llt.</strong>")
17814  );
17815  $('.js-search-field').cms_fancy_selects();
17816
17817  $('.js-result-list-filter').cms_result_list_filter();
17818
17819
17820  $('.js-flip-card').cms_flip_card();
17821
17822  // Flip-Cards (c-flip-card__front und c-flip-card__back) in der Timeline sollen nicht fokussierbar sein (GSBBAFIN-257)
17823  const $front = $('.js-timeline .c-flip-card__front');
17824  const $back = $('.js-timeline .c-flip-card__back');
17825
17826  if ($front.attr('tabindex') === '0') {
17827    $front.removeAttr('tabindex');
17828  }
17829
17830  $('.js-timeline .js-flip-card-button').on('click', function () {
17831    $front.each(function (index, element) {
17832      if ($(element).attr('tabindex') === '0') {
17833        $(element).removeAttr('tabindex');
17834        $(element).children().first().attr('tabindex', '0');
17835      } else if ($(element).attr('tabindex') === '-1') {
17836        $(element).children().first().attr('tabindex', '-1');
17837      }
17838    });
17839
17840    $back.each(function (index, element) {
17841      if ($(element).attr('tabindex') === '0') {
17842        $(element).removeAttr('tabindex');
17843        $(element).children().first().attr('tabindex', '0');
17844      } else if ($(element).attr('tabindex') === '-1') {
17845        $(element).children().first().attr('tabindex', '-1');
17846      }
17847    });
17848  });
17849
17850  function hasParentWithTabindexMinusOne(element) {
17851    return $(element).parents('[tabindex="-1"]').length > 0;
17852  }
17853
17854  let observer = new MutationObserver((mutationsList) => {
17855    for (const mutation of mutationsList) {
17856      if (
17857      mutation.type === 'attributes' &&
17858      mutation.attributeName === 'tabindex')
17859      {
17860        const target = mutation.target;
17861
17862        if (
17863        target.getAttribute('tabindex') !== '-1' &&
17864        hasParentWithTabindexMinusOne(target))
17865        {
17866          target.setAttribute('tabindex', '-1');
17867        }
17868      }
17869    }
17870  });
17871
17872  document.querySelectorAll('.js-flip-card-button').forEach((el) => {
17873    observer.observe(el, {
17874      attributes: true,
17875      attributeFilter: ['tabindex']
17876    });
17877  });
17878
17879
17880  cms.requireCMSComponent('bundle_animate_number', $('.js-teaser-number__number')).done(function ($animate_numbers) {
17881    $animate_numbers.cms_animate_number({
17882      triggerPositionOffsetPercent: 80
17883    });
17884  });
17885
17886
17887  // Social Media Consent Wrapper
17888  const $mastodonTeasers = $('.js-mastodon-consent-reload').
17889  cms_consent_reload({ cookieName: 'cms_consent_mastodon' }).
17890  on('afterConsent.consent_reload.cms', () => $mastodonTeasers.trigger('consent.consent_reload.cms'));
17891  const $linkedinTeasers = $('.js-linkedin-consent-reload').
17892  cms_consent_reload({ cookieName: 'cms_consent_linkedin' }).
17893  on('afterConsent.consent_reload.cms', () => $linkedinTeasers.trigger('consent.consent_reload.cms'));
17894  const $instagramTeasers = $('.js-instagram-consent-reload').
17895  cms_consent_reload({ cookieName: 'cms_consent_instagram' }).
17896  on('afterConsent.consent_reload.cms', () => $instagramTeasers.trigger('consent.consent_reload.cms'));
17897  const $videoTeasers = $('.js-video-consent-reload').
17898  cms_consent_reload({ cookieName: 'cms_consent_video' }).
17899  on('afterConsent.consent_reload.cms', () => $videoTeasers.trigger('consent.consent_reload.cms'));
17900
17901
17902  // Prüft ob der Consentwrapper vorhanden ist und fügt nach schließen des Cookiebanners einen Pagereload durch
17903  const consentContainer = document.querySelector('.c-consent-container');
17904  const cookieBannerClicker = document.querySelector('.c-cookiebanner');
17905  if (typeof consentContainer != 'undefined' && consentContainer != null) {
17906    cookieBannerClicker.addEventListener("afterClose", function (e) {
17907      location.reload();
17908    });
17909  }
17910
17911  //DTVP-Importer
17912  cms.requireCMSComponent('bundle_datatables', $('.js-dtvp-importer')).done(function ($dtvp_importer) {
17913    $dtvp_importer.cms_dtvp_importer();
17914  });
17915
17916  //Kontakt-Finder
17917  $(".js-contact-finder").each(function () {
17918    addContactFinderEventHandlers($(this));
17919  });
17920
17921  function normalizeContactFinderTextLinks($scope) {
17922    $scope.find('.c-contact-finder__text a.RichTextIntLink, .c-contact-finder__text a.RichTextExtLink').
17923    each(function () {
17924      const $a = $(this);
17925      const href = $a.attr('href');
17926      if (!href || /^https?:\/\//i.test(href) || /^mailto:/i.test(href) || /^tel:/i.test(href) || href.startsWith('#')) {
17927        return;
17928      }
17929      if (href.startsWith('/')) {
17930        $a.attr('href', window.location.origin + href);
17931      } else {
17932        $a.attr('href', window.location.origin + '/' + href);
17933      }
17934    });
17935  }
17936
17937  function addContactFinderEventHandlers($contactFinderContent) {
17938    normalizeContactFinderTextLinks($contactFinderContent);
17939
17940    $contactFinderContent.find("a").not(".c-teaser *").on("click", function (ev) {
17941      const $link = $(this);
17942      if ($link.closest('.c-contact-finder__text').length && $link.is('.RichTextIntLink, .RichTextExtLink')) {
17943        return;
17944      }
17945      ev.preventDefault();
17946      const href = $link.attr("href") + "?view=render";
17947      $.ajax({
17948        url: href,
17949        success: function (data) {
17950          const $newContactFinderContent = $(data).find(".js-contact-finder");
17951          $contactFinderContent.html($newContactFinderContent.html());
17952        },
17953        complete: function (data) {
17954          addContactFinderEventHandlers($contactFinderContent);
17955          window.scrollTo({ top: $contactFinderContent.position().top, behavior: 'smooth' });
17956        }
17957      });
17958    });
17959  }
17960
17961  const $fileUploadForm = $('.js-dynamic-file-upload-form');
17962  $fileUploadForm.cms_dynamic_file_uploader();
17963
17964  // Fussnoten
17965  function changeTagName($el, newTag) {
17966    const $newEl = $(`<${newTag}>`);
17967    $.each($el[0].attributes, function () {
17968      $newEl.attr(this.name, this.value);
17969    });
17970    $newEl.append($el.contents());
17971    $newEl.data($el.data());
17972    $el.replaceWith($newEl);
17973    return $newEl;
17974  }
17975  $($('.js-footnote__button').toArray().map((el) => changeTagName($(el), 'a')));
17976  const $buttons = $('.js-footnote__button');
17977  const $footnotes = $('.js-anmerkungstexte li');
17978  $('.js-anmerkungstexte').attr('aria-label', $('body').hasClass('lang-de') ? 'Fußnoten' : 'Footnotes');
17979
17980  $buttons.each(function (index) {
17981    $(this).attr('href', '#footnote-' + (index + 1)).
17982    attr('aria-label', `(${$('body').hasClass('lang-de') ? 'Fußnote' : 'footnote'} ${$(this).text()})`);
17983  });$footnotes.each(function (index) {
17984    $(this).attr('id', 'footnote-' + (index + 1));
17985  });
17986
17987  function handleHashTarget() {
17988    const hash = window.location.hash;
17989    if (!hash) return;
17990
17991    const target = document.querySelector(hash);
17992    if (!target) return;
17993
17994    if (hash === '#facetReset') {
17995      $(target).on('focus', function () {
17996        let $facetResetLink = $('.c-facet-reset__link');
17997        let $searchResults = $('#searchResults');
17998
17999        if ($facetResetLink.length !== 0) {
18000          $facetResetLink.get(0).focus();
18001        } else {
18002          $searchResults.attr("tabindex", -1).focus();
18003          $('html, body').animate({
18004            scrollTop: $searchResults.offset().top - 120
18005          }, 800);
18006        }
18007      });
18008    } else {
18009      const accordionEntry = target.closest(".js-accordion-entry");
18010      if (accordionEntry) {
18011        const controlledId = accordionEntry.id;
18012        const accordionButton = document.querySelector(`button[aria-controls="${controlledId}"]`);
18013
18014        if (accordionButton) {
18015          accordionButton.click();
18016
18017          const observer = new MutationObserver(() => {
18018            if (accordionButton.getAttribute("aria-expanded") === 'true') {
18019              setTimeout(function () {
18020                target.focus();
18021                observer.disconnect();
18022              }, 100);
18023            }
18024          });
18025
18026          observer.observe(accordionButton, { attributes: true, attributeFilter: ["aria-expanded"] });
18027        }
18028      } else {
18029        target.focus();
18030      }
18031    }
18032  }
18033
18034  $(document).ready(handleHashTarget);
18035  window.addEventListener("hashchange", handleHashTarget);
18036
18037});
18038// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -- Unterdrücke, dass no-console nicht wieder aktiviert wird
18039/* eslint-disable no-console -- Das Ziel ist es Konsolen-Ausgaben zu machen */
18040$(function () {
18041  // Prüfe, ob Aria-describedby und labelled-by passende IDs und zugehörige Elemente haben
18042  if (ISPREVIEW) {
18043    const $body = $('body');
18044    let aria = new Set();
18045    let ids = new Set();
18046    const arrAria = [...$body.html().matchAll(/<[^<]*(aria-labelledby="([^"]*)"|aria-describedby="([^"]*)")[^>]*>/gmu)];
18047    arrAria.forEach((el) => {
18048      if (!aria.has(el[2]) && !aria.has(el[3])) {
18049        aria.add(el[2]);
18050        aria.add(el[3]);
18051        aria.delete(undefined);
18052      } else {
18053        console.log(`ID bereits vergeben: ${el[0]}`);
18054      }
18055    });
18056    const arrId = [...$body.html().matchAll(/<[^<]* id="([^"]*)"[^>]*>/gmu)];
18057    arrId.forEach((el) => {
18058      if (!ids.has(el[1])) {
18059        ids.add(el[1]);
18060      } else {
18061        console.log(`ID doppelt: ${el[0]}`);
18062      }
18063    });
18064
18065    function splitArr(arr) {
18066      const splits = [];
18067      const newSet = new Set();
18068      arr.forEach((el) => {
18069        splits.push(el.split(" "));
18070      });
18071      splits.forEach((array) => {
18072        array.forEach((el) => {
18073          newSet.add(el);
18074        });
18075      });
18076      newSet.delete("");
18077      return newSet;
18078    }
18079
18080    aria = splitArr(aria);
18081    ids = splitArr(ids);
18082
18083    const missingIds = new Set();
18084    aria.forEach((el) => {
18085      if (!ids.has(el)) {
18086        missingIds.add(el);
18087      }
18088    });
18089
18090    if (missingIds.size > 0) {
18091      const additionalHTML = 'Folgende Aria-Ids haben kein Ziel: ';
18092      missingIds.forEach((el) => console.log(additionalHTML + el));
18093    }
18094  }
18095});
18096
18097    /* Ende init */
18098jQuery(document).ready(function (jQuery){
18099    // Autosuggest
18100    var searchforms = [];
18101    if(searchforms.length > 0){
18102        $(searchforms).each(function(index){
18103            var valueObj = searchforms[index],form;
18104            if(valueObj !== undefined){
18105                form = jQuery('form[name="'+ valueObj.name +'"]');
18106                if(form.length > 0){
18107                    form.cms_AutoSuggest({}, valueObj.action);
18108                }
18109            }
18110        });
18111    }
18112});

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.