/** * created by chenzhi1757 on 2015/10/23. */ var qrcode; (function () { //--------------------------------------------------------------------- // qrcode for javascript // // copyright (c) 2009 kazuhiko arase // // url: http://www.d-project.com/ // // licensed under the mit license: // http://www.opensource.org/licenses/mit-license.php // // the word "qr code" is registered trademark of // denso wave incorporated // http://www.denso-wave.com/qrcode/faqpatent-e.html // //--------------------------------------------------------------------- function qr8bitbyte(data) { this.mode = qrmode.mode_8bit_byte; this.data = data; this.parseddata = []; // added to support utf-8 characters for (var i = 0, l = this.data.length; i < l; i++) { var bytearray = []; var code = this.data.charcodeat(i); if (code > 0x10000) { bytearray[0] = 0xf0 | ((code & 0x1c0000) >>> 18); bytearray[1] = 0x80 | ((code & 0x3f000) >>> 12); bytearray[2] = 0x80 | ((code & 0xfc0) >>> 6); bytearray[3] = 0x80 | (code & 0x3f); } else if (code > 0x800) { bytearray[0] = 0xe0 | ((code & 0xf000) >>> 12); bytearray[1] = 0x80 | ((code & 0xfc0) >>> 6); bytearray[2] = 0x80 | (code & 0x3f); } else if (code > 0x80) { bytearray[0] = 0xc0 | ((code & 0x7c0) >>> 6); bytearray[1] = 0x80 | (code & 0x3f); } else { bytearray[0] = code; } this.parseddata.push(bytearray); } this.parseddata = array.prototype.concat.apply([], this.parseddata); if (this.parseddata.length != this.data.length) { this.parseddata.unshift(191); this.parseddata.unshift(187); this.parseddata.unshift(239); } } qr8bitbyte.prototype = { getlength: function (buffer) { return this.parseddata.length; }, write: function (buffer) { for (var i = 0, l = this.parseddata.length; i < l; i++) { buffer.put(this.parseddata[i], 8); } } }; function qrcodemodel(typenumber, errorcorrectlevel) { this.typenumber = typenumber; this.errorcorrectlevel = errorcorrectlevel; this.modules = null; this.modulecount = 0; this.datacache = null; this.datalist = []; } function qrpolynomial(num, shift) { if (num.length == undefined) throw new error(num.length + "/" + shift); var offset = 0; while (offset < num.length && num[offset] == 0) offset++; this.num = new array(num.length - offset + shift); for (var i = 0; i < num.length - offset; i++) this.num[i] = num[i + offset]; } function qrrsblock(totalcount, datacount) { this.totalcount = totalcount, this.datacount = datacount; } function qrbitbuffer() { this.buffer = [], this.length = 0; } qrcodemodel.prototype = { "adddata": function(data) { var newdata = new qr8bitbyte(data); this.datalist.push(newdata), this.datacache = null; }, "isdark": function(row, col) { if (row < 0 || this.modulecount <= row || col < 0 || this.modulecount <= col) throw new error(row + "," + col); return this.modules[row][col]; }, "getmodulecount": function() { return this.modulecount; }, "make": function() { this.makeimpl(!1, this.getbestmaskpattern()); }, "makeimpl": function(test, maskpattern) { this.modulecount = this.typenumber * 4 + 17, this.modules = new array(this.modulecount); for (var row = 0; row < this.modulecount; row++) { this.modules[row] = new array(this.modulecount); for (var col = 0; col < this.modulecount; col++) this.modules[row][col] = null; } this.setuppositionprobepattern(0, 0), this.setuppositionprobepattern(this.modulecount - 7, 0), this.setuppositionprobepattern(0, this.modulecount - 7), this.setuppositionadjustpattern(), this.setuptimingpattern(), this.setuptypeinfo(test, maskpattern), this.typenumber >= 7 && this.setuptypenumber(test), this.datacache == null && (this.datacache = qrcodemodel.createdata(this.typenumber, this.errorcorrectlevel, this.datalist)), this.mapdata(this.datacache, maskpattern); }, "setuppositionprobepattern": function(row, col) { for (var r = -1; r <= 7; r++) { if (row + r <= -1 || this.modulecount <= row + r) continue; for (var c = -1; c <= 7; c++) { if (col + c <= -1 || this.modulecount <= col + c) continue; 0 <= r && r <= 6 && (c == 0 || c == 6) || 0 <= c && c <= 6 && (r == 0 || r == 6) || 2 <= r && r <= 4 && 2 <= c && c <= 4 ? this.modules[row + r][col + c] = !0 : this.modules[row + r][col + c] = !1; } } }, "getbestmaskpattern": function() { var minlostpoint = 0, pattern = 0; for (var i = 0; i < 8; i++) { this.makeimpl(!0, i); var lostpoint = qrutil.getlostpoint(this); if (i == 0 || minlostpoint > lostpoint) minlostpoint = lostpoint, pattern = i; } return pattern; }, "createmovieclip": function(target_mc, instance_name, depth) { var qr_mc = target_mc.createemptymovieclip(instance_name, depth), cs = 1; this.make(); for (var row = 0; row < this.modules.length; row++) { var y = row * cs; for (var col = 0; col < this.modules[row].length; col++) { var x = col * cs, dark = this.modules[row][col]; dark && (qr_mc.beginfill(0, 100), qr_mc.moveto(x, y), qr_mc.lineto(x + cs, y), qr_mc.lineto(x + cs, y + cs), qr_mc.lineto(x, y + cs), qr_mc.endfill()); } } return qr_mc; }, "setuptimingpattern": function() { for (var r = 8; r < this.modulecount - 8; r++) { if (this.modules[r][6] != null) continue; this.modules[r][6] = r % 2 == 0; } for (var c = 8; c < this.modulecount - 8; c++) { if (this.modules[6][c] != null) continue; this.modules[6][c] = c % 2 == 0; } }, "setuppositionadjustpattern": function() { var pos = qrutil.getpatternposition(this.typenumber); for (var i = 0; i < pos.length; i++) for (var j = 0; j < pos.length; j++) { var row = pos[i], col = pos[j]; if (this.modules[row][col] != null) continue; for (var r = -2; r <= 2; r++) for (var c = -2; c <= 2; c++) r == -2 || r == 2 || c == -2 || c == 2 || r == 0 && c == 0 ? this.modules[row + r][col + c] = !0 : this.modules[row + r][col + c] = !1; } }, "setuptypenumber": function(test) { var bits = qrutil.getbchtypenumber(this.typenumber); for (var i = 0; i < 18; i++) { var mod = !test && (bits >> i & 1) == 1; this.modules[math.floor(i / 3)][i % 3 + this.modulecount - 8 - 3] = mod; } for (var i = 0; i < 18; i++) { var mod = !test && (bits >> i & 1) == 1; this.modules[i % 3 + this.modulecount - 8 - 3][math.floor(i / 3)] = mod; } }, "setuptypeinfo": function(test, maskpattern) { var data = this.errorcorrectlevel << 3 | maskpattern, bits = qrutil.getbchtypeinfo(data); for (var i = 0; i < 15; i++) { var mod = !test && (bits >> i & 1) == 1; i < 6 ? this.modules[i][8] = mod : i < 8 ? this.modules[i + 1][8] = mod : this.modules[this.modulecount - 15 + i][8] = mod; } for (var i = 0; i < 15; i++) { var mod = !test && (bits >> i & 1) == 1; i < 8 ? this.modules[8][this.modulecount - i - 1] = mod : i < 9 ? this.modules[8][15 - i - 1 + 1] = mod : this.modules[8][15 - i - 1] = mod; } this.modules[this.modulecount - 8][8] = !test; }, "mapdata": function(data, maskpattern) { var inc = -1, row = this.modulecount - 1, bitindex = 7, byteindex = 0; for (var col = this.modulecount - 1; col > 0; col -= 2) { col == 6 && col--; for (;;) { for (var c = 0; c < 2; c++) if (this.modules[row][col - c] == null) { var dark = !1; byteindex < data.length && (dark = (data[byteindex] >>> bitindex & 1) == 1); var mask = qrutil.getmask(maskpattern, row, col - c); mask && (dark = !dark), this.modules[row][col - c] = dark, bitindex--, bitindex == -1 && (byteindex++, bitindex = 7); } row += inc; if (row < 0 || this.modulecount <= row) { row -= inc, inc = -inc; break; } } } } }, qrcodemodel.pad0 = 236, qrcodemodel.pad1 = 17, qrcodemodel.createdata = function(typenumber, errorcorrectlevel, datalist) { var rsblocks = qrrsblock.getrsblocks(typenumber, errorcorrectlevel), buffer = new qrbitbuffer; for (var i = 0; i < datalist.length; i++) { var data = datalist[i]; buffer.put(data.mode, 4), buffer.put(data.getlength(), qrutil.getlengthinbits(data.mode, typenumber)), data.write(buffer); } var totaldatacount = 0; for (var i = 0; i < rsblocks.length; i++) totaldatacount += rsblocks[i].datacount; if (buffer.getlengthinbits() > totaldatacount * 8) throw new error("code length overflow. (" + buffer.getlengthinbits() + ">" + totaldatacount * 8 + ")"); buffer.getlengthinbits() + 4 <= totaldatacount * 8 && buffer.put(0, 4); while (buffer.getlengthinbits() % 8 != 0) buffer.putbit(!1); for (;;) { if (buffer.getlengthinbits() >= totaldatacount * 8) break; buffer.put(qrcodemodel.pad0, 8); if (buffer.getlengthinbits() >= totaldatacount * 8) break; buffer.put(qrcodemodel.pad1, 8); } return qrcodemodel.createbytes(buffer, rsblocks); }, qrcodemodel.createbytes = function(buffer, rsblocks) { var offset = 0, maxdccount = 0, maxeccount = 0, dcdata = new array(rsblocks.length), ecdata = new array(rsblocks.length); for (var r = 0; r < rsblocks.length; r++) { var dccount = rsblocks[r].datacount, eccount = rsblocks[r].totalcount - dccount; maxdccount = math.max(maxdccount, dccount), maxeccount = math.max(maxeccount, eccount), dcdata[r] = new array(dccount); for (var i = 0; i < dcdata[r].length; i++) dcdata[r][i] = 255 & buffer.buffer[i + offset]; offset += dccount; var rspoly = qrutil.geterrorcorrectpolynomial(eccount), rawpoly = new qrpolynomial(dcdata[r], rspoly.getlength() - 1), modpoly = rawpoly.mod(rspoly); ecdata[r] = new array(rspoly.getlength() - 1); for (var i = 0; i < ecdata[r].length; i++) { var modindex = i + modpoly.getlength() - ecdata[r].length; ecdata[r][i] = modindex >= 0 ? modpoly.get(modindex) : 0; } } var totalcodecount = 0; for (var i = 0; i < rsblocks.length; i++) totalcodecount += rsblocks[i].totalcount; var data = new array(totalcodecount), index = 0; for (var i = 0; i < maxdccount; i++) for (var r = 0; r < rsblocks.length; r++) i < dcdata[r].length && (data[index++] = dcdata[r][i]); for (var i = 0; i < maxeccount; i++) for (var r = 0; r < rsblocks.length; r++) i < ecdata[r].length && (data[index++] = ecdata[r][i]); return data; }; var qrmode = { "mode_number": 1, "mode_alpha_num": 2, "mode_8bit_byte": 4, "mode_kanji": 8 }, qrerrorcorrectlevel = { "l": 1, "m": 0, "q": 3, "h": 2 }, qrmaskpattern = { "pattern000": 0, "pattern001": 1, "pattern010": 2, "pattern011": 3, "pattern100": 4, "pattern101": 5, "pattern110": 6, "pattern111": 7 }, qrutil = { "pattern_position_table": [ [], [ 6, 18 ], [ 6, 22 ], [ 6, 26 ], [ 6, 30 ], [ 6, 34 ], [ 6, 22, 38 ], [ 6, 24, 42 ], [ 6, 26, 46 ], [ 6, 28, 50 ], [ 6, 30, 54 ], [ 6, 32, 58 ], [ 6, 34, 62 ], [ 6, 26, 46, 66 ], [ 6, 26, 48, 70 ], [ 6, 26, 50, 74 ], [ 6, 30, 54, 78 ], [ 6, 30, 56, 82 ], [ 6, 30, 58, 86 ], [ 6, 34, 62, 90 ], [ 6, 28, 50, 72, 94 ], [ 6, 26, 50, 74, 98 ], [ 6, 30, 54, 78, 102 ], [ 6, 28, 54, 80, 106 ], [ 6, 32, 58, 84, 110 ], [ 6, 30, 58, 86, 114 ], [ 6, 34, 62, 90, 118 ], [ 6, 26, 50, 74, 98, 122 ], [ 6, 30, 54, 78, 102, 126 ], [ 6, 26, 52, 78, 104, 130 ], [ 6, 30, 56, 82, 108, 134 ], [ 6, 34, 60, 86, 112, 138 ], [ 6, 30, 58, 86, 114, 142 ], [ 6, 34, 62, 90, 118, 146 ], [ 6, 30, 54, 78, 102, 126, 150 ], [ 6, 24, 50, 76, 102, 128, 154 ], [ 6, 28, 54, 80, 106, 132, 158 ], [ 6, 32, 58, 84, 110, 136, 162 ], [ 6, 26, 54, 82, 110, 138, 166 ], [ 6, 30, 58, 86, 114, 142, 170 ] ], "g15": 1335, "g18": 7973, "g15_mask": 21522, "getbchtypeinfo": function(data) { var d = data << 10; while (qrutil.getbchdigit(d) - qrutil.getbchdigit(qrutil.g15) >= 0) d ^= qrutil.g15 << qrutil.getbchdigit(d) - qrutil.getbchdigit(qrutil.g15); return (data << 10 | d) ^ qrutil.g15_mask; }, "getbchtypenumber": function(data) { var d = data << 12; while (qrutil.getbchdigit(d) - qrutil.getbchdigit(qrutil.g18) >= 0) d ^= qrutil.g18 << qrutil.getbchdigit(d) - qrutil.getbchdigit(qrutil.g18); return data << 12 | d; }, "getbchdigit": function(data) { var digit = 0; while (data != 0) digit++, data >>>= 1; return digit; }, "getpatternposition": function(typenumber) { return qrutil.pattern_position_table[typenumber - 1]; }, "getmask": function(maskpattern, i, j) { switch (maskpattern) { case qrmaskpattern.pattern000: return (i + j) % 2 == 0; case qrmaskpattern.pattern001: return i % 2 == 0; case qrmaskpattern.pattern010: return j % 3 == 0; case qrmaskpattern.pattern011: return (i + j) % 3 == 0; case qrmaskpattern.pattern100: return (math.floor(i / 2) + math.floor(j / 3)) % 2 == 0; case qrmaskpattern.pattern101: return i * j % 2 + i * j % 3 == 0; case qrmaskpattern.pattern110: return (i * j % 2 + i * j % 3) % 2 == 0; case qrmaskpattern.pattern111: return (i * j % 3 + (i + j) % 2) % 2 == 0; default: throw new error("bad maskpattern:" + maskpattern); } }, "geterrorcorrectpolynomial": function(errorcorrectlength) { var a = new qrpolynomial([ 1 ], 0); for (var i = 0; i < errorcorrectlength; i++) a = a.multiply(new qrpolynomial([ 1, qrmath.gexp(i) ], 0)); return a; }, "getlengthinbits": function(mode, type) { if (1 <= type && type < 10) switch (mode) { case qrmode.mode_number: return 10; case qrmode.mode_alpha_num: return 9; case qrmode.mode_8bit_byte: return 8; case qrmode.mode_kanji: return 8; default: throw new error("mode:" + mode); } else if (type < 27) switch (mode) { case qrmode.mode_number: return 12; case qrmode.mode_alpha_num: return 11; case qrmode.mode_8bit_byte: return 16; case qrmode.mode_kanji: return 10; default: throw new error("mode:" + mode); } else { if (!(type < 41)) throw new error("type:" + type); switch (mode) { case qrmode.mode_number: return 14; case qrmode.mode_alpha_num: return 13; case qrmode.mode_8bit_byte: return 16; case qrmode.mode_kanji: return 12; default: throw new error("mode:" + mode); } } }, "getlostpoint": function(qrcode) { var modulecount = qrcode.getmodulecount(), lostpoint = 0; for (var row = 0; row < modulecount; row++) for (var col = 0; col < modulecount; col++) { var samecount = 0, dark = qrcode.isdark(row, col); for (var r = -1; r <= 1; r++) { if (row + r < 0 || modulecount <= row + r) continue; for (var c = -1; c <= 1; c++) { if (col + c < 0 || modulecount <= col + c) continue; if (r == 0 && c == 0) continue; dark == qrcode.isdark(row + r, col + c) && samecount++; } } samecount > 5 && (lostpoint += 3 + samecount - 5); } for (var row = 0; row < modulecount - 1; row++) for (var col = 0; col < modulecount - 1; col++) { var count = 0; qrcode.isdark(row, col) && count++, qrcode.isdark(row + 1, col) && count++, qrcode.isdark(row, col + 1) && count++, qrcode.isdark(row + 1, col + 1) && count++; if (count == 0 || count == 4) lostpoint += 3; } for (var row = 0; row < modulecount; row++) for (var col = 0; col < modulecount - 6; col++) qrcode.isdark(row, col) && !qrcode.isdark(row, col + 1) && qrcode.isdark(row, col + 2) && qrcode.isdark(row, col + 3) && qrcode.isdark(row, col + 4) && !qrcode.isdark(row, col + 5) && qrcode.isdark(row, col + 6) && (lostpoint += 40); for (var col = 0; col < modulecount; col++) for (var row = 0; row < modulecount - 6; row++) qrcode.isdark(row, col) && !qrcode.isdark(row + 1, col) && qrcode.isdark(row + 2, col) && qrcode.isdark(row + 3, col) && qrcode.isdark(row + 4, col) && !qrcode.isdark(row + 5, col) && qrcode.isdark(row + 6, col) && (lostpoint += 40); var darkcount = 0; for (var col = 0; col < modulecount; col++) for (var row = 0; row < modulecount; row++) qrcode.isdark(row, col) && darkcount++; var ratio = math.abs(100 * darkcount / modulecount / modulecount - 50) / 5; return lostpoint += ratio * 10, lostpoint; } }, qrmath = { "glog": function(n) { if (n < 1) throw new error("glog(" + n + ")"); return qrmath.log_table[n]; }, "gexp": function(n) { while (n < 0) n += 255; while (n >= 256) n -= 255; return qrmath.exp_table[n]; }, "exp_table": new array(256), "log_table": new array(256) }; for (var i = 0; i < 8; i++) qrmath.exp_table[i] = 1 << i; for (var i = 8; i < 256; i++) qrmath.exp_table[i] = qrmath.exp_table[i - 4] ^ qrmath.exp_table[i - 5] ^ qrmath.exp_table[i - 6] ^ qrmath.exp_table[i - 8]; for (var i = 0; i < 255; i++) qrmath.log_table[qrmath.exp_table[i]] = i; qrpolynomial.prototype = { "get": function(index) { return this.num[index]; }, "getlength": function() { return this.num.length; }, "multiply": function(e) { var num = new array(this.getlength() + e.getlength() - 1); for (var i = 0; i < this.getlength(); i++) for (var j = 0; j < e.getlength(); j++) num[i + j] ^= qrmath.gexp(qrmath.glog(this.get(i)) + qrmath.glog(e.get(j))); return new qrpolynomial(num, 0); }, "mod": function(e) { if (this.getlength() - e.getlength() < 0) return this; var ratio = qrmath.glog(this.get(0)) - qrmath.glog(e.get(0)), num = new array(this.getlength()); for (var i = 0; i < this.getlength(); i++) num[i] = this.get(i); for (var i = 0; i < e.getlength(); i++) num[i] ^= qrmath.gexp(qrmath.glog(e.get(i)) + ratio); return (new qrpolynomial(num, 0)).mod(e); } }, qrrsblock.rs_block_table = [ [ 1, 26, 19 ], [ 1, 26, 16 ], [ 1, 26, 13 ], [ 1, 26, 9 ], [ 1, 44, 34 ], [ 1, 44, 28 ], [ 1, 44, 22 ], [ 1, 44, 16 ], [ 1, 70, 55 ], [ 1, 70, 44 ], [ 2, 35, 17 ], [ 2, 35, 13 ], [ 1, 100, 80 ], [ 2, 50, 32 ], [ 2, 50, 24 ], [ 4, 25, 9 ], [ 1, 134, 108 ], [ 2, 67, 43 ], [ 2, 33, 15, 2, 34, 16 ], [ 2, 33, 11, 2, 34, 12 ], [ 2, 86, 68 ], [ 4, 43, 27 ], [ 4, 43, 19 ], [ 4, 43, 15 ], [ 2, 98, 78 ], [ 4, 49, 31 ], [ 2, 32, 14, 4, 33, 15 ], [ 4, 39, 13, 1, 40, 14 ], [ 2, 121, 97 ], [ 2, 60, 38, 2, 61, 39 ], [ 4, 40, 18, 2, 41, 19 ], [ 4, 40, 14, 2, 41, 15 ], [ 2, 146, 116 ], [ 3, 58, 36, 2, 59, 37 ], [ 4, 36, 16, 4, 37, 17 ], [ 4, 36, 12, 4, 37, 13 ], [ 2, 86, 68, 2, 87, 69 ], [ 4, 69, 43, 1, 70, 44 ], [ 6, 43, 19, 2, 44, 20 ], [ 6, 43, 15, 2, 44, 16 ], [ 4, 101, 81 ], [ 1, 80, 50, 4, 81, 51 ], [ 4, 50, 22, 4, 51, 23 ], [ 3, 36, 12, 8, 37, 13 ], [ 2, 116, 92, 2, 117, 93 ], [ 6, 58, 36, 2, 59, 37 ], [ 4, 46, 20, 6, 47, 21 ], [ 7, 42, 14, 4, 43, 15 ], [ 4, 133, 107 ], [ 8, 59, 37, 1, 60, 38 ], [ 8, 44, 20, 4, 45, 21 ], [ 12, 33, 11, 4, 34, 12 ], [ 3, 145, 115, 1, 146, 116 ], [ 4, 64, 40, 5, 65, 41 ], [ 11, 36, 16, 5, 37, 17 ], [ 11, 36, 12, 5, 37, 13 ], [ 5, 109, 87, 1, 110, 88 ], [ 5, 65, 41, 5, 66, 42 ], [ 5, 54, 24, 7, 55, 25 ], [ 11, 36, 12 ], [ 5, 122, 98, 1, 123, 99 ], [ 7, 73, 45, 3, 74, 46 ], [ 15, 43, 19, 2, 44, 20 ], [ 3, 45, 15, 13, 46, 16 ], [ 1, 135, 107, 5, 136, 108 ], [ 10, 74, 46, 1, 75, 47 ], [ 1, 50, 22, 15, 51, 23 ], [ 2, 42, 14, 17, 43, 15 ], [ 5, 150, 120, 1, 151, 121 ], [ 9, 69, 43, 4, 70, 44 ], [ 17, 50, 22, 1, 51, 23 ], [ 2, 42, 14, 19, 43, 15 ], [ 3, 141, 113, 4, 142, 114 ], [ 3, 70, 44, 11, 71, 45 ], [ 17, 47, 21, 4, 48, 22 ], [ 9, 39, 13, 16, 40, 14 ], [ 3, 135, 107, 5, 136, 108 ], [ 3, 67, 41, 13, 68, 42 ], [ 15, 54, 24, 5, 55, 25 ], [ 15, 43, 15, 10, 44, 16 ], [ 4, 144, 116, 4, 145, 117 ], [ 17, 68, 42 ], [ 17, 50, 22, 6, 51, 23 ], [ 19, 46, 16, 6, 47, 17 ], [ 2, 139, 111, 7, 140, 112 ], [ 17, 74, 46 ], [ 7, 54, 24, 16, 55, 25 ], [ 34, 37, 13 ], [ 4, 151, 121, 5, 152, 122 ], [ 4, 75, 47, 14, 76, 48 ], [ 11, 54, 24, 14, 55, 25 ], [ 16, 45, 15, 14, 46, 16 ], [ 6, 147, 117, 4, 148, 118 ], [ 6, 73, 45, 14, 74, 46 ], [ 11, 54, 24, 16, 55, 25 ], [ 30, 46, 16, 2, 47, 17 ], [ 8, 132, 106, 4, 133, 107 ], [ 8, 75, 47, 13, 76, 48 ], [ 7, 54, 24, 22, 55, 25 ], [ 22, 45, 15, 13, 46, 16 ], [ 10, 142, 114, 2, 143, 115 ], [ 19, 74, 46, 4, 75, 47 ], [ 28, 50, 22, 6, 51, 23 ], [ 33, 46, 16, 4, 47, 17 ], [ 8, 152, 122, 4, 153, 123 ], [ 22, 73, 45, 3, 74, 46 ], [ 8, 53, 23, 26, 54, 24 ], [ 12, 45, 15, 28, 46, 16 ], [ 3, 147, 117, 10, 148, 118 ], [ 3, 73, 45, 23, 74, 46 ], [ 4, 54, 24, 31, 55, 25 ], [ 11, 45, 15, 31, 46, 16 ], [ 7, 146, 116, 7, 147, 117 ], [ 21, 73, 45, 7, 74, 46 ], [ 1, 53, 23, 37, 54, 24 ], [ 19, 45, 15, 26, 46, 16 ], [ 5, 145, 115, 10, 146, 116 ], [ 19, 75, 47, 10, 76, 48 ], [ 15, 54, 24, 25, 55, 25 ], [ 23, 45, 15, 25, 46, 16 ], [ 13, 145, 115, 3, 146, 116 ], [ 2, 74, 46, 29, 75, 47 ], [ 42, 54, 24, 1, 55, 25 ], [ 23, 45, 15, 28, 46, 16 ], [ 17, 145, 115 ], [ 10, 74, 46, 23, 75, 47 ], [ 10, 54, 24, 35, 55, 25 ], [ 19, 45, 15, 35, 46, 16 ], [ 17, 145, 115, 1, 146, 116 ], [ 14, 74, 46, 21, 75, 47 ], [ 29, 54, 24, 19, 55, 25 ], [ 11, 45, 15, 46, 46, 16 ], [ 13, 145, 115, 6, 146, 116 ], [ 14, 74, 46, 23, 75, 47 ], [ 44, 54, 24, 7, 55, 25 ], [ 59, 46, 16, 1, 47, 17 ], [ 12, 151, 121, 7, 152, 122 ], [ 12, 75, 47, 26, 76, 48 ], [ 39, 54, 24, 14, 55, 25 ], [ 22, 45, 15, 41, 46, 16 ], [ 6, 151, 121, 14, 152, 122 ], [ 6, 75, 47, 34, 76, 48 ], [ 46, 54, 24, 10, 55, 25 ], [ 2, 45, 15, 64, 46, 16 ], [ 17, 152, 122, 4, 153, 123 ], [ 29, 74, 46, 14, 75, 47 ], [ 49, 54, 24, 10, 55, 25 ], [ 24, 45, 15, 46, 46, 16 ], [ 4, 152, 122, 18, 153, 123 ], [ 13, 74, 46, 32, 75, 47 ], [ 48, 54, 24, 14, 55, 25 ], [ 42, 45, 15, 32, 46, 16 ], [ 20, 147, 117, 4, 148, 118 ], [ 40, 75, 47, 7, 76, 48 ], [ 43, 54, 24, 22, 55, 25 ], [ 10, 45, 15, 67, 46, 16 ], [ 19, 148, 118, 6, 149, 119 ], [ 18, 75, 47, 31, 76, 48 ], [ 34, 54, 24, 34, 55, 25 ], [ 20, 45, 15, 61, 46, 16 ] ], qrrsblock.getrsblocks = function(typenumber, errorcorrectlevel) { var rsblock = qrrsblock.getrsblocktable(typenumber, errorcorrectlevel); if (rsblock == undefined) throw new error("bad rs block @ typenumber:" + typenumber + "/errorcorrectlevel:" + errorcorrectlevel); var length = rsblock.length / 3, list = []; for (var i = 0; i < length; i++) { var count = rsblock[i * 3 + 0], totalcount = rsblock[i * 3 + 1], datacount = rsblock[i * 3 + 2]; for (var j = 0; j < count; j++) list.push(new qrrsblock(totalcount, datacount)); } return list; }, qrrsblock.getrsblocktable = function(typenumber, errorcorrectlevel) { switch (errorcorrectlevel) { case qrerrorcorrectlevel.l: return qrrsblock.rs_block_table[(typenumber - 1) * 4 + 0]; case qrerrorcorrectlevel.m: return qrrsblock.rs_block_table[(typenumber - 1) * 4 + 1]; case qrerrorcorrectlevel.q: return qrrsblock.rs_block_table[(typenumber - 1) * 4 + 2]; case qrerrorcorrectlevel.h: return qrrsblock.rs_block_table[(typenumber - 1) * 4 + 3]; default: return undefined; } }, qrbitbuffer.prototype = { "get": function(index) { var bufindex = math.floor(index / 8); return (this.buffer[bufindex] >>> 7 - index % 8 & 1) == 1; }, "put": function(num, length) { for (var i = 0; i < length; i++) this.putbit((num >>> length - i - 1 & 1) == 1); }, "getlengthinbits": function() { return this.length; }, "putbit": function(bit) { var bufindex = math.floor(this.length / 8); this.buffer.length <= bufindex && this.buffer.push(0), bit && (this.buffer[bufindex] |= 128 >>> this.length % 8), this.length++; } }; var qrcodelimitlength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; function _issupportcanvas() { return typeof canvasrenderingcontext2d != "undefined"; } // android 2.x doesn't support data-uri spec function _getandroid() { var android = false; var sagent = navigator.useragent; if (/android/i.test(sagent)) { // android android = true; amat = sagent.tostring().match(/android ([0-9]\.[0-9])/i); if (amat && amat[1]) { android = parsefloat(amat[1]); } } return android; } var svgdrawer = (function() { var drawing = function (el, htoption) { this._el = el; this._htoption = htoption; }; drawing.prototype.draw = function (oqrcode) { var _htoption = this._htoption; var _el = this._el; var ncount = oqrcode.getmodulecount(); var nwidth = math.floor(_htoption.width / ncount); var nheight = math.floor(_htoption.height / ncount); this.clear(); function makesvg(tag, attrs) { var el = document.createelementns('http://www.w3.org/2000/svg', tag); for (var k in attrs) if (attrs.hasownproperty(k)) el.setattribute(k, attrs[k]); return el; } var svg = makesvg("svg" , {'viewbox': '0 0 ' + string(ncount) + " " + string(ncount), 'width': '100%', 'height': '100%', 'fill': _htoption.colorlight}); svg.setattributens("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); _el.appendchild(svg); svg.appendchild(makesvg("rect", {"fill": _htoption.colordark, "width": "1", "height": "1", "id": "template"})); for (var row = 0; row < ncount; row++) { for (var col = 0; col < ncount; col++) { if (oqrcode.isdark(row, col)) { var child = makesvg("use", {"x": string(row), "y": string(col)}); child.setattributens("http://www.w3.org/1999/xlink", "href", "#template") svg.appendchild(child); } } } }; drawing.prototype.clear = function () { while (this._el.haschildnodes()) this._el.removechild(this._el.lastchild); }; return drawing; })(); var usesvg = document.documentelement.tagname.tolowercase() === "svg"; // drawing in dom by using table tag var drawing = usesvg ? svgdrawer : !_issupportcanvas() ? (function () { var drawing = function (el, htoption) { this._el = el; this._htoption = htoption; }; /** * draw the qrcode * * @param {qrcode} oqrcode */ drawing.prototype.draw = function (oqrcode) { var _htoption = this._htoption; var _el = this._el; var ncount = oqrcode.getmodulecount(); var nwidth = math.floor(_htoption.width / ncount); var nheight = math.floor(_htoption.height / ncount); var ahtml = ['']; for (var row = 0; row < ncount; row++) { ahtml.push(''); for (var col = 0; col < ncount; col++) { ahtml.push(''); } ahtml.push(''); } ahtml.push('
'); _el.innerhtml = ahtml.join(''); // fix the margin values as real size. var eltable = _el.childnodes[0]; var nleftmargintable = (_htoption.width - eltable.offsetwidth) / 2; var ntopmargintable = (_htoption.height - eltable.offsetheight) / 2; if (nleftmargintable > 0 && ntopmargintable > 0) { eltable.style.margin = ntopmargintable + "px " + nleftmargintable + "px"; } }; /** * clear the qrcode */ drawing.prototype.clear = function () { this._el.innerhtml = ''; }; return drawing; })() : (function () { // drawing in canvas function _onmakeimage() { this._elimage.src = this._elcanvas.todataurl("image/png"); this._elimage.style.display = "block"; this._elcanvas.style.display = "none"; } // android 2.1 bug workaround // http://code.google.com/p/android/issues/detail?id=5141 if (this._android && this._android <= 2.1) { var factor = 1 / window.devicepixelratio; var drawimage = canvasrenderingcontext2d.prototype.drawimage; canvasrenderingcontext2d.prototype.drawimage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { if (("nodename" in image) && /img/i.test(image.nodename)) { for (var i = arguments.length - 1; i >= 1; i--) { arguments[i] = arguments[i] * factor; } } else if (typeof dw == "undefined") { arguments[1] *= factor; arguments[2] *= factor; arguments[3] *= factor; arguments[4] *= factor; } drawimage.apply(this, arguments); }; } /** * check whether the user's browser supports data uri or not * * @private * @param {function} fsuccess occurs if it supports data uri * @param {function} ffail occurs if it doesn't support data uri */ function _safesetdatauri(fsuccess, ffail) { var self = this; self._ffail = ffail; self._fsuccess = fsuccess; // check it just once if (self._bsupportdatauri === null) { var el = document.createelement("img"); var fonerror = function() { self._bsupportdatauri = false; if (self._ffail) { _ffail.call(self); } }; var fonsuccess = function() { self._bsupportdatauri = true; if (self._fsuccess) { self._fsuccess.call(self); } }; el.onabort = fonerror; el.onerror = fonerror; el.onload = fonsuccess; el.src = "data:image/gif;base64,ivborw0kggoaaaansuheugaaaauaaaafcayaaacnbyblaaaaheleqvqi12p4//8/w38giaxdibke0dhxgljnbaao9txl0y4ohwaaaabjru5erkjggg=="; // the image contains 1px data. return; } else if (self._bsupportdatauri === true && self._fsuccess) { self._fsuccess.call(self); } else if (self._bsupportdatauri === false && self._ffail) { self._ffail.call(self); } }; /** * drawing qrcode by using canvas * * @constructor * @param {htmlelement} el * @param {object} htoption qrcode options */ var drawing = function (el, htoption) { this._bispainted = false; this._android = _getandroid(); this._htoption = htoption; this._elcanvas = document.createelement("canvas"); this._elcanvas.width = htoption.width; this._elcanvas.height = htoption.height; el.appendchild(this._elcanvas); this._el = el; this._ocontext = this._elcanvas.getcontext("2d"); this._bispainted = false; this._elimage = document.createelement("img"); this._elimage.alt = "scan me!"; this._elimage.style.display = "none"; this._el.appendchild(this._elimage); this._bsupportdatauri = null; }; /** * draw the qrcode * * @param {qrcode} oqrcode */ drawing.prototype.draw = function (oqrcode) { var _elimage = this._elimage; var _ocontext = this._ocontext; var _htoption = this._htoption; var ncount = oqrcode.getmodulecount(); var nwidth = _htoption.width / ncount; var nheight = _htoption.height / ncount; var nroundedwidth = math.round(nwidth); var nroundedheight = math.round(nheight); _elimage.style.display = "none"; this.clear(); for (var row = 0; row < ncount; row++) { for (var col = 0; col < ncount; col++) { var bisdark = oqrcode.isdark(row, col); var nleft = col * nwidth; var ntop = row * nheight; _ocontext.strokestyle = bisdark ? _htoption.colordark : _htoption.colorlight; _ocontext.linewidth = 1; _ocontext.fillstyle = bisdark ? _htoption.colordark : _htoption.colorlight; _ocontext.fillrect(nleft, ntop, nwidth, nheight); // 안티 앨리어싱 방지 처리 _ocontext.strokerect( math.floor(nleft) + 0.5, math.floor(ntop) + 0.5, nroundedwidth, nroundedheight ); _ocontext.strokerect( math.ceil(nleft) - 0.5, math.ceil(ntop) - 0.5, nroundedwidth, nroundedheight ); } } this._bispainted = true; }; /** * make the image from canvas if the browser supports data uri. */ drawing.prototype.makeimage = function () { if (this._bispainted) { _safesetdatauri.call(this, _onmakeimage); } }; /** * return whether the qrcode is painted or not * * @return {boolean} */ drawing.prototype.ispainted = function () { return this._bispainted; }; /** * clear the qrcode */ drawing.prototype.clear = function () { this._ocontext.clearrect(0, 0, this._elcanvas.width, this._elcanvas.height); this._bispainted = false; }; /** * @private * @param {number} nnumber */ drawing.prototype.round = function (nnumber) { if (!nnumber) { return nnumber; } return math.floor(nnumber * 1000) / 1000; }; return drawing; })(); /** * get the type by string length * * @private * @param {string} stext * @param {number} ncorrectlevel * @return {number} type */ function _gettypenumber(stext, ncorrectlevel) { var ntype = 1; var length = _getutf8length(stext); for (var i = 0, len = qrcodelimitlength.length; i <= len; i++) { var nlimit = 0; switch (ncorrectlevel) { case qrerrorcorrectlevel.l : nlimit = qrcodelimitlength[i][0]; break; case qrerrorcorrectlevel.m : nlimit = qrcodelimitlength[i][1]; break; case qrerrorcorrectlevel.q : nlimit = qrcodelimitlength[i][2]; break; case qrerrorcorrectlevel.h : nlimit = qrcodelimitlength[i][3]; break; } if (length <= nlimit) { break; } else { ntype++; } } if (ntype > qrcodelimitlength.length) { throw new error("too long data"); } return ntype; } function _getutf8length(stext) { var replacedtext = encodeuri(stext).tostring().replace(/\%[0-9a-fa-f]{2}/g, 'a'); return replacedtext.length + (replacedtext.length != stext ? 3 : 0); } /** * @class qrcode * @constructor * @example * new qrcode(document.getelementbyid("test"), "http://jindo.dev.naver.com/collie"); * * @example * var oqrcode = new qrcode("test", { * text : "http://naver.com", * width : 128, * height : 128 * }); * * oqrcode.clear(); // clear the qrcode. * oqrcode.makecode("http://map.naver.com"); // re-create the qrcode. * * @param {htmlelement|string} el target element or 'id' attribute of element. * @param {object|string} voption * @param {string} voption.text qrcode link data * @param {number} [voption.width=256] * @param {number} [voption.height=256] * @param {string} [voption.colordark="#000000"] * @param {string} [voption.colorlight="#ffffff"] * @param {qrcode.correctlevel} [voption.correctlevel=qrcode.correctlevel.h] [l|m|q|h] */ qrcode = function (el, voption) { this._htoption = { width : 256, height : 256, typenumber : 4, colordark : "#000000", colorlight : "#ffffff", correctlevel : qrerrorcorrectlevel.h }; if (typeof voption === 'string') { voption = { text : voption }; } // overwrites options if (voption) { for (var i in voption) { this._htoption[i] = voption[i]; } } if (typeof el == "string") { el = document.getelementbyid(el); } this._android = _getandroid(); this._el = el; this._oqrcode = null; this._odrawing = new drawing(this._el, this._htoption); if (this._htoption.text) { this.makecode(this._htoption.text); } }; /** * make the qrcode * * @param {string} stext link data */ qrcode.prototype.makecode = function (stext) { this._oqrcode = new qrcodemodel(_gettypenumber(stext, this._htoption.correctlevel), this._htoption.correctlevel); this._oqrcode.adddata(stext); this._oqrcode.make(); this._el.title = stext; this._odrawing.draw(this._oqrcode); this.makeimage(); }; /** * make the image from canvas element * - it occurs automatically * - android below 3 doesn't support data-uri spec. * * @private */ qrcode.prototype.makeimage = function () { if (typeof this._odrawing.makeimage == "function" && (!this._android || this._android >= 3)) { this._odrawing.makeimage(); } }; /** * clear the qrcode */ qrcode.prototype.clear = function () { this._odrawing.clear(); }; /** * @name qrcode.correctlevel */ qrcode.correctlevel = qrerrorcorrectlevel; })();