library Strings {
  // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol
  function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string) {
      bytes memory _ba = bytes(_a);
      bytes memory _bb = bytes(_b);
      bytes memory _bc = bytes(_c);
      bytes memory _bd = bytes(_d);
      bytes memory _be = bytes(_e);
      string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
      bytes memory babcde = bytes(abcde);
      uint k = 0;
      for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
      for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
      for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
      for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
      for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
      return string(babcde);
    }

    function strConcat(string _a, string _b, string _c, string _d) internal pure returns (string) {
        return strConcat(_a, _b, _c, _d, "");
    }

    function strConcat(string _a, string _b, string _c) internal pure returns (string) {
        return strConcat(_a, _b, _c, "", "");
    }

    function strConcat(string _a, string _b) internal pure returns (string) {
        return strConcat(_a, _b, "", "", "");
    }

    function uint2str(uint i) internal pure returns (string) {
        if (i == 0) return "0";
        uint j = i;
        uint len;
        while (j != 0){
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint k = len - 1;
        while (i != 0){
            bstr[k--] = byte(48 + i % 10);
            i /= 10;
        }
        return string(bstr);
    }
}
/**
 *
 *     ****      *****   **         *****   *******     ****    **     **    ** *******   **     **   ****   
 *   **    **  **     ** **       **     ** **     ** **    **  **      **  **  **     ** **     ** **    ** 
 *   **        **     ** **       **     ** **     ** **        **       ****   **     ** **     ** **       
 *   **        **     ** **       **     ** *******   **   **** **        **    *******   *********   ****   
 *   **        **     ** **       **     ** **   **   **    **  **        **    **        **     **       ** 
 *   **    **  **     ** **       **     ** **    **  **    **  **        **    **        **     ** **    ** 
 *     ****      *****   ********   *****   **     **   ****    ********  **    **        **     **   ****   
 *
 *
 *                                                                by Daniel Viau
 *
 * Colorglyphs extends Autoglyphs.
 * Quoting from Autoglyphs:
 *  The output of the 'tokenURI' function is a set of instructions to make a drawing.
 *  Each symbol in the output corresponds to a cell, and there are 64x64 cells arranged in a square grid.
 *  The drawing can be any size, and the pen's stroke width should be between 1/5th to 1/10th the size of a cell.
 *  The drawing instructions for the nine different symbols are as follows:
 *
 *    .  Draw nothing in the cell.
 *    O  Draw a circle bounded by the cell.
 *    +  Draw centered lines vertically and horizontally the length of the cell.
 *    X  Draw diagonal lines connecting opposite corners of the cell.
 *    |  Draw a centered vertical line the length of the cell.
 *    -  Draw a centered horizontal line the length of the cell.
 *    \  Draw a line connecting the top left corner of the cell to the bottom right corner.
 *    /  Draw a line connecting the bottom left corner of teh cell to the top right corner.
 *    #  Fill in the cell completely.
 *
 * The 'tokenURI' function of colorglyphs adds two pieces of information to the response provided by autoglyphs:
 *  1) The color scheme to apply to the Colorglyph.
 *  2) The address of the Colorglyph's creator, from which colors are derived.
 *
 * The address of the Colorglyph's creator is split up into 35 6 digit chunks.
 * For example, the first three chunks of 0xb189f76323678E094D4996d182A792E52369c005 are: b189f7, 189f76, and 89f763.
 * The last chunk is 69c005.
 * Each Colorglyph is an Autoglyph with a color scheme applied to it.
 * Each Colorglyph takes the same shape as the Autoglyph of the corresponding ID.
 * If the Colorglyph's ID is higher than 512, it takes the shape of the Autoglyph with its Colorglyphs ID - 512.
 * Each black element in the Autoglyph is assigned a new color.
 * The background color of the Autoglyph is changed to either black or one of the address colors.
 * Visual implementations of Colorglyphs may exercise a substantial degree of flexibility.
 * Color schemes that use multiple colors may apply any permitted color to any element,
 * but no color should appear more than 16 times as often as the color with the lowest number of incidences.
 * In the event that a color meets two conditions (reddest and orangest, for example),
 * it may be used for both purposes.  The previous guideline establishing a threshold ratio of occurances
 * treats the reddest color and the orangest color as two different colors, even if they have the same actual value.
 
 * lightest address color = chunk with the lowest value resulting from red value + green value + blue value
 * second lightest address color = second lightest chunk in relevant address
 * third lightest address color = third lightest chunk in relevant address
 * fourth lightest address color = fourth lightest chunk in relevant address
 * fifth lightest address color = fifth lightest chunk in relevant address
 * reddest address color = chunk with the lowest value resulting from red value - green value - blue value
 * orangest address color = chunk with the highest value resulting from red value - blue value
 * yellowest address color = chunk with higest value resulting from red value + green value - blue value
 * greenest address color = chunk with higest value resulting from green value - red value - blue value
 * bluest address color = chunk with higest value resulting from blue value - green value - red value
 * darkest address color = darkest chunk in relevant address
 * white = ffffff
 * black = 020408
 
 * scheme 1 = lightest address color, third lightest address color, and fifth lightest address color on black
 * scheme 2 = lighest 4 address colors on black                            
 * scheme 3 = reddest address color, orangest address color, and yellowest address color on black                                             
 * scheme 4 = reddest address color, yellowest address color, greenest address color, and white on black                                      
 * scheme 5 = lightest address color, reddest address color, yellowest address color, greenest address color, and bluest address color on black                                      
 * scheme 6 = reddest address color and white on black                     
 * scheme 7 = greenest address color on black                              
 * scheme 8 = lightest address color on darkest address color              
 * scheme 9 = greenest address color on reddest address color                                        
 * scheme 10 = reddest address color, yellowest address color, bluest address color, lightest address color, and black on white
 */
function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string) {
    bytes memory _ba = bytes(_a);
    bytes memory _bb = bytes(_b);
    bytes memory _bc = bytes(_c);
    bytes memory _bd = bytes(_d);
    bytes memory _be = bytes(_e);
    string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
    bytes memory babcde = bytes(abcde);
    uint k = 0;
    for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
    for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
    for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
    for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
    for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
    return string(babcde);
  }

// via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol