text: /* qr.js -- QR code generator in Javascript (revision 2011-01-19)
   * Written by Kang Seonghoon <public+qrjs@mearie.org>.
   *
   * This source code is in the public domain; if your jurisdiction does not
   * recognize the public domain the terms of Creative Commons CC0 license
   * apply. In the other words, you can always do what you want.
   */
  (function (root, name, definition) {
    if (typeof define === "function" && define.amd) {
      define([], definition);
    } else if (typeof module === "object" && module.exports) {
      module.exports = definition();
    } else {
      root[name] = definition();
    }
  })(this, "QRCode", function () {
    /* Quick overview: QR code composed of 2D array of modules (a rectangular
     * area that conveys one bit of information); some modules are fixed to help
     * the recognition of the code, and remaining data modules are further divided
     * into 8-bit code words which are augumented by Reed-Solomon error correcting
     * codes (ECC). There could be multiple ECCs, in the case the code is so large
     * that it is helpful to split the raw data into several chunks.
     *
     * The number of modules is determined by the code's "version", ranging from 1
     * (21x21) to 40 (177x177). How many ECC bits are used is determined by the
     * ECC level (L/M/Q/H). The number and size (and thus the order of generator
     * polynomial) of ECCs depend to the version and ECC level.
     */
    // per-version information (cf. JIS X 0510:2004 pp. 30--36, 71)
    //
    // [0]: the degree of generator polynomial by ECC levels
    // [1]: # of code blocks by ECC levels
    // [2]: left-top positions of alignment patterns
    //
    // the number in this table (in particular, [0]) does not exactly match with
    // the numbers in the specficiation. see augumenteccs below for the reason.
    var VERSIONS = [null, [[10, 7, 17, 13], [1, 1, 1, 1], []], [[16, 10, 28, 22], [1, 1, 1, 1], [4, 16]], [[26, 15, 22, 18], [1, 1, 2, 2], [4, 20]], [[18, 20, 16, 26], [2, 1, 4, 2], [4, 24]], [[24, 26, 22, 18], [2, 1, 4, 4], [4, 28]], [[16, 18, 28, 24], [4, 2, 4, 4], [4, 32]], [[18, 20, 26, 18], [4, 2, 5, 6], [4, 20, 36]], [[22, 24, 26, 22], [4, 2, 6, 6], [4, 22, 40]], [[22, 30, 24, 20], [5, 2, 8, 8], [4, 24, 44]], [[26, 18, 28, 24], [5, 4, 8, 8], [4, 26, 48]], [[30, 20, 24, 28], [5, 4, 11, 8], [4, 28, 52]], [[22, 24, 28, 26], [8, 4, 11, 10], [4, 30, 56]], [[22, 26, 22, 24], [9, 4, 16, 12], [4, 32, 60]], [[24, 30, 24, 20], [9, 4, 16, 16], [4, 24, 44, 64]], [[24, 22, 24, 30], [10, 6, 18, 12], [4, 24, 46, 68]], [[28, 24, 30, 24], [10, 6, 16, 17], [4, 24, 48, 72]], [[28, 28, 28, 28], [11, 6, 19, 16], [4, 28, 52, 76]], [[26, 30, 28, 28], [13, 6, 21, 18], [4, 28, 54, 80]], [[26, 28, 26, 26], [14, 7, 25, 21], [4, 28, 56, 84]], [[26, 28, 28, 30], [16, 8, 25, 20], [4, 32, 60, 88]], [[26, 28, 30, 28], [17, 8, 25, 23], [4, 26, 48, 70, 92]], [[28, 28, 24, 30], [17, 9, 34, 23], [4, 24, 48, 72, 96]], [[28, 30, 30, 30], [18, 9, 30, 25], [4, 28, 52, 76, 100]], [[28, 30, 30, 30], [20, 10, 32, 27], [4, 26, 52, 78, 104]], [[28, 26, 30, 30], [21, 12, 35, 29], [4, 30, 56, 82, 108]], [[28, 28, 30, 28], [23, 12, 37, 34], [4, 28, 56, 84, 112]], [[28, 30, 30, 30], [25, 12, 40, 34], [4, 32, 60, 88, 116]], [[28, 30, 30, 30], [26, 13, 42, 35], [4, 24, 48, 72, 96, 120]], [[28, 30, 30, 30], [28, 14, 45, 38], [4, 28, 52, 76, 100, 124]], [[28, 30, 30, 30], [29, 15, 48, 40], [4, 24, 50, 76, 102, 128]], [[28, 30, 30, 30], [31, 16, 51, 43], [4, 28, 54, 80, 106, 132]], [[28, 30, 30, 30], [33, 17, 54, 45], [4, 32, 58, 84, 110, 136]], [[28, 30, 30, 30], [35, 18, 57, 48], [4, 28, 56, 84, 112, 140]], [[28, 30, 30, 30], [37, 19, 60, 51], [4, 32, 60, 88, 116, 144]], [[28, 30, 30, 30], [38, 19, 63, 53], [4, 28, 52, 76, 100, 124, 148]], [[28, 30, 30, 30], [40, 20, 66, 56], [4, 22, 48, 74, 100, 126, 152]], [[28, 30, 30, 30], [43, 21, 70, 59], [4, 26, 52, 78, 104, 130, 156]], [[28, 30, 30, 30], [45, 22, 74, 62], [4, 30, 56, 82, 108, 134, 160]], [[28, 30, 30, 30], [47, 24, 77, 65], [4, 24, 52, 80, 108, 136, 164]], [[28, 30, 30, 30], [49, 25, 81, 68], [4, 28, 56, 84, 112, 140, 168]]]; // mode constants (cf. Table 2 in JIS X 0510:2004 p. 16)
  
    var MODE_TERMINATOR = 0;
    var MODE_NUMERIC = 1,
        MODE_ALPHANUMERIC = 2,
        MODE_OCTET = 4,
        MODE_KANJI = 8; // validation regexps
  
    var NUMERIC_REGEXP = /^\d*$/;
    var ALPHANUMERIC_REGEXP = /^[A-Za-z0-9 $%*+\-./:]*$/;
    var ALPHANUMERIC_OUT_REGEXP = /^[A-Z0-9 $%*+\-./:]*$/; // ECC levels (cf. Table 22 in JIS X 0510:2004 p. 45)
  
    var ECCLEVEL_L = 1,
        ECCLEVEL_M = 0,
        ECCLEVEL_Q = 3,
        ECCLEVEL_H = 2; // GF(2^8)-to-integer mapping with a reducing polynomial x^8+x^4+x^3+x^2+1
    // invariant: GF256_MAP[GF256_INVMAP[i]] == i for all i in [1,256)
  
    var GF256_MAP = [],
        GF256_INVMAP = [-1];
  
    for (var i = 0, v = 1; i < 255; ++i) {
      GF256_MAP.push(v);
      GF256_INVMAP[v] = i;
      v = v * 2 ^ (v >= 128 ? 0x11d : 0);
    } // generator polynomials up to degree 30
    // (should match with polynomials in JIS X 0510:2004 Appendix A)
    //
    // generator polynomial of degree K is product of (x-\alpha^0), (x-\alpha^1),
    // ..., (x-\alpha^(K-1)). by convention, we omit the K-th coefficient (always 1)
    // from the result; also other coefficients are written in terms of the exponent
    // to \alpha to avoid the redundant calculation. (see also calculateecc below.)
  
  
    var GF256_GENPOLY = [[]];
  
    for (var i = 0; i < 30; ++i) {
      var prevpoly = GF256_GENPOLY[i],
          poly = [];
  
      for (var j = 0; j <= i; ++j) {
        var a = j < i ? GF256_MAP[prevpoly[j]] : 0;
        var b = GF256_MAP[(i + (prevpoly[j - 1] || 0)) % 255];
        poly.push(GF256_INVMAP[a ^ b]);
      }
  
      GF256_GENPOLY.push(poly);
    } // alphanumeric character mapping (cf. Table 5 in JIS X 0510:2004 p. 19)
  
  
    var ALPHANUMERIC_MAP = {};
  
    for (var i = 0; i < 45; ++i) {
      ALPHANUMERIC_MAP["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".charAt(i)] = i;
    } // mask functions in terms of row # and column #
    // (cf. Table 20 in JIS X 0510:2004 p. 42)
  
  
    var MASKFUNCS = [function (i, j) {
      return (i + j) % 2 == 0;
    }, function (i, j) {
      return i % 2 == 0;
    }, function (i, j) {
      return j % 3 == 0;
    }, function (i, j) {
      return (i + j) % 3 == 0;
    }, function (i, j) {
      return ((i / 2 | 0) + (j / 3 | 0)) % 2 == 0;
    }, function (i, j) {
      return i * j % 2 + i * j % 3 == 0;
    }, function (i, j) {
      return (i * j % 2 + i * j % 3) % 2 == 0;
    }, function (i, j) {
      return ((i + j) % 2 + i * j % 3) % 2 == 0;
    }]; // returns true when the version information has to be embeded.
  
    var needsverinfo = function (ver) {
      return ver > 6;
    }; // returns the size of entire QR code for given version.
  
  
    var getsizebyver = function (ver) {
      return 4 * ver + 17;
    }; // returns the number of bits available for code words in this version.
  
  
    var nfullbits = function (ver) {
      /*
       * |<--------------- n --------------->|
       * |        |<----- n-17 ---->|        |
       * +-------+                ///+-------+ ----
       * |       |                ///|       |    ^
       * |  9x9  |       @@@@@    ///|  9x8  |    |
       * |       | # # # @5x5@ # # # |       |    |
       * +-------+       @@@@@       +-------+    |
       *       #                               ---|
       *                                        ^ |
       *       #                                |
       *     @@@@@       @@@@@       @@@@@      | n
       *     @5x5@       @5x5@       @5x5@   n-17
       *     @@@@@       @@@@@       @@@@@      | |
       *       #                                | |
       * //////                                 v |
       * //////#                               ---|
       * +-------+       @@@@@       @@@@@        |
       * |       |       @5x5@       @5x5@        |
       * |  8x9  |       @@@@@       @@@@@        |
       * |       |                                v
       * +-------+                             ----
       *
       * when the entire code has n^2 modules and there are m^2-3 alignment
       * patterns, we have:
       * - 225 (= 9x9 + 9x8 + 8x9) modules for finder patterns and
       *   format information;
       * - 2n-34 (= 2(n-17)) modules for timing patterns;
       * - 36 (= 3x6 + 6x3) modules for version information, if any;
       * - 25m^2-75 (= (m^2-3)(5x5)) modules for alignment patterns
       *   if any, but 10m-20 (= 2(m-2)x5) of them overlaps with
       *   timing patterns.
       */
      var v = VERSIONS[ver];
      var nbits = 16 * ver * ver + 128 * ver + 64; // finder, timing and format info.
  
      if (needsverinfo(ver)) nbits -= 36; // version information
  
      if (v[2].length) {
        // alignment patterns
        nbits -= 25 * v[2].length * v[2].length - 10 * v[2].length - 55;
      }
  
      return nbits;
    }; // returns the number of bits available for data portions (i.e. excludes ECC
    // bits but includes mode and length bits) in this version and ECC level.
  
  
    var ndatabits = function (ver, ecclevel) {
      var nbits = nfullbits(ver) & ~7; // no sub-octet code words
  
      var v = VERSIONS[ver];
      nbits -= 8 * v[0][ecclevel] * v[1][ecclevel]; // ecc bits
  
      return nbits;
    }; // returns the number of bits required for the length of data.
    // (cf. Table 3 in JIS X 0510:2004 p. 16)
  
  
    var ndatalenbits = function (ver, mode) {
      switch (mode) {
        case MODE_NUMERIC:
          return ver < 10 ? 10 : ver < 27 ? 12 : 14;
  
        case MODE_ALPHANUMERIC:
          return ver < 10 ? 9 : ver < 27 ? 11 : 13;
  
        case MODE_OCTET:
          return ver < 10 ? 8 : 16;
  
        case MODE_KANJI:
          return ver < 10 ? 8 : ver < 27 ? 10 : 12;
      }
    }; // returns the maximum length of data possible in given configuration.
  
  
    var getmaxdatalen = function (ver, mode, ecclevel) {
      var nbits = ndatabits(ver, ecclevel) - 4 - ndatalenbits(ver, mode); // 4 for mode bits
  
      switch (mode) {
        case MODE_NUMERIC:
          return (nbits / 10 | 0) * 3 + (nbits % 10 < 4 ? 0 : nbits % 10 < 7 ? 1 : 2);
  
        case MODE_ALPHANUMERIC:
          return (nbits / 11 | 0) * 2 + (nbits % 11 < 6 ? 0 : 1);
  
        case MODE_OCTET:
          return nbits / 8 | 0;
  
        case MODE_KANJI:
          return nbits / 13 | 0;
      }
    }; // checks if the given data can be encoded in given mode, and returns
    // the converted data for the further processing if possible. otherwise
    // returns null.
    //
    // this function does not check the length of data; it is a duty of
    // encode function below (as it depends on the version and ECC level too).
  
  
    var validatedata = function (mode, data) {
      switch (mode) {
        case MODE_NUMERIC:
          if (!data.match(NUMERIC_REGEXP)) return null;
          return data;
  
        case MODE_ALPHANUMERIC:
          if (!data.match(ALPHANUMERIC_REGEXP)) return null;
          return data.toUpperCase();
  
        case MODE_OCTET:
          if (typeof data === "string") {
            // encode as utf-8 string
            var newdata = [];
  
            for (var i = 0; i < data.length; ++i) {
              var ch = data.charCodeAt(i);
  
              if (ch < 0x80) {
                newdata.push(ch);
              } else if (ch < 0x800) {
                newdata.push(0xc0 | ch >> 6, 0x80 | ch & 0x3f);
              } else if (ch < 0x10000) {
                newdata.push(0xe0 | ch >> 12, 0x80 | ch >> 6 & 0x3f, 0x80 | ch & 0x3f);
              } else {
                newdata.push(0xf0 | ch >> 18, 0x80 | ch >> 12 & 0x3f, 0x80 | ch >> 6 & 0x3f, 0x80 | ch & 0x3f);
              }
            }
  
            return newdata;
          } else {
            return data;
          }
  
      }
    }; // returns the code words (sans ECC bits) for given data and configurations.
    // requires data to be preprocessed by validatedata. no length check is
    // performed, and everything has to be checked before calling this function.
  
  
    var encode = function (ver, mode, data, maxbuflen) {
      var buf = [];
      var bits = 0,
          remaining = 8;
      var datalen = data.length; // this function is intentionally no-op when n=0.
  
      var pack = function (x, n) {
        if (n >= remaining) {
          buf.push(bits | x >> (n -= remaining));
  
          while (n >= 8) buf.push(x >> (n -= 8) & 255);
  
          bits = 0;
          remaining = 8;
        }
  
        if (n > 0) bits |= (x & (1 << n) - 1) << (remaining -= n);
      };
  
      var nlenbits = ndatalenbits(ver, mode);
      pack(mode, 4);
      pack(datalen, nlenbits);
  
      switch (mode) {
        case MODE_NUMERIC:
          for (var i = 2; i < datalen; i += 3) {
            pack(parseInt(data.substring(i - 2, i + 1), 10), 10);
          }
  
          pack(parseInt(data.substring(i - 2), 10), [0, 4, 7][datalen % 3]);
          break;
  
        case MODE_ALPHANUMERIC:
          for (var i = 1; i < datalen; i += 2) {
            pack(ALPHANUMERIC_MAP[data.charAt(i - 1)] * 45 + ALPHANUMERIC_MAP[data.charAt(i)], 11);
          }
  
          if (datalen % 2 == 1) {
            pack(ALPHANUMERIC_MAP[data.charAt(i - 1)], 6);
          }
  
          break;
  
        case MODE_OCTET:
          for (var i = 0; i < datalen; ++i) {
            pack(data[i], 8);
          }
  
          break;
      } // final bits. it is possible that adding terminator causes the buffer
      // to overflow, but then the buffer truncated to the maximum size will
      // be valid as the truncated terminator mode bits and padding is
      // identical in appearance (cf. JIS X 0510:2004 sec 8.4.8).
  
  
      pack(MODE_TERMINATOR, 4);
      if (remaining < 8) buf.push(bits); // the padding to fill up the remaining space. we should not add any
      // words when the overflow already occurred.
  
      while (buf.length + 1 < maxbuflen) buf.push(0xec, 0x11);
  
      if (buf.length < maxbuflen) buf.push(0xec);
      return buf;
    }; // calculates ECC code words for given code words and generator polynomial.
    //
    // this is quite similar to CRC calculation as both Reed-Solomon and CRC use
    // the certain kind of cyclic codes, which is effectively the division of
    // zero-augumented polynomial by the generator polynomial. the only difference
    // is that Reed-Solomon uses GF(2^8), instead of CRC's GF(2), and Reed-Solomon
    // uses the different generator polynomial than CRC's.
  
  
    var calculateecc = function (poly, genpoly) {
      var modulus = poly.slice(0);
      var polylen = poly.length,
          genpolylen = genpoly.length;
  
      for (var i = 0; i < genpolylen; ++i) modulus.push(0);
  
      for (var i = 0; i < polylen;) {
        var quotient = GF256_INVMAP[modulus[i++]];
  
        if (quotient >= 0) {
          for (var j = 0; j < genpolylen; ++j) {
            modulus[i + j] ^= GF256_MAP[(quotient + genpoly[j]) % 255];
          }
        }
      }
  
      return modulus.slice(polylen);
    }; // auguments ECC code words to given code words. the resulting words are
    // ready to be encoded in the matrix.
    //
    // the much of actual augumenting procedure follows JIS X 0510:2004 sec 8.7.
    // the code is simplified using the fact that the size of each code & ECC
    // blocks is almost same; for example, when we have 4 blocks and 46 data words
    // the number of code words in those blocks are 11, 11, 12, 12 respectively.
  
  
    var augumenteccs = function (poly, nblocks, genpoly) {
      var subsizes = [];
      var subsize = poly.length / nblocks | 0,
          subsize0 = 0;
      var pivot = nblocks - poly.length % nblocks;
  
      for (var i = 0; i < pivot; ++i) {
        subsizes.push(subsize0);
        subsize0 += subsize;
      }
  
      for (var i = pivot; i < nblocks; ++i) {
        subsizes.push(subsize0);
        subsize0 += subsize + 1;
      }
  
      subsizes.push(subsize0);
      var eccs = [];
  
      for (var i = 0; i < nblocks; ++i) {
        eccs.push(calculateecc(poly.slice(subsizes[i], subsizes[i + 1]), genpoly));
      }
  
      var result = [];
      var nitemsperblock = poly.length / nblocks | 0;
  
      for (var i = 0; i < nitemsperblock; ++i) {
        for (var j = 0; j < nblocks; ++j) {
          result.push(poly[subsizes[j] + i]);
        }
      }
  
      for (var j = pivot; j < nblocks; ++j) {
        result.push(poly[subsizes[j + 1] - 1]);
      }
  
      for (var i = 0; i < genpoly.length; ++i) {
        for (var j = 0; j < nblocks; ++j) {
          result.push(eccs[j][i]);
        }
      }
  
      return result;
    }; // auguments BCH(p+q,q) code to the polynomial over GF(2), given the proper
    // genpoly. the both input and output are in binary numbers, and unlike
    // calculateecc genpoly should include the 1 bit for the highest degree.
    //
    // actual polynomials used for this procedure are as follows:
    // - p=10, q=5, genpoly=x^10+x^8+x^5+x^4+x^2+x+1 (JIS X 0510:2004 Appendix C)
    // - p=18, q=6, genpoly=x^12+x^11+x^10+x^9+x^8+x^5+x^2+1 (ibid. Appendix D)
  
  
    var augumentbch = function (poly, p, genpoly, q) {
      var modulus = poly << q;
  
      for (var i = p - 1; i >= 0; --i) {
        if (modulus >> q + i & 1) modulus ^= genpoly << i;
      }
  
      return poly << q | modulus;
    }; // creates the base matrix for given version. it returns two matrices, one of
    // them is the actual one and the another represents the "reserved" portion
    // (e.g. finder and timing patterns) of the matrix.
    //
    // some entries in the matrix may be undefined, rather than 0 or 1. this is
    // intentional (no initialization needed!), and putdata below will fill
    // the remaining ones.
  
  
    var makebasematrix = function (ver) {
      var v = VERSIONS[ver],
          n = getsizebyver(ver);
      var matrix = [],
          reserved = [];
  
      for (var i = 0; i < n; ++i) {
        matrix.push([]);
        reserved.push([]);
      }
  
      var blit = function (y, x, h, w, bits) {
        for (var i = 0; i < h; ++i) {
          for (var j = 0; j < w; ++j) {
            matrix[y + i][x + j] = bits[i] >> j & 1;
            reserved[y + i][x + j] = 1;
          }
        }
      }; // finder patterns and a part of timing patterns
      // will also mark the format information area (not yet written) as reserved.
  
  
      blit(0, 0, 9, 9, [0x7f, 0x41, 0x5d, 0x5d, 0x5d, 0x41, 0x17f, 0x00, 0x40]);
      blit(n - 8, 0, 8, 9, [0x100, 0x7f, 0x41, 0x5d, 0x5d, 0x5d, 0x41, 0x7f]);
      blit(0, n - 8, 9, 8, [0xfe, 0x82, 0xba, 0xba, 0xba, 0x82, 0xfe, 0x00, 0x00]); // the rest of timing patterns
  
      for (var i = 9; i < n - 8; ++i) {
        matrix[6][i] = matrix[i][6] = ~i & 1;
        reserved[6][i] = reserved[i][6] = 1;
      } // alignment patterns
  
  
      var aligns = v[2],
          m = aligns.length;
  
      for (var i = 0; i < m; ++i) {
        var minj = i == 0 || i == m - 1 ? 1 : 0,
            maxj = i == 0 ? m - 1 : m;
  
        for (var j = minj; j < maxj; ++j) {
          blit(aligns[i], aligns[j], 5, 5, [0x1f, 0x11, 0x15, 0x11, 0x1f]);
        }
      } // version information
  
  
      if (needsverinfo(ver)) {
        var code = augumentbch(ver, 6, 0x1f25, 12);
        var k = 0;
  
        for (var i = 0; i < 6; ++i) {
          for (var j = 0; j < 3; ++j) {
            matrix[i][n - 11 + j] = matrix[n - 11 + j][i] = code >> k++ & 1;
            reserved[i][n - 11 + j] = reserved[n - 11 + j][i] = 1;
          }
        }
      }
  
      return {
        matrix: matrix,
        reserved: reserved
      };
    }; // fills the data portion (i.e. unmarked in reserved) of the matrix with given
    // code words. the size of code words should be no more than available bits,
    // and remaining bits are padded to 0 (cf. JIS X 0510:2004 sec 8.7.3).
  
  
    var putdata = function (matrix, reserved, buf) {
      var n = matrix.length;
      var k = 0,
          dir = -1;
  
      for (var i = n - 1; i >= 0; i -= 2) {
        if (i == 6) --i; // skip the entire timing pattern column
  
        var jj = dir < 0 ? n - 1 : 0;
  
        for (var j = 0; j < n; ++j) {
          for (var ii = i; ii > i - 2; --ii) {
            if (!reserved[jj][ii]) {
              // may overflow, but (undefined >> x)
              // is 0 so it will auto-pad to zero.
              matrix[jj][ii] = buf[k >> 3] >> (~k & 7) & 1;
              ++k;
            }
          }
  
          jj += dir;
        }
  
        dir = -dir;
      }
  
      return matrix;
    }; // XOR-masks the data portion of the matrix. repeating the call with the same
    // arguments will revert the prior call (convenient in the matrix evaluation).
  
  
    var maskdata = function (matrix, reserved, mask) {
      var maskf = MASKFUNCS[mask];
      var n = matrix.length;
  
      for (var i = 0; i < n; ++i) {
        for (var j = 0; j < n; ++j) {
          if (!reserved[i][j]) matrix[i][j] ^= maskf(i, j);
        }
      }
  
      return matrix;
    }; // puts the format information.
  
  
    var putformatinfo = function (matrix, reserved, ecclevel, mask) {
      var n = matrix.length;
      var code = augumentbch(ecclevel << 3 | mask, 5, 0x537, 10) ^ 0x5412;
  
      for (var i = 0; i < 15; ++i) {
        var r = [0, 1, 2, 3, 4, 5, 7, 8, n - 7, n - 6, n - 5, n - 4, n - 3, n - 2, n - 1][i];
        var c = [n - 1, n - 2, n - 3, n - 4, n - 5, n - 6, n - 7, n - 8, 7, 5, 4, 3, 2, 1, 0][i];
        matrix[r][8] = matrix[8][c] = code >> i & 1; // we don't have to mark those bits reserved; always done
        // in makebasematrix above.
      }
  
      return matrix;
    }; // evaluates the resulting matrix and returns the score (lower is better).
    // (cf. JIS X 0510:2004 sec 8.8.2)
    //
    // the evaluation procedure tries to avoid the problematic patterns naturally
    // occuring from the original matrix. for example, it penaltizes the patterns
    // which just look like the finder pattern which will confuse the decoder.
    // we choose the mask which results in the lowest score among 8 possible ones.
    //
    // note: zxing seems to use the same procedure and in many cases its choice
    // agrees to ours, but sometimes it does not. practically it doesn't matter.
  
  
    var evaluatematrix = function (matrix) {
      // N1+(k-5) points for each consecutive row of k same-colored modules,
      // where k >= 5. no overlapping row counts.
      var PENALTY_CONSECUTIVE = 3; // N2 points for each 2x2 block of same-colored modules.
      // overlapping block does count.
  
      var PENALTY_TWOBYTWO = 3; // N3 points for each pattern with >4W:1B:1W:3B:1W:1B or
      // 1B:1W:3B:1W:1B:>4W, or their multiples (e.g. highly unlikely,
      // but 13W:3B:3W:9B:3W:3B counts).
  
      var PENALTY_FINDERLIKE = 40; // N4*k points for every (5*k)% deviation from 50% black density.
      // i.e. k=1 for 55~60% and 40~45%, k=2 for 60~65% and 35~40%, etc.
  
      var PENALTY_DENSITY = 10;
  
      var evaluategroup = function (groups) {
        // assumes [W,B,W,B,W,...,B,W]
        var score = 0;
  
        for (var i = 0; i < groups.length; ++i) {
          if (groups[i] >= 5) score += PENALTY_CONSECUTIVE + (groups[i] - 5);
        }
  
        for (var i = 5; i < groups.length; i += 2) {
          var p = groups[i];
  
          if (groups[i - 1] == p && groups[i - 2] == 3 * p && groups[i - 3] == p && groups[i - 4] == p && (groups[i - 5] >= 4 * p || groups[i + 1] >= 4 * p)) {
            // this part differs from zxing...
            score += PENALTY_FINDERLIKE;
          }
        }
  
        return score;
      };
  
      var n = matrix.length;
      var score = 0,
          nblacks = 0;
  
      for (var i = 0; i < n; ++i) {
        var row = matrix[i];
        var groups; // evaluate the current row
  
        groups = [0]; // the first empty group of white
  
        for (var j = 0; j < n;) {
          var k;
  
          for (k = 0; j < n && row[j]; ++k) ++j;
  
          groups.push(k);
  
          for (k = 0; j < n && !row[j]; ++k) ++j;
  
          groups.push(k);
        }
  
        score += evaluategroup(groups); // evaluate the current column
  
        groups = [0];
  
        for (var j = 0; j < n;) {
          var k;
  
          for (k = 0; j < n && matrix[j][i]; ++k) ++j;
  
          groups.push(k);
  
          for (k = 0; j < n && !matrix[j][i]; ++k) ++j;
  
          groups.push(k);
        }
  
        score += evaluategroup(groups); // check the 2x2 box and calculate the density
  
        var nextrow = matrix[i + 1] || [];
        nblacks += row[0];
  
        for (var j = 1; j < n; ++j) {
          var p = row[j];
          nblacks += p; // at least comparison with next row should be strict...
  
          if (row[j - 1] == p && nextrow[j] === p && nextrow[j - 1] === p) {
            score += PENALTY_TWOBYTWO;
          }
        }
      }
  
      score += PENALTY_DENSITY * (Math.abs(nblacks / n / n - 0.5) / 0.05 | 0);
      return score;
    }; // returns the fully encoded QR code matrix which contains given data.
    // it also chooses the best mask automatically when mask is -1.
  
  
    var generate = function (data, ver, mode, ecclevel, mask) {
      var v = VERSIONS[ver];
      var buf = encode(ver, mode, data, ndatabits(ver, ecclevel) >> 3);
      buf = augumenteccs(buf, v[1][ecclevel], GF256_GENPOLY[v[0][ecclevel]]);
      var result = makebasematrix(ver);
      var matrix = result.matrix,
          reserved = result.reserved;
      putdata(matrix, reserved, buf);
  
      if (mask < 0) {
        // find the best mask
        maskdata(matrix, reserved, 0);
        putformatinfo(matrix, reserved, ecclevel, 0);
        var bestmask = 0,
            bestscore = evaluatematrix(matrix);
        maskdata(matrix, reserved, 0);
  
        for (mask = 1; mask < 8; ++mask) {
          maskdata(matrix, reserved, mask);
          putformatinfo(matrix, reserved, ecclevel, mask);
          var score = evaluatematrix(matrix);
  
          if (bestscore > score) {
            bestscore = score;
            bestmask = mask;
          }
  
          maskdata(matrix, reserved, mask);
        }
  
        mask = bestmask;
      }
  
      maskdata(matrix, reserved, mask);
      putformatinfo(matrix, reserved, ecclevel, mask);
      return matrix;
    }; // the public interface is trivial; the options available are as follows:
    //
    // - version: an integer in [1,40]. when omitted (or -1) the smallest possible
    //   version is chosen.
    // - mode: one of 'numeric', 'alphanumeric', 'octet'. when omitted the smallest
    //   possible mode is chosen.
    // - ecclevel: one of 'L', 'M', 'Q', 'H'. defaults to 'L'.
    // - mask: an integer in [0,7]. when omitted (or -1) the best mask is chosen.
    //
    // for generate{HTML,PNG}:
    //
    // - modulesize: a number. this is a size of each modules in pixels, and
    //   defaults to 5px.
    // - margin: a number. this is a size of margin in *modules*, and defaults to
    //   4 (white modules). the specficiation mandates the margin no less than 4
    //   modules, so it is better not to alter this value unless you know what
    //   you're doing.
  
  
    var QRCode = {
      generate: function (data, options) {
        var MODES = {
          numeric: MODE_NUMERIC,
          alphanumeric: MODE_ALPHANUMERIC,
          octet: MODE_OCTET
        };
        var ECCLEVELS = {
          L: ECCLEVEL_L,
          M: ECCLEVEL_M,
          Q: ECCLEVEL_Q,
          H: ECCLEVEL_H
        };
        options = options || {};
        var ver = options.version || -1;
        var ecclevel = ECCLEVELS[(options.ecclevel || "L").toUpperCase()];
        var mode = options.mode ? MODES[options.mode.toLowerCase()] : -1;
        var mask = "mask" in options ? options.mask : -1;
  
        if (mode < 0) {
          if (typeof data === "string") {
            if (data.match(NUMERIC_REGEXP)) {
              mode = MODE_NUMERIC;
            } else if (data.match(ALPHANUMERIC_OUT_REGEXP)) {
              // while encode supports case-insensitive
              // encoding, we restrict the data to be
              // uppercased when auto-selecting the mode.
              mode = MODE_ALPHANUMERIC;
            } else {
              mode = MODE_OCTET;
            }
          } else {
            mode = MODE_OCTET;
          }
        } else if (!(mode == MODE_NUMERIC || mode == MODE_ALPHANUMERIC || mode == MODE_OCTET)) {
          throw "invalid or unsupported mode";
        }
  
        data = validatedata(mode, data);
        if (data === null) throw "invalid data format";
        if (ecclevel < 0 || ecclevel > 3) throw "invalid ECC level";
  
        if (ver < 0) {
          for (ver = 1; ver <= 40; ++ver) {
            if (data.length <= getmaxdatalen(ver, mode, ecclevel)) break;
          }
  
          if (ver > 40) throw "too large data";
        } else if (ver < 1 || ver > 40) {
          throw "invalid version";
        }
  
        if (mask != -1 && (mask < 0 || mask > 8)) throw "invalid mask";
        return generate(data, ver, mode, ecclevel, mask);
      },
      generateHTML: function (data, options) {
        options = options || {};
        var matrix = QRCode["generate"](data, options);
        var modsize = Math.max(options.modulesize || 5, 0.5);
        var margin = Math.max(options.margin !== null ? options.margin : 4, 0.0);
        var e = document.createElement("div");
        var n = matrix.length;
        var html = ['<table border="0" cellspacing="0" cellpadding="0" style="border:' + modsize * margin + 'px solid #fff;background:#fff">'];
  
        for (var i = 0; i < n; ++i) {
          html.push("<tr>");
  
          for (var j = 0; j < n; ++j) {
            html.push('<td style="width:' + modsize + "px;height:" + modsize + "px" + (matrix[i][j] ? ";background:#000" : "") + '"></td>');
          }
  
          html.push("</tr>");
        }
  
        e.className = "qrcode";
        e.innerHTML = html.join("") + "</table>";
        return e;
      },
      generateSVG: function (data, options) {
        options = options || {};
        var matrix = QRCode["generate"](data, options);
        var n = matrix.length;
        var modsize = Math.max(options.modulesize || 5, 0.5);
        var margin = Math.max(options.margin !== null ? options.margin : 4, 0.0);
        var size = modsize * (n + 2 * margin);
        var common = ' class= "fg"' + ' width="' + modsize + '" height="' + modsize + '"/>';
        var e = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        e.setAttribute("viewBox", "0 0 " + size + " " + size);
        e.setAttribute("style", "shape-rendering:crispEdges");
  
        if (options.modulesize) {
          e.setAttribute("width", size);
          e.setAttribute("height", size);
        }
  
        var svg = ["<style scoped>.bg{fill:#FFF}.fg{fill:#000}</style>", '<rect class="bg" x="0" y="0"', 'width="' + size + '" height="' + size + '"/>'];
        var yo = margin * modsize;
  
        for (var y = 0; y < n; ++y) {
          var xo = margin * modsize;
  
          for (var x = 0; x < n; ++x) {
            if (matrix[y][x]) svg.push('<rect x="' + xo + '" y="' + yo + '"', common);
            xo += modsize;
          }
  
          yo += modsize;
        }
  
        e.innerHTML = svg.join("");
        return e;
      },
      generatePNG: function (data, options) {
        options = options || {};
        var matrix = QRCode["generate"](data, options);
        var modsize = Math.max(options.modulesize || 5, 0.5);
        var margin = Math.max(options.margin !== null ? options.margin : 4, 0.0);
        var n = matrix.length;
        var size = modsize * (n + 2 * margin);
        var canvas = document.createElement("canvas"),
            context;
        canvas.width = canvas.height = size;
        context = canvas.getContext("2d");
        if (!context) throw "canvas support is needed for PNG output";
        context.fillStyle = "#fff";
        context.fillRect(0, 0, size, size);
        context.fillStyle = "#000";
  
        for (var i = 0; i < n; ++i) {
          for (var j = 0; j < n; ++j) {
            if (matrix[i][j]) {
              context.fillRect(modsize * (margin + j), modsize * (margin + i), modsize, modsize);
            }
          }
        } //context.fillText('evaluation: ' + evaluatematrix(matrix), 10, 10);
  
  
        return canvas.toDataURL();
      }
    };
    return QRCode;
  });