PageSourceSearch

https://www.djclub.pro/vendor/qrcode-generator.mjs

js djclub.pro collected 2026-10-04 20:23:42 UTC 51,907 bytes, 2,237 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.