PageSourceSearch

https://www.adpushup.com/wp-content/themes/thesaasx/js/nouislider.js?ver=7.0.4

js adpushup.com collected 2026-09-24 07:51:07 UTC 106,364 bytes, 2,341 lines download raw bytes

vendor: 106,364 bytes, lines 1-2341
1(function (global, factory) {
2    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3    typeof define === 'function' && define.amd ? define(['exports'], factory) :
4    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.noUiSlider = {}));
5})(this, (function (exports) { 'use strict';
6
7    exports.PipsMode = void 0;
8    (function (PipsMode) {
9        PipsMode["Range"] = "range";
10        PipsMode["Steps"] = "steps";
11        PipsMode["Positions"] = "positions";
12        PipsMode["Count"] = "count";
13        PipsMode["Values"] = "values";
14    })(exports.PipsMode || (exports.PipsMode = {}));
15    exports.PipsType = void 0;
16    (function (PipsType) {
17        PipsType[PipsType["None"] = -1] = "None";
18        PipsType[PipsType["NoValue"] = 0] = "NoValue";
19        PipsType[PipsType["LargeValue"] = 1] = "LargeValue";
20        PipsType[PipsType["SmallValue"] = 2] = "SmallValue";
21    })(exports.PipsType || (exports.PipsType = {}));
22    //region Helper Methods
23    function isValidFormatter(entry) {
24        return isValidPartialFormatter(entry) && typeof entry.from === "function";
25    }
26    function isValidPartialFormatter(entry) {
27        // partial formatters only need a to function and not a from function
28        return typeof entry === "object" && typeof entry.to === "function";
29    }
30    function removeElement(el) {
31        el.parentElement.removeChild(el);
32    }
33    function isSet(value) {
34        return value !== null && value !== undefined;
35    }
36    // Bindable version
37    function preventDefault(e) {
38        e.preventDefault();
39    }
40    // Removes duplicates from an array.
41    function unique(array) {
42        return array.filter(function (a) {
43            return !this[a] ? (this[a] = true) : false;
44        }, {});
45    }
46    // Round a value to the closest 'to'.
47    function closest(value, to) {
48        return Math.round(value / to) * to;
49    }
50    // Current position of an element relative to the document.
51    function offset(elem, orientation) {
52        var rect = elem.getBoundingClientRect();
53        var doc = elem.ownerDocument;
54        var docElem = doc.documentElement;
55        var pageOffset = getPageOffset(doc);
56        // getBoundingClientRect contains left scroll in Chrome on Android.
57        // I haven't found a feature detection that proves this. Worst case
58        // scenario on mis-match: the 'tap' feature on horizontal sliders breaks.
59        if (/webkit.*Chrome.*Mobile/i.test(navigator.userAgent)) {
60            pageOffset.x = 0;
61        }
62        return orientation ? rect.top + pageOffset.y - docElem.clientTop : rect.left + pageOffset.x - docElem.clientLeft;
63    }
64    // Checks whether a value is numerical.
65    function isNumeric(a) {
66        return typeof a === "number" && !isNaN(a) && isFinite(a);
67    }
68    // Sets a class and removes it after [duration] ms.
69    function addClassFor(element, className, duration) {
70        if (duration > 0) {
71            addClass(element, className);
72            setTimeout(function () {
73                removeClass(element, className);
74            }, duration);
75        }
76    }
77    // Limits a value to 0 - 100
78    function limit(a) {
79        return Math.max(Math.min(a, 100), 0);
80    }
81    // Wraps a variable as an array, if it isn't one yet.
82    // Note that an input array is returned by reference!
83    function asArray(a) {
84        return Array.isArray(a) ? a : [a];
85    }
86    // Counts decimals
87    function countDecimals(numStr) {
88        numStr = String(numStr);
89        var pieces = numStr.split(".");
90        return pieces.length > 1 ? pieces[1].length : 0;
91    }
92    // http://youmightnotneedjquery.com/#add_class
93    function addClass(el, className) {
94        if (el.classList && !/\s/.test(className)) {
95            el.classList.add(className);
96        }
97        else {
98            el.className += " " + className;
99        }
100    }
101    // http://youmightnotneedjquery.com/#remove_class
102    function removeClass(el, className) {
103        if (el.classList && !/\s/.test(className)) {
104            el.classList.remove(className);
105        }
106        else {
107            el.className = el.className.replace(new RegExp("(^|\\b)" + className.split(" ").join("|") + "(\\b|$)", "gi"), " ");
108        }
109    }
110    // https://plainjs.com/javascript/attributes/adding-removing-and-testing-for-classes-9/
111    function hasClass(el, className) {
112        return el.classList ? el.classList.contains(className) : new RegExp("\\b" + className + "\\b").test(el.className);
113    }
114    // https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY#Notes
115    function getPageOffset(doc) {
116        var supportPageOffset = window.pageXOffset !== undefined;
117        var isCSS1Compat = (doc.compatMode || "") === "CSS1Compat";
118        var x = supportPageOffset
119            ? window.pageXOffset
120            : isCSS1Compat
121                ? doc.documentElement.scrollLeft
122                : doc.body.scrollLeft;
123        var y = supportPageOffset
124            ? window.pageYOffset
125            : isCSS1Compat
126                ? doc.documentElement.scrollTop
127                : doc.body.scrollTop;
128        return {
129            x: x,
130            y: y,
131        };
132    }
133    // we provide a function to compute constants instead
134    // of accessing window.* as soon as the module needs it
135    // so that we do not compute anything if not needed
136    function getActions() {
137        // Determine the events to bind. IE11 implements pointerEvents without
138        // a prefix, which breaks compatibility with the IE10 implementation.
139        return window.navigator.pointerEnabled
140            ? {
141                start: "pointerdown",
142                move: "pointermove",
143                end: "pointerup",
144            }
145            : window.navigator.msPointerEnabled
146                ? {
147                    start: "MSPointerDown",
148                    move: "MSPointerMove",
149                    end: "MSPointerUp",
150                }
151                : {
152                    start: "mousedown touchstart",
153                    move: "mousemove touchmove",
154                    end: "mouseup touchend",
155                };
156    }
157    // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
158    // Issue #785
159    function getSupportsPassive() {
160        var supportsPassive = false;
161        /* eslint-disable */
162        try {
163            var opts = Object.defineProperty({}, "passive", {
164                get: function () {
165                    supportsPassive = true;
166                },
167            });
168            // @ts-ignore
169            window.addEventListener("test", null, opts);
170        }
171        catch (e) { }
172        /* eslint-enable */
173        return supportsPassive;
174    }
175    function getSupportsTouchActionNone() {
176        return window.CSS && CSS.supports && CSS.supports("touch-action", "none");
177    }
178    //endregion
179    //region Range Calculation
180    // Determine the size of a sub-range in relation to a full range.
181    function subRangeRatio(pa, pb) {
182        return 100 / (pb - pa);
183    }
184    // (percentage) How many percent is this value of this range?
185    function fromPercentage(range, value, startRange) {
186        return (value * 100) / (range[startRange + 1] - range[startRange]);
187    }
188    // (percentage) Where is this value on this range?
189    function toPercentage(range, value) {
190        return fromPercentage(range, range[0] < 0 ? value + Math.abs(range[0]) : value - range[0], 0);
191    }
192    // (value) How much is this percentage on this range?
193    function isPercentage(range, value) {
194        return (value * (range[1] - range[0])) / 100 + range[0];
195    }
196    function getJ(value, arr) {
197        var j = 1;
198        while (value >= arr[j]) {
199            j += 1;
200        }
201        return j;
202    }
203    // (percentage) Input a value, find where, on a scale of 0-100, it applies.
204    function toStepping(xVal, xPct, value) {
205        if (value >= xVal.slice(-1)[0]) {
206            return 100;
207        }
208        var j = getJ(value, xVal);
209        var va = xVal[j - 1];
210        var vb = xVal[j];
211        var pa = xPct[j - 1];
212        var pb = xPct[j];
213        return pa + toPercentage([va, vb], value) / subRangeRatio(pa, pb);
214    }
215    // (value) Input a percentage, find where it is on the specified range.
216    function fromStepping(xVal, xPct, value) {
217        // There is no range group that fits 100
218        if (value >= 100) {
219            return xVal.slice(-1)[0];
220        }
221        var j = getJ(value, xPct);
222        var va = xVal[j - 1];
223        var vb = xVal[j];
224        var pa = xPct[j - 1];
225        var pb = xPct[j];
226        return isPercentage([va, vb], (value - pa) * subRangeRatio(pa, pb));
227    }
228    // (percentage) Get the step that applies at a certain value.
229    function getStep(xPct, xSteps, snap, value) {
230        if (value === 100) {
231            return value;
232        }
233        var j = getJ(value, xPct);
234        var a = xPct[j - 1];
235        var b = xPct[j];
236        // If 'snap' is set, steps are used as fixed points on the slider.
237        if (snap) {
238            // Find the closest position, a or b.
239            if (value - a > (b - a) / 2) {
240                return b;
241            }
242            return a;
243        }
244        if (!xSteps[j - 1]) {
245            return value;
246        }
247        return xPct[j - 1] + closest(value - xPct[j - 1], xSteps[j - 1]);
248    }
249    //endregion
250    //region Spectrum
251    var Spectrum = /** @class */ (function () {
252        function Spectrum(entry, snap, singleStep) {
253            this.xPct = [];
254            this.xVal = [];
255            this.xSteps = [];
256            this.xNumSteps = [];
257            this.xHighestCompleteStep = [];
258            this.xSteps = [singleStep || false];
259            this.xNumSteps = [false];
260            this.snap = snap;
261            var index;
262            var ordered = [];
263            // Map the object keys to an array.
264            Object.keys(entry).forEach(function (index) {
265                ordered.push([asArray(entry[index]), index]);
266            });
267            // Sort all entries by value (numeric sort).
268            ordered.sort(function (a, b) {
269                return a[0][0] - b[0][0];
270            });
271            // Convert all entries to subranges.
272            for (index = 0; index < ordered.length; index++) {
273                this.handleEntryPoint(ordered[index][1], ordered[index][0]);
274            }
275            // Store the actual step values.
276            // xSteps is sorted in the same order as xPct and xVal.
277            this.xNumSteps = this.xSteps.slice(0);
278            // Convert all numeric steps to the percentage of the subrange they represent.
279            for (index = 0; index < this.xNumSteps.length; index++) {
280                this.handleStepPoint(index, this.xNumSteps[index]);
281            }
282        }
283        Spectrum.prototype.getDistance = function (value) {
284            var distances = [];
285            for (var index = 0; index < this.xNumSteps.length - 1; index++) {
286                distances[index] = fromPercentage(this.xVal, value, index);
287            }
288            return distances;
289        };
290        // Calculate the percentual distance over the whole scale of ranges.
291        // direction: 0 = backwards / 1 = forwards
292        Spectrum.prototype.getAbsoluteDistance = function (value, distances, direction) {
293            var xPct_index = 0;
294            // Calculate range where to start calculation
295            if (value < this.xPct[this.xPct.length - 1]) {
296                while (value > this.xPct[xPct_index + 1]) {
297                    xPct_index++;
298                }
299            }
300            else if (value === this.xPct[this.xPct.length - 1]) {
301                xPct_index = this.xPct.length - 2;
302            }
303            // If looking backwards and the value is exactly at a range separator then look one range further
304            if (!direction && value === this.xPct[xPct_index + 1]) {
305                xPct_index++;
306            }
307            if (distances === null) {
308                distances = [];
309            }
310            var start_factor;
311            var rest_factor = 1;
312            var rest_rel_distance = distances[xPct_index];
313            var range_pct = 0;
314            var rel_range_distance = 0;
315            var abs_distance_counter = 0;
316            var range_counter = 0;
317            // Calculate what part of the start range the value is
318            if (direction) {
319                start_factor = (value - this.xPct[xPct_index]) / (this.xPct[xPct_index + 1] - this.xPct[xPct_index]);
320            }
321            else {
322                start_factor = (this.xPct[xPct_index + 1] - value) / (this.xPct[xPct_index + 1] - this.xPct[xPct_index]);
323            }
324            // Do until the complete distance across ranges is calculated
325            while (rest_rel_distance > 0) {
326                // Calculate the percentage of total range
327                range_pct = this.xPct[xPct_index + 1 + range_counter] - this.xPct[xPct_index + range_counter];
328                // Detect if the margin, padding or limit is larger then the current range and calculate
329                if (distances[xPct_index + range_counter] * rest_factor + 100 - start_factor * 100 > 100) {
330                    // If larger then take the percentual distance of the whole range
331                    rel_range_distance = range_pct * start_factor;
332                    // Rest factor of relative percentual distance still to be calculated
333                    rest_factor = (rest_rel_distance - 100 * start_factor) / distances[xPct_index + range_counter];
334                    // Set start factor to 1 as for next range it does not apply.
335                    start_factor = 1;
336                }
337                else {
338                    // If smaller or equal then take the percentual distance of the calculate percentual part of that range
339                    rel_range_distance = ((distances[xPct_index + range_counter] * range_pct) / 100) * rest_factor;
340                    // No rest left as the rest fits in current range
341                    rest_factor = 0;
342                }
343                if (direction) {
344                    abs_distance_counter = abs_distance_counter - rel_range_distance;
345                    // Limit range to first range when distance becomes outside of minimum range
346                    if (this.xPct.length + range_counter >= 1) {
347                        range_counter--;
348                    }
349                }
350                else {
351                    abs_distance_counter = abs_distance_counter + rel_range_distance;
352                    // Limit range to last range when distance becomes outside of maximum range
353                    if (this.xPct.length - range_counter >= 1) {
354                        range_counter++;
355                    }
356                }
357                // Rest of relative percentual distance still to be calculated
358                rest_rel_distance = distances[xPct_index + range_counter] * rest_factor;
359            }
360            return value + abs_distance_counter;
361        };
362        Spectrum.prototype.toStepping = function (value) {
363            value = toStepping(this.xVal, this.xPct, value);
364            return value;
365        };
366        Spectrum.prototype.fromStepping = function (value) {
367            return fromStepping(this.xVal, this.xPct, value);
368        };
369        Spectrum.prototype.getStep = function (value) {
370            value = getStep(this.xPct, this.xSteps, this.snap, value);
371            return value;
372        };
373        Spectrum.prototype.getDefaultStep = function (value, isDown, size) {
374            var j = getJ(value, this.xPct);
375            // When at the top or stepping down, look at the previous sub-range
376            if (value === 100 || (isDown && value === this.xPct[j - 1])) {
377                j = Math.max(j - 1, 1);
378            }
379            return (this.xVal[j] - this.xVal[j - 1]) / size;
380        };
381        Spectrum.prototype.getNearbySteps = function (value) {
382            var j = getJ(value, this.xPct);
383            return {
384                stepBefore: {
385                    startValue: this.xVal[j - 2],
386                    step: this.xNumSteps[j - 2],
387                    highestStep: this.xHighestCompleteStep[j - 2],
388                },
389                thisStep: {
390                    startValue: this.xVal[j - 1],
391                    step: this.xNumSteps[j - 1],
392                    highestStep: this.xHighestCompleteStep[j - 1],
393                },
394                stepAfter: {
395                    startValue: this.xVal[j],
396                    step: this.xNumSteps[j],
397                    highestStep: this.xHighestCompleteStep[j],
398                },
399            };
400        };
401        Spectrum.prototype.countStepDecimals = function () {
402            var stepDecimals = this.xNumSteps.map(countDecimals);
403            return Math.max.apply(null, stepDecimals);
404        };
405        Spectrum.prototype.hasNoSize = function () {
406            return this.xVal[0] === this.xVal[this.xVal.length - 1];
407        };
408        // Outside testing
409        Spectrum.prototype.convert = function (value) {
410            return this.getStep(this.toStepping(value));
411        };
412        Spectrum.prototype.handleEntryPoint = function (index, value) {
413            var percentage;
414            // Covert min/max syntax to 0 and 100.
415            if (index === "min") {
416                percentage = 0;
417            }
418            else if (index === "max") {
419                percentage = 100;
420            }
421            else {
422                percentage = parseFloat(index);
423            }
424            // Check for correct input.
425            if (!isNumeric(percentage) || !isNumeric(value[0])) {
426                throw new Error("noUiSlider: 'range' value isn't numeric.");
427            }
428            // Store values.
429            this.xPct.push(percentage);
430            this.xVal.push(value[0]);
431            var value1 = Number(value[1]);
432            // NaN will evaluate to false too, but to keep
433            // logging clear, set step explicitly. Make sure
434            // not to override the 'step' setting with false.
435            if (!percentage) {
436                if (!isNaN(value1)) {
437                    this.xSteps[0] = value1;
438                }
439            }
440            else {
441                this.xSteps.push(isNaN(value1) ? false : value1);
442            }
443            this.xHighestCompleteStep.push(0);
444        };
445        Spectrum.prototype.handleStepPoint = function (i, n) {
446            // Ignore 'false' stepping.
447            if (!n) {
448                return;
449            }
450            // Step over zero-length ranges (#948);
451            if (this.xVal[i] === this.xVal[i + 1]) {
452                this.xSteps[i] = this.xHighestCompleteStep[i] = this.xVal[i];
453                return;
454            }
455            // Factor to range ratio
456            this.xSteps[i] =
457                fromPercentage([this.xVal[i], this.xVal[i + 1]], n, 0) / subRangeRatio(this.xPct[i], this.xPct[i + 1]);
458            var totalSteps = (this.xVal[i + 1] - this.xVal[i]) / this.xNumSteps[i];
459            var highestStep = Math.ceil(Number(totalSteps.toFixed(3)) - 1);
460            var step = this.xVal[i] + this.xNumSteps[i] * highestStep;
461            this.xHighestCompleteStep[i] = step;
462        };
463        return Spectrum;
464    }());
465    //endregion
466    //region Options
467    /*	Every input option is tested and parsed. This will prevent
468        endless validation in internal methods. These tests are
469        structured with an item for every option available. An
470        option can be marked as required by setting the 'r' flag.
471        The testing function is provided with three arguments:
472            - The provided value for the option;
473            - A reference to the options object;
474            - The name for the option;
475
476        The testing function returns false when an error is detected,
477        or true when everything is OK. It can also modify the option
478        object, to make sure all values can be correctly looped elsewhere. */
479    //region Defaults
480    var defaultFormatter = {
481        to: function (value) {
482            return value === undefined ? "" : value.toFixed(2);
483        },
484        from: Number,
485    };
486    var cssClasses = {
487        target: "target",
488        base: "base",
489        origin: "origin",
490        handle: "handle",
491        handleLower: "handle-lower",
492        handleUpper: "handle-upper",
493        touchArea: "touch-area",
494        horizontal: "horizontal",
495        vertical: "vertical",
496        background: "background",
497        connect: "connect",
498        connects: "connects",
499        ltr: "ltr",
500        rtl: "rtl",
501        textDirectionLtr: "txt-dir-ltr",
502        textDirectionRtl: "txt-dir-rtl",
503        draggable: "draggable",
504        drag: "state-drag",
505        tap: "state-tap",
506        active: "active",
507        tooltip: "tooltip",
508        pips: "pips",
509        pipsHorizontal: "pips-horizontal",
510        pipsVertical: "pips-vertical",
511        marker: "marker",
512        markerHorizontal: "marker-horizontal",
513        markerVertical: "marker-vertical",
514        markerNormal: "marker-normal",
515        markerLarge: "marker-large",
516        markerSub: "marker-sub",
517        value: "value",
518        valueHorizontal: "value-horizontal",
519        valueVertical: "value-vertical",
520        valueNormal: "value-normal",
521        valueLarge: "value-large",
522        valueSub: "value-sub",
523    };
524    // Namespaces of internal event listeners
525    var INTERNAL_EVENT_NS = {
526        tooltips: ".__tooltips",
527        aria: ".__aria",
528    };
529    //endregion
530    function testStep(parsed, entry) {
531        if (!isNumeric(entry)) {
532            throw new Error("noUiSlider: 'step' is not numeric.");
533        }
534        // The step option can still be used to set stepping
535        // for linear sliders. Overwritten if set in 'range'.
536        parsed.singleStep = entry;
537    }
538    function testKeyboardPageMultiplier(parsed, entry) {
539        if (!isNumeric(entry)) {
540            throw new Error("noUiSlider: 'keyboardPageMultiplier' is not numeric.");
541        }
542        parsed.keyboardPageMultiplier = entry;
543    }
544    function testKeyboardMultiplier(parsed, entry) {
545        if (!isNumeric(entry)) {
546            throw new Error("noUiSlider: 'keyboardMultiplier' is not numeric.");
547        }
548        parsed.keyboardMultiplier = entry;
549    }
550    function testKeyboardDefaultStep(parsed, entry) {
551        if (!isNumeric(entry)) {
552            throw new Error("noUiSlider: 'keyboardDefaultStep' is not numeric.");
553        }
554        parsed.keyboardDefaultStep = entry;
555    }
556    function testRange(parsed, entry) {
557        // Filter incorrect input.
558        if (typeof entry !== "object" || Array.isArray(entry)) {
559            throw new Error("noUiSlider: 'range' is not an object.");
560        }
561        // Catch missing start or end.
562        if (entry.min === undefined || entry.max === undefined) {
563            throw new Error("noUiSlider: Missing 'min' or 'max' in 'range'.");
564        }
565        parsed.spectrum = new Spectrum(entry, parsed.snap || false, parsed.singleStep);
566    }
567    function testStart(parsed, entry) {
568        entry = asArray(entry);
569        // Validate input. Values aren't tested, as the public .val method
570        // will always provide a valid location.
571        if (!Array.isArray(entry) || !entry.length) {
572            throw new Error("noUiSlider: 'start' option is incorrect.");
573        }
574        // Store the number of handles.
575        parsed.handles = entry.length;
576        // When the slider is initialized, the .val method will
577        // be called with the start options.
578        parsed.start = entry;
579    }
580    function testSnap(parsed, entry) {
581        if (typeof entry !== "boolean") {
582            throw new Error("noUiSlider: 'snap' option must be a boolean.");
583        }
584        // Enforce 100% stepping within subranges.
585        parsed.snap = entry;
586    }
587    function testAnimate(parsed, entry) {
588        if (typeof entry !== "boolean") {
589            throw new Error("noUiSlider: 'animate' option must be a boolean.");
590        }
591        // Enforce 100% stepping within subranges.
592        parsed.animate = entry;
593    }
594    function testAnimationDuration(parsed, entry) {
595        if (typeof entry !== "number") {
596            throw new Error("noUiSlider: 'animationDuration' option must be a number.");
597        }
598        parsed.animationDuration = entry;
599    }
600    function testConnect(parsed, entry) {
601        var connect = [false];
602        var i;
603        // Map legacy options
604        if (entry === "lower") {
605            entry = [true, false];
606        }
607        else if (entry === "upper") {
608            entry = [false, true];
609        }
610        // Handle boolean options
611        if (entry === true || entry === false) {
612            for (i = 1; i < parsed.handles; i++) {
613                connect.push(entry);
614            }
615            connect.push(false);
616        }
617        // Reject invalid input
618        else if (!Array.isArray(entry) || !entry.length || entry.length !== parsed.handles + 1) {
619            throw new Error("noUiSlider: 'connect' option doesn't match handle count.");
620        }
621        else {
622            connect = entry;
623        }
624        parsed.connect = connect;
625    }
626    function testOrientation(parsed, entry) {
627        // Set orientation to an a numerical value for easy
628        // array selection.
629        switch (entry) {
630            case "horizontal":
631                parsed.ort = 0;
632                break;
633            case "vertical":
634                parsed.ort = 1;
635                break;
636            default:
637                throw new Error("noUiSlider: 'orientation' option is invalid.");
638        }
639    }
640    function testMargin(parsed, entry) {
641        if (!isNumeric(entry)) {
642            throw new Error("noUiSlider: 'margin' option must be numeric.");
643        }
644        // Issue #582
645        if (entry === 0) {
646            return;
647        }
648        parsed.margin = parsed.spectrum.getDistance(entry);
649    }
650    function testLimit(parsed, entry) {
651        if (!isNumeric(entry)) {
652            throw new Error("noUiSlider: 'limit' option must be numeric.");
653        }
654        parsed.limit = parsed.spectrum.getDistance(entry);
655        if (!parsed.limit || parsed.handles < 2) {
656            throw new Error("noUiSlider: 'limit' option is only supported on linear sliders with 2 or more handles.");
657        }
658    }
659    function testPadding(parsed, entry) {
660        var index;
661        if (!isNumeric(entry) && !Array.isArray(entry)) {
662            throw new Error("noUiSlider: 'padding' option must be numeric or array of exactly 2 numbers.");
663        }
664        if (Array.isArray(entry) && !(entry.length === 2 || isNumeric(entry[0]) || isNumeric(entry[1]))) {
665            throw new Error("noUiSlider: 'padding' option must be numeric or array of exactly 2 numbers.");
666        }
667        if (entry === 0) {
668            return;
669        }
670        if (!Array.isArray(entry)) {
671            entry = [entry, entry];
672        }
673        // 'getDistance' returns false for invalid values.
674        parsed.padding = [parsed.spectrum.getDistance(entry[0]), parsed.spectrum.getDistance(entry[1])];
675        for (index = 0; index < parsed.spectrum.xNumSteps.length - 1; index++) {
676            // last "range" can't contain step size as it is purely an endpoint.
677            if (parsed.padding[0][index] < 0 || parsed.padding[1][index] < 0) {
678                throw new Error("noUiSlider: 'padding' option must be a positive number(s).");
679            }
680        }
681        var totalPadding = entry[0] + entry[1];
682        var firstValue = parsed.spectrum.xVal[0];
683        var lastValue = parsed.spectrum.xVal[parsed.spectrum.xVal.length - 1];
684        if (totalPadding / (lastValue - firstValue) > 1) {
685            throw new Error("noUiSlider: 'padding' option must not exceed 100% of the range.");
686        }
687    }
688    function testDirection(parsed, entry) {
689        // Set direction as a numerical value for easy parsing.
690        // Invert connection for RTL sliders, so that the proper
691        // handles get the connect/background classes.
692        switch (entry) {
693            case "ltr":
694                parsed.dir = 0;
695                break;
696            case "rtl":
697                parsed.dir = 1;
698                break;
699            default:
700                throw new Error("noUiSlider: 'direction' option was not recognized.");
701        }
702    }
703    function testBehaviour(parsed, entry) {
704        // Make sure the input is a string.
705        if (typeof entry !== "string") {
706            throw new Error("noUiSlider: 'behaviour' must be a string containing options.");
707        }
708        // Check if the string contains any keywords.
709        // None are required.
710        var tap = entry.indexOf("tap") >= 0;
711        var drag = entry.indexOf("drag") >= 0;
712        var fixed = entry.indexOf("fixed") >= 0;
713        var snap = entry.indexOf("snap") >= 0;
714        var hover = entry.indexOf("hover") >= 0;
715        var unconstrained = entry.indexOf("unconstrained") >= 0;
716        var invertConnects = entry.indexOf("invert-connects") >= 0;
717        var dragAll = entry.indexOf("drag-all") >= 0;
718        var smoothSteps = entry.indexOf("smooth-steps") >= 0;
719        if (fixed) {
720            if (parsed.handles !== 2) {
721                throw new Error("noUiSlider: 'fixed' behaviour must be used with 2 handles");
722            }
723            // Use margin to enforce fixed state
724            testMargin(parsed, parsed.start[1] - parsed.start[0]);
725        }
726        if (invertConnects && parsed.handles !== 2) {
727            throw new Error("noUiSlider: 'invert-connects' behaviour must be used with 2 handles");
728        }
729        if (unconstrained && (parsed.margin || parsed.limit)) {
730            throw new Error("noUiSlider: 'unconstrained' behaviour cannot be used with margin or limit");
731        }
732        parsed.events = {
733            tap: tap || snap,
734            drag: drag,
735            dragAll: dragAll,
736            smoothSteps: smoothSteps,
737            fixed: fixed,
738            snap: snap,
739            hover: hover,
740            unconstrained: unconstrained,
741            invertConnects: invertConnects,
742        };
743    }
744    function testTooltips(parsed, entry) {
745        if (entry === false) {
746            return;
747        }
748        if (entry === true || isValidPartialFormatter(entry)) {
749            parsed.tooltips = [];
750            for (var i = 0; i < parsed.handles; i++) {
751                parsed.tooltips.push(entry);
752            }
753        }
754        else {
755            entry = asArray(entry);
756            if (entry.length !== parsed.handles) {
757                throw new Error("noUiSlider: must pass a formatter for all handles.");
758            }
759            entry.forEach(function (formatter) {
760                if (typeof formatter !== "boolean" && !isValidPartialFormatter(formatter)) {
761                    throw new Error("noUiSlider: 'tooltips' must be passed a formatter or 'false'.");
762                }
763            });
764            parsed.tooltips = entry;
765        }
766    }
767    function testHandleAttributes(parsed, entry) {
768        if (entry.length !== parsed.handles) {
769            throw new Error("noUiSlider: must pass a attributes for all handles.");
770        }
771        parsed.handleAttributes = entry;
772    }
773    function testAriaFormat(parsed, entry) {
774        if (!isValidPartialFormatter(entry)) {
775            throw new Error("noUiSlider: 'ariaFormat' requires 'to' method.");
776        }
777        parsed.ariaFormat = entry;
778    }
779    function testFormat(parsed, entry) {
780        if (!isValidFormatter(entry)) {
781            throw new Error("noUiSlider: 'format' requires 'to' and 'from' methods.");
782        }
783        parsed.format = entry;
784    }
785    function testKeyboardSupport(parsed, entry) {
786        if (typeof entry !== "boolean") {
787            throw new Error("noUiSlider: 'keyboardSupport' option must be a boolean.");
788        }
789        parsed.keyboardSupport = entry;
790    }
791    function testDocumentElement(parsed, entry) {
792        // This is an advanced option. Passed values are used without validation.
793        parsed.documentElement = entry;
794    }
795    function testCssPrefix(parsed, entry) {
796        if (typeof entry !== "string" && entry !== false) {
797            throw new Error("noUiSlider: 'cssPrefix' must be a string or `false`.");
798        }
799        parsed.cssPrefix = entry;
800    }
801    function testCssClasses(parsed, entry) {
802        if (typeof entry !== "object") {
803            throw new Error("noUiSlider: 'cssClasses' must be an object.");
804        }
805        if (typeof parsed.cssPrefix === "string") {
806            parsed.cssClasses = {};
807            Object.keys(entry).forEach(function (key) {
808                parsed.cssClasses[key] = parsed.cssPrefix + entry[key];
809            });
810        }
811        else {
812            parsed.cssClasses = entry;
813        }
814    }
815    // Test all developer settings and parse to assumption-safe values.
816    function testOptions(options) {
817        // To prove a fix for #537, freeze options here.
818        // If the object is modified, an error will be thrown.
819        // Object.freeze(options);
820        var parsed = {
821            margin: null,
822            limit: null,
823            padding: null,
824            animate: true,
825            animationDuration: 300,
826            ariaFormat: defaultFormatter,
827            format: defaultFormatter,
828        };
829        // Tests are executed in the order they are presented here.
830        var tests = {
831            step: { r: false, t: testStep },
832            keyboardPageMultiplier: { r: false, t: testKeyboardPageMultiplier },
833            keyboardMultiplier: { r: false, t: testKeyboardMultiplier },
834            keyboardDefaultStep: { r: false, t: testKeyboardDefaultStep },
835            start: { r: true, t: testStart },
836            connect: { r: true, t: testConnect },
837            direction: { r: true, t: testDirection },
838            snap: { r: false, t: testSnap },
839            animate: { r: false, t: testAnimate },
840            animationDuration: { r: false, t: testAnimationDuration },
841            range: { r: true, t: testRange },
842            orientation: { r: false, t: testOrientation },
843            margin: { r: false, t: testMargin },
844            limit: { r: false, t: testLimit },
845            padding: { r: false, t: testPadding },
846            behaviour: { r: true, t: testBehaviour },
847            ariaFormat: { r: false, t: testAriaFormat },
848            format: { r: false, t: testFormat },
849            tooltips: { r: false, t: testTooltips },
850            keyboardSupport: { r: true, t: testKeyboardSupport },
851            documentElement: { r: false, t: testDocumentElement },
852            cssPrefix: { r: true, t: testCssPrefix },
853            cssClasses: { r: true, t: testCssClasses },
854            handleAttributes: { r: false, t: testHandleAttributes },
855        };
856        var defaults = {
857            connect: false,
858            direction: "ltr",
859            behaviour: "tap",
860            orientation: "horizontal",
861            keyboardSupport: true,
862            cssPrefix: "noUi-",
863            cssClasses: cssClasses,
864            keyboardPageMultiplier: 5,
865            keyboardMultiplier: 1,
866            keyboardDefaultStep: 10,
867        };
868        // AriaFormat defaults to regular format, if any.
869        if (options.format && !options.ariaFormat) {
870            options.ariaFormat = options.format;
871        }
872        // Run all options through a testing mechanism to ensure correct
873        // input. It should be noted that options might get modified to
874        // be handled properly. E.g. wrapping integers in arrays.
875        Object.keys(tests).forEach(function (name) {
876            // If the option isn't set, but it is required, throw an error.
877            if (!isSet(options[name]) && defaults[name] === undefined) {
878                if (tests[name].r) {
879                    throw new Error("noUiSlider: '" + name + "' is required.");
880                }
881                return;
882            }
883            tests[name].t(parsed, !isSet(options[name]) ? defaults[name] : options[name]);
884        });
885        // Forward pips options
886        parsed.pips = options.pips;
887        // All recent browsers accept unprefixed transform.
888        // We need -ms- for IE9 and -webkit- for older Android;
889        // Assume use of -webkit- if unprefixed and -ms- are not supported.
890        // https://caniuse.com/#feat=transforms2d
891        var d = document.createElement("div");
892        var msPrefix = d.style.msTransform !== undefined;
893        var noPrefix = d.style.transform !== undefined;
894        parsed.transformRule = noPrefix ? "transform" : msPrefix ? "msTransform" : "webkitTransform";
895        // Pips don't move, so we can place them using left/top.
896        var styles = [
897            ["left", "top"],
898            ["right", "bottom"],
899        ];
900        parsed.style = styles[parsed.dir][parsed.ort];
901        return parsed;
902    }
903    //endregion
904    function scope(target, options, originalOptions) {
905        var actions = getActions();
906        var supportsTouchActionNone = getSupportsTouchActionNone();
907        var supportsPassive = supportsTouchActionNone && getSupportsPassive();
908        // All variables local to 'scope' are prefixed with 'scope_'
909        // Slider DOM Nodes
910        var scope_Target = target;
911        var scope_Base;
912        var scope_ConnectBase;
913        var scope_Handles;
914        var scope_Connects;
915        var scope_Pips;
916        var scope_Tooltips;
917        // Slider state values
918        var scope_Spectrum = options.spectrum;
919        var scope_Values = [];
920        var scope_Locations = [];
921        var scope_HandleNumbers = [];
922        var scope_ActiveHandlesCount = 0;
923        var scope_Events = {};
924        var scope_ConnectsInverted = false;
925        // Document Nodes
926        var scope_Document = target.ownerDocument;
927        var scope_DocumentElement = options.documentElement || scope_Document.documentElement;
928        var scope_Body = scope_Document.body;
929        // For horizontal sliders in standard ltr documents,
930        // make .noUi-origin overflow to the left so the document doesn't scroll.
931        var scope_DirOffset = scope_Document.dir === "rtl" || options.ort === 1 ? 0 : 100;
932        // Creates a node, adds it to target, returns the new node.
933        function addNodeTo(addTarget, className) {
934            var div = scope_Document.createElement("div");
935            if (className) {
936                addClass(div, className);
937            }
938            addTarget.appendChild(div);
939            return div;
940        }
941        // Append a origin to the base
942        function addOrigin(base, handleNumber) {
943            var origin = addNodeTo(base, options.cssClasses.origin);
944            var handle = addNodeTo(origin, options.cssClasses.handle);
945            addNodeTo(handle, options.cssClasses.touchArea);
946            handle.setAttribute("data-handle", String(handleNumber));
947            if (options.keyboardSupport) {
948                // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
949                // 0 = focusable and reachable
950                handle.setAttribute("tabindex", "0");
951                handle.addEventListener("keydown", function (event) {
952                    return eventKeydown(event, handleNumber);
953                });
954            }
955            if (options.handleAttributes !== undefined) {
956                var attributes_1 = options.handleAttributes[handleNumber];
957                Object.keys(attributes_1).forEach(function (attribute) {
958                    handle.setAttribute(attribute, attributes_1[attribute]);
959                });
960            }
961            handle.setAttribute("role", "slider");
962            handle.setAttribute("aria-orientation", options.ort ? "vertical" : "horizontal");
963            if (handleNumber === 0) {
964                addClass(handle, options.cssClasses.handleLower);
965            }
966            else if (handleNumber === options.handles - 1) {
967                addClass(handle, options.cssClasses.handleUpper);
968            }
969            origin.handle = handle;
970            return origin;
971        }
972        // Insert nodes for connect elements
973        function addConnect(base, add) {
974            if (!add) {
975                return false;
976            }
977            return addNodeTo(base, options.cssClasses.connect);
978        }
979        // Add handles to the slider base.
980        function addElements(connectOptions, base) {
981            scope_ConnectBase = addNodeTo(base, options.cssClasses.connects);
982            scope_Handles = [];
983            scope_Connects = [];
984            scope_Connects.push(addConnect(scope_ConnectBase, connectOptions[0]));
985            // [::::O====O====O====]
986            // connectOptions = [0, 1, 1, 1]
987            for (var i = 0; i < options.handles; i++) {
988                // Keep a list of all added handles.
989                scope_Handles.push(addOrigin(base, i));
990                scope_HandleNumbers[i] = i;
991                scope_Connects.push(addConnect(scope_ConnectBase, connectOptions[i + 1]));
992            }
993        }
994        // Initialize a single slider.
995        function addSlider(addTarget) {
996            // Apply classes and data to the target.
997            addClass(addTarget, options.cssClasses.target);
998            if (options.dir === 0) {
999                addClass(addTarget, options.cssClasses.ltr);
1000            }
1001            else {
1002                addClass(addTarget, options.cssClasses.rtl);
1003            }
1004            if (options.ort === 0) {
1005                addClass(addTarget, options.cssClasses.horizontal);
1006            }
1007            else {
1008                addClass(addTarget, options.cssClasses.vertical);
1009            }
1010            var textDirection = getComputedStyle(addTarget).direction;
1011            if (textDirection === "rtl") {
1012                addClass(addTarget, options.cssClasses.textDirectionRtl);
1013            }
1014            else {
1015                addClass(addTarget, options.cssClasses.textDirectionLtr);
1016            }
1017            return addNodeTo(addTarget, options.cssClasses.base);
1018        }
1019        function addTooltip(handle, handleNumber) {
1020            if (!options.tooltips || !options.tooltips[handleNumber]) {
1021                return false;
1022            }
1023            return addNodeTo(handle.firstChild, options.cssClasses.tooltip);
1024        }
1025        function isSliderDisabled() {
1026            return scope_Target.hasAttribute("disabled");
1027        }
1028        // Disable the slider dragging if any handle is disabled
1029        function isHandleDisabled(handleNumber) {
1030            var handleOrigin = scope_Handles[handleNumber];
1031            return handleOrigin.hasAttribute("disabled");
1032        }
1033        function disable(handleNumber) {
1034            if (handleNumber !== null && handleNumber !== undefined) {
1035                scope_Handles[handleNumber].setAttribute("disabled", "");
1036                scope_Handles[handleNumber].handle.removeAttribute("tabindex");
1037            }
1038            else {
1039                scope_Target.setAttribute("disabled", "");
1040                scope_Handles.forEach(function (handle) {
1041                    handle.handle.removeAttribute("tabindex");
1042                });
1043            }
1044        }
1045        function enable(handleNumber) {
1046            if (handleNumber !== null && handleNumber !== undefined) {
1047                scope_Handles[handleNumber].removeAttribute("disabled");
1048                scope_Handles[handleNumber].handle.setAttribute("tabindex", "0");
1049            }
1050            else {
1051                scope_Target.removeAttribute("disabled");
1052                scope_Handles.forEach(function (handle) {
1053                    handle.removeAttribute("disabled");
1054                    handle.handle.setAttribute("tabindex", "0");
1055                });
1056            }
1057        }
1058        function removeTooltips() {
1059            if (scope_Tooltips) {
1060                removeEvent("update" + INTERNAL_EVENT_NS.tooltips);
1061                scope_Tooltips.forEach(function (tooltip) {
1062                    if (tooltip) {
1063                        removeElement(tooltip);
1064                    }
1065                });
1066                scope_Tooltips = null;
1067            }
1068        }
1069        // The tooltips option is a shorthand for using the 'update' event.
1070        function tooltips() {
1071            removeTooltips();
1072            // Tooltips are added with options.tooltips in original order.
1073            scope_Tooltips = scope_Handles.map(addTooltip);
1074            bindEvent("update" + INTERNAL_EVENT_NS.tooltips, function (values, handleNumber, unencoded) {
1075                if (!scope_Tooltips || !options.tooltips) {
1076                    return;
1077                }
1078                if (scope_Tooltips[handleNumber] === false) {
1079                    return;
1080                }
1081                var formattedValue = values[handleNumber];
1082                if (options.tooltips[handleNumber] !== true) {
1083                    formattedValue = options.tooltips[handleNumber].to(unencoded[handleNumber]);
1084                }
1085                scope_Tooltips[handleNumber].innerHTML = formattedValue;
1086            });
1087        }
1088        function aria() {
1089            removeEvent("update" + INTERNAL_EVENT_NS.aria);
1090            bindEvent("update" + INTERNAL_EVENT_NS.aria, function (values, handleNumber, unencoded, tap, positions) {
1091                // Update Aria Values for all handles, as a change in one changes min and max values for the next.
1092                scope_HandleNumbers.forEach(function (index) {
1093                    var handle = scope_Handles[index];
1094                    var min = checkHandlePosition(scope_Locations, index, 0, true, true, true);
1095                    var max = checkHandlePosition(scope_Locations, index, 100, true, true, true);
1096                    var now = positions[index];
1097                    // Formatted value for display
1098                    var text = String(options.ariaFormat.to(unencoded[index]));
1099                    // Map to slider range values
1100                    min = scope_Spectrum.fromStepping(min).toFixed(1);
1101                    max = scope_Spectrum.fromStepping(max).toFixed(1);
1102                    now = scope_Spectrum.fromStepping(now).toFixed(1);
1103                    handle.children[0].setAttribute("aria-valuemin", min);
1104                    handle.children[0].setAttribute("aria-valuemax", max);
1105                    handle.children[0].setAttribute("aria-valuenow", now);
1106                    handle.children[0].setAttribute("aria-valuetext", text);
1107                });
1108            });
1109        }
1110        function getGroup(pips) {
1111            // Use the range.
1112            if (pips.mode === exports.PipsMode.Range || pips.mode === exports.PipsMode.Steps) {
1113                return scope_Spectrum.xVal;
1114            }
1115            if (pips.mode === exports.PipsMode.Count) {
1116                if (pips.values < 2) {
1117                    throw new Error("noUiSlider: 'values' (>= 2) required for mode 'count'.");
1118                }
1119                // Divide 0 - 100 in 'count' parts.
1120                var interval = pips.values - 1;
1121                var spread = 100 / interval;
1122                var values = [];
1123                // List these parts and have them handled as 'positions'.
1124                while (interval--) {
1125                    values[interval] = interval * spread;
1126                }
1127                values.push(100);
1128                return mapToRange(values, pips.stepped);
1129            }
1130            if (pips.mode === exports.PipsMode.Positions) {
1131                // Map all percentages to on-range values.
1132                return mapToRange(pips.values, pips.stepped);
1133            }
1134            if (pips.mode === exports.PipsMode.Values) {
1135                // If the value must be stepped, it needs to be converted to a percentage first.
1136                if (pips.stepped) {
1137                    return pips.values.map(function (value) {
1138                        // Convert to percentage, apply step, return to value.
1139                        return scope_Spectrum.fromStepping(scope_Spectrum.getStep(scope_Spectrum.toStepping(value)));
1140                    });
1141                }
1142                // Otherwise, we can simply use the values.
1143                return pips.values;
1144            }
1145            return []; // pips.mode = never
1146        }
1147        function mapToRange(values, stepped) {
1148            return values.map(function (value) {
1149                return scope_Spectrum.fromStepping(stepped ? scope_Spectrum.getStep(value) : value);
1150            });
1151        }
1152        function generateSpread(pips) {
1153            function safeIncrement(value, increment) {
1154                // Avoid floating point variance by dropping the smallest decimal places.
1155                return Number((value + increment).toFixed(7));
1156            }
1157            var group = getGroup(pips);
1158            var indexes = {};
1159            var firstInRange = scope_Spectrum.xVal[0];
1160            var lastInRange = scope_Spectrum.xVal[scope_Spectrum.xVal.length - 1];
1161            var ignoreFirst = false;
1162            var ignoreLast = false;
1163            var prevPct = 0;
1164            // Create a copy of the group, sort it and filter away all duplicates.
1165            group = unique(group.slice().sort(function (a, b) {
1166                return a - b;
1167            }));
1168            // Make sure the range starts with the first element.
1169            if (group[0] !== firstInRange) {
1170                group.unshift(firstInRange);
1171                ignoreFirst = true;
1172            }
1173            // Likewise for the last one.
1174            if (group[group.length - 1] !== lastInRange) {
1175                group.push(lastInRange);
1176                ignoreLast = true;
1177            }
1178            group.forEach(function (current, index) {
1179                // Get the current step and the lower + upper positions.
1180                var step;
1181                var i;
1182                var q;
1183                var low = current;
1184                var high = group[index + 1];
1185                var newPct;
1186                var pctDifference;
1187                var pctPos;
1188                var type;
1189                var steps;
1190                var realSteps;
1191                var stepSize;
1192                var isSteps = pips.mode === exports.PipsMode.Steps;
1193                // When using 'steps' mode, use the provided steps.
1194                // Otherwise, we'll step on to the next subrange.
1195                if (isSteps) {
1196                    step = scope_Spectrum.xNumSteps[index];
1197                }
1198                // Default to a 'full' step.
1199                if (!step) {
1200                    step = high - low;
1201                }
1202                // If high is undefined we are at the last subrange. Make sure it iterates once (#1088)
1203                if (high === undefined) {
1204                    high = low;
1205                }
1206                // Make sure step isn't 0, which would cause an infinite loop (#654)
1207                step = Math.max(step, 0.0000001);
1208                // Find all steps in the subrange.
1209                for (i = low; i <= high; i = safeIncrement(i, step)) {
1210                    // Get the percentage value for the current step,
1211                    // calculate the size for the subrange.
1212                    newPct = scope_Spectrum.toStepping(i);
1213                    pctDifference = newPct - prevPct;
1214                    steps = pctDifference / (pips.density || 1);
1215                    realSteps = Math.round(steps);
1216                    // This ratio represents the amount of percentage-space a point indicates.
1217                    // For a density 1 the points/percentage = 1. For density 2, that percentage needs to be re-divided.
1218                    // Round the percentage offset to an even number, then divide by two
1219                    // to spread the offset on both sides of the range.
1220                    stepSize = pctDifference / realSteps;
1221                    // Divide all points evenly, adding the correct number to this subrange.
1222                    // Run up to <= so that 100% gets a point, event if ignoreLast is set.
1223                    for (q = 1; q <= realSteps; q += 1) {
1224                        // The ratio between the rounded value and the actual size might be ~1% off.
1225                        // Correct the percentage offset by the number of points
1226                        // per subrange. density = 1 will result in 100 points on the
1227                        // full range, 2 for 50, 4 for 25, etc.
1228                        pctPos = prevPct + q * stepSize;
1229                        indexes[pctPos.toFixed(5)] = [scope_Spectrum.fromStepping(pctPos), 0];
1230                    }
1231                    // Determine the point type.
1232                    type = group.indexOf(i) > -1 ? exports.PipsType.LargeValue : isSteps ? exports.PipsType.SmallValue : exports.PipsType.NoValue;
1233                    // Enforce the 'ignoreFirst' option by overwriting the type for 0.
1234                    if (!index && ignoreFirst && i !== high) {
1235                        type = 0;
1236                    }
1237                    if (!(i === high && ignoreLast)) {
1238                        // Mark the 'type' of this point. 0 = plain, 1 = real value, 2 = step value.
1239                        indexes[newPct.toFixed(5)] = [i, type];
1240                    }
1241                    // Update the percentage count.
1242                    prevPct = newPct;
1243                }
1244            });
1245            return indexes;
1246        }
1247        function addMarking(spread, filterFunc, formatter) {
1248            var _a, _b;
1249            var element = scope_Document.createElement("div");
1250            var valueSizeClasses = (_a = {},
1251                _a[exports.PipsType.None] = "",
1252                _a[exports.PipsType.NoValue] = options.cssClasses.valueNormal,
1253                _a[exports.PipsType.LargeValue] = options.cssClasses.valueLarge,
1254                _a[exports.PipsType.SmallValue] = options.cssClasses.valueSub,
1255                _a);
1256            var markerSizeClasses = (_b = {},
1257                _b[exports.PipsType.None] = "",
1258                _b[exports.PipsType.NoValue] = options.cssClasses.markerNormal,
1259                _b[exports.PipsType.LargeValue] = options.cssClasses.markerLarge,
1260                _b[exports.PipsType.SmallValue] = options.cssClasses.markerSub,
1261                _b);
1262            var valueOrientationClasses = [options.cssClasses.valueHorizontal, options.cssClasses.valueVertical];
1263            var markerOrientationClasses = [options.cssClasses.markerHorizontal, options.cssClasses.markerVertical];
1264            addClass(element, options.cssClasses.pips);
1265            addClass(element, options.ort === 0 ? options.cssClasses.pipsHorizontal : options.cssClasses.pipsVertical);
1266            function getClasses(type, source) {
1267                var a = source === options.cssClasses.value;
1268                var orientationClasses = a ? valueOrientationClasses : markerOrientationClasses;
1269                var sizeClasses = a ? valueSizeClasses : markerSizeClasses;
1270                return source + " " + orientationClasses[options.ort] + " " + sizeClasses[type];
1271            }
1272            function addSpread(offset, value, type) {
1273                // Apply the filter function, if it is set.
1274                type = filterFunc ? filterFunc(value, type) : type;
1275                if (type === exports.PipsType.None) {
1276                    return;
1277                }
1278                // Add a marker for every point
1279                var node = addNodeTo(element, false);
1280                node.className = getClasses(type, options.cssClasses.marker);
1281                node.style[options.style] = offset + "%";
1282                // Values are only appended for points marked '1' or '2'.
1283                if (type > exports.PipsType.NoValue) {
1284                    node = addNodeTo(element, false);
1285                    node.className = getClasses(type, options.cssClasses.value);
1286                    node.setAttribute("data-value", String(value));
1287                    node.style[options.style] = offset + "%";
1288                    node.innerHTML = String(formatter.to(value));
1289                }
1290            }
1291            // Append all points.
1292            Object.keys(spread).forEach(function (offset) {
1293                addSpread(offset, spread[offset][0], spread[offset][1]);
1294            });
1295            return element;
1296        }
1297        function removePips() {
1298            if (scope_Pips) {
1299                removeElement(scope_Pips);
1300                scope_Pips = null;
1301            }
1302        }
1303        function pips(pips) {
1304            // Fix #669
1305            removePips();
1306            var spread = generateSpread(pips);
1307            var filter = pips.filter;
1308            var format = pips.format || {
1309                to: function (value) {
1310                    return String(Math.round(value));
1311                },
1312            };
1313            scope_Pips = scope_Target.appendChild(addMarking(spread, filter, format));
1314            return scope_Pips;
1315        }
1316        // Shorthand for base dimensions.
1317        function baseSize() {
1318            var rect = scope_Base.getBoundingClientRect();
1319            var alt = ("offset" + ["Width", "Height"][options.ort]);
1320            return options.ort === 0 ? rect.width || scope_Base[alt] : rect.height || scope_Base[alt];
1321        }
1322        // Handler for attaching events trough a proxy.
1323        function attachEvent(events, element, callback, data) {
1324            // This function can be used to 'filter' events to the slider.
1325            // element is a node, not a nodeList
1326            var method = function (event) {
1327                var e = fixEvent(event, data.pageOffset, data.target || element);
1328                // fixEvent returns false if this event has a different target
1329                // when handling (multi-) touch events;
1330                if (!e) {
1331                    return false;
1332                }
1333                // doNotReject is passed by all end events to make sure released touches
1334                // are not rejected, leaving the slider "stuck" to the cursor;
1335                if (isSliderDisabled() && !data.doNotReject) {
1336                    return false;
1337                }
1338                // Stop if an active 'tap' transition is taking place.
1339                if (hasClass(scope_Target, options.cssClasses.tap) && !data.doNotReject) {
1340                    return false;
1341                }
1342                // Ignore right or middle clicks on start #454
1343                if (events === actions.start && e.buttons !== undefined && e.buttons > 1) {
1344                    return false;
1345                }
1346                // Ignore right or middle clicks on start #454
1347                if (data.hover && e.buttons) {
1348                    return false;
1349                }
1350                // 'supportsPassive' is only true if a browser also supports touch-action: none in CSS.
1351                // iOS safari does not, so it doesn't get to benefit from passive scrolling. iOS does support
1352                // touch-action: manipulation, but that allows panning, which breaks
1353                // sliders after zooming/on non-responsive pages.
1354                // See: https://bugs.webkit.org/show_bug.cgi?id=133112
1355                if (!supportsPassive) {
1356                    e.preventDefault();
1357                }
1358                e.calcPoint = e.points[options.ort];
1359                // Call the event handler with the event [ and additional data ].
1360                callback(e, data);
1361                return;
1362            };
1363            var methods = [];
1364            // Bind a closure on the target for every event type.
1365            events.split(" ").forEach(function (eventName) {
1366                element.addEventListener(eventName, method, supportsPassive ? { passive: true } : false);
1367                methods.push([eventName, method]);
1368            });
1369            return methods;
1370        }
1371        // Provide a clean event with standardized offset values.
1372        function fixEvent(e, pageOffset, eventTarget) {
1373            // Filter the event to register the type, which can be
1374            // touch, mouse or pointer. Offset changes need to be
1375            // made on an event specific basis.
1376            var touch = e.type.indexOf("touch") === 0;
1377            var mouse = e.type.indexOf("mouse") === 0;
1378            var pointer = e.type.indexOf("pointer") === 0;
1379            var x = 0;
1380            var y = 0;
1381            // IE10 implemented pointer events with a prefix;
1382            if (e.type.indexOf("MSPointer") === 0) {
1383                pointer = true;
1384            }
1385            // Erroneous events seem to be passed in occasionally on iOS/iPadOS after user finishes interacting with
1386            // the slider. They appear to be of type MouseEvent, yet they don't have usual properties set. Ignore
1387            // events that have no touches or buttons associated with them. (#1057, #1079, #1095)
1388            if (e.type === "mousedown" && !e.buttons && !e.touches) {
1389                return false;
1390            }
1391            // The only thing one handle should be concerned about is the touches that originated on top of it.
1392            if (touch) {
1393                // Returns true if a touch originated on the target.
1394                var isTouchOnTarget = function (checkTouch) {
1395                    var target = checkTouch.target;
1396                    return (target === eventTarget ||
1397                        eventTarget.contains(target) ||
1398                        (e.composed && e.composedPath().shift() === eventTarget));
1399                };
1400                // In the case of touchstart events, we need to make sure there is still no more than one
1401                // touch on the target so we look amongst all touches.
1402                if (e.type === "touchstart") {
1403                    var targetTouches = Array.prototype.filter.call(e.touches, isTouchOnTarget);
1404                    // Do not support more than one touch per handle.
1405                    if (targetTouches.length > 1) {
1406                        return false;
1407                    }
1408                    x = targetTouches[0].pageX;
1409                    y = targetTouches[0].pageY;
1410                }
1411                else {
1412                    // In the other cases, find on changedTouches is enough.
1413                    var targetTouch = Array.prototype.find.call(e.changedTouches, isTouchOnTarget);
1414                    // Cancel if the target touch has not moved.
1415                    if (!targetTouch) {
1416                        return false;
1417                    }
1418                    x = targetTouch.pageX;
1419                    y = targetTouch.pageY;
1420                }
1421            }
1422            pageOffset = pageOffset || getPageOffset(scope_Document);
1423            if (mouse || pointer) {
1424                x = e.clientX + pageOffset.x;
1425                y = e.clientY + pageOffset.y;
1426            }
1427            e.pageOffset = pageOffset;
1428            e.points = [x, y];
1429            e.cursor = mouse || pointer; // Fix #435
1430            return e;
1431        }
1432        // Translate a coordinate in the document to a percentage on the slider
1433        function calcPointToPercentage(calcPoint) {
1434            var location = calcPoint - offset(scope_Base, options.ort);
1435            var proposal = (location * 100) / baseSize();
1436            // Clamp proposal between 0% and 100%
1437            // Out-of-bound coordinates may occur when .noUi-base pseudo-elements
1438            // are used (e.g. contained handles feature)
1439            proposal = limit(proposal);
1440            return options.dir ? 100 - proposal : proposal;
1441        }
1442        // Find handle closest to a certain percentage on the slider
1443        function getClosestHandle(clickedPosition) {
1444            var smallestDifference = 100;
1445            var handleNumber = false;
1446            scope_Handles.forEach(function (handle, index) {
1447                // Disabled handles are ignored
1448                if (isHandleDisabled(index)) {
1449                    return;
1450                }
1451                var handlePosition = scope_Locations[index];
1452                var differenceWithThisHandle = Math.abs(handlePosition - clickedPosition);
1453                // Initial state
1454                var clickAtEdge = differenceWithThisHandle === 100 && smallestDifference === 100;
1455                // Difference with this handle is smaller than the previously checked handle
1456                var isCloser = differenceWithThisHandle < smallestDifference;
1457                var isCloserAfter = differenceWithThisHandle <= smallestDifference && clickedPosition > handlePosition;
1458                if (isCloser || isCloserAfter || clickAtEdge) {
1459                    handleNumber = index;
1460                    smallestDifference = differenceWithThisHandle;
1461                }
1462            });
1463            return handleNumber;
1464        }
1465        // Fire 'end' when a mouse or pen leaves the document.
1466        function documentLeave(event, data) {
1467            if (event.type === "mouseout" &&
1468                event.target.nodeName === "HTML" &&
1469                event.relatedTarget === null) {
1470                eventEnd(event, data);
1471            }
1472        }
1473        // Handle movement on document for handle and range drag.
1474        function eventMove(event, data) {
1475            // Fix #498
1476            // Check value of .buttons in 'start' to work around a bug in IE10 mobile (data.buttonsProperty).
1477            // https://connect.microsoft.com/IE/feedback/details/927005/mobile-ie10-windows-phone-buttons-property-of-pointermove-event-always-zero
1478            // IE9 has .buttons and .which zero on mousemove.
1479            // Firefox breaks the spec MDN defines.
1480            if (navigator.appVersion.indexOf("MSIE 9") === -1 && event.buttons === 0 && data.buttonsProperty !== 0) {
1481                return eventEnd(event, data);
1482            }
1483            // Check if we are moving up or down
1484            var movement = (options.dir ? -1 : 1) * (event.calcPoint - data.startCalcPoint);
1485            // Convert the movement into a percentage of the slider width/height
1486            var proposal = (movement * 100) / data.baseSize;
1487            moveHandles(movement > 0, proposal, data.locations, data.handleNumbers, data.connect);
1488        }
1489        // Unbind move events on document, call callbacks.
1490        function eventEnd(event, data) {
1491            // The handle is no longer active, so remove the class.
1492            if (data.handle) {
1493                removeClass(data.handle, options.cssClasses.active);
1494                scope_ActiveHandlesCount -= 1;
1495            }
1496            // Unbind the move and end events, which are added on 'start'.
1497            data.listeners.forEach(function (c) {
1498                scope_DocumentElement.removeEventListener(c[0], c[1]);
1499            });
1500            if (scope_ActiveHandlesCount === 0) {
1501                // Remove dragging class.
1502                removeClass(scope_Target, options.cssClasses.drag);
1503                setZindex();
1504                // Remove cursor styles and text-selection events bound to the body.
1505                if (event.cursor) {
1506                    scope_Body.style.cursor = "";
1507                    scope_Body.removeEventListener("selectstart", preventDefault);
1508                }
1509            }
1510            if (options.events.smoothSteps) {
1511                data.handleNumbers.forEach(function (handleNumber) {
1512                    setHandle(handleNumber, scope_Locations[handleNumber], true, true, false, false);
1513                });
1514                data.handleNumbers.forEach(function (handleNumber) {
1515                    fireEvent("update", handleNumber);
1516                });
1517            }
1518            data.handleNumbers.forEach(function (handleNumber) {
1519                fireEvent("change", handleNumber);
1520                fireEvent("set", handleNumber);
1521                fireEvent("end", handleNumber);
1522            });
1523        }
1524        // Bind move events on document.
1525        function eventStart(event, data) {
1526            // Ignore event if any handle is disabled
1527            if (data.handleNumbers.some(isHandleDisabled)) {
1528                return;
1529            }
1530            var handle;
1531            if (data.handleNumbers.length === 1) {
1532                var handleOrigin = scope_Handles[data.handleNumbers[0]];
1533                handle = handleOrigin.children[0];
1534                scope_ActiveHandlesCount += 1;
1535                // Mark the handle as 'active' so it can be styled.
1536                addClass(handle, options.cssClasses.active);
1537            }
1538            // A drag should never propagate up to the 'tap' event.
1539            event.stopPropagation();
1540            // Record the event listeners.
1541            var listeners = [];
1542            // Attach the move and end events.
1543            var moveEvent = attachEvent(actions.move, scope_DocumentElement, eventMove, {
1544                // The event target has changed so we need to propagate the original one so that we keep
1545                // relying on it to extract target touches.
1546                target: event.target,
1547                handle: handle,
1548                connect: data.connect,
1549                listeners: listeners,
1550                startCalcPoint: event.calcPoint,
1551                baseSize: baseSize(),
1552                pageOffset: event.pageOffset,
1553                handleNumbers: data.handleNumbers,
1554                buttonsProperty: event.buttons,
1555                locations: scope_Locations.slice(),
1556            });
1557            var endEvent = attachEvent(actions.end, scope_DocumentElement, eventEnd, {
1558                target: event.target,
1559                handle: handle,
1560                listeners: listeners,
1561                doNotReject: true,
1562                handleNumbers: data.handleNumbers,
1563            });
1564            var outEvent = attachEvent("mouseout", scope_DocumentElement, documentLeave, {
1565                target: event.target,
1566                handle: handle,
1567                listeners: listeners,
1568                doNotReject: true,
1569                handleNumbers: data.handleNumbers,
1570            });
1571            // We want to make sure we pushed the listeners in the listener list rather than creating
1572            // a new one as it has already been passed to the event handlers.
1573            listeners.push.apply(listeners, moveEvent.concat(endEvent, outEvent));
1574            // Text selection isn't an issue on touch devices,
1575            // so adding cursor styles can be skipped.
1576            if (event.cursor) {
1577                // Prevent the 'I' cursor and extend the range-drag cursor.
1578                scope_Body.style.cursor = getComputedStyle(event.target).cursor;
1579                // Mark the target with a dragging state.
1580                if (scope_Handles.length > 1) {
1581                    addClass(scope_Target, options.cssClasses.drag);
1582                }
1583                // Prevent text selection when dragging the handles.
1584                // In noUiSlider <= 9.2.0, this was handled by calling preventDefault on mouse/touch start/move,
1585                // which is scroll blocking. The selectstart event is supported by FireFox starting from version 52,
1586                // meaning the only holdout is iOS Safari. This doesn't matter: text selection isn't triggered there.
1587                // The 'cursor' flag is false.
1588                // See: http://caniuse.com/#search=selectstart
1589                scope_Body.addEventListener("selectstart", preventDefault, false);
1590            }
1591            data.handleNumbers.forEach(function (handleNumber) {
1592                fireEvent("start", handleNumber);
1593            });
1594        }
1595        // Move closest handle to tapped location.
1596        function eventTap(event) {
1597            // The tap event shouldn't propagate up
1598            event.stopPropagation();
1599            var proposal = calcPointToPercentage(event.calcPoint);
1600            var handleNumber = getClosestHandle(proposal);
1601            // Tackle the case that all handles are 'disabled'.
1602            if (handleNumber === false) {
1603                return;
1604            }
1605            // Flag the slider as it is now in a transitional state.
1606            // Transition takes a configurable amount of ms (default 300). Re-enable the slider after that.
1607            if (!options.events.snap) {
1608                addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration);
1609            }
1610            setHandle(handleNumber, proposal, true, true);
1611            setZindex();
1612            fireEvent("slide", handleNumber, true);
1613            fireEvent("update", handleNumber, true);
1614            if (!options.events.snap) {
1615                fireEvent("change", handleNumber, true);
1616                fireEvent("set", handleNumber, true);
1617            }
1618            else {
1619                eventStart(event, { handleNumbers: [handleNumber] });
1620            }
1621        }
1622        // Fires a 'hover' event for a hovered mouse/pen position.
1623        function eventHover(event) {
1624            var proposal = calcPointToPercentage(event.calcPoint);
1625            var to = scope_Spectrum.getStep(proposal);
1626            var value = scope_Spectrum.fromStepping(to);
1627            Object.keys(scope_Events).forEach(function (targetEvent) {
1628                if ("hover" === targetEvent.split(".")[0]) {
1629                    scope_Events[targetEvent].forEach(function (callback) {
1630                        callback.call(scope_Self, value);
1631                    });
1632                }
1633            });
1634        }
1635        // Handles keydown on focused handles
1636        // Don't move the document when pressing arrow keys on focused handles
1637        function eventKeydown(event, handleNumber) {
1638            if (isSliderDisabled() || isHandleDisabled(handleNumber)) {
1639                return false;
1640            }
1641            var horizontalKeys = ["Left", "Right"];
1642            var verticalKeys = ["Down", "Up"];
1643            var largeStepKeys = ["PageDown", "PageUp"];
1644            var edgeKeys = ["Home", "End"];
1645            if (options.dir && !options.ort) {
1646                // On an right-to-left slider, the left and right keys act inverted
1647                horizontalKeys.reverse();
1648            }
1649            else if (options.ort && !options.dir) {
1650                // On a top-to-bottom slider, the up and down keys act inverted
1651                verticalKeys.reverse();
1652                largeStepKeys.reverse();
1653            }
1654            // Strip "Arrow" for IE compatibility. https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
1655            var key = event.key.replace("Arrow", "");
1656            var isLargeDown = key === largeStepKeys[0];
1657            var isLargeUp = key === largeStepKeys[1];
1658            var isDown = key === verticalKeys[0] || key === horizontalKeys[0] || isLargeDown;
1659            var isUp = key === verticalKeys[1] || key === horizontalKeys[1] || isLargeUp;
1660            var isMin = key === edgeKeys[0];
1661            var isMax = key === edgeKeys[1];
1662            if (!isDown && !isUp && !isMin && !isMax) {
1663                return true;
1664            }
1665            event.preventDefault();
1666            var to;
1667            if (isUp || isDown) {
1668                var direction = isDown ? 0 : 1;
1669                var steps = getNextStepsForHandle(handleNumber);
1670                var step = steps[direction];
1671                // At the edge of a slider, do nothing
1672                if (step === null) {
1673                    return false;
1674                }
1675                // No step set, use the default of 10% of the sub-range
1676                if (step === false) {
1677                    step = scope_Spectrum.getDefaultStep(scope_Locations[handleNumber], isDown, options.keyboardDefaultStep);
1678                }
1679                if (isLargeUp || isLargeDown) {
1680                    step *= options.keyboardPageMultiplier;
1681                }
1682                else {
1683                    step *= options.keyboardMultiplier;
1684                }
1685                // Step over zero-length ranges (#948);
1686                step = Math.max(step, 0.0000001);
1687                // Decrement for down steps
1688                step = (isDown ? -1 : 1) * step;
1689                to = scope_Values[handleNumber] + step;
1690            }
1691            else if (isMax) {
1692                // End key
1693                to = options.spectrum.xVal[options.spectrum.xVal.length - 1];
1694            }
1695            else {
1696                // Home key
1697                to = options.spectrum.xVal[0];
1698            }
1699            setHandle(handleNumber, scope_Spectrum.toStepping(to), true, true);
1700            fireEvent("slide", handleNumber);
1701            fireEvent("update", handleNumber);
1702            fireEvent("change", handleNumber);
1703            fireEvent("set", handleNumber);
1704            return false;
1705        }
1706        // Attach events to several slider parts.
1707        function bindSliderEvents(behaviour) {
1708            // Attach the standard drag event to the handles.
1709            if (!behaviour.fixed) {
1710                scope_Handles.forEach(function (handle, index) {
1711                    // These events are only bound to the visual handle
1712                    // element, not the 'real' origin element.
1713                    attachEvent(actions.start, handle.children[0], eventStart, {
1714                        handleNumbers: [index],
1715                    });
1716                });
1717            }
1718            // Attach the tap event to the slider base.
1719            if (behaviour.tap) {
1720                attachEvent(actions.start, scope_Base, eventTap, {});
1721            }
1722            // Fire hover events
1723            if (behaviour.hover) {
1724                attachEvent(actions.move, scope_Base, eventHover, {
1725                    hover: true,
1726                });
1727            }
1728            // Make the range draggable.
1729            if (behaviour.drag) {
1730                scope_Connects.forEach(function (connect, index) {
1731                    if (connect === false || index === 0 || index === scope_Connects.length - 1) {
1732                        return;
1733                    }
1734                    var handleBefore = scope_Handles[index - 1];
1735                    var handleAfter = scope_Handles[index];
1736                    var eventHolders = [connect];
1737                    var handlesToDrag = [handleBefore, handleAfter];
1738                    var handleNumbersToDrag = [index - 1, index];
1739                    addClass(connect, options.cssClasses.draggable);
1740                    // When the range is fixed, the entire range can
1741                    // be dragged by the handles. The handle in the first
1742                    // origin will propagate the start event upward,
1743                    // but it needs to be bound manually on the other.
1744                    if (behaviour.fixed) {
1745                        eventHolders.push(handleBefore.children[0]);
1746                        eventHolders.push(handleAfter.children[0]);
1747                    }
1748                    if (behaviour.dragAll) {
1749                        handlesToDrag = scope_Handles;
1750                        handleNumbersToDrag = scope_HandleNumbers;
1751                    }
1752                    eventHolders.forEach(function (eventHolder) {
1753                        attachEvent(actions.start, eventHolder, eventStart, {
1754                            handles: handlesToDrag,
1755                            handleNumbers: handleNumbersToDrag,
1756                            connect: connect,
1757                        });
1758                    });
1759                });
1760            }
1761        }
1762        // Attach an event to this slider, possibly including a namespace
1763        function bindEvent(namespacedEvent, callback) {
1764            scope_Events[namespacedEvent] = scope_Events[namespacedEvent] || [];
1765            scope_Events[namespacedEvent].push(callback);
1766            // If the event bound is 'update,' fire it immediately for all handles.
1767            if (namespacedEvent.split(".")[0] === "update") {
1768                scope_Handles.forEach(function (a, index) {
1769                    fireEvent("update", index);
1770                });
1771            }
1772        }
1773        function isInternalNamespace(namespace) {
1774            return namespace === INTERNAL_EVENT_NS.aria || namespace === INTERNAL_EVENT_NS.tooltips;
1775        }
1776        // Undo attachment of event
1777        function removeEvent(namespacedEvent) {
1778            var event = namespacedEvent && namespacedEvent.split(".")[0];
1779            var namespace = event ? namespacedEvent.substring(event.length) : namespacedEvent;
1780            Object.keys(scope_Events).forEach(function (bind) {
1781                var tEvent = bind.split(".")[0];
1782                var tNamespace = bind.substring(tEvent.length);
1783                if ((!event || event === tEvent) && (!namespace || namespace === tNamespace)) {
1784                    // only delete protected internal event if intentional
1785                    if (!isInternalNamespace(tNamespace) || namespace === tNamespace) {
1786                        delete scope_Events[bind];
1787                    }
1788                }
1789            });
1790        }
1791        // External event handling
1792        function fireEvent(eventName, handleNumber, tap) {
1793            Object.keys(scope_Events).forEach(function (targetEvent) {
1794                var eventType = targetEvent.split(".")[0];
1795                if (eventName === eventType) {
1796                    scope_Events[targetEvent].forEach(function (callback) {
1797                        callback.call(
1798                        // Use the slider public API as the scope ('this')
1799                        scope_Self, 
1800                        // Return values as array, so arg_1[arg_2] is always valid.
1801                        scope_Values.map(options.format.to), 
1802                        // Handle index, 0 or 1
1803                        handleNumber, 
1804                        // Un-formatted slider values
1805                        scope_Values.slice(), 
1806                        // Event is fired by tap, true or false
1807                        tap || false, 
1808                        // Left offset of the handle, in relation to the slider
1809                        scope_Locations.slice(), 
1810                        // add the slider public API to an accessible parameter when this is unavailable
1811                        scope_Self);
1812                    });
1813                }
1814            });
1815        }
1816        // Split out the handle positioning logic so the Move event can use it, too
1817        function checkHandlePosition(reference, handleNumber, to, lookBackward, lookForward, getValue, smoothSteps) {
1818            var distance;
1819            // For sliders with multiple handles, limit movement to the other handle.
1820            // Apply the margin option by adding it to the handle positions.
1821            if (scope_Handles.length > 1 && !options.events.unconstrained) {
1822                if (lookBackward && handleNumber > 0) {
1823                    distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber - 1], options.margin, false);
1824                    to = Math.max(to, distance);
1825                }
1826                if (lookForward && handleNumber < scope_Handles.length - 1) {
1827                    distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber + 1], options.margin, true);
1828                    to = Math.min(to, distance);
1829                }
1830            }
1831            // The limit option has the opposite effect, limiting handles to a
1832            // maximum distance from another. Limit must be > 0, as otherwise
1833            // handles would be unmovable.
1834            if (scope_Handles.length > 1 && options.limit) {
1835                if (lookBackward && handleNumber > 0) {
1836                    distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber - 1], options.limit, false);
1837                    to = Math.min(to, distance);
1838                }
1839                if (lookForward && handleNumber < scope_Handles.length - 1) {
1840                    distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber + 1], options.limit, true);
1841                    to = Math.max(to, distance);
1842                }
1843            }
1844            // The padding option keeps the handles a certain distance from the
1845            // edges of the slider. Padding must be > 0.
1846            if (options.padding) {
1847                if (handleNumber === 0) {
1848                    distance = scope_Spectrum.getAbsoluteDistance(0, options.padding[0], false);
1849                    to = Math.max(to, distance);
1850                }
1851                if (handleNumber === scope_Handles.length - 1) {
1852                    distance = scope_Spectrum.getAbsoluteDistance(100, options.padding[1], true);
1853                    to = Math.min(to, distance);
1854                }
1855            }
1856            if (!smoothSteps) {
1857                to = scope_Spectrum.getStep(to);
1858            }
1859            // Limit percentage to the 0 - 100 range
1860            to = limit(to);
1861            // Return false if handle can't move
1862            if (to === reference[handleNumber] && !getValue) {
1863                return false;
1864            }
1865            return to;
1866        }
1867        // Uses slider orientation to create CSS rules. a = base value;
1868        function inRuleOrder(v, a) {
1869            var o = options.ort;
1870            return (o ? a : v) + ", " + (o ? v : a);
1871        }
1872        // Moves handle(s) by a percentage
1873        // (bool, % to move, [% where handle started, ...], [index in scope_Handles, ...])
1874        function moveHandles(upward, proposal, locations, handleNumbers, connect) {
1875            var proposals = locations.slice();
1876            // Store first handle now, so we still have it in case handleNumbers is reversed
1877            var firstHandle = handleNumbers[0];
1878            var smoothSteps = options.events.smoothSteps;
1879            var b = [!upward, upward];
1880            var f = [upward, !upward];
1881            // Copy handleNumbers so we don't change the dataset
1882            handleNumbers = handleNumbers.slice();
1883            // Check to see which handle is 'leading'.
1884            // If that one can't move the second can't either.
1885            if (upward) {
1886                handleNumbers.reverse();
1887            }
1888            // Step 1: get the maximum percentage that any of the handles can move
1889            if (handleNumbers.length > 1) {
1890                handleNumbers.forEach(function (handleNumber, o) {
1891                    var to = checkHandlePosition(proposals, handleNumber, proposals[handleNumber] + proposal, b[o], f[o], false, smoothSteps);
1892                    // Stop if one of the handles can't move.
1893                    if (to === false) {
1894                        proposal = 0;
1895                    }
1896                    else {
1897                        proposal = to - proposals[handleNumber];
1898                        proposals[handleNumber] = to;
1899                    }
1900                });
1901            }
1902            // If using one handle, check backward AND forward
1903            else {
1904                b = f = [true];
1905            }
1906            var state = false;
1907            // Step 2: Try to set the handles with the found percentage
1908            handleNumbers.forEach(function (handleNumber, o) {
1909                state =
1910                    setHandle(handleNumber, locations[handleNumber] + proposal, b[o], f[o], false, smoothSteps) || state;
1911            });
1912            // Step 3: If a handle moved, fire events
1913            if (state) {
1914                handleNumbers.forEach(function (handleNumber) {
1915                    fireEvent("update", handleNumber);
1916                    fireEvent("slide", handleNumber);
1917                });
1918                // If target is a connect, then fire drag event
1919                if (connect != undefined) {
1920                    fireEvent("drag", firstHandle);
1921                }
1922            }
1923        }
1924        // Takes a base value and an offset. This offset is used for the connect bar size.
1925        // In the initial design for this feature, the origin element was 1% wide.
1926        // Unfortunately, a rounding bug in Chrome makes it impossible to implement this feature
1927        // in this manner: https://bugs.chromium.org/p/chromium/issues/detail?id=798223
1928        function transformDirection(a, b) {
1929            return options.dir ? 100 - a - b : a;
1930        }
1931        // Updates scope_Locations and scope_Values, updates visual state
1932        function updateHandlePosition(handleNumber, to) {
1933            // Update locations.
1934            scope_Locations[handleNumber] = to;
1935            // Convert the value to the slider stepping/range.
1936            scope_Values[handleNumber] = scope_Spectrum.fromStepping(to);
1937            var translation = transformDirection(to, 0) - scope_DirOffset;
1938            var translateRule = "translate(" + inRuleOrder(translation + "%", "0") + ")";
1939            scope_Handles[handleNumber].style[options.transformRule] = translateRule;
1940            // sanity check for at least 2 handles (e.g. during setup)
1941            if (options.events.invertConnects && scope_Locations.length > 1) {
1942                // check if handles passed each other, but don't match the ConnectsInverted state
1943                var handlesAreInOrder = scope_Locations.every(function (position, index, locations) {
1944                    return index === 0 || position >= locations[index - 1];
1945                });
1946                if (scope_ConnectsInverted !== !handlesAreInOrder) {
1947                    // invert connects when handles pass each other
1948                    invertConnects();
1949                    // invertConnects already updates all connect elements
1950                    return;
1951                }
1952            }
1953            updateConnect(handleNumber);
1954            updateConnect(handleNumber + 1);
1955            if (scope_ConnectsInverted) {
1956                // When connects are inverted, we also have to update adjacent connects
1957                updateConnect(handleNumber - 1);
1958                updateConnect(handleNumber + 2);
1959            }
1960        }
1961        // Handles before the slider middle are stacked later = higher,
1962        // Handles after the middle later is lower
1963        // [[7] [8] .......... | .......... [5] [4]
1964        function setZindex() {
1965            scope_HandleNumbers.forEach(function (handleNumber) {
1966                var dir = scope_Locations[handleNumber] > 50 ? -1 : 1;
1967                var zIndex = 3 + (scope_Handles.length + dir * handleNumber);
1968                scope_Handles[handleNumber].style.zIndex = String(zIndex);
1969            });
1970        }
1971        // Test suggested values and apply margin, step.
1972        // if exactInput is true, don't run checkHandlePosition, then the handle can be placed in between steps (#436)
1973        function setHandle(handleNumber, to, lookBackward, lookForward, exactInput, smoothSteps) {
1974            if (!exactInput) {
1975                to = checkHandlePosition(scope_Locations, handleNumber, to, lookBackward, lookForward, false, smoothSteps);
1976            }
1977            if (to === false) {
1978                return false;
1979            }
1980            updateHandlePosition(handleNumber, to);
1981            return true;
1982        }
1983        // Updates style attribute for connect nodes
1984        function updateConnect(index) {
1985            // Skip connects set to false
1986            if (!scope_Connects[index]) {
1987                return;
1988            }
1989            // Create a copy of locations, so we can sort them for the local scope logic
1990            var locations = scope_Locations.slice();
1991            if (scope_ConnectsInverted) {
1992                locations.sort(function (a, b) {
1993                    return a - b;
1994                });
1995            }
1996            var l = 0;
1997            var h = 100;
1998            if (index !== 0) {
1999                l = locations[index - 1];
2000            }
2001            if (index !== scope_Connects.length - 1) {
2002                h = locations[index];
2003            }
2004            // We use two rules:
2005            // 'translate' to change the left/top offset;
2006            // 'scale' to change the width of the element;
2007            // As the element has a width of 100%, a translation of 100% is equal to 100% of the parent (.noUi-base)
2008            var connectWidth = h - l;
2009            var translateRule = "translate(" + inRuleOrder(transformDirection(l, connectWidth) + "%", "0") + ")";
2010            var scaleRule = "scale(" + inRuleOrder(connectWidth / 100, "1") + ")";
2011            scope_Connects[index].style[options.transformRule] =
2012                translateRule + " " + scaleRule;
2013        }
2014        // Parses value passed to .set method. Returns current value if not parse-able.
2015        function resolveToValue(to, handleNumber) {
2016            // Setting with null indicates an 'ignore'.
2017            // Inputting 'false' is invalid.
2018            if (to === null || to === false || to === undefined) {
2019                return scope_Locations[handleNumber];
2020            }
2021            // If a formatted number was passed, attempt to decode it.
2022            if (typeof to === "number") {
2023                to = String(to);
2024            }
2025            to = options.format.from(to);
2026            if (to !== false) {
2027                to = scope_Spectrum.toStepping(to);
2028            }
2029            // If parsing the number failed, use the current value.
2030            if (to === false || isNaN(to)) {
2031                return scope_Locations[handleNumber];
2032            }
2033            return to;
2034        }
2035        // Set the slider value.
2036        function valueSet(input, fireSetEvent, exactInput) {
2037            var values = asArray(input);
2038            var isInit = scope_Locations[0] === undefined;
2039            // Event fires by default
2040            fireSetEvent = fireSetEvent === undefined ? true : fireSetEvent;
2041            // Animation is optional.
2042            // Make sure the initial values were set before using animated placement.
2043            if (options.animate && !isInit) {
2044                addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration);
2045            }
2046            // First pass, without lookAhead but with lookBackward. Values are set from left to right.
2047            scope_HandleNumbers.forEach(function (handleNumber) {
2048                setHandle(handleNumber, resolveToValue(values[handleNumber], handleNumber), true, false, exactInput);
2049            });
2050            var i = scope_HandleNumbers.length === 1 ? 0 : 1;
2051            // Spread handles evenly across the slider if the range has no size (min=max)
2052            if (isInit && scope_Spectrum.hasNoSize()) {
2053                exactInput = true;
2054                scope_Locations[0] = 0;
2055                if (scope_HandleNumbers.length > 1) {
2056                    var space_1 = 100 / (scope_HandleNumbers.length - 1);
2057                    scope_HandleNumbers.forEach(function (handleNumber) {
2058                        scope_Locations[handleNumber] = handleNumber * space_1;
2059                    });
2060                }
2061            }
2062            // Secondary passes. Now that all base values are set, apply constraints.
2063            // Iterate all handles to ensure constraints are applied for the entire slider (Issue #1009)
2064            for (; i < scope_HandleNumbers.length; ++i) {
2065                scope_HandleNumbers.forEach(function (handleNumber) {
2066                    setHandle(handleNumber, scope_Locations[handleNumber], true, true, exactInput);
2067                });
2068            }
2069            setZindex();
2070            scope_HandleNumbers.forEach(function (handleNumber) {
2071                fireEvent("update", handleNumber);
2072                // Fire the event only for handles that received a new value, as per #579
2073                if (values[handleNumber] !== null && fireSetEvent) {
2074                    fireEvent("set", handleNumber);
2075                }
2076            });
2077        }
2078        // Reset slider to initial values
2079        function valueReset(fireSetEvent) {
2080            valueSet(options.start, fireSetEvent);
2081        }
2082        // Set value for a single handle
2083        function valueSetHandle(handleNumber, value, fireSetEvent, exactInput) {
2084            // Ensure numeric input
2085            handleNumber = Number(handleNumber);
2086            if (!(handleNumber >= 0 && handleNumber < scope_HandleNumbers.length)) {
2087                throw new Error("noUiSlider: invalid handle number, got: " + handleNumber);
2088            }
2089            // Look both backward and forward, since we don't want this handle to "push" other handles (#960);
2090            // The exactInput argument can be used to ignore slider stepping (#436)
2091            setHandle(handleNumber, resolveToValue(value, handleNumber), true, true, exactInput);
2092            fireEvent("update", handleNumber);
2093            if (fireSetEvent) {
2094                fireEvent("set", handleNumber);
2095            }
2096        }
2097        // Get the slider value.
2098        function valueGet(unencoded) {
2099            if (unencoded === void 0) { unencoded = false; }
2100            if (unencoded) {
2101                // return a copy of the raw values
2102                return scope_Values.length === 1 ? scope_Values[0] : scope_Values.slice(0);
2103            }
2104            var values = scope_Values.map(options.format.to);
2105            // If only one handle is used, return a single value.
2106            if (values.length === 1) {
2107                return values[0];
2108            }
2109            return values;
2110        }
2111        // Removes classes from the root and empties it.
2112        function destroy() {
2113            // remove protected internal listeners
2114            removeEvent(INTERNAL_EVENT_NS.aria);
2115            removeEvent(INTERNAL_EVENT_NS.tooltips);
2116            Object.keys(options.cssClasses).forEach(function (key) {
2117                removeClass(scope_Target, options.cssClasses[key]);
2118            });
2119            while (scope_Target.firstChild) {
2120                scope_Target.removeChild(scope_Target.firstChild);
2121            }
2122            delete scope_Target.noUiSlider;
2123        }
2124        function getNextStepsForHandle(handleNumber) {
2125            var location = scope_Locations[handleNumber];
2126            var nearbySteps = scope_Spectrum.getNearbySteps(location);
2127            var value = scope_Values[handleNumber];
2128            var increment = nearbySteps.thisStep.step;
2129            var decrement = null;
2130            // If snapped, directly use defined step value
2131            if (options.snap) {
2132                return [
2133                    value - nearbySteps.stepBefore.startValue || null,
2134                    nearbySteps.stepAfter.startValue - value || null,
2135                ];
2136            }
2137            // If the next value in this step moves into the next step,
2138            // the increment is the start of the next step - the current value
2139            if (increment !== false) {
2140                if (value + increment > nearbySteps.stepAfter.startValue) {
2141                    increment = nearbySteps.stepAfter.startValue - value;
2142                }
2143            }
2144            // If the value is beyond the starting point
2145            if (value > nearbySteps.thisStep.startValue) {
2146                decrement = nearbySteps.thisStep.step;
2147            }
2148            else if (nearbySteps.stepBefore.step === false) {
2149                decrement = false;
2150            }
2151            // If a handle is at the start of a step, it always steps back into the previous step first
2152            else {
2153                decrement = value - nearbySteps.stepBefore.highestStep;
2154            }
2155            // Now, if at the slider edges, there is no in/decrement
2156            if (location === 100) {
2157                increment = null;
2158            }
2159            else if (location === 0) {
2160                decrement = null;
2161            }
2162            // As per #391, the comparison for the decrement step can have some rounding issues.
2163            var stepDecimals = scope_Spectrum.countStepDecimals();
2164            // Round per #391
2165            if (increment !== null && increment !== false) {
2166                increment = Number(increment.toFixed(stepDecimals));
2167            }
2168            if (decrement !== null && decrement !== false) {
2169                decrement = Number(decrement.toFixed(stepDecimals));
2170            }
2171            return [decrement, increment];
2172        }
2173        // Get the current step size for the slider.
2174        function getNextSteps() {
2175            return scope_HandleNumbers.map(getNextStepsForHandle);
2176        }
2177        // Updatable: margin, limit, padding, step, range, animate, snap
2178        function updateOptions(optionsToUpdate, fireSetEvent) {
2179            // Spectrum is created using the range, snap, direction and step options.
2180            // 'snap' and 'step' can be updated.
2181            // If 'snap' and 'step' are not passed, they should remain unchanged.
2182            var v = valueGet();
2183            var updateAble = [
2184                "margin",
2185                "limit",
2186                "padding",
2187                "range",
2188                "animate",
2189                "snap",
2190                "step",
2191                "format",
2192                "pips",
2193                "tooltips",
2194                "connect",
2195            ];
2196            // Only change options that we're actually passed to update.
2197            updateAble.forEach(function (name) {
2198                // Check for undefined. null removes the value.
2199                if (optionsToUpdate[name] !== undefined) {
2200                    originalOptions[name] = optionsToUpdate[name];
2201                }
2202            });
2203            var newOptions = testOptions(originalOptions);
2204            // Load new options into the slider state
2205            updateAble.forEach(function (name) {
2206                if (optionsToUpdate[name] !== undefined) {
2207                    options[name] = newOptions[name];
2208                }
2209            });
2210            scope_Spectrum = newOptions.spectrum;
2211            // Limit, margin and padding depend on the spectrum but are stored outside of it. (#677)
2212            options.margin = newOptions.margin;
2213            options.limit = newOptions.limit;
2214            options.padding = newOptions.padding;
2215            // Update pips, removes existing.
2216            if (options.pips) {
2217                pips(options.pips);
2218            }
2219            else {
2220                removePips();
2221            }
2222            // Update tooltips, removes existing.
2223            if (options.tooltips) {
2224                tooltips();
2225            }
2226            else {
2227                removeTooltips();
2228            }
2229            // Invalidate the current positioning so valueSet forces an update.
2230            scope_Locations = [];
2231            valueSet(isSet(optionsToUpdate.start) ? optionsToUpdate.start : v, fireSetEvent);
2232            // Update connects only if it was set
2233            if (optionsToUpdate.connect) {
2234                updateConnectOption();
2235            }
2236        }
2237        function updateConnectOption() {
2238            // IE supported way of removing children including event handlers
2239            while (scope_ConnectBase.firstChild) {
2240                scope_ConnectBase.removeChild(scope_ConnectBase.firstChild);
2241            }
2242            // Adding new connects according to the new connect options
2243            for (var i = 0; i <= options.handles; i++) {
2244                scope_Connects[i] = addConnect(scope_ConnectBase, options.connect[i]);
2245                updateConnect(i);
2246            }
2247            // re-adding drag events for the new connect elements
2248            // to ignore the other events we have to negate the 'if (!behaviour.fixed)' check
2249            bindSliderEvents({ drag: options.events.drag, fixed: true });
2250        }
2251        // Invert options for connect handles
2252        function invertConnects() {
2253            scope_ConnectsInverted = !scope_ConnectsInverted;
2254            testConnect(options, 
2255            // inverse the connect boolean array
2256            options.connect.map(function (b) { return !b; }));
2257            updateConnectOption();
2258        }
2259        // Initialization steps
2260        function setupSlider() {
2261            // Create the base element, initialize HTML and set classes.
2262            // Add handles and connect elements.
2263            scope_Base = addSlider(scope_Target);
2264            addElements(options.connect, scope_Base);
2265            // Attach user events.
2266            bindSliderEvents(options.events);
2267            // Use the public value method to set the start values.
2268            valueSet(options.start);
2269            if (options.pips) {
2270                pips(options.pips);
2271            }
2272            if (options.tooltips) {
2273                tooltips();
2274            }
2275            aria();
2276        }
2277        setupSlider();
2278        var scope_Self = {
2279            destroy: destroy,
2280            steps: getNextSteps,
2281            on: bindEvent,
2282            off: removeEvent,
2283            get: valueGet,
2284            set: valueSet,
2285            setHandle: valueSetHandle,
2286            reset: valueReset,
2287            disable: disable,
2288            enable: enable,
2289            // Exposed for unit testing, don't use this in your application.
2290            __moveHandles: function (upward, proposal, handleNumbers) {
2291                moveHandles(upward, proposal, scope_Locations, handleNumbers);
2292            },
2293            options: originalOptions,
2294            updateOptions: updateOptions,
2295            target: scope_Target,
2296            removePips: removePips,
2297            removeTooltips: removeTooltips,
2298            getPositions: function () {
2299                return scope_Locations.slice();
2300            },
2301            getTooltips: function () {
2302                return scope_Tooltips;
2303            },
2304            getOrigins: function () {
2305                return scope_Handles;
2306            },
2307            pips: pips, // Issue #594
2308        };
2309        return scope_Self;
2310    }
2311    // Run the standard initializer
2312    function initialize(target, originalOptions) {
2313        if (!target || !target.nodeName) {
2314            throw new Error("noUiSlider: create requires a single element, got: " + target);
2315        }
2316        // Throw an error if the slider was already initialized.
2317        if (target.noUiSlider) {
2318            throw new Error("noUiSlider: Slider was already initialized.");
2319        }
2320        // Test the options and create the slider environment;
2321        var options = testOptions(originalOptions);
2322        var api = scope(target, options, originalOptions);
2323        target.noUiSlider = api;
2324        return api;
2325    }
2326    var nouislider = {
2327        // Exposed for unit testing, don't use this in your application.
2328        __spectrum: Spectrum,
2329        // A reference to the default classes, allows global changes.
2330        // Use the cssClasses option for changes to one slider.
2331        cssClasses: cssClasses,
2332        create: initialize,
2333    };
2334
2335    exports.create = initialize;
2336    exports.cssClasses = cssClasses;
2337    exports["default"] = nouislider;
2338
2339    Object.defineProperty(exports, '__esModule', { value: true });
2340
2341}));

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.