/*! nouislider - 13.0.0 - 2/6/2019 */ (function(factory) { if (typeof define === "function" && define.amd) { // AMD. Register as an anonymous module. define([], factory); } else if (typeof exports === "object") { // Node/CommonJS module.exports = factory(); } else { // Browser globals window.noUiSlider = factory(); } })(function() { "use strict"; var VERSION = "13.0.0"; function isValidFormatter(entry) { return typeof entry === "object" && typeof entry.to === "function" && typeof entry.from === "function"; } function removeElement(el) { el.parentElement.removeChild(el); } function isSet(value) { return value !== null && value !== undefined; } // Bindable version function preventDefault(e) { e.preventDefault(); } // Removes duplicates from an array. function unique(array) { return array.filter(function(a) { return !this[a] ? (this[a] = true) : false; }, {}); } // Round a value to the closest 'to'. function closest(value, to) { return Math.round(value / to) * to; } // Current position of an element relative to the document. function offset(elem, orientation) { var rect = elem.getBoundingClientRect(); var doc = elem.ownerDocument; var docElem = doc.documentElement; var pageOffset = getPageOffset(doc); // getBoundingClientRect contains left scroll in Chrome on Android. // I haven't found a feature detection that proves this. Worst case // scenario on mis-match: the 'tap' feature on horizontal sliders breaks. if (/webkit.*Chrome.*Mobile/i.test(navigator.userAgent)) { pageOffset.x = 0; } return orientation ? rect.top + pageOffset.y - docElem.clientTop : rect.left + pageOffset.x - docElem.clientLeft; } // Checks whether a value is numerical. function isNumeric(a) { return typeof a === "number" && !isNaN(a) && isFinite(a); } // Sets a class and removes it after [duration] ms. function addClassFor(element, className, duration) { if (duration > 0) { addClass(element, className); setTimeout(function() { removeClass(element, className); }, duration); } } // Limits a value to 0 - 100 function limit(a) { return Math.max(Math.min(a, 100), 0); } // Wraps a variable as an array, if it isn't one yet. // Note that an input array is returned by reference! function asArray(a) { return Array.isArray(a) ? a : [a]; } // Counts decimals function countDecimals(numStr) { numStr = String(numStr); var pieces = numStr.split("."); return pieces.length > 1 ? pieces[1].length : 0; } // http://youmightnotneedjquery.com/#add_class function addClass(el, className) { if (el.classList) { el.classList.add(className); } else { el.className += " " + className; } } // http://youmightnotneedjquery.com/#remove_class function removeClass(el, className) { if (el.classList) { el.classList.remove(className); } else { el.className = el.className.replace( new RegExp("(^|\\b)" + className.split(" ").join("|") + "(\\b|$)", "gi"), " " ); } } // https://plainjs.com/javascript/attributes/adding-removing-and-testing-for-classes-9/ function hasClass(el, className) { return el.classList ? el.classList.contains(className) : new RegExp("\\b" + className + "\\b").test(el.className); } // https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY#Notes function getPageOffset(doc) { var supportPageOffset = window.pageXOffset !== undefined; var isCSS1Compat = (doc.compatMode || "") === "CSS1Compat"; var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? doc.documentElement.scrollLeft : doc.body.scrollLeft; var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? doc.documentElement.scrollTop : doc.body.scrollTop; return { x: x, y: y }; } // we provide a function to compute constants instead // of accessing window.* as soon as the module needs it // so that we do not compute anything if not needed function getActions() { // Determine the events to bind. IE11 implements pointerEvents without // a prefix, which breaks compatibility with the IE10 implementation. return window.navigator.pointerEnabled ? { start: "pointerdown", move: "pointermove", end: "pointerup" } : window.navigator.msPointerEnabled ? { start: "MSPointerDown", move: "MSPointerMove", end: "MSPointerUp" } : { start: "mousedown touchstart", move: "mousemove touchmove", end: "mouseup touchend" }; } // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md // Issue #785 function getSupportsPassive() { var supportsPassive = false; /* eslint-disable */ try { var opts = Object.defineProperty({}, "passive", { get: function() { supportsPassive = true; } }); window.addEventListener("test", null, opts); } catch (e) {} /* eslint-enable */ return supportsPassive; } function getSupportsTouchActionNone() { return window.CSS && CSS.supports && CSS.supports("touch-action", "none"); } // Value calculation // Determine the size of a sub-range in relation to a full range. function subRangeRatio(pa, pb) { return 100 / (pb - pa); } // (percentage) How many percent is this value of this range? function fromPercentage(range, value) { return (value * 100) / (range[1] - range[0]); } // (percentage) Where is this value on this range? function toPercentage(range, value) { return fromPercentage(range, range[0] < 0 ? value + Math.abs(range[0]) : value - range[0]); } // (value) How much is this percentage on this range? function isPercentage(range, value) { return (value * (range[1] - range[0])) / 100 + range[0]; } // Range conversion function getJ(value, arr) { var j = 1; while (value >= arr[j]) { j += 1; } return j; } // (percentage) Input a value, find where, on a scale of 0-100, it applies. function toStepping(xVal, xPct, value) { if (value >= xVal.slice(-1)[0]) { return 100; } var j = getJ(value, xVal); var va = xVal[j - 1]; var vb = xVal[j]; var pa = xPct[j - 1]; var pb = xPct[j]; return pa + toPercentage([va, vb], value) / subRangeRatio(pa, pb); } // (value) Input a percentage, find where it is on the specified range. function fromStepping(xVal, xPct, value) { // There is no range group that fits 100 if (value >= 100) { return xVal.slice(-1)[0]; } var j = getJ(value, xPct); var va = xVal[j - 1]; var vb = xVal[j]; var pa = xPct[j - 1]; var pb = xPct[j]; return isPercentage([va, vb], (value - pa) * subRangeRatio(pa, pb)); } // (percentage) Get the step that applies at a certain value. function getStep(xPct, xSteps, snap, value) { if (value === 100) { return value; } var j = getJ(value, xPct); var a = xPct[j - 1]; var b = xPct[j]; // If 'snap' is set, steps are used as fixed points on the slider. if (snap) { // Find the closest position, a or b. if (value - a > (b - a) / 2) { return b; } return a; } if (!xSteps[j - 1]) { return value; } return xPct[j - 1] + closest(value - xPct[j - 1], xSteps[j - 1]); } // Entry parsing function handleEntryPoint(index, value, that) { var percentage; // Wrap numerical input in an array. if (typeof value === "number") { value = [value]; } // Reject any invalid input, by testing whether value is an array. if (!Array.isArray(value)) { throw new Error("noUiSlider (" + VERSION + "): 'range' contains invalid value."); } // Covert min/max syntax to 0 and 100. if (index === "min") { percentage = 0; } else if (index === "max") { percentage = 100; } else { percentage = parseFloat(index); } // Check for correct input. if (!isNumeric(percentage) || !isNumeric(value[0])) { throw new Error("noUiSlider (" + VERSION + "): 'range' value isn't numeric."); } // Store values. that.xPct.push(percentage); that.xVal.push(value[0]); // NaN will evaluate to false too, but to keep // logging clear, set step explicitly. Make sure // not to override the 'step' setting with false. if (!percentage) { if (!isNaN(value[1])) { that.xSteps[0] = value[1]; } } else { that.xSteps.push(isNaN(value[1]) ? false : value[1]); } that.xHighestCompleteStep.push(0); } function handleStepPoint(i, n, that) { // Ignore 'false' stepping. if (!n) { return true; } // Factor to range ratio that.xSteps[i] = fromPercentage([that.xVal[i], that.xVal[i + 1]], n) / subRangeRatio(that.xPct[i], that.xPct[i + 1]); var totalSteps = (that.xVal[i + 1] - that.xVal[i]) / that.xNumSteps[i]; var highestStep = Math.ceil(Number(totalSteps.toFixed(3)) - 1); var step = that.xVal[i] + that.xNumSteps[i] * highestStep; that.xHighestCompleteStep[i] = step; } // Interface function Spectrum(entry, snap, singleStep) { this.xPct = []; this.xVal = []; this.xSteps = [singleStep || false]; this.xNumSteps = [false]; this.xHighestCompleteStep = []; this.snap = snap; var index; var ordered = []; // [0, 'min'], [1, '50%'], [2, 'max'] // Map the object keys to an array. for (index in entry) { if (entry.hasOwnProperty(index)) { ordered.push([entry[index], index]); } } // Sort all entries by value (numeric sort). if (ordered.length && typeof ordered[0][0] === "object") { ordered.sort(function(a, b) { return a[0][0] - b[0][0]; }); } else { ordered.sort(function(a, b) { return a[0] - b[0]; }); } // Convert all entries to subranges. for (index = 0; index < ordered.length; index++) { handleEntryPoint(ordered[index][1], ordered[index][0], this); } // Store the actual step values. // xSteps is sorted in the same order as xPct and xVal. this.xNumSteps = this.xSteps.slice(0); // Convert all numeric steps to the percentage of the subrange they represent. for (index = 0; index < this.xNumSteps.length; index++) { handleStepPoint(index, this.xNumSteps[index], this); } } Spectrum.prototype.getMargin = function(value) { var step = this.xNumSteps[0]; if (step && (value / step) % 1 !== 0) { throw new Error("noUiSlider (" + VERSION + "): 'limit', 'mar