text: // randomColor by David Merfield under the CC0 license
  // https://github.com/davidmerfield/randomColor/
  
  ;(function(root, factory) {
  
      // Support CommonJS
      if (typeof exports === 'object') {
          var randomColor = factory();
  
          // Support NodeJS & Component, which allow module.exports to be a function
          if (typeof module === 'object' && module && module.exports) {
              exports = module.exports = randomColor;
          }
  
          // Support CommonJS 1.1.1 spec
          exports.randomColor = randomColor;
  
          // Support AMD
      } else if (typeof define === 'function' && define.amd) {
          define([], factory);
  
          // Support vanilla script loading
      } else {
          root.randomColor = factory();
      }
  
  }(this, function() {
  
      // Seed to get repeatable colors
      var seed = null;
  
      // Shared color dictionary
      var colorDictionary = {};
  
      // Populate the color dictionary
      loadColorBounds();
  
      // check if a range is taken
      var colorRanges = [];
  
      var randomColor = function (options) {
  
          options = options || {};
  
          // Check if there is a seed and ensure it's an
          // integer. Otherwise, reset the seed value.
          if (options.seed !== undefined && options.seed !== null && options.seed === parseInt(options.seed, 10)) {
              seed = options.seed;
  
              // A string was passed as a seed
          } else if (typeof options.seed === 'string') {
              seed = stringToInteger(options.seed);
  
              // Something was passed as a seed but it wasn't an integer or string
          } else if (options.seed !== undefined && options.seed !== null) {
              throw new TypeError('The seed value must be an integer or string');
  
              // No seed, reset the value outside.
          } else {
              seed = null;
          }
  
          var H,S,B;
  
          // Check if we need to generate multiple colors
          if (options.count !== null && options.count !== undefined) {
  
              var totalColors = options.count,
                  colors = [];
              // Value false at index i means the range i is not taken yet.
              for (var i = 0; i < options.count; i++) {
                  colorRanges.push(false)
              }
              options.count = null;
  
              while (totalColors > colors.length) {
  
                  // Since we're generating multiple colors,
                  // incremement the seed. Otherwise we'd just
                  // generate the same color each time...
                  if (seed && options.seed) options.seed += 1;
  
                  colors.push(randomColor(options));
              }
  
              options.count = totalColors;
  
              return colors;
          }
  
          // First we pick a hue (H)
          H = pickHue(options);
  
          // Then use H to determine saturation (S)
          S = pickSaturation(H, options);
  
          // Then use S and H to determine brightness (B).
          B = pickBrightness(H, S, options);
  
          // Then we return the HSB color in the desired format
          return setFormat([H,S,B], options);
      };
  
      function pickHue(options) {
          if (colorRanges.length > 0) {
              var hueRange = getRealHueRange(options.hue)
  
              var hue = randomWithin(hueRange)
  
              //Each of colorRanges.length ranges has a length equal approximatelly one step
              var step = (hueRange[1] - hueRange[0]) / colorRanges.length
  
              var j = parseInt((hue - hueRange[0]) / step)
  
              //Check if the range j is taken
              if (colorRanges[j] === true) {
                  j = (j + 2) % colorRanges.length
              }
              else {
                  colorRanges[j] = true
              }
  
              var min = (hueRange[0] + j * step) % 359,
                  max = (hueRange[0] + (j + 1) * step) % 359;
  
              hueRange = [min, max]
  
              hue = randomWithin(hueRange)
  
              if (hue < 0) {hue = 360 + hue;}
              return hue
          }
          else {
              var hueRange = getHueRange(options.hue)
  
              hue = randomWithin(hueRange);
              // Instead of storing red as two seperate ranges,
              // we group them, using negative numbers
              if (hue < 0) {
                  hue = 360 + hue;
              }
  
              return hue;
          }
      }
  
      function pickSaturation (hue, options) {
  
          if (options.hue === 'monochrome') {
              return 0;
          }
  
          if (options.luminosity === 'random') {
              return randomWithin([0,100]);
          }
  
          var saturationRange = getSaturationRange(hue);
  
          var sMin = saturationRange[0],
              sMax = saturationRange[1];
  
          switch (options.luminosity) {
  
              case 'bright':
                  sMin = 55;
                  break;
  
              case 'dark':
                  sMin = sMax - 10;
                  break;
  
              case 'light':
                  sMax = 55;
                  break;
          }
  
          return randomWithin([sMin, sMax]);
  
      }
  
      function pickBrightness (H, S, options) {
  
          var bMin = getMinimumBrightness(H, S),
              bMax = 100;
  
          switch (options.luminosity) {
  
              case 'dark':
                  bMax = bMin + 20;
                  break;
  
              case 'light':
                  bMin = (bMax + bMin)/2;
                  break;
  
              case 'random':
                  bMin = 0;
                  bMax = 100;
                  break;
          }
  
          return randomWithin([bMin, bMax]);
      }
  
      function setFormat (hsv, options) {
  
          switch (options.format) {
  
              case 'hsvArray':
                  return hsv;
  
              case 'hslArray':
                  return HSVtoHSL(hsv);
  
              case 'hsl':
                  var hsl = HSVtoHSL(hsv);
                  return 'hsl('+hsl[0]+', '+hsl[1]+'%, '+hsl[2]+'%)';
  
              case 'hsla':
                  var hslColor = HSVtoHSL(hsv);
                  var alpha = options.alpha || Math.random();
                  return 'hsla('+hslColor[0]+', '+hslColor[1]+'%, '+hslColor[2]+'%, ' + alpha + ')';
  
              case 'rgbArray':
                  return HSVtoRGB(hsv);
  
              case 'rgb':
                  var rgb = HSVtoRGB(hsv);
                  return 'rgb(' + rgb.join(', ') + ')';
  
              case 'rgba':
                  var rgbColor = HSVtoRGB(hsv);
                  var alpha = options.alpha || Math.random();
                  return 'rgba(' + rgbColor.join(', ') + ', ' + alpha + ')';
  
              default:
                  return HSVtoHex(hsv);
          }
  
      }
  
      function getMinimumBrightness(H, S) {
  
          var lowerBounds = getColorInfo(H).lowerBounds;
  
          for (var i = 0; i < lowerBounds.length - 1; i++) {
  
              var s1 = lowerBounds[i][0],
                  v1 = lowerBounds[i][1];
  
              var s2 = lowerBounds[i+1][0],
                  v2 = lowerBounds[i+1][1];
  
              if (S >= s1 && S <= s2) {
  
                  var m = (v2 - v1)/(s2 - s1),
                      b = v1 - m*s1;
  
                  return m*S + b;
              }
  
          }
  
          return 0;
      }
  
      function getHueRange (colorInput) {
  
          if (typeof parseInt(colorInput) === 'number') {
  
              var number = parseInt(colorInput);
  
              if (number < 360 && number > 0) {
                  return [number, number];
              }
  
          }
  
          if (typeof colorInput === 'string') {
  
              if (colorDictionary[colorInput]) {
                  var color = colorDictionary[colorInput];
                  if (color.hueRange) {return color.hueRange;}
              } else if (colorInput.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)) {
                  var hue = HexToHSB(colorInput)[0];
                  return [ hue, hue ];
              }
          }
  
          return [0,360];
  
      }
  
      function getSaturationRange (hue) {
          return getColorInfo(hue).saturationRange;
      }
  
      function getColorInfo (hue) {
  
          // Maps red colors to make picking hue easier
          if (hue >= 334 && hue <= 360) {
              hue-= 360;
          }
  
          for (var colorName in colorDictionary) {
              var color = colorDictionary[colorName];
              if (color.hueRange &&
                  hue >= color.hueRange[0] &&
                  hue <= color.hueRange[1]) {
                  return colorDictionary[colorName];
              }
          } return 'Color not found';
      }
  
      function randomWithin (range) {
          if (seed === null) {
              //generate random evenly destinct number from : https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
              var golden_ratio = 0.618033988749895
              var r=Math.random()
              r += golden_ratio
              r %= 1
              return Math.floor(range[0] + r*(range[1] + 1 - range[0]));
          } else {
              //Seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
              var max = range[1] || 1;
              var min = range[0] || 0;
              seed = (seed * 9301 + 49297) % 233280;
              var rnd = seed / 233280.0;
              return Math.floor(min + rnd * (max - min));
          }
      }
  
      function HSVtoHex (hsv){
  
          var rgb = HSVtoRGB(hsv);
  
          function componentToHex(c) {
              var hex = c.toString(16);
              return hex.length == 1 ? '0' + hex : hex;
          }
  
          var hex = '#' + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
  
          return hex;
  
      }
  
      function defineColor (name, hueRange, lowerBounds) {
  
          var sMin = lowerBounds[0][0],
              sMax = lowerBounds[lowerBounds.length - 1][0],
  
              bMin = lowerBounds[lowerBounds.length - 1][1],
              bMax = lowerBounds[0][1];
  
          colorDictionary[name] = {
              hueRange: hueRange,
              lowerBounds: lowerBounds,
              saturationRange: [sMin, sMax],
              brightnessRange: [bMin, bMax]
          };
  
      }
  
      function loadColorBounds () {
  
          defineColor(
              'monochrome',
              null,
              [[0,0],[100,0]]
          );
  
          defineColor(
              'red',
              [-26,18],
              [[20,100],[30,92],[40,89],[50,85],[60,78],[70,70],[80,60],[90,55],[100,50]]
          );
  
          defineColor(
              'orange',
              [19,46],
              [[20,100],[30,93],[40,88],[50,86],[60,85],[70,70],[100,70]]
          );
  
          defineColor(
              'yellow',
              [47,62],
              [[25,100],[40,94],[50,89],[60,86],[70,84],[80,82],[90,80],[100,75]]
          );
  
          defineColor(
              'green',
              [63,178],
              [[30,100],[40,90],[50,85],[60,81],[70,74],[80,64],[90,50],[100,40]]
          );
  
          defineColor(
              'blue',
              [179, 257],
              [[20,100],[30,86],[40,80],[50,74],[60,60],[70,52],[80,44],[90,39],[100,35]]
          );
  
          defineColor(
              'purple',
              [258, 282],
              [[20,100],[30,87],[40,79],[50,70],[60,65],[70,59],[80,52],[90,45],[100,42]]
          );
  
          defineColor(
              'pink',
              [283, 334],
              [[20,100],[30,90],[40,86],[60,84],[80,80],[90,75],[100,73]]
          );
  
      }
  
      function HSVtoRGB (hsv) {
  
          // this doesn't work for the values of 0 and 360
          // here's the hacky fix
          var h = hsv[0];
          if (h === 0) {h = 1;}
          if (h === 360) {h = 359;}
  
          // Rebase the h,s,v values
          h = h/360;
          var s = hsv[1]/100,
              v = hsv[2]/100;
  
          var h_i = Math.floor(h*6),
              f = h * 6 - h_i,
              p = v * (1 - s),
              q = v * (1 - f*s),
              t = v * (1 - (1 - f)*s),
              r = 256,
              g = 256,
              b = 256;
  
          switch(h_i) {
              case 0: r = v; g = t; b = p;  break;
              case 1: r = q; g = v; b = p;  break;
              case 2: r = p; g = v; b = t;  break;
              case 3: r = p; g = q; b = v;  break;
              case 4: r = t; g = p; b = v;  break;
              case 5: r = v; g = p; b = q;  break;
          }
  
          var result = [Math.floor(r*255), Math.floor(g*255), Math.floor(b*255)];
          return result;
      }
  
      function HexToHSB (hex) {
          hex = hex.replace(/^#/, '');
          hex = hex.length === 3 ? hex.replace(/(.)/g, '$1$1') : hex;
  
          var red = parseInt(hex.substr(0, 2), 16) / 255,
              green = parseInt(hex.substr(2, 2), 16) / 255,
              blue = parseInt(hex.substr(4, 2), 16) / 255;
  
          var cMax = Math.max(red, green, blue),
              delta = cMax - Math.min(red, green, blue),
              saturation = cMax ? (delta / cMax) : 0;
  
          switch (cMax) {
              case red: return [ 60 * (((green - blue) / delta) % 6) || 0, saturation, cMax ];
              case green: return [ 60 * (((blue - red) / delta) + 2) || 0, saturation, cMax ];
              case blue: return [ 60 * (((red - green) / delta) + 4) || 0, saturation, cMax ];
          }
      }
  
      function HSVtoHSL (hsv) {
          var h = hsv[0],
              s = hsv[1]/100,
              v = hsv[2]/100,
              k = (2-s)*v;
  
          return [
              h,
              Math.round(s*v / (k<1 ? k : 2-k) * 10000) / 100,
              k/2 * 100
          ];
      }
  
      function stringToInteger (string) {
          var total = 0
          for (var i = 0; i !== string.length; i++) {
              if (total >= Number.MAX_SAFE_INTEGER) break;
              total += string.charCodeAt(i)
          }
          return total
      }
  
      // get The range of given hue when options.count!=0
      function getRealHueRange(colorHue)
      { if (!isNaN(colorHue)) {
          var number = parseInt(colorHue);
  
          if (number < 360 && number > 0) {
              return getColorInfo(colorHue).hueRange
          }
      }
      else if (typeof colorHue === 'string') {
  
          if (colorDictionary[colorHue]) {
              var color = colorDictionary[colorHue];
  
              if (color.hueRange) {
                  return color.hueRange
              }
          } else if (colorHue.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)) {
              var hue = HexToHSB(colorHue)[0]
              return getColorInfo(hue).hueRange
          }
      }
  
          return [0,360]
      }
      return randomColor;
  }));