text: 
  	function getGroup ( mode, values, stepped ) {
  
  		// Use the range.
  		if ( mode === 'range' || mode === 'steps' ) {
  			return scope_Spectrum.xVal;
  		}
  
  		if ( mode === 'count' ) {
  
  			if ( !values ) {
  				throw new Error("noUiSlider (" + VERSION + "): 'values' required for mode 'count'.");
  			}
  
  			// Divide 0 - 100 in 'count' parts.
  			var spread = ( 100 / (values - 1) );
  			var v;
  			var i = 0;
  
  			values = [];
  
  			// List these parts and have them handled as 'positions'.
  			while ( (v = i++ * spread) <= 100 ) {
  				values.push(v);
  			}
  
  			mode = 'positions';
  		}
  
  		if ( mode === 'positions' ) {
  
  			// Map all percentages to on-range values.
  			return values.map(function( value ){
  				return scope_Spectrum.fromStepping( stepped ? scope_Spectrum.getStep( value ) : value );
  			});
  		}
  
  		if ( mode === 'values' ) {
  
  			// If the value must be stepped, it needs to be converted to a percentage first.
  			if ( stepped ) {
  
  				return values.map(function( value ){
  
  					// Convert to percentage, apply step, return to value.
  					return scope_Spectrum.fromStepping( scope_Spectrum.getStep( scope_Spectrum.toStepping( value ) ) );
  				});
  
  			}
  
  			// Otherwise, we can simply use the values.
  			return values;
  		}
  	}
  
  	function generateSpread ( density, mode, group ) {
  
  		function safeIncrement(value, increment) {
  			// Avoid floating point variance by dropping the smallest decimal places.
  			return (value + increment).toFixed(7) / 1;
  		}
  
  		var indexes = {};
  		var firstInRange = scope_Spectrum.xVal[0];
  		var lastInRange = scope_Spectrum.xVal[scope_Spectrum.xVal.length-1];
  		var ignoreFirst = false;
  		var ignoreLast = false;
  		var prevPct = 0;
  
  		// Create a copy of the group, sort it and filter away all duplicates.
  		group = unique(group.slice().sort(function(a, b){ return a - b; }));
  
  		// Make sure the range starts with the first element.
  		if ( group[0] !== firstInRange ) {
  			group.unshift(firstInRange);
  			ignoreFirst = true;
  		}
  
  		// Likewise for the last one.
  		if ( group[group.length - 1] !== lastInRange ) {
  			group.push(lastInRange);
  			ignoreLast = true;
  		}
  
  		group.forEach(function ( current, index ) {
  
  			// Get the current step and the lower + upper positions.
  			var step;
  			var i;
  			var q;
  			var low = current;
  			var high = group[index+1];
  			var newPct;
  			var pctDifference;
  			var pctPos;
  			var type;
  			var steps;
  			var realSteps;
  			var stepsize;
  
  			// When using 'steps' mode, use the provided steps.
  			// Otherwise, we'll step on to the next subrange.
  			if ( mode === 'steps' ) {
  				step = scope_Spectrum.xNumSteps[ index ];
  			}
  
  			// Default to a 'full' step.
  			if ( !step ) {
  				step = high-low;
  			}
  
  			// Low can be 0, so test for false. If high is undefined,
  			// we are at the last subrange. Index 0 is already handled.
  			if ( low === false || high === undefined ) {
  				return;
  			}
  
  			// Make sure step isn't 0, which would cause an infinite loop (#654)
  			step = Math.max(step, 0.0000001);
  
  			// Find all steps in the subrange.
  			for ( i = low; i <= high; i = safeIncrement(i, step) ) {
  
  				// Get the percentage value for the current step,
  				// calculate the size for the subrange.
  				newPct = scope_Spectrum.toStepping( i );
  				pctDifference = newPct - prevPct;
  
  				steps = pctDifference / density;
  				realSteps = Math.round(steps);
  
  				// This ratio represents the ammount of percentage-space a point indicates.
  				// For a density 1 the points/percentage = 1. For density 2, that percentage needs to be re-devided.
  				// Round the percentage offset to an even number, then divide by two
  				// to spread the offset on both sides of the range.
  				stepsize = pctDifference/realSteps;
  
  				// Divide all points evenly, adding the correct number to this subrange.
  				// Run up to <= so that 100% gets a point, event if ignoreLast is set.
  				for ( q = 1; q <= realSteps; q += 1 ) {
  
  					// The ratio between the rounded value and the actual size might be ~1% off.
  					// Correct the percentage offset by the number of points
  					// per subrange. density = 1 will result in 100 points on the
  					// full range, 2 for 50, 4 for 25, etc.
  					pctPos = prevPct + ( q * stepsize );
  					indexes[pctPos.toFixed(5)] = ['x', 0];
  				}
  
  				// Determine the point type.
  				type = (group.indexOf(i) > -1) ? 1 : ( mode === 'steps' ? 2 : 0 );
  
  				// Enforce the 'ignoreFirst' option by overwriting the type for 0.
  				if ( !index && ignoreFirst ) {
  					type = 0;
  				}
  
  				if ( !(i === high && ignoreLast)) {
  					// Mark the 'type' of this point. 0 = plain, 1 = real value, 2 = step value.
  					indexes[newPct.toFixed(5)] = [i, type];
  				}
  
  				// Update the percentage count.
  				prevPct = newPct;
  			}
  		});
  
  		return indexes;
  	}
  
  	function addMarking ( spread, filterFunc, formatter ) {
  
  		var element = document.createElement('div');
  		var out = '';
  		var valueSizeClasses = [
  			options.cssClasses.valueNormal,
  			options.cssClasses.valueLarge,
  			options.cssClasses.valueSub
  		];
  		var markerSizeClasses = [
  			options.cssClasses.markerNormal,
  			options.cssClasses.markerLarge,
  			options.cssClasses.markerSub
  		];
  		var valueOrientationClasses = [
  			options.cssClasses.valueHorizontal,
  			options.cssClasses.valueVertical
  		];
  		var markerOrientationClasses = [
  			options.cssClasses.markerHorizontal,
  			options.cssClasses.markerVertical
  		];
  
  		addClass(element, options.cssClasses.pips);
  		addClass(element, options.ort === 0 ? options.cssClasses.pipsHorizontal : options.cssClasses.pipsVertical);
  
  		function getClasses( type, source ){
  			var a = source === options.cssClasses.value;
  			var orientationClasses = a ? valueOrientationClasses : markerOrientationClasses;
  			var sizeClasses = a ? valueSizeClasses : markerSizeClasses;
  
  			return source + ' ' + orientationClasses[options.ort] + ' ' + sizeClasses[type];
  		}
  
  		function getTags( offset, source, values ) {
  			return 'class="' + getClasses(values[1], source) + '" style="' + options.style + ': ' + offset + '%"';
  		}
  
  		function addSpread ( offset, values ){
  
  			// Apply the filter function, if it is set.
  			values[1] = (values[1] && filterFunc) ? filterFunc(values[0], values[1]) : values[1];
  
  			// Add a marker for every point
  			out += '<div ' + getTags(offset, options.cssClasses.marker, values) + '></div>';
  
  			// Values are only appended for points marked '1' or '2'.
  			if ( values[1] ) {
  				out += '<div ' + getTags(offset, options.cssClasses.value, values) + '>' + formatter.to(values[0]) + '</div>';
  			}
  		}
  
  		// Append all points.
  		Object.keys(spread).forEach(function(a){
  			addSpread(a, spread[a]);
  		});
  
  		element.innerHTML = out;
  
  		return element;
  	}
  
  	function pips ( grid ) {
  
  		var mode = grid.mode;
  		var density = grid.density || 1;
  		var filter = grid.filter || false;
  		var values = grid.values || false;
  		var stepped = grid.stepped || false;
  		var group = getGroup( mode, values, stepped );
  		var spread = generateSpread( density, mode, group );
  		var format = grid.format || {
  			to: Math.round
  		};
  
  		return scope_Target.appendChild(addMarking(
  			spread,
  			filter,
  			format
  		));
  	}
  