1 (function webpackUniversalModuleDefinition(root, factory) {
2 if(typeof exports === 'object' && typeof module === 'object')
3 module.exports = factory();
4 else if(typeof define === 'function' && define.amd)
6 else if(typeof exports === 'object')
7 exports["jsQR"] = factory();
9 root["jsQR"] = factory();
10 })(typeof self !== 'undefined' ? self : this, function() {
11 return /******/ (function(modules) { // webpackBootstrap
12 /******/ // The module cache
13 /******/ var installedModules = {};
15 /******/ // The require function
16 /******/ function __webpack_require__(moduleId) {
18 /******/ // Check if module is in cache
19 /******/ if(installedModules[moduleId]) {
20 /******/ return installedModules[moduleId].exports;
22 /******/ // Create a new module (and put it into the cache)
23 /******/ var module = installedModules[moduleId] = {
29 /******/ // Execute the module function
30 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
32 /******/ // Flag the module as loaded
33 /******/ module.l = true;
35 /******/ // Return the exports of the module
36 /******/ return module.exports;
40 /******/ // expose the modules object (__webpack_modules__)
41 /******/ __webpack_require__.m = modules;
43 /******/ // expose the module cache
44 /******/ __webpack_require__.c = installedModules;
46 /******/ // define getter function for harmony exports
47 /******/ __webpack_require__.d = function(exports, name, getter) {
48 /******/ if(!__webpack_require__.o(exports, name)) {
49 /******/ Object.defineProperty(exports, name, {
50 /******/ configurable: false,
51 /******/ enumerable: true,
57 /******/ // getDefaultExport function for compatibility with non-harmony modules
58 /******/ __webpack_require__.n = function(module) {
59 /******/ var getter = module && module.__esModule ?
60 /******/ function getDefault() { return module['default']; } :
61 /******/ function getModuleExports() { return module; };
62 /******/ __webpack_require__.d(getter, 'a', getter);
63 /******/ return getter;
66 /******/ // Object.prototype.hasOwnProperty.call
67 /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
69 /******/ // __webpack_public_path__
70 /******/ __webpack_require__.p = "";
72 /******/ // Load entry module and return exports
73 /******/ return __webpack_require__(__webpack_require__.s = 3);
75 /************************************************************************/
78 /***/ (function(module, exports, __webpack_require__) {
82 Object.defineProperty(exports, "__esModule", { value: true });
83 var BitMatrix = /** @class */ (function () {
84 function BitMatrix(data, width) {
86 this.height = data.length / width;
89 BitMatrix.createEmpty = function (width, height) {
90 return new BitMatrix(new Uint8ClampedArray(width * height), width);
92 BitMatrix.prototype.get = function (x, y) {
93 if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
96 return !!this.data[y * this.width + x];
98 BitMatrix.prototype.set = function (x, y, v) {
99 this.data[y * this.width + x] = v ? 1 : 0;
101 BitMatrix.prototype.setRegion = function (left, top, width, height, v) {
102 for (var y = top; y < top + height; y++) {
103 for (var x = left; x < left + width; x++) {
110 exports.BitMatrix = BitMatrix;
115 /***/ (function(module, exports, __webpack_require__) {
119 Object.defineProperty(exports, "__esModule", { value: true });
120 var GenericGFPoly_1 = __webpack_require__(2);
121 function addOrSubtractGF(a, b) {
122 return a ^ b; // tslint:disable-line:no-bitwise
124 exports.addOrSubtractGF = addOrSubtractGF;
125 var GenericGF = /** @class */ (function () {
126 function GenericGF(primitive, size, genBase) {
127 this.primitive = primitive;
129 this.generatorBase = genBase;
130 this.expTable = new Array(this.size);
131 this.logTable = new Array(this.size);
133 for (var i = 0; i < this.size; i++) {
134 this.expTable[i] = x;
136 if (x >= this.size) {
137 x = (x ^ this.primitive) & (this.size - 1); // tslint:disable-line:no-bitwise
140 for (var i = 0; i < this.size - 1; i++) {
141 this.logTable[this.expTable[i]] = i;
143 this.zero = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([0]));
144 this.one = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([1]));
146 GenericGF.prototype.multiply = function (a, b) {
147 if (a === 0 || b === 0) {
150 return this.expTable[(this.logTable[a] + this.logTable[b]) % (this.size - 1)];
152 GenericGF.prototype.inverse = function (a) {
154 throw new Error("Can't invert 0");
156 return this.expTable[this.size - this.logTable[a] - 1];
158 GenericGF.prototype.buildMonomial = function (degree, coefficient) {
160 throw new Error("Invalid monomial degree less than 0");
162 if (coefficient === 0) {
165 var coefficients = new Uint8ClampedArray(degree + 1);
166 coefficients[0] = coefficient;
167 return new GenericGFPoly_1.default(this, coefficients);
169 GenericGF.prototype.log = function (a) {
171 throw new Error("Can't take log(0)");
173 return this.logTable[a];
175 GenericGF.prototype.exp = function (a) {
176 return this.expTable[a];
180 exports.default = GenericGF;
185 /***/ (function(module, exports, __webpack_require__) {
189 Object.defineProperty(exports, "__esModule", { value: true });
190 var GenericGF_1 = __webpack_require__(1);
191 var GenericGFPoly = /** @class */ (function () {
192 function GenericGFPoly(field, coefficients) {
193 if (coefficients.length === 0) {
194 throw new Error("No coefficients.");
197 var coefficientsLength = coefficients.length;
198 if (coefficientsLength > 1 && coefficients[0] === 0) {
199 // Leading term must be non-zero for anything except the constant polynomial "0"
200 var firstNonZero = 1;
201 while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) {
204 if (firstNonZero === coefficientsLength) {
205 this.coefficients = field.zero.coefficients;
208 this.coefficients = new Uint8ClampedArray(coefficientsLength - firstNonZero);
209 for (var i = 0; i < this.coefficients.length; i++) {
210 this.coefficients[i] = coefficients[firstNonZero + i];
215 this.coefficients = coefficients;
218 GenericGFPoly.prototype.degree = function () {
219 return this.coefficients.length - 1;
221 GenericGFPoly.prototype.isZero = function () {
222 return this.coefficients[0] === 0;
224 GenericGFPoly.prototype.getCoefficient = function (degree) {
225 return this.coefficients[this.coefficients.length - 1 - degree];
227 GenericGFPoly.prototype.addOrSubtract = function (other) {
232 if (other.isZero()) {
235 var smallerCoefficients = this.coefficients;
236 var largerCoefficients = other.coefficients;
237 if (smallerCoefficients.length > largerCoefficients.length) {
238 _a = [largerCoefficients, smallerCoefficients], smallerCoefficients = _a[0], largerCoefficients = _a[1];
240 var sumDiff = new Uint8ClampedArray(largerCoefficients.length);
241 var lengthDiff = largerCoefficients.length - smallerCoefficients.length;
242 for (var i = 0; i < lengthDiff; i++) {
243 sumDiff[i] = largerCoefficients[i];
245 for (var i = lengthDiff; i < largerCoefficients.length; i++) {
246 sumDiff[i] = GenericGF_1.addOrSubtractGF(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
248 return new GenericGFPoly(this.field, sumDiff);
250 GenericGFPoly.prototype.multiply = function (scalar) {
252 return this.field.zero;
257 var size = this.coefficients.length;
258 var product = new Uint8ClampedArray(size);
259 for (var i = 0; i < size; i++) {
260 product[i] = this.field.multiply(this.coefficients[i], scalar);
262 return new GenericGFPoly(this.field, product);
264 GenericGFPoly.prototype.multiplyPoly = function (other) {
265 if (this.isZero() || other.isZero()) {
266 return this.field.zero;
268 var aCoefficients = this.coefficients;
269 var aLength = aCoefficients.length;
270 var bCoefficients = other.coefficients;
271 var bLength = bCoefficients.length;
272 var product = new Uint8ClampedArray(aLength + bLength - 1);
273 for (var i = 0; i < aLength; i++) {
274 var aCoeff = aCoefficients[i];
275 for (var j = 0; j < bLength; j++) {
276 product[i + j] = GenericGF_1.addOrSubtractGF(product[i + j], this.field.multiply(aCoeff, bCoefficients[j]));
279 return new GenericGFPoly(this.field, product);
281 GenericGFPoly.prototype.multiplyByMonomial = function (degree, coefficient) {
283 throw new Error("Invalid degree less than 0");
285 if (coefficient === 0) {
286 return this.field.zero;
288 var size = this.coefficients.length;
289 var product = new Uint8ClampedArray(size + degree);
290 for (var i = 0; i < size; i++) {
291 product[i] = this.field.multiply(this.coefficients[i], coefficient);
293 return new GenericGFPoly(this.field, product);
295 GenericGFPoly.prototype.evaluateAt = function (a) {
298 // Just return the x^0 coefficient
299 return this.getCoefficient(0);
301 var size = this.coefficients.length;
303 // Just the sum of the coefficients
304 this.coefficients.forEach(function (coefficient) {
305 result = GenericGF_1.addOrSubtractGF(result, coefficient);
309 result = this.coefficients[0];
310 for (var i = 1; i < size; i++) {
311 result = GenericGF_1.addOrSubtractGF(this.field.multiply(a, result), this.coefficients[i]);
315 return GenericGFPoly;
317 exports.default = GenericGFPoly;
322 /***/ (function(module, exports, __webpack_require__) {
326 Object.defineProperty(exports, "__esModule", { value: true });
327 var binarizer_1 = __webpack_require__(4);
328 var decoder_1 = __webpack_require__(5);
329 var extractor_1 = __webpack_require__(11);
330 var locator_1 = __webpack_require__(12);
331 function scan(matrix) {
332 var locations = locator_1.locate(matrix);
336 for (var _i = 0, locations_1 = locations; _i < locations_1.length; _i++) {
337 var location_1 = locations_1[_i];
338 var extracted = extractor_1.extract(matrix, location_1);
339 var decoded = decoder_1.decode(extracted.matrix);
342 binaryData: decoded.bytes,
344 chunks: decoded.chunks,
345 version: decoded.version,
347 topRightCorner: extracted.mappingFunction(location_1.dimension, 0),
348 topLeftCorner: extracted.mappingFunction(0, 0),
349 bottomRightCorner: extracted.mappingFunction(location_1.dimension, location_1.dimension),
350 bottomLeftCorner: extracted.mappingFunction(0, location_1.dimension),
351 topRightFinderPattern: location_1.topRight,
352 topLeftFinderPattern: location_1.topLeft,
353 bottomLeftFinderPattern: location_1.bottomLeft,
354 bottomRightAlignmentPattern: location_1.alignmentPattern,
361 var defaultOptions = {
362 inversionAttempts: "attemptBoth",
364 function jsQR(data, width, height, providedOptions) {
365 if (providedOptions === void 0) { providedOptions = {}; }
366 var options = defaultOptions;
367 Object.keys(options || {}).forEach(function (opt) {
368 options[opt] = providedOptions[opt] || options[opt];
370 var shouldInvert = options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst";
371 var tryInvertedFirst = options.inversionAttempts === "onlyInvert" || options.inversionAttempts === "invertFirst";
372 var _a = binarizer_1.binarize(data, width, height, shouldInvert), binarized = _a.binarized, inverted = _a.inverted;
373 var result = scan(tryInvertedFirst ? inverted : binarized);
374 if (!result && (options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst")) {
375 result = scan(tryInvertedFirst ? binarized : inverted);
380 exports.default = jsQR;
385 /***/ (function(module, exports, __webpack_require__) {
389 Object.defineProperty(exports, "__esModule", { value: true });
390 var BitMatrix_1 = __webpack_require__(0);
392 var MIN_DYNAMIC_RANGE = 24;
393 function numBetween(value, min, max) {
394 return value < min ? min : value > max ? max : value;
396 // Like BitMatrix but accepts arbitry Uint8 values
397 var Matrix = /** @class */ (function () {
398 function Matrix(width, height) {
400 this.data = new Uint8ClampedArray(width * height);
402 Matrix.prototype.get = function (x, y) {
403 return this.data[y * this.width + x];
405 Matrix.prototype.set = function (x, y, value) {
406 this.data[y * this.width + x] = value;
410 function binarize(data, width, height, returnInverted) {
411 if (data.length !== width * height * 4) {
412 throw new Error("Malformed data passed to binarizer.");
414 // Convert image to greyscale
415 var greyscalePixels = new Matrix(width, height);
416 for (var x = 0; x < width; x++) {
417 for (var y = 0; y < height; y++) {
418 var r = data[((y * width + x) * 4) + 0];
419 var g = data[((y * width + x) * 4) + 1];
420 var b = data[((y * width + x) * 4) + 2];
421 greyscalePixels.set(x, y, 0.2126 * r + 0.7152 * g + 0.0722 * b);
424 var horizontalRegionCount = Math.ceil(width / REGION_SIZE);
425 var verticalRegionCount = Math.ceil(height / REGION_SIZE);
426 var blackPoints = new Matrix(horizontalRegionCount, verticalRegionCount);
427 for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) {
428 for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) {
432 for (var y = 0; y < REGION_SIZE; y++) {
433 for (var x = 0; x < REGION_SIZE; x++) {
434 var pixelLumosity = greyscalePixels.get(hortizontalRegion * REGION_SIZE + x, verticalRegion * REGION_SIZE + y);
435 sum += pixelLumosity;
436 min = Math.min(min, pixelLumosity);
437 max = Math.max(max, pixelLumosity);
440 var average = sum / (Math.pow(REGION_SIZE, 2));
441 if (max - min <= MIN_DYNAMIC_RANGE) {
442 // If variation within the block is low, assume this is a block with only light or only
443 // dark pixels. In that case we do not want to use the average, as it would divide this
444 // low contrast area into black and white pixels, essentially creating data out of noise.
446 // Default the blackpoint for these blocks to be half the min - effectively white them out
448 if (verticalRegion > 0 && hortizontalRegion > 0) {
449 // Correct the "white background" assumption for blocks that have neighbors by comparing
450 // the pixels in this block to the previously calculated black points. This is based on
451 // the fact that dark barcode symbology is always surrounded by some amount of light
452 // background for which reasonable black point estimates were made. The bp estimated at
453 // the boundaries is used for the interior.
454 // The (min < bp) is arbitrary but works better than other heuristics that were tried.
455 var averageNeighborBlackPoint = (blackPoints.get(hortizontalRegion, verticalRegion - 1) +
456 (2 * blackPoints.get(hortizontalRegion - 1, verticalRegion)) +
457 blackPoints.get(hortizontalRegion - 1, verticalRegion - 1)) / 4;
458 if (min < averageNeighborBlackPoint) {
459 average = averageNeighborBlackPoint;
463 blackPoints.set(hortizontalRegion, verticalRegion, average);
466 var binarized = BitMatrix_1.BitMatrix.createEmpty(width, height);
468 if (returnInverted) {
469 inverted = BitMatrix_1.BitMatrix.createEmpty(width, height);
471 for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) {
472 for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) {
473 var left = numBetween(hortizontalRegion, 2, horizontalRegionCount - 3);
474 var top_1 = numBetween(verticalRegion, 2, verticalRegionCount - 3);
476 for (var xRegion = -2; xRegion <= 2; xRegion++) {
477 for (var yRegion = -2; yRegion <= 2; yRegion++) {
478 sum += blackPoints.get(left + xRegion, top_1 + yRegion);
481 var threshold = sum / 25;
482 for (var xRegion = 0; xRegion < REGION_SIZE; xRegion++) {
483 for (var yRegion = 0; yRegion < REGION_SIZE; yRegion++) {
484 var x = hortizontalRegion * REGION_SIZE + xRegion;
485 var y = verticalRegion * REGION_SIZE + yRegion;
486 var lum = greyscalePixels.get(x, y);
487 binarized.set(x, y, lum <= threshold);
488 if (returnInverted) {
489 inverted.set(x, y, !(lum <= threshold));
495 if (returnInverted) {
496 return { binarized: binarized, inverted: inverted };
498 return { binarized: binarized };
500 exports.binarize = binarize;
505 /***/ (function(module, exports, __webpack_require__) {
509 Object.defineProperty(exports, "__esModule", { value: true });
510 var BitMatrix_1 = __webpack_require__(0);
511 var decodeData_1 = __webpack_require__(6);
512 var reedsolomon_1 = __webpack_require__(9);
513 var version_1 = __webpack_require__(10);
514 // tslint:disable:no-bitwise
515 function numBitsDiffering(x, y) {
524 function pushBit(bit, byte) {
525 return (byte << 1) | bit;
527 // tslint:enable:no-bitwise
528 var FORMAT_INFO_TABLE = [
529 { bits: 0x5412, formatInfo: { errorCorrectionLevel: 1, dataMask: 0 } },
530 { bits: 0x5125, formatInfo: { errorCorrectionLevel: 1, dataMask: 1 } },
531 { bits: 0x5E7C, formatInfo: { errorCorrectionLevel: 1, dataMask: 2 } },
532 { bits: 0x5B4B, formatInfo: { errorCorrectionLevel: 1, dataMask: 3 } },
533 { bits: 0x45F9, formatInfo: { errorCorrectionLevel: 1, dataMask: 4 } },
534 { bits: 0x40CE, formatInfo: { errorCorrectionLevel: 1, dataMask: 5 } },
535 { bits: 0x4F97, formatInfo: { errorCorrectionLevel: 1, dataMask: 6 } },
536 { bits: 0x4AA0, formatInfo: { errorCorrectionLevel: 1, dataMask: 7 } },
537 { bits: 0x77C4, formatInfo: { errorCorrectionLevel: 0, dataMask: 0 } },
538 { bits: 0x72F3, formatInfo: { errorCorrectionLevel: 0, dataMask: 1 } },
539 { bits: 0x7DAA, formatInfo: { errorCorrectionLevel: 0, dataMask: 2 } },
540 { bits: 0x789D, formatInfo: { errorCorrectionLevel: 0, dataMask: 3 } },
541 { bits: 0x662F, formatInfo: { errorCorrectionLevel: 0, dataMask: 4 } },
542 { bits: 0x6318, formatInfo: { errorCorrectionLevel: 0, dataMask: 5 } },
543 { bits: 0x6C41, formatInfo: { errorCorrectionLevel: 0, dataMask: 6 } },
544 { bits: 0x6976, formatInfo: { errorCorrectionLevel: 0, dataMask: 7 } },
545 { bits: 0x1689, formatInfo: { errorCorrectionLevel: 3, dataMask: 0 } },
546 { bits: 0x13BE, formatInfo: { errorCorrectionLevel: 3, dataMask: 1 } },
547 { bits: 0x1CE7, formatInfo: { errorCorrectionLevel: 3, dataMask: 2 } },
548 { bits: 0x19D0, formatInfo: { errorCorrectionLevel: 3, dataMask: 3 } },
549 { bits: 0x0762, formatInfo: { errorCorrectionLevel: 3, dataMask: 4 } },
550 { bits: 0x0255, formatInfo: { errorCorrectionLevel: 3, dataMask: 5 } },
551 { bits: 0x0D0C, formatInfo: { errorCorrectionLevel: 3, dataMask: 6 } },
552 { bits: 0x083B, formatInfo: { errorCorrectionLevel: 3, dataMask: 7 } },
553 { bits: 0x355F, formatInfo: { errorCorrectionLevel: 2, dataMask: 0 } },
554 { bits: 0x3068, formatInfo: { errorCorrectionLevel: 2, dataMask: 1 } },
555 { bits: 0x3F31, formatInfo: { errorCorrectionLevel: 2, dataMask: 2 } },
556 { bits: 0x3A06, formatInfo: { errorCorrectionLevel: 2, dataMask: 3 } },
557 { bits: 0x24B4, formatInfo: { errorCorrectionLevel: 2, dataMask: 4 } },
558 { bits: 0x2183, formatInfo: { errorCorrectionLevel: 2, dataMask: 5 } },
559 { bits: 0x2EDA, formatInfo: { errorCorrectionLevel: 2, dataMask: 6 } },
560 { bits: 0x2BED, formatInfo: { errorCorrectionLevel: 2, dataMask: 7 } },
563 function (p) { return ((p.y + p.x) % 2) === 0; },
564 function (p) { return (p.y % 2) === 0; },
565 function (p) { return p.x % 3 === 0; },
566 function (p) { return (p.y + p.x) % 3 === 0; },
567 function (p) { return (Math.floor(p.y / 2) + Math.floor(p.x / 3)) % 2 === 0; },
568 function (p) { return ((p.x * p.y) % 2) + ((p.x * p.y) % 3) === 0; },
569 function (p) { return ((((p.y * p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; },
570 function (p) { return ((((p.y + p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; },
572 function buildFunctionPatternMask(version) {
573 var dimension = 17 + 4 * version.versionNumber;
574 var matrix = BitMatrix_1.BitMatrix.createEmpty(dimension, dimension);
575 matrix.setRegion(0, 0, 9, 9, true); // Top left finder pattern + separator + format
576 matrix.setRegion(dimension - 8, 0, 8, 9, true); // Top right finder pattern + separator + format
577 matrix.setRegion(0, dimension - 8, 9, 8, true); // Bottom left finder pattern + separator + format
578 // Alignment patterns
579 for (var _i = 0, _a = version.alignmentPatternCenters; _i < _a.length; _i++) {
581 for (var _b = 0, _c = version.alignmentPatternCenters; _b < _c.length; _b++) {
583 if (!(x === 6 && y === 6 || x === 6 && y === dimension - 7 || x === dimension - 7 && y === 6)) {
584 matrix.setRegion(x - 2, y - 2, 5, 5, true);
588 matrix.setRegion(6, 9, 1, dimension - 17, true); // Vertical timing pattern
589 matrix.setRegion(9, 6, dimension - 17, 1, true); // Horizontal timing pattern
590 if (version.versionNumber > 6) {
591 matrix.setRegion(dimension - 11, 0, 3, 6, true); // Version info, top right
592 matrix.setRegion(0, dimension - 11, 6, 3, true); // Version info, bottom left
596 function readCodewords(matrix, version, formatInfo) {
597 var dataMask = DATA_MASKS[formatInfo.dataMask];
598 var dimension = matrix.height;
599 var functionPatternMask = buildFunctionPatternMask(version);
603 // Read columns in pairs, from right to left
604 var readingUp = true;
605 for (var columnIndex = dimension - 1; columnIndex > 0; columnIndex -= 2) {
606 if (columnIndex === 6) { // Skip whole column with vertical alignment pattern;
609 for (var i = 0; i < dimension; i++) {
610 var y = readingUp ? dimension - 1 - i : i;
611 for (var columnOffset = 0; columnOffset < 2; columnOffset++) {
612 var x = columnIndex - columnOffset;
613 if (!functionPatternMask.get(x, y)) {
615 var bit = matrix.get(x, y);
616 if (dataMask({ y: y, x: x })) {
619 currentByte = pushBit(bit, currentByte);
620 if (bitsRead === 8) { // Whole bytes
621 codewords.push(currentByte);
628 readingUp = !readingUp;
632 function readVersion(matrix) {
633 var dimension = matrix.height;
634 var provisionalVersion = Math.floor((dimension - 17) / 4);
635 if (provisionalVersion <= 6) { // 6 and under dont have version info in the QR code
636 return version_1.VERSIONS[provisionalVersion - 1];
638 var topRightVersionBits = 0;
639 for (var y = 5; y >= 0; y--) {
640 for (var x = dimension - 9; x >= dimension - 11; x--) {
641 topRightVersionBits = pushBit(matrix.get(x, y), topRightVersionBits);
644 var bottomLeftVersionBits = 0;
645 for (var x = 5; x >= 0; x--) {
646 for (var y = dimension - 9; y >= dimension - 11; y--) {
647 bottomLeftVersionBits = pushBit(matrix.get(x, y), bottomLeftVersionBits);
650 var bestDifference = Infinity;
652 for (var _i = 0, VERSIONS_1 = version_1.VERSIONS; _i < VERSIONS_1.length; _i++) {
653 var version = VERSIONS_1[_i];
654 if (version.infoBits === topRightVersionBits || version.infoBits === bottomLeftVersionBits) {
657 var difference = numBitsDiffering(topRightVersionBits, version.infoBits);
658 if (difference < bestDifference) {
659 bestVersion = version;
660 bestDifference = difference;
662 difference = numBitsDiffering(bottomLeftVersionBits, version.infoBits);
663 if (difference < bestDifference) {
664 bestVersion = version;
665 bestDifference = difference;
668 // We can tolerate up to 3 bits of error since no two version info codewords will
669 // differ in less than 8 bits.
670 if (bestDifference <= 3) {
674 function readFormatInformation(matrix) {
675 var topLeftFormatInfoBits = 0;
676 for (var x = 0; x <= 8; x++) {
677 if (x !== 6) { // Skip timing pattern bit
678 topLeftFormatInfoBits = pushBit(matrix.get(x, 8), topLeftFormatInfoBits);
681 for (var y = 7; y >= 0; y--) {
682 if (y !== 6) { // Skip timing pattern bit
683 topLeftFormatInfoBits = pushBit(matrix.get(8, y), topLeftFormatInfoBits);
686 var dimension = matrix.height;
687 var topRightBottomRightFormatInfoBits = 0;
688 for (var y = dimension - 1; y >= dimension - 7; y--) { // bottom left
689 topRightBottomRightFormatInfoBits = pushBit(matrix.get(8, y), topRightBottomRightFormatInfoBits);
691 for (var x = dimension - 8; x < dimension; x++) { // top right
692 topRightBottomRightFormatInfoBits = pushBit(matrix.get(x, 8), topRightBottomRightFormatInfoBits);
694 var bestDifference = Infinity;
695 var bestFormatInfo = null;
696 for (var _i = 0, FORMAT_INFO_TABLE_1 = FORMAT_INFO_TABLE; _i < FORMAT_INFO_TABLE_1.length; _i++) {
697 var _a = FORMAT_INFO_TABLE_1[_i], bits = _a.bits, formatInfo = _a.formatInfo;
698 if (bits === topLeftFormatInfoBits || bits === topRightBottomRightFormatInfoBits) {
701 var difference = numBitsDiffering(topLeftFormatInfoBits, bits);
702 if (difference < bestDifference) {
703 bestFormatInfo = formatInfo;
704 bestDifference = difference;
706 if (topLeftFormatInfoBits !== topRightBottomRightFormatInfoBits) { // also try the other option
707 difference = numBitsDiffering(topRightBottomRightFormatInfoBits, bits);
708 if (difference < bestDifference) {
709 bestFormatInfo = formatInfo;
710 bestDifference = difference;
714 // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match
715 if (bestDifference <= 3) {
716 return bestFormatInfo;
720 function getDataBlocks(codewords, version, ecLevel) {
721 var ecInfo = version.errorCorrectionLevels[ecLevel];
723 var totalCodewords = 0;
724 ecInfo.ecBlocks.forEach(function (block) {
725 for (var i = 0; i < block.numBlocks; i++) {
726 dataBlocks.push({ numDataCodewords: block.dataCodewordsPerBlock, codewords: [] });
727 totalCodewords += block.dataCodewordsPerBlock + ecInfo.ecCodewordsPerBlock;
730 // In some cases the QR code will be malformed enough that we pull off more or less than we should.
731 // If we pull off less there's nothing we can do.
732 // If we pull off more we can safely truncate
733 if (codewords.length < totalCodewords) {
736 codewords = codewords.slice(0, totalCodewords);
737 var shortBlockSize = ecInfo.ecBlocks[0].dataCodewordsPerBlock;
738 // Pull codewords to fill the blocks up to the minimum size
739 for (var i = 0; i < shortBlockSize; i++) {
740 for (var _i = 0, dataBlocks_1 = dataBlocks; _i < dataBlocks_1.length; _i++) {
741 var dataBlock = dataBlocks_1[_i];
742 dataBlock.codewords.push(codewords.shift());
745 // If there are any large blocks, pull codewords to fill the last element of those
746 if (ecInfo.ecBlocks.length > 1) {
747 var smallBlockCount = ecInfo.ecBlocks[0].numBlocks;
748 var largeBlockCount = ecInfo.ecBlocks[1].numBlocks;
749 for (var i = 0; i < largeBlockCount; i++) {
750 dataBlocks[smallBlockCount + i].codewords.push(codewords.shift());
753 // Add the rest of the codewords to the blocks. These are the error correction codewords.
754 while (codewords.length > 0) {
755 for (var _a = 0, dataBlocks_2 = dataBlocks; _a < dataBlocks_2.length; _a++) {
756 var dataBlock = dataBlocks_2[_a];
757 dataBlock.codewords.push(codewords.shift());
762 function decodeMatrix(matrix) {
763 var version = readVersion(matrix);
767 var formatInfo = readFormatInformation(matrix);
771 var codewords = readCodewords(matrix, version, formatInfo);
772 var dataBlocks = getDataBlocks(codewords, version, formatInfo.errorCorrectionLevel);
776 // Count total number of data bytes
777 var totalBytes = dataBlocks.reduce(function (a, b) { return a + b.numDataCodewords; }, 0);
778 var resultBytes = new Uint8ClampedArray(totalBytes);
780 for (var _i = 0, dataBlocks_3 = dataBlocks; _i < dataBlocks_3.length; _i++) {
781 var dataBlock = dataBlocks_3[_i];
782 var correctedBytes = reedsolomon_1.decode(dataBlock.codewords, dataBlock.codewords.length - dataBlock.numDataCodewords);
783 if (!correctedBytes) {
786 for (var i = 0; i < dataBlock.numDataCodewords; i++) {
787 resultBytes[resultIndex++] = correctedBytes[i];
791 return decodeData_1.decode(resultBytes, version.versionNumber);
797 function decode(matrix) {
798 if (matrix == null) {
801 var result = decodeMatrix(matrix);
805 // Decoding didn't work, try mirroring the QR across the topLeft -> bottomRight line.
806 for (var x = 0; x < matrix.width; x++) {
807 for (var y = x + 1; y < matrix.height; y++) {
808 if (matrix.get(x, y) !== matrix.get(y, x)) {
809 matrix.set(x, y, !matrix.get(x, y));
810 matrix.set(y, x, !matrix.get(y, x));
814 return decodeMatrix(matrix);
816 exports.decode = decode;
821 /***/ (function(module, exports, __webpack_require__) {
825 Object.defineProperty(exports, "__esModule", { value: true });
826 // tslint:disable:no-bitwise
827 var BitStream_1 = __webpack_require__(7);
828 var shiftJISTable_1 = __webpack_require__(8);
831 Mode["Numeric"] = "numeric";
832 Mode["Alphanumeric"] = "alphanumeric";
833 Mode["Byte"] = "byte";
834 Mode["Kanji"] = "kanji";
836 })(Mode = exports.Mode || (exports.Mode = {}));
838 (function (ModeByte) {
839 ModeByte[ModeByte["Terminator"] = 0] = "Terminator";
840 ModeByte[ModeByte["Numeric"] = 1] = "Numeric";
841 ModeByte[ModeByte["Alphanumeric"] = 2] = "Alphanumeric";
842 ModeByte[ModeByte["Byte"] = 4] = "Byte";
843 ModeByte[ModeByte["Kanji"] = 8] = "Kanji";
844 ModeByte[ModeByte["ECI"] = 7] = "ECI";
845 // StructuredAppend = 0x3,
846 // FNC1FirstPosition = 0x5,
847 // FNC1SecondPosition = 0x9,
848 })(ModeByte || (ModeByte = {}));
849 function decodeNumeric(stream, size) {
852 var characterCountSize = [10, 12, 14][size];
853 var length = stream.readBits(characterCountSize);
854 // Read digits in groups of 3
855 while (length >= 3) {
856 var num = stream.readBits(10);
858 throw new Error("Invalid numeric value above 999");
860 var a = Math.floor(num / 100);
861 var b = Math.floor(num / 10) % 10;
863 bytes.push(48 + a, 48 + b, 48 + c);
864 text += a.toString() + b.toString() + c.toString();
867 // If the number of digits aren't a multiple of 3, the remaining digits are special cased.
869 var num = stream.readBits(7);
871 throw new Error("Invalid numeric value above 99");
873 var a = Math.floor(num / 10);
875 bytes.push(48 + a, 48 + b);
876 text += a.toString() + b.toString();
878 else if (length === 1) {
879 var num = stream.readBits(4);
881 throw new Error("Invalid numeric value above 9");
883 bytes.push(48 + num);
884 text += num.toString();
886 return { bytes: bytes, text: text };
888 var AlphanumericCharacterCodes = [
889 "0", "1", "2", "3", "4", "5", "6", "7", "8",
890 "9", "A", "B", "C", "D", "E", "F", "G", "H",
891 "I", "J", "K", "L", "M", "N", "O", "P", "Q",
892 "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
893 " ", "$", "%", "*", "+", "-", ".", "/", ":",
895 function decodeAlphanumeric(stream, size) {
898 var characterCountSize = [9, 11, 13][size];
899 var length = stream.readBits(characterCountSize);
900 while (length >= 2) {
901 var v = stream.readBits(11);
902 var a = Math.floor(v / 45);
904 bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0), AlphanumericCharacterCodes[b].charCodeAt(0));
905 text += AlphanumericCharacterCodes[a] + AlphanumericCharacterCodes[b];
909 var a = stream.readBits(6);
910 bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0));
911 text += AlphanumericCharacterCodes[a];
913 return { bytes: bytes, text: text };
915 function decodeByte(stream, size) {
918 var characterCountSize = [8, 16, 16][size];
919 var length = stream.readBits(characterCountSize);
920 for (var i = 0; i < length; i++) {
921 var b = stream.readBits(8);
925 text += decodeURIComponent(bytes.map(function (b) { return "%" + ("0" + b.toString(16)).substr(-2); }).join(""));
930 return { bytes: bytes, text: text };
932 function decodeKanji(stream, size) {
935 var characterCountSize = [8, 10, 12][size];
936 var length = stream.readBits(characterCountSize);
937 for (var i = 0; i < length; i++) {
938 var k = stream.readBits(13);
939 var c = (Math.floor(k / 0xC0) << 8) | (k % 0xC0);
946 bytes.push(c >> 8, c & 0xFF);
947 text += String.fromCharCode(shiftJISTable_1.shiftJISTable[c]);
949 return { bytes: bytes, text: text };
951 function decode(data, version) {
953 var stream = new BitStream_1.BitStream(data);
954 // There are 3 'sizes' based on the version. 1-9 is small (0), 10-26 is medium (1) and 27-40 is large (2).
955 var size = version <= 9 ? 0 : version <= 26 ? 1 : 2;
962 while (stream.available() >= 4) {
963 var mode = stream.readBits(4);
964 if (mode === ModeByte.Terminator) {
967 else if (mode === ModeByte.ECI) {
968 if (stream.readBits(1) === 0) {
971 assignmentNumber: stream.readBits(7),
974 else if (stream.readBits(1) === 0) {
977 assignmentNumber: stream.readBits(14),
980 else if (stream.readBits(1) === 0) {
983 assignmentNumber: stream.readBits(21),
987 // ECI data seems corrupted
990 assignmentNumber: -1,
994 else if (mode === ModeByte.Numeric) {
995 var numericResult = decodeNumeric(stream, size);
996 result.text += numericResult.text;
997 (_a = result.bytes).push.apply(_a, numericResult.bytes);
1000 text: numericResult.text,
1003 else if (mode === ModeByte.Alphanumeric) {
1004 var alphanumericResult = decodeAlphanumeric(stream, size);
1005 result.text += alphanumericResult.text;
1006 (_b = result.bytes).push.apply(_b, alphanumericResult.bytes);
1007 result.chunks.push({
1008 type: Mode.Alphanumeric,
1009 text: alphanumericResult.text,
1012 else if (mode === ModeByte.Byte) {
1013 var byteResult = decodeByte(stream, size);
1014 result.text += byteResult.text;
1015 (_c = result.bytes).push.apply(_c, byteResult.bytes);
1016 result.chunks.push({
1018 bytes: byteResult.bytes,
1019 text: byteResult.text,
1022 else if (mode === ModeByte.Kanji) {
1023 var kanjiResult = decodeKanji(stream, size);
1024 result.text += kanjiResult.text;
1025 (_d = result.bytes).push.apply(_d, kanjiResult.bytes);
1026 result.chunks.push({
1028 bytes: kanjiResult.bytes,
1029 text: kanjiResult.text,
1033 // If there is no data left, or the remaining bits are all 0, then that counts as a termination marker
1034 if (stream.available() === 0 || stream.readBits(stream.available()) === 0) {
1038 exports.decode = decode;
1043 /***/ (function(module, exports, __webpack_require__) {
1047 // tslint:disable:no-bitwise
1048 Object.defineProperty(exports, "__esModule", { value: true });
1049 var BitStream = /** @class */ (function () {
1050 function BitStream(bytes) {
1051 this.byteOffset = 0;
1055 BitStream.prototype.readBits = function (numBits) {
1056 if (numBits < 1 || numBits > 32 || numBits > this.available()) {
1057 throw new Error("Cannot read " + numBits.toString() + " bits");
1060 // First, read remainder from current byte
1061 if (this.bitOffset > 0) {
1062 var bitsLeft = 8 - this.bitOffset;
1063 var toRead = numBits < bitsLeft ? numBits : bitsLeft;
1064 var bitsToNotRead = bitsLeft - toRead;
1065 var mask = (0xFF >> (8 - toRead)) << bitsToNotRead;
1066 result = (this.bytes[this.byteOffset] & mask) >> bitsToNotRead;
1068 this.bitOffset += toRead;
1069 if (this.bitOffset === 8) {
1074 // Next read whole bytes
1076 while (numBits >= 8) {
1077 result = (result << 8) | (this.bytes[this.byteOffset] & 0xFF);
1081 // Finally read a partial byte
1083 var bitsToNotRead = 8 - numBits;
1084 var mask = (0xFF >> bitsToNotRead) << bitsToNotRead;
1085 result = (result << numBits) | ((this.bytes[this.byteOffset] & mask) >> bitsToNotRead);
1086 this.bitOffset += numBits;
1091 BitStream.prototype.available = function () {
1092 return 8 * (this.bytes.length - this.byteOffset) - this.bitOffset;
1096 exports.BitStream = BitStream;
1101 /***/ (function(module, exports, __webpack_require__) {
1105 Object.defineProperty(exports, "__esModule", { value: true });
1106 exports.shiftJISTable = {
8149 /***/ (function(module, exports, __webpack_require__) {
8153 Object.defineProperty(exports, "__esModule", { value: true });
8154 var GenericGF_1 = __webpack_require__(1);
8155 var GenericGFPoly_1 = __webpack_require__(2);
8156 function runEuclideanAlgorithm(field, a, b, R) {
8158 // Assume a's degree is >= b's
8159 if (a.degree() < b.degree()) {
8160 _a = [b, a], a = _a[0], b = _a[1];
8164 var tLast = field.zero;
8166 // Run Euclidean algorithm until r's degree is less than R/2
8167 while (r.degree() >= R / 2) {
8168 var rLastLast = rLast;
8169 var tLastLast = tLast;
8172 // Divide rLastLast by rLast, with quotient in q and remainder in r
8173 if (rLast.isZero()) {
8174 // Euclidean algorithm already terminated?
8179 var denominatorLeadingTerm = rLast.getCoefficient(rLast.degree());
8180 var dltInverse = field.inverse(denominatorLeadingTerm);
8181 while (r.degree() >= rLast.degree() && !r.isZero()) {
8182 var degreeDiff = r.degree() - rLast.degree();
8183 var scale = field.multiply(r.getCoefficient(r.degree()), dltInverse);
8184 q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale));
8185 r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));
8187 t = q.multiplyPoly(tLast).addOrSubtract(tLastLast);
8188 if (r.degree() >= rLast.degree()) {
8192 var sigmaTildeAtZero = t.getCoefficient(0);
8193 if (sigmaTildeAtZero === 0) {
8196 var inverse = field.inverse(sigmaTildeAtZero);
8197 return [t.multiply(inverse), r.multiply(inverse)];
8199 function findErrorLocations(field, errorLocator) {
8200 // This is a direct application of Chien's search
8201 var numErrors = errorLocator.degree();
8202 if (numErrors === 1) {
8203 return [errorLocator.getCoefficient(1)];
8205 var result = new Array(numErrors);
8207 for (var i = 1; i < field.size && errorCount < numErrors; i++) {
8208 if (errorLocator.evaluateAt(i) === 0) {
8209 result[errorCount] = field.inverse(i);
8213 if (errorCount !== numErrors) {
8218 function findErrorMagnitudes(field, errorEvaluator, errorLocations) {
8219 // This is directly applying Forney's Formula
8220 var s = errorLocations.length;
8221 var result = new Array(s);
8222 for (var i = 0; i < s; i++) {
8223 var xiInverse = field.inverse(errorLocations[i]);
8224 var denominator = 1;
8225 for (var j = 0; j < s; j++) {
8227 denominator = field.multiply(denominator, GenericGF_1.addOrSubtractGF(1, field.multiply(errorLocations[j], xiInverse)));
8230 result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse), field.inverse(denominator));
8231 if (field.generatorBase !== 0) {
8232 result[i] = field.multiply(result[i], xiInverse);
8237 function decode(bytes, twoS) {
8238 var outputBytes = new Uint8ClampedArray(bytes.length);
8239 outputBytes.set(bytes);
8240 var field = new GenericGF_1.default(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1
8241 var poly = new GenericGFPoly_1.default(field, outputBytes);
8242 var syndromeCoefficients = new Uint8ClampedArray(twoS);
8244 for (var s = 0; s < twoS; s++) {
8245 var evaluation = poly.evaluateAt(field.exp(s + field.generatorBase));
8246 syndromeCoefficients[syndromeCoefficients.length - 1 - s] = evaluation;
8247 if (evaluation !== 0) {
8254 var syndrome = new GenericGFPoly_1.default(field, syndromeCoefficients);
8255 var sigmaOmega = runEuclideanAlgorithm(field, field.buildMonomial(twoS, 1), syndrome, twoS);
8256 if (sigmaOmega === null) {
8259 var errorLocations = findErrorLocations(field, sigmaOmega[0]);
8260 if (errorLocations == null) {
8263 var errorMagnitudes = findErrorMagnitudes(field, sigmaOmega[1], errorLocations);
8264 for (var i = 0; i < errorLocations.length; i++) {
8265 var position = outputBytes.length - 1 - field.log(errorLocations[i]);
8269 outputBytes[position] = GenericGF_1.addOrSubtractGF(outputBytes[position], errorMagnitudes[i]);
8273 exports.decode = decode;
8278 /***/ (function(module, exports, __webpack_require__) {
8282 Object.defineProperty(exports, "__esModule", { value: true });
8283 exports.VERSIONS = [
8287 alignmentPatternCenters: [],
8288 errorCorrectionLevels: [
8290 ecCodewordsPerBlock: 7,
8291 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 19 }],
8294 ecCodewordsPerBlock: 10,
8295 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 16 }],
8298 ecCodewordsPerBlock: 13,
8299 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 13 }],
8302 ecCodewordsPerBlock: 17,
8303 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 9 }],
8310 alignmentPatternCenters: [6, 18],
8311 errorCorrectionLevels: [
8313 ecCodewordsPerBlock: 10,
8314 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 34 }],
8317 ecCodewordsPerBlock: 16,
8318 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 28 }],
8321 ecCodewordsPerBlock: 22,
8322 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 22 }],
8325 ecCodewordsPerBlock: 28,
8326 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 16 }],
8333 alignmentPatternCenters: [6, 22],
8334 errorCorrectionLevels: [
8336 ecCodewordsPerBlock: 15,
8337 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 55 }],
8340 ecCodewordsPerBlock: 26,
8341 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 44 }],
8344 ecCodewordsPerBlock: 18,
8345 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 17 }],
8348 ecCodewordsPerBlock: 22,
8349 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 13 }],
8356 alignmentPatternCenters: [6, 26],
8357 errorCorrectionLevels: [
8359 ecCodewordsPerBlock: 20,
8360 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 80 }],
8363 ecCodewordsPerBlock: 18,
8364 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 32 }],
8367 ecCodewordsPerBlock: 26,
8368 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 24 }],
8371 ecCodewordsPerBlock: 16,
8372 ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 9 }],
8379 alignmentPatternCenters: [6, 30],
8380 errorCorrectionLevels: [
8382 ecCodewordsPerBlock: 26,
8383 ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 108 }],
8386 ecCodewordsPerBlock: 24,
8387 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 43 }],
8390 ecCodewordsPerBlock: 18,
8392 { numBlocks: 2, dataCodewordsPerBlock: 15 },
8393 { numBlocks: 2, dataCodewordsPerBlock: 16 },
8397 ecCodewordsPerBlock: 22,
8399 { numBlocks: 2, dataCodewordsPerBlock: 11 },
8400 { numBlocks: 2, dataCodewordsPerBlock: 12 },
8408 alignmentPatternCenters: [6, 34],
8409 errorCorrectionLevels: [
8411 ecCodewordsPerBlock: 18,
8412 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 68 }],
8415 ecCodewordsPerBlock: 16,
8416 ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 27 }],
8419 ecCodewordsPerBlock: 24,
8420 ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 19 }],
8423 ecCodewordsPerBlock: 28,
8424 ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 15 }],
8431 alignmentPatternCenters: [6, 22, 38],
8432 errorCorrectionLevels: [
8434 ecCodewordsPerBlock: 20,
8435 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 78 }],
8438 ecCodewordsPerBlock: 18,
8439 ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 31 }],
8442 ecCodewordsPerBlock: 18,
8444 { numBlocks: 2, dataCodewordsPerBlock: 14 },
8445 { numBlocks: 4, dataCodewordsPerBlock: 15 },
8449 ecCodewordsPerBlock: 26,
8451 { numBlocks: 4, dataCodewordsPerBlock: 13 },
8452 { numBlocks: 1, dataCodewordsPerBlock: 14 },
8460 alignmentPatternCenters: [6, 24, 42],
8461 errorCorrectionLevels: [
8463 ecCodewordsPerBlock: 24,
8464 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 97 }],
8467 ecCodewordsPerBlock: 22,
8469 { numBlocks: 2, dataCodewordsPerBlock: 38 },
8470 { numBlocks: 2, dataCodewordsPerBlock: 39 },
8474 ecCodewordsPerBlock: 22,
8476 { numBlocks: 4, dataCodewordsPerBlock: 18 },
8477 { numBlocks: 2, dataCodewordsPerBlock: 19 },
8481 ecCodewordsPerBlock: 26,
8483 { numBlocks: 4, dataCodewordsPerBlock: 14 },
8484 { numBlocks: 2, dataCodewordsPerBlock: 15 },
8492 alignmentPatternCenters: [6, 26, 46],
8493 errorCorrectionLevels: [
8495 ecCodewordsPerBlock: 30,
8496 ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 116 }],
8499 ecCodewordsPerBlock: 22,
8501 { numBlocks: 3, dataCodewordsPerBlock: 36 },
8502 { numBlocks: 2, dataCodewordsPerBlock: 37 },
8506 ecCodewordsPerBlock: 20,
8508 { numBlocks: 4, dataCodewordsPerBlock: 16 },
8509 { numBlocks: 4, dataCodewordsPerBlock: 17 },
8513 ecCodewordsPerBlock: 24,
8515 { numBlocks: 4, dataCodewordsPerBlock: 12 },
8516 { numBlocks: 4, dataCodewordsPerBlock: 13 },
8524 alignmentPatternCenters: [6, 28, 50],
8525 errorCorrectionLevels: [
8527 ecCodewordsPerBlock: 18,
8529 { numBlocks: 2, dataCodewordsPerBlock: 68 },
8530 { numBlocks: 2, dataCodewordsPerBlock: 69 },
8534 ecCodewordsPerBlock: 26,
8536 { numBlocks: 4, dataCodewordsPerBlock: 43 },
8537 { numBlocks: 1, dataCodewordsPerBlock: 44 },
8541 ecCodewordsPerBlock: 24,
8543 { numBlocks: 6, dataCodewordsPerBlock: 19 },
8544 { numBlocks: 2, dataCodewordsPerBlock: 20 },
8548 ecCodewordsPerBlock: 28,
8550 { numBlocks: 6, dataCodewordsPerBlock: 15 },
8551 { numBlocks: 2, dataCodewordsPerBlock: 16 },
8559 alignmentPatternCenters: [6, 30, 54],
8560 errorCorrectionLevels: [
8562 ecCodewordsPerBlock: 20,
8563 ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 81 }],
8566 ecCodewordsPerBlock: 30,
8568 { numBlocks: 1, dataCodewordsPerBlock: 50 },
8569 { numBlocks: 4, dataCodewordsPerBlock: 51 },
8573 ecCodewordsPerBlock: 28,
8575 { numBlocks: 4, dataCodewordsPerBlock: 22 },
8576 { numBlocks: 4, dataCodewordsPerBlock: 23 },
8580 ecCodewordsPerBlock: 24,
8582 { numBlocks: 3, dataCodewordsPerBlock: 12 },
8583 { numBlocks: 8, dataCodewordsPerBlock: 13 },
8591 alignmentPatternCenters: [6, 32, 58],
8592 errorCorrectionLevels: [
8594 ecCodewordsPerBlock: 24,
8596 { numBlocks: 2, dataCodewordsPerBlock: 92 },
8597 { numBlocks: 2, dataCodewordsPerBlock: 93 },
8601 ecCodewordsPerBlock: 22,
8603 { numBlocks: 6, dataCodewordsPerBlock: 36 },
8604 { numBlocks: 2, dataCodewordsPerBlock: 37 },
8608 ecCodewordsPerBlock: 26,
8610 { numBlocks: 4, dataCodewordsPerBlock: 20 },
8611 { numBlocks: 6, dataCodewordsPerBlock: 21 },
8615 ecCodewordsPerBlock: 28,
8617 { numBlocks: 7, dataCodewordsPerBlock: 14 },
8618 { numBlocks: 4, dataCodewordsPerBlock: 15 },
8626 alignmentPatternCenters: [6, 34, 62],
8627 errorCorrectionLevels: [
8629 ecCodewordsPerBlock: 26,
8630 ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 107 }],
8633 ecCodewordsPerBlock: 22,
8635 { numBlocks: 8, dataCodewordsPerBlock: 37 },
8636 { numBlocks: 1, dataCodewordsPerBlock: 38 },
8640 ecCodewordsPerBlock: 24,
8642 { numBlocks: 8, dataCodewordsPerBlock: 20 },
8643 { numBlocks: 4, dataCodewordsPerBlock: 21 },
8647 ecCodewordsPerBlock: 22,
8649 { numBlocks: 12, dataCodewordsPerBlock: 11 },
8650 { numBlocks: 4, dataCodewordsPerBlock: 12 },
8658 alignmentPatternCenters: [6, 26, 46, 66],
8659 errorCorrectionLevels: [
8661 ecCodewordsPerBlock: 30,
8663 { numBlocks: 3, dataCodewordsPerBlock: 115 },
8664 { numBlocks: 1, dataCodewordsPerBlock: 116 },
8668 ecCodewordsPerBlock: 24,
8670 { numBlocks: 4, dataCodewordsPerBlock: 40 },
8671 { numBlocks: 5, dataCodewordsPerBlock: 41 },
8675 ecCodewordsPerBlock: 20,
8677 { numBlocks: 11, dataCodewordsPerBlock: 16 },
8678 { numBlocks: 5, dataCodewordsPerBlock: 17 },
8682 ecCodewordsPerBlock: 24,
8684 { numBlocks: 11, dataCodewordsPerBlock: 12 },
8685 { numBlocks: 5, dataCodewordsPerBlock: 13 },
8693 alignmentPatternCenters: [6, 26, 48, 70],
8694 errorCorrectionLevels: [
8696 ecCodewordsPerBlock: 22,
8698 { numBlocks: 5, dataCodewordsPerBlock: 87 },
8699 { numBlocks: 1, dataCodewordsPerBlock: 88 },
8703 ecCodewordsPerBlock: 24,
8705 { numBlocks: 5, dataCodewordsPerBlock: 41 },
8706 { numBlocks: 5, dataCodewordsPerBlock: 42 },
8710 ecCodewordsPerBlock: 30,
8712 { numBlocks: 5, dataCodewordsPerBlock: 24 },
8713 { numBlocks: 7, dataCodewordsPerBlock: 25 },
8717 ecCodewordsPerBlock: 24,
8719 { numBlocks: 11, dataCodewordsPerBlock: 12 },
8720 { numBlocks: 7, dataCodewordsPerBlock: 13 },
8728 alignmentPatternCenters: [6, 26, 50, 74],
8729 errorCorrectionLevels: [
8731 ecCodewordsPerBlock: 24,
8733 { numBlocks: 5, dataCodewordsPerBlock: 98 },
8734 { numBlocks: 1, dataCodewordsPerBlock: 99 },
8738 ecCodewordsPerBlock: 28,
8740 { numBlocks: 7, dataCodewordsPerBlock: 45 },
8741 { numBlocks: 3, dataCodewordsPerBlock: 46 },
8745 ecCodewordsPerBlock: 24,
8747 { numBlocks: 15, dataCodewordsPerBlock: 19 },
8748 { numBlocks: 2, dataCodewordsPerBlock: 20 },
8752 ecCodewordsPerBlock: 30,
8754 { numBlocks: 3, dataCodewordsPerBlock: 15 },
8755 { numBlocks: 13, dataCodewordsPerBlock: 16 },
8763 alignmentPatternCenters: [6, 30, 54, 78],
8764 errorCorrectionLevels: [
8766 ecCodewordsPerBlock: 28,
8768 { numBlocks: 1, dataCodewordsPerBlock: 107 },
8769 { numBlocks: 5, dataCodewordsPerBlock: 108 },
8773 ecCodewordsPerBlock: 28,
8775 { numBlocks: 10, dataCodewordsPerBlock: 46 },
8776 { numBlocks: 1, dataCodewordsPerBlock: 47 },
8780 ecCodewordsPerBlock: 28,
8782 { numBlocks: 1, dataCodewordsPerBlock: 22 },
8783 { numBlocks: 15, dataCodewordsPerBlock: 23 },
8787 ecCodewordsPerBlock: 28,
8789 { numBlocks: 2, dataCodewordsPerBlock: 14 },
8790 { numBlocks: 17, dataCodewordsPerBlock: 15 },
8798 alignmentPatternCenters: [6, 30, 56, 82],
8799 errorCorrectionLevels: [
8801 ecCodewordsPerBlock: 30,
8803 { numBlocks: 5, dataCodewordsPerBlock: 120 },
8804 { numBlocks: 1, dataCodewordsPerBlock: 121 },
8808 ecCodewordsPerBlock: 26,
8810 { numBlocks: 9, dataCodewordsPerBlock: 43 },
8811 { numBlocks: 4, dataCodewordsPerBlock: 44 },
8815 ecCodewordsPerBlock: 28,
8817 { numBlocks: 17, dataCodewordsPerBlock: 22 },
8818 { numBlocks: 1, dataCodewordsPerBlock: 23 },
8822 ecCodewordsPerBlock: 28,
8824 { numBlocks: 2, dataCodewordsPerBlock: 14 },
8825 { numBlocks: 19, dataCodewordsPerBlock: 15 },
8833 alignmentPatternCenters: [6, 30, 58, 86],
8834 errorCorrectionLevels: [
8836 ecCodewordsPerBlock: 28,
8838 { numBlocks: 3, dataCodewordsPerBlock: 113 },
8839 { numBlocks: 4, dataCodewordsPerBlock: 114 },
8843 ecCodewordsPerBlock: 26,
8845 { numBlocks: 3, dataCodewordsPerBlock: 44 },
8846 { numBlocks: 11, dataCodewordsPerBlock: 45 },
8850 ecCodewordsPerBlock: 26,
8852 { numBlocks: 17, dataCodewordsPerBlock: 21 },
8853 { numBlocks: 4, dataCodewordsPerBlock: 22 },
8857 ecCodewordsPerBlock: 26,
8859 { numBlocks: 9, dataCodewordsPerBlock: 13 },
8860 { numBlocks: 16, dataCodewordsPerBlock: 14 },
8868 alignmentPatternCenters: [6, 34, 62, 90],
8869 errorCorrectionLevels: [
8871 ecCodewordsPerBlock: 28,
8873 { numBlocks: 3, dataCodewordsPerBlock: 107 },
8874 { numBlocks: 5, dataCodewordsPerBlock: 108 },
8878 ecCodewordsPerBlock: 26,
8880 { numBlocks: 3, dataCodewordsPerBlock: 41 },
8881 { numBlocks: 13, dataCodewordsPerBlock: 42 },
8885 ecCodewordsPerBlock: 30,
8887 { numBlocks: 15, dataCodewordsPerBlock: 24 },
8888 { numBlocks: 5, dataCodewordsPerBlock: 25 },
8892 ecCodewordsPerBlock: 28,
8894 { numBlocks: 15, dataCodewordsPerBlock: 15 },
8895 { numBlocks: 10, dataCodewordsPerBlock: 16 },
8903 alignmentPatternCenters: [6, 28, 50, 72, 94],
8904 errorCorrectionLevels: [
8906 ecCodewordsPerBlock: 28,
8908 { numBlocks: 4, dataCodewordsPerBlock: 116 },
8909 { numBlocks: 4, dataCodewordsPerBlock: 117 },
8913 ecCodewordsPerBlock: 26,
8914 ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 42 }],
8917 ecCodewordsPerBlock: 28,
8919 { numBlocks: 17, dataCodewordsPerBlock: 22 },
8920 { numBlocks: 6, dataCodewordsPerBlock: 23 },
8924 ecCodewordsPerBlock: 30,
8926 { numBlocks: 19, dataCodewordsPerBlock: 16 },
8927 { numBlocks: 6, dataCodewordsPerBlock: 17 },
8935 alignmentPatternCenters: [6, 26, 50, 74, 98],
8936 errorCorrectionLevels: [
8938 ecCodewordsPerBlock: 28,
8940 { numBlocks: 2, dataCodewordsPerBlock: 111 },
8941 { numBlocks: 7, dataCodewordsPerBlock: 112 },
8945 ecCodewordsPerBlock: 28,
8946 ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 46 }],
8949 ecCodewordsPerBlock: 30,
8951 { numBlocks: 7, dataCodewordsPerBlock: 24 },
8952 { numBlocks: 16, dataCodewordsPerBlock: 25 },
8956 ecCodewordsPerBlock: 24,
8957 ecBlocks: [{ numBlocks: 34, dataCodewordsPerBlock: 13 }],
8964 alignmentPatternCenters: [6, 30, 54, 74, 102],
8965 errorCorrectionLevels: [
8967 ecCodewordsPerBlock: 30,
8969 { numBlocks: 4, dataCodewordsPerBlock: 121 },
8970 { numBlocks: 5, dataCodewordsPerBlock: 122 },
8974 ecCodewordsPerBlock: 28,
8976 { numBlocks: 4, dataCodewordsPerBlock: 47 },
8977 { numBlocks: 14, dataCodewordsPerBlock: 48 },
8981 ecCodewordsPerBlock: 30,
8983 { numBlocks: 11, dataCodewordsPerBlock: 24 },
8984 { numBlocks: 14, dataCodewordsPerBlock: 25 },
8988 ecCodewordsPerBlock: 30,
8990 { numBlocks: 16, dataCodewordsPerBlock: 15 },
8991 { numBlocks: 14, dataCodewordsPerBlock: 16 },
8999 alignmentPatternCenters: [6, 28, 54, 80, 106],
9000 errorCorrectionLevels: [
9002 ecCodewordsPerBlock: 30,
9004 { numBlocks: 6, dataCodewordsPerBlock: 117 },
9005 { numBlocks: 4, dataCodewordsPerBlock: 118 },
9009 ecCodewordsPerBlock: 28,
9011 { numBlocks: 6, dataCodewordsPerBlock: 45 },
9012 { numBlocks: 14, dataCodewordsPerBlock: 46 },
9016 ecCodewordsPerBlock: 30,
9018 { numBlocks: 11, dataCodewordsPerBlock: 24 },
9019 { numBlocks: 16, dataCodewordsPerBlock: 25 },
9023 ecCodewordsPerBlock: 30,
9025 { numBlocks: 30, dataCodewordsPerBlock: 16 },
9026 { numBlocks: 2, dataCodewordsPerBlock: 17 },
9034 alignmentPatternCenters: [6, 32, 58, 84, 110],
9035 errorCorrectionLevels: [
9037 ecCodewordsPerBlock: 26,
9039 { numBlocks: 8, dataCodewordsPerBlock: 106 },
9040 { numBlocks: 4, dataCodewordsPerBlock: 107 },
9044 ecCodewordsPerBlock: 28,
9046 { numBlocks: 8, dataCodewordsPerBlock: 47 },
9047 { numBlocks: 13, dataCodewordsPerBlock: 48 },
9051 ecCodewordsPerBlock: 30,
9053 { numBlocks: 7, dataCodewordsPerBlock: 24 },
9054 { numBlocks: 22, dataCodewordsPerBlock: 25 },
9058 ecCodewordsPerBlock: 30,
9060 { numBlocks: 22, dataCodewordsPerBlock: 15 },
9061 { numBlocks: 13, dataCodewordsPerBlock: 16 },
9069 alignmentPatternCenters: [6, 30, 58, 86, 114],
9070 errorCorrectionLevels: [
9072 ecCodewordsPerBlock: 28,
9074 { numBlocks: 10, dataCodewordsPerBlock: 114 },
9075 { numBlocks: 2, dataCodewordsPerBlock: 115 },
9079 ecCodewordsPerBlock: 28,
9081 { numBlocks: 19, dataCodewordsPerBlock: 46 },
9082 { numBlocks: 4, dataCodewordsPerBlock: 47 },
9086 ecCodewordsPerBlock: 28,
9088 { numBlocks: 28, dataCodewordsPerBlock: 22 },
9089 { numBlocks: 6, dataCodewordsPerBlock: 23 },
9093 ecCodewordsPerBlock: 30,
9095 { numBlocks: 33, dataCodewordsPerBlock: 16 },
9096 { numBlocks: 4, dataCodewordsPerBlock: 17 },
9104 alignmentPatternCenters: [6, 34, 62, 90, 118],
9105 errorCorrectionLevels: [
9107 ecCodewordsPerBlock: 30,
9109 { numBlocks: 8, dataCodewordsPerBlock: 122 },
9110 { numBlocks: 4, dataCodewordsPerBlock: 123 },
9114 ecCodewordsPerBlock: 28,
9116 { numBlocks: 22, dataCodewordsPerBlock: 45 },
9117 { numBlocks: 3, dataCodewordsPerBlock: 46 },
9121 ecCodewordsPerBlock: 30,
9123 { numBlocks: 8, dataCodewordsPerBlock: 23 },
9124 { numBlocks: 26, dataCodewordsPerBlock: 24 },
9128 ecCodewordsPerBlock: 30,
9130 { numBlocks: 12, dataCodewordsPerBlock: 15 },
9131 { numBlocks: 28, dataCodewordsPerBlock: 16 },
9139 alignmentPatternCenters: [6, 26, 50, 74, 98, 122],
9140 errorCorrectionLevels: [
9142 ecCodewordsPerBlock: 30,
9144 { numBlocks: 3, dataCodewordsPerBlock: 117 },
9145 { numBlocks: 10, dataCodewordsPerBlock: 118 },
9149 ecCodewordsPerBlock: 28,
9151 { numBlocks: 3, dataCodewordsPerBlock: 45 },
9152 { numBlocks: 23, dataCodewordsPerBlock: 46 },
9156 ecCodewordsPerBlock: 30,
9158 { numBlocks: 4, dataCodewordsPerBlock: 24 },
9159 { numBlocks: 31, dataCodewordsPerBlock: 25 },
9163 ecCodewordsPerBlock: 30,
9165 { numBlocks: 11, dataCodewordsPerBlock: 15 },
9166 { numBlocks: 31, dataCodewordsPerBlock: 16 },
9174 alignmentPatternCenters: [6, 30, 54, 78, 102, 126],
9175 errorCorrectionLevels: [
9177 ecCodewordsPerBlock: 30,
9179 { numBlocks: 7, dataCodewordsPerBlock: 116 },
9180 { numBlocks: 7, dataCodewordsPerBlock: 117 },
9184 ecCodewordsPerBlock: 28,
9186 { numBlocks: 21, dataCodewordsPerBlock: 45 },
9187 { numBlocks: 7, dataCodewordsPerBlock: 46 },
9191 ecCodewordsPerBlock: 30,
9193 { numBlocks: 1, dataCodewordsPerBlock: 23 },
9194 { numBlocks: 37, dataCodewordsPerBlock: 24 },
9198 ecCodewordsPerBlock: 30,
9200 { numBlocks: 19, dataCodewordsPerBlock: 15 },
9201 { numBlocks: 26, dataCodewordsPerBlock: 16 },
9209 alignmentPatternCenters: [6, 26, 52, 78, 104, 130],
9210 errorCorrectionLevels: [
9212 ecCodewordsPerBlock: 30,
9214 { numBlocks: 5, dataCodewordsPerBlock: 115 },
9215 { numBlocks: 10, dataCodewordsPerBlock: 116 },
9219 ecCodewordsPerBlock: 28,
9221 { numBlocks: 19, dataCodewordsPerBlock: 47 },
9222 { numBlocks: 10, dataCodewordsPerBlock: 48 },
9226 ecCodewordsPerBlock: 30,
9228 { numBlocks: 15, dataCodewordsPerBlock: 24 },
9229 { numBlocks: 25, dataCodewordsPerBlock: 25 },
9233 ecCodewordsPerBlock: 30,
9235 { numBlocks: 23, dataCodewordsPerBlock: 15 },
9236 { numBlocks: 25, dataCodewordsPerBlock: 16 },
9244 alignmentPatternCenters: [6, 30, 56, 82, 108, 134],
9245 errorCorrectionLevels: [
9247 ecCodewordsPerBlock: 30,
9249 { numBlocks: 13, dataCodewordsPerBlock: 115 },
9250 { numBlocks: 3, dataCodewordsPerBlock: 116 },
9254 ecCodewordsPerBlock: 28,
9256 { numBlocks: 2, dataCodewordsPerBlock: 46 },
9257 { numBlocks: 29, dataCodewordsPerBlock: 47 },
9261 ecCodewordsPerBlock: 30,
9263 { numBlocks: 42, dataCodewordsPerBlock: 24 },
9264 { numBlocks: 1, dataCodewordsPerBlock: 25 },
9268 ecCodewordsPerBlock: 30,
9270 { numBlocks: 23, dataCodewordsPerBlock: 15 },
9271 { numBlocks: 28, dataCodewordsPerBlock: 16 },
9279 alignmentPatternCenters: [6, 34, 60, 86, 112, 138],
9280 errorCorrectionLevels: [
9282 ecCodewordsPerBlock: 30,
9283 ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 115 }],
9286 ecCodewordsPerBlock: 28,
9288 { numBlocks: 10, dataCodewordsPerBlock: 46 },
9289 { numBlocks: 23, dataCodewordsPerBlock: 47 },
9293 ecCodewordsPerBlock: 30,
9295 { numBlocks: 10, dataCodewordsPerBlock: 24 },
9296 { numBlocks: 35, dataCodewordsPerBlock: 25 },
9300 ecCodewordsPerBlock: 30,
9302 { numBlocks: 19, dataCodewordsPerBlock: 15 },
9303 { numBlocks: 35, dataCodewordsPerBlock: 16 },
9311 alignmentPatternCenters: [6, 30, 58, 86, 114, 142],
9312 errorCorrectionLevels: [
9314 ecCodewordsPerBlock: 30,
9316 { numBlocks: 17, dataCodewordsPerBlock: 115 },
9317 { numBlocks: 1, dataCodewordsPerBlock: 116 },
9321 ecCodewordsPerBlock: 28,
9323 { numBlocks: 14, dataCodewordsPerBlock: 46 },
9324 { numBlocks: 21, dataCodewordsPerBlock: 47 },
9328 ecCodewordsPerBlock: 30,
9330 { numBlocks: 29, dataCodewordsPerBlock: 24 },
9331 { numBlocks: 19, dataCodewordsPerBlock: 25 },
9335 ecCodewordsPerBlock: 30,
9337 { numBlocks: 11, dataCodewordsPerBlock: 15 },
9338 { numBlocks: 46, dataCodewordsPerBlock: 16 },
9346 alignmentPatternCenters: [6, 34, 62, 90, 118, 146],
9347 errorCorrectionLevels: [
9349 ecCodewordsPerBlock: 30,
9351 { numBlocks: 13, dataCodewordsPerBlock: 115 },
9352 { numBlocks: 6, dataCodewordsPerBlock: 116 },
9356 ecCodewordsPerBlock: 28,
9358 { numBlocks: 14, dataCodewordsPerBlock: 46 },
9359 { numBlocks: 23, dataCodewordsPerBlock: 47 },
9363 ecCodewordsPerBlock: 30,
9365 { numBlocks: 44, dataCodewordsPerBlock: 24 },
9366 { numBlocks: 7, dataCodewordsPerBlock: 25 },
9370 ecCodewordsPerBlock: 30,
9372 { numBlocks: 59, dataCodewordsPerBlock: 16 },
9373 { numBlocks: 1, dataCodewordsPerBlock: 17 },
9381 alignmentPatternCenters: [6, 30, 54, 78, 102, 126, 150],
9382 errorCorrectionLevels: [
9384 ecCodewordsPerBlock: 30,
9386 { numBlocks: 12, dataCodewordsPerBlock: 121 },
9387 { numBlocks: 7, dataCodewordsPerBlock: 122 },
9391 ecCodewordsPerBlock: 28,
9393 { numBlocks: 12, dataCodewordsPerBlock: 47 },
9394 { numBlocks: 26, dataCodewordsPerBlock: 48 },
9398 ecCodewordsPerBlock: 30,
9400 { numBlocks: 39, dataCodewordsPerBlock: 24 },
9401 { numBlocks: 14, dataCodewordsPerBlock: 25 },
9405 ecCodewordsPerBlock: 30,
9407 { numBlocks: 22, dataCodewordsPerBlock: 15 },
9408 { numBlocks: 41, dataCodewordsPerBlock: 16 },
9416 alignmentPatternCenters: [6, 24, 50, 76, 102, 128, 154],
9417 errorCorrectionLevels: [
9419 ecCodewordsPerBlock: 30,
9421 { numBlocks: 6, dataCodewordsPerBlock: 121 },
9422 { numBlocks: 14, dataCodewordsPerBlock: 122 },
9426 ecCodewordsPerBlock: 28,
9428 { numBlocks: 6, dataCodewordsPerBlock: 47 },
9429 { numBlocks: 34, dataCodewordsPerBlock: 48 },
9433 ecCodewordsPerBlock: 30,
9435 { numBlocks: 46, dataCodewordsPerBlock: 24 },
9436 { numBlocks: 10, dataCodewordsPerBlock: 25 },
9440 ecCodewordsPerBlock: 30,
9442 { numBlocks: 2, dataCodewordsPerBlock: 15 },
9443 { numBlocks: 64, dataCodewordsPerBlock: 16 },
9451 alignmentPatternCenters: [6, 28, 54, 80, 106, 132, 158],
9452 errorCorrectionLevels: [
9454 ecCodewordsPerBlock: 30,
9456 { numBlocks: 17, dataCodewordsPerBlock: 122 },
9457 { numBlocks: 4, dataCodewordsPerBlock: 123 },
9461 ecCodewordsPerBlock: 28,
9463 { numBlocks: 29, dataCodewordsPerBlock: 46 },
9464 { numBlocks: 14, dataCodewordsPerBlock: 47 },
9468 ecCodewordsPerBlock: 30,
9470 { numBlocks: 49, dataCodewordsPerBlock: 24 },
9471 { numBlocks: 10, dataCodewordsPerBlock: 25 },
9475 ecCodewordsPerBlock: 30,
9477 { numBlocks: 24, dataCodewordsPerBlock: 15 },
9478 { numBlocks: 46, dataCodewordsPerBlock: 16 },
9486 alignmentPatternCenters: [6, 32, 58, 84, 110, 136, 162],
9487 errorCorrectionLevels: [
9489 ecCodewordsPerBlock: 30,
9491 { numBlocks: 4, dataCodewordsPerBlock: 122 },
9492 { numBlocks: 18, dataCodewordsPerBlock: 123 },
9496 ecCodewordsPerBlock: 28,
9498 { numBlocks: 13, dataCodewordsPerBlock: 46 },
9499 { numBlocks: 32, dataCodewordsPerBlock: 47 },
9503 ecCodewordsPerBlock: 30,
9505 { numBlocks: 48, dataCodewordsPerBlock: 24 },
9506 { numBlocks: 14, dataCodewordsPerBlock: 25 },
9510 ecCodewordsPerBlock: 30,
9512 { numBlocks: 42, dataCodewordsPerBlock: 15 },
9513 { numBlocks: 32, dataCodewordsPerBlock: 16 },
9521 alignmentPatternCenters: [6, 26, 54, 82, 110, 138, 166],
9522 errorCorrectionLevels: [
9524 ecCodewordsPerBlock: 30,
9526 { numBlocks: 20, dataCodewordsPerBlock: 117 },
9527 { numBlocks: 4, dataCodewordsPerBlock: 118 },
9531 ecCodewordsPerBlock: 28,
9533 { numBlocks: 40, dataCodewordsPerBlock: 47 },
9534 { numBlocks: 7, dataCodewordsPerBlock: 48 },
9538 ecCodewordsPerBlock: 30,
9540 { numBlocks: 43, dataCodewordsPerBlock: 24 },
9541 { numBlocks: 22, dataCodewordsPerBlock: 25 },
9545 ecCodewordsPerBlock: 30,
9547 { numBlocks: 10, dataCodewordsPerBlock: 15 },
9548 { numBlocks: 67, dataCodewordsPerBlock: 16 },
9556 alignmentPatternCenters: [6, 30, 58, 86, 114, 142, 170],
9557 errorCorrectionLevels: [
9559 ecCodewordsPerBlock: 30,
9561 { numBlocks: 19, dataCodewordsPerBlock: 118 },
9562 { numBlocks: 6, dataCodewordsPerBlock: 119 },
9566 ecCodewordsPerBlock: 28,
9568 { numBlocks: 18, dataCodewordsPerBlock: 47 },
9569 { numBlocks: 31, dataCodewordsPerBlock: 48 },
9573 ecCodewordsPerBlock: 30,
9575 { numBlocks: 34, dataCodewordsPerBlock: 24 },
9576 { numBlocks: 34, dataCodewordsPerBlock: 25 },
9580 ecCodewordsPerBlock: 30,
9582 { numBlocks: 20, dataCodewordsPerBlock: 15 },
9583 { numBlocks: 61, dataCodewordsPerBlock: 16 },
9593 /***/ (function(module, exports, __webpack_require__) {
9597 Object.defineProperty(exports, "__esModule", { value: true });
9598 var BitMatrix_1 = __webpack_require__(0);
9599 function squareToQuadrilateral(p1, p2, p3, p4) {
9600 var dx3 = p1.x - p2.x + p3.x - p4.x;
9601 var dy3 = p1.y - p2.y + p3.y - p4.y;
9602 if (dx3 === 0 && dy3 === 0) { // Affine
9616 var dx1 = p2.x - p3.x;
9617 var dx2 = p4.x - p3.x;
9618 var dy1 = p2.y - p3.y;
9619 var dy2 = p4.y - p3.y;
9620 var denominator = dx1 * dy2 - dx2 * dy1;
9621 var a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
9622 var a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
9624 a11: p2.x - p1.x + a13 * p2.x,
9625 a12: p2.y - p1.y + a13 * p2.y,
9627 a21: p4.x - p1.x + a23 * p4.x,
9628 a22: p4.y - p1.y + a23 * p4.y,
9636 function quadrilateralToSquare(p1, p2, p3, p4) {
9637 // Here, the adjoint serves as the inverse:
9638 var sToQ = squareToQuadrilateral(p1, p2, p3, p4);
9640 a11: sToQ.a22 * sToQ.a33 - sToQ.a23 * sToQ.a32,
9641 a12: sToQ.a13 * sToQ.a32 - sToQ.a12 * sToQ.a33,
9642 a13: sToQ.a12 * sToQ.a23 - sToQ.a13 * sToQ.a22,
9643 a21: sToQ.a23 * sToQ.a31 - sToQ.a21 * sToQ.a33,
9644 a22: sToQ.a11 * sToQ.a33 - sToQ.a13 * sToQ.a31,
9645 a23: sToQ.a13 * sToQ.a21 - sToQ.a11 * sToQ.a23,
9646 a31: sToQ.a21 * sToQ.a32 - sToQ.a22 * sToQ.a31,
9647 a32: sToQ.a12 * sToQ.a31 - sToQ.a11 * sToQ.a32,
9648 a33: sToQ.a11 * sToQ.a22 - sToQ.a12 * sToQ.a21,
9651 function times(a, b) {
9653 a11: a.a11 * b.a11 + a.a21 * b.a12 + a.a31 * b.a13,
9654 a12: a.a12 * b.a11 + a.a22 * b.a12 + a.a32 * b.a13,
9655 a13: a.a13 * b.a11 + a.a23 * b.a12 + a.a33 * b.a13,
9656 a21: a.a11 * b.a21 + a.a21 * b.a22 + a.a31 * b.a23,
9657 a22: a.a12 * b.a21 + a.a22 * b.a22 + a.a32 * b.a23,
9658 a23: a.a13 * b.a21 + a.a23 * b.a22 + a.a33 * b.a23,
9659 a31: a.a11 * b.a31 + a.a21 * b.a32 + a.a31 * b.a33,
9660 a32: a.a12 * b.a31 + a.a22 * b.a32 + a.a32 * b.a33,
9661 a33: a.a13 * b.a31 + a.a23 * b.a32 + a.a33 * b.a33,
9664 function extract(image, location) {
9665 var qToS = quadrilateralToSquare({ x: 3.5, y: 3.5 }, { x: location.dimension - 3.5, y: 3.5 }, { x: location.dimension - 6.5, y: location.dimension - 6.5 }, { x: 3.5, y: location.dimension - 3.5 });
9666 var sToQ = squareToQuadrilateral(location.topLeft, location.topRight, location.alignmentPattern, location.bottomLeft);
9667 var transform = times(sToQ, qToS);
9668 var matrix = BitMatrix_1.BitMatrix.createEmpty(location.dimension, location.dimension);
9669 var mappingFunction = function (x, y) {
9670 var denominator = transform.a13 * x + transform.a23 * y + transform.a33;
9672 x: (transform.a11 * x + transform.a21 * y + transform.a31) / denominator,
9673 y: (transform.a12 * x + transform.a22 * y + transform.a32) / denominator,
9676 for (var y = 0; y < location.dimension; y++) {
9677 for (var x = 0; x < location.dimension; x++) {
9678 var xValue = x + 0.5;
9679 var yValue = y + 0.5;
9680 var sourcePixel = mappingFunction(xValue, yValue);
9681 matrix.set(x, y, image.get(Math.floor(sourcePixel.x), Math.floor(sourcePixel.y)));
9686 mappingFunction: mappingFunction,
9689 exports.extract = extract;
9694 /***/ (function(module, exports, __webpack_require__) {
9698 Object.defineProperty(exports, "__esModule", { value: true });
9699 var MAX_FINDERPATTERNS_TO_SEARCH = 4;
9700 var MIN_QUAD_RATIO = 0.5;
9701 var MAX_QUAD_RATIO = 1.5;
9702 var distance = function (a, b) { return Math.sqrt(Math.pow((b.x - a.x), 2) + Math.pow((b.y - a.y), 2)); };
9703 function sum(values) {
9704 return values.reduce(function (a, b) { return a + b; });
9706 // Takes three finder patterns and organizes them into topLeft, topRight, etc
9707 function reorderFinderPatterns(pattern1, pattern2, pattern3) {
9709 // Find distances between pattern centers
9710 var oneTwoDistance = distance(pattern1, pattern2);
9711 var twoThreeDistance = distance(pattern2, pattern3);
9712 var oneThreeDistance = distance(pattern1, pattern3);
9716 // Assume one closest to other two is B; A and C will just be guesses at first
9717 if (twoThreeDistance >= oneTwoDistance && twoThreeDistance >= oneThreeDistance) {
9718 _a = [pattern2, pattern1, pattern3], bottomLeft = _a[0], topLeft = _a[1], topRight = _a[2];
9720 else if (oneThreeDistance >= twoThreeDistance && oneThreeDistance >= oneTwoDistance) {
9721 _b = [pattern1, pattern2, pattern3], bottomLeft = _b[0], topLeft = _b[1], topRight = _b[2];
9724 _c = [pattern1, pattern3, pattern2], bottomLeft = _c[0], topLeft = _c[1], topRight = _c[2];
9726 // Use cross product to figure out whether bottomLeft (A) and topRight (C) are correct or flipped in relation to topLeft (B)
9727 // This asks whether BC x BA has a positive z component, which is the arrangement we want. If it's negative, then
9728 // we've got it flipped around and should swap topRight and bottomLeft.
9729 if (((topRight.x - topLeft.x) * (bottomLeft.y - topLeft.y)) - ((topRight.y - topLeft.y) * (bottomLeft.x - topLeft.x)) < 0) {
9730 _d = [topRight, bottomLeft], bottomLeft = _d[0], topRight = _d[1];
9732 return { bottomLeft: bottomLeft, topLeft: topLeft, topRight: topRight };
9734 // Computes the dimension (number of modules on a side) of the QR Code based on the position of the finder patterns
9735 function computeDimension(topLeft, topRight, bottomLeft, matrix) {
9736 var moduleSize = (sum(countBlackWhiteRun(topLeft, bottomLeft, matrix, 5)) / 7 + // Divide by 7 since the ratio is 1:1:3:1:1
9737 sum(countBlackWhiteRun(topLeft, topRight, matrix, 5)) / 7 +
9738 sum(countBlackWhiteRun(bottomLeft, topLeft, matrix, 5)) / 7 +
9739 sum(countBlackWhiteRun(topRight, topLeft, matrix, 5)) / 7) / 4;
9740 if (moduleSize < 1) {
9741 throw new Error("Invalid module size");
9743 var topDimension = Math.round(distance(topLeft, topRight) / moduleSize);
9744 var sideDimension = Math.round(distance(topLeft, bottomLeft) / moduleSize);
9745 var dimension = Math.floor((topDimension + sideDimension) / 2) + 7;
9746 switch (dimension % 4) {
9754 return { dimension: dimension, moduleSize: moduleSize };
9756 // Takes an origin point and an end point and counts the sizes of the black white run from the origin towards the end point.
9757 // Returns an array of elements, representing the pixel size of the black white run.
9758 // Uses a variant of http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
9759 function countBlackWhiteRunTowardsPoint(origin, end, matrix, length) {
9760 var switchPoints = [{ x: Math.floor(origin.x), y: Math.floor(origin.y) }];
9761 var steep = Math.abs(end.y - origin.y) > Math.abs(end.x - origin.x);
9767 fromX = Math.floor(origin.y);
9768 fromY = Math.floor(origin.x);
9769 toX = Math.floor(end.y);
9770 toY = Math.floor(end.x);
9773 fromX = Math.floor(origin.x);
9774 fromY = Math.floor(origin.y);
9775 toX = Math.floor(end.x);
9776 toY = Math.floor(end.y);
9778 var dx = Math.abs(toX - fromX);
9779 var dy = Math.abs(toY - fromY);
9780 var error = Math.floor(-dx / 2);
9781 var xStep = fromX < toX ? 1 : -1;
9782 var yStep = fromY < toY ? 1 : -1;
9783 var currentPixel = true;
9784 // Loop up until x == toX, but not beyond
9785 for (var x = fromX, y = fromY; x !== toX + xStep; x += xStep) {
9786 // Does current pixel mean we have moved white to black or vice versa?
9787 // Scanning black in state 0,2 and white in state 1, so if we find the wrong
9788 // color, advance to next state or end if we are in state 2 already
9789 var realX = steep ? y : x;
9790 var realY = steep ? x : y;
9791 if (matrix.get(realX, realY) !== currentPixel) {
9792 currentPixel = !currentPixel;
9793 switchPoints.push({ x: realX, y: realY });
9794 if (switchPoints.length === length + 1) {
9808 for (var i = 0; i < length; i++) {
9809 if (switchPoints[i] && switchPoints[i + 1]) {
9810 distances.push(distance(switchPoints[i], switchPoints[i + 1]));
9818 // Takes an origin point and an end point and counts the sizes of the black white run in the origin point
9819 // along the line that intersects with the end point. Returns an array of elements, representing the pixel sizes
9820 // of the black white run. Takes a length which represents the number of switches from black to white to look for.
9821 function countBlackWhiteRun(origin, end, matrix, length) {
9823 var rise = end.y - origin.y;
9824 var run = end.x - origin.x;
9825 var towardsEnd = countBlackWhiteRunTowardsPoint(origin, end, matrix, Math.ceil(length / 2));
9826 var awayFromEnd = countBlackWhiteRunTowardsPoint(origin, { x: origin.x - run, y: origin.y - rise }, matrix, Math.ceil(length / 2));
9827 var middleValue = towardsEnd.shift() + awayFromEnd.shift() - 1; // Substract one so we don't double count a pixel
9828 return (_a = awayFromEnd.concat(middleValue)).concat.apply(_a, towardsEnd);
9830 // Takes in a black white run and an array of expected ratios. Returns the average size of the run as well as the "error" -
9831 // that is the amount the run diverges from the expected ratio
9832 function scoreBlackWhiteRun(sequence, ratios) {
9833 var averageSize = sum(sequence) / sum(ratios);
9835 ratios.forEach(function (ratio, i) {
9836 error += Math.pow((sequence[i] - ratio * averageSize), 2);
9838 return { averageSize: averageSize, error: error };
9840 // Takes an X,Y point and an array of sizes and scores the point against those ratios.
9841 // For example for a finder pattern takes the ratio list of 1:1:3:1:1 and checks horizontal, vertical and diagonal ratios
9843 function scorePattern(point, ratios, matrix) {
9845 var horizontalRun = countBlackWhiteRun(point, { x: -1, y: point.y }, matrix, ratios.length);
9846 var verticalRun = countBlackWhiteRun(point, { x: point.x, y: -1 }, matrix, ratios.length);
9847 var topLeftPoint = {
9848 x: Math.max(0, point.x - point.y) - 1,
9849 y: Math.max(0, point.y - point.x) - 1,
9851 var topLeftBottomRightRun = countBlackWhiteRun(point, topLeftPoint, matrix, ratios.length);
9852 var bottomLeftPoint = {
9853 x: Math.min(matrix.width, point.x + point.y) + 1,
9854 y: Math.min(matrix.height, point.y + point.x) + 1,
9856 var bottomLeftTopRightRun = countBlackWhiteRun(point, bottomLeftPoint, matrix, ratios.length);
9857 var horzError = scoreBlackWhiteRun(horizontalRun, ratios);
9858 var vertError = scoreBlackWhiteRun(verticalRun, ratios);
9859 var diagDownError = scoreBlackWhiteRun(topLeftBottomRightRun, ratios);
9860 var diagUpError = scoreBlackWhiteRun(bottomLeftTopRightRun, ratios);
9861 var ratioError = Math.sqrt(horzError.error * horzError.error +
9862 vertError.error * vertError.error +
9863 diagDownError.error * diagDownError.error +
9864 diagUpError.error * diagUpError.error);
9865 var avgSize = (horzError.averageSize + vertError.averageSize + diagDownError.averageSize + diagUpError.averageSize) / 4;
9866 var sizeError = (Math.pow((horzError.averageSize - avgSize), 2) +
9867 Math.pow((vertError.averageSize - avgSize), 2) +
9868 Math.pow((diagDownError.averageSize - avgSize), 2) +
9869 Math.pow((diagUpError.averageSize - avgSize), 2)) / avgSize;
9870 return ratioError + sizeError;
9876 function recenterLocation(matrix, p) {
9877 var leftX = Math.round(p.x);
9878 while (matrix.get(leftX, Math.round(p.y))) {
9881 var rightX = Math.round(p.x);
9882 while (matrix.get(rightX, Math.round(p.y))) {
9885 var x = (leftX + rightX) / 2;
9886 var topY = Math.round(p.y);
9887 while (matrix.get(Math.round(x), topY)) {
9890 var bottomY = Math.round(p.y);
9891 while (matrix.get(Math.round(x), bottomY)) {
9894 var y = (topY + bottomY) / 2;
9895 return { x: x, y: y };
9897 function locate(matrix) {
9898 var finderPatternQuads = [];
9899 var activeFinderPatternQuads = [];
9900 var alignmentPatternQuads = [];
9901 var activeAlignmentPatternQuads = [];
9902 var _loop_1 = function (y) {
9904 var lastBit = false;
9905 var scans = [0, 0, 0, 0, 0];
9906 var _loop_2 = function (x) {
9907 var v = matrix.get(x, y);
9908 if (v === lastBit) {
9912 scans = [scans[1], scans[2], scans[3], scans[4], length_1];
9915 // Do the last 5 color changes ~ match the expected ratio for a finder pattern? 1:1:3:1:1 of b:w:b:w:b
9916 var averageFinderPatternBlocksize = sum(scans) / 7;
9917 var validFinderPattern = Math.abs(scans[0] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize &&
9918 Math.abs(scans[1] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize &&
9919 Math.abs(scans[2] - 3 * averageFinderPatternBlocksize) < 3 * averageFinderPatternBlocksize &&
9920 Math.abs(scans[3] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize &&
9921 Math.abs(scans[4] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize &&
9922 !v; // And make sure the current pixel is white since finder patterns are bordered in white
9923 // Do the last 3 color changes ~ match the expected ratio for an alignment pattern? 1:1:1 of w:b:w
9924 var averageAlignmentPatternBlocksize = sum(scans.slice(-3)) / 3;
9925 var validAlignmentPattern = Math.abs(scans[2] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize &&
9926 Math.abs(scans[3] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize &&
9927 Math.abs(scans[4] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize &&
9928 v; // Is the current pixel black since alignment patterns are bordered in black
9929 if (validFinderPattern) {
9930 // Compute the start and end x values of the large center black square
9931 var endX_1 = x - scans[3] - scans[4];
9932 var startX_1 = endX_1 - scans[2];
9933 var line = { startX: startX_1, endX: endX_1, y: y };
9934 // Is there a quad directly above the current spot? If so, extend it with the new line. Otherwise, create a new quad with
9935 // that line as the starting point.
9936 var matchingQuads = activeFinderPatternQuads.filter(function (q) {
9937 return (startX_1 >= q.bottom.startX && startX_1 <= q.bottom.endX) ||
9938 (endX_1 >= q.bottom.startX && startX_1 <= q.bottom.endX) ||
9939 (startX_1 <= q.bottom.startX && endX_1 >= q.bottom.endX && ((scans[2] / (q.bottom.endX - q.bottom.startX)) < MAX_QUAD_RATIO &&
9940 (scans[2] / (q.bottom.endX - q.bottom.startX)) > MIN_QUAD_RATIO));
9942 if (matchingQuads.length > 0) {
9943 matchingQuads[0].bottom = line;
9946 activeFinderPatternQuads.push({ top: line, bottom: line });
9949 if (validAlignmentPattern) {
9950 // Compute the start and end x values of the center black square
9951 var endX_2 = x - scans[4];
9952 var startX_2 = endX_2 - scans[3];
9953 var line = { startX: startX_2, y: y, endX: endX_2 };
9954 // Is there a quad directly above the current spot? If so, extend it with the new line. Otherwise, create a new quad with
9955 // that line as the starting point.
9956 var matchingQuads = activeAlignmentPatternQuads.filter(function (q) {
9957 return (startX_2 >= q.bottom.startX && startX_2 <= q.bottom.endX) ||
9958 (endX_2 >= q.bottom.startX && startX_2 <= q.bottom.endX) ||
9959 (startX_2 <= q.bottom.startX && endX_2 >= q.bottom.endX && ((scans[2] / (q.bottom.endX - q.bottom.startX)) < MAX_QUAD_RATIO &&
9960 (scans[2] / (q.bottom.endX - q.bottom.startX)) > MIN_QUAD_RATIO));
9962 if (matchingQuads.length > 0) {
9963 matchingQuads[0].bottom = line;
9966 activeAlignmentPatternQuads.push({ top: line, bottom: line });
9971 for (var x = -1; x <= matrix.width; x++) {
9974 finderPatternQuads.push.apply(finderPatternQuads, activeFinderPatternQuads.filter(function (q) { return q.bottom.y !== y && q.bottom.y - q.top.y >= 2; }));
9975 activeFinderPatternQuads = activeFinderPatternQuads.filter(function (q) { return q.bottom.y === y; });
9976 alignmentPatternQuads.push.apply(alignmentPatternQuads, activeAlignmentPatternQuads.filter(function (q) { return q.bottom.y !== y; }));
9977 activeAlignmentPatternQuads = activeAlignmentPatternQuads.filter(function (q) { return q.bottom.y === y; });
9979 for (var y = 0; y <= matrix.height; y++) {
9982 finderPatternQuads.push.apply(finderPatternQuads, activeFinderPatternQuads.filter(function (q) { return q.bottom.y - q.top.y >= 2; }));
9983 alignmentPatternQuads.push.apply(alignmentPatternQuads, activeAlignmentPatternQuads);
9984 var finderPatternGroups = finderPatternQuads
9985 .filter(function (q) { return q.bottom.y - q.top.y >= 2; }) // All quads must be at least 2px tall since the center square is larger than a block
9987 var x = (q.top.startX + q.top.endX + q.bottom.startX + q.bottom.endX) / 4;
9988 var y = (q.top.y + q.bottom.y + 1) / 2;
9989 if (!matrix.get(Math.round(x), Math.round(y))) {
9992 var lengths = [q.top.endX - q.top.startX, q.bottom.endX - q.bottom.startX, q.bottom.y - q.top.y + 1];
9993 var size = sum(lengths) / lengths.length;
9994 var score = scorePattern({ x: Math.round(x), y: Math.round(y) }, [1, 1, 3, 1, 1], matrix);
9995 return { score: score, x: x, y: y, size: size };
9997 .filter(function (q) { return !!q; }) // Filter out any rejected quads from above
9998 .sort(function (a, b) { return a.score - b.score; })
9999 // Now take the top finder pattern options and try to find 2 other options with a similar size.
10000 .map(function (point, i, finderPatterns) {
10001 if (i > MAX_FINDERPATTERNS_TO_SEARCH) {
10004 var otherPoints = finderPatterns
10005 .filter(function (p, ii) { return i !== ii; })
10006 .map(function (p) { return ({ x: p.x, y: p.y, score: p.score + (Math.pow((p.size - point.size), 2)) / point.size, size: p.size }); })
10007 .sort(function (a, b) { return a.score - b.score; });
10008 if (otherPoints.length < 2) {
10011 var score = point.score + otherPoints[0].score + otherPoints[1].score;
10012 return { points: [point].concat(otherPoints.slice(0, 2)), score: score };
10014 .filter(function (q) { return !!q; }) // Filter out any rejected finder patterns from above
10015 .sort(function (a, b) { return a.score - b.score; });
10016 if (finderPatternGroups.length === 0) {
10019 var _a = reorderFinderPatterns(finderPatternGroups[0].points[0], finderPatternGroups[0].points[1], finderPatternGroups[0].points[2]), topRight = _a.topRight, topLeft = _a.topLeft, bottomLeft = _a.bottomLeft;
10020 var alignment = findAlignmentPattern(matrix, alignmentPatternQuads, topRight, topLeft, bottomLeft);
10024 alignmentPattern: { x: alignment.alignmentPattern.x, y: alignment.alignmentPattern.y },
10025 bottomLeft: { x: bottomLeft.x, y: bottomLeft.y },
10026 dimension: alignment.dimension,
10027 topLeft: { x: topLeft.x, y: topLeft.y },
10028 topRight: { x: topRight.x, y: topRight.y },
10031 // We normally use the center of the quads as the location of the tracking points, which is optimal for most cases and will account
10032 // for a skew in the image. However, In some cases, a slight skew might not be real and instead be caused by image compression
10033 // errors and/or low resolution. For those cases, we'd be better off centering the point exactly in the middle of the black area. We
10034 // compute and return the location data for the naively centered points as it is little additional work and allows for multiple
10035 // attempts at decoding harder images.
10036 var midTopRight = recenterLocation(matrix, topRight);
10037 var midTopLeft = recenterLocation(matrix, topLeft);
10038 var midBottomLeft = recenterLocation(matrix, bottomLeft);
10039 var centeredAlignment = findAlignmentPattern(matrix, alignmentPatternQuads, midTopRight, midTopLeft, midBottomLeft);
10040 if (centeredAlignment) {
10042 alignmentPattern: { x: centeredAlignment.alignmentPattern.x, y: centeredAlignment.alignmentPattern.y },
10043 bottomLeft: { x: midBottomLeft.x, y: midBottomLeft.y },
10044 topLeft: { x: midTopLeft.x, y: midTopLeft.y },
10045 topRight: { x: midTopRight.x, y: midTopRight.y },
10046 dimension: centeredAlignment.dimension,
10049 if (result.length === 0) {
10054 exports.locate = locate;
10055 function findAlignmentPattern(matrix, alignmentPatternQuads, topRight, topLeft, bottomLeft) {
10057 // Now that we've found the three finder patterns we can determine the blockSize and the size of the QR code.
10058 // We'll use these to help find the alignment pattern but also later when we do the extraction.
10062 (_a = computeDimension(topLeft, topRight, bottomLeft, matrix), dimension = _a.dimension, moduleSize = _a.moduleSize);
10067 // Now find the alignment pattern
10068 var bottomRightFinderPattern = {
10069 x: topRight.x - topLeft.x + bottomLeft.x,
10070 y: topRight.y - topLeft.y + bottomLeft.y,
10072 var modulesBetweenFinderPatterns = ((distance(topLeft, bottomLeft) + distance(topLeft, topRight)) / 2 / moduleSize);
10073 var correctionToTopLeft = 1 - (3 / modulesBetweenFinderPatterns);
10074 var expectedAlignmentPattern = {
10075 x: topLeft.x + correctionToTopLeft * (bottomRightFinderPattern.x - topLeft.x),
10076 y: topLeft.y + correctionToTopLeft * (bottomRightFinderPattern.y - topLeft.y),
10078 var alignmentPatterns = alignmentPatternQuads
10079 .map(function (q) {
10080 var x = (q.top.startX + q.top.endX + q.bottom.startX + q.bottom.endX) / 4;
10081 var y = (q.top.y + q.bottom.y + 1) / 2;
10082 if (!matrix.get(Math.floor(x), Math.floor(y))) {
10085 var lengths = [q.top.endX - q.top.startX, q.bottom.endX - q.bottom.startX, (q.bottom.y - q.top.y + 1)];
10086 var size = sum(lengths) / lengths.length;
10087 var sizeScore = scorePattern({ x: Math.floor(x), y: Math.floor(y) }, [1, 1, 1], matrix);
10088 var score = sizeScore + distance({ x: x, y: y }, expectedAlignmentPattern);
10089 return { x: x, y: y, score: score };
10091 .filter(function (v) { return !!v; })
10092 .sort(function (a, b) { return a.score - b.score; });
10093 // If there are less than 15 modules between finder patterns it's a version 1 QR code and as such has no alignmemnt pattern
10094 // so we can only use our best guess.
10095 var alignmentPattern = modulesBetweenFinderPatterns >= 15 && alignmentPatterns.length ? alignmentPatterns[0] : expectedAlignmentPattern;
10096 return { alignmentPattern: alignmentPattern, dimension: dimension };
10101 /******/ ])["default"];