PageSourceSearch

https://www.eqlstore.com/eql_pc/resources/js/uiux/OverlayScrollbars.js?timestamp=20260922141411

js eqlstore.com collected 2026-09-26 06:16:03 UTC 319,702 bytes, 8,252 lines download raw bytes

1/*!
2 * OverlayScrollbars
3 * https://github.com/KingSora/OverlayScrollbars
4 *
5 * Version: 1.13.3
6 *
7 * Copyright KingSora | Rene Haas.
8 * https://github.com/KingSora
9 *
10 * Released under the MIT license.
11 * Date: 20.07.2022
12 */
13
14(function (global, factory) {
15  if (typeof define === "function" && define.amd)
16    define(function () {
17      return factory(global, global.document, undefined);
18    });
19  else if (typeof module === "object" && typeof module.exports === "object")
20    module.exports = factory(global, global.document, undefined);
21  else factory(global, global.document, undefined);
22})(
23  typeof window !== "undefined" ? window : this,
24  function (window, document, undefined) {
25    "use strict";
26    var PLUGINNAME = "OverlayScrollbars";
27    var TYPES = {
28      o: "object",
29      f: "function",
30      a: "array",
31      s: "string",
32      b: "boolean",
33      n: "number",
34      u: "undefined",
35      z: "null",
36      //d : 'date',
37      //e : 'error',
38      //r : 'regexp',
39      //y : 'symbol'
40    };
41    var LEXICON = {
42      c: "class",
43      s: "style",
44      i: "id",
45      l: "length",
46      p: "prototype",
47      ti: "tabindex",
48      oH: "offsetHeight",
49      cH: "clientHeight",
50      sH: "scrollHeight",
51      oW: "offsetWidth",
52      cW: "clientWidth",
53      sW: "scrollWidth",
54      hOP: "hasOwnProperty",
55      bCR: "getBoundingClientRect",
56    };
57    var VENDORS = (function () {
58      //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix
59      var jsCache = {};
60      var cssCache = {};
61      var cssPrefixes = ["-webkit-", "-moz-", "-o-", "-ms-"];
62      var jsPrefixes = ["WebKit", "Moz", "O", "MS"];
63      function firstLetterToUpper(str) {
64        return str.charAt(0).toUpperCase() + str.slice(1);
65      }
66
67      return {
68        _cssPrefixes: cssPrefixes,
69        _jsPrefixes: jsPrefixes,
70        _cssProperty: function (name) {
71          var result = cssCache[name];
72
73          if (cssCache[LEXICON.hOP](name)) return result;
74
75          var uppercasedName = firstLetterToUpper(name);
76          var elmStyle = document.createElement("div")[LEXICON.s];
77          var resultPossibilities;
78          var i = 0;
79          var v;
80          var currVendorWithoutDashes;
81
82          for (; i < cssPrefixes.length; i++) {
83            currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, "");
84            resultPossibilities = [
85              name, //transition
86              cssPrefixes[i] + name, //-webkit-transition
87              currVendorWithoutDashes + uppercasedName, //webkitTransition
88              firstLetterToUpper(currVendorWithoutDashes) + uppercasedName, //WebkitTransition
89            ];
90            for (v = 0; v < resultPossibilities[LEXICON.l]; v++) {
91              if (elmStyle[resultPossibilities[v]] !== undefined) {
92                result = resultPossibilities[v];
93                break;
94              }
95            }
96          }
97
98          cssCache[name] = result;
99          return result;
100        },
101        _cssPropertyValue: function (property, values, suffix) {
102          var name = property + " " + values;
103          var result = cssCache[name];
104
105          if (cssCache[LEXICON.hOP](name)) return result;
106
107          var dummyStyle = document.createElement("div")[LEXICON.s];
108          var possbleValues = values.split(" ");
109          var preparedSuffix = suffix || "";
110          var i = 0;
111          var v = -1;
112          var prop;
113
114          for (; i < possbleValues[LEXICON.l]; i++) {
115            for (; v < VENDORS._cssPrefixes[LEXICON.l]; v++) {
116              prop =
117                v < 0
118                  ? possbleValues[i]
119                  : VENDORS._cssPrefixes[v] + possbleValues[i];
120              dummyStyle.cssText = property + ":" + prop + preparedSuffix;
121              if (dummyStyle[LEXICON.l]) {
122                result = prop;
123                break;
124              }
125            }
126          }
127
128          cssCache[name] = result;
129          return result;
130        },
131        _jsAPI: function (name, isInterface, fallback) {
132          var i = 0;
133          var result = jsCache[name];
134
135          if (!jsCache[LEXICON.hOP](name)) {
136            result = window[name];
137            for (; i < jsPrefixes[LEXICON.l]; i++)
138              result =
139                result ||
140                window[
141                  (isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) +
142                    firstLetterToUpper(name)
143                ];
144            jsCache[name] = result;
145          }
146          return result || fallback;
147        },
148      };
149    })();
150    var COMPATIBILITY = (function () {
151      function windowSize(x) {
152        return x
153          ? window.innerWidth ||
154              document.documentElement[LEXICON.cW] ||
155              document.body[LEXICON.cW]
156          : window.innerHeight ||
157              document.documentElement[LEXICON.cH] ||
158              document.body[LEXICON.cH];
159      }
160      function bind(func, thisObj) {
161        if (typeof func != TYPES.f) {
162          throw "Can't bind function!";
163          // closest thing possible to the ECMAScript 5
164          // internal IsCallable function
165          //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
166        }
167        var proto = LEXICON.p;
168        var aArgs = Array[proto].slice.call(arguments, 2);
169        var fNOP = function () {};
170        var fBound = function () {
171          return func.apply(
172            this instanceof fNOP ? this : thisObj,
173            aArgs.concat(Array[proto].slice.call(arguments))
174          );
175        };
176
177        if (func[proto]) fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property
178        fBound[proto] = new fNOP();
179
180        return fBound;
181      }
182
183      return {
184        /**
185         * Gets the current window width.
186         * @returns {Number|number} The current window width in pixel.
187         */
188        wW: bind(windowSize, 0, true),
189
190        /**
191         * Gets the current window height.
192         * @returns {Number|number} The current window height in pixel.
193         */
194        wH: bind(windowSize, 0),
195
196        /**
197         * Gets the MutationObserver Object or undefined if not supported.
198         * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined.
199         */
200        mO: bind(VENDORS._jsAPI, 0, "MutationObserver", true),
201
202        /**
203         * Gets the ResizeObserver Object or undefined if not supported.
204         * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined.
205         */
206        rO: bind(VENDORS._jsAPI, 0, "ResizeObserver", true),
207
208        /**
209         * Gets the RequestAnimationFrame method or it's corresponding pol
209yfill.
210         * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill.
211         */
212        rAF: bind(
213          VENDORS._jsAPI,
214          0,
215          "requestAnimationFrame",
216          false,
217          function (func) {
218            return window.setTimeout(func, 1000 / 60);
219          }
220        ),
221
222        /**
223         * Gets the CancelAnimationFrame method or it's corresponding polyfill.
224         * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill.
225         */
226        cAF: bind(
227          VENDORS._jsAPI,
228          0,
229          "cancelAnimationFrame",
230          false,
231          function (id) {
232            return window.clearTimeout(id);
233          }
234        ),
235
236        /**
237         * Gets the current time.
238         * @returns {number} The current time.
239         */
240        now: function () {
241          return (Date.now && Date.now()) || new Date().getTime();
242        },
243
244        /**
245         * Stops the propagation of the given event.
246         * @param event The event of which the propagation shall be stoped.
247         */
248        stpP: function (event) {
249          if (event.stopPropagation) event.stopPropagation();
250          else event.cancelBubble = true;
251        },
252
253        /**
254         * Prevents the default action of the given event.
255         * @param event The event of which the default action shall be prevented.
256         */
257        prvD: function (event) {
258          if (event.preventDefault && event.cancelable) event.preventDefault();
259          else event.returnValue = false;
260        },
261
262        /**
263         * Gets the pageX and pageY values of the given mouse event.
264         * @param event The mouse event of which the pageX and pageX shall be got.
265         * @returns {{x: number, y: number}} x = pageX value, y = pageY value.
266         */
267        page: function (event) {
268          event = event.originalEvent || event;
269
270          var strPage = "page";
271          var strClient = "client";
272          var strX = "X";
273          var strY = "Y";
274          var target = event.target || event.srcElement || document;
275          var eventDoc = target.ownerDocument || document;
276          var doc = eventDoc.documentElement;
277          var body = eventDoc.body;
278
279          //if touch event return return pageX/Y of it
280          if (event.touches !== undefined) {
281            var touch = event.touches[0];
282            return {
283              x: touch[strPage + strX],
284              y: touch[strPage + strY],
285            };
286          }
287
288          // Calculate pageX/Y if not native supported
289          if (
290            !event[strPage + strX] &&
291            event[strClient + strX] &&
292            event[strClient + strX] != null
293          ) {
294            return {
295              x:
296                event[strClient + strX] +
297                ((doc && doc.scrollLeft) || (body && body.scrollLeft) || 0) -
298                ((doc && doc.clientLeft) || (body && body.clientLeft) || 0),
299              y:
300                event[strClient + strY] +
301                ((doc && doc.scrollTop) || (body && body.scrollTop) || 0) -
302                ((doc && doc.clientTop) || (body && body.clientTop) || 0),
303            };
304          }
305          return {
306            x: event[strPage + strX],
307            y: event[strPage + strY],
308          };
309        },
310
311        /**
312         * Gets the clicked mouse button of the given mouse event.
313         * @param event The mouse event of which the clicked button shal be got.
314         * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton)
315         */
316        mBtn: function (event) {
317          var button = event.button;
318          if (!event.which && button !== undefined)
319            return button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0;
320          else return event.which;
321        },
322
323        /**
324         * Checks whether a item is in the given array and returns its index.
325         * @param item The item of which the position in the array shall be determined.
326         * @param arr The array.
327         * @returns {number} The zero based index of the item or -1 if the item isn't in the array.
328         */
329        inA: function (item, arr) {
330          for (var i = 0; i < arr[LEXICON.l]; i++)
331            //Sometiems in IE a "SCRIPT70" Permission denied error occurs if HTML elements in a iFrame are compared
332            try {
333              if (arr[i] === item) return i;
334            } catch (e) {}
335          return -1;
336        },
337
338        /**
339         * Returns true if the given value is a array.
340         * @param arr The potential array.
341         * @returns {boolean} True if the given value is a array, false otherwise.
342         */
343        isA: function (arr) {
344          var def = Array.isArray;
345          return def ? def(arr) : this.type(arr) == TYPES.a;
346        },
347
348        /**
349         * Determine the internal JavaScript [[Class]] of the given object.
350         * @param obj The object of which the type shall be determined.
351         * @returns {string} The type of the given object.
352         */
353        type: function (obj) {
354          if (obj === undefined) return obj + "";
355          if (obj === null) return obj + "";
356          return Object[LEXICON.p].toString
357            .call(obj)
358            .replace(/^\[object (.+)\]$/, "$1")
359            .toLowerCase();
360        },
361
362        bind: bind,
363
364        /**
365                 * Gets the vendor-prefixed CSS property by the given name.
366                 * For example the given name is "transform" and you're using a old Firefox browser then the returned value would be "-moz-transform".
367                 * If the browser doesn't need a vendor-prefix, then the returned string is the given name.
368                 * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null.
369                 * @param propName The unprefixed CSS property name.
370                 * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property.
371
372                cssProp: function(propName) {
373                    return VENDORS._cssProperty(propName);
374                }
375                */
376      };
377    })();
378
379    var MATH = Math;
380    var JQUERY = window.jQuery;
381    var EASING = (function () {
382      var _easingsMath = {
383        p: MATH.PI,
384        c: MATH.cos,
385        s: MATH.sin,
386        w: MATH.pow,
387        t: MATH.sqrt,
388        n: MATH.asin,
389        a: MATH.abs,
390        o: 1.70158,
391      };
392
393      /*
394             x : current percent (0 - 1),
395             t : current time (duration * percent),
396             b : start value (from),
397             c : end value (to),
398             d : duration
399
400             easingName : function(x, t, b, c, d) { return easedValue; }
401             */
402
403      return {
404        swing: function (x, t, b, c, d) {
405          return 0.5 - _easingsMath.c(x * _easingsMath.p) / 2;
406        },
407        linear: function (x, t, b, c, d) {
408          return x;
409        },
410        easeInQuad: function (x, t, b, c, d) {
411          return c * (t /= d) * t + b;
412        },
413        easeOutQuad: function (x, t, b, c, d) {
414          return -c * (t /= d) * (t - 2) + b;
415        },
416        easeInOutQuad: function (x, t, b, c, d) {
417          return (t /= d / 2) < 1
418            ? (c / 2) * t * t + b
419            : (-c / 2) * (--t * (t - 2) - 1) + b;
420        },
421        easeInCubic: function (x, t, b, c, d) {
422          return c * (t /= d) * t * t + b;
423        },
424        easeOutCubic: function (x, t, b, c, d) {
425          return c * ((t = t / d - 1) * t * t + 1) + b;
426        },
427        easeInOutCubic: function (x, t, b, c, d) {
428          return (t /= d / 2) < 1
429            ? (c / 2) * t * t * t + b
430            : (c / 2) * ((t -= 2) * t * t + 2) + b;
431        },
432        easeInQuart: function (x, t, b, c, d) {
433          return c * (t /= d) * t * t * t + b;
434        },
435        easeOutQuart: function (x, t, b, c, d) {
436          return -c * ((t = t / d - 1) * t * t * t - 1) + b;
437        },
438        easeInOutQuart: function (x, t, b, c, d) {
439          return (t /= d / 2) < 1
440            ? (c / 2) * t * t * t * t + b
441            : (-c / 2) * ((t -= 2) * t * t * t - 2) + b;
442        },
443        easeInQuint: function (x, t, b, c, d) {
444          return c * (t /= d) * t * t * t * t + b;
445        },
446        easeOutQuint: function (x, t, b, c, d) {
447          return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
448        },
449        easeInOutQuint: function (x, t, b, c, d) {
450          return (t /= d / 2) < 1
451            ? (c / 2) * t * t * t * t * t + b
452            : (c / 2) * ((t -= 2) * t * t * t * t + 2) + b;
453        },
454        easeInSine: function (x, t, b, c, d) {
455          return -c * _easingsMath.c((t / d) * (_easingsMath.p / 2)) + c + b;
456        },
457        easeOutSine: function (x, t, b, c, d) {
458          return c * _easingsMath.s((t / d) * (_easingsMath.p / 2)) + b;
459        },
460        easeInOutSine: function (x, t, b, c, d) {
461          return (-c / 2) * (_easingsMath.c((_easingsMath.p * t) / d) - 1) + b;
462        },
463        easeInExpo: function (x, t, b, c, d) {
464          return t == 0 ? b : c * _easingsMath.w(2, 10 * (t / d - 1)) + b;
465        },
466        easeOutExpo: function (x, t, b, c, d) {
467          return t == d
468            ? b + c
469            : c * (-_easingsMath.w(2, (-10 * t) / d) + 1) + b;
470        },
471        easeInOutExpo: function (x, t, b, c, d) {
472          if (t == 0) return b;
473          if (t == d) return b + c;
474          if ((t /= d / 2) < 1)
475            return (c / 2) * _easingsMath.w(2, 10 * (t - 1)) + b;
476          return (c / 2) * (-_easingsMath.w(2, -10 * --t) + 2) + b;
477        },
478        easeInCirc: function (x, t, b, c, d) {
479          return -c * (_easingsMath.t(1 - (t /= d) * t) - 1) + b;
480        },
481        easeOutCirc: function (x, t, b, c, d) {
482          return c * _easingsMath.t(1 - (t = t / d - 1) * t) + b;
483        },
484        easeInOutCirc: function (x, t, b, c, d) {
485          return (t /= d / 2) < 1
486            ? (-c / 2) * (_easingsMath.t(1 - t * t) - 1) + b
487            : (c / 2) * (_easingsMath.t(1 - (t -= 2) * t) + 1) + b;
488        },
489        easeInElastic: function (x, t, b, c, d) {
490          var s = _easingsMath.o;
491          var p = 0;
492          var a = c;
493          if (t == 0) return b;
494          if ((t /= d) == 1) return b + c;
495          if (!p) p = d * 0.3;
496          if (a < _easingsMath.a(c)) {
497            a = c;
498            s = p / 4;
499          } else s = (p / (2 * _easingsMath.p)) * _easingsMath.n(c / a);
500          return (
501            -(
502              a *
503              _easingsMath.w(2, 10 * (t -= 1)) *
504              _easingsMath.s(((t * d - s) * (2 * _easingsMath.p)) / p)
505            ) + b
506          );
507        },
508        easeOutElastic: function (x, t, b, c, d) {
509          var s = _easingsMath.o;
510          var p = 0;
511          var a = c;
512          if (t == 0) return b;
513          if ((t /= d) == 1) return b + c;
514          if (!p) p = d * 0.3;
515          if (a < _easingsMath.a(c)) {
516            a = c;
517            s = p / 4;
518          } else s = (p / (2 * _easingsMath.p)) * _easingsMath.n(c / a);
519          return (
520            a *
521              _easingsMath.w(2, -10 * t) *
522              _easingsMath.s(((t * d - s) * (2 * _easingsMath.p)) / p) +
523            c +
524            b
525          );
526        },
527        easeInOutElastic: function (x, t, b, c, d) {
528          var s = _easingsMath.o;
529          var p = 0;
530          var a = c;
531          if (t == 0) return b;
532          if ((t /= d / 2) == 2) return b + c;
533          if (!p) p = d * (0.3 * 1.5);
534          if (a < _easingsMath.a(c)) {
535            a = c;
536            s = p / 4;
537          } else s = (p / (2 * _easingsMath.p)) * _easingsMath.n(c / a);
538          if (t < 1)
539            return (
540              -0.5 *
541                (a *
542                  _easingsMath.w(2, 10 * (t -= 1)) *
543                  _easingsMath.s(((t * d - s) * (2 * _easingsMath.p)) / p)) +
544              b
545            );
546          return (
547            a *
548              _easingsMath.w(2, -10 * (t -= 1)) *
549              _easingsMath.s(((t * d - s) * (2 * _easingsMath.p)) / p) *
550              0.5 +
551            c +
552            b
553          );
554        },
555        easeInBack: function (x, t, b, c, d, s) {
556          s = s || _easingsMath.o;
557          return c * (t /= d) * t * ((s + 1) * t - s) + b;
558        },
559        easeOutBack: function (x, t, b, c, d, s) {
560          s = s || _easingsMath.o;
561          return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
562        },
563        easeInOutBack: function (x, t, b, c, d, s) {
564          s = s || _easingsMath.o;
565          return (t /= d / 2) < 1
566            ? (c / 2) * (t * t * (((s *= 1.525) + 1) * t - s)) + b
567            : (c / 2) * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;
568        },
569        easeInBounce: function (x, t, b, c, d) {
570          return c - this.easeOutBounce(x, d - t, 0, c, d) + b;
571        },
572        easeOutBounce: function (x, t, b, c, d) {
573          var o = 7.5625;
574          if ((t /= d) < 1 / 2.75) {
575            return c * (o * t * t) + b;
576          } else if (t < 2 / 2.75) {
577            return c * (o * (t -= 1.5 / 2.75) * t + 0.75) + b;
578          } else if (t < 2.5 / 2.75) {
579            return c * (o * (t -= 2.25 / 2.75) * t + 0.9375) + b;
580          } else {
581            return c * (o * (t -= 2.625 / 2.75) * t + 0.984375) + b;
582          }
583        },
584        easeInOutBounce: function (x, t, b, c, d) {
585          return t < d / 2
586            ? this.easeInBounce(x, t * 2, 0, c, d) * 0.5 + b
587            : this.easeOutBounce(x, t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
588        },
589      };
590      /*
591       *
592       * TERMS OF USE - EASING EQUATIONS
593       *
594       * Open source under the BSD License.
595       *
596       * Copyright © 2001 Robert Penner
597       * All rights reserved.
598       *
599       * Redistribution and use in source and binary forms, with or without modification,
600       * are permitted provided that the following conditions are met:
601       *
602       * Redistributions of source code must retain the above copyright notice, this list of
603       * conditions and the following disclaimer.
604       * Redistributions in binary form must reproduce the above copyright notice, this list
605       * of conditions and the following disclaimer in the documentation and/or other materials
606       * provided with the distribution.
607       *
608       * Neither the name of the author nor the names of contributors may be used to endorse
609       * or promote products derived from this software without specific prior written permission.
610       *
611       * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
612       * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
613       * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
614       *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
615       *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
616       *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
617       * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
618       *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
619       * OF THE POSSIBILITY OF SUCH DAMAGE.
620       *
621       */
622    })();
623    var FRAMEWORK = (function () {
624      var _rnothtmlwhite = /[^\x20\t\r\n\f]+/g;
625      var _strSpace = " ";
626      var _strEmpty = "";
627      var _strScrollLeft = "scrollLeft";
628      var _strScrollTop = "scrollTop";
629      var _animations = [];
630      var _type = COMPATIBILITY.type;
631      var _cssNumber = {
632        animationIterationCount: true,
633        columnCount: true,
634        fillOpacity: true,
635        flexGrow: true,
636        flexShrink: true,
637        fontWeight: true,
638        lineHeight: true,
639        opacity: true,
640        order: true,
641        orphans: true,
642        widows: true,
643        zIndex: true,
644        zoom: true,
645      };
646
647      function extend() {
648        var src,
649          copyIsArray,
650          copy,
651          name,
652          options,
653          clone,
654          target = arguments[0] || {},
655          i = 1,
656          length = arguments[LEXICON.l],
657          deep = false;
658
659        // Handle a deep copy situation
660        if (_type(target) == TYPES.b) {
661          deep = target;
662          target = arguments[1] || {};
663          // skip the boolean and the target
664          i = 2;
665        }
666
667        // Handle case when target is a string or something (possible in deep copy)
668        if (_type(target) != TYPES.o && !_type(target) == TYPES.f) {
669          target = {};
670        }
671
672        // extend jQuery itself if only one argument is passed
673        if (length === i) {
674          target = FakejQuery;
675          --i;
676        }
677
678        for (; i < length; i++) {
679          // Only deal with non-null/undefined values
680          if ((options = arguments[i]) != null) {
681            // Extend the base object
682            for (name in options) {
683              src = target[name];
684              copy = options[name];
685
686              // Prevent never-ending loop
687              if (target === copy) {
688                continue;
689              }
690
691              // Recurse if we're merging plain objects or arrays
692              if (
693                deep &&
694                copy &&
695                (isPlainObject(copy) || (copyIsArray = COMPATIBILITY.isA(copy)))
696              ) {
697                if (copyIsArray) {
698                  copyIsArray = false;
699                  clone = src && COMPATIBILITY.isA(src) ? src : [];
700                } else {
701                  clone = src && isPlainObject(src) ? src : {};
702                }
703
704                // Never move original objects, clone them
705                target[name] = extend(deep, clone, copy);
706
707                // Don't bring in undefined values
708              } else if (copy !== undefined) {
709                target[name] = copy;
710              }
711            }
712          }
713        }
714
715        // Return the modified object
716        return target;
717      }
718
719      function inArray(item, arr, fromIndex) {
720        for (var i = fromIndex || 0; i < arr[LEXICON.l]; i++)
721          if (arr[i] === item) return i;
722        return -1;
723      }
724
725      function isFunction(obj) {
726        return _type(obj) == TYPES.f;
727      }
728
729      function isEmptyObject(obj) {
730        for (var name in obj) return false;
731        return true;
732      }
733
734      function isPlainObject(obj) {
735        if (!obj || _type(obj) != TYPES.o) return false;
736
737        var key;
738        var proto = LEXICON.p;
739        var hasOwnProperty = Object[proto].hasOwnProperty;
740        var hasOwnConstructor = hasOwnProperty.call(obj, "constructor");
741        var hasIsPrototypeOf =
742          obj.constructor &&
743          obj.constructor[proto] &&
744          hasOwnProperty.call(obj.constructor[proto], "isPrototypeOf");
745
746        if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
747          return false;
748        }
749
750        for (key in obj) {
751          /**/
752        }
753
754        return _type(key) == TYPES.u || hasOwnProperty.call(obj, key);
755      }
756
757      function each(obj, callback) {
758        var i = 0;
759
760        if (isArrayLike(obj)) {
761          for (; i < obj[LEXICON.l]; i++) {
762            if (callback.call(obj[i], i, obj[i]) === false) break;
763          }
764        } else {
765          for (i in obj) {
766            if (callback.call(obj[i], i, obj[i]) === false) break;
767          }
768        }
769
770        return obj;
771      }
772
773      function isArrayLike(obj) {
774        var length = !!obj && [LEXICON.l] in obj && obj[LEXICON.l];
775        var t = _type(obj);
776        return isFunction(t)
777          ? false
778          : t == TYPES.a ||
779              length === 0 ||
780              (_type(length) == TYPES.n && length > 0 && length - 1 in obj);
781      }
782
783      function stripAndCollapse(value) {
784        var tokens = value.match(_rnothtmlwhite) || [];
785        return tokens.join(_strSpace);
786      }
787
788      function matches(elem, selector) {
789        var nodeList =
790          (elem.parentNode || document).querySelectorAll(selector) || [];
791        var i = nodeList[LEXICON.l];
792
793        while (i--) if (nodeList[i] == elem) return true;
794
795        return false;
796      }
797
798      function insertAdjacentElement(el, strategy, child) {
799        if (COMPATIBILITY.isA(child)) {
800          for (var i = 0; i < child[LEXICON.l]; i++)
801            insertAdjacentElement(el, strategy, child[i]);
802        } else if (_type(child) == TYPES.s)
803          el.insertAdjacentHTML(strategy, child);
804        else
805          el.insertAdjacentElement(strategy, child.nodeType ? child : child[0]);
806      }
807
808      function setCSSVal(el, prop, val) {
809        try {
810          if (el[LEXICON.s][prop] !== undefined)
811            el[LEXICON.s][prop] = parseCSSVal(prop, val);
812        } catch (e) {}
813      }
814
815      function parseCSSVal(prop, val) {
816        if (!_cssNumber[prop.toLowerCase()] && _type(val) == TYPES.n)
817          val += "px";
818        return val;
819      }
820
821      function startNextAnimationInQ(animObj, removeFromQ) {
822        var index;
823        var nextAnim;
824        if (removeFromQ !== false) animObj.q.splice(0, 1);
825        if (animObj.q[LEXICON.l] > 0) {
826          nextAnim = animObj.q[0];
827          animate(
828            animObj.el,
829            nextAnim.props,
830            nextAnim.duration,
831            nextAnim.easing,
832            nextAnim.complete,
833            true
834          );
835        } else {
836          index = inArray(animObj, _animations);
837          if (index > -1) _animations.splice(index, 1);
838        }
839      }
840
841      function setAnimationValue(el, prop, value) {
842        if (prop === _strScrollLeft || prop === _strScrollTop) el[prop] = value;
843        else setCSSVal(el, prop, value);
844      }
845
846      function animate(el, props, options, easing, complete, guaranteedNext) {
847        var hasOptions = isPlainObject(options);
848        var from = {};
849        var to = {};
850        var i = 0;
851        var key;
852        var animObj;
853        var start;
854        var progress;
855        var step;
856        var specialEasing;
857        var duration;
858        if (hasOptions) {
859          easing = options.easing;
860          start = options.start;
861          progress = options.progress;
862          step = options.step;
863          specialEasing = options.specialEasing;
864          complete = options.complete;
865          duration = options.duration;
866        } else duration = options;
867        specialEasing = specialEasing || {};
868        duration = duration || 400;
869        easing = easing || "swing";
870        guaranteedNext = guaranteedNext || false;
871
872        for (; i < _animations[LEXICON.l]; i++) {
873          if (_animations[i].el === el) {
874            animObj = _animations[i];
875            break;
876          }
877        }
878
879        if (!animObj) {
880          animObj = {
881            el: el,
882            q: [],
883          };
884          _animations.push(animObj);
885        }
886
887        for (key in props) {
888          if (key === _strScrollLeft || key === _strScrollTop)
889            from[key] = el[key];
890          else from[key] = FakejQuery(el).css(key);
891        }
892
893        for (key in from) {
894          if (from[key] !== props[key] && props[key] !== undefined)
895            to[key] = props[key];
896        }
897
898        if (!isEmptyObject(to)) {
899          var timeNow;
900          var end;
901          var percent;
902          var fromVal;
903          var toVal;
904          var easedVal;
905          var timeStart;
906          var frame;
907          var elapsed;
908          var qPos = guaranteedNext ? 0 : inArray(qObj, animObj.q);
909          var qObj = {
910            props: to,
911            duration: hasOptions ? options : duration,
912            easing: easing,
913            complete: complete,
914          };
915          if (qPos === -1) {
916            qPos = animObj.q[LEXICON.l];
917            animObj.q.push(qObj);
918          }
919
920          if (qPos === 0) {
921            if (duration > 0) {
922              timeStart = COMPATIBILITY.now();
923              frame = function () {
924                timeNow = COMPATIBILITY.now();
925                elapsed = timeNow - timeStart;
926                end = qObj.stop || elapsed >= duration;
927                percent =
928                  1 -
929                  (MATH.max(0, timeStart + duration - timeNow) / duration || 0);
930
931                for (key in to) {
932                  fromVal = parseFloat(from[key]);
933                  toVal = parseFloat(to[key]);
934                  easedVal =
935                    (toVal - fromVal) *
936                      EASING[specialEasing[key] || easing](
937                        percent,
938                        percent * duration,
939                        0,
940                        1,
941                        duration
942                      ) +
943                    fromVal;
944                  setAnimationValue(el, key, easedVal);
945                  if (isFunction(step)) {
946                    step(easedVal, {
947                      elem: el,
948                      prop: key,
949                      start: fromVal,
950                      now: easedVal,
951                      end: toVal,
952                      pos: percent,
953                      options: {
954                        easing: easing,
955                        speacialEasing: specialEasing,
956                        duration: duration,
957                        complete: complete,
958                        step: step,
959                      },
960                      startTime: timeStart,
961                    });
962                  }
963                }
964
965                if (isFunction(progress))
966                  progress({}, percent, MATH.max(0, duration - elapsed));
967
968                if (end) {
969                  startNextAnimationInQ(animObj);
970                  if (isFunction(complete)) complete();
971                } else qObj.frame = COMPATIBILITY.rAF()(frame);
972              };
973              qObj.frame = COMPATIBILITY.rAF()(frame);
974            } else {
975              for (key in to) setAnimationValue(el, key, to[key]);
976              startNextAnimationInQ(animObj);
977            }
978          }
979        } else if (guaranteedNext) startNextAnimationInQ(animObj);
980      }
981
982      function stop(el, clearQ, jumpToEnd) {
983        var animObj;
984        var qObj;
985        var key;
986        var i = 0;
987        for (; i < _animations[LEXICON.l]; i++) {
988          animObj = _animations[i];
989          if (animObj.el === el) {
990            if (animObj.q[LEXICON.l] > 0) {
991              qObj = animObj.q[0];
992              qObj.stop = true;
993              COMPATIBILITY.cAF()(qObj.frame);
994              animObj.q.splice(0, 1);
995
996              if (jumpToEnd)
997                for (key in qObj.props)
998                  setAnimationValue(el, key, qObj.props[key]);
999
1000              if (clearQ) animObj.q = [];
1001              else startNextAnimationInQ(animObj, false);
1002            }
1003            break;
1004          }
1005        }
1006      }
1007
1008      function elementIsVisible(el) {
1009        return !!(
1010          el[LEXICON.oW] ||
1011          el[LEXICON.oH] ||
1012          el.getClientRects()[LEXICON.l]
1013        );
1014      }
1015
1016      function FakejQuery(selector) {
1017        if (arguments[LEXICON.l] === 0) return this;
1018
1019        var base = new FakejQuery();
1020        var elements = selector;
1021        var i = 0;
1022        var elms;
1023        var el;
1024
1025        if (_type(selector) == TYPES.s) {
1026          elements = [];
1027          if (selector.charAt(0) === "<") {
1028            el = document.createElement("div");
1029            el.innerHTML = selector;
1030            elms = el.children;
1031          } else {
1032            elms = document.querySelectorAll(selector);
1033          }
1034
1035          for (; i < elms[LEXICON.l]; i++) elements.push(elms[i]);
1036        }
1037
1038        if (elements) {
1039          if (
1040            _type(elements) != TYPES.s &&
1041            (!isArrayLike(elements) ||
1042              elements === window ||
1043              elements === elements.self)
1044          )
1045            elements = [elements];
1046
1047          for (i = 0; i < elements[LEXICON.l]; i++) base[i] = elements[i];
1048
1049          base[LEXICON.l] = elements[LEXICON.l];
1050        }
1051
1052        return base;
1053      }
1054
1055      FakejQuery[LEXICON.p] = {
1056        //EVENTS:
1057
1058        on: function (eventName, handler) {
1059          eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [
1060            _strEmpty,
1061          ];
1062
1063          var eventNameLength = eventName[LEXICON.l];
1064          var i = 0;
1065          var el;
1066          return this.each(function () {
1067            el = this;
1068            try {
1069              if (el.addEventListener) {
1070                for (; i < eventNameLength; i++)
1071                  el.addEventListener(eventName[i], handler);
1072              } else if (el.detachEvent) {
1073                for (; i < eventNameLength; i++)
1074                  el.attachEvent("on" + eventName[i], handler);
1075              }
1076            } catch (e) {}
1077          });
1078        },
1079
1080        off: function (eventName, handler) {
1081          eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [
1082            _strEmpty,
1083          ];
1084
1085          var eventNameLength = eventName[LEXICON.l];
1086          var i = 0;
1087          var el;
1088          return this.each(function () {
1089            el = this;
1090            try {
1091              if (el.removeEventListener) {
1092                for (; i < eventNameLength; i++)
1093                  el.removeEventListener(eventName[i], handler);
1094              } else if (el.detachEvent) {
1095                for (; i < eventNameLength; i++)
1096                  el.detachEvent("on" + eventName[i], handler);
1097              }
1098            } catch (e) {}
1099          });
1100        },
1101
1102        one: function (eventName, handler) {
1103          eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [
1104            _strEmpty,
1105          ];
1106          return this.each(function () {
1107            var el = FakejQuery(this);
1108            FakejQuery.each(eventName, function (i, oneEventName) {
1109              var oneHandler = function (e) {
1110                handler.call(this, e);
1111                el.off(oneEventName, oneHandler);
1112              };
1113              el.on(oneEventName, oneHandler);
1114            });
1115          });
1116        },
1117
1118        trigger: function (eventName) {
1119          var el;
1120          var event;
1121          return this.each(function () {
1122            el = this;
1123            if (document.createEvent) {
1124              event = document.createEvent("HTMLEvents");
1125              event.initEvent(eventName, true, false);
1126              el.dispatchEvent(event);
1127            } else {
1128              el.fireEvent("on" + eventName);
1129            }
1130          });
1131        },
1132
1133        //DOM NODE INSERTING / REMOVING:
1134
1135        append: function (child) {
1136          return this.each(function () {
1137            insertAdjacentElement(this, "beforeend", child);
1138          });
1139        },
1140
1141        prepend: function (child) {
1142          return this.each(function () {
1143            insertAdjacentElement(this, "afterbegin", child);
1144          });
1145        },
1146
1147        before: function (child) {
1148          return this.each(function () {
1149            insertAdjacentElement(this, "beforebegin", child);
1150          });
1151        },
1152
1153        after: function (child) {
1154          return this.each(function () {
1155            insertAdjacentElement(this, "afterend", child);
1156          });
1157        },
1158
1159        remove: function () {
1160          return this.each(function () {
1161            var el = this;
1162            var parentNode = el.parentNode;
1163            if (parentNode != null) parentNode.removeChild(el);
1164          });
1165        },
1166
1167        unwrap: function () {
1168          var parents = [];
1169          var i;
1170          var el;
1171          var parent;
1172
1173          this.each(function () {
1174            parent = this.parentNode;
1175            if (inArray(parent, parents) === -1) parents.push(parent);
1176          });
1177
1178          for (i = 0; i < parents[LEXICON.l]; i++) {
1179            el = parents[i];
1180            parent = el.parentNode;
1181            while (el.firstChild) parent.insertBefore(el.firstChild, el);
1182            parent.removeChild(el);
1183          }
1184
1185          return this;
1186        },
1187
1188        wrapAll: function (wrapperHTML) {
1189          var i;
1190          var nodes = this;
1191          var wrapper = FakejQuery(wrapperHTML)[0];
1192          var deepest = wrapper;
1193          var parent = nodes[0].parentNode;
1194          var previousSibling = nodes[0].previousSibling;
1195          while (deepest.childNodes[LEXICON.l] > 0)
1196            deepest = deepest.childNodes[0];
1197
1198          for (
1199            i = 0;
1200            nodes[LEXICON.l] - i;
1201            deepest.firstChild === nodes[0] && i++
1202          )
1203            deepest.appendChild(nodes[i]);
1204
1205          var nextSibling = previousSibling
1206            ? previousSibling.nextSibling
1207            : parent.firstChild;
1208          parent.insertBefore(wrapper, nextSibling);
1209
1210          return this;
1211        },
1212
1213        wrapInner: function (wrapperHTML) {
1214          return this.each(function () {
1215            var el = FakejQuery(this);
1216            var contents = el.contents();
1217
1218            if (contents[LEXICON.l]) contents.wrapAll(wrapperHTML);
1219            else el.append(wrapperHTML);
1220          });
1221        },
1222
1223        wrap: function (wrapperHTML) {
1224          return this.each(function () {
1225            FakejQuery(this).wrapAll(wrapperHTML);
1226          });
1227        },
1228
1229        //DOM NODE MANIPULATION / INFORMATION:
1230
1231        css: function (styles, val) {
1232          var el;
1233          var key;
1234          var cptStyle;
1235          var getCptStyle = window.getComputedStyle;
1236          if (_type(styles) == TYPES.s) {
1237            if (val === undefined) {
1238              el = this[0];
1239              cptStyle = getCptStyle
1240                ? getCptStyle(el, null)
1241                : el.currentStyle[styles];
1242
1243              //https://bugzilla.mozilla.org/show_bug.cgi?id=548397 can be null sometimes if iframe with display: none (firefox only!)
1244              return getCptStyle
1245                ? cptStyle != null
1246                  ? cptStyle.getPropertyValue(styles)
1247                  : el[LEXICON.s][styles]
1248                : cptStyle;
1249            } else {
1250              return this.each(function () {
1251                setCSSVal(this, styles, val);
1252              });
1253            }
1254          } else {
1255            return this.each(function () {
1256              for (key in styles) setCSSVal(this, key, styles[key]);
1257            });
1258          }
1259        },
1260
1261        hasClass: function (className) {
1262          var elem,
1263            i = 0;
1264          var classNamePrepared = _strSpace + className + _strSpace;
1265          var classList;
1266
1267          while ((elem = this[i++])) {
1268            classList = elem.classList;
1269            if (classList && classList.contains(className)) return true;
1270            else if (
1271              elem.nodeType === 1 &&
1272              (
1273                _strSpace +
1274                stripAndCollapse(elem.className + _strEmpty) +
1275                _strSpace
1276              ).indexOf(classNamePrepared) > -1
1277            )
1278              return true;
1279          }
1280
1281          return false;
1282        },
1283
1284        addClass: function (className) {
1285          var classes;
1286          var elem;
1287          var cur;
1288          var curValue;
1289          var clazz;
1290          var finalValue;
1291          var supportClassList;
1292          var elmClassList;
1293          var i = 0;
1294          var v = 0;
1295
1296          if (className) {
1297            classes = className.match(_rnothtmlwhite) || [];
1298
1299            while ((elem = this[i++])) {
1300              elmClassList = elem.classList;
1301              if (supportClassList === undefined)
1302                supportClassList = elmClassList !== undefined;
1303
1304              if (supportClassList) {
1305                while ((clazz = classes[v++])) elmClassList.add(clazz);
1306              } else {
1307                curValue = elem.className + _strEmpty;
1308                cur =
1309                  elem.nodeType === 1 &&
1310                  _strSpace + stripAndCollapse(curValue) + _strSpace;
1311
1312                if (cur) {
1313                  while ((clazz = classes[v++]))
1314                    if (cur.indexOf(_strSpace + clazz + _strSpace) < 0)
1315                      cur += clazz + _strSpace;
1316
1317                  finalValue = stripAndCollapse(cur);
1318                  if (curValue !== finalValue) elem.className = finalValue;
1319                }
1320              }
1321            }
1322          }
1323
1324          return this;
1325        },
1326
1327        removeClass: function (className) {
1328          var classes;
1329          var elem;
1330          var cur;
1331          var curValue;
1332          var clazz;
1333          var finalValue;
1334          var supportClassList;
1335          var elmClassList;
1336          var i = 0;
1337          var v = 0;
1338
1339          if (className) {
1340            classes = className.match(_rnothtmlwhite) || [];
1341
1342            while ((elem = this[i++])) {
1343              elmClassList = elem.classList;
1344              if (supportClassList === undefined)
1345                supportClassList = elmClassList !== undefined;
1346
1347              if (supportClassList) {
1348                while ((clazz = classes[v++])) elmClassList.remove(clazz);
1349              } else {
1350                curValue = elem.className + _strEmpty;
1351                cur =
1352                  elem.nodeType === 1 &&
1353                  _strSpace + stripAndCollapse(curValue) + _strSpace;
1354
1355                if (cur) {
1356                  while ((clazz = classes[v++]))
1357                    while (cur.indexOf(_strSpace + clazz + _strSpace) > -1)
1358                      cur = cur.replace(
1359                        _strSpace + clazz + _strSpace,
1360                        _strSpace
1361                      );
1362
1363                  finalValue = stripAndCollapse(cur);
1364                  if (curValue !== finalValue) elem.className = finalValue;
1365                }
1366              }
1367            }
1368          }
1369
1370          return this;
1371        },
1372
1373        hide: function () {
1374          return this.each(function () {
1375            this[LEXICON.s].display = "none";
1376          });
1377        },
1378
1379        show: function () {
1380          return this.each(function () {
1381            this[LEXICON.s].display = "block";
1382          });
1383        },
1384
1385        attr: function (attrName, value) {
1386          var i = 0;
1387          var el;
1388          while ((el = this[i++])) {
1389            if (value === undefined) return el.getAttribute(attrName);
1390            el.setAttribute(attrName, value);
1391          }
1392          return this;
1393        },
1394
1395        removeAttr: function (attrName) {
1396          return this.each(function () {
1397            this.removeAttribute(attrName);
1398          });
1399        },
1400
1401        offset: function () {
1402          var el = this[0];
1403          var rect = el[LEXICON.bCR]();
1404          var scrollLeft =
1405            window.pageXOffset || document.documentElement[_strScrollLeft];
1406          var scrollTop =
1407            window.pageYOffset || document.documentElement[_strScrollTop];
1408          return {
1409            top: rect.top + scrollTop,
1410            left: rect.left + scrollLeft,
1411          };
1412        },
1413
1414        position: function () {
1415          var el = this[0];
1416          return {
1417            top: el.offsetTop,
1418            left: el.offsetLeft,
1419          };
1420        },
1421
1422        scrollLeft: function (value) {
1423          var i = 0;
1424          var el;
1425          while ((el = this[i++])) {
1426            if (value === undefined) return el[_strScrollLeft];
1427            el[_strScrollLeft] = value;
1428          }
1429          return this;
1430        },
1431
1432        scrollTop: function (value) {
1433          var i = 0;
1434          var el;
1435          while ((el = this[i++])) {
1436            if (value === undefined) return el[_strScrollTop];
1437            el[_strScrollTop] = value;
1438          }
1439          return this;
1440        },
1441
1442        val: function (value) {
1443          var el = this[0];
1444          if (!value) return el.value;
1445          el.value = value;
1446          return this;
1447        },
1448
1449        //DOM TRAVERSAL / FILTERING:
1450
1451        first: function () {
1452          return this.eq(0);
1453        },
1454
1455        last: function () {
1456          return this.eq(-1);
1457        },
1458
1459        eq: function (index) {
1460          return FakejQuery(this[index >= 0 ? index : this[LEXICON.l] + index]);
1461        },
1462
1463        find: function (selector) {
1464          var children = [];
1465          var i;
1466          this.each(function () {
1467            var el = this;
1468            var ch = el.querySelectorAll(selector);
1469            for (i = 0; i < ch[LEXICON.l]; i++) children.push(ch[i]);
1470          });
1471          return FakejQuery(children);
1472        },
1473
1474        children: function (selector) {
1475          var children = [];
1476          var el;
1477          var ch;
1478          var i;
1479
1480          this.each(function () {
1481            ch = this.children;
1482            for (i = 0; i < ch[LEXICON.l]; i++) {
1483              el = ch[i];
1484              if (selector) {
1485                if (
1486                  (el.matches && el.matches(selector)) ||
1487                  matches(el, selector)
1488                )
1489                  children.push(el);
1490              } else children.push(el);
1491            }
1492          });
1493          return FakejQuery(children);
1494        },
1495
1496        parent: function (selector) {
1497          var parents = [];
1498          var parent;
1499          this.each(function () {
1500            parent = this.parentNode;
1501            if (selector ? FakejQuery(parent).is(selector) : true)
1502              parents.push(parent);
1503          });
1504          return FakejQuery(parents);
1505        },
1506
1507        is: function (selector) {
1508          var el;
1509          var i;
1510          for (i = 0; i < this[LEXICON.l]; i++) {
1511            el = this[i];
1512            if (selector === ":visible") return elementIsVisible(el);
1513            if (selector === ":hidden") return !elementIsVisible(el);
1514            if ((el.matches && el.matches(selector)) || matches(el, selector))
1515              return true;
1516          }
1517          return false;
1518        },
1519
1520        contents: function () {
1521          var contents = [];
1522          var childs;
1523          var i;
1524
1525          this.each(function () {
1526            childs = this.childNodes;
1527            for (i = 0; i < childs[LEXICON.l]; i++) contents.push(childs[i]);
1528          });
1529
1530          return FakejQuery(contents);
1531        },
1532
1533        each: function (callback) {
1534          return each(this, callback);
1535        },
1536
1537        //ANIMATION:
1538
1539        animate: function (props, duration, easing, complete) {
1540          return this.each(function () {
1541            animate(this, props, duration, easing, complete);
1542          });
1543        },
1544
1545        stop: function (clearQ, jump) {
1546          return this.each(function () {
1547            stop(this, clearQ, jump);
1548          });
1549        },
1550      };
1551
1552      extend(FakejQuery, {
1553        extend: extend,
1554        inArray: inArray,
1555        isEmptyObject: isEmptyObject,
1556        isPlainObject: isPlainObject,
1557        each: each,
1558      });
1559
1560      return FakejQuery;
1561    })();
1562    var INSTANCES = (function () {
1563      var _targets = [];
1564      var _instancePropertyString = "__overlayScrollbars__";
1565
1566      /**
1567       * Register, unregister or get a certain (or all) instances.
1568       * Register: Pass the target and the instance.
1569       * Unregister: Pass the target and null.
1570       * Get Instance: Pass the target from which the instance shall be got.
1571       * Get Targets: Pass no arguments.
1572       * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got
1573       * @param instance The instance.
1574       * @returns {*|void} Returns the instance from the given target.
1575       */
1576      return function (target, instance) {
1577        var argLen = arguments[LEXICON.l];
1578        if (argLen < 1) {
1579          //return all targets
1580          return _targets;
1581        } else {
1582          if (instance) {
1583            //register instance
1584            target[_instancePropertyString] = instance;
1585            _targets.push(target);
1586          } else {
1587            var index = COMPATIBILITY.inA(target, _targets);
1588            if (index > -1) {
1589              if (argLen > 1) {
1590                //unregister instance
1591                delete target[_instancePropertyString];
1592                _targets.splice(index, 1);
1593              } else {
1594                //get instance from target
1595                return _targets[index][_instancePropertyString];
1596              }
1597            }
1598          }
1599        }
1600      };
1601    })();
1602    var PLUGIN = (function () {
1603      var _plugin;
1604      var _pluginsGlobals;
1605      var _pluginsAutoUpdateLoop;
1606      var _pluginsExtensions = [];
1607      var _pluginsOptions = (function () {
1608        var type = COMPATIBILITY.type;
1609        var possibleTemplateTypes = [
1610          TYPES.b, //boolean
1611          TYPES.n, //number
1612          TYPES.s, //string
1613          TYPES.a, //array
1614          TYPES.o, //object
1615          TYPES.f, //function
1616          TYPES.z, //null
1617        ];
1618        var restrictedStringsSplit = " ";
1619        var restrictedStringsPossibilitiesSplit = ":";
1620        var classNameAllowedValues = [TYPES.z, TYPES.s];
1621        var numberAllowedValues = TYPES.n;
1622        var booleanNullAllowedValues = [TYPES.z, TYPES.b];
1623        var booleanTrueTemplate = [true, TYPES.b];
1624        var booleanFalseTemplate = [false, TYPES.b];
1625        var callbackTemplate = [null, [TYPES.z, TYPES.f]];
1626        var updateOnLoadTemplate = [["img"], [TYPES.s, TYPES.a, TYPES.z]];
1627        var inheritedAttrsTemplate = [
1628          ["style", "class"],
1629          [TYPES.s, TYPES.a, TYPES.z],
1630        ];
1631        var resizeAllowedValues = "n:none b:both h:horizontal v:vertical";
1632        var overflowBehaviorAllowedValues =
1633          "v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden";
1634        var scrollbarsVisibilityAllowedValues = "v:visible h:hidden a:auto";
1635        var scrollbarsAutoHideAllowedValues = "n:never s:scroll l:leave m:move";
1636        var optionsDefaultsAndTemplate = {
1637          className: ["os-theme-dark", classNameAllowedValues], //null || string
1638          resize: ["none", resizeAllowedValues], //none || both  || horizontal || vertical || n || b || h || v
1639          sizeAutoCapable: booleanTrueTemplate, //true || false
1640          clipAlways: booleanTrueTemplate, //true || false
1641          normalizeRTL: booleanTrueTemplate, //true || false
1642          paddingAbsolute: booleanFalseTemplate, //true || false
1643          autoUpdate: [null, booleanNullAllowedValues], //true || false || null
1644          autoUpdateInterval: [33, numberAllowedValues], //number
1645          updateOnLoad: updateOnLoadTemplate, //string || array || null
1646          nativeScrollbarsOverlaid: {
1647            showNativeScrollbars: booleanFalseTemplate, //true || false
1648            initialize: booleanTrueTemplate, //true || false
1649          },
1650          overflowBehavior: {
1651            x: ["scroll", overflowBehaviorAllowedValues], //visible-hidden  || visible-scroll || hidden || scroll || v-h || v-s || h || s
1652            y: ["scroll", overflowBehaviorAllowedValues], //visible-hidden  || visible-scroll || hidden || scroll || v-h || v-s || h || s
1653          },
1654          scrollbars: {
1655            visibility: ["auto", scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a
1656            autoHide: ["never", scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m
1657            autoHideDelay: [800, numberAllowedValues], //number
1658            dragScrolling: booleanTrueTemplate, //true || false
1659            clickScrolling: booleanFalseTemplate, //true || false
1660            touchSupport: booleanTrueTemplate, //true || false
1661            snapHandle: booleanFalseTemplate, //true || false
1662          },
1663          textarea: {
1664            dynWidth: booleanFalseTemplate, //true || false
1665            dynHeight: booleanFalseTemplate, //true || false
1666            inheritedAttrs: inheritedAttrsTemplate, //string || array || null
1667          },
1668          callbacks: {
1669            onInitialized: callbackTemplate, //null || function
1670            onInitializationWithdrawn: callbackTemplate, //null || function
1671            onDestroyed: callbackTemplate, //null || function
1672            onScrollStart: callbackTemplate, //null || function
1673            onScroll: callbackTemplate, //null || function
1674            onScrollStop: callbackTemplate, //null || function
1675            onOverflowChanged: callbackTemplate, //null || function
1676            onOverflowAmountChanged: callbackTemplate, //null || function
1677            onDirectionChanged: callbackTemplate, //null || function
1678            onContentSizeChanged: callbackTemplate, //null || function
1679            onHostSizeChanged: callbackTemplate, //null || function
1680            onUpdated: callbackTemplate, //null || function
1681          },
1682        };
1683        var convert = function (template) {
1684          var recursive = function (obj) {
1685            var key;
1686            var val;
1687            var valType;
1688            for (key in obj) {
1689              if (!obj[LEXICON.hOP](key)) continue;
1690              val = obj[key];
1691              valType = type(val);
1692              if (valType == TYPES.a) obj[key] = val[template ? 1 : 0];
1693              else if (valType == TYPES.o) obj[key] = recursive(val);
1694            }
1695            return obj;
1696          };
1697          return recursive(
1698            FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate)
1699          );
1700        };
1701
1702        return {
1703          _defaults: convert(),
1704
1705          _template: convert(true),
1706
1707          /**
1708           * Validates the passed object by the passed template.
1709           * @param obj The object which shall be validated.
1710           * @param template The template which defines the allowed values and types.
1711           * @param writeErrors True if errors shall be logged to the console.
1712           * @param diffObj If a object is passed then only valid differences to this object will be returned.
1713           * @returns {{}} A object which contains two objects called "default" and "prepared" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj.
1714           */
1715          _validate: function (obj, template, writeErrors, diffObj) {
1716            var validatedOptions = {};
1717            var validatedOptionsPrepared = {};
1718            var objectCopy = FRAMEWORK.extend(true, {}, obj);
1719            var inArray = FRAMEWORK.inArray;
1720            var isEmptyObj = FRAMEWORK.isEmptyObject;
1721            var checkObjectProps = function (
1722              data,
1723              template,
1724              diffData,
1725              validatedOptions,
1726              validatedOptionsPrepared,
1727              prevPropName
1728            ) {
1729              for (var prop in template) {
1730                if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) {
1731                  var isValid = false;
vendor: 7,474 bytes, lines 1732-1899
1732                  var isDiff = false;
1733                  var templateValue = template[prop];
1734                  var templateValueType = type(templateValue);
1735                  var templateIsComplex = templateValueType == TYPES.o;
1736                  var templateTypes = !COMPATIBILITY.isA(templateValue)
1737                    ? [templateValue]
1738                    : templateValue;
1739                  var dataDiffValue = diffData[prop];
1740                  var dataValue = data[prop];
1741                  var dataValueType = type(dataValue);
1742                  var propPrefix = prevPropName ? prevPropName + "." : "";
1743                  var error =
1744                    'The option "' +
1745                    propPrefix +
1746                    prop +
1747                    "\" wasn't set, because";
1748                  var errorPossibleTypes = [];
1749                  var errorRestrictedStrings = [];
1750                  var restrictedStringValuesSplit;
1751                  var restrictedStringValuesPossibilitiesSplit;
1752                  var isRestrictedValue;
1753                  var mainPossibility;
1754                  var currType;
1755                  var i;
1756                  var v;
1757                  var j;
1758
1759                  dataDiffValue =
1760                    dataDiffValue === undefined ? {} : dataDiffValue;
1761
1762                  //if the template has a object as value, it means that the options are complex (verschachtelt)
1763                  if (templateIsComplex && dataValueType == TYPES.o) {
1764                    validatedOptions[prop] = {};
1765                    validatedOptionsPrepared[prop] = {};
1766                    checkObjectProps(
1767                      dataValue,
1768                      templateValue,
1769                      dataDiffValue,
1770                      validatedOptions[prop],
1771                      validatedOptionsPrepared[prop],
1772                      propPrefix + prop
1773                    );
1774                    FRAMEWORK.each(
1775                      [data, validatedOptions, validatedOptionsPrepared],
1776                      function (index, value) {
1777                        if (isEmptyObj(value[prop])) {
1778                          delete value[prop];
1779                        }
1780                      }
1781                    );
1782                  } else if (!templateIsComplex) {
1783                    for (i = 0; i < templateTypes[LEXICON.l]; i++) {
1784                      currType = templateTypes[i];
1785                      templateValueType = type(currType);
1786                      //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix
1787                      isRestrictedValue =
1788                        templateValueType == TYPES.s &&
1789                        inArray(currType, possibleTemplateTypes) === -1;
1790                      if (isRestrictedValue) {
1791                        errorPossibleTypes.push(TYPES.s);
1792
1793                        //split it into a array which contains all possible values for example: ["y:yes", "n:no", "m:maybe"]
1794                        restrictedStringValuesSplit = currType.split(
1795                          restrictedStringsSplit
1796                        );
1797                        errorRestrictedStrings = errorRestrictedStrings.concat(
1798                          restrictedStringValuesSplit
1799                        );
1800                        for (
1801                          v = 0;
1802                          v < restrictedStringValuesSplit[LEXICON.l];
1803                          v++
1804                        ) {
1805                          //split the possible values into their possibiliteis for example: ["y", "yes"] -> the first is always the mainPossibility
1806                          restrictedStringValuesPossibilitiesSplit =
1807                            restrictedStringValuesSplit[v].split(
1808                              restrictedStringsPossibilitiesSplit
1809                            );
1810                          mainPossibility =
1811                            restrictedStringValuesPossibilitiesSplit[0];
1812                          for (
1813                            j = 0;
1814                            j <
1815                            restrictedStringValuesPossibilitiesSplit[LEXICON.l];
1816                            j++
1817                          ) {
1818                            //if any possibility matches with the dataValue, its valid
1819                            if (
1820                              dataValue ===
1821                              restrictedStringValuesPossibilitiesSplit[j]
1822                            ) {
1823                              isValid = true;
1824                              break;
1825                            }
1826                          }
1827                          if (isValid) break;
1828                        }
1829                      } else {
1830                        errorPossibleTypes.push(currType);
1831
1832                        if (dataValueType === currType) {
1833                          isValid = true;
1834                          break;
1835                        }
1836                      }
1837                    }
1838
1839                    if (isValid) {
1840                      isDiff = dataValue !== dataDiffValue;
1841
1842                      if (isDiff) validatedOptions[prop] = dataValue;
1843
1844                      if (
1845                        isRestrictedValue
1846                          ? inArray(
1847                              dataDiffValue,
1848                              restrictedStringValuesPossibilitiesSplit
1849                            ) < 0
1850                          : isDiff
1851                      )
1852                        validatedOptionsPrepared[prop] = isRestrictedValue
1853                          ? mainPossibility
1854                          : dataValue;
1855                    } else if (writeErrors) {
1856                      console.warn(
1857                        error +
1858                          " it doesn't accept the type [ " +
1859                          dataValueType.toUpperCase() +
1860                          ' ] with the value of "' +
1861                          dataValue +
1862                          '".\r\n' +
1863                          "Accepted types are: [ " +
1864                          errorPossibleTypes.join(", ").toUpperCase() +
1865                          " ]." +
1866                          (errorRestrictedStrings[length] > 0
1867                            ? "\r\nValid strings are: [ " +
1868                              errorRestrictedStrings
1869                                .join(", ")
1870                                .split(restrictedStringsPossibilitiesSplit)
1871                                .join(", ") +
1872                              " ]."
1873                            : "")
1874                      );
1875                    }
1876                    delete data[prop];
1877                  }
1878                }
1879              }
1880            };
1881            checkObjectProps(
1882              objectCopy,
1883              template,
1884              diffObj || {},
1885              validatedOptions,
1886              validatedOptionsPrepared
1887            );
1888
1889            //add values which aren't specified in the template to the finished validated object to prevent them from being discarded
1890            /*
1891                        if(keepForeignProps) {
1892                            FRAMEWORK.extend(true, validatedOptions, objectCopy);
1893                            FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy);
1894                        }
1895                        */
1896
1897            if (!isEmptyObj(objectCopy) && writeErrors)
1898              console.warn(
1899                "The following options are discarded due to invali
1899dity:\r\n" +
1900                  window.JSON.stringify(objectCopy, null, 2)
1901              );
1902
1903            return {
1904              _default: validatedOptions,
1905              _prepared: validatedOptionsPrepared,
1906            };
1907          },
1908        };
1909      })();
1910
1911      /**
1912       * Initializes the object which contains global information about the plugin and each instance of it.
1913       */
1914      function initOverlayScrollbarsStatics() {
1915        if (!_pluginsGlobals)
1916          _pluginsGlobals = new OverlayScrollbarsGlobals(
1917            _pluginsOptions._defaults
1918          );
1919        if (!_pluginsAutoUpdateLoop)
1920          _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(
1921            _pluginsGlobals
1922          );
1923      }
1924
1925      /**
1926       * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized.
1927       * @param defaultOptions
1928       * @constructor
1929       */
1930      function OverlayScrollbarsGlobals(defaultOptions) {
1931        var _base = this;
1932        var strOverflow = "overflow";
1933        var strHidden = "hidden";
1934        var strScroll = "scroll";
1935        var bodyElement = FRAMEWORK("body");
1936        var scrollbarDummyElement = FRAMEWORK(
1937          '<div id="os-dummy-scrollbar-size"><div></div></div>'
1938        );
1939        var scrollbarDummyElement0 = scrollbarDummyElement[0];
1940        var dummyContainerChild = FRAMEWORK(
1941          scrollbarDummyElement.children("div").eq(0)
1942        );
1943
1944        bodyElement.append(scrollbarDummyElement);
1945        scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring)
1946
1947        var nativeScrollbarSize = calcNativeScrollbarSize(
1948          scrollbarDummyElement0
1949        );
1950        var nativeScrollbarIsOverlaid = {
1951          x: nativeScrollbarSize.x === 0,
1952          y: nativeScrollbarSize.y === 0,
1953        };
1954        var msie = (function () {
1955          var ua = window.navigator.userAgent;
1956          var strIndexOf = "indexOf";
1957          var strSubString = "substring";
1958          var msie = ua[strIndexOf]("MSIE ");
1959          var trident = ua[strIndexOf]("Trident/");
1960          var edge = ua[strIndexOf]("Edge/");
1961          var rv = ua[strIndexOf]("rv:");
1962          var result;
1963          var parseIntFunc = parseInt;
1964
1965          // IE 10 or older => return version number
1966          if (msie > 0)
1967            result = parseIntFunc(
1968              ua[strSubString](msie + 5, ua[strIndexOf](".", msie)),
1969              10
1970            );
1971          // IE 11 => return version number
1972          else if (trident > 0)
1973            result = parseIntFunc(
1974              ua[strSubString](rv + 3, ua[strIndexOf](".", rv)),
1975              10
1976            );
1977          // Edge (IE 12+) => return version number
1978          else if (edge > 0)
1979            result = parseIntFunc(
1980              ua[strSubString](edge + 5, ua[strIndexOf](".", edge)),
1981              10
1982            );
1983
1984          // other browser
1985          return result;
1986        })();
1987
1988        FRAMEWORK.extend(_base, {
1989          defaultOptions: defaultOptions,
1990          msie: msie,
1991          autoUpdateLoop: false,
1992          autoUpdateRecommended: !COMPATIBILITY.mO(),
1993          nativeScrollbarSize: nativeScrollbarSize,
1994          nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid,
1995          nativeScrollbarStyling: (function () {
1996            var result = false;
1997            scrollbarDummyElement.addClass(
1998              "os-viewport-native-scrollbars-invisible"
1999            );
2000            try {
2001              result =
2002                (scrollbarDummyElement.css("scrollbar-width") === "none" &&
2003                  (msie > 9 || !msie)) ||
2004                window
2005                  .getComputedStyle(
2006                    scrollbarDummyElement0,
2007                    "::-webkit-scrollbar"
2008                  )
2009                  .getPropertyValue("display") === "none";
2010            } catch (ex) {}
2011
2012            //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style.
2013            //and set overflow to scroll
2014            //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show();
2015            //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0;
2016
2017            return result;
2018          })(),
2019          overlayScrollbarDummySize: { x: 30, y: 30 },
2020          cssCalc: VENDORS._cssPropertyValue("width", "calc", "(1px)") || null,
2021          restrictedMeasuring: (function () {
2022            //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305
2023            //since 1.11.0 always false -> fixed via CSS (hopefully)
2024            scrollbarDummyElement.css(strOverflow, strHidden);
2025            var scrollSize = {
2026              w: scrollbarDummyElement0[LEXICON.sW],
2027              h: scrollbarDummyElement0[LEXICON.sH],
2028            };
2029            scrollbarDummyElement.css(strOverflow, "visible");
2030            var scrollSize2 = {
2031              w: scrollbarDummyElement0[LEXICON.sW],
2032              h: scrollbarDummyElement0[LEXICON.sH],
2033            };
2034            return (
2035              scrollSize.w - scrollSize2.w !== 0 ||
2036              scrollSize.h - scrollSize2.h !== 0
2037            );
2038          })(),
2039          rtlScrollBehavior: (function () {
2040            scrollbarDummyElement
2041              .css({
2042                "overflow-y": strHidden,
2043                "overflow-x": strScroll,
2044                direction: "rtl",
2045              })
2046              .scrollLeft(0);
2047            var dummyContainerOffset = scrollbarDummyElement.offset();
2048            var dummyContainerChildOffset = dummyContainerChild.offset();
2049            //https://github.com/KingSora/OverlayScrollbars/issues/187
2050            scrollbarDummyElement.scrollLeft(-999);
2051            var dummyContainerChildOffsetAfterScroll =
2052              dummyContainerChild.offset();
2053            return {
2054              //origin direction = determines if the zero scroll position is on the left or right side
2055              //'i' means 'invert' (i === true means that the axis must be inverted to be correct)
2056              //true = on the left side
2057              //false = on the right side
2058              i: dummyContainerOffset.left === dummyContainerChildOffset.left,
2059              //negative = determines if the maximum scroll is positive or negative
2060              //'n' means 'negate' (n === true means that the axis must be negated to be correct)
2061              //true = negative
2062              //false = positive
2063              n:
2064                dummyContainerChildOffset.left !==
2065                dummyContainerChildOffsetAfterScroll.left,
2066            };
2067          })(),
2068          supportTransform: !!VENDORS._cssProperty("transform"),
2069          supportTransition: !!VENDORS._cssProperty("transition"),
2070          supportPassiveEvents: (function () {
2071            var supportsPassive = false;
2072            try {
2073              window.addEventListener(
2074                "test",
2075                null,
2076                Object.defineProperty({}, "passive", {
2077                  get: function () {
2078                    supportsPassive = true;
2079                  },
2080                })
2081              );
2082            } catch (e) {}
2083            return supportsPassive;
2084          })(),
2085          supportResizeObserver: !!COMPATIBILITY.rO(),
2086          supportMutationObserver: !!COMPATIBILITY.mO(),
2087        });
2088
2089        scrollbarDummyElement.removeAttr(LEXICON.s).remove();
2090
2091        //Catch zoom event:
2092        (function () {
2093          if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y)
2094            return;
2095
2096          var abs = MATH.abs;
vendor: 17,173 bytes, lines 2097-2528
2097          var windowWidth = COMPATIBILITY.wW();
2098          var windowHeight = COMPATIBILITY.wH();
2099          var windowDpr = getWindowDPR();
2100          var onResize = function () {
2101            if (INSTANCES().length > 0) {
2102              var newW = COMPATIBILITY.wW();
2103              var newH = COMPATIBILITY.wH();
2104              var deltaW = newW - windowWidth;
2105              var deltaH = newH - windowHeight;
2106
2107              if (deltaW === 0 && deltaH === 0) return;
2108
2109              var deltaWRatio = MATH.round(newW / (windowWidth / 100.0));
2110              var deltaHRatio = MATH.round(newH / (windowHeight / 100.0));
2111              var absDeltaW = abs(deltaW);
2112              var absDeltaH = abs(deltaH);
2113              var absDeltaWRatio = abs(deltaWRatio);
2114              var absDeltaHRatio = abs(deltaHRatio);
2115              var newDPR = getWindowDPR();
2116
2117              var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2;
2118              var difference = !differenceIsBiggerThanOne(
2119                absDeltaWRatio,
2120                absDeltaHRatio
2121              );
2122              var dprChanged = newDPR !== windowDpr && windowDpr > 0;
2123              var isZoom = deltaIsBigger && difference && dprChanged;
2124              var oldScrollbarSize = _base.nativeScrollbarSize;
2125              var newScrollbarSize;
2126
2127              if (isZoom) {
2128                bodyElement.append(scrollbarDummyElement);
2129                newScrollbarSize = _base.nativeScrollbarSize =
2130                  calcNativeScrollbarSize(scrollbarDummyElement[0]);
2131                scrollbarDummyElement.remove();
2132                if (
2133                  oldScrollbarSize.x !== newScrollbarSize.x ||
2134                  oldScrollbarSize.y !== newScrollbarSize.y
2135                ) {
2136                  FRAMEWORK.each(INSTANCES(), function () {
2137                    if (INSTANCES(this)) INSTANCES(this).update("zoom");
2138                  });
2139                }
2140              }
2141
2142              windowWidth = newW;
2143              windowHeight = newH;
2144              windowDpr = newDPR;
2145            }
2146          };
2147
2148          function differenceIsBiggerThanOne(valOne, valTwo) {
2149            var absValOne = abs(valOne);
2150            var absValTwo = abs(valTwo);
2151            return !(
2152              absValOne === absValTwo ||
2153              absValOne + 1 === absValTwo ||
2154              absValOne - 1 === absValTwo
2155            );
2156          }
2157
2158          function getWindowDPR() {
2159            var dDPI = window.screen.deviceXDPI || 0;
2160            var sDPI = window.screen.logicalXDPI || 1;
2161            return window.devicePixelRatio || dDPI / sDPI;
2162          }
2163
2164          FRAMEWORK(window).on("resize", onResize);
2165        })();
2166
2167        function calcNativeScrollbarSize(measureElement) {
2168          return {
2169            x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH],
2170            y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW],
2171          };
2172        }
2173      }
2174
2175      /**
2176       * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized.
2177       * @constructor
2178       */
2179      function OverlayScrollbarsAutoUpdateLoop(globals) {
2180        var _base = this;
2181        var _inArray = FRAMEWORK.inArray;
2182        var _getNow = COMPATIBILITY.now;
2183        var _strAutoUpdate = "autoUpdate";
2184        var _strAutoUpdateInterval = _strAutoUpdate + "Interval";
2185        var _strLength = LEXICON.l;
2186        var _loopingInstances = [];
2187        var _loopingInstancesIntervalCache = [];
2188        var _loopIsActive = false;
2189        var _loopIntervalDefault = 33;
2190        var _loopInterval = _loopIntervalDefault;
2191        var _loopTimeOld = _getNow();
2192        var _loopID;
2193
2194        /**
2195         * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds.
2196         */
2197        var loop = function () {
2198          if (_loopingInstances[_strLength] > 0 && _loopIsActive) {
2199            _loopID = COMPATIBILITY.rAF()(function () {
2200              loop();
2201            });
2202            var timeNew = _getNow();
2203            var timeDelta = timeNew - _loopTimeOld;
2204            var lowestInterval;
2205            var instance;
2206            var instanceOptions;
2207            var instanceAutoUpdateAllowed;
2208            var instanceAutoUpdateInterval;
2209            var now;
2210
2211            if (timeDelta > _loopInterval) {
2212              _loopTimeOld = timeNew - (timeDelta % _loopInterval);
2213              lowestInterval = _loopIntervalDefault;
2214              for (var i = 0; i < _loopingInstances[_strLength]; i++) {
2215                instance = _loopingInstances[i];
2216                if (instance !== undefined) {
2217                  instanceOptions = instance.options();
2218                  instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate];
2219                  instanceAutoUpdateInterval = MATH.max(
2220                    1,
2221                    instanceOptions[_strAutoUpdateInterval]
2222                  );
2223                  now = _getNow();
2224
2225                  if (
2226                    (instanceAutoUpdateAllowed === true ||
2227                      instanceAutoUpdateAllowed === null) &&
2228                    now - _loopingInstancesIntervalCache[i] >
2229                      instanceAutoUpdateInterval
2230                  ) {
2231                    instance.update("auto");
2232                    _loopingInstancesIntervalCache[i] = new Date(
2233                      (now += instanceAutoUpdateInterval)
2234                    );
2235                  }
2236
2237                  lowestInterval = MATH.max(
2238                    1,
2239                    MATH.min(lowestInterval, instanceAutoUpdateInterval)
2240                  );
2241                }
2242              }
2243              _loopInterval = lowestInterval;
2244            }
2245          } else {
2246            _loopInterval = _loopIntervalDefault;
2247          }
2248        };
2249
2250        /**
2251         * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added.
2252         * @param instance The instance which shall be updated in a loop automatically.
2253         */
2254        _base.add = function (instance) {
2255          if (_inArray(instance, _loopingInstances) === -1) {
2256            _loopingInstances.push(instance);
2257            _loopingInstancesIntervalCache.push(_getNow());
2258            if (_loopingInstances[_strLength] > 0 && !_loopIsActive) {
2259              _loopIsActive = true;
2260              globals.autoUpdateLoop = _loopIsActive;
2261              loop();
2262            }
2263          }
2264        };
2265
2266        /**
2267         * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before.
2268         * @param instance The instance which shall be updated in a loop automatically.
2269         */
2270        _base.remove = function (instance) {
2271          var index = _inArray(instance, _loopingInstances);
2272          if (index > -1) {
2273            //remove from loopingInstances list
2274            _loopingInstancesIntervalCache.splice(index, 1);
2275            _loopingInstances.splice(index, 1);
2276
2277            //correct update loop behavior
2278            if (_loopingInstances[_strLength] === 0 && _loopIsActive) {
2279              _loopIsActive = false;
2280              globals.autoUpdateLoop = _loopIsActive;
2281              if (_loopID !== undefined) {
2282                COMPATIBILITY.cAF()(_loopID);
2283                _loopID = -1;
2284              }
2285            }
2286          }
2287        };
2288      }
2289
2290      /**
2291       * A object which manages the scrollbars visibility of the target element.
2292       * @param pluginTargetElement The element from which the scrollbars shall be hidden.
2293       * @param options The custom options.
2294       * @param extensions The custom extensions.
2295       * @param globals
2296       * @param autoUpdateLoop
2297       * @returns {*}
2298       * @constructor
2299       */
2300      function OverlayScrollbarsInstance(
2301        pluginTargetElement,
2302        options,
2303        extensions,
2304        globals,
2305        autoUpdateLoop
2306      ) {
2307        //shortcuts
2308        var type = COMPATIBILITY.type;
2309        var inArray = FRAMEWORK.inArray;
2310        var each = FRAMEWORK.each;
2311
2312        //make correct instanceof
2313        var _base = new _plugin();
2314        var _frameworkProto = FRAMEWORK[LEXICON.p];
2315
2316        //if passed element is no HTML element: skip and return
2317        if (!isHTMLElement(pluginTargetElement)) return;
2318
2319        //if passed element is already initialized: set passed options if there are any and return its instance
2320        if (INSTANCES(pluginTargetElement)) {
2321          var inst = INSTANCES(pluginTargetElement);
2322          inst.options(options);
2323          return inst;
2324        }
2325
2326        //globals:
2327        var _nativeScrollbarIsOverlaid;
2328        var _overlayScrollbarDummySize;
2329        var _rtlScrollBehavior;
2330        var _autoUpdateRecommended;
2331        var _msieVersion;
2332        var _nativeScrollbarStyling;
2333        var _cssCalc;
2334        var _nativeScrollbarSize;
2335        var _supportTransition;
2336        var _supportTransform;
2337        var _supportPassiveEvents;
2338        var _supportResizeObserver;
2339        var _supportMutationObserver;
2340        var _restrictedMeasuring;
2341
2342        //general readonly:
2343        var _initialized;
2344        var _destroyed;
2345        var _isTextarea;
2346        var _isBody;
2347        var _documentMixed;
2348        var _domExists;
2349
2350        //general:
2351        var _isBorderBox;
2352        var _sizeAutoObserverAdded;
2353        var _paddingX;
2354        var _paddingY;
2355        var _borderX;
2356        var _borderY;
2357        var _marginX;
2358        var _marginY;
2359        var _isRTL;
2360        var _sleeping;
2361        var _contentBorderSize = {};
2362        var _scrollHorizontalInfo = {};
2363        var _scrollVerticalInfo = {};
2364        var _viewportSize = {};
2365        var _nativeScrollbarMinSize = {};
2366
2367        //naming:
2368        var _strMinusHidden = "-hidden";
2369        var _strMarginMinus = "margin-";
2370        var _strPaddingMinus = "padding-";
2371        var _strBorderMinus = "border-";
2372        var _strTop = "top";
2373        var _strRight = "right";
2374        var _strBottom = "bottom";
2375        var _strLeft = "left";
2376        var _strMinMinus = "min-";
2377        var _strMaxMinus = "max-";
2378        var _strWidth = "width";
2379        var _strHeight = "height";
2380        var _strFloat = "float";
2381        var _strEmpty = "";
2382        var _strAuto = "auto";
2383        var _strSync = "sync";
2384        var _strScroll = "scroll";
2385        var _strHundredPercent = "100%";
2386        var _strX = "x";
2387        var _strY = "y";
2388        var _strDot = ".";
2389        var _strSpace = " ";
2390        var _strScrollbar = "scrollbar";
2391        var _strMinusHorizontal = "-horizontal";
2392        var _strMinusVertical = "-vertical";
2393        var _strScrollLeft = _strScroll + "Left";
2394        var _strScrollTop = _strScroll + "Top";
2395        var _strMouseTouchDownEvent = "mousedown touchstart";
2396        var _strMouseTouchUpEvent = "mouseup touchend touchcancel";
2397        var _strMouseTouchMoveEvent = "mousemove touchmove";
2398        var _strMouseEnter = "mouseenter";
2399        var _strMouseLeave = "mouseleave";
2400        var _strKeyDownEvent = "keydown";
2401        var _strKeyUpEvent = "keyup";
2402        var _strSelectStartEvent = "selectstart";
2403        var _strTransitionEndEvent =
2404          "transitionend webkitTransitionEnd oTransitionEnd";
2405        var _strResizeObserverProperty = "__overlayScrollbarsRO__";
2406
2407        //class names:
2408        var _cassNamesPrefix = "os-";
2409        var _classNameHTMLElement = _cassNamesPrefix + "html";
2410        var _classNameHostElement = _cassNamesPrefix + "host";
2411        var _classNameHostElementForeign = _classNameHostElement + "-foreign";
2412        var _classNameHostTextareaElement = _classNameHostElement + "-textarea";
2413        var _classNameHostScrollbarHorizontalHidden =
2414          _classNameHostElement +
2415          "-" +
2416          _strScrollbar +
2417          _strMinusHorizontal +
2418          _strMinusHidden;
2419        var _classNameHostScrollbarVerticalHidden =
2420          _classNameHostElement +
2421          "-" +
2422          _strScrollbar +
2423          _strMinusVertical +
2424          _strMinusHidden;
2425        var _classNameHostTransition = _classNameHostElement + "-transition";
2426        var _classNameHostRTL = _classNameHostElement + "-rtl";
2427        var _classNameHostResizeDisabled =
2428          _classNameHostElement + "-resize-disabled";
2429        var _classNameHostScrolling = _classNameHostElement + "-scrolling";
2430        var _classNameHostOverflow = _classNameHostElement + "-overflow";
2431        var _classNameHostOverflow = _classNameHostElement + "-overflow";
2432        var _classNameHostOverflowX = _classNameHostOverflow + "-x";
2433        var _classNameHostOverflowY = _classNameHostOverflow + "-y";
2434        var _classNameTextareaElement = _cassNamesPrefix + "textarea";
2435        var _classNameTextareaCoverElement =
2436          _classNameTextareaElement + "-cover";
2437        var _classNamePaddingElement = _cassNamesPrefix + "padding";
2438        var _classNameViewportElement = _cassNamesPrefix + "viewport";
2439        var _classNameViewportNativeScrollbarsInvisible =
2440          _classNameViewportElement + "-native-scrollbars-invisible";
2441        var _classNameViewportNativeScrollbarsOverlaid =
2442          _classNameViewportElement + "-native-scrollbars-overlaid";
2443        var _classNameContentElement = _cassNamesPrefix + "content";
2444        var _classNameContentArrangeElement =
2445          _cassNamesPrefix + "content-arrange";
2446        var _classNameContentGlueElement = _cassNamesPrefix + "content-glue";
2447        var _classNameSizeAutoObserverElement =
2448          _cassNamesPrefix + "size-auto-observer";
2449        var _classNameResizeObserverElement =
2450          _cassNamesPrefix + "resize-observer";
2451        var _classNameResizeObserverItemElement =
2452          _cassNamesPrefix + "resize-observer-item";
2453        var _classNameResizeObserverItemFinalElement =
2454          _classNameResizeObserverItemElement + "-final";
2455        var _classNameTextInherit = _cassNamesPrefix + "text-inherit";
2456        var _classNameScrollbar = _cassNamesPrefix + _strScrollbar;
2457        var _classNameScrollbarTrack = _classNameScrollbar + "-track";
2458        var _classNameScrollbarTrackOff = _classNameScrollbarTrack + "-off";
2459        var _classNameScrollbarHandle = _classNameScrollbar + "-handle";
2460        var _classNameScrollbarHandleOff = _classNameScrollbarHandle + "-off";
2461        var _classNameScrollbarUnusable = _classNameScrollbar + "-unusable";
2462        var _classNameScrollbarAutoHidden =
2463          _classNameScrollbar + "-" + _strAuto + _strMinusHidden;
2464        var _classNameScrollbarCorner = _classNameScrollbar + "-corner";
2465        var _classNameScrollbarCornerResize =
2466          _classNameScrollbarCorner + "-resize";
2467        var _classNameScrollbarCornerResizeB =
2468          _classNameScrollbarCornerResize + "-both";
2469        var _classNameScrollbarCornerResizeH =
2470          _classNameScrollbarCornerResize + _strMinusHorizontal;
2471        var _classNameScrollbarCornerResizeV =
2472          _classNameScrollbarCornerResize + _strMinusVertical;
2473        var _classNameScrollbarHorizontal =
2474          _classNameScrollbar + _strMinusHorizontal;
2475        var _classNameScrollbarVertical =
2476          _classNameScrollbar + _strMinusVertical;
2477        var _classNameDragging = _cassNamesPrefix + "dragging";
2478        var _classNameThemeNone = _cassNamesPrefix + "theme-none";
2479        var _classNamesDynamicDestroy = [
2480          _classNameViewportNativeScrollbarsInvisible,
2481          _classNameViewportNativeScrollbarsOverlaid,
2482          _classNameScrollbarTrackOff,
2483          _classNameScrollbarHandleOff,
2484          _classNameScrollbarUnusable,
2485          _classNameScrollbarAutoHidden,
2486          _classNameScrollbarCornerResize,
2487          _classNameScrollbarCornerResizeB,
2488          _classNameScrollbarCornerResizeH,
2489          _classNameScrollbarCornerResizeV,
2490          _classNameDragging,
2491        ].join(_strSpace);
2492
2493        //callbacks:
2494        var _callbacksInitQeueue = [];
2495
2496        //attrs viewport shall inherit from target
2497        var _viewportAttrsFromTarget = [LEXICON.ti];
2498
2499        //options:
2500        var _defaultOptions;
2501        var _currentOptions;
2502        var _currentPreparedOptions;
2503
2504        //extensions:
2505        var _extensions = {};
2506        var _extensionsPrivateMethods = "added removed on contract";
2507
2508        //update
2509        var _lastUpdateTime;
2510        var _swallowedUpdateHints = {};
2511        var _swallowedUpdateTimeout;
2512        var _swallowUpdateLag = 42;
2513        var _updateOnLoadEventName = "load";
2514        var _updateOnLoadElms = [];
2515
2516        //DOM elements:
2517        var _windowElement;
2518        var _documentElement;
2519        var _htmlElement;
2520        var _bodyElement;
2521        var _targetElement; //the target element of this OverlayScrollbars object
2522        var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement
2523        var _sizeAutoObserverElement; //observes size auto changes
2524        var _sizeObserverElement; //observes size and padding changes
2525        var _paddingElement; //manages the padding
2526        var _viewportElement; //is the viewport of our scrollbar model
2527        var _contentElement; //the element which holds the content
2528        var _contentArrangeElement;
2528 //is needed for correct sizing of the content element (only if native scrollbars are overlays)
2529        var _contentGlueElement; //has always the size of the content element
2530        var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling
2531        var _scrollbarCornerElement;
2532        var _scrollbarHorizontalElement;
2533        var _scrollbarHorizontalTrackElement;
2534        var _scrollbarHorizontalHandleElement;
2535        var _scrollbarVerticalElement;
2536        var _scrollbarVerticalTrackElement;
2537        var _scrollbarVerticalHandleElement;
2538        var _windowElementNative;
2539        var _documentElementNative;
2540        var _targetElementNative;
2541        var _hostElementNative;
2542        var _sizeAutoObserverElementNative;
2543        var _sizeObserverElementNative;
2544        var _paddingElementNative;
2545        var _viewportElementNative;
2546        var _contentElementNative;
2547
2548        //Cache:
2549        var _hostSizeCache;
2550        var _contentScrollSizeCache;
2551        var _arrangeContentSizeCache;
2552        var _hasOverflowCache;
2553        var _hideOverflowCache;
2554        var _widthAutoCache;
2555        var _heightAutoCache;
2556        var _cssBoxSizingCache;
2557        var _cssPaddingCache;
2558        var _cssBorderCache;
2559        var _cssMarginCache;
2560        var _cssDirectionCache;
2561        var _cssDirectionDetectedCache;
2562        var _paddingAbsoluteCache;
2563        var _clipAlwaysCache;
2564        var _contentGlueSizeCache;
2565        var _overflowBehaviorCache;
2566        var _overflowAmountCache;
2567        var _ignoreOverlayScrollbarHidingCache;
2568        var _autoUpdateCache;
2569        var _sizeAutoCapableCache;
2570        var _contentElementScrollSizeChangeDetectedCache;
2571        var _hostElementSizeChangeDetectedCache;
2572        var _scrollbarsVisibilityCache;
2573        var _scrollbarsAutoHideCache;
2574        var _scrollbarsClickScrollingCache;
2575        var _scrollbarsDragScrollingCache;
2576        var _resizeCache;
2577        var _normalizeRTLCache;
2578        var _classNameCache;
2579        var _oldClassName;
2580        var _textareaAutoWrappingCache;
2581        var _textareaInfoCache;
2582        var _textareaSizeCache;
2583        var _textareaDynHeightCache;
2584        var _textareaDynWidthCache;
2585        var _bodyMinSizeCache;
2586        var _updateAutoCache = {};
2587
2588        //MutationObserver:
2589        var _mutationObserverHost;
2590        var _mutationObserverContent;
2591        var _mutationObserverHostCallback;
2592        var _mutationObserverContentCallback;
2593        var _mutationObserversConnected;
2594        var _mutationObserverAttrsTextarea = ["wrap", "cols", "rows"];
2595        var _mutationObserverAttrsHost = [
2596          LEXICON.i,
2597          LEXICON.c,
2598          LEXICON.s,
2599          "open",
2600        ].concat(_viewportAttrsFromTarget);
2601
2602        //events:
2603        var _destroyEvents = [];
2604
2605        //textarea:
2606        var _textareaHasFocus;
2607
2608        //scrollbars:
2609        var _scrollbarsAutoHideTimeoutId;
2610        var _scrollbarsAutoHideMoveTimeoutId;
2611        var _scrollbarsAutoHideDelay;
2612        var _scrollbarsAutoHideNever;
2613        var _scrollbarsAutoHideScroll;
2614        var _scrollbarsAutoHideMove;
2615        var _scrollbarsAutoHideLeave;
2616        var _scrollbarsHandleHovered;
2617        var _scrollbarsHandlesDefineScrollPos;
2618
2619        //resize
2620        var _resizeNone;
2621        var _resizeBoth;
2622        var _resizeHorizontal;
2623        var _resizeVertical;
2624
2625        //==== Event Listener ====//
2626
2627        /**
2628         * Adds or removes a event listener from the given element.
2629         * @param element The element to which the event listener shall be applied or removed.
2630         * @param eventNames The name(s) of the events.
2631         * @param listener The method which shall be called.
2632         * @param remove True if the handler shall be removed, false or undefined if the handler shall be added.
2633         * @param passiveOrOptions The options for the event.
2634         */
2635        function setupResponsiveEventListener(
2636          element,
2637          eventNames,
2638          listener,
2639          remove,
2640          passiveOrOptions
2641        ) {
2642          var collected =
2643            COMPATIBILITY.isA(eventNames) && COMPATIBILITY.isA(listener);
2644          var method = remove ? "removeEventListener" : "addEventListener";
2645          var onOff = remove ? "off" : "on";
2646          var events = collected ? false : eventNames.split(_strSpace);
2647          var i = 0;
2648
2649          var passiveOrOptionsIsObj = FRAMEWORK.isPlainObject(passiveOrOptions);
2650          var passive =
2651            (_supportPassiveEvents &&
2652              (passiveOrOptionsIsObj
2653                ? passiveOrOptions._passive
2654                : passiveOrOptions)) ||
2655            false;
2656          var capture =
2657            passiveOrOptionsIsObj && (passiveOrOptions._capture || false);
2658          var nativeParam = _supportPassiveEvents
2659            ? {
2660                passive: passive,
2661                capture: capture,
2662              }
2663            : capture;
2664
2665          if (collected) {
2666            for (; i < eventNames[LEXICON.l]; i++)
2667              setupResponsiveEventListener(
2668                element,
2669                eventNames[i],
2670                listener[i],
2671                remove,
2672                passiveOrOptions
2673              );
2674          } else {
2675            for (; i < events[LEXICON.l]; i++) {
2676              if (_supportPassiveEvents) {
2677                element[0][method](events[i], listener, nativeParam);
2678              } else {
2679                element[onOff](events[i], listener);
2680              }
2681            }
2682          }
2683        }
2684
2685        function addDestroyEventListener(
2686          element,
2687          eventNames,
2688          listener,
2689          passive
2690        ) {
2691          setupResponsiveEventListener(
2692            element,
2693            eventNames,
2694            listener,
2695            false,
2696            passive
2697          );
2698          _destroyEvents.push(
2699            COMPATIBILITY.bind(
2700              setupResponsiveEventListener,
2701              0,
2702              element,
2703              eventNames,
2704              listener,
2705              true,
2706              passive
2707            )
2708          );
2709        }
2710
2711        //==== Resize Observer ====//
2712
2713        /**
2714         * Adds or removes a resize observer from the given element.
2715         * @param targetElement The element to which the resize observer shall be added or removed.
2716         * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed.
2717         */
2718        function setupResizeObserver(targetElement, onElementResizedCallback) {
2719          if (targetElement) {
2720            var resizeObserver = COMPATIBILITY.rO();
2721            var strAnimationStartEvent =
2722              "animationstart mozAnimationStart webkitAnimationStart MSAnimationStart";
2723            var strChildNodes = "childNodes";
2724            var constScroll = 3333333;
2725            var callback = function () {
2726              targetElement[_strScrollTop](constScroll)[_strScrollLeft](
2727                _isRTL
2728                  ? _rtlScrollBehavior.n
2729                    ? -constScroll
2730                    : _rtlScrollBehavior.i
2731                    ? 0
2732                    : constScroll
2733                  : constScroll
2734              );
2735              onElementResizedCallback();
2736            };
2737            //add resize observer:
2738            if (onElementResizedCallback) {
2739              if (_supportResizeObserver) {
2740                var element = targetElement
2741                  .addClass("observed")
2742                  .append(generateDiv(_classNameResizeObserverElement))
2743                  .contents()[0];
2744                var observer = (element[_strResizeObserverProperty] =
2745                  new resizeObserver(callback));
2746                observer.observe(element);
2747              } else {
2748                if (_msieVersion > 9 || !_autoUpdateRecommended) {
2749                  targetElement.prepend(
2750                    generateDiv(
2751                      _classNameResizeObserverElement,
2752                      generateDiv(
2753                        { c: _classNameResizeObserverItemElement, dir: "ltr" },
2754                        generateDiv(
2755                          _classNameResizeObserverItemElement,
2756                          generateDiv(_classNameResizeObserverItemFinalElement)
2757                        ) +
2758                          generateDiv(
2759                            _classNameResizeObserverItemElement,
2760                            generateDiv({
2761                              c: _classNameResizeObserverItemFinalElement,
2762                              style: "width: 200%; height: 200%",
2763                            })
2764                          )
2765                      )
2766                    )
2767                  );
2768
2769                  var observerElement =
2770                    targetElement[0][strChildNodes][0][strChildNodes][0];
2771                  var shrinkElement = FRAMEWORK(
2772                    observerElement[strChildNodes][1]
2773                  );
2774                  var expandElement = FRAMEWORK(
2775                    observerElement[strChildNodes][0]
2776                  );
2777                  var expandElementChild = FRAMEWORK(
2778                    expandElement[0][strChildNodes][0]
2779                  );
2780                  var widthCache = observerElement[LEXICON.oW];
2781                  var heightCache = observerElement[LEXICON.oH];
2782                  var isDirty;
2783                  var rAFId;
2784                  var currWidth;
2785                  var currHeight;
2786                  var factor = 2;
2787                  var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!!
2788                  var reset = function () {
2789                    /*
2790                                         var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y;
2791                                         var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y;
2792                                         var expandChildCSS = {};
2793                                         expandChildCSS[_strWidth] = sizeResetWidth;
2794                                         expandChildCSS[_strHeight] = sizeResetHeight;
2795                                         expandElementChild.css(expandChildCSS);
2796
2797
2798                                         expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight);
2799                                         shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight);
2800                                         */
2801                    expandElement[_strScrollLeft](constScroll)[_strScrollTop](
2802                      constScroll
2803                    );
2804                    shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](
2805                      constScroll
2806                    );
2807                  };
2808                  var onResized = function () {
2809                    rAFId = 0;
2810                    if (!isDirty) return;
2811
2812                    widthCache = currWidth;
2813                    heightCache = currHeight;
2814                    callback();
2815                  };
2816                  var onScroll = function (event) {
2817                    currWidth = observerElement[LEXICON.oW];
2818                    currHeight = observerElement[LEXICON.oH];
2819                    isDirty =
2820                      currWidth != widthCache || currHeight != heightCache;
2821
2822                    if (event && isDirty && !rAFId) {
2823                      COMPATIBILITY.cAF()(rAFId);
2824                      rAFId = COMPATIBILITY.rAF()(onResized);
2825                    } else if (!event) onResized();
2826
2827                    reset();
2828                    if (event) {
2829                      COMPATIBILITY.prvD(event);
2830                      COMPATIBILITY.stpP(event);
2831                    }
2832                    return false;
2833                  };
2834                  var expandChildCSS = {};
2835                  var observerElementCSS = {};
2836
2837                  setTopRightBottomLeft(observerElementCSS, _strEmpty, [
2838                    -((nativeScrollbarSize.y + 1) * factor),
2839                    nativeScrollbarSize.x * -factor,
2840                    nativeScrollbarSize.y * -factor,
2841                    -((nativeScrollbarSize.x + 1) * factor),
2842                  ]);
2843
2844                  FRAMEWORK(observerElement).css(observerElementCSS);
2845                  expandElement.on(_strScroll, onScroll);
2846                  shrinkElement.on(_strScroll, onScroll);
2847                  targetElement.on(strAnimationStartEvent, function () {
2848                    onScroll(false);
2849                  });
2850                  //lets assume that the divs will never be that large and a constant value is enough
2851                  expandChildCSS[_strWidth] = constScroll;
2852                  expandChildCSS[_strHeight] = constScroll;
2853                  expandElementChild.css(expandChildCSS);
2854
2855                  reset();
2856                } else {
2857                  var attachEvent = _documentElementNative.attachEvent;
2858                  var isIE = _msieVersion !== undefined;
2859                  if (attachEvent) {
2860                    targetElement.prepend(
2861                      generateDiv(_classNameResizeObserverElement)
2862                    );
2863                    findFirst(
2864                      targetElement,
2865                      _strDot + _classNameResizeObserverElement
2866                    )[0].attachEvent("onresize", callback);
2867                  } else {
2868                    var obj = _documentElementNative.createElement(TYPES.o);
2869                    obj.setAttribute(LEXICON.ti, "-1");
2870                    obj.setAttribute(
2871                      LEXICON.c,
2872                      _classNameResizeObserverElement
2873                    );
2874                    obj.onload = function () {
2875                      var wnd = this.contentDocument.defaultView;
2876                      wnd.addEventListener("resize", callback);
2877                      wnd.document.documentElement.style.display = "none";
2878                    };
2879                    obj.type = "text/html";
2880                    if (isIE) targetElement.prepend(obj);
2881                    obj.data = "about:blank";
2882                    if (!isIE) targetElement.prepend(obj);
2883                    targetElement.on(strAnimationStartEvent, callback);
2884                  }
2885                }
2886              }
2887
2888              if (targetElement[0] === _sizeObserverElementNative) {
2889                var directionChanged = function () {
2890                  var dir = _hostElement.css("direction");
2891                  var css = {};
2892                  var scrollLeftValue = 0;
2893                  var result = false;
vendor: 9,470 bytes, lines 2894-3131
2894                  if (dir !== _cssDirectionDetectedCache) {
2895                    if (dir === "ltr") {
2896                      css[_strLeft] = 0;
2897                      css[_strRight] = _strAuto;
2898                      scrollLeftValue = constScroll;
2899                    } else {
2900                      css[_strLeft] = _strAuto;
2901                      css[_strRight] = 0;
2902                      scrollLeftValue = _rtlScrollBehavior.n
2903                        ? -constScroll
2904                        : _rtlScrollBehavior.i
2905                        ? 0
2906                        : constScroll;
2907                    }
2908                    //execution order is important for IE!!!
2909                    _sizeObserverElement.children().eq(0).css(css);
2910                    _sizeObserverElement[_strScrollLeft](scrollLeftValue)[
2911                      _strScrollTop
2912                    ](constScroll);
2913                    _cssDirectionDetectedCache = dir;
2914                    result = true;
2915                  }
2916                  return result;
2917                };
2918                directionChanged();
2919                addDestroyEventListener(
2920                  targetElement,
2921                  _strScroll,
2922                  function (event) {
2923                    if (directionChanged()) update();
2924                    COMPATIBILITY.prvD(event);
2925                    COMPATIBILITY.stpP(event);
2926                    return false;
2927                  }
2928                );
2929              }
2930            }
2931            //remove resize observer:
2932            else {
2933              if (_supportResizeObserver) {
2934                var element = targetElement.contents()[0];
2935                var resizeObserverObj = element[_strResizeObserverProperty];
2936                if (resizeObserverObj) {
2937                  resizeObserverObj.disconnect();
2938                  delete element[_strResizeObserverProperty];
2939                }
2940              } else {
2941                remove(
2942                  targetElement
2943                    .children(_strDot + _classNameResizeObserverElement)
2944                    .eq(0)
2945                );
2946              }
2947            }
2948          }
2949        }
2950
2951        /**
2952                 * Freezes or unfreezes the given resize observer.
2953                 * @param targetElement The element to which the target resize observer is applied.
2954                 * @param freeze True if the resize observer shall be frozen, false otherwise.
2955                 
2956                function freezeResizeObserver(targetElement, freeze) {
2957                    if (targetElement !== undefined) {
2958                        if(freeze) {
2959                            if (_supportResizeObserver) {
2960                                var element = targetElement.contents()[0];
2961                                element[_strResizeObserverProperty].unobserve(element);
2962                            }
2963                            else {
2964                                targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0);
2965                                var w = targetElement.css(_strWidth);
2966                                var h = targetElement.css(_strHeight);
2967                                var css = {};
2968                                css[_strWidth] = w;
2969                                css[_strHeight] = h;
2970                                targetElement.css(css);
2971                            }
2972                        }
2973                        else {
2974                            if (_supportResizeObserver) {
2975                                var element = targetElement.contents()[0];
2976                                element[_strResizeObserverProperty].observe(element);
2977                            }
2978                            else {
2979                                var css = { };
2980                                css[_strHeight] = _strEmpty;
2981                                css[_strWidth] = _strEmpty;
2982                                targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css);
2983                            }
2984                        }
2985                    }
2986                }
2987                */
2988
2989        //==== Mutation Observers ====//
2990
2991        /**
2992         * Creates MutationObservers for the host and content Element if they are supported.
2993         */
2994        function createMutationObservers() {
2995          if (_supportMutationObserver) {
2996            var mutationObserverContentLag = 11;
2997            var mutationObserver = COMPATIBILITY.mO();
2998            var contentLastUpdate = COMPATIBILITY.now();
2999            var mutationTarget;
3000            var mutationAttrName;
3001            var mutationIsClass;
3002            var oldMutationVal;
3003            var newClassVal;
3004            var hostClassNameRegex;
3005            var contentTimeout;
3006            var now;
3007            var sizeAuto;
3008            var action;
3009
3010            _mutationObserverHostCallback = function (mutations) {
3011              var doUpdate = false;
3012              var doUpdateForce = false;
3013              var mutation;
3014              var mutatedAttrs = [];
3015
3016              if (_initialized && !_sleeping) {
3017                each(mutations, function () {
3018                  mutation = this;
3019                  mutationTarget = mutation.target;
3020                  mutationAttrName = mutation.attributeName;
3021                  mutationIsClass = mutationAttrName === LEXICON.c;
3022                  oldMutationVal = mutation.oldValue;
3023                  newClassVal = mutationTarget.className;
3024
3025                  if (_domExists && mutationIsClass && !doUpdateForce) {
3026                    // if old class value contains _classNameHostElementForeign and new class value doesn't
3027                    if (
3028                      oldMutationVal.indexOf(_classNameHostElementForeign) >
3029                        -1 &&
3030                      newClassVal.indexOf(_classNameHostElementForeign) < 0
3031                    ) {
3032                      hostClassNameRegex = createHostClassNameRegExp(true);
3033                      _hostElementNative.className = newClassVal
3034                        .split(_strSpace)
3035                        .concat(
3036                          oldMutationVal
3037                            .split(_strSpace)
3038                            .filter(function (name) {
3039                              return name.match(hostClassNameRegex);
3040                            })
3041                        )
3042                        .join(_strSpace);
3043                      doUpdate = doUpdateForce = true;
3044                    }
3045                  }
3046
3047                  if (!doUpdate) {
3048                    doUpdate = mutationIsClass
3049                      ? hostClassNamesChanged(oldMutationVal, newClassVal)
3050                      : mutationAttrName === LEXICON.s
3051                      ? oldMutationVal !== mutationTarget[LEXICON.s].cssText
3052                      : true;
3053                  }
3054
3055                  mutatedAttrs.push(mutationAttrName);
3056                });
3057
3058                updateViewportAttrsFromTarget(mutatedAttrs);
3059
3060                if (doUpdate) _base.update(doUpdateForce || _strAuto);
3061              }
3062              return doUpdate;
3063            };
3064            _mutationObserverContentCallback = function (mutations) {
3065              var doUpdate = false;
3066              var mutation;
3067
3068              if (_initialized && !_sleeping) {
3069                each(mutations, function () {
3070                  mutation = this;
3071                  doUpdate = isUnknownMutation(mutation);
3072                  return !doUpdate;
3073                });
3074
3075                if (doUpdate) {
3076                  now = COMPATIBILITY.now();
3077                  sizeAuto = _heightAutoCache || _widthAutoCache;
3078                  action = function () {
3079                    if (!_destroyed) {
3080                      contentLastUpdate = now;
3081
3082                      //if cols, rows or wrap attr was changed
3083                      if (_isTextarea) textareaUpdate();
3084
3085                      if (sizeAuto) update();
3086                      else _base.update(_strAuto);
3087                    }
3088                  };
3089                  clearTimeout(contentTimeout);
3090                  if (
3091                    mutationObserverContentLag <= 0 ||
3092                    now - contentLastUpdate > mutationObserverContentLag ||
3093                    !sizeAuto
3094                  )
3095                    action();
3096                  else
3097                    contentTimeout = setTimeout(
3098                      action,
3099                      mutationObserverContentLag
3100                    );
3101                }
3102              }
3103              return doUpdate;
3104            };
3105
3106            _mutationObserverHost = new mutationObserver(
3107              _mutationObserverHostCallback
3108            );
3109            _mutationObserverContent = new mutationObserver(
3110              _mutationObserverContentCallback
3111            );
3112          }
3113        }
3114
3115        /**
3116         * Connects the MutationObservers if they are supported.
3117         */
3118        function connectMutationObservers() {
3119          if (_supportMutationObserver && !_mutationObserversConnected) {
3120            _mutationObserverHost.observe(_hostElementNative, {
3121              attributes: true,
3122              attributeOldValue: true,
3123              attributeFilter: _mutationObserverAttrsHost,
3124            });
3125
3126            _mutationObserverContent.observe(
3127              _isTextarea ? _targetElementNative : _contentElementNative,
3128              {
3129                attributes: true,
3130                attributeOldValue: true,
3131                subtree: !_isTextarea,
3132                childList: !_isTextarea,
3133                characterData: !_isTextarea,
3134                attributeFilter: _isTextarea
3135                  ? _mutationObserverAttrsTextarea
3136                  : _mutationObserverAttrsHost,
3137              }
3138            );
3139
3140            _mutationObserversConnected = true;
3141          }
3142        }
3143
3144        /**
3145         * Disconnects the MutationObservers if they are supported.
3146         */
3147        function disconnectMutationObservers() {
3148          if (_supportMutationObserver && _mutationObserversConnected) {
3149            _mutationObserverHost.disconnect();
3150            _mutationObserverContent.disconnect();
3151
3152            _mutationObserversConnected = false;
3153          }
3154        }
3155
3156        //==== Events of elements ====//
3157
3158        /**
3159         * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!!
3160         * It refreshes the hostResizedEventArgs and the hostSizeResizeCache.
3161         * If there are any size changes, the update method gets called.
3162         */
3163        function hostOnResized() {
3164          if (!_sleeping) {
3165            var changed;
3166            var hostSize = {
3167              w: _sizeObserverElementNative[LEXICON.sW],
3168              h: _sizeObserverElementNative[LEXICON.sH],
3169            };
3170
3171            changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache);
3172            _hostElementSizeChangeDetectedCache = hostSize;
3173            if (changed) update({ _hostSizeChanged: true });
3174          }
3175        }
3176
3177        /**
3178         * The mouse enter event of the host element. This event is only needed for the autoHide feature.
3179         */
3180        function hostOnMouseEnter() {
3181          if (_scrollbarsAutoHideLeave) refreshScrollbarsAutoHide(true);
3182        }
3183
3184        /**
3185         * The mouse leave event of the host element. This event is only needed for the autoHide feature.
3186         */
3187        function hostOnMouseLeave() {
3188          if (
3189            _scrollbarsAutoHideLeave &&
3190            !_bodyElement.hasClass(_classNameDragging)
3191          )
3192            refreshScrollbarsAutoHide(false);
3193        }
3194
3195        /**
3196         * The mouse move event of the host element. This event is only needed for the autoHide "move" feature.
3197         */
3198        function hostOnMouseMove() {
3199          if (_scrollbarsAutoHideMove) {
3200            refreshScrollbarsAutoHide(true);
3201            clearTimeout(_scrollbarsAutoHideMoveTimeoutId);
3202            _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () {
3203              if (_scrollbarsAutoHideMove && !_destroyed)
3204                refreshScrollbarsAutoHide(false);
3205            }, 100);
3206          }
3207        }
3208
3209        /**
3210         * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element.
3211         * @param event The select start event.
3212         */
3213        function documentOnSelectStart(event) {
3214          COMPATIBILITY.prvD(event);
3215          return false;
3216        }
3217
3218        /**
3219         * A callback which will be called after a element has loaded.
3220         */
3221        function updateOnLoadCallback(event) {
3222          if (!_destroyed) {
3223            var target = event.target;
3224            var elm = FRAMEWORK(event.target);
3225            var index = FRAMEWORK.inArray(target, _updateOnLoadElms);
3226            if (index > -1) {
3227              _updateOnLoadElms.splice(index, 1);
3228            }
3229
3230            eachUpdateOnLoad(function (i, updateOnLoadSelector) {
3231              if (elm.is(updateOnLoadSelector)) {
3232                update({ _contentSizeChanged: true });
3233              }
3234            });
3235          }
3236        }
3237
3238        /**
3239         * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars)
3240         * @param destroy Indicates whether the events shall be added or removed.
3241         */
3242        function setupHostMouseTouchEvents(destroy) {
3243          if (!destroy) setupHostMouseTouchEvents(true);
3244
3245          setupResponsiveEventListener(
3246            _hostElement,
3247            _strMouseTouchMoveEvent.split(_strSpace)[0],
3248            hostOnMouseMove,
3249            !_scrollbarsAutoHideMove || destroy,
3250            true
3251          );
3252          setupResponsiveEventListener(
3253            _hostElement,
3254            [_strMouseEnter, _strMouseLeave],
3255            [hostOnMouseEnter, hostOnMouseLeave],
3256            !_scrollbarsAutoHideLeave || destroy,
3257            true
3258          );
3259
3260          //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible
3261          if (!_initialized && !destroy)
3262            _hostElement.one("mouseover", hostOnMouseEnter);
3263        }
3264
3265        //==== Update Detection ====//
3266
3267        /**
3268         * Measures the min width and min height of the body element and refreshes the related cache.
3269         * @returns {boolean} True if the min width or min height has changed, false otherwise.
3270         */
3271        function bodyMinSizeChanged() {
3272          var bodyMinSize = {};
3273          if (_isBody && _contentArrangeElement) {
3274            bodyMinSize.w = parseToZeroOrNumber(
3275              _contentArrangeElement.css(_strMinMinus + _strWidth)
3276            );
3277            bodyMinSize.h = parseToZeroOrNumber(
3278              _contentArrangeElement.css(_strMinMinus + _strHeight)
3279            );
3280            bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache);
3281            bodyMinSize.f = true; //flag for "measured at least once"
3282          }
3283          _bodyMinSizeCache = bodyMinSize;
3284          return !!bodyMinSize.c;
3285        }
3286
3287        /**
3288         * Returns true if the class names really changed (new class without plugin host prefix)
3289         * @param oldClassNames The old ClassName string or array.
3290         * @param newClassNames The new ClassName string or array.
3291         * @returns {boolean} True if the class names has really changed, false otherwise.
3292         */
3293        function hostClassNamesChanged(oldClassNames, newClassNames) {
3294          var currClasses =
3295            typeof newClassNames == TYPES.s
3296              ? newClassNames.split(_strSpace)
3297              : [];
3298          var oldClasses =
3299            typeof oldClassNames == TYPES.s
3300              ? oldClassNames.split(_strSpace)
3301              : [];
3302          var diff = getArrayDifferences(oldClasses, currClasses);
3303
3304          // remove none theme from diff list to prevent update
3305          var idx = inArray(_classNameThemeNone, diff);
3306          var i;
3307          var regex;
3308
3309          if (idx > -1) diff.splice(idx, 1);
3310
3311          if (diff[LEXICON.l] > 0) {
3312            regex = createHostClassNameRegExp(true, true);
3313            for (i = 0; i < diff.length; i++) {
3314              if (!diff[i].match(regex)) {
3315                return true;
3316              }
3317            }
3318          }
3319          return false;
3320        }
3321
3322        /**
3323         * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown.
3324         * @param mutation The mutation which shall be checked.
3325         * @returns {boolean} True if the mutation is from a unknown element, false otherwise.
3326         */
3327        function isUnknownMutation(mutation) {
3328          var attributeName = mutation.attributeName;
3329          var mutationTarget = mutation.target;
3330          var mutationType = mutation.type;
3331          var strClosest = "closest";
3332
3333          if (mutationTarget === _contentElementNative)
3334            return attributeName === null;
3335          if (
3336            mutationType === "attributes" &&
3337            (attributeName === LEXICON.c || attributeName === LEXICON.s) &&
3338            !_isTextarea
3339          ) {
3340            //ignore className changes by the plugin
3341            if (
3342              attributeName === LEXICON.c &&
3343              FRAMEWORK(mutationTarget).hasClass(_classNameHostElement)
3344            )
3345              return hostClassNamesChanged(
3346                mutation.oldValue,
3347                mutationTarget.className
3348              );
3349
3350            //only do it of browser support it natively
3351            if (typeof mutationTarget[strClosest] != TYPES.f) return true;
3352            if (
3353              mutationTarget[strClosest](
3354                _strDot + _classNameResizeObserverElement
3355              ) !== null ||
3356              mutationTarget[strClosest](_strDot + _classNameScrollbar) !==
3357                null ||
3358              mutationTarget[strClosest](
3359                _strDot + _classNameScrollbarCorner
3360              ) !== null
3361            )
3362              return false;
3363          }
3364          return true;
3365        }
3366
3367        /**
3368         * Returns true if the content size was changed since the last time this method was called.
3369         * @returns {boolean} True if the content size was changed, false otherwise.
3370         */
3371        function updateAutoContentSizeChanged() {
3372          if (_sleeping) return false;
3373
3374          var contentMeasureElement = getContentMeasureElement();
3375          var textareaValueLength =
3376            _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache
3377              ? _targetElement.val().length
3378              : 0;
3379          var setCSS =
3380            !_mutationObserversConnected && _widthAutoCache && !_isTextarea;
3381          var css = {};
3382          var float;
3383          var bodyMinSizeC;
3384          var changed;
3385          var contentElementScrollSize;
3386
3387          if (setCSS) {
3388            float = _contentElement.css(_strFloat);
3389            css[_strFloat] = _isRTL ? _strRight : _strLeft;
3390            css[_strWidth] = _strAuto;
3391            _contentElement.css(css);
3392          }
3393          contentElementScrollSize = {
3394            w: contentMeasureElement[LEXICON.sW] + textareaValueLength,
3395            h: contentMeasureElement[LEXICON.sH] + textareaValueLength,
3396          };
3397          if (setCSS) {
3398            css[_strFloat] = float;
3399            css[_strWidth] = _strHundredPercent;
3400            _contentElement.css(css);
3401          }
3402
3403          bodyMinSizeC = bodyMinSizeChanged();
3404          changed = checkCache(
3405            contentElementScrollSize,
3406            _contentElementScrollSizeChangeDetectedCache
3407          );
3408
3409          _contentElementScrollSizeChangeDetectedCache =
3410            contentElementScrollSize;
3411
3412          return changed || bodyMinSizeC;
3413        }
3414
3415        /**
3416         * Returns true when a attribute which the MutationObserver would observe has changed.
3417         * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise.
3418         */
3419        function meaningfulAttrsChanged() {
3420          if (_sleeping || _mutationObserversConnected) return;
3421
3422          var elem;
3423          var curr;
3424          var cache;
3425          var changedAttrs = [];
3426          var checks = [
3427            {
3428              _elem: _hostElement,
3429              _attrs: _mutationObserverAttrsHost.concat(":visible"),
3430            },
3431            {
3432              _elem: _isTextarea ? _targetElement : undefined,
3433              _attrs: _mutationObserverAttrsTextarea,
3434            },
3435          ];
3436
3437          each(checks, function (index, check) {
3438            elem = check._elem;
3439            if (elem) {
3440              each(check._attrs, function (index, attr) {
3441                curr = attr.charAt(0) === ":" ? elem.is(attr) : elem.attr(attr);
3442                cache = _updateAutoCache[attr];
3443
3444                if (checkCache(curr, cache)) {
3445                  changedAttrs.push(attr);
3446                }
3447
3448                _updateAutoCache[attr] = curr;
3449              });
3450            }
3451          });
3452
3453          updateViewportAttrsFromTarget(changedAttrs);
3454
3455          return changedAttrs[LEXICON.l] > 0;
3456        }
3457
3458        /**
3459         * Checks is a CSS Property of a child element is affecting the scroll size of the content.
3460         * @param propertyName The CSS property name.
3461         * @returns {boolean} True if the property is affecting the content scroll size, false otherwise.
3462         */
3463        function isSizeAffectingCSSProperty(propertyName) {
3464          if (!_initialized) return true;
3465          var flexGrow = "flex-grow";
3466          var flexShrink = "flex-shrink";
3467          var flexBasis = "flex-basis";
3468          var affectingPropsX = [
3469            _strWidth,
3470            _strMinMinus + _strWidth,
3471            _strMaxMinus + _strWidth,
3472            _strMarginMinus + _strLeft,
3473            _strMarginMinus + _strRight,
3474            _strLeft,
3475            _strRight,
3476            "font-weight",
3477            "word-spacing",
3478            flexGrow,
3479            flexShrink,
3480            flexBasis,
3481          ];
3482          var affectingPropsXContentBox = [
3483            _strPaddingMinus + _strLeft,
3484            _strPaddingMinus + _strRight,
3485            _strBorderMinus + _strLeft + _strWidth,
3486            _strBorderMinus + _strRight + _strWidth,
3487          ];
3488          var affectingPropsY = [
3489            _strHeight,
3490            _strMinMinus + _strHeight,
3491            _strMaxMinus + _strHeight,
3492            _strMarginMinus + _strTop,
3493            _strMarginMinus + _strBottom,
3494            _strTop,
3495            _strBottom,
3496            "line-height",
3497            flexGrow,
3498            flexShrink,
3499            flexBasis,
3500          ];
3501          var affectingPropsYContentBox = [
3502            _strPaddingMinus + _strTop,
3503            _strPaddingMinus + _strBottom,
3504            _strBorderMinus + _strTop + _strWidth,
3505            _strBorderMinus + _strBottom + _strWidth,
3506          ];
3507          var _strS = "s";
3508          var _strVS = "v-s";
3509          var checkX =
3510            _overflowBehaviorCache.x === _strS ||
3511            _overflowBehaviorCache.x === _strVS;
3512          var checkY =
3513            _overflowBehaviorCache.y === _strS ||
3514            _overflowBehaviorCache.y === _strVS;
3515          var sizeIsAffected = false;
3516          var checkPropertyName = function (arr, name) {
3517            for (var i = 0; i < arr[LEXICON.l]; i++) {
3518              if (arr[i] === name) return true;
3519            }
3520            return false;
3521          };
3522
3523          if (checkY) {
3524            sizeIsAffected = checkPropertyName(affectingPropsY, propertyName);
3525            if (!sizeIsAffected && !_isBorderBox)
3526              sizeIsAffected = checkPropertyName(
3527                affectingPropsYContentBox,
3528                propertyName
3529              );
3530          }
3531          if (checkX && !sizeIsAffected) {
3532            sizeIsAffected = checkPropertyName(affectingPropsX, propertyName);
3533            if (!sizeIsAffected && !_isBorderBox)
3534              sizeIsAffected = checkPropertyName(
3535                affectingPropsXContentBox,
3536                propertyName
3537              );
3538          }
3539          return sizeIsAffected;
3540        }
3541
3542        //==== Update ====//
3543
3544        /**
3545         * Sets the attribute values of the viewport element to the values from the target element.
3546         * The value of a attribute is only set if the attribute is whitelisted.
3547         * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set.
3548         */
3549        function updateViewportAttrsFromTarget(attrs) {
3550          attrs = attrs || _viewportAttrsFromTarget;
3551          each(attrs, function (index, attr) {
3552            if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) {
3553              var targetAttr = _targetElement.attr(attr);
3554              if (type(targetAttr) == TYPES.s) {
3555                _viewportElement.attr(attr, targetAttr);
3556              } else {
3557                _viewportElement.removeAttr(attr);
3558              }
3559            }
3560          });
3561        }
3562
3563        /**
3564         * Updates the variables and size of the textarea element, and manages the scroll on new line or new character.
3565         */
3566        function textareaUpdate() {
3567          if (!_sleeping) {
3568            var wrapAttrOff = !_textareaAutoWrappingCache;
3569            var minWidth = _viewportSize.w;
3570            var minHeight = _viewportSize.h;
3571            var css = {};
3572            var doMeasure = _widthAutoCache || wrapAttrOff;
3573            var origWidth;
3574            var width;
3575            var origHeight;
3576            var height;
3577
3578            //reset min size
3579            css[_strMinMinus + _strWidth] = _strEmpty;
3580            css[_strMinMinus + _strHeight] = _strEmpty;
3581
3582            //set width auto
3583            css[_strWidth] = _strAuto;
3584            _targetElement.css(css);
3585
3586            //measure width
3587            origWidth = _targetElementNative[LEXICON.oW];
3588            width = doMeasure
3589              ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1)
3590              : 1;
3591            /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/
3592
3593            //set measured width
3594            css[_strWidth] = _widthAutoCache
3595              ? _strAuto /*width*/
3596              : _strHundredPercent;
3597            css[_strMinMinus + _strWidth] = _strHundredPercent;
3598
3599            //set height auto
3600            css[_strHeight] = _strAuto;
3601            _targetElement.css(css);
3602
3603            //measure height
3604            origHeight = _targetElementNative[LEXICON.oH];
3605            height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1);
3606
3607            //append correct size values
3608            css[_strWidth] = width;
3609            css[_strHeight] = height;
3610            _textareaCoverElement.css(css);
3611
3612            //apply min width / min height to prevent textarea collapsing
3613            css[_strMinMinus + _strWidth] =
3614              minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/;
3615            css[_strMinMinus + _strHeight] =
3616              minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/;
3617            _targetElement.css(css);
3618
3619            return {
3620              _originalWidth: origWidth,
3621              _originalHeight: origHeight,
3622              _dynamicWidth: width,
3623              _dynamicHeight: height,
3624            };
3625          }
3626        }
3627
3628        /**
3629         * Updates the plugin and DOM to the current options.
3630         * This method should only be called if a update is 100% required.
3631         * @param updateHints A objects which contains hints for this update:
3632         * {
3633         *   _hostSizeChanged : boolean,
3634         *   _contentSizeChanged : boolean,
3635         *   _force : boolean,                             == preventSwallowing
3636         *   _changedOptions : { },                        == preventSwallowing && preventSleep
3637         *  }
3638         */
3639        function update(updateHints) {
3640          clearTimeout(_swallowedUpdateTimeout);
3641          updateHints = updateHints || {};
3642          _swallowedUpdateHints._hostSizeChanged |=
3643            updateHints._hostSizeChanged;
3644          _swallowedUpdateHints._contentSizeChanged |=
3645            updateHints._contentSizeChanged;
3646          _swallowedUpdateHints._force |= updateHints._force;
3647
3648          var now = COMPATIBILITY.now();
3649          var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged;
3650          var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged;
3651          var force = !!_swallowedUpdateHints._force;
3652          var changedOptions = updateHints._changedOptions;
3653          var swallow =
3654            _swallowUpdateLag > 0 &&
3655            _initialized &&
3656            !_destroyed &&
3657            !force &&
3658            !changedOptions &&
3659            now - _lastUpdateTime < _swallowUpdateLag &&
3660            !_heightAutoCache &&
3661            !_widthAutoCache;
3662          var displayIsHidden;
3663
3664          if (swallow)
3665            _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag);
3666
3667          //abort update due to:
3668          //destroyed
3669          //swallowing
3670          //sleeping
3671          //host is hidden or has false display
3672          if (
3673            _destroyed ||
3674            swallow ||
3675            (_sleeping && !changedOptions) ||
3676            (_initialized &&
3677              !force &&
3678              (displayIsHidden = _hostElement.is(":hidden"))) ||
3679            _hostElement.css("display") === "inline"
3680          )
3681            return;
3682
3683          _lastUpdateTime = now;
3684          _swallowedUpdateHints = {};
3685
3686          //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely.
3687          if (
3688            _nativeScrollbarStyling &&
3689            !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)
3690          ) {
3691            //native scrollbars are hidden, so change the values to zero
3692            _nativeScrollbarSize.x = 0;
3693            _nativeScrollbarSize.y = 0;
3694          } else {
3695            //refresh native scrollbar size (in case of zoom)
3696            _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize);
3697          }
3698
3699          // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small.
3700          // The calculation: [scrollbar size +3 *3]
3701          // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar)
3702          // (*3 because (1)increase / (2)decrease -button and (3)resize handle)
3703          _nativeScrollbarMinSize = {
3704            x:
3705              (_nativeScrollbarSize.x +
3706                (_nativeScrollbarIsOverlaid.x ? 0 : 3)) *
3707              3,
3708            y:
3709              (_nativeScrollbarSize.y +
3710                (_nativeScrollbarIsOverlaid.y ? 0 : 3)) *
3711              3,
3712          };
3713
3714          changedOptions = changedOptions || {};
3715          //freezeResizeObserver(_sizeObserverElement, true);
3716          //freezeResizeObserver(_sizeAutoObserverElement, true);
3717
3718          var checkCacheAutoForce = function () {
3719            return checkCache.apply(
3720              this,
3721              [].slice.call(arguments).concat([force])
3722            );
3723          };
3724
3725          //save current scroll offset
3726          var currScroll = {
3727            x: _viewportElement[_strScrollLeft](),
3728            y: _viewportElement[_strScrollTop](),
3729          };
3730
3731          var currentPreparedOptionsScrollbars =
3732            _currentPreparedOptions.scrollbars;
3733          var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea;
3734
3735          //scrollbars visibility:
3736          var scrollbarsVisibility =
3737            currentPreparedOptionsScrollbars.visibility;
3738          var scrollbarsVisibilityChanged = checkCacheAutoForce(
3739            scrollbarsVisibility,
3740            _scrollbarsVisibilityCache
3741          );
3742
3743          //scrollbars autoHide:
3744          var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide;
3745          var scrollbarsAutoHideChanged = checkCacheAutoForce(
3746            scrollbarsAutoHide,
3747            _scrollbarsAutoHideCache
3748          );
3749
3750          //scrollbars click scrolling
3751          var scrollbarsClickScrolling =
3752            currentPreparedOptionsScrollbars.clickScrolling;
3753          var scrollbarsClickScrollingChanged = checkCacheAutoForce(
3754            scrollbarsClickScrolling,
3755            _scrollbarsClickScrollingCache
3756          );
3757
3758          //scrollbars drag scrolling
3759          var scrollbarsDragScrolling =
3760            currentPreparedOptionsScrollbars.dragScrolling;
3761          var scrollbarsDragScrollingChanged = checkCacheAutoForce(
3762            scrollbarsDragScrolling,
3763            _scrollbarsDragScrollingCache
3764          );
3765
3766          //className
3767          var className = _currentPreparedOptions.className;
3768          var classNameChanged = checkCacheAutoForce(
3769            className,
3770            _classNameCache
3771          );
3772
3773          //resize
3774          var resize = _currentPreparedOptions.resize;
3775          var resizeChanged =
3776            checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility.
3777
3778          //paddingAbsolute
3779          var paddingAbsolute = _currentPreparedOptions.paddingAbsolute;
3780          var paddingAbsoluteChanged = checkCacheAutoForce(
3781            paddingAbsolute,
3782            _paddingAbsoluteCache
3783          );
3784
3785          //clipAlways
3786          var clipAlways = _currentPreparedOptions.clipAlways;
3787          var clipAlwaysChanged = checkCacheAutoForce(
3788            clipAlways,
3789            _clipAlwaysCache
3790          );
3791
3792          //sizeAutoCapable
3793          var sizeAutoCapable =
3794            _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport.
3795          var sizeAutoCapableChanged = checkCacheAutoForce(
3796            sizeAutoCapable,
3797            _sizeAutoCapableCache
3798          );
3799
3800          //showNativeScrollbars
3801          var ignoreOverlayScrollbarHiding =
3802            _currentPreparedOptions.nativeScrollbarsOverlaid
3803              .showNativeScrollbars;
3804          var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(
3805            ignoreOverlayScrollbarHiding,
3806            _ignoreOverlayScrollbarHidingCache
3807          );
3808
3809          //autoUpdate
3810          var autoUpdate = _currentPreparedOptions.autoUpdate;
3811          var autoUpdateChanged = checkCacheAutoForce(
3812            autoUpdate,
3813            _autoUpdateCache
3814          );
3815
3816          //overflowBehavior
3817          var overflowBehavior = _currentPreparedOptions.overflowBehavior;
3818          var overflowBehaviorChanged = checkCacheAutoForce(
3819            overflowBehavior,
3820            _overflowBehaviorCache,
3821            force
3822          );
3823
3824          //dynWidth:
3825          var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth;
3826          var textareaDynWidthChanged = checkCacheAutoForce(
3827            _textareaDynWidthCache,
3828            textareaDynWidth
3829          );
3830
3831          //dynHeight:
3832          var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight;
3833          var textareaDynHeightChanged = checkCacheAutoForce(
3834            _textareaDynHeightCache,
3835            textareaDynHeight
3836          );
3837
3838          //scrollbars visibility
3839          _scrollbarsAutoHideNever = scrollbarsAutoHide === "n";
3840          _scrollbarsAutoHideScroll = scrollbarsAutoHide === "s";
3841          _scrollbarsAutoHideMove = scrollbarsAutoHide === "m";
3842          _scrollbarsAutoHideLeave = scrollbarsAutoHide === "l";
3843
3844          //scrollbars autoHideDelay
3845          _scrollbarsAutoHideDelay =
3846            currentPreparedOptionsScrollbars.autoHideDelay;
3847
3848          //old className
3849          _oldClassName = _classNameCache;
3850
3851          //resize
3852          _resizeNone = resize === "n";
3853          _resizeBoth = resize === "b";
3854          _resizeHorizontal = resize === "h";
3855          _resizeVertical = resize === "v";
3856
3857          //normalizeRTL
3858          _normalizeRTLCache = _currentPreparedOptions.normalizeRTL;
3859
3860          //ignore overlay scrollbar hiding
3861          ignoreOverlayScrollbarHiding =
3862            ignoreOverlayScrollbarHiding &&
3863            _nativeScrollbarIsOverlaid.x &&
3864            _nativeScrollbarIsOverlaid.y;
3865
3866          //refresh options cache
3867          _scrollbarsVisibilityCache = scrollbarsVisibility;
3868          _scrollbarsAutoHideCache = scrollbarsAutoHide;
3869          _scrollbarsClickScrollingCache = scrollbarsClickScrolling;
3870          _scrollbarsDragScrollingCache = scrollbarsDragScrolling;
3871          _classNameCache = className;
3872          _resizeCache = resize;
3873          _paddingAbsoluteCache = paddingAbsolute;
3874          _clipAlwaysCache = clipAlways;
3875          _sizeAutoCapableCache = sizeAutoCapable;
3876          _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding;
3877          _autoUpdateCache = autoUpdate;
3878          _overflowBehaviorCache = extendDeep({}, overflowBehavior);
3879          _textareaDynWidthCache = textareaDynWidth;
3880          _textareaDynHeightCache = textareaDynHeight;
3881          _hasOverflowCache = _hasOverflowCache || { x: false, y: false };
3882
3883          //set correct class name to the host element
3884          if (classNameChanged) {
3885            removeClass(
3886              _hostElement,
3887              _oldClassName + _strSpace + _classNameThemeNone
3888            );
3889            addClass(
3890              _hostElement,
3891              className !== undefined &&
3892                className !== null &&
3893                className.length > 0
3894                ? className
3895                : _classNameThemeNone
3896            );
3897          }
3898
3899          //set correct auto Update
3900          if (autoUpdateChanged) {
3901            if (
3902              autoUpdate === true ||
3903              (autoUpdate === null && _autoUpdateRecommended)
3904            ) {
3905              disconnectMutationObservers();
3906              autoUpdateLoop.add(_base);
3907            } else {
3908              autoUpdateLoop.remove(_base);
3909              connectMutationObservers();
3910            }
3911          }
3912
3913          //activate or deactivate size auto capability
3914          if (sizeAutoCapableChanged) {
3915            if (sizeAutoCapable) {
3916              if (_contentGlueElement) {
3917                _contentGlueElement.show();
3918              } else {
3919                _contentGlueElement = FRAMEWORK(
3920                  generateDiv(_classNameContentGlueElement)
3921                );
3922                _paddingElement.before(_contentGlueElement);
3923              }
3924              if (_sizeAutoObserverAdded) {
3925                _sizeAutoObserverElement.show();
3926              } else {
3927                _sizeAutoObserverElement = FRAMEWORK(
3928                  generateDiv(_classNameSizeAutoObserverElement)
3929                );
3930                _sizeAutoObserverElementNative = _sizeAutoObserverElement[0];
3931
3932                _contentGlueElement.before(_sizeAutoObserverElement);
3933                var oldSize = { w: -1, h: -1 };
3934                setupResizeObserver(_sizeAutoObserverElement, function () {
3935                  var newSize = {
3936                    w: _sizeAutoObserverElementNative[LEXICON.oW],
3937                    h: _sizeAutoObserverElementNative[LEXICON.oH],
3938                  };
3939                  if (checkCache(newSize, oldSize)) {
3940                    if (
3941                      (_initialized && _heightAutoCache && newSize.h > 0) ||
3942                      (_widthAutoCache && newSize.w > 0)
3943                    ) {
3944                      update();
3945                    } else if (
3946                      (_initialized && !_heightAutoCache && newSize.h === 0) ||
3947                      (!_widthAutoCache && newSize.w === 0)
3948                    ) {
3949                      update();
3950                    }
3951                  }
3952                  oldSize = newSize;
3953                });
3954                _sizeAutoObserverAdded = true;
3955                //fix heightAuto detector bug if height is fixed but contentHeight is 0.
3956                //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8.
3957                if (_cssCalc !== null)
3958                  _sizeAutoObserverElement.css(
3959                    _strHeight,
3960                    _cssCalc + "(100% + 1px)"
3961                  );
3962              }
3963            } else {
3964              if (_sizeAutoObserverAdded) _sizeAutoObserverElement.hide();
3965              if (_contentGlueElement) _contentGlueElement.hide();
3966            }
3967          }
3968
3969          //if force, update all resizeObservers too
3970          if (force) {
3971            _sizeObserverElement.find("*").trigger(_strScroll);
3972            if (_sizeAutoObserverAdded)
3973              _sizeAutoObserverElement.find("*").trigger(_strScroll);
3974          }
3975
3976          //display hidden:
3977          displayIsHidden =
3978            displayIsHidden === undefined
3979              ? _hostElement.is(":hidden")
3980              : displayIsHidden;
3981
3982          //textarea AutoWrapping:
3983          var textareaAutoWrapping = _isTextarea
3984            ? _targetElement.attr("wrap") !== "off"
3985            : false;
3986          var textareaAutoWrappingChanged = checkCacheAutoForce(
3987            textareaAutoWrapping,
3988            _textareaAutoWrappingCache
3989          );
3990
3991          //detect direction:
3992          var cssDirection = _hostElement.css("direction");
3993          var cssDirectionChanged = checkCacheAutoForce(
3994            cssDirection,
3995            _cssDirectionCache
3996          );
3997
3998          //detect box-sizing:
3999          var boxSizing = _hostElement.css("box-sizing");
4000          var boxSizingChanged = checkCacheAutoForce(
4001            boxSizing,
4002            _cssBoxSizingCache
4003          );
4004
4005          //detect padding:
4006          var padding = getTopRightBottomLeftHost(_strPaddingMinus);
4007
4008          //width + height auto detecting var:
4009          var sizeAutoObserverElementBCRect;
4010          //exception occurs in IE8 sometimes (unknown exception)
4011          try {
4012            sizeAutoObserverElementBCRect = _sizeAutoObserverAdded
4013              ? _sizeAutoObserverElementNative[LEXICON.bCR]()
4014              : null;
4015          } catch (ex) {
4016            return;
4017          }
4018
4019          _isRTL = cssDirection === "rtl";
4020          _isBorderBox = boxSizing === "border-box";
4021          var isRTLLeft = _isRTL ? _strLeft : _strRight;
4022          var isRTLRight = _isRTL ? _strRight : _strLeft;
4023
4024          //detect width auto:
4025          var widthAutoResizeDetection = false;
4026          var widthAutoObserverDetection =
4027            _sizeAutoObserverAdded &&
4028            _hostElement.css(_strFloat) !== "none" /*|| _isTextarea */
4029              ? MATH.round(
4030                  sizeAutoObserverElementBCRect.right -
4031                    sizeAutoObserverElementBCRect.left
4032                ) === 0 &&
4033                (!paddingAbsolute
4034                  ? _hostElementNative[LEXICON.cW] - _paddingX > 0
4035                  : true)
4036              : false;
4037          if (sizeAutoCapable && !widthAutoObserverDetection) {
4038            var tmpCurrHostWidth = _hostElementNative[LEXICON.oW];
4039            var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth);
4040            _contentGlueElement.css(_strWidth, _strAuto);
4041
4042            var tmpNewHostWidth = _hostElementNative[LEXICON.oW];
4043            _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth);
4044            widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth;
4045            if (!widthAutoResizeDetection) {
4046              _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1);
4047              tmpNewHostWidth = _hostElementNative[LEXICON.oW];
4048              _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth);
4049              widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth;
4050            }
4051          }
4052          var widthAuto =
4053            (widthAutoObserverDetection || widthAutoResizeDetection) &&
4054            sizeAutoCapable &&
4055            !displayIsHidden;
4056          var widthAutoChanged = checkCacheAutoForce(
4057            widthAuto,
4058            _widthAutoCache
4059          );
4060          var wasWidthAuto = !widthAuto && _widthAutoCache;
4061
4062          //detect height auto:
4063          var heightAuto =
4064            _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden
4065              ? MATH.round(
4066                  sizeAutoObserverElementBCRect.bottom -
4067                    sizeAutoObserverElementBCRect.top
4068                ) ===
4069                0 /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */
4070              : false;
4071          var heightAutoChanged = checkCacheAutoForce(
4072            heightAuto,
4073            _heightAutoCache
4074          );
4075          var wasHeightAuto = !heightAuto && _heightAutoCache;
4076
4077          //detect border:
4078          //we need the border only if border box and auto size
4079          var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox;
4080          var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox;
4081          var border = getTopRightBottomLeftHost(
4082            _strBorderMinus,
4083            "-" + _strWidth,
4084            !updateBorderX,
4085            !updateBorderY
4086          );
4087
4088          //detect margin:
4089          var margin = getTopRightBottomLeftHost(_strMarginMinus);
4090
4091          //vars to apply correct css
4092          var contentElementCSS = {};
4093          var contentGlueElementCSS = {};
4094
4095          //funcs
4096          var getHostSize = function () {
4097            //has to be clientSize because offsetSize respect borders
4098            return {
4099              w: _hostElementNative[LEXICON.cW],
4100              h: _hostElementNative[LEXICON.cH],
4101            };
4102          };
4103          var getViewportSize = function () {
4104            //viewport size is padding container because it never has padding, margin and a border
4105            //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height
4106            //if this happens add the difference to the viewportSize to compensate the rounding error
4107            return {
4108              w:
4109                _paddingElementNative[LEXICON.oW] +
4110                MATH.max(
4111                  0,
4112                  _contentElementNative[LEXICON.cW] -
4113                    _contentElementNative[LEXICON.sW]
4114                ),
4115              h:
4116                _paddingElementNative[LEXICON.oH] +
4117                MATH.max(
4118                  0,
4119                  _contentElementNative[LEXICON.cH] -
4120                    _contentElementNative[LEXICON.sH]
4121                ),
4122            };
4123          };
4124
4125          //set info for padding
4126          var paddingAbsoluteX = (_paddingX = padding.l + padding.r);
4127          var paddingAbsoluteY = (_paddingY = padding.t + padding.b);
4128          paddingAbsoluteX *= paddingAbsolute ? 1 : 0;
4129          paddingAbsoluteY *= paddingAbsolute ? 1 : 0;
4130          padding.c = checkCacheAutoForce(padding, _cssPaddingCache);
4131
4132          //set info for border
4133          _borderX = border.l + border.r;
4134          _borderY = border.t + border.b;
4135          border.c = checkCacheAutoForce(border, _cssBorderCache);
4136
4137          //set info for margin
4138          _marginX = margin.l + margin.r;
4139          _marginY = margin.t + margin.b;
4140          margin.c = checkCacheAutoForce(margin, _cssMarginCache);
4141
4142          //refresh cache
4143          _textareaAutoWrappingCache = textareaAutoWrapping;
4144          _cssDirectionCache = cssDirection;
4145          _cssBoxSizingCache = boxSizing;
4146          _widthAutoCache = widthAuto;
vendor: 8,459 bytes, lines 4147-4360
4147          _heightAutoCache = heightAuto;
4148          _cssPaddingCache = padding;
4149          _cssBorderCache = border;
4150          _cssMarginCache = margin;
4151
4152          //IEFix direction changed
4153          if (cssDirectionChanged && _sizeAutoObserverAdded)
4154            _sizeAutoObserverElement.css(_strFloat, isRTLRight);
4155
4156          //apply padding:
4157          if (
4158            padding.c ||
4159            cssDirectionChanged ||
4160            paddingAbsoluteChanged ||
4161            widthAutoChanged ||
4162            heightAutoChanged ||
4163            boxSizingChanged ||
4164            sizeAutoCapableChanged
4165          ) {
4166            var paddingElementCSS = {};
4167            var textareaCSS = {};
4168            var paddingValues = [padding.t, padding.r, padding.b, padding.l];
4169
4170            setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [
4171              -padding.t,
4172              -padding.r,
4173              -padding.b,
4174              -padding.l,
4175            ]);
4176            if (paddingAbsolute) {
4177              setTopRightBottomLeft(
4178                paddingElementCSS,
4179                _strEmpty,
4180                paddingValues
4181              );
4182              setTopRightBottomLeft(
4183                _isTextarea ? textareaCSS : contentElementCSS,
4184                _strPaddingMinus
4185              );
4186            } else {
4187              setTopRightBottomLeft(paddingElementCSS, _strEmpty);
4188              setTopRightBottomLeft(
4189                _isTextarea ? textareaCSS : contentElementCSS,
4190                _strPaddingMinus,
4191                paddingValues
4192              );
4193            }
4194
4195            _paddingElement.css(paddingElementCSS);
4196            _targetElement.css(textareaCSS);
4197          }
4198
4199          //viewport size is padding container because it never has padding, margin and a border.
4200          _viewportSize = getViewportSize();
4201
4202          //update Textarea
4203          var textareaSize = _isTextarea ? textareaUpdate() : false;
4204          var textareaSizeChanged =
4205            _isTextarea &&
4206            checkCacheAutoForce(textareaSize, _textareaSizeCache);
4207          var textareaDynOrigSize =
4208            _isTextarea && textareaSize
4209              ? {
4210                  w: textareaDynWidth
4211                    ? textareaSize._dynamicWidth
4212                    : textareaSize._originalWidth,
4213                  h: textareaDynHeight
4214                    ? textareaSize._dynamicHeight
4215                    : textareaSize._originalHeight,
4216                }
4217              : {};
4218          _textareaSizeCache = textareaSize;
4219
4220          //fix height auto / width auto in cooperation with current padding & boxSizing behavior:
4221          if (
4222            heightAuto &&
4223            (heightAutoChanged ||
4224              paddingAbsoluteChanged ||
4225              boxSizingChanged ||
4226              padding.c ||
4227              border.c)
4228          ) {
4229            contentElementCSS[_strHeight] = _strAuto;
4230          } else if (heightAutoChanged || paddingAbsoluteChanged) {
4231            contentElementCSS[_strHeight] = _strHundredPercent;
4232          }
4233          if (
4234            widthAuto &&
4235            (widthAutoChanged ||
4236              paddingAbsoluteChanged ||
4237              boxSizingChanged ||
4238              padding.c ||
4239              border.c ||
4240              cssDirectionChanged)
4241          ) {
4242            contentElementCSS[_strWidth] = _strAuto;
4243            contentGlueElementCSS[_strMaxMinus + _strWidth] =
4244              _strHundredPercent; //IE Fix
4245          } else if (widthAutoChanged || paddingAbsoluteChanged) {
4246            contentElementCSS[_strWidth] = _strHundredPercent;
4247            contentElementCSS[_strFloat] = _strEmpty;
4248            contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix
4249          }
4250          if (widthAuto) {
4251            //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width
4252            contentGlueElementCSS[_strWidth] = _strAuto;
4253
4254            contentElementCSS[_strWidth] =
4255              VENDORS._cssPropertyValue(_strWidth, "max-content intrinsic") ||
4256              _strAuto;
4257            contentElementCSS[_strFloat] = isRTLRight;
4258          } else {
4259            contentGlueElementCSS[_strWidth] = _strEmpty;
4260          }
4261          if (heightAuto) {
4262            //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping
4263            contentGlueElementCSS[_strHeight] =
4264              textareaDynOrigSize.h || _contentElementNative[LEXICON.cH];
4265          } else {
4266            contentGlueElementCSS[_strHeight] = _strEmpty;
4267          }
4268          if (sizeAutoCapable) _contentGlueElement.css(contentGlueElementCSS);
4269          _contentElement.css(contentElementCSS);
4270
4271          //CHECKPOINT HERE ~
4272          contentElementCSS = {};
4273          contentGlueElementCSS = {};
4274
4275          //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true
4276          if (
4277            hostSizeChanged ||
4278            contentSizeChanged ||
4279            textareaSizeChanged ||
4280            cssDirectionChanged ||
4281            boxSizingChanged ||
4282            paddingAbsoluteChanged ||
4283            widthAutoChanged ||
4284            widthAuto ||
4285            heightAutoChanged ||
4286            heightAuto ||
4287            ignoreOverlayScrollbarHidingChanged ||
4288            overflowBehaviorChanged ||
4289            clipAlwaysChanged ||
4290            resizeChanged ||
4291            scrollbarsVisibilityChanged ||
4292            scrollbarsAutoHideChanged ||
4293            scrollbarsDragScrollingChanged ||
4294            scrollbarsClickScrollingChanged ||
4295            textareaDynWidthChanged ||
4296            textareaDynHeightChanged ||
4297            textareaAutoWrappingChanged
4298          ) {
4299            var strOverflow = "overflow";
4300            var strOverflowX = strOverflow + "-x";
4301            var strOverflowY = strOverflow + "-y";
4302            var strHidden = "hidden";
4303            var strVisible = "visible";
4304
4305            //Reset the viewport (very important for natively overlaid scrollbars and zoom change
4306            //don't change the overflow prop as it is very expensive and affects performance !A LOT!
4307            if (!_nativeScrollbarStyling) {
4308              var viewportElementResetCSS = {};
4309              var resetXTmp =
4310                _hasOverflowCache.y &&
4311                _hideOverflowCache.ys &&
4312                !ignoreOverlayScrollbarHiding
4313                  ? _nativeScrollbarIsOverlaid.y
4314                    ? _viewportElement.css(isRTLLeft)
4315                    : -_nativeScrollbarSize.y
4316                  : 0;
4317              var resetBottomTmp =
4318                _hasOverflowCache.x &&
4319                _hideOverflowCache.xs &&
4320                !ignoreOverlayScrollbarHiding
4321                  ? _nativeScrollbarIsOverlaid.x
4322                    ? _viewportElement.css(_strBottom)
4323                    : -_nativeScrollbarSize.x
4324                  : 0;
4325              setTopRightBottomLeft(viewportElementResetCSS, _strEmpty);
4326              _viewportElement.css(viewportElementResetCSS);
4327            }
4328
4329            //measure several sizes:
4330            var contentMeasureElement = getContentMeasureElement();
4331            //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid
4332            var contentSize = {
4333              //use clientSize because natively overlaidScrollbars add borders
4334              w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW],
4335              h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH],
4336            };
4337            var scrollSize = {
4338              w: contentMeasureElement[LEXICON.sW],
4339              h: contentMeasureElement[LEXICON.sH],
4340            };
4341
4342            //apply the correct viewport style and measure viewport size
4343            if (!_nativeScrollbarStyling) {
4344              viewportElementResetCSS[_strBottom] = wasHeightAuto
4345                ? _strEmpty
4346                : resetBottomTmp;
4347              viewportElementResetCSS[isRTLLeft] = wasWidthAuto
4348                ? _strEmpty
4349                : resetXTmp;
4350              _viewportElement.css(viewportElementResetCSS);
4351            }
4352            _viewportSize = getViewportSize();
4353
4354            //measure and correct several sizes
4355            var hostSize = getHostSize();
4356            var hostAbsoluteRectSize = {
4357              w:
4358                hostSize.w -
4359                _marginX -
4360                _borderX -
4361                (_isBorderBox ? 0 : _paddingX),
4362              h:
4363                hostSize.h -
4364                _marginY -
4365                _borderY -
4366                (_isBorderBox ? 0 : _paddingY),
4367            };
4368            var contentGlueSize = {
4369              //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually
4370              //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding
4371              w: MATH.max(
4372                (widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX,
4373                hostAbsoluteRectSize.w
4374              ),
4375              h: MATH.max(
4376                (heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY,
4377                hostAbsoluteRectSize.h
4378              ),
4379            };
4380            contentGlueSize.c = checkCacheAutoForce(
4381              contentGlueSize,
4382              _contentGlueSizeCache
4383            );
4384            _contentGlueSizeCache = contentGlueSize;
4385
4386            //apply correct contentGlue size
4387            if (sizeAutoCapable) {
4388              //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto
4389              if (contentGlueSize.c || heightAuto || widthAuto) {
4390                contentGlueElementCSS[_strWidth] = contentGlueSize.w;
4391                contentGlueElementCSS[_strHeight] = contentGlueSize.h;
4392
4393                //textarea-sizes are already calculated correctly at this point
4394                if (!_isTextarea) {
4395                  contentSize = {
4396                    //use clientSize because natively overlaidScrollbars add borders
4397                    w: contentMeasureElement[LEXICON.cW],
4398                    h: contentMeasureElement[LEXICON.cH],
4399                  };
4400                }
4401              }
4402              var textareaCoverCSS = {};
4403              var setContentGlueElementCSSfunction = function (horizontal) {
4404                var scrollbarVars = getScrollbarVars(horizontal);
4405                var wh = scrollbarVars._w_h;
4406                var strWH = scrollbarVars._width_height;
4407                var autoSize = horizontal ? widthAuto : heightAuto;
4408                var borderSize = horizontal ? _borderX : _borderY;
4409                var paddingSize = horizontal ? _paddingX : _paddingY;
4410                var marginSize = horizontal ? _marginX : _marginY;
4411                var viewportSize =
4412                  _viewportSize[wh] -
4413                  borderSize -
4414                  marginSize -
4415                  (_isBorderBox ? 0 : paddingSize);
4416
4417                //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks
4418                if (!autoSize || (!autoSize && border.c))
4419                  contentGlueElementCSS[strWH] = hostAbsoluteRectSize[wh] - 1;
4420
4421                //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0)
4422                if (
4423                  autoSize &&
4424                  contentSize[wh] < viewportSize &&
4425                  (horizontal && _isTextarea ? !textareaAutoWrapping : true)
4426                ) {
4427                  if (_isTextarea)
4428                    textareaCoverCSS[strWH] =
4429                      parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1;
4430                  contentGlueElementCSS[strWH] -= 1;
4431                }
4432
4433                //make sure content glue size is at least 1
4434                if (contentSize[wh] > 0)
4435                  contentGlueElementCSS[strWH] = MATH.max(
4436                    1,
4437                    contentGlueElementCSS[strWH]
4438                  );
4439              };
4440              setContentGlueElementCSSfunction(true);
4441              setContentGlueElementCSSfunction(false);
4442
4443              if (_isTextarea) _textareaCoverElement.css(textareaCoverCSS);
4444              _contentGlueElement.css(contentGlueElementCSS);
4445            }
4446            if (widthAuto) contentElementCSS[_strWidth] = _strHundredPercent;
4447            if (widthAuto && !_isBorderBox && !_mutationObserversConnected)
4448              contentElementCSS[_strFloat] = "none";
4449
4450            //apply and reset content style
4451            _contentElement.css(contentElementCSS);
4452            contentElementCSS = {};
4453
vendor: 8,629 bytes, lines 4454-4650
4454            //measure again, but this time all correct sizes:
4455            var contentScrollSize = {
4456              w: contentMeasureElement[LEXICON.sW],
4457              h: contentMeasureElement[LEXICON.sH],
4458            };
4459            contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(
4460              contentScrollSize,
4461              _contentScrollSizeCache
4462            );
4463            _contentScrollSizeCache = contentScrollSize;
4464
4465            //refresh viewport size after correct measuring
4466            _viewportSize = getViewportSize();
4467
4468            hostSize = getHostSize();
4469            hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache);
4470            _hostSizeCache = hostSize;
4471
4472            var hideOverflowForceTextarea =
4473              _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0);
4474            var previousOverflowAmount = _overflowAmountCache;
4475            var overflowBehaviorIsVS = {};
4476            var overflowBehaviorIsVH = {};
4477            var overflowBehaviorIsS = {};
4478            var overflowAmount = {};
4479            var hasOverflow = {};
4480            var hideOverflow = {};
4481            var canScroll = {};
4482            var viewportRect = _paddingElementNative[LEXICON.bCR]();
4483            var setOverflowVariables = function (horizontal) {
4484              var scrollbarVars = getScrollbarVars(horizontal);
4485              var scrollbarVarsInverted = getScrollbarVars(!horizontal);
4486              var xyI = scrollbarVarsInverted._x_y;
4487              var xy = scrollbarVars._x_y;
4488              var wh = scrollbarVars._w_h;
4489              var widthHeight = scrollbarVars._width_height;
4490              var scrollMax = _strScroll + scrollbarVars._Left_Top + "Max";
4491              var fractionalOverflowAmount = viewportRect[widthHeight]
4492                ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh])
4493                : 0;
4494              var checkFractionalOverflowAmount =
4495                previousOverflowAmount &&
4496                previousOverflowAmount[xy] > 0 &&
4497                _viewportElementNative[scrollMax] === 0;
4498              overflowBehaviorIsVS[xy] = overflowBehavior[xy] === "v-s";
4499              overflowBehaviorIsVH[xy] = overflowBehavior[xy] === "v-h";
4500              overflowBehaviorIsS[xy] = overflowBehavior[xy] === "s";
4501              overflowAmount[xy] = MATH.max(
4502                0,
4503                MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) /
4504                  100
4505              );
4506              overflowAmount[xy] *=
4507                hideOverflowForceTextarea ||
4508                (checkFractionalOverflowAmount &&
4509                  fractionalOverflowAmount > 0 &&
4510                  fractionalOverflowAmount < 1)
4511                  ? 0
4512                  : 1;
4513              hasOverflow[xy] = overflowAmount[xy] > 0;
4514
4515              //hideOverflow:
4516              //x || y : true === overflow is hidden by "overflow: scroll" OR "overflow: hidden"
4517              //xs || ys : true === overflow is hidden by "overflow: scroll"
4518              hideOverflow[xy] =
4519                overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy]
4520                  ? hasOverflow[xyI] &&
4521                    !overflowBehaviorIsVS[xyI] &&
4522                    !overflowBehaviorIsVH[xyI]
4523                  : hasOverflow[xy];
4524              hideOverflow[xy + "s"] = hideOverflow[xy]
4525                ? overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]
4526                : false;
4527
4528              canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + "s"];
4529            };
4530            setOverflowVariables(true);
4531            setOverflowVariables(false);
4532
4533            overflowAmount.c = checkCacheAutoForce(
4534              overflowAmount,
4535              _overflowAmountCache
4536            );
4537            _overflowAmountCache = overflowAmount;
4538            hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache);
4539            _hasOverflowCache = hasOverflow;
4540            hideOverflow.c = checkCacheAutoForce(
4541              hideOverflow,
4542              _hideOverflowCache
4543            );
4544            _hideOverflowCache = hideOverflow;
4545
4546            //if native scrollbar is overlay at x OR y axis, prepare DOM
4547            if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) {
4548              var borderDesign = "px solid transparent";
4549              var contentArrangeElementCSS = {};
4550              var arrangeContent = {};
4551              var arrangeChanged = force;
4552              var setContentElementCSS;
4553
4554              if (hasOverflow.x || hasOverflow.y) {
4555                arrangeContent.w =
4556                  _nativeScrollbarIsOverlaid.y && hasOverflow.y
4557                    ? contentScrollSize.w + _overlayScrollbarDummySize.y
4558                    : _strEmpty;
4559                arrangeContent.h =
4560                  _nativeScrollbarIsOverlaid.x && hasOverflow.x
4561                    ? contentScrollSize.h + _overlayScrollbarDummySize.x
4562                    : _strEmpty;
4563                arrangeChanged = checkCacheAutoForce(
4564                  arrangeContent,
4565                  _arrangeContentSizeCache
4566                );
4567                _arrangeContentSizeCache = arrangeContent;
4568              }
4569
4570              if (
4571                hasOverflow.c ||
4572                hideOverflow.c ||
4573                contentScrollSize.c ||
4574                cssDirectionChanged ||
4575                widthAutoChanged ||
4576                heightAutoChanged ||
4577                widthAuto ||
4578                heightAuto ||
4579                ignoreOverlayScrollbarHidingChanged
4580              ) {
4581                contentElementCSS[_strMarginMinus + isRTLRight] =
4582                  contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty;
4583                setContentElementCSS = function (horizontal) {
4584                  var scrollbarVars = getScrollbarVars(horizontal);
4585                  var scrollbarVarsInverted = getScrollbarVars(!horizontal);
4586                  var xy = scrollbarVars._x_y;
4587                  var strDirection = horizontal ? _strBottom : isRTLLeft;
4588                  var invertedAutoSize = horizontal ? heightAuto : widthAuto;
4589
4590                  if (
4591                    _nativeScrollbarIsOverlaid[xy] &&
4592                    hasOverflow[xy] &&
4593                    hideOverflow[xy + "s"]
4594                  ) {
4595                    contentElementCSS[_strMarginMinus + strDirection] =
4596                      invertedAutoSize
4597                        ? ignoreOverlayScrollbarHiding
4598                          ? _strEmpty
4599                          : _overlayScrollbarDummySize[xy]
4600                        : _strEmpty;
4601                    contentElementCSS[_strBorderMinus + strDirection] =
4602                      (horizontal ? !invertedAutoSize : true) &&
4603                      !ignoreOverlayScrollbarHiding
4604                        ? _overlayScrollbarDummySize[xy] + borderDesign
4605                        : _strEmpty;
4606                  } else {
4607                    arrangeContent[scrollbarVarsInverted._w_h] =
4608                      contentElementCSS[_strMarginMinus + strDirection] =
4609                      contentElementCSS[_strBorderMinus + strDirection] =
4610                        _strEmpty;
4611                    arrangeChanged = true;
4612                  }
4613                };
4614
4615                if (_nativeScrollbarStyling) {
4616                  addRemoveClass(
4617                    _viewportElement,
4618                    _classNameViewportNativeScrollbarsInvisible,
4619                    !ignoreOverlayScrollbarHiding
4620                  );
4621                } else {
4622                  setContentElementCSS(true);
4623                  setContentElementCSS(false);
4624                }
4625              }
4626              if (ignoreOverlayScrollbarHiding) {
4627                arrangeContent.w = arrangeContent.h = _strEmpty;
4628                arrangeChanged = true;
4629              }
4630              if (arrangeChanged && !_nativeScrollbarStyling) {
4631                contentArrangeElementCSS[_strWidth] = hideOverflow.y
4632                  ? arrangeContent.w
4633                  : _strEmpty;
4634                contentArrangeElementCSS[_strHeight] = hideOverflow.x
4635                  ? arrangeContent.h
4636                  : _strEmpty;
4637
4638                if (!_contentArrangeElement) {
4639                  _contentArrangeElement = FRAMEWORK(
4640                    generateDiv(_classNameContentArrangeElement)
4641                  );
4642                  _viewportElement.prepend(_contentArrangeElement);
4643                }
4644                _contentArrangeElement.css(contentArrangeElementCSS);
4645              }
4646              _contentElement.css(contentElementCSS);
4647            }
4648
4649            var viewportElementCSS = {};
4650            var paddingElementCSS = {};
4651            var setViewportCSS;
4652            if (
4653              hostSizeChanged ||
4654              hasOverflow.c ||
4655              hideOverflow.c ||
4656              contentScrollSize.c ||
4657              overflowBehaviorChanged ||
4658              boxSizingChanged ||
4659              ignoreOverlayScrollbarHidingChanged ||
4660              cssDirectionChanged ||
4661              clipAlwaysChanged ||
4662              heightAutoChanged
4663            ) {
4664              viewportElementCSS[isRTLRight] = _strEmpty;
4665              setViewportCSS = function (horizontal) {
4666                var scrollbarVars = getScrollbarVars(horizontal);
4667                var scrollbarVarsInverted = getScrollbarVars(!horizontal);
4668                var xy = scrollbarVars._x_y;
4669                var XY = scrollbarVars._X_Y;
4670                var strDirection = horizontal ? _strBottom : isRTLLeft;
4671
4672                var reset = function () {
4673                  viewportElementCSS[strDirection] = _strEmpty;
4674                  _contentBorderSize[scrollbarVarsInverted._w_h] = 0;
4675                };
4676                if (hasOverflow[xy] && hideOverflow[xy + "s"]) {
4677                  viewportElementCSS[strOverflow + XY] = _strScroll;
4678                  if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) {
4679                    reset();
4680                  } else {
4681                    viewportElementCSS[strDirection] =
4682                      -(_nativeScrollbarIsOverlaid[xy]
4683                        ? _overlayScrollbarDummySize[xy]
4684                        : _nativeScrollbarSize[xy]);
4685                    _contentBorderSize[scrollbarVarsInverted._w_h] =
4686                      _nativeScrollbarIsOverlaid[xy]
4687                        ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y]
4688                        : 0;
4689                  }
4690                } else {
4691                  viewportElementCSS[strOverflow + XY] = _strEmpty;
4692                  reset();
4693                }
4694              };
4695              setViewportCSS(true);
4696              setViewportCSS(false);
4697
4698              // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible),
4699              // make viewport element greater in size (Firefox hide Scrollbars fix)
4700              // because firefox starts hiding scrollbars on too small elements
4701              // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly
4702              // https://bugzilla.mozilla.org/show_bug.cgi?id=292284
4703              if (
4704                !_nativeScrollbarStyling &&
4705                (_viewportSize.h < _nativeScrollbarMinSize.x ||
4706                  _viewportSize.w < _nativeScrollbarMinSize.y) &&
4707                ((hasOverflow.x &&
4708                  hideOverflow.x &&
4709                  !_nativeScrollbarIsOverlaid.x) ||
4710                  (hasOverflow.y &&
4711                    hideOverflow.y &&
4712                    !_nativeScrollbarIsOverlaid.y))
4713              ) {
4714                viewportElementCSS[_strPaddingMinus + _strTop] =
4715                  _nativeScrollbarMinSize.x;
4716                viewportElementCSS[_strMarginMinus + _strTop] =
4717                  -_nativeScrollbarMinSize.x;
4718
4719                viewportElementCSS[_strPaddingMinus + isRTLRight] =
4720                  _nativeScrollbarMinSize.y;
4721                viewportElementCSS[_strMarginMinus + isRTLRight] =
4722                  -_nativeScrollbarMinSize.y;
4723              } else {
4724                viewportElementCSS[_strPaddingMinus + _strTop] =
4725                  viewportElementCSS[_strMarginMinus + _strTop] =
4726                  viewportElementCSS[_strPaddingMinus + isRTLRight] =
4727                  viewportElementCSS[_strMarginMinus + isRTLRight] =
4728                    _strEmpty;
4729              }
4730              viewportElementCSS[_strPaddingMinus + isRTLLeft] =
4731                viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty;
4732
4733              //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible
4734              if (
4735                (hasOverflow.x && hideOverflow.x) ||
4736                (hasOverflow.y && hideOverflow.y) ||
4737                hideOverflowForceTextarea
4738              ) {
4739                //only hide if is Textarea
4740                if (_isTextarea && hideOverflowForceTextarea) {
4741                  paddingElementCSS[strOverflowX] = paddingElementCSS[
4742                    strOverflowY
4743                  ] = strHidden;
4744                }
4745              } else {
4746                if (
4747                  !clipAlways ||
4748                  overflowBehaviorIsVH.x ||
4749                  overflowBehaviorIsVS.x ||
4750                  overflowBehaviorIsVH.y ||
4751                  overflowBehaviorIsVS.y
4752                ) {
4753                  //only un-hide if Textarea
4754                  if (_isTextarea) {
4755                    paddingElementCSS[strOverflowX] = paddingElementCSS[
4756                      strOverflowY
4757                    ] = _strEmpty;
4758                  }
4759                  viewportElementCSS[strOverflowX] = viewportElementCSS[
4760                    strOverflowY
4761                  ] = strVisible;
4762                }
4763              }
4764
4765              _paddingElement.css(paddingElementCSS);
4766              _viewportElement.css(viewportElementCSS);
4767              viewportElementCSS = {};
4768
4769              //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions
4770              if (
4771                (hasOverflow.c ||
4772                  boxSizingChanged ||
4773                  widthAutoChanged ||
4774                  heightAutoChanged) &&
4775                !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)
4776              ) {
4777                var elementStyle = _contentElementNative[LEXICON.s];
4778                var dump;
4779                elementStyle.webkitTransform = "scale(1)";
4780                elementStyle.display = "run-in";
4781                dump = _contentElementNative[LEXICON.oH];
4782                elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify
4783                elementStyle.webkitTransform = _strEmpty;
4784              }
4785              /*
4786                            //force hard redraw in webkit if native overlaid scrollbars shall appear
4787                            if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) {
4788                                _hostElement.hide();
4789                                var dump = _hostElementNative[LEXICON.oH];
4790                                _hostElement.show();
4791                            }
4792                            */
4793            }
4794
4795            //change to direction RTL and width auto Bugfix in Webkit
4796            //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left
4797            contentElementCSS = {};
4798            if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) {
4799              if (_isRTL && widthAuto) {
4800                var floatTmp = _contentElement.css(_strFloat);
4801                var posLeftWithoutFloat = MATH.round(
4802                  _contentElement
4803                    .css(_strFloat, _strEmpty)
4804                    .css(_strLeft, _strEmpty)
4805                    .position().left
4806                );
4807                _contentElement.css(_strFloat, floatTmp);
4808                var posLeftWithFloat = MATH.round(
4809                  _contentElement.position().left
4810                );
4811
4812                if (posLeftWithoutFloat !== posLeftWithFloat)
4813                  contentElementCSS[_strLeft] = posLeftWithoutFloat;
4814              } else {
4815                contentElementCSS[_strLeft] = _strEmpty;
4816              }
4817            }
4818            _contentElement.css(contentElementCSS);
4819
4820            //handle scroll position
4821            if (_isTextarea && contentSizeChanged) {
4822              var textareaInfo = getTextareaInfo();
4823              if (textareaInfo) {
4824                var textareaRowsChanged =
4825                  _textareaInfoCache === undefined
4826                    ? true
4827                    : textareaInfo._rows !== _textareaInfoCache._rows;
4828                var cursorRow = textareaInfo._cursorRow;
4829                var cursorCol = textareaInfo._cursorColumn;
4830                var widestRow = textareaInfo._widestRow;
4831                var lastRow = textareaInfo._rows;
4832                var lastCol = textareaInfo._columns;
4833                var cursorPos = textareaInfo._cursorPosition;
4834                var cursorMax = textareaInfo._cursorMax;
4835                var cursorIsLastPosition =
4836                  cursorPos >= cursorMax && _textareaHasFocus;
4837                var textareaScrollAmount = {
4838                  x:
4839                    !textareaAutoWrapping &&
4840                    cursorCol === lastCol &&
4841                    cursorRow === widestRow
4842                      ? _overflowAmountCache.x
4843                      : -1,
4844                  y: (
4845                    textareaAutoWrapping
4846                      ? cursorIsLastPosition ||
4847                        (textareaRowsChanged &&
4848                          (previousOverflowAmount
4849                            ? currScroll.y === previousOverflowAmount.y
4850                            : false))
4851                      : (cursorIsLastPosition || textareaRowsChanged) &&
4852                        cursorRow === lastRow
4853                  )
4854                    ? _overflowAmountCache.y
4855                    : -1,
4856                };
4857                currScroll.x =
4858                  textareaScrollAmount.x > -1
4859                    ? _isRTL && _normalizeRTLCache && _rtlScrollBehavior.i
4860                      ? 0
4861                      : textareaScrollAmount.x
4862                    : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset.
4863                currScroll.y =
4864                  textareaScrollAmount.y > -1
4865                    ? textareaScrollAmount.y
4866                    : currScroll.y;
4867              }
4868              _textareaInfoCache = textareaInfo;
4869            }
4870            if (
4871              _isRTL &&
4872              _rtlScrollBehavior.i &&
4873              _nativeScrollbarIsOverlaid.y &&
4874              hasOverflow.x &&
4875              _normalizeRTLCache
4876            )
4877              currScroll.x += _contentBorderSize.w || 0;
4878            if (widthAuto) _hostElement[_strScrollLeft](0);
4879            if (heightAuto) _hostElement[_strScrollTop](0);
4880            _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](
4881              currScroll.y
4882            );
4883
4884            //scrollbars management:
4885            var scrollbarsVisibilityVisible = scrollbarsVisibility === "v";
4886            var scrollbarsVisibilityHidden = scrollbarsVisibility === "h";
4887            var scrollbarsVisibilityAuto = scrollbarsVisibility === "a";
4888            var refreshScrollbarsVisibility = function (showX, showY) {
4889              showY = showY === undefined ? showX : showY;
4890              refreshScrollbarAppearance(true, showX, canScroll.x);
4891              refreshScrollbarAppearance(false, showY, canScroll.y);
4892            };
4893
4894            //manage class name which indicates scrollable overflow
4895            addRemoveClass(
4896              _hostElement,
4897              _classNameHostOverflow,
4898              hideOverflow.x || hideOverflow.y
4899            );
4900            addRemoveClass(
4901              _hostElement,
4902              _classNameHostOverflowX,
4903              hideOverflow.x
4904            );
4905            addRemoveClass(
4906              _hostElement,
4907              _classNameHostOverflowY,
4908              hideOverflow.y
4909            );
4910
4911            //add or remove rtl class name for styling purposes except when its body, then the scrollbar stays
4912            if (cssDirectionChanged && !_isBody) {
4913              addRemoveClass(_hostElement, _classNameHostRTL, _isRTL);
4914            }
4915
4916            //manage the resize feature (CSS3 resize "polyfill" for this plugin)
4917            if (_isBody) addClass(_hostElement, _classNameHostResizeDisabled);
4918            if (resizeChanged) {
4919              addRemoveClass(
4920                _hostElement,
4921                _classNameHostResizeDisabled,
4922                _resizeNone
4923              );
4924              addRemoveClass(
4925                _scrollbarCornerElement,
4926                _classNameScrollbarCornerResize,
4927                !_resizeNone
4928              );
4929              addRemoveClass(
4930                _scrollbarCornerElement,
4931                _classNameScrollbarCornerResizeB,
4932                _resizeBoth
4933              );
4934              addRemoveClass(
4935                _scrollbarCornerElement,
4936                _classNameScrollbarCornerResizeH,
4937                _resizeHorizontal
4938              );
4939              addRemoveClass(
4940                _scrollbarCornerElement,
4941                _classNameScrollbarCornerResizeV,
4942                _resizeVertical
4943              );
4944            }
4945
4946            //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name)
4947            if (
4948              scrollbarsVisibilityChanged ||
4949              overflowBehaviorChanged ||
4950              hideOverflow.c ||
4951              hasOverflow.c ||
4952              ignoreOverlayScrollbarHidingChanged
4953            ) {
4954              if (ignoreOverlayScrollbarHiding) {
4955                if (ignoreOverlayScrollbarHidingChanged) {
4956                  removeClass(_hostElement, _classNameHostScrolling);
4957                  if (ignoreOverlayScrollbarHiding) {
4958                    refreshScrollbarsVisibility(false);
4959                  }
4960                }
4961              } else if (scrollbarsVisibilityAuto) {
4962                refreshScrollbarsVisibility(canScroll.x, canScroll.y);
4963              } else if (scrollbarsVisibilityVisible) {
4964                refreshScrollbarsVisibility(true);
4965              } else if (scrollbarsVisibilityHidden) {
4966                refreshScrollbarsVisibility(false);
4967              }
4968            }
4969
4970            //manage the scrollbars auto hide feature (auto hide them after specific actions)
4971            if (
4972              scrollbarsAutoHideChanged ||
4973              ignoreOverlayScrollbarHidingChanged
4974            ) {
4975              setupHostMouseTouchEvents(
4976                !_scrollbarsAutoHideLeave && !_scrollbarsAutoHideMove
4977              );
4978              refreshScrollbarsAutoHide(
4979                _scrollbarsAutoHideNever,
4980                !_scrollbarsAutoHideNever
4981              );
4982            }
4983
4984            //manage scrollbars handle length & offset - don't remove!
4985            if (
4986              hostSizeChanged ||
4987              overflowAmount.c ||
4988              heightAutoChanged ||
4989              widthAutoChanged ||
4990              resizeChanged ||
4991              boxSizingChanged ||
4992              paddingAbsoluteChanged ||
4993              ignoreOverlayScrollbarHidingChanged ||
4994              cssDirectionChanged
4995            ) {
4996              refreshScrollbarHandleLength(true);
4997              refreshScrollbarHandleOffset(true);
4998              refreshScrollbarHandleLength(false);
4999              refreshScrollbarHandleOffset(false);
5000            }
5001
5002            //manage interactivity
5003            if (scrollbarsClickScrollingChanged)
5004              refreshScrollbarsInteractive(true, scrollbarsClickScrolling);
5005            if (scrollbarsDragScrollingChanged)
5006              refreshScrollbarsInteractive(false, scrollbarsDragScrolling);
5007
5008            //callbacks:
5009            dispatchCallback(
5010              "onDirectionChanged",
5011              {
5012                isRTL: _isRTL,
5013                dir: cssDirection,
5014              },
5015              cssDirectionChanged
5016            );
5017            dispatchCallback(
5018              "onHostSizeChanged",
5019              {
5020                width: _hostSizeCache.w,
5021                height: _hostSizeCache.h,
5022              },
5023              hostSizeChanged
5024            );
5025            dispatchCallback(
5026              "onContentSizeChanged",
5027              {
5028                width: _contentScrollSizeCache.w,
5029                height: _contentScrollSizeCache.h,
5030              },
5031              contentSizeChanged
5032            );
5033            dispatchCallback(
5034              "onOverflowChanged",
5035              {
5036                x: hasOverflow.x,
5037                y: hasOverflow.y,
5038                xScrollable: hideOverflow.xs,
5039                yScrollable: hideOverflow.ys,
5040                clipped: hideOverflow.x || hideOverflow.y,
5041              },
5042              hasOverflow.c || hideOverflow.c
5043            );
5044            dispatchCallback(
5045              "onOverflowAmountChanged",
5046              {
5047                x: overflowAmount.x,
5048                y: overflowAmount.y,
5049              },
5050              overflowAmount.c
5051            );
5052          }
5053
5054          //fix body min size
5055          if (
5056            _isBody &&
5057            _bodyMinSizeCache &&
5058            (_hasOverflowCache.c || _bodyMinSizeCache.c)
5059          ) {
5060            //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size.
5061            if (!_bodyMinSizeCache.f) bodyMinSizeChanged();
5062            if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x)
5063              _contentElement.css(
5064                _strMinMinus + _strWidth,
5065                _bodyMinSizeCache.w + _overlayScrollbarDummySize.y
5066              );
5067            if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y)
5068              _contentElement.css(
5069                _strMinMinus + _strHeight,
5070                _bodyMinSizeCache.h + _overlayScrollbarDummySize.x
5071              );
5072            _bodyMinSizeCache.c = false;
vendor: 24,393 bytes, lines 5073-5735
5073          }
5074
5075          if (_initialized && changedOptions.updateOnLoad) {
5076            updateElementsOnLoad();
5077          }
5078
5079          //freezeResizeObserver(_sizeObserverElement, false);
5080          //freezeResizeObserver(_sizeAutoObserverElement, false);
5081
5082          dispatchCallback("onUpdated", { forced: force });
5083        }
5084
5085        /**
5086         * Updates the found elements of which the load event shall be handled.
5087         */
5088        function updateElementsOnLoad() {
5089          if (!_isTextarea) {
5090            eachUpdateOnLoad(function (i, updateOnLoadSelector) {
5091              _contentElement.find(updateOnLoadSelector).each(function (i, el) {
5092                // if element doesn't have a updateOnLoadCallback applied
5093                if (COMPATIBILITY.inA(el, _updateOnLoadElms) < 0) {
5094                  _updateOnLoadElms.push(el);
5095                  FRAMEWORK(el)
5096                    .off(_updateOnLoadEventName, updateOnLoadCallback)
5097                    .on(_updateOnLoadEventName, updateOnLoadCallback);
5098                }
5099              });
5100            });
5101          }
5102        }
5103
5104        //==== Options ====//
5105
5106        /**
5107         * Sets new options but doesn't call the update method.
5108         * @param newOptions The object which contains the new options.
5109         * @returns {*} A object which contains the changed options.
5110         */
5111        function setOptions(newOptions) {
5112          var validatedOpts = _pluginsOptions._validate(
5113            newOptions,
5114            _pluginsOptions._template,
5115            true,
5116            _currentOptions
5117          );
5118
5119          _currentOptions = extendDeep(
5120            {},
5121            _currentOptions,
5122            validatedOpts._default
5123          );
5124          _currentPreparedOptions = extendDeep(
5125            {},
5126            _currentPreparedOptions,
5127            validatedOpts._prepared
5128          );
5129
5130          return validatedOpts._prepared;
5131        }
5132
5133        //==== Structure ====//
5134
5135        /**
5136         * Builds or destroys the wrapper and helper DOM elements.
5137         * @param destroy Indicates whether the DOM shall be build or destroyed.
5138         */
5139        /**
5140         * Builds or destroys the wrapper and helper DOM elements.
5141         * @param destroy Indicates whether the DOM shall be build or destroyed.
5142         */
5143        function setupStructureDOM(destroy) {
5144          var strParent = "parent";
5145          var classNameResizeObserverHost = "os-resize-observer-host";
5146          var classNameTextareaElementFull =
5147            _classNameTextareaElement + _strSpace + _classNameTextInherit;
5148          var textareaClass = _isTextarea
5149            ? _strSpace + _classNameTextInherit
5150            : _strEmpty;
5151          var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs;
5152          var adoptAttrsMap = {};
5153          var applyAdoptedAttrs = function () {
5154            var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement;
5155            each(adoptAttrsMap, function (key, value) {
5156              if (type(value) == TYPES.s) {
5157                if (key == LEXICON.c) applyAdoptedAttrsElm.addClass(value);
5158                else applyAdoptedAttrsElm.attr(key, value);
5159              }
5160            });
5161          };
5162          var hostElementClassNames = [
5163            _classNameHostElement,
5164            _classNameHostElementForeign,
5165            _classNameHostTextareaElement,
5166            _classNameHostResizeDisabled,
5167            _classNameHostRTL,
5168            _classNameHostScrollbarHorizontalHidden,
5169            _classNameHostScrollbarVerticalHidden,
5170            _classNameHostTransition,
5171            _classNameHostScrolling,
5172            _classNameHostOverflow,
5173            _classNameHostOverflowX,
5174            _classNameHostOverflowY,
5175            _classNameThemeNone,
5176            _classNameTextareaElement,
5177            _classNameTextInherit,
5178            _classNameCache,
5179          ].join(_strSpace);
5180          var hostElementCSS = {};
5181
5182          //get host element as first element, because that's the most upper element and required for the other elements
5183          _hostElement =
5184            _hostElement ||
5185            (_isTextarea
5186              ? _domExists
5187                ? _targetElement[strParent]()
5188                    [strParent]()
5189                    [strParent]()
5190                    [strParent]()
5191                : FRAMEWORK(generateDiv(_classNameHostTextareaElement))
5192              : _targetElement);
5193          _contentElement =
5194            _contentElement ||
5195            selectOrGenerateDivByClass(
5196              _classNameContentElement + textareaClass
5197            );
5198          _viewportElement =
5199            _viewportElement ||
5200            selectOrGenerateDivByClass(
5201              _classNameViewportElement + textareaClass
5202            );
5203          _paddingElement =
5204            _paddingElement ||
5205            selectOrGenerateDivByClass(
5206              _classNamePaddingElement + textareaClass
5207            );
5208          _sizeObserverElement =
5209            _sizeObserverElement ||
5210            selectOrGenerateDivByClass(classNameResizeObserverHost);
5211          _textareaCoverElement =
5212            _textareaCoverElement ||
5213            (_isTextarea
5214              ? selectOrGenerateDivByClass(_classNameTextareaCoverElement)
5215              : undefined);
5216
5217          //add this class to workaround class changing issues with UI frameworks especially Vue
5218          if (_domExists) addClass(_hostElement, _classNameHostElementForeign);
5219
5220          //on destroy, remove all generated class names from the host element before collecting the adopted attributes
5221          //to prevent adopting generated class names
5222          if (destroy) removeClass(_hostElement, hostElementClassNames);
5223
5224          //collect all adopted attributes
5225          adoptAttrs =
5226            type(adoptAttrs) == TYPES.s
5227              ? adoptAttrs.split(_strSpace)
5228              : adoptAttrs;
5229          if (COMPATIBILITY.isA(adoptAttrs) && _isTextarea) {
5230            each(adoptAttrs, function (i, v) {
5231              if (type(v) == TYPES.s) {
5232                adoptAttrsMap[v] = destroy
5233                  ? _hostElement.attr(v)
5234                  : _targetElement.attr(v);
5235              }
5236            });
5237          }
5238
5239          if (!destroy) {
5240            if (_isTextarea) {
5241              if (!_currentPreparedOptions.sizeAutoCapable) {
5242                hostElementCSS[_strWidth] = _targetElement.css(_strWidth);
5243                hostElementCSS[_strHeight] = _targetElement.css(_strHeight);
5244              }
5245
5246              if (!_domExists)
5247                _targetElement
5248                  .addClass(_classNameTextInherit)
5249                  .wrap(_hostElement);
5250
5251              //jQuery clones elements in wrap functions, so we have to select them again
5252              _hostElement = _targetElement[strParent]().css(hostElementCSS);
5253            }
5254
5255            if (!_domExists) {
5256              //add the correct class to the target element
5257              addClass(
5258                _targetElement,
5259                _isTextarea
5260                  ? classNameTextareaElementFull
5261                  : _classNameHostElement
5262              );
5263
5264              //wrap the content into the generated elements to create the required DOM
5265              _hostElement
5266                .wrapInner(_contentElement)
5267                .wrapInner(_viewportElement)
5268                .wrapInner(_paddingElement)
5269                .prepend(_sizeObserverElement);
5270
5271              //jQuery clones elements in wrap functions, so we have to select them again
5272              _contentElement = findFirst(
5273                _hostElement,
5274                _strDot + _classNameContentElement
5275              );
5276              _viewportElement = findFirst(
5277                _hostElement,
5278                _strDot + _classNameViewportElement
5279              );
5280              _paddingElement = findFirst(
5281                _hostElement,
5282                _strDot + _classNamePaddingElement
5283              );
5284
5285              if (_isTextarea) {
5286                _contentElement.prepend(_textareaCoverElement);
5287                applyAdoptedAttrs();
5288              }
5289            }
5290
5291            if (_nativeScrollbarStyling)
5292              addClass(
5293                _viewportElement,
5294                _classNameViewportNativeScrollbarsInvisible
5295              );
5296            if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)
5297              addClass(
5298                _viewportElement,
5299                _classNameViewportNativeScrollbarsOverlaid
5300              );
5301            if (_isBody) addClass(_htmlElement, _classNameHTMLElement);
5302
5303            _sizeObserverElementNative = _sizeObserverElement[0];
5304            _hostElementNative = _hostElement[0];
5305            _paddingElementNative = _paddingElement[0];
5306            _viewportElementNative = _viewportElement[0];
5307            _contentElementNative = _contentElement[0];
5308
5309            updateViewportAttrsFromTarget();
5310          } else {
5311            if (_domExists && _initialized) {
5312              //clear size observer
5313              _sizeObserverElement.children().remove();
5314
5315              //remove the style property and classes from already generated elements
5316              each(
5317                [
5318                  _paddingElement,
5319                  _viewportElement,
5320                  _contentElement,
5321                  _textareaCoverElement,
5322                ],
5323                function (i, elm) {
5324                  if (elm) {
5325                    removeClass(
5326                      elm.removeAttr(LEXICON.s),
5327                      _classNamesDynamicDestroy
5328                    );
5329                  }
5330                }
5331              );
5332
5333              //add classes to the host element which was removed previously to match the expected DOM
5334              addClass(
5335                _hostElement,
5336                _isTextarea
5337                  ? _classNameHostTextareaElement
5338                  : _classNameHostElement
5339              );
5340            } else {
5341              //remove size observer
5342              remove(_sizeObserverElement);
5343
5344              //unwrap the content to restore DOM
5345              _contentElement.contents().unwrap().unwrap().unwrap();
5346
5347              if (_isTextarea) {
5348                _targetElement.unwrap();
5349                remove(_hostElement);
5350                remove(_textareaCoverElement);
5351                applyAdoptedAttrs();
5352              }
5353            }
5354
5355            if (_isTextarea) _targetElement.removeAttr(LEXICON.s);
5356
5357            if (_isBody) removeClass(_htmlElement, _classNameHTMLElement);
5358          }
5359        }
5360
5361        /**
5362         * Adds or removes all wrapper elements interactivity events.
5363         * @param destroy Indicates whether the Events shall be added or removed.
5364         */
5365        function setupStructureEvents() {
5366          var textareaKeyDownRestrictedKeyCodes = [
5367            112,
5368            113,
5369            114,
5370            115,
5371            116,
5372            117,
5373            118,
5374            119,
5375            120,
5376            121,
5377            123, //F1 to F12
5378            33,
5379            34, //page up, page down
5380            37,
5381            38,
5382            39,
5383            40, //left, up, right, down arrows
5384            16,
5385            17,
5386            18,
5387            19,
5388            20,
5389            144, //Shift, Ctrl, Alt, Pause, CapsLock, NumLock
5390          ];
5391          var textareaKeyDownKeyCodesList = [];
5392          var textareaUpdateIntervalID;
5393          var scrollStopTimeoutId;
5394          var scrollStopDelay = 175;
5395          var strFocus = "focus";
5396
5397          function updateTextarea(doClearInterval) {
5398            textareaUpdate();
5399            _base.update(_strAuto);
5400            if (doClearInterval && _autoUpdateRecommended)
5401              clearInterval(textareaUpdateIntervalID);
5402          }
5403          function textareaOnScroll(event) {
5404            _targetElement[_strScrollLeft](
5405              _rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0
5406            );
5407            _targetElement[_strScrollTop](0);
5408            COMPATIBILITY.prvD(event);
5409            COMPATIBILITY.stpP(event);
5410            return false;
5411          }
5412          function textareaOnDrop(event) {
5413            setTimeout(function () {
5414              if (!_destroyed) updateTextarea();
5415            }, 50);
5416          }
5417          function textareaOnFocus() {
5418            _textareaHasFocus = true;
5419            addClass(_hostElement, strFocus);
5420          }
5421          function textareaOnFocusout() {
5422            _textareaHasFocus = false;
5423            textareaKeyDownKeyCodesList = [];
5424            removeClass(_hostElement, strFocus);
5425            updateTextarea(true);
5426          }
5427          function textareaOnKeyDown(event) {
5428            var keyCode = event.keyCode;
5429
5430            if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) {
5431              if (!textareaKeyDownKeyCodesList[LEXICON.l]) {
5432                updateTextarea();
5433                textareaUpdateIntervalID = setInterval(
5434                  updateTextarea,
5435                  1000 / 60
5436                );
5437              }
5438              if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0)
5439                textareaKeyDownKeyCodesList.push(keyCode);
5440            }
5441          }
5442          function textareaOnKeyUp(event) {
5443            var keyCode = event.keyCode;
5444            var index = inArray(keyCode, textareaKeyDownKeyCodesList);
5445
5446            if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) {
5447              if (index > -1) textareaKeyDownKeyCodesList.splice(index, 1);
5448              if (!textareaKeyDownKeyCodesList[LEXICON.l]) updateTextarea(true);
5449            }
5450          }
5451          function contentOnTransitionEnd(event) {
5452            if (_autoUpdateCache === true) return;
5453            event = event.originalEvent || event;
5454            if (isSizeAffectingCSSProperty(event.propertyName))
5455              _base.update(_strAuto);
5456          }
5457          function viewportOnScroll(event) {
5458            if (!_sleeping) {
5459              if (scrollStopTimeoutId !== undefined)
5460                clearTimeout(scrollStopTimeoutId);
5461              else {
5462                if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)
5463                  refreshScrollbarsAutoHide(true);
5464
5465                if (!nativeOverlayScrollbarsAreActive())
5466                  addClass(_hostElement, _classNameHostScrolling);
5467
5468                dispatchCallback("onScrollStart", event);
5469              }
5470
5471              //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset
5472              //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point
5473              //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove
5474              if (!_scrollbarsHandlesDefineScrollPos) {
5475                refreshScrollbarHandleOffset(true);
5476                refreshScrollbarHandleOffset(false);
5477              }
5478              dispatchCallback("onScroll", event);
5479
5480              scrollStopTimeoutId = setTimeout(function () {
5481                if (!_destroyed) {
5482                  //OnScrollStop:
5483                  clearTimeout(scrollStopTimeoutId);
5484                  scrollStopTimeoutId = undefined;
5485
5486                  if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)
5487                    refreshScrollbarsAutoHide(false);
5488
5489                  if (!nativeOverlayScrollbarsAreActive())
5490                    removeClass(_hostElement, _classNameHostScrolling);
5491
5492                  dispatchCallback("onScrollStop", event);
5493                }
5494              }, scrollStopDelay);
5495            }
5496          }
5497
5498          if (_isTextarea) {
5499            if (_msieVersion > 9 || !_autoUpdateRecommended) {
5500              addDestroyEventListener(_targetElement, "input", updateTextarea);
5501            } else {
5502              addDestroyEventListener(
5503                _targetElement,
5504                [_strKeyDownEvent, _strKeyUpEvent],
5505                [textareaOnKeyDown, textareaOnKeyUp]
5506              );
5507            }
5508
5509            addDestroyEventListener(
5510              _targetElement,
5511              [_strScroll, "drop", strFocus, strFocus + "out"],
5512              [
5513                textareaOnScroll,
5514                textareaOnDrop,
5515                textareaOnFocus,
5516                textareaOnFocusout,
5517              ]
5518            );
5519          } else {
5520            addDestroyEventListener(
5521              _contentElement,
5522              _strTransitionEndEvent,
5523              contentOnTransitionEnd
5524            );
5525          }
5526          addDestroyEventListener(
5527            _viewportElement,
5528            _strScroll,
5529            viewportOnScroll,
5530            true
5531          );
5532        }
5533
5534        //==== Scrollbars ====//
5535
5536        /**
5537         * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle)
5538         * @param destroy Indicates whether the DOM shall be build or destroyed.
5539         */
5540        function setupScrollbarsDOM(destroy) {
5541          var selectOrGenerateScrollbarDOM = function (isHorizontal) {
5542            var scrollbarClassName = isHorizontal
5543              ? _classNameScrollbarHorizontal
5544              : _classNameScrollbarVertical;
5545            var scrollbar = selectOrGenerateDivByClass(
5546              _classNameScrollbar + _strSpace + scrollbarClassName,
5547              true
5548            );
5549            var track = selectOrGenerateDivByClass(
5550              _classNameScrollbarTrack,
5551              scrollbar
5552            );
5553            var handle = selectOrGenerateDivByClass(
5554              _classNameScrollbarHandle,
5555              scrollbar
5556            );
5557
5558            if (!_domExists && !destroy) {
5559              scrollbar.append(track);
5560              track.append(handle);
5561            }
5562
5563            return {
5564              _scrollbar: scrollbar,
5565              _track: track,
5566              _handle: handle,
5567            };
5568          };
5569          function resetScrollbarDOM(isHorizontal) {
5570            var scrollbarVars = getScrollbarVars(isHorizontal);
5571            var scrollbar = scrollbarVars._scrollbar;
5572            var track = scrollbarVars._track;
5573            var handle = scrollbarVars._handle;
5574
5575            if (_domExists && _initialized) {
5576              each([scrollbar, track, handle], function (i, elm) {
5577                removeClass(
5578                  elm.removeAttr(LEXICON.s),
5579                  _classNamesDynamicDestroy
5580                );
5581              });
5582            } else {
5583              remove(
5584                scrollbar ||
5585                  selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar
5586              );
5587            }
5588          }
5589          var horizontalElements;
5590          var verticalElements;
5591
5592          if (!destroy) {
5593            horizontalElements = selectOrGenerateScrollbarDOM(true);
5594            verticalElements = selectOrGenerateScrollbarDOM();
5595
5596            _scrollbarHorizontalElement = horizontalElements._scrollbar;
5597            _scrollbarHorizontalTrackElement = horizontalElements._track;
5598            _scrollbarHorizontalHandleElement = horizontalElements._handle;
5599            _scrollbarVerticalElement = verticalElements._scrollbar;
5600            _scrollbarVerticalTrackElement = verticalElements._track;
5601            _scrollbarVerticalHandleElement = verticalElements._handle;
5602
5603            if (!_domExists) {
5604              _paddingElement.after(_scrollbarVerticalElement);
5605              _paddingElement.after(_scrollbarHorizontalElement);
5606            }
5607          } else {
5608            resetScrollbarDOM(true);
5609            resetScrollbarDOM();
5610          }
5611        }
5612
5613        /**
5614         * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling)
5615         * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar.
5616         */
5617        function setupScrollbarEvents(isHorizontal) {
5618          var scrollbarVars = getScrollbarVars(isHorizontal);
5619          var scrollbarVarsInfo = scrollbarVars._info;
5620          var insideIFrame = _windowElementNative.top !== _windowElementNative;
5621          var xy = scrollbarVars._x_y;
5622          var XY = scrollbarVars._X_Y;
5623          var scroll = _strScroll + scrollbarVars._Left_Top;
5624          var strActive = "active";
5625          var strSnapHandle = "snapHandle";
5626          var strClickEvent = "click";
5627          var scrollDurationFactor = 1;
5628          var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl
5629          var trackTimeout;
5630          var mouseDownScroll;
5631          var mouseDownOffset;
5632          var mouseDownInvertedScale;
5633
5634          function getPointerPosition(event) {
5635            return _msieVersion && insideIFrame
5636              ? event["screen" + XY]
5637              : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames.
5638          }
5639          function getPreparedScrollbarsOption(name) {
5640            return _currentPreparedOptions.scrollbars[name];
5641          }
5642          function increaseTrackScrollAmount() {
5643            scrollDurationFactor = 0.5;
5644          }
5645          function decreaseTrackScrollAmount() {
5646            scrollDurationFactor = 1;
5647          }
5648          function stopClickEventPropagation(event) {
5649            COMPATIBILITY.stpP(event);
5650          }
5651          function documentKeyDown(event) {
5652            if (
5653              inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1
5654            )
5655              increaseTrackScrollAmount();
5656          }
5657          function documentKeyUp(event) {
5658            if (
5659              inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1
5660            )
5661              decreaseTrackScrollAmount();
5662          }
5663          function onMouseTouchDownContinue(event) {
5664            var originalEvent = event.originalEvent || event;
5665            var isTouchEvent = originalEvent.touches !== undefined;
5666            return _sleeping ||
5667              _destroyed ||
5668              nativeOverlayScrollbarsAreActive() ||
5669              !_scrollbarsDragScrollingCache ||
5670              (isTouchEvent && !getPreparedScrollbarsOption("touchSupport"))
5671              ? false
5672              : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent;
5673          }
5674          function documentDragMove(event) {
5675            if (onMouseTouchDownContinue(event)) {
5676              var trackLength = scrollbarVarsInfo._trackLength;
5677              var handleLength = scrollbarVarsInfo._handleLength;
5678              var scrollRange = scrollbarVarsInfo._maxScroll;
5679              var scrollRaw =
5680                (getPointerPosition(event) - mouseDownOffset) *
5681                mouseDownInvertedScale;
5682              var scrollDeltaPercent = scrollRaw / (trackLength - handleLength);
5683              var scrollDelta = scrollRange * scrollDeltaPercent;
5684              scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0;
5685              if (_isRTL && isHorizontal && !_rtlScrollBehavior.i)
5686                scrollDelta *= -1;
5687
5688              _viewportElement[scroll](
5689                MATH.round(mouseDownScroll + scrollDelta)
5690              );
5691
5692              if (_scrollbarsHandlesDefineScrollPos)
5693                refreshScrollbarHandleOffset(
5694                  isHorizontal,
5695                  mouseDownScroll + scrollDelta
5696                );
5697
5698              if (!_supportPassiveEvents) COMPATIBILITY.prvD(event);
5699            } else documentMouseTouchUp(event);
5700          }
5701          function documentMouseTouchUp(event) {
5702            event = event || event.originalEvent;
5703
5704            setupResponsiveEventListener(
5705              _documentElement,
5706              [
5707                _strMouseTouchMoveEvent,
5708                _strMouseTouchUpEvent,
5709                _strKeyDownEvent,
5710                _strKeyUpEvent,
5711                _strSelectStartEvent,
5712              ],
5713              [
5714                documentDragMove,
5715                documentMouseTouchUp,
5716                documentKeyDown,
5717                documentKeyUp,
5718                documentOnSelectStart,
5719              ],
5720              true
5721            );
5722            COMPATIBILITY.rAF()(function () {
5723              setupResponsiveEventListener(
5724                _documentElement,
5725                strClickEvent,
5726                stopClickEventPropagation,
5727                true,
5728                { _capture: true }
5729              );
5730            });
5731
5732            if (_scrollbarsHandlesDefineScrollPos)
5733              refreshScrollbarHandleOffset(isHorizontal, true);
5734
5735            _scrollbarsHandlesDefineScrollPos = false;
5736            removeClass(_bodyElement, _classNameDragging);
5737            removeClass(scrollbarVars._handle, strActive);
5738            removeClass(scrollbarVars._track, strActive);
5739            removeClass(scrollbarVars._scrollbar, strActive);
5740
5741            mouseDownScroll = undefined;
5742            mouseDownOffset = undefined;
5743            mouseDownInvertedScale = 1;
5744
5745            decreaseTrackScrollAmount();
5746
5747            if (trackTimeout !== undefined) {
5748              _base.scrollStop();
5749              clearTimeout(trackTimeout);
5750              trackTimeout = undefined;
5751            }
5752
5753            if (event) {
5754              var rect = _hostElementNative[LEXICON.bCR]();
5755              var mouseInsideHost =
5756                event.clientX >= rect.left &&
5757                event.clientX <= rect.right &&
5758                event.clientY >= rect.top &&
5759                event.clientY <= rect.bottom;
5760
5761              //if mouse is outside host element
5762              if (!mouseInsideHost) hostOnMouseLeave();
5763
5764              if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)
5765                refreshScrollbarsAutoHide(false);
5766            }
5767          }
5768          function onHandleMouseTouchDown(event) {
5769            if (onMouseTouchDownContinue(event))
5770              onHandleMouseTouchDownAction(event);
5771          }
5772          function onHandleMouseTouchDownAction(event) {
5773            mouseDownScroll = _viewportElement[scroll]();
5774            mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll;
5775            if ((_isRTL && isHorizontal && !_rtlScrollBehavior.n) || !_isRTL)
5776              mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll;
5777
5778            mouseDownInvertedScale = getHostElementInvertedScale()[xy];
5779            mouseDownOffset = getPointerPosition(event);
5780
5781            _scrollbarsHandlesDefineScrollPos =
5782              !getPreparedScrollbarsOption(strSnapHandle);
5783            addClass(_bodyElement, _classNameDragging);
5784            addClass(scrollbarVars._handle, strActive);
5785            addClass(scrollbarVars._scrollbar, strActive);
5786
5787            setupResponsiveEventListener(
5788              _documentElement,
5789              [
5790                _strMouseTouchMoveEvent,
5791                _strMouseTouchUpEvent,
5792                _strSelectStartEvent,
5793              ],
5794              [documentDragMove, documentMouseTouchUp, documentOnSelectStart]
5795            );
5796            COMPATIBILITY.rAF()(function () {
5797              setupResponsiveEventListener(
5798                _documentElement,
5799                strClickEvent,
5800                stopClickEventPropagation,
5801                false,
5802                { _capture: true }
5803              );
5804            });
5805
5806            if (_msieVersion || !_documentMixed) COMPATIBILITY.prvD(event);
5807            COMPATIBILITY.stpP(event);
5808          }
5809          function onTrackMouseTouchDown(event) {
5810            if (onMouseTouchDownContinue(event)) {
5811              var handleToViewportRatio =
5812                scrollbarVars._info._handleLength /
5813                Math.round(
5814                  MATH.min(
5815                    1,
5816                    _viewportSize[scrollbarVars._w_h] /
5817                      _contentScrollSizeCache[scrollbarVars._w_h]
5818                  ) * scrollbarVars._info._trackLength
5819                );
5820              var scrollDistance = MATH.round(
5821                _viewportSize[scrollbarVars._w_h] * handleToViewportRatio
5822              );
5823              var scrollBaseDuration = 270 * handleToViewportRatio;
5824              var scrollFirstIterationDelay = 400 * handleToViewportRatio;
5825              var trackOffset =
5826                scrollbarVars._track.offset()[scrollbarVars._left_top];
5827              var ctrlKey = event.ctrlKey;
5828              var instantScroll = event.shiftKey;
5829              var instantScrollTransition = instantScroll && ctrlKey;
5830              var isFirstIteration = true;
5831              var easing = "linear";
5832              var decreaseScroll;
5833              var finishedCondition;
5834              var scrollActionFinsished = function (transition) {
5835                if (_scrollbarsHandlesDefineScrollPos)
5836                  refreshScrollbarHandleOffset(isHorizontal, transition);
5837              };
5838              var scrollActionInstantFinished = function () {
5839                scrollActionFinsished();
5840                onHandleMouseTouchDownAction(event);
5841              };
5842              var scrollAction = function () {
5843                if (!_destroyed) {
5844                  var mouseOffset =
5845                    (mouseDownOffset - trackOffset) * mouseDownInvertedScale;
5846                  var handleOffset = scrollbarVarsInfo._handleOffset;
5847                  var trackLength = scrollbarVarsInfo._trackLength;
5848                  var handleLength = scrollbarVarsInfo._handleLength;
5849                  var scrollRange = scrollbarVarsInfo._maxScroll;
5850                  var currScroll = scrollbarVarsInfo._currentScroll;
5851                  var scrollDuration =
5852                    scrollBaseDuration * scrollDurationFactor;
5853                  var timeoutDelay = isFirstIteration
5854                    ? MATH.max(scrollFirstIterationDelay, scrollDuration)
5855                    : scrollDuration;
5856                  var instantScrollPosition =
5857                    scrollRange *
5858                    ((mouseOffset - handleLength / 2) /
5859                      (trackLength - handleLength)); // 100% * positionPercent
5860                  var rtlIsNormal =
5861                    _isRTL &&
5862                    isHorizontal &&
5863                    ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) ||
5864                      _normalizeRTLCache);
5865                  var decreaseScrollCondition = rtlIsNormal
5866                    ? handleOffset < mouseOffset
5867                    : handleOffset > mouseOffset;
5868                  var scrollObj = {};
5869                  var animationObj = {
5870                    easing: easing,
5871                    step: function (now) {
5872                      if (_scrollbarsHandlesDefineScrollPos) {
5873                        _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340
5874                        refreshScrollbarHandleOffset(isHorizontal, now);
5875                      }
5876                    },
5877                  };
5878                  instantScrollPosition = isFinite(instantScrollPosition)
5879                    ? instantScrollPosition
5880                    : 0;
5881                  instantScrollPosition =
5882                    _isRTL && isHorizontal && !_rtlScrollBehavior.i
5883                      ? scrollRange - instantScrollPosition
5884                      : instantScrollPosition;
5885
5886                  //_base.scrollStop();
5887
5888                  if (instantScroll) {
5889                    _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position
5890                    if (instantScrollTransition) {
5891                      //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position
5892                      //and the animation stops at the correct point
5893                      instantScrollPosition = _viewportElement[scroll]();
5894                      //scroll back to the position before instant scrolling so animation can be performed
5895                      _viewportElement[scroll](currScroll);
5896
5897                      instantScrollPosition =
5898                        rtlIsNormal && _rtlScrollBehavior.i
5899                          ? scrollRange - instantScrollPosition
5900                          : instantScrollPosition;
5901                      instantScrollPosition =
5902                        rtlIsNormal && _rtlScrollBehavior.n
5903                          ? -instantScrollPosition
5904                          : instantScrollPosition;
5905
5906                      scrollObj[xy] = instantScrollPosition;
5907                      _base.scroll(
5908                        scrollObj,
5909                        extendDeep(animationObj, {
5910                          duration: 130,
5911                          complete: scrollActionInstantFinished,
5912                        })
5913                      );
5914                    } else scrollActionInstantFinished();
5915                  } else {
5916                    decreaseScroll = isFirstIteration
5917                      ? decreaseScrollCondition
5918                      : decreaseScroll;
5919                    finishedCondition = rtlIsNormal
5920                      ? decreaseScroll
5921                        ? handleOffset + handleLength >= mouseOffset
5922                        : handleOffset <= mouseOffset
5923                      : decreaseScroll
5924                      ? handleOffset <= mouseOffset
5925                      : handleOffset + handleLength >= mouseOffset;
5926
5927                    if (finishedCondition) {
5928                      clearTimeout(trackTimeout);
5929                      _base.scrollStop();
5930                      trackTimeout = undefined;
5931                      scrollActionFinsished(true);
5932                    } else {
5933                      trackTimeout = setTimeout(scrollAction, timeoutDelay);
5934
5935                      scrollObj[xy] =
5936                        (decreaseScroll ? "-=" : "+=") + scrollDistance;
5937                      _base.scroll(
5938                        scrollObj,
5939                        extendDeep(animationObj, {
5940                          duration: scrollDuration,
5941                        })
5942                      );
5943                    }
5944                    isFirstIteration = false;
5945                  }
5946                }
5947              };
5948              if (ctrlKey) increaseTrackScrollAmount();
5949
5950              mouseDownInvertedScale = getHostElementInvertedScale()[xy];
5951              mouseDownOffset = COMPATIBILITY.page(event)[xy];
5952
5953              _scrollbarsHandlesDefineScrollPos =
5954                !getPreparedScrollbarsOption(strSnapHandle);
5955              addClass(_bodyElement, _classNameDragging);
5956              addClass(scrollbarVars._track, strActive);
5957              addClass(scrollbarVars._scrollbar, strActive);
5958
5959              setupResponsiveEventListener(
5960                _documentElement,
5961                [
5962                  _strMouseTouchUpEvent,
5963                  _strKeyDownEvent,
5964                  _strKeyUpEvent,
5965                  _strSelectStartEvent,
5966                ],
5967                [
5968                  documentMouseTouchUp,
5969                  documentKeyDown,
5970                  documentKeyUp,
5971                  documentOnSelectStart,
5972                ]
5973              );
5974
5975              scrollAction();
5976              COMPATIBILITY.prvD(event);
5977              COMPATIBILITY.stpP(event);
5978            }
5979          }
5980          function onTrackMouseTouchEnter(event) {
5981            //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is "scroll" or "move".
5982            _scrollbarsHandleHovered = true;
5983            if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)
5984              refreshScrollbarsAutoHide(true);
5985          }
5986          function onTrackMouseTouchLeave(event) {
5987            _scrollbarsHandleHovered = false;
vendor: 19,961 bytes, lines 5988-6470
5988            if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)
5989              refreshScrollbarsAutoHide(false);
5990          }
5991          function onScrollbarMouseTouchDown(event) {
5992            COMPATIBILITY.stpP(event);
5993          }
5994
5995          addDestroyEventListener(
5996            scrollbarVars._handle,
5997            _strMouseTouchDownEvent,
5998            onHandleMouseTouchDown
5999          );
6000          addDestroyEventListener(
6001            scrollbarVars._track,
6002            [_strMouseTouchDownEvent, _strMouseEnter, _strMouseLeave],
6003            [
6004              onTrackMouseTouchDown,
6005              onTrackMouseTouchEnter,
6006              onTrackMouseTouchLeave,
6007            ]
6008          );
6009          addDestroyEventListener(
6010            scrollbarVars._scrollbar,
6011            _strMouseTouchDownEvent,
6012            onScrollbarMouseTouchDown
6013          );
6014
6015          if (_supportTransition) {
6016            addDestroyEventListener(
6017              scrollbarVars._scrollbar,
6018              _strTransitionEndEvent,
6019              function (event) {
6020                if (event.target !== scrollbarVars._scrollbar[0]) return;
6021                refreshScrollbarHandleLength(isHorizontal);
6022                refreshScrollbarHandleOffset(isHorizontal);
6023              }
6024            );
6025          }
6026        }
6027
6028        /**
6029         * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not.
6030         * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target.
6031         * @param shallBeVisible True if the scrollbar shall be shown, false if hidden.
6032         * @param canScroll True if the scrollbar is scrollable, false otherwise.
6033         */
6034        function refreshScrollbarAppearance(
6035          isHorizontal,
6036          shallBeVisible,
6037          canScroll
6038        ) {
6039          var scrollbarHiddenClassName = isHorizontal
6040            ? _classNameHostScrollbarHorizontalHidden
6041            : _classNameHostScrollbarVerticalHidden;
6042          var scrollbarElement = isHorizontal
6043            ? _scrollbarHorizontalElement
6044            : _scrollbarVerticalElement;
6045
6046          addRemoveClass(
6047            _hostElement,
6048            scrollbarHiddenClassName,
6049            !shallBeVisible
6050          );
6051          addRemoveClass(
6052            scrollbarElement,
6053            _classNameScrollbarUnusable,
6054            !canScroll
6055          );
6056        }
6057
6058        /**
6059         * Autoshows / autohides both scrollbars with.
6060         * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden.
6061         * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise.
6062         */
6063        function refreshScrollbarsAutoHide(shallBeVisible, delayfree) {
6064          clearTimeout(_scrollbarsAutoHideTimeoutId);
6065          if (shallBeVisible) {
6066            //if(_hasOverflowCache.x && _hideOverflowCache.xs)
6067            removeClass(
6068              _scrollbarHorizontalElement,
6069              _classNameScrollbarAutoHidden
6070            );
6071            //if(_hasOverflowCache.y && _hideOverflowCache.ys)
6072            removeClass(
6073              _scrollbarVerticalElement,
6074              _classNameScrollbarAutoHidden
6075            );
6076          } else {
6077            var anyActive;
6078            var strActive = "active";
6079            var hide = function () {
6080              if (!_scrollbarsHandleHovered && !_destroyed) {
6081                anyActive =
6082                  _scrollbarHorizontalHandleElement.hasClass(strActive) ||
6083                  _scrollbarVerticalHandleElement.hasClass(strActive);
6084                if (
6085                  !anyActive &&
6086                  (_scrollbarsAutoHideScroll ||
6087                    _scrollbarsAutoHideMove ||
6088                    _scrollbarsAutoHideLeave)
6089                )
6090                  addClass(
6091                    _scrollbarHorizontalElement,
6092                    _classNameScrollbarAutoHidden
6093                  );
6094                if (
6095                  !anyActive &&
6096                  (_scrollbarsAutoHideScroll ||
6097                    _scrollbarsAutoHideMove ||
6098                    _scrollbarsAutoHideLeave)
6099                )
6100                  addClass(
6101                    _scrollbarVerticalElement,
6102                    _classNameScrollbarAutoHidden
6103                  );
6104              }
6105            };
6106            if (_scrollbarsAutoHideDelay > 0 && delayfree !== true)
6107              _scrollbarsAutoHideTimeoutId = setTimeout(
6108                hide,
6109                _scrollbarsAutoHideDelay
6110              );
6111            else hide();
6112          }
6113        }
6114
6115        /**
6116         * Refreshes the handle length of the given scrollbar.
6117         * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed.
6118         */
6119        function refreshScrollbarHandleLength(isHorizontal) {
6120          var handleCSS = {};
6121          var scrollbarVars = getScrollbarVars(isHorizontal);
6122          var scrollbarVarsInfo = scrollbarVars._info;
6123          var digit = 1000000;
6124          //get and apply intended handle length
6125          var handleRatio = MATH.min(
6126            1,
6127            _viewportSize[scrollbarVars._w_h] /
6128              _contentScrollSizeCache[scrollbarVars._w_h]
6129          );
6130          handleCSS[scrollbarVars._width_height] =
6131            MATH.floor(handleRatio * 100 * digit) / digit + "%"; //the last * digit / digit is for flooring to the 4th digit
6132
6133          if (!nativeOverlayScrollbarsAreActive())
6134            scrollbarVars._handle.css(handleCSS);
6135
6136          //measure the handle length to respect min & max length
6137          scrollbarVarsInfo._handleLength =
6138            scrollbarVars._handle[0]["offset" + scrollbarVars._Width_Height];
6139          scrollbarVarsInfo._handleLengthRatio = handleRatio;
6140        }
6141
6142        /**
6143         * Refreshes the handle offset of the given scrollbar.
6144         * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed.
6145         * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop)
6146         */
6147        function refreshScrollbarHandleOffset(
6148          isHorizontal,
6149          scrollOrTransition
6150        ) {
6151          var transition = type(scrollOrTransition) == TYPES.b;
6152          var transitionDuration = 250;
6153          var isRTLisHorizontal = _isRTL && isHorizontal;
6154          var scrollbarVars = getScrollbarVars(isHorizontal);
6155          var scrollbarVarsInfo = scrollbarVars._info;
6156          var strTranslateBrace = "translate(";
6157          var strTransform = VENDORS._cssProperty("transform");
6158          var strTransition = VENDORS._cssProperty("transition");
6159          var nativeScroll = isHorizontal
6160            ? _viewportElement[_strScrollLeft]()
6161            : _viewportElement[_strScrollTop]();
6162          var currentScroll =
6163            scrollOrTransition === undefined || transition
6164              ? nativeScroll
6165              : scrollOrTransition;
6166
6167          //measure the handle length to respect min & max length
6168          var handleLength = scrollbarVarsInfo._handleLength;
6169          var trackLength =
6170            scrollbarVars._track[0]["offset" + scrollbarVars._Width_Height];
6171          var handleTrackDiff = trackLength - handleLength;
6172          var handleCSS = {};
6173          var transformOffset;
6174          var translateValue;
6175
6176          //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]'
6177          // because its a bit behind during the small delay when content size updates
6178          //(delay = mutationObserverContentLag, if its 0 then this var could be used)
6179          var maxScroll =
6180            (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] -
6181              _viewportElementNative["client" + scrollbarVars._Width_Height]) *
6182            (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative
6183          var getScrollRatio = function (base) {
6184            return isNaN(base / maxScroll)
6185              ? 0
6186              : MATH.max(0, MATH.min(1, base / maxScroll));
6187          };
6188          var getHandleOffset = function (scrollRatio) {
6189            var offset = handleTrackDiff * scrollRatio;
6190            offset = isNaN(offset) ? 0 : offset;
6191            offset =
6192              isRTLisHorizontal && !_rtlScrollBehavior.i
6193                ? trackLength - handleLength - offset
6194                : offset;
6195            offset = MATH.max(0, offset);
6196            return offset;
6197          };
6198          var scrollRatio = getScrollRatio(nativeScroll);
6199          var unsnappedScrollRatio = getScrollRatio(currentScroll);
6200          var handleOffset = getHandleOffset(unsnappedScrollRatio);
6201          var snappedHandleOffset = getHandleOffset(scrollRatio);
6202
6203          scrollbarVarsInfo._maxScroll = maxScroll;
6204          scrollbarVarsInfo._currentScroll = nativeScroll;
6205          scrollbarVarsInfo._currentScrollRatio = scrollRatio;
6206
6207          if (_supportTransform) {
6208            transformOffset = isRTLisHorizontal
6209              ? -(trackLength - handleLength - handleOffset)
6210              : handleOffset; //in px
6211            //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in %
6212            translateValue = isHorizontal
6213              ? strTranslateBrace + transformOffset + "px, 0)"
6214              : strTranslateBrace + "0, " + transformOffset + "px)";
6215
6216            handleCSS[strTransform] = translateValue;
6217
6218            //apply or clear up transition
6219            if (_supportTransition)
6220              handleCSS[strTransition] =
6221                transition &&
6222                MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1
6223                  ? getCSSTransitionString(scrollbarVars._handle) +
6224                    ", " +
6225                    (strTransform + _strSpace + transitionDuration + "ms")
6226                  : _strEmpty;
6227          } else handleCSS[scrollbarVars._left_top] = handleOffset;
6228
6229          //only apply css if offset has changed and overflow exists.
6230          if (!nativeOverlayScrollbarsAreActive()) {
6231            scrollbarVars._handle.css(handleCSS);
6232
6233            //clear up transition
6234            if (_supportTransform && _supportTransition && transition) {
6235              scrollbarVars._handle.one(_strTransitionEndEvent, function () {
6236                if (!_destroyed)
6237                  scrollbarVars._handle.css(strTransition, _strEmpty);
6238              });
6239            }
6240          }
6241
6242          scrollbarVarsInfo._handleOffset = handleOffset;
6243          scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset;
6244          scrollbarVarsInfo._trackLength = trackLength;
6245        }
6246
6247        /**
6248         * Refreshes the interactivity of the given scrollbar element.
6249         * @param isTrack True if the track element is the target, false if the handle element is the target.
6250         * @param value True for interactivity false for no interactivity.
6251         */
6252        function refreshScrollbarsInteractive(isTrack, value) {
6253          var action = value ? "removeClass" : "addClass";
6254          var element1 = isTrack
6255            ? _scrollbarHorizontalTrackElement
6256            : _scrollbarHorizontalHandleElement;
6257          var element2 = isTrack
6258            ? _scrollbarVerticalTrackElement
6259            : _scrollbarVerticalHandleElement;
6260          var className = isTrack
6261            ? _classNameScrollbarTrackOff
6262            : _classNameScrollbarHandleOff;
6263
6264          element1[action](className);
6265          element2[action](className);
6266        }
6267
6268        /**
6269         * Returns a object which is used for fast access for specific variables.
6270         * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed.
6271         * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}}
6272         */
6273        function getScrollbarVars(isHorizontal) {
6274          return {
6275            _width_height: isHorizontal ? _strWidth : _strHeight,
6276            _Width_Height: isHorizontal ? "Width" : "Height",
6277            _left_top: isHorizontal ? _strLeft : _strTop,
6278            _Left_Top: isHorizontal ? "Left" : "Top",
6279            _x_y: isHorizontal ? _strX : _strY,
6280            _X_Y: isHorizontal ? "X" : "Y",
6281            _w_h: isHorizontal ? "w" : "h",
6282            _l_t: isHorizontal ? "l" : "t",
6283            _track: isHorizontal
6284              ? _scrollbarHorizontalTrackElement
6285              : _scrollbarVerticalTrackElement,
6286            _handle: isHorizontal
6287              ? _scrollbarHorizontalHandleElement
6288              : _scrollbarVerticalHandleElement,
6289            _scrollbar: isHorizontal
6290              ? _scrollbarHorizontalElement
6291              : _scrollbarVerticalElement,
6292            _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo,
6293          };
6294        }
6295
6296        //==== Scrollbar Corner ====//
6297
6298        /**
6299         * Builds or destroys the scrollbar corner DOM element.
6300         * @param destroy Indicates whether the DOM shall be build or destroyed.
6301         */
6302        function setupScrollbarCornerDOM(destroy) {
6303          _scrollbarCornerElement =
6304            _scrollbarCornerElement ||
6305            selectOrGenerateDivByClass(_classNameScrollbarCorner, true);
6306
6307          if (!destroy) {
6308            if (!_domExists) {
6309              _hostElement.append(_scrollbarCornerElement);
6310            }
6311          } else {
6312            if (_domExists && _initialized) {
6313              removeClass(
6314                _scrollbarCornerElement.removeAttr(LEXICON.s),
6315                _classNamesDynamicDestroy
6316              );
6317            } else {
6318              remove(_scrollbarCornerElement);
6319            }
6320          }
6321        }
6322
6323        /**
6324         * Initializes all scrollbar corner interactivity events.
6325         */
6326        function setupScrollbarCornerEvents() {
6327          var insideIFrame = _windowElementNative.top !== _windowElementNative;
6328          var mouseDownPosition = {};
6329          var mouseDownSize = {};
6330          var mouseDownInvertedScale = {};
6331          var reconnectMutationObserver;
6332
6333          function documentDragMove(event) {
6334            if (onMouseTouchDownContinue(event)) {
6335              var pageOffset = getCoordinates(event);
6336              var hostElementCSS = {};
6337              if (_resizeHorizontal || _resizeBoth)
6338                hostElementCSS[_strWidth] =
6339                  mouseDownSize.w +
6340                  (pageOffset.x - mouseDownPosition.x) *
6341                    mouseDownInvertedScale.x;
6342              if (_resizeVertical || _resizeBoth)
6343                hostElementCSS[_strHeight] =
6344                  mouseDownSize.h +
6345                  (pageOffset.y - mouseDownPosition.y) *
6346                    mouseDownInvertedScale.y;
6347              _hostElement.css(hostElementCSS);
6348              COMPATIBILITY.stpP(event);
6349            } else {
6350              documentMouseTouchUp(event);
6351            }
6352          }
6353          function documentMouseTouchUp(event) {
6354            var eventIsTrusted = event !== undefined;
6355
6356            setupResponsiveEventListener(
6357              _documentElement,
6358              [
6359                _strSelectStartEvent,
6360                _strMouseTouchMoveEvent,
6361                _strMouseTouchUpEvent,
6362              ],
6363              [documentOnSelectStart, documentDragMove, documentMouseTouchUp],
6364              true
6365            );
6366
6367            removeClass(_bodyElement, _classNameDragging);
6368            if (_scrollbarCornerElement.releaseCapture)
6369              _scrollbarCornerElement.releaseCapture();
6370
6371            if (eventIsTrusted) {
6372              if (reconnectMutationObserver) connectMutationObservers();
6373              _base.update(_strAuto);
6374            }
6375            reconnectMutationObserver = false;
6376          }
6377          function onMouseTouchDownContinue(event) {
6378            var originalEvent = event.originalEvent || event;
6379            var isTouchEvent = originalEvent.touches !== undefined;
6380            return _sleeping || _destroyed
6381              ? false
6382              : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent;
6383          }
6384          function getCoordinates(event) {
6385            return _msieVersion && insideIFrame
6386              ? { x: event.screenX, y: event.screenY }
6387              : COMPATIBILITY.page(event);
6388          }
6389
6390          addDestroyEventListener(
6391            _scrollbarCornerElement,
6392            _strMouseTouchDownEvent,
6393            function (event) {
6394              if (onMouseTouchDownContinue(event) && !_resizeNone) {
6395                if (_mutationObserversConnected) {
6396                  reconnectMutationObserver = true;
6397                  disconnectMutationObservers();
6398                }
6399
6400                mouseDownPosition = getCoordinates(event);
6401
6402                mouseDownSize.w =
6403                  _hostElementNative[LEXICON.oW] -
6404                  (!_isBorderBox ? _paddingX : 0);
6405                mouseDownSize.h =
6406                  _hostElementNative[LEXICON.oH] -
6407                  (!_isBorderBox ? _paddingY : 0);
6408                mouseDownInvertedScale = getHostElementInvertedScale();
6409
6410                setupResponsiveEventListener(
6411                  _documentElement,
6412                  [
6413                    _strSelectStartEvent,
6414                    _strMouseTouchMoveEvent,
6415                    _strMouseTouchUpEvent,
6416                  ],
6417                  [
6418                    documentOnSelectStart,
6419                    documentDragMove,
6420                    documentMouseTouchUp,
6421                  ]
6422                );
6423
6424                addClass(_bodyElement, _classNameDragging);
6425                if (_scrollbarCornerElement.setCapture)
6426                  _scrollbarCornerElement.setCapture();
6427
6428                COMPATIBILITY.prvD(event);
6429                COMPATIBILITY.stpP(event);
6430              }
6431            }
6432          );
6433        }
6434
6435        //==== Utils ====//
6436
6437        /**
6438         * Calls the callback with the given name. The Context of this callback is always _base (this).
6439         * @param name The name of the target which shall be called.
6440         * @param args The args with which the callback shall be called.
6441         * @param dependent Boolean which decides whether the callback shall be fired, undefined is like a "true" value.
6442         */
6443        function dispatchCallback(name, args, dependent) {
6444          if (dependent === false) return;
6445          if (_initialized) {
6446            var callback = _currentPreparedOptions.callbacks[name];
6447            var extensionOnName = name;
6448            var ext;
6449
6450            if (extensionOnName.substr(0, 2) === "on")
6451              extensionOnName =
6452                extensionOnName.substr(2, 1).toLowerCase() +
6453                extensionOnName.substr(3);
6454
6455            if (type(callback) == TYPES.f) callback.call(_base, args);
6456
6457            each(_extensions, function () {
6458              ext = this;
6459              if (type(ext.on) == TYPES.f) ext.on(extensionOnName, args);
6460            });
6461          } else if (!_destroyed)
6462            _callbacksInitQeueue.push({ n: name, a: args });
6463        }
6464
6465        /**
6466         * Sets the "top, right, bottom, left" properties, with a given prefix, of the given css object.
6467         * @param targetCSSObject The css object to which the values shall be applied.
6468         * @param prefix The prefix of the "top, right, bottom, left" css properties. (example: 'padding-' is a valid prefix)
6469         * @param values A array of values which shall be applied to the "top, right, bottom, left" -properties. The array order is [top, right, bottom, left].
6470         * If this argument is undefined the value '' (empty string) 
6470will be applied to all properties.
6471         */
6472        function setTopRightBottomLeft(targetCSSObject, prefix, values) {
6473          prefix = prefix || _strEmpty;
6474          values = values || [_strEmpty, _strEmpty, _strEmpty, _strEmpty];
6475
6476          targetCSSObject[prefix + _strTop] = values[0];
6477          targetCSSObject[prefix + _strRight] = values[1];
6478          targetCSSObject[prefix + _strBottom] = values[2];
6479          targetCSSObject[prefix + _strLeft] = values[3];
6480        }
6481
6482        /**
6483         * Gets the "top, right, bottom, left" CSS properties of the CSS property with the given prefix from the host element.
6484         * @param prefix The prefix of the "top, right, bottom, left" css properties. (example: 'padding-' is a valid prefix)
6485         * @param suffix The suffix of the "top, right, bottom, left" css properties. (example: 'border-' is a valid prefix with '-width' is a valid suffix)
6486         * @param zeroX True if the x axis shall be 0.
6487         * @param zeroY True if the y axis shall be 0.
6488         * @returns {{}} The object which contains the numbers of the read CSS properties.
6489         */
6490        function getTopRightBottomLeftHost(prefix, suffix, zeroX, zeroY) {
6491          suffix = suffix || _strEmpty;
6492          prefix = prefix || _strEmpty;
6493          return {
6494            t: zeroY
6495              ? 0
6496              : parseToZeroOrNumber(
6497                  _hostElement.css(prefix + _strTop + suffix)
6498                ),
6499            r: zeroX
6500              ? 0
6501              : parseToZeroOrNumber(
6502                  _hostElement.css(prefix + _strRight + suffix)
6503                ),
6504            b: zeroY
6505              ? 0
6506              : parseToZeroOrNumber(
6507                  _hostElement.css(prefix + _strBottom + suffix)
6508                ),
6509            l: zeroX
6510              ? 0
6511              : parseToZeroOrNumber(
6512                  _hostElement.css(prefix + _strLeft + suffix)
6513                ),
6514          };
6515        }
6516
6517        /**
6518         * Returns the computed CSS transition string from the given element.
6519         * @param element The element from which the transition string shall be returned.
6520         * @returns {string} The CSS transition string from the given element.
6521         */
6522        function getCSSTransitionString(element) {
6523          var transitionStr = VENDORS._cssProperty("transition");
6524          var assembledValue = element.css(transitionStr);
6525          if (assembledValue) return assembledValue;
6526          var regExpString = "\\s*(" + "([^,(]+(\\(.+?\\))?)+" + ")[\\s,]*";
6527          var regExpMain = new RegExp(regExpString);
6528          var regExpValidate = new RegExp("^(" + regExpString + ")+$");
6529          var properties = "property duration timing-function delay".split(" ");
6530          var result = [];
6531          var strResult;
6532          var valueArray;
6533          var i = 0;
6534          var j;
6535          var splitCssStyleByComma = function (str) {
6536            strResult = [];
6537            if (!str.match(regExpValidate)) return str;
6538            while (str.match(regExpMain)) {
6539              strResult.push(RegExp.$1);
6540              str = str.replace(regExpMain, _strEmpty);
6541            }
6542
6543            return strResult;
6544          };
6545          for (; i < properties[LEXICON.l]; i++) {
6546            valueArray = splitCssStyleByComma(
6547              element.css(transitionStr + "-" + properties[i])
6548            );
6549            for (j = 0; j < valueArray[LEXICON.l]; j++)
6550              result[j] =
6551                (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j];
6552          }
6553          return result.join(", ");
6554        }
6555
6556        /**
6557         * Generates a Regular Expression which matches with a string which starts with 'os-host'.
6558         * @param {boolean} withCurrClassNameOption The Regular Expression also matches if the string is the current ClassName option (multiple values splitted by space possible).
6559         * @param {boolean} withOldClassNameOption The Regular Expression also matches if the string is the old ClassName option (multiple values splitted by space possible).
6560         */
6561        function createHostClassNameRegExp(
6562          withCurrClassNameOption,
6563          withOldClassNameOption
6564        ) {
6565          var i;
6566          var split;
6567          var appendix;
6568          var appendClasses = function (classes, condition) {
6569            appendix = "";
6570            if (condition && typeof classes == TYPES.s) {
6571              split = classes.split(_strSpace);
6572              for (i = 0; i < split[LEXICON.l]; i++)
6573                appendix += "|" + split[i] + "$";
6574              // split[i].replace(/[.*+?^${}()|[\]\\]/g, '\\$&') for escaping regex characters
6575            }
6576            return appendix;
6577          };
6578
6579          return new RegExp(
6580            "(^" +
6581              _classNameHostElement +
6582              "([-_].+|)$)" +
6583              appendClasses(_classNameCache, withCurrClassNameOption) +
6584              appendClasses(_oldClassName, withOldClassNameOption),
6585            "g"
6586          );
6587        }
6588
6589        /**
6590         * Calculates the host-elements inverted scale. (invertedScale = 1 / scale)
6591         * @returns {{x: number, y: number}} The scale of the host-element.
6592         */
6593        function getHostElementInvertedScale() {
6594          var rect = _paddingElementNative[LEXICON.bCR]();
6595          return {
6596            x: _supportTransform
6597              ? 1 /
6598                  (MATH.round(rect.width) /
6599                    _paddingElementNative[LEXICON.oW]) || 1
6600              : 1,
6601            y: _supportTransform
6602              ? 1 /
6603                  (MATH.round(rect.height) /
6604                    _paddingElementNative[LEXICON.oH]) || 1
6605              : 1,
6606          };
6607        }
6608
6609        /**
6610         * Checks whether the given object is a HTMLElement.
6611         * @param o The object which shall be checked.
6612         * @returns {boolean} True the given object is a HTMLElement, false otherwise.
6613         */
6614        function isHTMLElement(o) {
6615          var strOwnerDocument = "ownerDocument";
6616          var strHTMLElement = "HTMLElement";
6617          var wnd =
6618            o && o[strOwnerDocument]
6619              ? o[strOwnerDocument].parentWindow || window
6620              : window;
6621          return typeof wnd[strHTMLElement] == TYPES.o
6622            ? o instanceof wnd[strHTMLElement] //DOM2
6623            : o &&
6624                typeof o == TYPES.o &&
6625                o !== null &&
6626                o.nodeType === 1 &&
6627                typeof o.nodeName == TYPES.s;
6628        }
6629
6630        /**
6631         * Compares 2 arrays and returns the differences between them as a array.
6632         * @param a1 The first array which shall be compared.
6633         * @param a2 The second array which shall be compared.
6634         * @returns {Array} The differences between the two arrays.
6635         */
6636        function getArrayDifferences(a1, a2) {
6637          var a = [];
6638          var diff = [];
6639          var i;
6640          var k;
6641          for (i = 0; i < a1.length; i++) a[a1[i]] = true;
6642          for (i = 0; i < a2.length; i++) {
6643            if (a[a2[i]]) delete a[a2[i]];
6644            else a[a2[i]] = true;
6645          }
6646          for (k in a) diff.push(k);
6647          return diff;
6648        }
6649
6650        /**
6651         * Returns Zero or the number to which the value can be parsed.
6652         * @param value The value which shall be parsed.
6653         * @param toFloat Indicates whether the number shall be parsed to a float.
6654         */
6655        function parseToZeroOrNumber(value, toFloat) {
6656          var num = toFloat ? parseFloat(value) : parseInt(value, 10);
6657          return isNaN(num) ? 0 : num;
6658        }
6659
6660        /**
6661         * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it.
6662         * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported.
6663         */
6664        function getTextareaInfo() {
6665          //read needed values
6666          var textareaCursorPosition = _targetElementNative.selectionStart;
6667          if (textareaCursorPosition === undefined) return;
6668
6669          var textareaValue = _targetElement.val();
6670          var textareaLength = textareaValue[LEXICON.l];
6671          var textareaRowSplit = textareaValue.split("\n");
6672          var textareaLastRow = textareaRowSplit[LEXICON.l];
6673          var textareaCurrentCursorRowSplit = textareaValue
6674            .substr(0, textareaCursorPosition)
6675            .split("\n");
6676          var widestRow = 0;
6677          var textareaLastCol = 0;
6678          var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l];
6679          var cursorCol =
6680            textareaCurrentCursorRowSplit[
6681              textareaCurrentCursorRowSplit[LEXICON.l] - 1
6682            ][LEXICON.l];
6683          var rowCols;
6684          var i;
6685
6686          //get widest Row and the last column of the textarea
6687          for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) {
6688            rowCols = textareaRowSplit[i][LEXICON.l];
6689            if (rowCols > textareaLastCol) {
6690              widestRow = i + 1;
6691              textareaLastCol = rowCols;
6692            }
6693          }
6694
6695          return {
6696            _cursorRow: cursorRow, //cursorRow
6697            _cursorColumn: cursorCol, //cursorCol
6698            _rows: textareaLastRow, //rows
6699            _columns: textareaLastCol, //cols
6700            _widestRow: widestRow, //wRow
6701            _cursorPosition: textareaCursorPosition, //pos
6702            _cursorMax: textareaLength, //max
6703          };
6704        }
6705
6706        /**
6707         * Determines whether native overlay scrollbars are active.
6708         * @returns {boolean} True if native overlay scrollbars are active, false otherwise.
6709         */
6710        function nativeOverlayScrollbarsAreActive() {
6711          return (
6712            _ignoreOverlayScrollbarHidingCache &&
6713            _nativeScrollbarIsOverlaid.x &&
6714            _nativeScrollbarIsOverlaid.y
6715          );
6716        }
6717
6718        /**
6719         * Gets the element which is used to measure the content size.
6720         * @returns {*} TextareaCover if target element is textarea else the ContentElement.
6721         */
6722        function getContentMeasureElement() {
6723          return _isTextarea ? _textareaCoverElement[0] : _contentElementNative;
6724        }
6725
6726        /**
6727         * Generates a string which represents a HTML div with the given classes or attributes.
6728         * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as "className".)
6729         * @param content The content of the div as string.
6730         * @returns {string} The concated string which represents a HTML div and its content.
6731         */
6732        function generateDiv(classesOrAttrs, content) {
6733          return (
6734            "<div " +
6735            (classesOrAttrs
6736              ? type(classesOrAttrs) == TYPES.s
6737                ? 'class="' + classesOrAttrs + '"'
6738                : (function () {
6739                    var key;
6740                    var attrs = _strEmpty;
6741                    if (FRAMEWORK.isPlainObject(classesOrAttrs)) {
6742                      for (key in classesOrAttrs)
6743                        attrs +=
6744                          (key === "c" ? "class" : key) +
6745                          '="' +
6746                          classesOrAttrs[key] +
6747                          '" ';
6748                    }
6749                    return attrs;
6750                  })()
6751              : _strEmpty) +
6752            ">" +
6753            (content || _strEmpty) +
6754            "</div>"
6755          );
6756        }
6757
6758        /**
6759         * Selects or generates a div with the given class attribute.
6760         * @param className The class names (divided by spaces) of the div which shall be selected or generated.
6761         * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement)
6762         * If its a boolean it decides whether only the children of the host element shall be selected.
6763         * @returns {*} The generated or selected element.
6764         */
6765        function selectOrGenerateDivByClass(
6766          className,
6767          selectParentOrOnlyChildren
6768        ) {
6769          var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b;
6770          var selectParent = onlyChildren
6771            ? _hostElement
6772            : selectParentOrOnlyChildren || _hostElement;
6773
6774          return _domExists && !selectParent[LEXICON.l]
6775            ? null
6776            : _domExists
6777            ? selectParent[onlyChildren ? "children" : "find"](
6778                _strDot + className.replace(/\s/g, _strDot)
6779              ).eq(0)
6780            : FRAMEWORK(generateDiv(className));
6781        }
6782
6783        /**
6784         * Gets the value of the given property from the given object.
6785         * @param obj The object from which the property value shall be got.
6786         * @param path The property of which the value shall be got.
6787         * @returns {*} Returns the value of the searched property or undefined of the property wasn't found.
6788         */
6789        function getObjectPropVal(obj, path) {
6790          var splits = path.split(_strDot);
6791          var i = 0;
6792          var val;
6793          for (; i < splits.length; i++) {
6794            if (!obj[LEXICON.hOP](splits[i])) return;
6795            val = obj[splits[i]];
6796            if (i < splits.length && type(val) == TYPES.o) obj = val;
6797          }
6798          return val;
6799        }
6800
6801        /**
6802         * Sets the value of the given property from the given object.
6803         * @param obj The object from which the property value shall be set.
6804         * @param path The property of which the value shall be set.
6805         * @param val The value of the property which shall be set.
6806         */
6807        function setObjectPropVal(obj, path, val) {
6808          var splits = path.split(_strDot);
6809          var splitsLength = splits.length;
6810          var i = 0;
6811          var extendObj = {};
6812          var extendObjRoot = extendObj;
6813          for (; i < splitsLength; i++)
6814            extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val;
6815          FRAMEWORK.extend(obj, extendObjRoot, true);
6816        }
6817
6818        /**
6819         * Runs a action for each selector inside the updateOnLoad option.
6820         * @param {Function} action The action for each updateOnLoad selector, the arguments the function takes is the index and the value (the selector).
6821         */
6822        function eachUpdateOnLoad(action) {
6823          var updateOnLoad = _currentPreparedOptions.updateOnLoad;
6824          updateOnLoad =
6825            type(updateOnLoad) == TYPES.s
6826              ? updateOnLoad.split(_strSpace)
6827              : updateOnLoad;
6828
6829          if (COMPATIBILITY.isA(updateOnLoad) && !_destroyed) {
6830            each(updateOnLoad, action);
6831          }
6832        }
6833
6834        //==== Utils Cache ====//
6835
6836        /**
6837         * Compares two values or objects and returns true if they aren't equal.
6838         * @param current The first value or object which shall be compared.
6839         * @param cache The second value or object which shall be compared.
6840         * @param force If true the returned value is always true.
6841         * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise.
6842         */
6843        function checkCache(current, cache, force) {
6844          if (force) return force;
6845          if (type(current) == TYPES.o && type(cache) == TYPES.o) {
6846            for (var prop in current) {
6847              if (prop !== "c") {
vendor: 2,815 bytes, lines 6848-6926
6848                if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) {
6849                  if (checkCache(current[prop], cache[prop])) return true;
6850                } else {
6851                  return true;
6852                }
6853              }
6854            }
6855          } else {
6856            return current !== cache;
6857          }
6858          return false;
6859        }
6860
6861        //==== Shortcuts ====//
6862
6863        /**
6864         * jQuery extend method shortcut with a appended "true" as first argument.
6865         */
6866        function extendDeep() {
6867          return FRAMEWORK.extend.apply(
6868            this,
6869            [true].concat([].slice.call(arguments))
6870          );
6871        }
6872
6873        /**
6874         * jQuery addClass method shortcut.
6875         */
6876        function addClass(el, classes) {
6877          return _frameworkProto.addClass.call(el, classes);
6878        }
6879
6880        /**
6881         * jQuery removeClass method shortcut.
6882         */
6883        function removeClass(el, classes) {
6884          return _frameworkProto.removeClass.call(el, classes);
6885        }
6886
6887        /**
6888         * Adds or removes the given classes dependent on the boolean value. True for add, false for remove.
6889         */
6890        function addRemoveClass(el, classes, doAdd) {
6891          return doAdd ? addClass(el, classes) : removeClass(el, classes);
6892        }
6893
6894        /**
6895         * jQuery remove method shortcut.
6896         */
6897        function remove(el) {
6898          return _frameworkProto.remove.call(el);
6899        }
6900
6901        /**
6902         * Finds the first child element with the given selector of the given element.
6903         * @param el The root element from which the selector shall be valid.
6904         * @param selector The selector of the searched element.
6905         * @returns {*} The first element which is a child of the given element and matches the givens selector.
6906         */
6907        function findFirst(el, selector) {
6908          return _frameworkProto.find.call(el, selector).eq(0);
6909        }
6910
6911        //==== API ====//
6912
6913        /**
6914         * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle.
6915         * This behavior can be reset by calling the update method.
6916         */
6917        _base.sleep = function () {
6918          _sleeping = true;
6919        };
6920
6921        /**
6922         * Updates the plugin and DOM to the current options.
6923         * This method should only be called if a update is 100% required.
6924         * @param force True if every property shall be updated and the cache shall be ignored.
6925         * !INTERNAL USAGE! : force can be a string "auto", "sync" or "zoom" too
6926         * if "auto" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called.
6927         * if "sync" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes.
6928         * if "zoom" then a update takes place where it's assumed that content and host size changed
6929         * @returns {boolean|undefined}
6930         * If force is "sync" then a boolean is returned which indicates whether a update was needed due to pending changes.
6931         * If force is "auto" then a boolean is returned whether a update was needed due to attribute or size changes.
6932         * undefined otherwise.
6933         */
6934        _base.update = function (force) {
6935          if (_destroyed) return;
6936
6937          var attrsChanged;
6938          var contentSizeC;
6939          var isString = type(force) == TYPES.s;
6940          var doUpdateAuto;
6941          var mutHost;
6942          var mutContent;
6943
6944          if (isString) {
6945            if (force === _strAuto) {
6946              attrsChanged = meaningfulAttrsChanged();
6947              contentSizeC = updateAutoContentSizeChanged();
6948              doUpdateAuto = attrsChanged || contentSizeC;
6949              if (doUpdateAuto) {
6950                update({
6951                  _contentSizeChanged: contentSizeC,
6952                  _changedOptions: _initialized
6953                    ? undefined
6954                    : _currentPreparedOptions,
6955                });
6956              }
6957            } else if (force === _strSync) {
6958              if (_mutationObserversConnected) {
6959                mutHost = _mutationObserverHostCallback(
6960                  _mutationObserverHost.takeRecords()
6961                );
6962                mutContent = _mutationObserverContentCallback(
6963                  _mutationObserverContent.takeRecords()
6964                );
6965              } else {
6966                mutHost = _base.update(_strAuto);
6967              }
6968            } else if (force === "zoom") {
6969              update({
6970                _hostSizeChanged: true,
6971                _contentSizeChanged: true,
6972              });
6973            }
6974          } else {
6975            force = _sleeping || force;
6976            _sleeping = false;
6977            if (!_base.update(_strSync) || force) update({ _force: force });
6978          }
6979
6980          updateElementsOnLoad();
6981
6982          return doUpdateAuto || mutHost || mutContent;
6983        };
6984
6985        /**
6986                 Gets or sets the current options. The update method will be called automatically if new options were set.
6987                 * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned.
6988                 * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads.
6989                 * @returns {*}
6990                 */
6991        _base.options = function (newOptions, value) {
6992          var option = {};
6993          var changedOps;
6994
6995          //return current options if newOptions are undefined or empty
6996          if (
6997            FRAMEWORK.isEmptyObject(newOptions) ||
6998            !FRAMEWORK.isPlainObject(newOptions)
6999          ) {
7000            if (type(newOptions) == TYPES.s) {
7001              if (arguments.length > 1) {
7002                setObjectPropVal(option, newOptions, value);
7003                changedOps = setOptions(option);
7004              } else return getObjectPropVal(_currentOptions, newOptions);
7005            } else return _currentOptions;
7006          } else {
7007            changedOps = setOptions(newOptions);
7008          }
7009
7010          if (!FRAMEWORK.isEmptyObject(changedOps)) {
7011            update({ _changedOptions: changedOps });
7012          }
7013        };
7014
7015        /**
7016         * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep.
7017         */
7018        _base.destroy = function () {
7019          if (_destroyed) return;
7020
7021          //remove this instance from auto update loop
7022          autoUpdateLoop.remove(_base);
7023
7024          //disconnect all mutation observers
7025          disconnectMutationObservers();
7026
7027          //remove all resize observers
7028          setupResizeObserver(_sizeObserverElement);
7029          setupResizeObserver(_sizeAutoObserverElement);
7030
7031          //remove all extensions
7032          for (var extName in _extensions) _base.removeExt(extName);
7033
7034          //remove all 'destroy' events
7035          while (_destroyEvents[LEXICON.l] > 0) _destroyEvents.pop()();
7036
7037          //remove all events from host element
7038          setupHostMouseTouchEvents(true);
7039
7040          //remove all helper / detection elements
7041          if (_contentGlueElement) remove(_contentGlueElement);
7042          if (_contentArrangeElement) remove(_contentArrangeElement);
7043          if (_sizeAutoObserverAdded) remove(_sizeAutoObserverElement);
7044
7045          //remove all generated DOM
7046          setupScrollbarsDOM(true);
7047          setupScrollbarCornerDOM(true);
7048          setupStructureDOM(true);
7049
7050          //remove all generated image load events
7051          for (var i = 0; i < _updateOnLoadElms[LEXICON.l]; i++)
7052            FRAMEWORK(_updateOnLoadElms[i]).off(
7053              _updateOnLoadEventName,
7054              updateOnLoadCallback
7055            );
7056          _updateOnLoadElms = undefined;
7057
7058          _destroyed = true;
7059          _sleeping = true;
7060
7061          //remove this instance from the instances list
7062          INSTANCES(pluginTargetElement, 0);
7063          dispatchCallback("onDestroyed");
7064
7065          //remove all properties and methods
7066          //for (var property in _base)
7067          //    delete _base[property];
7068          //_base = undefined;
7069        };
7070
7071        /**
7072         * Scrolls to a given position or element.
7073         * @param coordinates
7074         * 1. Can be "coordinates" which looks like:
7075         *    { x : ?, y : ? } OR          Object with x and y properties
7076         *    { left : ?, top : ? } OR     Object with left and top properties
7077         *    { l : ?, t : ? } OR          Object with l and t properties
7078         *    [ ?, ? ] OR                  Array where the first two element are the coordinates (first is x, second is y)
7079         *    ?                            A single value which stays for both axis
7080         *    A value can be a number, a string or a calculation.
7081         *
7082         *    Operators:
7083         *    [NONE]  The current scroll will be overwritten by the value.
7084         *    '+='    The value will be added to the current scroll offset
7085         *    '-='    The value will be subtracted from the current scroll offset
7086         *    '*='    The current scroll wil be multiplicated by the value.
7087         *    '/='    The current scroll wil be divided by the value.
7088         *
7089         *    Units:
7090         *    [NONE]  The value is the final scroll amount.                   final = (value * 1)
7091         *    'px'    Same as none
7092         *    '%'     The value is dependent on the current scroll value.     final = ((currentScrollValue / 100) * value)
7093         *    'vw'    The value is multiplicated by the viewport width.       final = (value * viewportWidth)
7094         *    'vh'    The value is multiplicated by the viewport height.      final = (value * viewportHe
7094ight)
7095         *
7096         *    example final values:
7097         *    200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%'
7098         *
7099         * 2. Can be a HTML or jQuery element:
7100         *    The final scroll offset is the offset (without margin) of the given HTML / jQuery element.
7101         *
7102         * 3. Can be a object with a HTML or jQuery element with additional settings:
7103         *    {
7104         *      el : [HTMLElement, jQuery element],             MUST be specified, else this object isn't valid.
7105         *      scroll : [string, array, object],               Default value is 'always'.
7106         *      block : [string, array, object],                Default value is 'begin'.
7107         *      margin : [number, boolean, array, object]       Default value is false.
7108         *    }
7109         *
7110         *    Possible scroll settings are:
7111         *    'always'      Scrolls always.
7112         *    'ifneeded'    Scrolls only if the element isnt fully in view.
7113         *    'never'       Scrolls never.
7114         *
7115         *    Possible block settings are:
7116         *    'begin'   Both axis shall be docked to the "begin" edge. - The element will be docked to the top and left edge of the viewport.
7117         *    'end'     Both axis shall be docked to the "end" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.)
7118         *    'center'  Both axis shall be docked to "center". - The element will be centered in the viewport.
7119         *    'nearest' The element will be docked to the nearest edge(s).
7120         *
7121         *    Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset.
7122         *    [BOOLEAN]                                         If true the css margin of the element will be used, if false no margin will be used.
7123         *    [NUMBER]                                          The margin will be used for all edges.
7124         *
7125         * @param duration The duration of the scroll animation, OR a jQuery animation configuration object.
7126         * @param easing The animation easing.
7127         * @param complete The animation complete callback.
7128         * @returns {{
7129         *   position: {x: number, y: number},
7130         *   ratio: {x: number, y: number},
7131         *   max: {x: number, y: number},
7132         *   handleOffset: {x: number, y: number},
7133         *   handleLength: {x: number, y: number},
7134         *   handleLengthRatio: {x: number, y: number}, t
7135         *   rackLength: {x: number, y: number},
7136         *   isRTL: boolean,
7137         *   isRTLNormalized: boolean
7138         *  }}
7139         */
7140        _base.scroll = function (coordinates, duration, easing, complete) {
7141          if (arguments.length === 0 || coordinates === undefined) {
7142            var infoX = _scrollHorizontalInfo;
7143            var infoY = _scrollVerticalInfo;
7144            var normalizeInvert =
7145              _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i;
7146            var normalizeNegate =
7147              _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n;
7148            var scrollX = infoX._currentScroll;
7149            var scrollXRatio = infoX._currentScrollRatio;
7150            var maxScrollX = infoX._maxScroll;
7151            scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio;
7152            scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX;
7153            scrollX *= normalizeNegate ? -1 : 1;
7154            maxScrollX *= normalizeNegate ? -1 : 1;
7155
7156            return {
7157              position: {
7158                x: scrollX,
7159                y: infoY._currentScroll,
7160              },
7161              ratio: {
7162                x: scrollXRatio,
7163                y: infoY._currentScrollRatio,
7164              },
7165              max: {
7166                x: maxScrollX,
7167                y: infoY._maxScroll,
7168              },
7169              handleOffset: {
7170                x: infoX._handleOffset,
7171                y: infoY._handleOffset,
7172              },
7173              handleLength: {
7174                x: infoX._handleLength,
7175                y: infoY._handleLength,
7176              },
7177              handleLengthRatio: {
7178                x: infoX._handleLengthRatio,
7179                y: infoY._handleLengthRatio,
7180              },
7181              trackLength: {
7182                x: infoX._trackLength,
7183                y: infoY._trackLength,
7184              },
7185              snappedHandleOffset: {
7186                x: infoX._snappedHandleOffset,
7187                y: infoY._snappedHandleOffset,
7188              },
7189              isRTL: _isRTL,
7190              isRTLNormalized: _normalizeRTLCache,
7191            };
7192          }
7193
7194          _base.update(_strSync);
7195
7196          var normalizeRTL = _normalizeRTLCache;
7197          var coordinatesXAxisProps = [_strX, _strLeft, "l"];
7198          var coordinatesYAxisProps = [_strY, _strTop, "t"];
7199          var coordinatesOperators = ["+=", "-=", "*=", "/="];
7200          var durationIsObject = type(duration) == TYPES.o;
7201          var completeCallback = durationIsObject
7202            ? duration.complete
7203            : complete;
7204          var i;
7205          var finalScroll = {};
7206          var specialEasing = {};
7207          var doScrollLeft;
7208          var doScrollTop;
7209          var animationOptions;
7210          var strEnd = "end";
7211          var strBegin = "begin";
7212          var strCenter = "center";
7213          var strNearest = "nearest";
7214          var strAlways = "always";
7215          var strNever = "never";
7216          var strIfNeeded = "ifneeded";
7217          var strLength = LEXICON.l;
7218          var settingsAxis;
7219          var settingsScroll;
7220          var settingsBlock;
7221          var settingsMargin;
7222          var finalElement;
7223          var elementObjSettingsAxisValues = [_strX, _strY, "xy", "yx"];
7224          var elementObjSettingsBlockValues = [
7225            strBegin,
7226            strEnd,
7227            strCenter,
7228            strNearest,
7229          ];
7230          var elementObjSettingsScrollValues = [
7231            strAlways,
7232            strNever,
7233            strIfNeeded,
7234          ];
7235          var coordinatesIsElementObj = coordinates[LEXICON.hOP]("el");
7236          var possibleElement = coordinatesIsElementObj
7237            ? coordinates.el
7238            : coordinates;
7239          var possibleElementIsJQuery =
7240            possibleElement instanceof FRAMEWORK || JQUERY
7241              ? possibleElement instanceof JQUERY
7242              : false;
7243          var possibleElementIsHTMLElement = possibleElementIsJQuery
7244            ? false
7245            : isHTMLElement(possibleElement);
7246          var updateScrollbarInfos = function () {
7247            if (doScrollLeft) refreshScrollbarHandleOffset(true);
7248            if (doScrollTop) refreshScrollbarHandleOffset(false);
7249          };
7250          var proxyCompleteCallback =
7251            type(completeCallback) != TYPES.f
7252              ? undefined
7253              : function () {
7254                  updateScrollbarInfos();
7255                  completeCallback();
7256                };
7257          function checkSettingsStringValue(currValue, allowedValues) {
7258            for (i = 0; i < allowedValues[strLength]; i++) {
7259              if (currValue === allowedValues[i]) return true;
7260            }
7261            return false;
7262          }
7263          function getRawScroll(isX, coordinates) {
7264            var coordinateProps = isX
7265              ? coordinatesXAxisProps
7266              : coordinatesYAxisProps;
7267            coordinates =
7268              type(coordinates) == TYPES.s || type(coordinates) == TYPES.n
7269                ? [coordinates, coordinates]
7270                : coordinates;
7271
7272            if (COMPATIBILITY.isA(coordinates))
7273              return isX ? coordinates[0] : coordinates[1];
7274            else if (type(coordinates) == TYPES.o) {
7275              //decides RTL normalization "hack" with .n
7276              //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL;
7277              for (i = 0; i < coordinateProps[strLength]; i++)
7278                if (coordinateProps[i] in coordinates)
7279                  return coordinates[coordinateProps[i]];
7280            }
7281          }
7282          function getFinalScroll(isX, rawScroll) {
7283            var isString = type(rawScroll) == TYPES.s;
7284            var operator;
7285            var amount;
7286            var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo;
7287            var currScroll = scrollInfo._currentScroll;
7288            var maxScroll = scrollInfo._maxScroll;
7289            var mult = " * ";
7290            var finalValue;
7291            var isRTLisX = _isRTL && isX;
7292            var normalizeShortcuts =
7293              isRTLisX && _rtlScrollBehavior.n && !normalizeRTL;
7294            var strReplace = "replace";
vendor: 9,408 bytes, lines 7295-7527
7295            var evalFunc = eval;
7296            var possibleOperator;
7297            if (isString) {
7298              //check operator
7299              if (rawScroll[strLength] > 2) {
7300                possibleOperator = rawScroll.substr(0, 2);
7301                if (inArray(possibleOperator, coordinatesOperators) > -1)
7302                  operator = possibleOperator;
7303              }
7304
7305              //calculate units and shortcuts
7306              rawScroll = operator ? rawScroll.substr(2) : rawScroll;
7307              rawScroll = rawScroll[strReplace](/min/g, 0) //'min' = 0%
7308                [strReplace](/</g, 0) //'<'   = 0%
7309                [strReplace](
7310                  /max/g,
7311                  (normalizeShortcuts ? "-" : _strEmpty) + _strHundredPercent
7312                ) //'max' = 100%
7313                [strReplace](
7314                  />/g,
7315                  (normalizeShortcuts ? "-" : _strEmpty) + _strHundredPercent
7316                ) //'>'   = 100%
7317                [strReplace](/px/g, _strEmpty)
7318                [strReplace](
7319                  /%/g,
7320                  mult +
7321                    (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1)) /
7322                      100.0
7323                )
7324                [strReplace](/vw/g, mult + _viewportSize.w)
7325                [strReplace](/vh/g, mult + _viewportSize.h);
7326              amount = parseToZeroOrNumber(
7327                isNaN(rawScroll)
7328                  ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed()
7329                  : rawScroll
7330              );
7331            } else {
7332              amount = rawScroll;
7333            }
7334
7335            if (
7336              amount !== undefined &&
7337              !isNaN(amount) &&
7338              type(amount) == TYPES.n
7339            ) {
7340              var normalizeIsRTLisX = normalizeRTL && isRTLisX;
7341              var operatorCurrScroll =
7342                currScroll *
7343                (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1);
7344              var invert = normalizeIsRTLisX && _rtlScrollBehavior.i;
7345              var negate = normalizeIsRTLisX && _rtlScrollBehavior.n;
7346              operatorCurrScroll = invert
7347                ? maxScroll - operatorCurrScroll
7348                : operatorCurrScroll;
7349              switch (operator) {
7350                case "+=":
7351                  finalValue = operatorCurrScroll + amount;
7352                  break;
7353                case "-=":
7354                  finalValue = operatorCurrScroll - amount;
7355                  break;
7356                case "*=":
7357                  finalValue = operatorCurrScroll * amount;
7358                  break;
7359                case "/=":
7360                  finalValue = operatorCurrScroll / amount;
7361                  break;
7362                default:
7363                  finalValue = amount;
7364                  break;
7365              }
7366              finalValue = invert ? maxScroll - finalValue : finalValue;
7367              finalValue *= negate ? -1 : 1;
7368              finalValue =
7369                isRTLisX && _rtlScrollBehavior.n
7370                  ? MATH.min(0, MATH.max(maxScroll, finalValue))
7371                  : MATH.max(0, MATH.min(maxScroll, finalValue));
7372            }
7373            return finalValue === currScroll ? undefined : finalValue;
7374          }
7375          function getPerAxisValue(
7376            value,
7377            valueInternalType,
7378            defaultValue,
7379            allowedValues
7380          ) {
7381            var resultDefault = [defaultValue, defaultValue];
7382            var valueType = type(value);
7383            var valueArrLength;
7384            var valueArrItem;
7385
7386            //value can be [ string, or array of two strings ]
7387            if (valueType == valueInternalType) {
7388              value = [value, value];
7389            } else if (valueType == TYPES.a) {
7390              valueArrLength = value[strLength];
7391              if (valueArrLength > 2 || valueArrLength < 1)
7392                value = resultDefault;
7393              else {
7394                if (valueArrLength === 1) value[1] = defaultValue;
7395                for (i = 0; i < valueArrLength; i++) {
7396                  valueArrItem = value[i];
7397                  if (
7398                    type(valueArrItem) != valueInternalType ||
7399                    !checkSettingsStringValue(valueArrItem, allowedValues)
7400                  ) {
7401                    value = resultDefault;
7402                    break;
7403                  }
7404                }
7405              }
7406            } else if (valueType == TYPES.o)
7407              value = [
7408                value[_strX] || defaultValue,
7409                value[_strY] || defaultValue,
7410              ];
7411            else value = resultDefault;
7412            return { x: value[0], y: value[1] };
7413          }
7414          function generateMargin(marginTopRightBottomLeftArray) {
7415            var result = [];
7416            var currValue;
7417            var currValueType;
7418            var valueDirections = [_strTop, _strRight, _strBottom, _strLeft];
7419            for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) {
7420              if (i === valueDirections[strLength]) break;
7421              currValue = marginTopRightBottomLeftArray[i];
7422              currValueType = type(currValue);
7423              if (currValueType == TYPES.b)
7424                result.push(
7425                  currValue
7426                    ? parseToZeroOrNumber(
7427                        finalElement.css(_strMarginMinus + valueDirections[i])
7428                      )
7429                    : 0
7430                );
7431              else result.push(currValueType == TYPES.n ? currValue : 0);
7432            }
7433            return result;
7434          }
7435
7436          if (possibleElementIsJQuery || possibleElementIsHTMLElement) {
7437            //get settings
7438            var margin = coordinatesIsElementObj ? coordinates.margin : 0;
7439            var axis = coordinatesIsElementObj ? coordinates.axis : 0;
7440            var scroll = coordinatesIsElementObj ? coordinates.scroll : 0;
7441            var block = coordinatesIsElementObj ? coordinates.block : 0;
7442            var marginDefault = [0, 0, 0, 0];
7443            var marginType = type(margin);
7444            var marginLength;
7445            finalElement = possibleElementIsJQuery
7446              ? possibleElement
7447              : FRAMEWORK(possibleElement);
7448
7449            if (finalElement[strLength] > 0) {
7450              //margin can be [ boolean, number, array of 2, array of 4, object ]
7451              if (marginType == TYPES.n || marginType == TYPES.b)
7452                margin = generateMargin([margin, margin, margin, margin]);
7453              else if (marginType == TYPES.a) {
7454                marginLength = margin[strLength];
7455                if (marginLength === 2)
7456                  margin = generateMargin([
7457                    margin[0],
7458                    margin[1],
7459                    margin[0],
7460                    margin[1],
7461                  ]);
7462                else if (marginLength >= 4) margin = generateMargin(margin);
7463                else margin = marginDefault;
7464              } else if (marginType == TYPES.o)
7465                margin = generateMargin([
7466                  margin[_strTop],
7467                  margin[_strRight],
7468                  margin[_strBottom],
7469                  margin[_strLeft],
7470                ]);
7471              else margin = marginDefault;
7472
7473              //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block;
7474              settingsAxis = checkSettingsStringValue(
7475                axis,
7476                elementObjSettingsAxisValues
7477              )
7478                ? axis
7479                : "xy";
7480              settingsScroll = getPerAxisValue(
7481                scroll,
7482                TYPES.s,
7483                strAlways,
7484                elementObjSettingsScrollValues
7485              );
7486              settingsBlock = getPerAxisValue(
7487                block,
7488                TYPES.s,
7489                strBegin,
7490                elementObjSettingsBlockValues
7491              );
7492              settingsMargin = margin;
7493
7494              var viewportScroll = {
7495                l: _scrollHorizontalInfo._currentScroll,
7496                t: _scrollVerticalInfo._currentScroll,
7497              };
7498              // use padding element instead of viewport element because padding element has never padding, margin or position applied.
7499              var viewportOffset = _paddingElement.offset();
7500
7501              //get coordinates
7502              var elementOffset = finalElement.offset();
7503              var doNotScroll = {
7504                x: settingsScroll.x == strNever || settingsAxis == _strY,
7505                y: settingsScroll.y == strNever || settingsAxis == _strX,
7506              };
7507              elementOffset[_strTop] -= settingsMargin[0];
7508              elementOffset[_strLeft] -= settingsMargin[3];
7509              var elementScrollCoordinates = {
7510                x: MATH.round(
7511                  elementOffset[_strLeft] -
7512                    viewportOffset[_strLeft] +
7513                    viewportScroll.l
7514                ),
7515                y: MATH.round(
7516                  elementOffset[_strTop] -
7517                    viewportOffset[_strTop] +
7518                    viewportScroll.t
7519                ),
7520              };
7521              if (_isRTL) {
7522                if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i)
7523                  elementScrollCoordinates.x = MATH.round(
7524                    viewportOffset[_strLeft] -
7525                      elementOffset[_strLeft] +
7526                      viewportScroll.l
7527                  );
7528                if (_rtlScrollBehavior.n && normalizeRTL)
7529                  elementScrollCoordinates.x *= -1;
7530                if (_rtlScrollBehavior.i && normalizeRTL)
7531                  elementScrollCoordinates.x = MATH.round(
7532                    viewportOffset[_strLeft] -
7533                      elementOffset[_strLeft] +
7534                      (_scrollHorizontalInfo._maxScroll - viewportScroll.l)
7535                  );
7536              }
7537
7538              //measuring is required
7539              if (
7540                settingsBlock.x != strBegin ||
7541                settingsBlock.y != strBegin ||
7542                settingsScroll.x == strIfNeeded ||
7543                settingsScroll.y == strIfNeeded ||
7544                _isRTL
7545              ) {
7546                var measuringElm = finalElement[0];
7547                var rawElementSize = _supportTransform
7548                  ? measuringElm[LEXICON.bCR]()
7549                  : {
7550                      width: measuringElm[LEXICON.oW],
7551                      height: measuringElm[LEXICON.oH],
7552                    };
7553                var elementSize = {
7554                  w:
7555                    rawElementSize[_strWidth] +
7556                    settingsMargin[3] +
7557                    settingsMargin[1],
7558                  h:
7559                    rawElementSize[_strHeight] +
7560                    settingsMargin[0] +
7561                    settingsMargin[2],
7562                };
7563                var finalizeBlock = function (isX) {
7564                  var vars = getScrollbarVars(isX);
7565                  var wh = vars._w_h;
7566                  var lt = vars._left_top;
7567                  var xy = vars._x_y;
7568                  var blockIsEnd =
7569                    settingsBlock[xy] ==
7570                    (isX ? (_isRTL ? strBegin : strEnd) : strEnd);
7571                  var blockIsCenter = settingsBlock[xy] == strCenter;
7572                  var blockIsNearest = settingsBlock[xy] == strNearest;
7573                  var scrollNever = settingsScroll[xy] == strNever;
7574                  var scrollIfNeeded = settingsScroll[xy] == strIfNeeded;
7575                  var vpSize = _viewportSize[wh];
7576                  var vpOffset = viewportOffset[lt];
7577                  var elSize = elementSize[wh];
7578                  var elOffset = elementOffset[lt];
7579                  var divide = blockIsCenter ? 2 : 1;
7580                  var elementCenterOffset = elOffset + elSize / 2;
7581                  var viewportCenterOffset = vpOffset + vpSize / 2;
7582                  var isInView =
7583                    elSize <= vpSize &&
7584                    elOffset >= vpOffset &&
7585                    elOffset + elSize <= vpOffset + vpSize;
7586
7587                  if (scrollNever) doNotScroll[xy] = true;
7588                  else if (!doNotScroll[xy]) {
7589                    if (blockIsNearest || scrollIfNeeded) {
7590                      doNotScroll[xy] = scrollIfNeeded ? isInView : false;
7591                      blockIsEnd =
7592                        elSize < vpSize
7593                          ? elementCenterOffset > viewportCenterOffset
7594                          : elementCenterOffset < viewportCenterOffset;
7595                    }
7596                    elementScrollCoordinates[xy] -=
7597                      blockIsEnd || blockIsCenter
7598                        ? (vpSize / divide - elSize / divide) *
7599                          (isX && _isRTL && normalizeRTL ? -1 : 1)
7600                        : 0;
7601                  }
7602                };
7603                finalizeBlock(true);
7604                finalizeBlock(false);
7605              }
7606
7607              if (doNotScroll.y) delete elementScrollCoordinates.y;
7608              if (doNotScroll.x) delete elementScrollCoordinates.x;
7609
7610              coordinates = elementScrollCoordinates;
7611            }
7612          }
7613
7614          finalScroll[_strScrollLeft] = getFinalScroll(
7615            true,
7616            getRawScroll(true, coordinates)
7617          );
7618          finalScroll[_strScrollTop] = getFinalScroll(
7619            false,
7620            getRawScroll(false, coordinates)
7621          );
7622          doScrollLeft = finalScroll[_strScrollLeft] !== undefined;
7623          doScrollTop = finalScroll[_strScrollTop] !== undefined;
7624
7625          if (
7626            (doScrollLeft || doScrollTop) &&
7627            (duration > 0 || durationIsObject)
7628          ) {
7629            if (durationIsObject) {
7630              duration.complete = proxyCompleteCallback;
7631              _viewportElement.animate(finalScroll, duration);
7632            } else {
7633              animationOptions = {
7634                duration: duration,
7635                complete: proxyCompleteCallback,
7636              };
7637              if (
7638                COMPATIBILITY.isA(easing) ||
7639                FRAMEWORK.isPlainObject(easing)
7640              ) {
7641                specialEasing[_strScrollLeft] = easing[0] || easing.x;
7642                specialEasing[_strScrollTop] = easing[1] || easing.y;
7643                animationOptions.specialEasing = specialEasing;
7644              } else {
7645                animationOptions.easing = easing;
7646              }
7647              _viewportElement.animate(finalScroll, animationOptions);
7648            }
7649          } else {
7650            if (doScrollLeft)
7651              _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]);
7652            if (doScrollTop)
7653              _viewportElement[_strScrollTop](finalScroll[_strScrollTop]);
7654            updateScrollbarInfos();
7655          }
7656        };
7657
7658        /**
7659         * Stops all scroll animations.
7660         * @returns {*} The current OverlayScrollbars instance (for chaining).
7661         */
7662        _base.scrollStop = function (param1, param2, param3) {
7663          _viewportElement.stop(param1, param2, param3);
7664          return _base;
7665        };
7666
7667        /**
7668         * Returns all relevant elements.
7669         * @param elementName The name of the element which shall be returned.
7670         * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *}
7671         */
7672        _base.getElements = function (elementName) {
7673          var obj = {
7674            target: _targetElementNative,
7675            host: _hostElementNative,
7676            padding: _paddingElementNative,
7677            viewport: _viewportElementNative,
7678            content: _contentElementNative,
7679            scrollbarHorizontal: {
7680              scrollbar: _scrollbarHorizontalElement[0],
7681              track: _scrollbarHorizontalTrackElement[0],
7682              handle: _scrollbarHorizontalHandleElement[0],
7683            },
7684            scrollbarVertical: {
7685              scrollbar: _scrollbarVerticalElement[0],
7686              track: _scrollbarVerticalTrackElement[0],
7687              handle: _scrollbarVerticalHandleElement[0],
7688            },
7689            scrollbarCorner: _scrollbarCornerElement[0],
7690          };
7691          return type(elementName) == TYPES.s
7692            ? getObjectPropVal(obj, elementName)
7693            : obj;
7694        };
7695
7696        /**
7697         * Returns a object which describes the current state of this instance.
7698         * @param stateProperty A specific property from the state object which shall be returned.
7699         * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *}
7700         */
7701        _base.getState = function (stateProperty) {
7702          function prepare(obj) {
7703            if (!FRAMEWORK.isPlainObject(obj)) return obj;
7704            var extended = extendDeep({}, obj);
7705            var changePropertyName = function (from, to) {
7706              if (extended[LEXICON.hOP](from)) {
7707                extended[to] = extended[from];
7708                delete extended[from];
7709              }
7710            };
7711            changePropertyName("w", _strWidth); //change w to width
7712            changePropertyName("h", _strHeight); //change h to height
7713            delete extended.c; //delete c (the 'changed' prop)
7714            return extended;
7715          }
7716          var obj = {
7717            destroyed: !!prepare(_destroyed),
7718            sleeping: !!prepare(_sleeping),
7719            autoUpdate: prepare(!_mutationObserversConnected),
7720            widthAuto: prepare(_widthAutoCache),
7721            heightAuto: prepare(_heightAutoCache),
7722            padding: prepare(_cssPaddingCache),
7723            overflowAmount: prepare(_overflowAmountCache),
7724            hideOverflow: prepare(_hideOverflowCache),
7725            hasOverflow: prepare(_hasOverflowCache),
7726            contentScrollSize: prepare(_contentScrollSizeCache),
7727            viewportSize: prepare(_viewportSize),
7728            hostSize: prepare(_hostSizeCache),
7729            documentMixed: prepare(_documentMixed),
7730          };
7731          return type(stateProperty) == TYPES.s
7732            ? getObjectPropVal(obj, stateProperty)
7733            : obj;
7734        };
7735
7736        /**
7737         * Gets all or specific extension instance.
7738         * @param extName The name of the extension from which the instance shall be got.
7739         * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found.
7740         */
7741        _base.ext = function (extName) {
7742          var result;
7743          var privateMethods = _extensionsPrivateMethods.split(" ");
7744          var i = 0;
7745          if (type(extName) == TYPES.s) {
7746            if (_extensions[LEXICON.hOP](extName)) {
7747              result = extendDeep({}, _extensions[extName]);
7748              for (; i < privateMethods.length; i++)
7749                delete result[privateMethods[i]];
7750            }
7751          } else {
7752            result = {};
7753            for (i in _extensions) result[i] = extendDeep({}, _base.ext(i));
7754          }
7755          return result;
7756        };
7757
7758        /**
7759         * Adds a extension to this instance.
7760         * @param extName The name of the extension which shall be added.
7761         * @param extensionOptions The extension options which shall be used.
7762         * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly.
7763         */
7764        _base.addExt = function (extName, extensionOptions) {
7765          var registeredExtensionObj = _plugin.extension(extName);
7766          var instance;
7767          var instanceAdded;
7768          var instanceContract;
7769          var contractResult;
7770          var contractFulfilled = true;
7771          if (registeredExtensionObj) {
7772            if (!_extensions[LEXICON.hOP](extName)) {
7773              instance = registeredExtensionObj.extensionFactory.call(
7774                _base,
7775                extendDeep({}, registeredExtensionObj.defaultOptions),
7776                FRAMEWORK,
7777                COMPATIBILITY
7778              );
7779
7780              if (instance) {
7781                instanceContract = instance.contract;
7782                if (type(instanceContract) == TYPES.f) {
7783                  contractResult = instanceContract(window);
7784                  contractFulfilled =
7785                    type(contractResult) == TYPES.b
7786                      ? contractResult
7787                      : contractFulfilled;
7788                }
7789                if (contractFulfilled) {
7790                  _extensions[extName] = instance;
7791                  instanceAdded = instance.added;
7792                  if (type(instanceAdded) == TYPES.f)
7793                    instanceAdded(extensionOptions);
7794
7795                  return _base.ext(extName);
7796                }
7797              }
7798            } else return _base.ext(extName);
7799          } else
7800            console.warn(
7801              'A extension with the name "' + extName + "\" isn't registered."
7802            );
7803        };
7804
7805        /**
7806         * Removes a extension from this instance.
7807         * @param extName The name of the extension which shall be removed.
7808         * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before.
7809         */
7810        _base.removeExt = function (extName) {
7811          var instance = _extensions[extName];
7812          var instanceRemoved;
7813          if (instance) {
7814            delete _extensions[extName];
7815
7816            instanceRemoved = instance.removed;
7817            if (type(instanceRemoved) == TYPES.f) instanceRemoved();
7818
7819            return true;
7820          }
7821          return false;
7822        };
7823
7824        /**
7825         * Constructs the plugin.
7826         * @param targetElement The element to which the plugin shall be applied.
7827         * @param options The initial options of the plugin.
7828         * @param extensions The extension(s) which shall be added right after the initialization.
7829         * @returns {boolean} True if the plugin was successfully initialized, false otherwise.
7830         */
7831        function construct(targetElement, options, extensions) {
7832          _defaultOptions = globals.defaultOptions;
7833          _nativeScrollbarStyling = globals.nativeScrollbarStyling;
7834          _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize);
7835          _nativeScrollbarIsOverlaid = extendDeep(
7836            {},
7837            globals.nativeScrollbarIsOverlaid
7838          );
7839          _overlayScrollbarDummySize = extendDeep(
7840            {},
7841            globals.overlayScrollbarDummySize
7842          );
7843          _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior);
7844
7845          //parse & set options but don't update
7846          setOptions(extendDeep({}, _defaultOptions, options));
7847
7848          _cssCalc = globals.cssCalc;
7849          _msieVersion = globals.msie;
7850          _autoUpdateRecommended = globals.autoUpdateRecommended;
7851          _supportTransition = globals.supportTransition;
7852          _supportTransform = globals.supportTransform;
7853          _supportPassiveEvents = globals.supportPassiveEvents;
7854          _supportResizeObserver = globals.supportResizeObserver;
7855          _supportMutationObserver = globals.supportMutationObserver;
7856          _restrictedMeasuring = globals.restrictedMeasuring;
7857          _documentElement = FRAMEWORK(targetElement.ownerDocument);
7858          _documentElementNative = _documentElement[0];
7859          _windowElement = FRAMEWORK(
7860            _documentElementNative.defaultView ||
7861              _documentElementNative.parentWindow
7862          );
7863          _windowElementNative = _windowElement[0];
7864          _htmlElement = findFirst(_documentElement, "html");
7865          _bodyElement = findFirst(_htmlElement, "body");
7866          _targetElement = FRAMEWORK(targetElement);
7867          _targetElementNative = _targetElement[0];
7868          _isTextarea = _targetElement.is("textarea");
7869          _isBody = _targetElement.is("body");
7870          _documentMixed = _documentElementNative !== document;
7871
7872          /* On a div Element The if checks only whether:
7873           * - the targetElement has the class "os-host"
7874           * - the targetElement has a a child with the class "os-padding"
7875           *
7876           * If that's the case, its assumed the DOM has already the following structure:
7877           * (The ".os-host" element is the targetElement)
7878           *
7879           *  <div class="os-host">
7880           *      <div class="os-resize-observer-host"></div>
7881           *      <div class="os-padding">
7882           *          <div class="os-viewport">
7883           *              <div class="os-content"></div>
7884           *          </div>
7885           *      </div>
7886           *      <div class="os-scrollbar os-scrollbar-horizontal ">
7887           *          <div class="os-scrollbar-track">
7888           *              <div class="os-scrollbar-handle"></div>
7889           *          </div>
7890           *      </div>
7891           *      <div class="os-scrollbar os-scrollbar-vertical">
7892           *          <div class="os-scrollbar-track">
7893           *              <div class="os-scrollbar-handle"></div>
7894           *          </div>
7895           *      </div>
7896           *      <div class="os-scrollbar-corner"></div>
7897           *  </div>
7898           *
7899           * =====================================================================================
7900           *
7901           * On a Textarea Element The if checks only whether:
7902           * - the targetElement has the class "os-textarea"
7903           * - the targetElement is inside a element with the class "os-content"
7904           *
7905           * If that's the case, its assumed the DOM has already the following structure:
7906           * (The ".os-textarea" (textarea) element is the targetElement)
7907           *
7908           *  <div class="os-host-textarea">
7909           *      <div class="os-resize-observer-host"></div>
7910           *      <div class="os-padding os-text-inherit">
7911           *          <div class="os-viewport os-text-inherit">
7912           *              <div class="os-content os-text-inherit">
7913           *                  <div class="os-textarea-cover"></div>
7914           *                  <textarea class="os-textarea os-text-inherit"></textarea>
7915           *              </div>
7916           *          </div>
7917           *      </div>
7918           *      <div class="os-scrollbar os-scrollbar-horizontal ">
7919           *          <div class="os-scrollbar-track">
7920           *              <div class="os-scrollbar-handle"></div>
7921           *          </div>
7922           *      </div>
7923           *      <div class="os-scrollbar os-scrollbar-vertical">
7924           *          <div class="os-scrollbar-track">
7925           *              <div class="os-scrollbar-handle"></div>
7926           *          </div>
7927           *      </div>
7928           *      <div class="os-scrollbar-corner"></div>
7929           *  </div>
7930           */
7931          _domExists = _isTextarea
7932            ? _targetElement.hasClass(_classNameTextareaElement) &&
7933              _targetElement.parent().hasClass(_classNameContentElement)
7934            : _targetElement.hasClass(_classNameHostElement) &&
7935              _targetElement.children(_strDot + _classNamePaddingElement)[
7936                LEXICON.l
7937              ];
7938
7939          var initBodyScroll;
7940          var bodyMouseTouchDownListener;
7941
7942          //check if the plugin hasn't to be initialized
7943          if (
7944            _nativeScrollbarIsOverlaid.x &&
7945            _nativeScrollbarIsOverlaid.y &&
7946            !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize
7947          ) {
7948            _initialized = true; // workaround so the onInitializationWithdrawn callback below is fired
7949            dispatchCallback("onInitializationWithdrawn");
7950            if (_domExists) {
7951              setupStructureDOM(true);
7952              setupScrollbarsDOM(true);
7953              setupScrollbarCornerDOM(true);
7954            }
7955
7956            _initialized = false;
7957            _destroyed = true;
7958            _sleeping = true;
7959
7960            return _base;
7961          }
7962
7963          if (_isBody) {
7964            initBodyScroll = {};
7965            initBodyScroll.l = MATH.max(
7966              _targetElement[_strScrollLeft](),
7967              _htmlElement[_strScrollLeft](),
7968              _windowElement[_strScrollLeft]()
7969            );
7970            initBodyScroll.t = MATH.max(
7971              _targetElement[_strScrollTop](),
7972              _htmlElement[_strScrollTop](),
7973              _windowElement[_strScrollTop]()
7974            );
7975
7976            bodyMouseTouchDownListener = function () {
7977              _viewportElement.removeAttr(LEXICON.ti);
7978              setupResponsiveEventListener(
7979                _viewportElement,
7980                _strMouseTouchDownEvent,
7981                bodyMouseTouchDownListener,
7982                true,
7983                true
7984              );
7985            };
7986          }
7987
7988          //build OverlayScrollbars DOM
7989          setupStructureDOM();
7990          setupScrollbarsDOM();
7991          setupScrollbarCornerDOM();
7992
7993          //create OverlayScrollbars events
7994          setupStructureEvents();
7995          setupScrollbarEvents(true);
7996          setupScrollbarEvents(false);
7997          setupScrollbarCornerEvents();
7998
7999          //create mutation observers
8000          createMutationObservers();
8001
8002          //build resize observer for the host element
8003          setupResizeObserver(_sizeObserverElement, hostOnResized);
8004
8005          if (_isBody) {
8006            //apply the body scroll to handle it right in the update method
8007            _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](
8008              initBodyScroll.t
8009            );
8010
8011            //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling
8012            if (
8013              document.activeElement == targetElement &&
8014              _viewportElementNative.focus
8015            ) {
8016              //set a tabindex to make the viewportElement focusable
8017              _viewportElement.attr(LEXICON.ti, "-1");
8018              _viewportElementNative.focus();
8019
8020              /* the tabindex has to be removed due to;
8021               * If you set the tabindex attribute on an <div>, then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too
8022               * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
8023               */
8024              setupResponsiveEventListener(
8025                _viewportElement,
8026                _strMouseTouchDownEvent,
8027                bodyMouseTouchDownListener,
8028                false,
8029                true
8030              );
8031            }
8032          }
8033
8034          //update for the first time & initialize cache
8035          _base.update(_strAuto);
8036
8037          //the plugin is initialized now!
8038          _initialized = true;
8039          dispatchCallback("onInitialized");
8040
8041          //call all callbacks which would fire before the initialized was complete
8042          each(_callbacksInitQeueue, function (index, value) {
8043            dispatchCallback(value.n, value.a);
8044          });
8045          _callbacksInitQeueue = [];
8046
8047          //add extensions
8048          if (type(extensions) == TYPES.s) extensions = [extensions];
8049          if (COMPATIBILITY.isA(extensions))
8050            each(extensions, function (index, value) {
8051              _base.addExt(value);
8052            });
8053          else if (FRAMEWORK.isPlainObject(extensions))
8054            each(extensions, function (key, value) {
8055              _base.addExt(key, value);
8056            });
8057
8058          //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions)
8059          setTimeout(function () {
8060            if (_supportTransition && !_destroyed)
8061              addClass(_hostElement, _classNameHostTransition);
8062          }, 333);
8063
8064          return _base;
8065        }
8066
8067        if (
8068          _plugin.valid(construct(pluginTargetElement, options, extensions))
8069        ) {
8070          INSTANCES(pluginTargetElement, _base);
8071        }
8072
8073        return _base;
8074      }
8075
8076      /**
8077       * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance.
8078       * @param pluginTargetElements The elements to which the Plugin shall be initialized.
8079       * @param options The custom options with which the plugin shall be initialized.
8080       * @param extensions The extension(s) which shall be added right after initialization.
8081       * @returns {*}
8082       */
8083      _plugin = window[PLUGINNAME] = function (
8084        pluginTargetElements,
8085        options,
8086        extensions
8087      ) {
8088        if (arguments[LEXICON.l] === 0) return this;
8089
8090        var arr = [];
8091        var optsIsPlainObj = FRAMEWORK.isPlainObject(options);
8092        var inst;
8093        var result;
8094
8095        //pluginTargetElements is null or undefined
8096        if (!pluginTargetElements)
8097          return optsIsPlainObj || !options ? result : arr;
8098
8099        /*
8100                   pluginTargetElements will be converted to:
8101                   1. A jQueryElement Array
8102                   2. A HTMLElement Array
8103                   3. A Array with a single HTML Element
8104                   so pluginTargetElements is always a array.
8105                */
8106        pluginTargetElements =
8107          pluginTargetElements[LEXICON.l] != undefined
8108            ? pluginTargetElements
8109            : [pluginTargetElements[0] || pluginTargetElements];
8110        initOverlayScrollbarsStatics();
8111
8112        if (pluginTargetElements[LEXICON.l] > 0) {
8113          if (optsIsPlainObj) {
8114            FRAMEWORK.each(pluginTargetElements, function (i, v) {
8115              inst = v;
8116              if (inst !== undefined)
8117                arr.push(
8118                  OverlayScrollbarsInstance(
8119                    inst,
8120                    options,
8121                    extensions,
8122                    _pluginsGlobals,
8123                    _pluginsAutoUpdateLoop
8124                  )
8125                );
8126            });
8127          } else {
8128            FRAMEWORK.each(pluginTargetElements, function (i, v) {
8129              inst = INSTANCES(v);
8130              if (
8131                (options === "!" && _plugin.valid(inst)) ||
8132                (COMPATIBILITY.type(options) == TYPES.f && options(v, inst))
8133              )
8134                arr.push(inst);
8135              else if (options === undefined) arr.push(inst);
8136            });
8137          }
8138          result = arr[LEXICON.l] === 1 ? arr[0] : arr;
8139        }
8140        return result;
8141      };
8142
8143      /**
8144       * Returns a object which contains global information about the plugin and each instance of it.
8145       * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object.
8146       */
8147      _plugin.globals = function () {
8148        initOverlayScrollbarsStatics();
8149        var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals);
8150        delete globals["msie"];
8151        return globals;
8152      };
8153
8154      /**
8155       * Gets or Sets the default options for each new plugin initialization.
8156       * @param newDefaultOptions The object with which the default options shall be extended.
8157       */
8158      _plugin.defaultOptions = function (newDefaultOptions) {
8159        initOverlayScrollbarsStatics();
8160        var currDefaultOptions = _pluginsGlobals.defaultOptions;
8161        if (newDefaultOptions === undefined)
8162          return FRAMEWORK.extend(true, {}, currDefaultOptions);
8163
8164        //set the new default options
8165        _pluginsGlobals.defaultOptions = FRAMEWORK.extend(
8166          true,
8167          {},
8168          currDefaultOptions,
8169          _pluginsOptions._validate(
8170            newDefaultOptions,
8171            _pluginsOptions._template,
8172            true,
8173            currDefaultOptions
8174          )._default
8175        );
8176      };
8177
8178      /**
8179       * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance.
8180       * @param osInstance The potential OverlayScrollbars instance which shall be checked.
8181       * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise.
8182       */
8183      _plugin.valid = function (osInstance) {
8184        return (
8185          osInstance instanceof _plugin && !osInstance.getState().destroyed
8186        );
8187      };
8188
8189      /**
8190       * Registers, Unregisters or returns a extension.
8191       * Register: Pass the name and the extension. (defaultOptions is optional)
8192       * Unregister: Pass the name and anything except a function as extension parameter.
8193       * Get extension: Pass the name of the extension which shall be got.
8194       * Get all extensions: Pass no arguments.
8195       * @param extensionName The name of the extension which shall be registered, unregistered or returned.
8196       * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension.
8197       * @param defaultOptions The default options which shall be used for the registered extension.
8198       */
8199      _plugin.extension = function (extensionName, extension, defaultOptions) {
8200        var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s;
8201        var argLen = arguments[LEXICON.l];
8202        var i = 0;
8203        if (argLen < 1 || !extNameTypeString) {
8204          //return a copy of all extension objects
8205          return FRAMEWORK.extend(
8206            true,
8207            { length: _pluginsExtensions[LEXICON.l] },
8208            _pluginsExtensions
8209          );
8210        } else if (extNameTypeString) {
8211          if (COMPATIBILITY.type(extension) == TYPES.f) {
8212            //register extension
8213            _pluginsExtensions.push({
8214              name: extensionName,
8215              extensionFactory: extension,
8216              defaultOptions: defaultOptions,
8217            });
8218          } else {
8219            for (; i < _pluginsExtensions[LEXICON.l]; i++) {
8220              if (_pluginsExtensions[i].name === extensionName) {
8221                if (argLen > 1)
8222                  _pluginsExtensions.splice(i, 1); //remove extension
8223                else return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name
8224              }
8225            }
8226          }
8227        }
8228      };
8229
8230      return _plugin;
8231    })();
8232
8233    if (JQUERY && JQUERY.fn) {
8234      /**
8235       * The jQuery initialization interface.
8236       * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized.
8237       * @param extensions The extension(s) which shall be added right after initialization.
8238       * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected.
8239       */
8240      JQUERY.fn.overlayScrollbars = function (options, extensions) {
8241        var _elements = this;
8242        if (JQUERY.isPlainObject(options)) {
8243          JQUERY.each(_elements, function () {
8244            PLUGIN(this, options, extensions);
8245          });
8246          return _elements;
8247        } else return PLUGIN(_elements, options);
8248      };
8249    }
8250    return PLUGIN;
8251  }
8252);

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.