PluginProbe
Two Factor Authentication / 1.14.15
Two Factor Authentication v1.14.15
1.12.2 1.13.0 1.14.10 1.14.11 1.14.14 1.14.15 1.14.16 1.14.17 1.14.23 1.14.24 1.14.26 1.14.27 1.14.3 1.14.4 1.14.5 1.14.7 1.14.8 1.15.5 1.16.0 1.2.10 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 All 98 releases
two-factor-authentication / simba-tfa / includes / jquery-qrcode / jquery-qrcode.js

jquery-qrcode.js in Two Factor Authentication 1.14.15, at simba-tfa/includes/jquery-qrcode/jquery-qrcode.js

2,333 lines 64.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*! jquery-qrcode v0.14.0 - https://larsjung.de/jquery-qrcode/ */
2 (function (vendor_qrcode) {
3 'use strict';
4
5 var jq = window.jQuery;
6
7 // Check if canvas is available in the browser (as Modernizr does)
8 var hasCanvas = (function () {
9 var elem = document.createElement('canvas');
10 return !!(elem.getContext && elem.getContext('2d'));
11 }());
12
13 // Wrapper for the original QR code generator.
14 function createQRCode(text, level, version, quiet) {
15 var qr = {};
16
17 var vqr = vendor_qrcode(version, level);
18 vqr.addData(text);
19 vqr.make();
20
21 quiet = quiet || 0;
22
23 var qrModuleCount = vqr.getModuleCount();
24 var quietModuleCount = vqr.getModuleCount() + 2 * quiet;
25
26 function isDark(row, col) {
27 row -= quiet;
28 col -= quiet;
29
30 if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) {
31 return false;
32 }
33 return vqr.isDark(row, col);
34 }
35
36 function addBlank(l, t, r, b) {
37 var prevIsDark = qr.isDark;
38 var moduleSize = 1 / quietModuleCount;
39
40 qr.isDark = function (row, col) {
41 var ml = col * moduleSize;
42 var mt = row * moduleSize;
43 var mr = ml + moduleSize;
44 var mb = mt + moduleSize;
45
46 return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b);
47 };
48 }
49
50 qr.text = text;
51 qr.level = level;
52 qr.version = version;
53 qr.moduleCount = quietModuleCount;
54 qr.isDark = isDark;
55 qr.addBlank = addBlank;
56
57 return qr;
58 }
59
60 // Returns a minimal QR code for the given text starting with version `minVersion`.
61 // Returns `undefined` if `text` is too long to be encoded in `maxVersion`.
62 function createMinQRCode(text, level, minVersion, maxVersion, quiet) {
63 minVersion = Math.max(1, minVersion || 1);
64 maxVersion = Math.min(40, maxVersion || 40);
65 for (var version = minVersion; version <= maxVersion; version += 1) {
66 try {
67 return createQRCode(text, level, version, quiet);
68 } catch (err) {/* empty */}
69 }
70 return undefined;
71 }
72
73 function drawBackgroundLabel(qr, context, settings) {
74 var size = settings.size;
75 var font = 'bold ' + settings.mSize * size + 'px ' + settings.fontname;
76 var ctx = jq('<canvas/>')[0].getContext('2d');
77
78 ctx.font = font;
79
80 var w = ctx.measureText(settings.label).width;
81 var sh = settings.mSize;
82 var sw = w / size;
83 var sl = (1 - sw) * settings.mPosX;
84 var st = (1 - sh) * settings.mPosY;
85 var sr = sl + sw;
86 var sb = st + sh;
87 var pad = 0.01;
88
89 if (settings.mode === 1) {
90 // Strip
91 qr.addBlank(0, st - pad, size, sb + pad);
92 } else {
93 // Box
94 qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
95 }
96
97 context.fillStyle = settings.fontcolor;
98 context.font = font;
99 context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
100 }
101
102 function drawBackgroundImage(qr, context, settings) {
103 var size = settings.size;
104 var w = settings.image.naturalWidth || 1;
105 var h = settings.image.naturalHeight || 1;
106 var sh = settings.mSize;
107 var sw = sh * w / h;
108 var sl = (1 - sw) * settings.mPosX;
109 var st = (1 - sh) * settings.mPosY;
110 var sr = sl + sw;
111 var sb = st + sh;
112 var pad = 0.01;
113
114 if (settings.mode === 3) {
115 // Strip
116 qr.addBlank(0, st - pad, size, sb + pad);
117 } else {
118 // Box
119 qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
120 }
121
122 context.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
123 }
124
125 function drawBackground(qr, context, settings) {
126 if (jq(settings.background).is('img')) {
127 context.drawImage(settings.background, 0, 0, settings.size, settings.size);
128 } else if (settings.background) {
129 context.fillStyle = settings.background;
130 context.fillRect(settings.left, settings.top, settings.size, settings.size);
131 }
132
133 var mode = settings.mode;
134 if (mode === 1 || mode === 2) {
135 drawBackgroundLabel(qr, context, settings);
136 } else if (mode === 3 || mode === 4) {
137 drawBackgroundImage(qr, context, settings);
138 }
139 }
140
141 function drawModuleDefault(qr, context, settings, left, top, width, row, col) {
142 if (qr.isDark(row, col)) {
143 context.rect(left, top, width, width);
144 }
145 }
146
147 function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) {
148 if (nw) {
149 ctx.moveTo(l + rad, t);
150 } else {
151 ctx.moveTo(l, t);
152 }
153
154 if (ne) {
155 ctx.lineTo(r - rad, t);
156 ctx.arcTo(r, t, r, b, rad);
157 } else {
158 ctx.lineTo(r, t);
159 }
160
161 if (se) {
162 ctx.lineTo(r, b - rad);
163 ctx.arcTo(r, b, l, b, rad);
164 } else {
165 ctx.lineTo(r, b);
166 }
167
168 if (sw) {
169 ctx.lineTo(l + rad, b);
170 ctx.arcTo(l, b, l, t, rad);
171 } else {
172 ctx.lineTo(l, b);
173 }
174
175 if (nw) {
176 ctx.lineTo(l, t + rad);
177 ctx.arcTo(l, t, r, t, rad);
178 } else {
179 ctx.lineTo(l, t);
180 }
181 }
182
183 function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) {
184 if (nw) {
185 ctx.moveTo(l + rad, t);
186 ctx.lineTo(l, t);
187 ctx.lineTo(l, t + rad);
188 ctx.arcTo(l, t, l + rad, t, rad);
189 }
190
191 if (ne) {
192 ctx.moveTo(r - rad, t);
193 ctx.lineTo(r, t);
194 ctx.lineTo(r, t + rad);
195 ctx.arcTo(r, t, r - rad, t, rad);
196 }
197
198 if (se) {
199 ctx.moveTo(r - rad, b);
200 ctx.lineTo(r, b);
201 ctx.lineTo(r, b - rad);
202 ctx.arcTo(r, b, r - rad, b, rad);
203 }
204
205 if (sw) {
206 ctx.moveTo(l + rad, b);
207 ctx.lineTo(l, b);
208 ctx.lineTo(l, b - rad);
209 ctx.arcTo(l, b, l + rad, b, rad);
210 }
211 }
212
213 function drawModuleRounded(qr, context, settings, left, top, width, row, col) {
214 var isDark = qr.isDark;
215 var right = left + width;
216 var bottom = top + width;
217 var radius = settings.radius * width;
218 var rowT = row - 1;
219 var rowB = row + 1;
220 var colL = col - 1;
221 var colR = col + 1;
222 var center = isDark(row, col);
223 var northwest = isDark(rowT, colL);
224 var north = isDark(rowT, col);
225 var northeast = isDark(rowT, colR);
226 var east = isDark(row, colR);
227 var southeast = isDark(rowB, colR);
228 var south = isDark(rowB, col);
229 var southwest = isDark(rowB, colL);
230 var west = isDark(row, colL);
231
232 if (center) {
233 drawModuleRoundedDark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west);
234 } else {
235 drawModuleRoundendLight(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest);
236 }
237 }
238
239 function drawModules(qr, context, settings) {
240 var moduleCount = qr.moduleCount;
241 var moduleSize = settings.size / moduleCount;
242 var fn = drawModuleDefault;
243 var row;
244 var col;
245
246 if (settings.radius > 0 && settings.radius <= 0.5) {
247 fn = drawModuleRounded;
248 }
249
250 context.beginPath();
251 for (row = 0; row < moduleCount; row += 1) {
252 for (col = 0; col < moduleCount; col += 1) {
253 var l = settings.left + col * moduleSize;
254 var t = settings.top + row * moduleSize;
255 var w = moduleSize;
256
257 fn(qr, context, settings, l, t, w, row, col);
258 }
259 }
260 if (jq(settings.fill).is('img')) {
261 context.strokeStyle = 'rgba(0,0,0,0.5)';
262 context.lineWidth = 2;
263 context.stroke();
264 var prev = context.globalCompositeOperation;
265 context.globalCompositeOperation = 'destination-out';
266 context.fill();
267 context.globalCompositeOperation = prev;
268
269 context.clip();
270 context.drawImage(settings.fill, 0, 0, settings.size, settings.size);
271 context.restore();
272 } else {
273 context.fillStyle = settings.fill;
274 context.fill();
275 }
276 }
277
278 // Draws QR code to the given `canvas` and returns it.
279 function drawOnCanvas(canvas, settings) {
280 var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
281 if (!qr) {
282 return null;
283 }
284
285 var $canvas = jq(canvas).data('qrcode', qr);
286 var context = $canvas[0].getContext('2d');
287
288 drawBackground(qr, context, settings);
289 drawModules(qr, context, settings);
290
291 return $canvas;
292 }
293
294 // Returns a `canvas` element representing the QR code for the given settings.
295 function createCanvas(settings) {
296 var $canvas = jq('<canvas/>').attr('width', settings.size).attr('height', settings.size);
297 return drawOnCanvas($canvas, settings);
298 }
299
300 // Returns an `image` element representing the QR code for the given settings.
301 function createImage(settings) {
302 return jq('<img/>').attr('src', createCanvas(settings)[0].toDataURL('image/png'));
303 }
304
305 // Returns a `div` element representing the QR code for the given settings.
306 function createDiv(settings) {
307 var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
308 if (!qr) {
309 return null;
310 }
311
312 // some shortcuts to improve compression
313 var settings_size = settings.size;
314 var settings_bgColor = settings.background;
315 var math_floor = Math.floor;
316
317 var moduleCount = qr.moduleCount;
318 var moduleSize = math_floor(settings_size / moduleCount);
319 var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount));
320
321 var row;
322 var col;
323
324 var containerCSS = {
325 position: 'relative',
326 left: 0,
327 top: 0,
328 padding: 0,
329 margin: 0,
330 width: settings_size,
331 height: settings_size
332 };
333 var darkCSS = {
334 position: 'absolute',
335 padding: 0,
336 margin: 0,
337 width: moduleSize,
338 height: moduleSize,
339 'background-color': settings.fill
340 };
341
342 var $div = jq('<div/>').data('qrcode', qr).css(containerCSS);
343
344 if (settings_bgColor) {
345 $div.css('background-color', settings_bgColor);
346 }
347
348 for (row = 0; row < moduleCount; row += 1) {
349 for (col = 0; col < moduleCount; col += 1) {
350 if (qr.isDark(row, col)) {
351 jq('<div/>')
352 .css(darkCSS)
353 .css({
354 left: offset + col * moduleSize,
355 top: offset + row * moduleSize
356 })
357 .appendTo($div);
358 }
359 }
360 }
361
362 return $div;
363 }
364
365 function createHTML(settings) {
366 if (hasCanvas && settings.render === 'canvas') {
367 return createCanvas(settings);
368 } else if (hasCanvas && settings.render === 'image') {
369 return createImage(settings);
370 }
371
372 return createDiv(settings);
373 }
374
375 // Plugin
376 // ======
377
378 // Default settings
379 // ----------------
380 var defaults = {
381 // render method: `'canvas'`, `'image'` or `'div'`
382 render: 'canvas',
383
384 // version range somewhere in 1 .. 40
385 minVersion: 1,
386 maxVersion: 40,
387
388 // error correction level: `'L'`, `'M'`, `'Q'` or `'H'`
389 ecLevel: 'L',
390
391 // offset in pixel if drawn onto existing canvas
392 left: 0,
393 top: 0,
394
395 // size in pixel
396 size: 200,
397
398 // code color or image element
399 fill: '#000',
400
401 // background color or image element, `null` for transparent background
402 background: null,
403
404 // content
405 text: 'no text',
406
407 // corner radius relative to module width: 0.0 .. 0.5
408 radius: 0,
409
410 // quiet zone in modules
411 quiet: 0,
412
413 // modes
414 // 0: normal
415 // 1: label strip
416 // 2: label box
417 // 3: image strip
418 // 4: image box
419 mode: 0,
420
421 mSize: 0.1,
422 mPosX: 0.5,
423 mPosY: 0.5,
424
425 label: 'no label',
426 fontname: 'sans',
427 fontcolor: '#000',
428
429 image: null
430 };
431
432 // Register the plugin
433 // -------------------
434 jq.fn.qrcode = function (options) {
435 var settings = jq.extend({}, defaults, options);
436
437 return this.each(function (idx, el) {
438 if (el.nodeName.toLowerCase() === 'canvas') {
439 drawOnCanvas(el, settings);
440 } else {
441 jq(el).append(createHTML(settings));
442 }
443 });
444 };
445 }(function () {
446 // `qrcode` is the single public function defined by the `QR Code Generator`
447 //---------------------------------------------------------------------
448 //
449 // QR Code Generator for JavaScript
450 //
451 // Copyright (c) 2009 Kazuhiko Arase
452 //
453 // URL: http://www.d-project.com/
454 //
455 // Licensed under the MIT license:
456 // http://www.opensource.org/licenses/mit-license.php
457 //
458 // The word 'QR Code' is registered trademark of
459 // DENSO WAVE INCORPORATED
460 // http://www.denso-wave.com/qrcode/faqpatent-e.html
461 //
462 //---------------------------------------------------------------------
463
464 var qrcode = function() {
465
466 //---------------------------------------------------------------------
467 // qrcode
468 //---------------------------------------------------------------------
469
470 /**
471 * qrcode
472 * @param typeNumber 1 to 40
473 * @param errorCorrectLevel 'L','M','Q','H'
474 */
475 var qrcode = function(typeNumber, errorCorrectLevel) {
476
477 var PAD0 = 0xEC;
478 var PAD1 = 0x11;
479
480 var _typeNumber = typeNumber;
481 var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel];
482 var _modules = null;
483 var _moduleCount = 0;
484 var _dataCache = null;
485 var _dataList = new Array();
486
487 var _this = {};
488
489 var makeImpl = function(test, maskPattern) {
490
491 _moduleCount = _typeNumber * 4 + 17;
492 _modules = function(moduleCount) {
493 var modules = new Array(moduleCount);
494 for (var row = 0; row < moduleCount; row += 1) {
495 modules[row] = new Array(moduleCount);
496 for (var col = 0; col < moduleCount; col += 1) {
497 modules[row][col] = null;
498 }
499 }
500 return modules;
501 }(_moduleCount);
502
503 setupPositionProbePattern(0, 0);
504 setupPositionProbePattern(_moduleCount - 7, 0);
505 setupPositionProbePattern(0, _moduleCount - 7);
506 setupPositionAdjustPattern();
507 setupTimingPattern();
508 setupTypeInfo(test, maskPattern);
509
510 if (_typeNumber >= 7) {
511 setupTypeNumber(test);
512 }
513
514 if (_dataCache == null) {
515 _dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList);
516 }
517
518 mapData(_dataCache, maskPattern);
519 };
520
521 var setupPositionProbePattern = function(row, col) {
522
523 for (var r = -1; r <= 7; r += 1) {
524
525 if (row + r <= -1 || _moduleCount <= row + r) continue;
526
527 for (var c = -1; c <= 7; c += 1) {
528
529 if (col + c <= -1 || _moduleCount <= col + c) continue;
530
531 if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
532 || (0 <= c && c <= 6 && (r == 0 || r == 6) )
533 || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
534 _modules[row + r][col + c] = true;
535 } else {
536 _modules[row + r][col + c] = false;
537 }
538 }
539 }
540 };
541
542 var getBestMaskPattern = function() {
543
544 var minLostPoint = 0;
545 var pattern = 0;
546
547 for (var i = 0; i < 8; i += 1) {
548
549 makeImpl(true, i);
550
551 var lostPoint = QRUtil.getLostPoint(_this);
552
553 if (i == 0 || minLostPoint > lostPoint) {
554 minLostPoint = lostPoint;
555 pattern = i;
556 }
557 }
558
559 return pattern;
560 };
561
562 var setupTimingPattern = function() {
563
564 for (var r = 8; r < _moduleCount - 8; r += 1) {
565 if (_modules[r][6] != null) {
566 continue;
567 }
568 _modules[r][6] = (r % 2 == 0);
569 }
570
571 for (var c = 8; c < _moduleCount - 8; c += 1) {
572 if (_modules[6][c] != null) {
573 continue;
574 }
575 _modules[6][c] = (c % 2 == 0);
576 }
577 };
578
579 var setupPositionAdjustPattern = function() {
580
581 var pos = QRUtil.getPatternPosition(_typeNumber);
582
583 for (var i = 0; i < pos.length; i += 1) {
584
585 for (var j = 0; j < pos.length; j += 1) {
586
587 var row = pos[i];
588 var col = pos[j];
589
590 if (_modules[row][col] != null) {
591 continue;
592 }
593
594 for (var r = -2; r <= 2; r += 1) {
595
596 for (var c = -2; c <= 2; c += 1) {
597
598 if (r == -2 || r == 2 || c == -2 || c == 2
599 || (r == 0 && c == 0) ) {
600 _modules[row + r][col + c] = true;
601 } else {
602 _modules[row + r][col + c] = false;
603 }
604 }
605 }
606 }
607 }
608 };
609
610 var setupTypeNumber = function(test) {
611
612 var bits = QRUtil.getBCHTypeNumber(_typeNumber);
613
614 for (var i = 0; i < 18; i += 1) {
615 var mod = (!test && ( (bits >> i) & 1) == 1);
616 _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
617 }
618
619 for (var i = 0; i < 18; i += 1) {
620 var mod = (!test && ( (bits >> i) & 1) == 1);
621 _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
622 }
623 };
624
625 var setupTypeInfo = function(test, maskPattern) {
626
627 var data = (_errorCorrectLevel << 3) | maskPattern;
628 var bits = QRUtil.getBCHTypeInfo(data);
629
630 // vertical
631 for (var i = 0; i < 15; i += 1) {
632
633 var mod = (!test && ( (bits >> i) & 1) == 1);
634
635 if (i < 6) {
636 _modules[i][8] = mod;
637 } else if (i < 8) {
638 _modules[i + 1][8] = mod;
639 } else {
640 _modules[_moduleCount - 15 + i][8] = mod;
641 }
642 }
643
644 // horizontal
645 for (var i = 0; i < 15; i += 1) {
646
647 var mod = (!test && ( (bits >> i) & 1) == 1);
648
649 if (i < 8) {
650 _modules[8][_moduleCount - i - 1] = mod;
651 } else if (i < 9) {
652 _modules[8][15 - i - 1 + 1] = mod;
653 } else {
654 _modules[8][15 - i - 1] = mod;
655 }
656 }
657
658 // fixed module
659 _modules[_moduleCount - 8][8] = (!test);
660 };
661
662 var mapData = function(data, maskPattern) {
663
664 var inc = -1;
665 var row = _moduleCount - 1;
666 var bitIndex = 7;
667 var byteIndex = 0;
668 var maskFunc = QRUtil.getMaskFunction(maskPattern);
669
670 for (var col = _moduleCount - 1; col > 0; col -= 2) {
671
672 if (col == 6) col -= 1;
673
674 while (true) {
675
676 for (var c = 0; c < 2; c += 1) {
677
678 if (_modules[row][col - c] == null) {
679
680 var dark = false;
681
682 if (byteIndex < data.length) {
683 dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
684 }
685
686 var mask = maskFunc(row, col - c);
687
688 if (mask) {
689 dark = !dark;
690 }
691
692 _modules[row][col - c] = dark;
693 bitIndex -= 1;
694
695 if (bitIndex == -1) {
696 byteIndex += 1;
697 bitIndex = 7;
698 }
699 }
700 }
701
702 row += inc;
703
704 if (row < 0 || _moduleCount <= row) {
705 row -= inc;
706 inc = -inc;
707 break;
708 }
709 }
710 }
711 };
712
713 var createBytes = function(buffer, rsBlocks) {
714
715 var offset = 0;
716
717 var maxDcCount = 0;
718 var maxEcCount = 0;
719
720 var dcdata = new Array(rsBlocks.length);
721 var ecdata = new Array(rsBlocks.length);
722
723 for (var r = 0; r < rsBlocks.length; r += 1) {
724
725 var dcCount = rsBlocks[r].dataCount;
726 var ecCount = rsBlocks[r].totalCount - dcCount;
727
728 maxDcCount = Math.max(maxDcCount, dcCount);
729 maxEcCount = Math.max(maxEcCount, ecCount);
730
731 dcdata[r] = new Array(dcCount);
732
733 for (var i = 0; i < dcdata[r].length; i += 1) {
734 dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
735 }
736 offset += dcCount;
737
738 var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
739 var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
740
741 var modPoly = rawPoly.mod(rsPoly);
742 ecdata[r] = new Array(rsPoly.getLength() - 1);
743 for (var i = 0; i < ecdata[r].length; i += 1) {
744 var modIndex = i + modPoly.getLength() - ecdata[r].length;
745 ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;
746 }
747 }
748
749 var totalCodeCount = 0;
750 for (var i = 0; i < rsBlocks.length; i += 1) {
751 totalCodeCount += rsBlocks[i].totalCount;
752 }
753
754 var data = new Array(totalCodeCount);
755 var index = 0;
756
757 for (var i = 0; i < maxDcCount; i += 1) {
758 for (var r = 0; r < rsBlocks.length; r += 1) {
759 if (i < dcdata[r].length) {
760 data[index] = dcdata[r][i];
761 index += 1;
762 }
763 }
764 }
765
766 for (var i = 0; i < maxEcCount; i += 1) {
767 for (var r = 0; r < rsBlocks.length; r += 1) {
768 if (i < ecdata[r].length) {
769 data[index] = ecdata[r][i];
770 index += 1;
771 }
772 }
773 }
774
775 return data;
776 };
777
778 var createData = function(typeNumber, errorCorrectLevel, dataList) {
779
780 var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
781
782 var buffer = qrBitBuffer();
783
784 for (var i = 0; i < dataList.length; i += 1) {
785 var data = dataList[i];
786 buffer.put(data.getMode(), 4);
787 buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
788 data.write(buffer);
789 }
790
791 // calc num max data.
792 var totalDataCount = 0;
793 for (var i = 0; i < rsBlocks.length; i += 1) {
794 totalDataCount += rsBlocks[i].dataCount;
795 }
796
797 if (buffer.getLengthInBits() > totalDataCount * 8) {
798 throw new Error('code length overflow. ('
799 + buffer.getLengthInBits()
800 + '>'
801 + totalDataCount * 8
802 + ')');
803 }
804
805 // end code
806 if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
807 buffer.put(0, 4);
808 }
809
810 // padding
811 while (buffer.getLengthInBits() % 8 != 0) {
812 buffer.putBit(false);
813 }
814
815 // padding
816 while (true) {
817
818 if (buffer.getLengthInBits() >= totalDataCount * 8) {
819 break;
820 }
821 buffer.put(PAD0, 8);
822
823 if (buffer.getLengthInBits() >= totalDataCount * 8) {
824 break;
825 }
826 buffer.put(PAD1, 8);
827 }
828
829 return createBytes(buffer, rsBlocks);
830 };
831
832 _this.addData = function(data) {
833 var newData = qr8BitByte(data);
834 _dataList.push(newData);
835 _dataCache = null;
836 };
837
838 _this.isDark = function(row, col) {
839 if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
840 throw new Error(row + ',' + col);
841 }
842 return _modules[row][col];
843 };
844
845 _this.getModuleCount = function() {
846 return _moduleCount;
847 };
848
849 _this.make = function() {
850 makeImpl(false, getBestMaskPattern() );
851 };
852
853 _this.createTableTag = function(cellSize, margin) {
854
855 cellSize = cellSize || 2;
856 margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
857
858 var qrHtml = '';
859
860 qrHtml += '<table style="';
861 qrHtml += ' border-width: 0px; border-style: none;';
862 qrHtml += ' border-collapse: collapse;';
863 qrHtml += ' padding: 0px; margin: ' + margin + 'px;';
864 qrHtml += '">';
865 qrHtml += '<tbody>';
866
867 for (var r = 0; r < _this.getModuleCount(); r += 1) {
868
869 qrHtml += '<tr>';
870
871 for (var c = 0; c < _this.getModuleCount(); c += 1) {
872 qrHtml += '<td style="';
873 qrHtml += ' border-width: 0px; border-style: none;';
874 qrHtml += ' border-collapse: collapse;';
875 qrHtml += ' padding: 0px; margin: 0px;';
876 qrHtml += ' width: ' + cellSize + 'px;';
877 qrHtml += ' height: ' + cellSize + 'px;';
878 qrHtml += ' background-color: ';
879 qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';
880 qrHtml += ';';
881 qrHtml += '"/>';
882 }
883
884 qrHtml += '</tr>';
885 }
886
887 qrHtml += '</tbody>';
888 qrHtml += '</table>';
889
890 return qrHtml;
891 };
892
893 _this.createImgTag = function(cellSize, margin) {
894
895 cellSize = cellSize || 2;
896 margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
897
898 var size = _this.getModuleCount() * cellSize + margin * 2;
899 var min = margin;
900 var max = size - margin;
901
902 return createImgTag(size, size, function(x, y) {
903 if (min <= x && x < max && min <= y && y < max) {
904 var c = Math.floor( (x - min) / cellSize);
905 var r = Math.floor( (y - min) / cellSize);
906 return _this.isDark(r, c)? 0 : 1;
907 } else {
908 return 1;
909 }
910 } );
911 };
912
913 return _this;
914 };
915
916 //---------------------------------------------------------------------
917 // qrcode.stringToBytes
918 //---------------------------------------------------------------------
919
920 qrcode.stringToBytes = function(s) {
921 var bytes = new Array();
922 for (var i = 0; i < s.length; i += 1) {
923 var c = s.charCodeAt(i);
924 bytes.push(c & 0xff);
925 }
926 return bytes;
927 };
928
929 //---------------------------------------------------------------------
930 // qrcode.createStringToBytes
931 //---------------------------------------------------------------------
932
933 /**
934 * @param unicodeData base64 string of byte array.
935 * [16bit Unicode],[16bit Bytes], ...
936 * @param numChars
937 */
938 qrcode.createStringToBytes = function(unicodeData, numChars) {
939
940 // create conversion map.
941
942 var unicodeMap = function() {
943
944 var bin = base64DecodeInputStream(unicodeData);
945 var read = function() {
946 var b = bin.read();
947 if (b == -1) throw new Error();
948 return b;
949 };
950
951 var count = 0;
952 var unicodeMap = {};
953 while (true) {
954 var b0 = bin.read();
955 if (b0 == -1) break;
956 var b1 = read();
957 var b2 = read();
958 var b3 = read();
959 var k = String.fromCharCode( (b0 << 8) | b1);
960 var v = (b2 << 8) | b3;
961 unicodeMap[k] = v;
962 count += 1;
963 }
964 if (count != numChars) {
965 throw new Error(count + ' != ' + numChars);
966 }
967
968 return unicodeMap;
969 }();
970
971 var unknownChar = '?'.charCodeAt(0);
972
973 return function(s) {
974 var bytes = new Array();
975 for (var i = 0; i < s.length; i += 1) {
976 var c = s.charCodeAt(i);
977 if (c < 128) {
978 bytes.push(c);
979 } else {
980 var b = unicodeMap[s.charAt(i)];
981 if (typeof b == 'number') {
982 if ( (b & 0xff) == b) {
983 // 1byte
984 bytes.push(b);
985 } else {
986 // 2bytes
987 bytes.push(b >>> 8);
988 bytes.push(b & 0xff);
989 }
990 } else {
991 bytes.push(unknownChar);
992 }
993 }
994 }
995 return bytes;
996 };
997 };
998
999 //---------------------------------------------------------------------
1000 // QRMode
1001 //---------------------------------------------------------------------
1002
1003 var QRMode = {
1004 MODE_NUMBER : 1 << 0,
1005 MODE_ALPHA_NUM : 1 << 1,
1006 MODE_8BIT_BYTE : 1 << 2,
1007 MODE_KANJI : 1 << 3
1008 };
1009
1010 //---------------------------------------------------------------------
1011 // QRErrorCorrectLevel
1012 //---------------------------------------------------------------------
1013
1014 var QRErrorCorrectLevel = {
1015 L : 1,
1016 M : 0,
1017 Q : 3,
1018 H : 2
1019 };
1020
1021 //---------------------------------------------------------------------
1022 // QRMaskPattern
1023 //---------------------------------------------------------------------
1024
1025 var QRMaskPattern = {
1026 PATTERN000 : 0,
1027 PATTERN001 : 1,
1028 PATTERN010 : 2,
1029 PATTERN011 : 3,
1030 PATTERN100 : 4,
1031 PATTERN101 : 5,
1032 PATTERN110 : 6,
1033 PATTERN111 : 7
1034 };
1035
1036 //---------------------------------------------------------------------
1037 // QRUtil
1038 //---------------------------------------------------------------------
1039
1040 var QRUtil = function() {
1041
1042 var PATTERN_POSITION_TABLE = [
1043 [],
1044 [6, 18],
1045 [6, 22],
1046 [6, 26],
1047 [6, 30],
1048 [6, 34],
1049 [6, 22, 38],
1050 [6, 24, 42],
1051 [6, 26, 46],
1052 [6, 28, 50],
1053 [6, 30, 54],
1054 [6, 32, 58],
1055 [6, 34, 62],
1056 [6, 26, 46, 66],
1057 [6, 26, 48, 70],
1058 [6, 26, 50, 74],
1059 [6, 30, 54, 78],
1060 [6, 30, 56, 82],
1061 [6, 30, 58, 86],
1062 [6, 34, 62, 90],
1063 [6, 28, 50, 72, 94],
1064 [6, 26, 50, 74, 98],
1065 [6, 30, 54, 78, 102],
1066 [6, 28, 54, 80, 106],
1067 [6, 32, 58, 84, 110],
1068 [6, 30, 58, 86, 114],
1069 [6, 34, 62, 90, 118],
1070 [6, 26, 50, 74, 98, 122],
1071 [6, 30, 54, 78, 102, 126],
1072 [6, 26, 52, 78, 104, 130],
1073 [6, 30, 56, 82, 108, 134],
1074 [6, 34, 60, 86, 112, 138],
1075 [6, 30, 58, 86, 114, 142],
1076 [6, 34, 62, 90, 118, 146],
1077 [6, 30, 54, 78, 102, 126, 150],
1078 [6, 24, 50, 76, 102, 128, 154],
1079 [6, 28, 54, 80, 106, 132, 158],
1080 [6, 32, 58, 84, 110, 136, 162],
1081 [6, 26, 54, 82, 110, 138, 166],
1082 [6, 30, 58, 86, 114, 142, 170]
1083 ];
1084 var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
1085 var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
1086 var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
1087
1088 var _this = {};
1089
1090 var getBCHDigit = function(data) {
1091 var digit = 0;
1092 while (data != 0) {
1093 digit += 1;
1094 data >>>= 1;
1095 }
1096 return digit;
1097 };
1098
1099 _this.getBCHTypeInfo = function(data) {
1100 var d = data << 10;
1101 while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {
1102 d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );
1103 }
1104 return ( (data << 10) | d) ^ G15_MASK;
1105 };
1106
1107 _this.getBCHTypeNumber = function(data) {
1108 var d = data << 12;
1109 while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {
1110 d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );
1111 }
1112 return (data << 12) | d;
1113 };
1114
1115 _this.getPatternPosition = function(typeNumber) {
1116 return PATTERN_POSITION_TABLE[typeNumber - 1];
1117 };
1118
1119 _this.getMaskFunction = function(maskPattern) {
1120
1121 switch (maskPattern) {
1122
1123 case QRMaskPattern.PATTERN000 :
1124 return function(i, j) { return (i + j) % 2 == 0; };
1125 case QRMaskPattern.PATTERN001 :
1126 return function(i, j) { return i % 2 == 0; };
1127 case QRMaskPattern.PATTERN010 :
1128 return function(i, j) { return j % 3 == 0; };
1129 case QRMaskPattern.PATTERN011 :
1130 return function(i, j) { return (i + j) % 3 == 0; };
1131 case QRMaskPattern.PATTERN100 :
1132 return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };
1133 case QRMaskPattern.PATTERN101 :
1134 return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };
1135 case QRMaskPattern.PATTERN110 :
1136 return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };
1137 case QRMaskPattern.PATTERN111 :
1138 return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };
1139
1140 default :
1141 throw new Error('bad maskPattern:' + maskPattern);
1142 }
1143 };
1144
1145 _this.getErrorCorrectPolynomial = function(errorCorrectLength) {
1146 var a = qrPolynomial([1], 0);
1147 for (var i = 0; i < errorCorrectLength; i += 1) {
1148 a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );
1149 }
1150 return a;
1151 };
1152
1153 _this.getLengthInBits = function(mode, type) {
1154
1155 if (1 <= type && type < 10) {
1156
1157 // 1 - 9
1158
1159 switch(mode) {
1160 case QRMode.MODE_NUMBER : return 10;
1161 case QRMode.MODE_ALPHA_NUM : return 9;
1162 case QRMode.MODE_8BIT_BYTE : return 8;
1163 case QRMode.MODE_KANJI : return 8;
1164 default :
1165 throw new Error('mode:' + mode);
1166 }
1167
1168 } else if (type < 27) {
1169
1170 // 10 - 26
1171
1172 switch(mode) {
1173 case QRMode.MODE_NUMBER : return 12;
1174 case QRMode.MODE_ALPHA_NUM : return 11;
1175 case QRMode.MODE_8BIT_BYTE : return 16;
1176 case QRMode.MODE_KANJI : return 10;
1177 default :
1178 throw new Error('mode:' + mode);
1179 }
1180
1181 } else if (type < 41) {
1182
1183 // 27 - 40
1184
1185 switch(mode) {
1186 case QRMode.MODE_NUMBER : return 14;
1187 case QRMode.MODE_ALPHA_NUM : return 13;
1188 case QRMode.MODE_8BIT_BYTE : return 16;
1189 case QRMode.MODE_KANJI : return 12;
1190 default :
1191 throw new Error('mode:' + mode);
1192 }
1193
1194 } else {
1195 throw new Error('type:' + type);
1196 }
1197 };
1198
1199 _this.getLostPoint = function(qrcode) {
1200
1201 var moduleCount = qrcode.getModuleCount();
1202
1203 var lostPoint = 0;
1204
1205 // LEVEL1
1206
1207 for (var row = 0; row < moduleCount; row += 1) {
1208 for (var col = 0; col < moduleCount; col += 1) {
1209
1210 var sameCount = 0;
1211 var dark = qrcode.isDark(row, col);
1212
1213 for (var r = -1; r <= 1; r += 1) {
1214
1215 if (row + r < 0 || moduleCount <= row + r) {
1216 continue;
1217 }
1218
1219 for (var c = -1; c <= 1; c += 1) {
1220
1221 if (col + c < 0 || moduleCount <= col + c) {
1222 continue;
1223 }
1224
1225 if (r == 0 && c == 0) {
1226 continue;
1227 }
1228
1229 if (dark == qrcode.isDark(row + r, col + c) ) {
1230 sameCount += 1;
1231 }
1232 }
1233 }
1234
1235 if (sameCount > 5) {
1236 lostPoint += (3 + sameCount - 5);
1237 }
1238 }
1239 };
1240
1241 // LEVEL2
1242
1243 for (var row = 0; row < moduleCount - 1; row += 1) {
1244 for (var col = 0; col < moduleCount - 1; col += 1) {
1245 var count = 0;
1246 if (qrcode.isDark(row, col) ) count += 1;
1247 if (qrcode.isDark(row + 1, col) ) count += 1;
1248 if (qrcode.isDark(row, col + 1) ) count += 1;
1249 if (qrcode.isDark(row + 1, col + 1) ) count += 1;
1250 if (count == 0 || count == 4) {
1251 lostPoint += 3;
1252 }
1253 }
1254 }
1255
1256 // LEVEL3
1257
1258 for (var row = 0; row < moduleCount; row += 1) {
1259 for (var col = 0; col < moduleCount - 6; col += 1) {
1260 if (qrcode.isDark(row, col)
1261 && !qrcode.isDark(row, col + 1)
1262 && qrcode.isDark(row, col + 2)
1263 && qrcode.isDark(row, col + 3)
1264 && qrcode.isDark(row, col + 4)
1265 && !qrcode.isDark(row, col + 5)
1266 && qrcode.isDark(row, col + 6) ) {
1267 lostPoint += 40;
1268 }
1269 }
1270 }
1271
1272 for (var col = 0; col < moduleCount; col += 1) {
1273 for (var row = 0; row < moduleCount - 6; row += 1) {
1274 if (qrcode.isDark(row, col)
1275 && !qrcode.isDark(row + 1, col)
1276 && qrcode.isDark(row + 2, col)
1277 && qrcode.isDark(row + 3, col)
1278 && qrcode.isDark(row + 4, col)
1279 && !qrcode.isDark(row + 5, col)
1280 && qrcode.isDark(row + 6, col) ) {
1281 lostPoint += 40;
1282 }
1283 }
1284 }
1285
1286 // LEVEL4
1287
1288 var darkCount = 0;
1289
1290 for (var col = 0; col < moduleCount; col += 1) {
1291 for (var row = 0; row < moduleCount; row += 1) {
1292 if (qrcode.isDark(row, col) ) {
1293 darkCount += 1;
1294 }
1295 }
1296 }
1297
1298 var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
1299 lostPoint += ratio * 10;
1300
1301 return lostPoint;
1302 };
1303
1304 return _this;
1305 }();
1306
1307 //---------------------------------------------------------------------
1308 // QRMath
1309 //---------------------------------------------------------------------
1310
1311 var QRMath = function() {
1312
1313 var EXP_TABLE = new Array(256);
1314 var LOG_TABLE = new Array(256);
1315
1316 // initialize tables
1317 for (var i = 0; i < 8; i += 1) {
1318 EXP_TABLE[i] = 1 << i;
1319 }
1320 for (var i = 8; i < 256; i += 1) {
1321 EXP_TABLE[i] = EXP_TABLE[i - 4]
1322 ^ EXP_TABLE[i - 5]
1323 ^ EXP_TABLE[i - 6]
1324 ^ EXP_TABLE[i - 8];
1325 }
1326 for (var i = 0; i < 255; i += 1) {
1327 LOG_TABLE[EXP_TABLE[i] ] = i;
1328 }
1329
1330 var _this = {};
1331
1332 _this.glog = function(n) {
1333
1334 if (n < 1) {
1335 throw new Error('glog(' + n + ')');
1336 }
1337
1338 return LOG_TABLE[n];
1339 };
1340
1341 _this.gexp = function(n) {
1342
1343 while (n < 0) {
1344 n += 255;
1345 }
1346
1347 while (n >= 256) {
1348 n -= 255;
1349 }
1350
1351 return EXP_TABLE[n];
1352 };
1353
1354 return _this;
1355 }();
1356
1357 //---------------------------------------------------------------------
1358 // qrPolynomial
1359 //---------------------------------------------------------------------
1360
1361 function qrPolynomial(num, shift) {
1362
1363 if (typeof num.length == 'undefined') {
1364 throw new Error(num.length + '/' + shift);
1365 }
1366
1367 var _num = function() {
1368 var offset = 0;
1369 while (offset < num.length && num[offset] == 0) {
1370 offset += 1;
1371 }
1372 var _num = new Array(num.length - offset + shift);
1373 for (var i = 0; i < num.length - offset; i += 1) {
1374 _num[i] = num[i + offset];
1375 }
1376 return _num;
1377 }();
1378
1379 var _this = {};
1380
1381 _this.getAt = function(index) {
1382 return _num[index];
1383 };
1384
1385 _this.getLength = function() {
1386 return _num.length;
1387 };
1388
1389 _this.multiply = function(e) {
1390
1391 var num = new Array(_this.getLength() + e.getLength() - 1);
1392
1393 for (var i = 0; i < _this.getLength(); i += 1) {
1394 for (var j = 0; j < e.getLength(); j += 1) {
1395 num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );
1396 }
1397 }
1398
1399 return qrPolynomial(num, 0);
1400 };
1401
1402 _this.mod = function(e) {
1403
1404 if (_this.getLength() - e.getLength() < 0) {
1405 return _this;
1406 }
1407
1408 var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );
1409
1410 var num = new Array(_this.getLength() );
1411 for (var i = 0; i < _this.getLength(); i += 1) {
1412 num[i] = _this.getAt(i);
1413 }
1414
1415 for (var i = 0; i < e.getLength(); i += 1) {
1416 num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);
1417 }
1418
1419 // recursive call
1420 return qrPolynomial(num, 0).mod(e);
1421 };
1422
1423 return _this;
1424 };
1425
1426 //---------------------------------------------------------------------
1427 // QRRSBlock
1428 //---------------------------------------------------------------------
1429
1430 var QRRSBlock = function() {
1431
1432 var RS_BLOCK_TABLE = [
1433
1434 // L
1435 // M
1436 // Q
1437 // H
1438
1439 // 1
1440 [1, 26, 19],
1441 [1, 26, 16],
1442 [1, 26, 13],
1443 [1, 26, 9],
1444
1445 // 2
1446 [1, 44, 34],
1447 [1, 44, 28],
1448 [1, 44, 22],
1449 [1, 44, 16],
1450
1451 // 3
1452 [1, 70, 55],
1453 [1, 70, 44],
1454 [2, 35, 17],
1455 [2, 35, 13],
1456
1457 // 4
1458 [1, 100, 80],
1459 [2, 50, 32],
1460 [2, 50, 24],
1461 [4, 25, 9],
1462
1463 // 5
1464 [1, 134, 108],
1465 [2, 67, 43],
1466 [2, 33, 15, 2, 34, 16],
1467 [2, 33, 11, 2, 34, 12],
1468
1469 // 6
1470 [2, 86, 68],
1471 [4, 43, 27],
1472 [4, 43, 19],
1473 [4, 43, 15],
1474
1475 // 7
1476 [2, 98, 78],
1477 [4, 49, 31],
1478 [2, 32, 14, 4, 33, 15],
1479 [4, 39, 13, 1, 40, 14],
1480
1481 // 8
1482 [2, 121, 97],
1483 [2, 60, 38, 2, 61, 39],
1484 [4, 40, 18, 2, 41, 19],
1485 [4, 40, 14, 2, 41, 15],
1486
1487 // 9
1488 [2, 146, 116],
1489 [3, 58, 36, 2, 59, 37],
1490 [4, 36, 16, 4, 37, 17],
1491 [4, 36, 12, 4, 37, 13],
1492
1493 // 10
1494 [2, 86, 68, 2, 87, 69],
1495 [4, 69, 43, 1, 70, 44],
1496 [6, 43, 19, 2, 44, 20],
1497 [6, 43, 15, 2, 44, 16],
1498
1499 // 11
1500 [4, 101, 81],
1501 [1, 80, 50, 4, 81, 51],
1502 [4, 50, 22, 4, 51, 23],
1503 [3, 36, 12, 8, 37, 13],
1504
1505 // 12
1506 [2, 116, 92, 2, 117, 93],
1507 [6, 58, 36, 2, 59, 37],
1508 [4, 46, 20, 6, 47, 21],
1509 [7, 42, 14, 4, 43, 15],
1510
1511 // 13
1512 [4, 133, 107],
1513 [8, 59, 37, 1, 60, 38],
1514 [8, 44, 20, 4, 45, 21],
1515 [12, 33, 11, 4, 34, 12],
1516
1517 // 14
1518 [3, 145, 115, 1, 146, 116],
1519 [4, 64, 40, 5, 65, 41],
1520 [11, 36, 16, 5, 37, 17],
1521 [11, 36, 12, 5, 37, 13],
1522
1523 // 15
1524 [5, 109, 87, 1, 110, 88],
1525 [5, 65, 41, 5, 66, 42],
1526 [5, 54, 24, 7, 55, 25],
1527 [11, 36, 12, 7, 37, 13],
1528
1529 // 16
1530 [5, 122, 98, 1, 123, 99],
1531 [7, 73, 45, 3, 74, 46],
1532 [15, 43, 19, 2, 44, 20],
1533 [3, 45, 15, 13, 46, 16],
1534
1535 // 17
1536 [1, 135, 107, 5, 136, 108],
1537 [10, 74, 46, 1, 75, 47],
1538 [1, 50, 22, 15, 51, 23],
1539 [2, 42, 14, 17, 43, 15],
1540
1541 // 18
1542 [5, 150, 120, 1, 151, 121],
1543 [9, 69, 43, 4, 70, 44],
1544 [17, 50, 22, 1, 51, 23],
1545 [2, 42, 14, 19, 43, 15],
1546
1547 // 19
1548 [3, 141, 113, 4, 142, 114],
1549 [3, 70, 44, 11, 71, 45],
1550 [17, 47, 21, 4, 48, 22],
1551 [9, 39, 13, 16, 40, 14],
1552
1553 // 20
1554 [3, 135, 107, 5, 136, 108],
1555 [3, 67, 41, 13, 68, 42],
1556 [15, 54, 24, 5, 55, 25],
1557 [15, 43, 15, 10, 44, 16],
1558
1559 // 21
1560 [4, 144, 116, 4, 145, 117],
1561 [17, 68, 42],
1562 [17, 50, 22, 6, 51, 23],
1563 [19, 46, 16, 6, 47, 17],
1564
1565 // 22
1566 [2, 139, 111, 7, 140, 112],
1567 [17, 74, 46],
1568 [7, 54, 24, 16, 55, 25],
1569 [34, 37, 13],
1570
1571 // 23
1572 [4, 151, 121, 5, 152, 122],
1573 [4, 75, 47, 14, 76, 48],
1574 [11, 54, 24, 14, 55, 25],
1575 [16, 45, 15, 14, 46, 16],
1576
1577 // 24
1578 [6, 147, 117, 4, 148, 118],
1579 [6, 73, 45, 14, 74, 46],
1580 [11, 54, 24, 16, 55, 25],
1581 [30, 46, 16, 2, 47, 17],
1582
1583 // 25
1584 [8, 132, 106, 4, 133, 107],
1585 [8, 75, 47, 13, 76, 48],
1586 [7, 54, 24, 22, 55, 25],
1587 [22, 45, 15, 13, 46, 16],
1588
1589 // 26
1590 [10, 142, 114, 2, 143, 115],
1591 [19, 74, 46, 4, 75, 47],
1592 [28, 50, 22, 6, 51, 23],
1593 [33, 46, 16, 4, 47, 17],
1594
1595 // 27
1596 [8, 152, 122, 4, 153, 123],
1597 [22, 73, 45, 3, 74, 46],
1598 [8, 53, 23, 26, 54, 24],
1599 [12, 45, 15, 28, 46, 16],
1600
1601 // 28
1602 [3, 147, 117, 10, 148, 118],
1603 [3, 73, 45, 23, 74, 46],
1604 [4, 54, 24, 31, 55, 25],
1605 [11, 45, 15, 31, 46, 16],
1606
1607 // 29
1608 [7, 146, 116, 7, 147, 117],
1609 [21, 73, 45, 7, 74, 46],
1610 [1, 53, 23, 37, 54, 24],
1611 [19, 45, 15, 26, 46, 16],
1612
1613 // 30
1614 [5, 145, 115, 10, 146, 116],
1615 [19, 75, 47, 10, 76, 48],
1616 [15, 54, 24, 25, 55, 25],
1617 [23, 45, 15, 25, 46, 16],
1618
1619 // 31
1620 [13, 145, 115, 3, 146, 116],
1621 [2, 74, 46, 29, 75, 47],
1622 [42, 54, 24, 1, 55, 25],
1623 [23, 45, 15, 28, 46, 16],
1624
1625 // 32
1626 [17, 145, 115],
1627 [10, 74, 46, 23, 75, 47],
1628 [10, 54, 24, 35, 55, 25],
1629 [19, 45, 15, 35, 46, 16],
1630
1631 // 33
1632 [17, 145, 115, 1, 146, 116],
1633 [14, 74, 46, 21, 75, 47],
1634 [29, 54, 24, 19, 55, 25],
1635 [11, 45, 15, 46, 46, 16],
1636
1637 // 34
1638 [13, 145, 115, 6, 146, 116],
1639 [14, 74, 46, 23, 75, 47],
1640 [44, 54, 24, 7, 55, 25],
1641 [59, 46, 16, 1, 47, 17],
1642
1643 // 35
1644 [12, 151, 121, 7, 152, 122],
1645 [12, 75, 47, 26, 76, 48],
1646 [39, 54, 24, 14, 55, 25],
1647 [22, 45, 15, 41, 46, 16],
1648
1649 // 36
1650 [6, 151, 121, 14, 152, 122],
1651 [6, 75, 47, 34, 76, 48],
1652 [46, 54, 24, 10, 55, 25],
1653 [2, 45, 15, 64, 46, 16],
1654
1655 // 37
1656 [17, 152, 122, 4, 153, 123],
1657 [29, 74, 46, 14, 75, 47],
1658 [49, 54, 24, 10, 55, 25],
1659 [24, 45, 15, 46, 46, 16],
1660
1661 // 38
1662 [4, 152, 122, 18, 153, 123],
1663 [13, 74, 46, 32, 75, 47],
1664 [48, 54, 24, 14, 55, 25],
1665 [42, 45, 15, 32, 46, 16],
1666
1667 // 39
1668 [20, 147, 117, 4, 148, 118],
1669 [40, 75, 47, 7, 76, 48],
1670 [43, 54, 24, 22, 55, 25],
1671 [10, 45, 15, 67, 46, 16],
1672
1673 // 40
1674 [19, 148, 118, 6, 149, 119],
1675 [18, 75, 47, 31, 76, 48],
1676 [34, 54, 24, 34, 55, 25],
1677 [20, 45, 15, 61, 46, 16]
1678 ];
1679
1680 var qrRSBlock = function(totalCount, dataCount) {
1681 var _this = {};
1682 _this.totalCount = totalCount;
1683 _this.dataCount = dataCount;
1684 return _this;
1685 };
1686
1687 var _this = {};
1688
1689 var getRsBlockTable = function(typeNumber, errorCorrectLevel) {
1690
1691 switch(errorCorrectLevel) {
1692 case QRErrorCorrectLevel.L :
1693 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
1694 case QRErrorCorrectLevel.M :
1695 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
1696 case QRErrorCorrectLevel.Q :
1697 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
1698 case QRErrorCorrectLevel.H :
1699 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
1700 default :
1701 return undefined;
1702 }
1703 };
1704
1705 _this.getRSBlocks = function(typeNumber, errorCorrectLevel) {
1706
1707 var rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel);
1708
1709 if (typeof rsBlock == 'undefined') {
1710 throw new Error('bad rs block @ typeNumber:' + typeNumber +
1711 '/errorCorrectLevel:' + errorCorrectLevel);
1712 }
1713
1714 var length = rsBlock.length / 3;
1715
1716 var list = new Array();
1717
1718 for (var i = 0; i < length; i += 1) {
1719
1720 var count = rsBlock[i * 3 + 0];
1721 var totalCount = rsBlock[i * 3 + 1];
1722 var dataCount = rsBlock[i * 3 + 2];
1723
1724 for (var j = 0; j < count; j += 1) {
1725 list.push(qrRSBlock(totalCount, dataCount) );
1726 }
1727 }
1728
1729 return list;
1730 };
1731
1732 return _this;
1733 }();
1734
1735 //---------------------------------------------------------------------
1736 // qrBitBuffer
1737 //---------------------------------------------------------------------
1738
1739 var qrBitBuffer = function() {
1740
1741 var _buffer = new Array();
1742 var _length = 0;
1743
1744 var _this = {};
1745
1746 _this.getBuffer = function() {
1747 return _buffer;
1748 };
1749
1750 _this.getAt = function(index) {
1751 var bufIndex = Math.floor(index / 8);
1752 return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
1753 };
1754
1755 _this.put = function(num, length) {
1756 for (var i = 0; i < length; i += 1) {
1757 _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
1758 }
1759 };
1760
1761 _this.getLengthInBits = function() {
1762 return _length;
1763 };
1764
1765 _this.putBit = function(bit) {
1766
1767 var bufIndex = Math.floor(_length / 8);
1768 if (_buffer.length <= bufIndex) {
1769 _buffer.push(0);
1770 }
1771
1772 if (bit) {
1773 _buffer[bufIndex] |= (0x80 >>> (_length % 8) );
1774 }
1775
1776 _length += 1;
1777 };
1778
1779 return _this;
1780 };
1781
1782 //---------------------------------------------------------------------
1783 // qr8BitByte
1784 //---------------------------------------------------------------------
1785
1786 var qr8BitByte = function(data) {
1787
1788 var _mode = QRMode.MODE_8BIT_BYTE;
1789 var _data = data;
1790 var _bytes = qrcode.stringToBytes(data);
1791
1792 var _this = {};
1793
1794 _this.getMode = function() {
1795 return _mode;
1796 };
1797
1798 _this.getLength = function(buffer) {
1799 return _bytes.length;
1800 };
1801
1802 _this.write = function(buffer) {
1803 for (var i = 0; i < _bytes.length; i += 1) {
1804 buffer.put(_bytes[i], 8);
1805 }
1806 };
1807
1808 return _this;
1809 };
1810
1811 //=====================================================================
1812 // GIF Support etc.
1813 //
1814
1815 //---------------------------------------------------------------------
1816 // byteArrayOutputStream
1817 //---------------------------------------------------------------------
1818
1819 var byteArrayOutputStream = function() {
1820
1821 var _bytes = new Array();
1822
1823 var _this = {};
1824
1825 _this.writeByte = function(b) {
1826 _bytes.push(b & 0xff);
1827 };
1828
1829 _this.writeShort = function(i) {
1830 _this.writeByte(i);
1831 _this.writeByte(i >>> 8);
1832 };
1833
1834 _this.writeBytes = function(b, off, len) {
1835 off = off || 0;
1836 len = len || b.length;
1837 for (var i = 0; i < len; i += 1) {
1838 _this.writeByte(b[i + off]);
1839 }
1840 };
1841
1842 _this.writeString = function(s) {
1843 for (var i = 0; i < s.length; i += 1) {
1844 _this.writeByte(s.charCodeAt(i) );
1845 }
1846 };
1847
1848 _this.toByteArray = function() {
1849 return _bytes;
1850 };
1851
1852 _this.toString = function() {
1853 var s = '';
1854 s += '[';
1855 for (var i = 0; i < _bytes.length; i += 1) {
1856 if (i > 0) {
1857 s += ',';
1858 }
1859 s += _bytes[i];
1860 }
1861 s += ']';
1862 return s;
1863 };
1864
1865 return _this;
1866 };
1867
1868 //---------------------------------------------------------------------
1869 // base64EncodeOutputStream
1870 //---------------------------------------------------------------------
1871
1872 var base64EncodeOutputStream = function() {
1873
1874 var _buffer = 0;
1875 var _buflen = 0;
1876 var _length = 0;
1877 var _base64 = '';
1878
1879 var _this = {};
1880
1881 var writeEncoded = function(b) {
1882 _base64 += String.fromCharCode(encode(b & 0x3f) );
1883 };
1884
1885 var encode = function(n) {
1886 if (n < 0) {
1887 // error.
1888 } else if (n < 26) {
1889 return 0x41 + n;
1890 } else if (n < 52) {
1891 return 0x61 + (n - 26);
1892 } else if (n < 62) {
1893 return 0x30 + (n - 52);
1894 } else if (n == 62) {
1895 return 0x2b;
1896 } else if (n == 63) {
1897 return 0x2f;
1898 }
1899 throw new Error('n:' + n);
1900 };
1901
1902 _this.writeByte = function(n) {
1903
1904 _buffer = (_buffer << 8) | (n & 0xff);
1905 _buflen += 8;
1906 _length += 1;
1907
1908 while (_buflen >= 6) {
1909 writeEncoded(_buffer >>> (_buflen - 6) );
1910 _buflen -= 6;
1911 }
1912 };
1913
1914 _this.flush = function() {
1915
1916 if (_buflen > 0) {
1917 writeEncoded(_buffer << (6 - _buflen) );
1918 _buffer = 0;
1919 _buflen = 0;
1920 }
1921
1922 if (_length % 3 != 0) {
1923 // padding
1924 var padlen = 3 - _length % 3;
1925 for (var i = 0; i < padlen; i += 1) {
1926 _base64 += '=';
1927 }
1928 }
1929 };
1930
1931 _this.toString = function() {
1932 return _base64;
1933 };
1934
1935 return _this;
1936 };
1937
1938 //---------------------------------------------------------------------
1939 // base64DecodeInputStream
1940 //---------------------------------------------------------------------
1941
1942 var base64DecodeInputStream = function(str) {
1943
1944 var _str = str;
1945 var _pos = 0;
1946 var _buffer = 0;
1947 var _buflen = 0;
1948
1949 var _this = {};
1950
1951 _this.read = function() {
1952
1953 while (_buflen < 8) {
1954
1955 if (_pos >= _str.length) {
1956 if (_buflen == 0) {
1957 return -1;
1958 }
1959 throw new Error('unexpected end of file./' + _buflen);
1960 }
1961
1962 var c = _str.charAt(_pos);
1963 _pos += 1;
1964
1965 if (c == '=') {
1966 _buflen = 0;
1967 return -1;
1968 } else if (c.match(/^\s$/) ) {
1969 // ignore if whitespace.
1970 continue;
1971 }
1972
1973 _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );
1974 _buflen += 6;
1975 }
1976
1977 var n = (_buffer >>> (_buflen - 8) ) & 0xff;
1978 _buflen -= 8;
1979 return n;
1980 };
1981
1982 var decode = function(c) {
1983 if (0x41 <= c && c <= 0x5a) {
1984 return c - 0x41;
1985 } else if (0x61 <= c && c <= 0x7a) {
1986 return c - 0x61 + 26;
1987 } else if (0x30 <= c && c <= 0x39) {
1988 return c - 0x30 + 52;
1989 } else if (c == 0x2b) {
1990 return 62;
1991 } else if (c == 0x2f) {
1992 return 63;
1993 } else {
1994 throw new Error('c:' + c);
1995 }
1996 };
1997
1998 return _this;
1999 };
2000
2001 //---------------------------------------------------------------------
2002 // gifImage (B/W)
2003 //---------------------------------------------------------------------
2004
2005 var gifImage = function(width, height) {
2006
2007 var _width = width;
2008 var _height = height;
2009 var _data = new Array(width * height);
2010
2011 var _this = {};
2012
2013 _this.setPixel = function(x, y, pixel) {
2014 _data[y * _width + x] = pixel;
2015 };
2016
2017 _this.write = function(out) {
2018
2019 //---------------------------------
2020 // GIF Signature
2021
2022 out.writeString('GIF87a');
2023
2024 //---------------------------------
2025 // Screen Descriptor
2026
2027 out.writeShort(_width);
2028 out.writeShort(_height);
2029
2030 out.writeByte(0x80); // 2bit
2031 out.writeByte(0);
2032 out.writeByte(0);
2033
2034 //---------------------------------
2035 // Global Color Map
2036
2037 // black
2038 out.writeByte(0x00);
2039 out.writeByte(0x00);
2040 out.writeByte(0x00);
2041
2042 // white
2043 out.writeByte(0xff);
2044 out.writeByte(0xff);
2045 out.writeByte(0xff);
2046
2047 //---------------------------------
2048 // Image Descriptor
2049
2050 out.writeString(',');
2051 out.writeShort(0);
2052 out.writeShort(0);
2053 out.writeShort(_width);
2054 out.writeShort(_height);
2055 out.writeByte(0);
2056
2057 //---------------------------------
2058 // Local Color Map
2059
2060 //---------------------------------
2061 // Raster Data
2062
2063 var lzwMinCodeSize = 2;
2064 var raster = getLZWRaster(lzwMinCodeSize);
2065
2066 out.writeByte(lzwMinCodeSize);
2067
2068 var offset = 0;
2069
2070 while (raster.length - offset > 255) {
2071 out.writeByte(255);
2072 out.writeBytes(raster, offset, 255);
2073 offset += 255;
2074 }
2075
2076 out.writeByte(raster.length - offset);
2077 out.writeBytes(raster, offset, raster.length - offset);
2078 out.writeByte(0x00);
2079
2080 //---------------------------------
2081 // GIF Terminator
2082 out.writeString(';');
2083 };
2084
2085 var bitOutputStream = function(out) {
2086
2087 var _out = out;
2088 var _bitLength = 0;
2089 var _bitBuffer = 0;
2090
2091 var _this = {};
2092
2093 _this.write = function(data, length) {
2094
2095 if ( (data >>> length) != 0) {
2096 throw new Error('length over');
2097 }
2098
2099 while (_bitLength + length >= 8) {
2100 _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );
2101 length -= (8 - _bitLength);
2102 data >>>= (8 - _bitLength);
2103 _bitBuffer = 0;
2104 _bitLength = 0;
2105 }
2106
2107 _bitBuffer = (data << _bitLength) | _bitBuffer;
2108 _bitLength = _bitLength + length;
2109 };
2110
2111 _this.flush = function() {
2112 if (_bitLength > 0) {
2113 _out.writeByte(_bitBuffer);
2114 }
2115 };
2116
2117 return _this;
2118 };
2119
2120 var getLZWRaster = function(lzwMinCodeSize) {
2121
2122 var clearCode = 1 << lzwMinCodeSize;
2123 var endCode = (1 << lzwMinCodeSize) + 1;
2124 var bitLength = lzwMinCodeSize + 1;
2125
2126 // Setup LZWTable
2127 var table = lzwTable();
2128
2129 for (var i = 0; i < clearCode; i += 1) {
2130 table.add(String.fromCharCode(i) );
2131 }
2132 table.add(String.fromCharCode(clearCode) );
2133 table.add(String.fromCharCode(endCode) );
2134
2135 var byteOut = byteArrayOutputStream();
2136 var bitOut = bitOutputStream(byteOut);
2137
2138 // clear code
2139 bitOut.write(clearCode, bitLength);
2140
2141 var dataIndex = 0;
2142
2143 var s = String.fromCharCode(_data[dataIndex]);
2144 dataIndex += 1;
2145
2146 while (dataIndex < _data.length) {
2147
2148 var c = String.fromCharCode(_data[dataIndex]);
2149 dataIndex += 1;
2150
2151 if (table.contains(s + c) ) {
2152
2153 s = s + c;
2154
2155 } else {
2156
2157 bitOut.write(table.indexOf(s), bitLength);
2158
2159 if (table.size() < 0xfff) {
2160
2161 if (table.size() == (1 << bitLength) ) {
2162 bitLength += 1;
2163 }
2164
2165 table.add(s + c);
2166 }
2167
2168 s = c;
2169 }
2170 }
2171
2172 bitOut.write(table.indexOf(s), bitLength);
2173
2174 // end code
2175 bitOut.write(endCode, bitLength);
2176
2177 bitOut.flush();
2178
2179 return byteOut.toByteArray();
2180 };
2181
2182 var lzwTable = function() {
2183
2184 var _map = {};
2185 var _size = 0;
2186
2187 var _this = {};
2188
2189 _this.add = function(key) {
2190 if (_this.contains(key) ) {
2191 throw new Error('dup key:' + key);
2192 }
2193 _map[key] = _size;
2194 _size += 1;
2195 };
2196
2197 _this.size = function() {
2198 return _size;
2199 };
2200
2201 _this.indexOf = function(key) {
2202 return _map[key];
2203 };
2204
2205 _this.contains = function(key) {
2206 return typeof _map[key] != 'undefined';
2207 };
2208
2209 return _this;
2210 };
2211
2212 return _this;
2213 };
2214
2215 var createImgTag = function(width, height, getPixel, alt) {
2216
2217 var gif = gifImage(width, height);
2218 for (var y = 0; y < height; y += 1) {
2219 for (var x = 0; x < width; x += 1) {
2220 gif.setPixel(x, y, getPixel(x, y) );
2221 }
2222 }
2223
2224 var b = byteArrayOutputStream();
2225 gif.write(b);
2226
2227 var base64 = base64EncodeOutputStream();
2228 var bytes = b.toByteArray();
2229 for (var i = 0; i < bytes.length; i += 1) {
2230 base64.writeByte(bytes[i]);
2231 }
2232 base64.flush();
2233
2234 var img = '';
2235 img += '<img';
2236 img += '\u0020src="';
2237 img += 'data:image/gif;base64,';
2238 img += base64;
2239 img += '"';
2240 img += '\u0020width="';
2241 img += width;
2242 img += '"';
2243 img += '\u0020height="';
2244 img += height;
2245 img += '"';
2246 if (alt) {
2247 img += '\u0020alt="';
2248 img += alt;
2249 img += '"';
2250 }
2251 img += '/>';
2252
2253 return img;
2254 };
2255
2256 //---------------------------------------------------------------------
2257 // returns qrcode function.
2258
2259 return qrcode;
2260 }();
2261
2262 (function (factory) {
2263 if (typeof define === 'function' && define.amd) {
2264 define([], factory);
2265 } else if (typeof exports === 'object') {
2266 module.exports = factory();
2267 }
2268 }(function () {
2269 return qrcode;
2270 }));
2271 //---------------------------------------------------------------------
2272 //
2273 // QR Code Generator for JavaScript UTF8 Support (optional)
2274 //
2275 // Copyright (c) 2011 Kazuhiko Arase
2276 //
2277 // URL: http://www.d-project.com/
2278 //
2279 // Licensed under the MIT license:
2280 // http://www.opensource.org/licenses/mit-license.php
2281 //
2282 // The word 'QR Code' is registered trademark of
2283 // DENSO WAVE INCORPORATED
2284 // http://www.denso-wave.com/qrcode/faqpatent-e.html
2285 //
2286 //---------------------------------------------------------------------
2287
2288 !function(qrcode) {
2289
2290 //---------------------------------------------------------------------
2291 // overwrite qrcode.stringToBytes
2292 //---------------------------------------------------------------------
2293
2294 qrcode.stringToBytes = function(s) {
2295 // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
2296 function toUTF8Array(str) {
2297 var utf8 = [];
2298 for (var i=0; i < str.length; i++) {
2299 var charcode = str.charCodeAt(i);
2300 if (charcode < 0x80) utf8.push(charcode);
2301 else if (charcode < 0x800) {
2302 utf8.push(0xc0 | (charcode >> 6),
2303 0x80 | (charcode & 0x3f));
2304 }
2305 else if (charcode < 0xd800 || charcode >= 0xe000) {
2306 utf8.push(0xe0 | (charcode >> 12),
2307 0x80 | ((charcode>>6) & 0x3f),
2308 0x80 | (charcode & 0x3f));
2309 }
2310 // surrogate pair
2311 else {
2312 i++;
2313 // UTF-16 encodes 0x10000-0x10FFFF by
2314 // subtracting 0x10000 and splitting the
2315 // 20 bits of 0x0-0xFFFFF into two halves
2316 charcode = 0x10000 + (((charcode & 0x3ff)<<10)
2317 | (str.charCodeAt(i) & 0x3ff));
2318 utf8.push(0xf0 | (charcode >>18),
2319 0x80 | ((charcode>>12) & 0x3f),
2320 0x80 | ((charcode>>6) & 0x3f),
2321 0x80 | (charcode & 0x3f));
2322 }
2323 }
2324 return utf8;
2325 }
2326 return toUTF8Array(s);
2327 };
2328
2329 }(qrcode);
2330
2331 return qrcode; // eslint-disable-line no-undef
2332 }()));
2333