angular2-qrscanner
Version:
QrScanner will scan for a QRCode from your Web-cam and return its string representation by drawing the captured image onto a 2D Canvas and use [@LazarSoft/jsqrcode](https://github.com/LazarSoft/jsqrcode) to check for a valid QRCode every *Xms*
1,118 lines (1,111 loc) • 152 kB
JavaScript
import { Component, EventEmitter, Input, Output, ViewChild, Renderer2, NgModule } from '@angular/core';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/*
Ported to JavaScript by Lazar Laszlo 2011
lazarsoft@gmail.com, www.lazarsoft.info
*/
/*
*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class AlignmentPattern {
/**
* @param {?} posX
* @param {?} posY
* @param {?} estimatedModuleSize
*/
constructor(posX, posY, estimatedModuleSize) {
this.count = 1;
this.incrementCount = function () {
this.count++;
};
this.aboutEquals = function (moduleSize, i, j) {
if (Math.abs(i - this.y) <= moduleSize && Math.abs(j - this.x) <= moduleSize) {
var /** @type {?} */ moduleSizeDiff = Math.abs(moduleSize - this.estimatedModuleSize);
return moduleSizeDiff <= 1.0 || moduleSizeDiff / this.estimatedModuleSize <= 1.0;
}
return false;
};
this.x = posX;
this.y = posY;
this.estimatedModuleSize = estimatedModuleSize;
}
/**
* @return {?}
*/
get EstimatedModuleSize() {
return this.estimatedModuleSize;
}
;
/**
* @return {?}
*/
get Count() {
return this.count;
}
;
/**
* @return {?}
*/
get X() {
return Math.floor(this.x);
}
;
/**
* @return {?}
*/
get Y() {
return Math.floor(this.y);
}
;
}
class AlignmentPatternFinder {
/**
* @param {?} image
* @param {?} startX
* @param {?} startY
* @param {?} width
* @param {?} height
* @param {?} moduleSize
* @param {?} imageWidth
* @param {?} imageHeight
* @param {?} resultPointCallback
*/
constructor(image, startX, startY, width, height, moduleSize, imageWidth, imageHeight, resultPointCallback) {
this.possibleCenters = new Array();
this.crossCheckStateCount = new Array(0, 0, 0);
this.centerFromEnd = function (stateCount, end) {
return (end - stateCount[2]) - stateCount[1] / 2.0;
};
this.foundPatternCross = function (stateCount) {
var /** @type {?} */ moduleSize = this.moduleSize;
var /** @type {?} */ maxVariance = moduleSize / 2.0;
for (var /** @type {?} */ i = 0; i < 3; i++) {
if (Math.abs(moduleSize - stateCount[i]) >= maxVariance) {
return false;
}
}
return true;
};
this.crossCheckVertical = function (startI, centerJ, maxCount, originalStateCountTotal) {
var /** @type {?} */ image = this.image;
var /** @type {?} */ maxI = this.imageHeight;
var /** @type {?} */ stateCount = this.crossCheckStateCount;
stateCount[0] = 0;
stateCount[1] = 0;
stateCount[2] = 0;
// Start counting up from center
var /** @type {?} */ i = startI;
while (i >= 0 && image[centerJ + i * this.imageWidth] && stateCount[1] <= maxCount) {
stateCount[1]++;
i--;
}
// If already too many modules in this state or ran off the edge:
if (i < 0 || stateCount[1] > maxCount) {
return NaN;
}
while (i >= 0 && !image[centerJ + i * this.imageWidth] && stateCount[0] <= maxCount) {
stateCount[0]++;
i--;
}
if (stateCount[0] > maxCount) {
return NaN;
}
// Now also count down from center
i = startI + 1;
while (i < maxI && image[centerJ + i * this.imageWidth] && stateCount[1] <= maxCount) {
stateCount[1]++;
i++;
}
if (i == maxI || stateCount[1] > maxCount) {
return NaN;
}
while (i < maxI && !image[centerJ + i * this.imageWidth] && stateCount[2] <= maxCount) {
stateCount[2]++;
i++;
}
if (stateCount[2] > maxCount) {
return NaN;
}
var /** @type {?} */ stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {
return NaN;
}
return this.foundPatternCross(stateCount) ? this.centerFromEnd(stateCount, i) : NaN;
};
this.handlePossibleCenter = function (stateCount, i, j) {
var /** @type {?} */ stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
var /** @type {?} */ centerJ = this.centerFromEnd(stateCount, j);
var /** @type {?} */ centerI = this.crossCheckVertical(i, Math.floor(centerJ), 2 * stateCount[1], stateCountTotal);
if (!isNaN(centerI)) {
var /** @type {?} */ estimatedModuleSize = (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0;
var /** @type {?} */ max = this.possibleCenters.length;
for (var /** @type {?} */ index = 0; index < max; index++) {
var /** @type {?} */ center = this.possibleCenters[index];
// Look for about the same center and module size:
if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) {
return new AlignmentPattern(centerJ, centerI, estimatedModuleSize);
}
}
// Hadn't found this before; save it
var /** @type {?} */ point = new AlignmentPattern(centerJ, centerI, estimatedModuleSize);
this.possibleCenters.push(point);
if (this.resultPointCallback != null) {
this.resultPointCallback.foundPossibleResultPoint(point);
}
}
return null;
};
this.find = function () {
var /** @type {?} */ startX = this.startX;
var /** @type {?} */ height = this.height;
var /** @type {?} */ maxJ = startX + this.width;
var /** @type {?} */ middleI = this.startY + (height >> 1);
// We are looking for black/white/black modules in 1:1:1 ratio;
// this tracks the number of black/white/black modules seen so far
var /** @type {?} */ stateCount = new Array(0, 0, 0);
for (var /** @type {?} */ iGen = 0; iGen < height; iGen++) {
// Search from middle outwards
var /** @type {?} */ i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
stateCount[0] = 0;
stateCount[1] = 0;
stateCount[2] = 0;
var /** @type {?} */ j = startX;
// Burn off leading white pixels before anything else; if we start in the middle of
// a white run, it doesn't make sense to count its length, since we don't know if the
// white run continued to the left of the start point
while (j < maxJ && !this.image[j + this.imageWidth * i]) {
j++;
}
var /** @type {?} */ currentState = 0;
while (j < maxJ) {
if (this.image[j + i * this.imageWidth]) {
// Black pixel
if (currentState == 1) {
// Counting black pixels
stateCount[currentState]++;
}
else {
// Counting white pixels
if (currentState == 2) {
// A winner?
if (this.foundPatternCross(stateCount)) {
// Yes
var /** @type {?} */ confirmed = this.handlePossibleCenter(stateCount, i, j);
if (confirmed != null) {
return confirmed;
}
}
stateCount[0] = stateCount[2];
stateCount[1] = 1;
stateCount[2] = 0;
currentState = 1;
}
else {
stateCount[++currentState]++;
}
}
}
else {
// White pixel
if (currentState == 1) {
// Counting black pixels
currentState++;
}
stateCount[currentState]++;
}
j++;
}
if (this.foundPatternCross(stateCount)) {
var /** @type {?} */ confirmed = this.handlePossibleCenter(stateCount, i, maxJ);
if (confirmed != null) {
return confirmed;
}
}
}
// Hmm, nothing we saw was observed and confirmed twice. If we had
// any guess at all, return it.
if (!(this.possibleCenters.length == 0)) {
return this.possibleCenters[0];
}
throw `Couldn't find enough alignment patterns`;
};
this.image = image;
this.startX = startX;
this.startY = startY;
this.width = width;
this.height = height;
this.moduleSize = moduleSize;
this.resultPointCallback = resultPointCallback;
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/*
Ported to JavaScript by Lazar Laszlo 2011
lazarsoft@gmail.com, www.lazarsoft.info
*/
class PerspectiveTransform {
/**
* @param {?} a11
* @param {?} a21
* @param {?} a31
* @param {?} a12
* @param {?} a22
* @param {?} a32
* @param {?} a13
* @param {?} a23
* @param {?} a33
*/
constructor(a11, a21, a31, a12, a22, a32, a13, a23, a33) {
this.transformPoints1 = function (points) {
var /** @type {?} */ max = points.length;
var /** @type {?} */ a11 = this.a11;
var /** @type {?} */ a12 = this.a12;
var /** @type {?} */ a13 = this.a13;
var /** @type {?} */ a21 = this.a21;
var /** @type {?} */ a22 = this.a22;
var /** @type {?} */ a23 = this.a23;
var /** @type {?} */ a31 = this.a31;
var /** @type {?} */ a32 = this.a32;
var /** @type {?} */ a33 = this.a33;
for (var /** @type {?} */ i = 0; i < max; i += 2) {
var /** @type {?} */ x = points[i];
var /** @type {?} */ y = points[i + 1];
var /** @type {?} */ denominator = a13 * x + a23 * y + a33;
points[i] = (a11 * x + a21 * y + a31) / denominator;
points[i + 1] = (a12 * x + a22 * y + a32) / denominator;
}
};
this.transformPoints2 = function (xValues, yValues) {
var /** @type {?} */ n = xValues.length;
for (var /** @type {?} */ i = 0; i < n; i++) {
var /** @type {?} */ x = xValues[i];
var /** @type {?} */ y = yValues[i];
var /** @type {?} */ denominator = this.a13 * x + this.a23 * y + this.a33;
xValues[i] = (this.a11 * x + this.a21 * y + this.a31) / denominator;
yValues[i] = (this.a12 * x + this.a22 * y + this.a32) / denominator;
}
};
this.buildAdjoint = function () {
// Adjoint is the transpose of the cofactor matrix:
return new PerspectiveTransform(this.a22 * this.a33 - this.a23 * this.a32, this.a23 * this.a31 - this.a21 * this.a33, this.a21 * this.a32 - this.a22 * this.a31, this.a13 * this.a32 - this.a12 * this.a33, this.a11 * this.a33 - this.a13 * this.a31, this.a12 * this.a31 - this.a11 * this.a32, this.a12 * this.a23 - this.a13 * this.a22, this.a13 * this.a21 - this.a11 * this.a23, this.a11 * this.a22 - this.a12 * this.a21);
};
this.times = function (other) {
return new PerspectiveTransform(this.a11 * other.a11 + this.a21 * other.a12 + this.a31 * other.a13, this.a11 * other.a21 + this.a21 * other.a22 + this.a31 * other.a23, this.a11 * other.a31 + this.a21 * other.a32 + this.a31 * other.a33, this.a12 * other.a11 + this.a22 * other.a12 + this.a32 * other.a13, this.a12 * other.a21 + this.a22 * other.a22 + this.a32 * other.a23, this.a12 * other.a31 + this.a22 * other.a32 + this.a32 * other.a33, this.a13 * other.a11 + this.a23 * other.a12 + this.a33 * other.a13, this.a13 * other.a21 + this.a23 * other.a22 + this.a33 * other.a23, this.a13 * other.a31 + this.a23 * other.a32 + this.a33 * other.a33);
};
this.a11 = a11;
this.a12 = a12;
this.a13 = a13;
this.a21 = a21;
this.a22 = a22;
this.a23 = a23;
this.a31 = a31;
this.a32 = a32;
this.a33 = a33;
}
/**
* @param {?} x0
* @param {?} y0
* @param {?} x1
* @param {?} y1
* @param {?} x2
* @param {?} y2
* @param {?} x3
* @param {?} y3
* @param {?} x0p
* @param {?} y0p
* @param {?} x1p
* @param {?} y1p
* @param {?} x2p
* @param {?} y2p
* @param {?} x3p
* @param {?} y3p
* @return {?}
*/
static quadrilateralToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3, x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p) {
var /** @type {?} */ qToS = this.quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);
var /** @type {?} */ sToQ = this.squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);
return sToQ.times(qToS);
}
/**
* @param {?} x0
* @param {?} y0
* @param {?} x1
* @param {?} y1
* @param {?} x2
* @param {?} y2
* @param {?} x3
* @param {?} y3
* @return {?}
*/
static squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3) {
var /** @type {?} */ dy2 = y3 - y2;
var /** @type {?} */ dy3 = y0 - y1 + y2 - y3;
if (dy2 == 0.0 && dy3 == 0.0) {
return new PerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0.0, 0.0, 1.0);
}
else {
var /** @type {?} */ dx1 = x1 - x2;
var /** @type {?} */ dx2 = x3 - x2;
var /** @type {?} */ dx3 = x0 - x1 + x2 - x3;
var /** @type {?} */ dy1 = y1 - y2;
var /** @type {?} */ denominator = dx1 * dy2 - dx2 * dy1;
var /** @type {?} */ a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
var /** @type {?} */ a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
return new PerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0, a13, a23, 1.0);
}
}
/**
* @param {?} x0
* @param {?} y0
* @param {?} x1
* @param {?} y1
* @param {?} x2
* @param {?} y2
* @param {?} x3
* @param {?} y3
* @return {?}
*/
static quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3) {
// Here, the adjoint serves as the inverse:
const /** @type {?} */ t = this.squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3);
return t.buildAdjoint();
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/*
Ported to JavaScript by Lazar Laszlo 2011
lazarsoft@gmail.com, www.lazarsoft.info
*/
/*
*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class BitMatrix {
/**
* @param {?} width
* @param {?=} height
*/
constructor(width, height) {
if (!height)
height = width;
if (width < 1 || height < 1) {
throw "Both dimensions must be greater than 0";
}
this.width = width;
this.height = height;
this.rowSize = width >> 5;
if ((width & 0x1f) != 0) {
this.rowSize++;
}
this.bits = new Array(this.rowSize * height);
for (var /** @type {?} */ i = 0; i < this.bits.length; i++)
this.bits[i] = 0;
}
/**
* @return {?}
*/
get Width() {
return this.width;
}
;
/**
* @return {?}
*/
get Height() {
return this.height;
}
;
/**
* @return {?}
*/
get Dimension() {
if (this.width != this.height) {
throw "Can't call getDimension() on a non-square matrix";
}
return this.width;
}
;
/**
* @param {?} number
* @param {?} bits
* @return {?}
*/
URShift(number, bits) {
if (number >= 0)
return number >> bits;
else
return (number >> bits) + (2 << ~bits);
}
/**
* @param {?} x
* @param {?} y
* @return {?}
*/
get_Renamed(x, y) {
var /** @type {?} */ offset = y * this.rowSize + (x >> 5);
return ((this.URShift(this.bits[offset], (x & 0x1f))) & 1) != 0;
}
/**
* @param {?} x
* @param {?} y
* @return {?}
*/
set_Renamed(x, y) {
var /** @type {?} */ offset = y * this.rowSize + (x >> 5);
this.bits[offset] |= 1 << (x & 0x1f);
}
/**
* @param {?} x
* @param {?} y
* @return {?}
*/
flip(x, y) {
var /** @type {?} */ offset = y * this.rowSize + (x >> 5);
this.bits[offset] ^= 1 << (x & 0x1f);
}
/**
* @return {?}
*/
clear() {
var /** @type {?} */ max = this.bits.length;
for (var /** @type {?} */ i = 0; i < max; i++) {
this.bits[i] = 0;
}
}
/**
* @param {?} left
* @param {?} top
* @param {?} width
* @param {?} height
* @return {?}
*/
setRegion(left, top, width, height) {
if (top < 0 || left < 0) {
throw "Left and top must be nonnegative";
}
if (height < 1 || width < 1) {
throw "Height and width must be at least 1";
}
var /** @type {?} */ right = left + width;
var /** @type {?} */ bottom = top + height;
if (bottom > this.height || right > this.width) {
throw "The region must fit inside the matrix";
}
for (var /** @type {?} */ y = top; y < bottom; y++) {
var /** @type {?} */ offset = y * this.rowSize;
for (var /** @type {?} */ x = left; x < right; x++) {
this.bits[offset + (x >> 5)] |= 1 << (x & 0x1f);
}
}
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/*
Ported to JavaScript by Lazar Laszlo 2011
lazarsoft@gmail.com, www.lazarsoft.info
*/
class GridSampler {
/**
* @param {?} width
* @param {?} height
*/
constructor(width, height) {
this.width = width;
this.height = height;
}
/**
* @param {?} image
* @param {?} points
* @return {?}
*/
checkAndNudgePoints(image, points) {
var /** @type {?} */ width = this.width;
var /** @type {?} */ height = this.height;
// Check and nudge points from start until we see some that are OK:
var /** @type {?} */ nudged = true;
for (var /** @type {?} */ offset = 0; offset < points.length && nudged; offset += 2) {
var /** @type {?} */ x = Math.floor(points[offset]);
var /** @type {?} */ y = Math.floor(points[offset + 1]);
if (x < -1 || x > width || y < -1 || y > height) {
throw "Error.checkAndNudgePoints ";
}
nudged = false;
if (x == -1) {
points[offset] = 0.0;
nudged = true;
}
else if (x == width) {
points[offset] = width - 1;
nudged = true;
}
if (y == -1) {
points[offset + 1] = 0.0;
nudged = true;
}
else if (y == height) {
points[offset + 1] = height - 1;
nudged = true;
}
}
// Check and nudge points from end:
nudged = true;
for (var /** @type {?} */ offset = points.length - 2; offset >= 0 && nudged; offset -= 2) {
var /** @type {?} */ x = Math.floor(points[offset]);
var /** @type {?} */ y = Math.floor(points[offset + 1]);
if (x < -1 || x > width || y < -1 || y > height) {
throw "Error.checkAndNudgePoints ";
}
nudged = false;
if (x == -1) {
points[offset] = 0.0;
nudged = true;
}
else if (x == width) {
points[offset] = width - 1;
nudged = true;
}
if (y == -1) {
points[offset + 1] = 0.0;
nudged = true;
}
else if (y == height) {
points[offset + 1] = height - 1;
nudged = true;
}
}
}
/**
* @param {?} image
* @param {?} rawImage
* @param {?} dimension
* @param {?} transform
* @return {?}
*/
sampleGrid3(image, rawImage, dimension, transform) {
var /** @type {?} */ bits = new BitMatrix(dimension, dimension);
var /** @type {?} */ points = new Array(dimension << 1);
for (var /** @type {?} */ y = 0; y < dimension; y++) {
var /** @type {?} */ max = points.length;
var /** @type {?} */ iValue = y + 0.5;
for (var /** @type {?} */ x = 0; x < max; x += 2) {
points[x] = (x >> 1) + 0.5;
points[x + 1] = iValue;
}
transform.transformPoints1(points);
// Quick check to see if points transformed to something inside the image;
// sufficient to check the endpoints
this.checkAndNudgePoints(image, points);
try {
for (var /** @type {?} */ x = 0; x < max; x += 2) {
var /** @type {?} */ xpoint = (Math.floor(points[x]) * 4) + (Math.floor(points[x + 1]) * this.width * 4);
var /** @type {?} */ bit = image[Math.floor(points[x]) + this.width * Math.floor(points[x + 1])];
rawImage.data[xpoint] = bit ? 255 : 0;
rawImage.data[xpoint + 1] = bit ? 255 : 0;
rawImage.data[xpoint + 2] = 0;
rawImage.data[xpoint + 3] = 255;
//bits[x >> 1][ y]=bit;
if (bit)
bits.set_Renamed(x >> 1, y);
}
}
catch (/** @type {?} */ aioobe) {
// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
// transform gets "twisted" such that it maps a straight line of points to a set of points
// whose endpoints are in bounds, but others are not. There is probably some mathematical
// way to detect this about the transformation that I don't know yet.
// This results in an ugly runtime exception despite our clever checks above -- can't have
// that. We could check each point's coordinates but that feels duplicative. We settle for
// catching and wrapping ArrayIndexOutOfBoundsException.
throw "Error.checkAndNudgePoints";
}
}
return bits;
}
/**
* @param {?} image
* @param {?} dimension
* @param {?} p1ToX
* @param {?} p1ToY
* @param {?} p2ToX
* @param {?} p2ToY
* @param {?} p3ToX
* @param {?} p3ToY
* @param {?} p4ToX
* @param {?} p4ToY
* @param {?} p1FromX
* @param {?} p1FromY
* @param {?} p2FromX
* @param {?} p2FromY
* @param {?} p3FromX
* @param {?} p3FromY
* @param {?} p4FromX
* @param {?} p4FromY
* @return {?}
*/
sampleGridx(image, dimension, p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY) {
var /** @type {?} */ transform = PerspectiveTransform.quadrilateralToQuadrilateral(p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
return this.sampleGrid3(image, {}, dimension, transform);
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/*
Ported to JavaScript by Lazar Laszlo 2011
lazarsoft@gmail.com, www.lazarsoft.info
*/
/*
*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class ErrorCorrectionLevel {
/**
* @param {?} ordinal
* @param {?} bits
* @param {?} name
*/
constructor(ordinal, bits, name) {
this.ordinal_Renamed_Field = ordinal;
this.bits = bits;
this.name = name;
}
/**
* @param {?} bits
* @return {?}
*/
static forBits(bits) {
if (bits < 0 || bits >= this.FOR_BITS.length) {
throw "ArgumentException";
}
return this.FOR_BITS[bits];
}
/**
* @return {?}
*/
get Bits() {
return this.bits;
}
;
/**
* @return {?}
*/
get Name() {
return this.name;
}
;
/**
* @return {?}
*/
ordinal() {
return this.ordinal_Renamed_Field;
}
}
ErrorCorrectionLevel.L = new ErrorCorrectionLevel(0, 0x01, "L");
ErrorCorrectionLevel.M = new ErrorCorrectionLevel(1, 0x00, "M");
ErrorCorrectionLevel.Q = new ErrorCorrectionLevel(2, 0x03, "Q");
ErrorCorrectionLevel.H = new ErrorCorrectionLevel(3, 0x02, "H");
ErrorCorrectionLevel.FOR_BITS = new Array(ErrorCorrectionLevel.M, ErrorCorrectionLevel.L, ErrorCorrectionLevel.H, ErrorCorrectionLevel.Q);
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/*
Ported to JavaScript by Lazar Laszlo 2011
lazarsoft@gmail.com, www.lazarsoft.info
*/
class FormatInformation {
/**
* @param {?} formatInfo
*/
constructor(formatInfo) {
this.Equals = function (o) {
var /** @type {?} */ other = o;
return this.errorCorrectionLevel == other.errorCorrectionLevel && this.dataMask == other.dataMask;
};
this.errorCorrectionLevel = ErrorCorrectionLevel.forBits((formatInfo >> 3) & 0x03);
this.dataMask = (formatInfo & 0x07);
}
/**
* @return {?}
*/
get ErrorCorrectionLevel() {
return this.errorCorrectionLevel;
}
;
/**
* @return {?}
*/
get DataMask() {
return this.dataMask;
}
;
/**
* @return {?}
*/
GetHashCode() {
return (this.errorCorrectionLevel.ordinal() << 3) | this.dataMask;
}
/**
* @param {?} number
* @param {?} bits
* @return {?}
*/
static URShift(number, bits) {
if (number >= 0)
return number >> bits;
else
return (number >> bits) + (2 << ~bits);
}
/**
* @param {?} a
* @param {?} b
* @return {?}
*/
static numBitsDiffering(a, b) {
a ^= b; // a now has a 1 bit exactly where its bit differs with b's
// Count bits set quickly with a series of lookups:
return FormatInformation.BITS_SET_IN_HALF_BYTE[a & 0x0F]
+ FormatInformation.BITS_SET_IN_HALF_BYTE[(this.URShift(a, 4) & 0x0F)]
+ FormatInformation.BITS_SET_IN_HALF_BYTE[(this.URShift(a, 8) & 0x0F)]
+ FormatInformation.BITS_SET_IN_HALF_BYTE[(this.URShift(a, 12) & 0x0F)]
+ FormatInformation.BITS_SET_IN_HALF_BYTE[(this.URShift(a, 16) & 0x0F)]
+ FormatInformation.BITS_SET_IN_HALF_BYTE[(this.URShift(a, 20) & 0x0F)]
+ FormatInformation.BITS_SET_IN_HALF_BYTE[(this.URShift(a, 24) & 0x0F)]
+ FormatInformation.BITS_SET_IN_HALF_BYTE[(this.URShift(a, 28) & 0x0F)];
}
/**
* @param {?} maskedFormatInfo
* @return {?}
*/
static decodeFormatInformation(maskedFormatInfo) {
var /** @type {?} */ formatInfo = this.doDecodeFormatInformation(maskedFormatInfo);
if (formatInfo != null) {
return formatInfo;
}
// Should return null, but, some QR codes apparently
// do not mask this info. Try again by actually masking the pattern
// first
return this.doDecodeFormatInformation(maskedFormatInfo ^ FormatInformation.FORMAT_INFO_MASK_QR);
}
/**
* @param {?} maskedFormatInfo
* @return {?}
*/
static doDecodeFormatInformation(maskedFormatInfo) {
// Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing
var /** @type {?} */ bestDifference = 0xffffffff;
var /** @type {?} */ bestFormatInfo = 0;
for (var /** @type {?} */ i = 0; i < FormatInformation.FORMAT_INFO_DECODE_LOOKUP.length; i++) {
var /** @type {?} */ decodeInfo = FormatInformation.FORMAT_INFO_DECODE_LOOKUP[i];
var /** @type {?} */ targetInfo = decodeInfo[0];
if (targetInfo == maskedFormatInfo) {
// Found an exact match
return new FormatInformation(decodeInfo[1]);
}
var /** @type {?} */ bitsDifference = FormatInformation.numBitsDiffering(maskedFormatInfo, targetInfo);
if (bitsDifference < bestDifference) {
bestFormatInfo = decodeInfo[1];
bestDifference = bitsDifference;
}
}
// Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits
// differing means we found a match
if (bestDifference <= 3) {
return new FormatInformation(bestFormatInfo);
}
return null;
}
/**
* @param {?} bits
* @return {?}
*/
static forBits(bits) {
{
if (bits < 0 || bits >= FormatInformation.FOR_BITS.length) {
throw "ArgumentException";
}
return FormatInformation.FOR_BITS[bits];
}
}
}
FormatInformation.FORMAT_INFO_MASK_QR = 0x5412;
FormatInformation.FORMAT_INFO_DECODE_LOOKUP = new Array(new Array(0x5412, 0x00), new Array(0x5125, 0x01), new Array(0x5E7C, 0x02), new Array(0x5B4B, 0x03), new Array(0x45F9, 0x04), new Array(0x40CE, 0x05), new Array(0x4F97, 0x06), new Array(0x4AA0, 0x07), new Array(0x77C4, 0x08), new Array(0x72F3, 0x09), new Array(0x7DAA, 0x0A), new Array(0x789D, 0x0B), new Array(0x662F, 0x0C), new Array(0x6318, 0x0D), new Array(0x6C41, 0x0E), new Array(0x6976, 0x0F), new Array(0x1689, 0x10), new Array(0x13BE, 0x11), new Array(0x1CE7, 0x12), new Array(0x19D0, 0x13), new Array(0x0762, 0x14), new Array(0x0255, 0x15), new Array(0x0D0C, 0x16), new Array(0x083B, 0x17), new Array(0x355F, 0x18), new Array(0x3068, 0x19), new Array(0x3F31, 0x1A), new Array(0x3A06, 0x1B), new Array(0x24B4, 0x1C), new Array(0x2183, 0x1D), new Array(0x2EDA, 0x1E), new Array(0x2BED, 0x1F));
FormatInformation.BITS_SET_IN_HALF_BYTE = new Array(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
FormatInformation.L = new ErrorCorrectionLevel(0, 0x01, "L");
FormatInformation.M = new ErrorCorrectionLevel(1, 0x00, "M");
FormatInformation.Q = new ErrorCorrectionLevel(2, 0x03, "Q");
FormatInformation.H = new ErrorCorrectionLevel(3, 0x02, "H");
FormatInformation.FOR_BITS = new Array(FormatInformation.M, FormatInformation.L, FormatInformation.H, FormatInformation.Q);
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/*
Ported to JavaScript by Lazar Laszlo 2011
lazarsoft@gmail.com, www.lazarsoft.info
*/
class ECB {
/**
* @param {?} count
* @param {?} dataCodewords
*/
constructor(count, dataCodewords) {
this.count = count;
this.dataCodewords = dataCodewords;
}
/**
* @return {?}
*/
get Count() {
return this.count;
}
;
/**
* @return {?}
*/
get DataCodewords() {
return this.dataCodewords;
}
;
}
class ECBlocks {
/**
* @param {?} ecCodewordsPerBlock
* @param {?} ecBlocks1
* @param {?=} ecBlocks2
*/
constructor(ecCodewordsPerBlock, ecBlocks1, ecBlocks2) {
this.getECBlocks = function () {
return this.ecBlocks;
};
this.ecCodewordsPerBlock = ecCodewordsPerBlock;
if (ecBlocks2)
this.ecBlocks = new Array(ecBlocks1, ecBlocks2);
else
this.ecBlocks = new Array(ecBlocks1);
}
/**
* @return {?}
*/
get ECCodewordsPerBlock() {
return this.ecCodewordsPerBlock;
}
;
/**
* @return {?}
*/
get TotalECCodewords() {
return this.ecCodewordsPerBlock * this.NumBlocks;
}
;
/**
* @return {?}
*/
get NumBlocks() {
var /** @type {?} */ total = 0;
for (var /** @type {?} */ i = 0; i < this.ecBlocks.length; i++) {
total += this.ecBlocks[i].length;
}
return total;
}
;
}
class Version {
/**
* @param {?} versionNumber
* @param {?} alignmentPatternCenters
* @param {?} ecBlocks1
* @param {?} ecBlocks2
* @param {?} ecBlocks3
* @param {?} ecBlocks4
*/
constructor(versionNumber, alignmentPatternCenters, ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4) {
this.buildFunctionPattern = function () {
var /** @type {?} */ dimension = this.DimensionForVersion;
var /** @type {?} */ bitMatrix = new BitMatrix(dimension);
// Top left finder pattern + separator + format
bitMatrix.setRegion(0, 0, 9, 9);
// Top right finder pattern + separator + format
bitMatrix.setRegion(dimension - 8, 0, 8, 9);
// Bottom left finder pattern + separator + format
bitMatrix.setRegion(0, dimension - 8, 9, 8);
// Alignment patterns
var /** @type {?} */ max = this.alignmentPatternCenters.length;
for (var /** @type {?} */ x = 0; x < max; x++) {
var /** @type {?} */ i = this.alignmentPatternCenters[x] - 2;
for (var /** @type {?} */ y = 0; y < max; y++) {
if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {
// No alignment patterns near the three finder paterns
continue;
}
bitMatrix.setRegion(this.alignmentPatternCenters[y] - 2, i, 5, 5);
}
}
// Vertical timing pattern
bitMatrix.setRegion(6, 9, 1, dimension - 17);
// Horizontal timing pattern
bitMatrix.setRegion(9, 6, dimension - 17, 1);
if (this.versionNumber > 6) {
// Version info, top right
bitMatrix.setRegion(dimension - 11, 0, 3, 6);
// Version info, bottom left
bitMatrix.setRegion(0, dimension - 11, 6, 3);
}
return bitMatrix;
};
this.getECBlocksForLevel = function (ecLevel) {
return this.ecBlocks[ecLevel.ordinal()];
};
this.versionNumber = versionNumber;
this.alignmentPatternCenters = alignmentPatternCenters;
this.ecBlocks = new Array(ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4);
var /** @type {?} */ total = 0;
var /** @type {?} */ ecCodewords = ecBlocks1.ECCodewordsPerBlock;
var /** @type {?} */ ecbArray = ecBlocks1.getECBlocks();
for (var /** @type {?} */ i = 0; i < ecbArray.length; i++) {
var /** @type {?} */ ecBlock = ecbArray[i];
total += ecBlock.Count * (ecBlock.DataCodewords + ecCodewords);
}
this.totalCodewords = total;
}
/**
* @return {?}
*/
get VersionNumber() {
return this.versionNumber;
}
;
/**
* @return {?}
*/
get AlignmentPatternCenters() {
return this.alignmentPatternCenters;
}
;
/**
* @return {?}
*/
get TotalCodewords() {
return this.totalCodewords;
}
;
/**
* @return {?}
*/
get DimensionForVersion() {
return 17 + 4 * this.versionNumber;
}
;
/**
* @param {?} versionNumber
* @return {?}
*/
static getVersionForNumber(versionNumber) {
if (versionNumber < 1 || versionNumber > 40) {
throw "ArgumentException";
}
return Version.VERSIONS[versionNumber - 1];
}
/**
* @param {?} dimension
* @return {?}
*/
static getProvisionalVersionForDimension(dimension) {
if (dimension % 4 != 1) {
throw "Error getProvisionalVersionForDimension";
}
try {
return Version.getVersionForNumber((dimension - 17) >> 2);
}
catch (/** @type {?} */ iae) {
throw "Error getVersionForNumber";
}
}
/**
* @param {?} versionBits
* @return {?}
*/
static decodeVersionInformation(versionBits) {
var /** @type {?} */ bestDifference = 0xffffffff;
var /** @type {?} */ bestVersion = 0;
for (var /** @type {?} */ i = 0; i < Version.VERSION_DECODE_INFO.length; i++) {
var /** @type {?} */ targetVersion = Version.VERSION_DECODE_INFO[i];
// Do the version info bits match exactly? done.
if (targetVersion == versionBits) {
return this.getVersionForNumber(i + 7);
}
// Otherwise see if this is the closest to a real version info bit string
// we have seen so far
var /** @type {?} */ bitsDifference = FormatInformation.numBitsDiffering(versionBits, targetVersion);
if (bitsDifference < bestDifference) {
bestVersion = i + 7;
bestDifference = bitsDifference;
}
}
// We can tolerate up to 3 bits of error since no two version info codewords will
// differ in less than 4 bits.
if (bestDifference <= 3) {
return this.getVersionForNumber(bestVersion);
}
// If we didn't find a close enough match, fail
return null;
}
/**
* @return {?}
*/
static buildVersions() {
return new Array(new Version(1, new Array(), new ECBlocks(7, new ECB(1, 19)), new ECBlocks(10, new ECB(1, 16)), new ECBlocks(13, new ECB(1, 13)), new ECBlocks(17, new ECB(1, 9))), new Version(2, new Array(6, 18), new ECBlocks(10, new ECB(1, 34)), new ECBlocks(16, new ECB(1, 28)), new ECBlocks(22, new ECB(1, 22)), new ECBlocks(28, new ECB(1, 16))), new Version(3, new Array(6, 22), new ECBlocks(15, new ECB(1, 55)), new ECBlocks(26, new ECB(1, 44)), new ECBlocks(18, new ECB(2, 17)), new ECBlocks(22, new ECB(2, 13))), new Version(4, new Array(6, 26), new ECBlocks(20, new ECB(1, 80)), new ECBlocks(18, new ECB(2, 32)), new ECBlocks(26, new ECB(2, 24)), new ECBlocks(16, new ECB(4, 9))), new Version(5, new Array(6, 30), new ECBlocks(26, new ECB(1, 108)), new ECBlocks(24, new ECB(2, 43)), new ECBlocks(18, new ECB(2, 15), new ECB(2, 16)), new ECBlocks(22, new ECB(2, 11), new ECB(2, 12))), new Version(6, new Array(6, 34), new ECBlocks(18, new ECB(2, 68)), new ECBlocks(16, new ECB(4, 27)), new ECBlocks(24, new ECB(4, 19)), new ECBlocks(28, new ECB(4, 15))), new Version(7, new Array(6, 22, 38), new ECBlocks(20, new ECB(2, 78)), new ECBlocks(18, new ECB(4, 31)), new ECBlocks(18, new ECB(2, 14), new ECB(4, 15)), new ECBlocks(26, new ECB(4, 13), new ECB(1, 14))), new Version(8, new Array(6, 24, 42), new ECBlocks(24, new ECB(2, 97)), new ECBlocks(22, new ECB(2, 38), new ECB(2, 39)), new ECBlocks(22, new ECB(4, 18), new ECB(2, 19)), new ECBlocks(26, new ECB(4, 14), new ECB(2, 15))), new Version(9, new Array(6, 26, 46), new ECBlocks(30, new ECB(2, 116)), new ECBlocks(22, new ECB(3, 36), new ECB(2, 37)), new ECBlocks(20, new ECB(4, 16), new ECB(4, 17)), new ECBlocks(24, new ECB(4, 12), new ECB(4, 13))), new Version(10, new Array(6, 28, 50), new ECBlocks(18, new ECB(2, 68), new ECB(2, 69)), new ECBlocks(26, new ECB(4, 43), new ECB(1, 44)), new ECBlocks(24, new ECB(6, 19), new ECB(2, 20)), new ECBlocks(28, new ECB(6, 15), new ECB(2, 16))), new Version(11, new Array(6, 30, 54), new ECBlocks(20, new ECB(4, 81)), new ECBlocks(30, new ECB(1, 50), new ECB(4, 51)), new ECBlocks(28, new ECB(4, 22), new ECB(4, 23)), new ECBlocks(24, new ECB(3, 12), new ECB(8, 13))), new Version(12, new Array(6, 32, 58), new ECBlocks(24, new ECB(2, 92), new ECB(2, 93)), new ECBlocks(22, new ECB(6, 36), new ECB(2, 37)), new ECBlocks(26, new ECB(4, 20), new ECB(6, 21)), new ECBlocks(28, new ECB(7, 14), new ECB(4, 15))), new Version(13, new Array(6, 34, 62), new ECBlocks(26, new ECB(4, 107)), new ECBlocks(22, new ECB(8, 37), new ECB(1, 38)), new ECBlocks(24, new ECB(8, 20), new ECB(4, 21)), new ECBlocks(22, new ECB(12, 11), new ECB(4, 12))), new Version(14, new Array(6, 26, 46, 66), new ECBlocks(30, new ECB(3, 115), new ECB(1, 116)), new ECBlocks(24, new ECB(4, 40), new ECB(5, 41)), new ECBlocks(20, new ECB(11, 16), new ECB(5, 17)), new ECBlocks(24, new ECB(11, 12), new ECB(5, 13))), new Version(15, new Array(6, 26, 48, 70), new ECBlocks(22, new ECB(5, 87), new ECB(1, 88)), new ECBlocks(24, new ECB(5, 41), new ECB(5, 42)), new ECBlocks(30, new ECB(5, 24), new ECB(7, 25)), new ECBlocks(24, new ECB(11, 12), new ECB(7, 13))), new Version(16, new Array(6, 26, 50, 74), new ECBlocks(24, new ECB(5, 98), new ECB(1, 99)), new ECBlocks(28, new ECB(7, 45), new ECB(3, 46)), new ECBlocks(24, new ECB(15, 19), new ECB(2, 20)), new ECBlocks(30, new ECB(3, 15), new ECB(13, 16))), new Version(17, new Array(6, 30, 54, 78), new ECBlocks(28, new ECB(1, 107), new ECB(5, 108)), new ECBlocks(28, new ECB(10, 46), new ECB(1, 47)), new ECBlocks(28, new ECB(1, 22), new ECB(15, 23)), new ECBlocks(28, new ECB(2, 14), new ECB(17, 15))), new Version(18, new Array(6, 30, 56, 82), new ECBlocks(30, new ECB(5, 120), new ECB(1, 121)), new ECBlocks(26, new ECB(9, 43), new ECB(4, 44)), new ECBlocks(28, new ECB(17, 22), new ECB(1, 23)), new ECBlocks(28, new ECB(2, 14), new ECB(19, 15))), new Version(19, new Array(6, 30, 58, 86), new ECBlocks(28, new ECB(3, 113), new ECB(4, 114)), new ECBlocks(26, new ECB(3, 44), new ECB(11, 45)), new ECBlocks(26, new ECB(17, 21), new ECB(4, 22)), new ECBlocks(26, new ECB(9, 13), new ECB(16, 14))), new Version(20, new Array(6, 34, 62, 90), new ECBlocks(28, new ECB(3, 107), new ECB(5, 108)), new ECBlocks(26, new ECB(3, 41), new ECB(13, 42)), new ECBlocks(30, new ECB(15, 24), new ECB(5, 25)), new ECBlocks(28, new ECB(15, 15), new ECB(10, 16))), new Version(21, new Array(6, 28, 50, 72, 94), new ECBlocks(28, new ECB(4, 116), new ECB(4, 117)), new ECBlocks(26, new ECB(17, 42)), new ECBlocks(28, new ECB(17, 22), new ECB(6, 23)), new ECBlocks(30, new ECB(19, 16), new ECB(6, 17))), new Version(22, new Array(6, 26, 50, 74, 98), new ECBlocks(28, new ECB(2, 111), new ECB(7, 112)), new ECBlocks(28, new ECB(17, 46)), new ECBlocks(30, new ECB(7, 24), new ECB(16, 25)), new ECBlocks(24, new ECB(34, 13))), new Version(23, new Array(6, 30, 54, 74, 102), new ECBlocks(30, new ECB(4, 121), new ECB(5, 122)), new ECBlocks(28, new ECB(4, 47), new ECB(14, 48)), new ECBlocks(30, new ECB(11, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(16, 15), new ECB(14, 16))), new Version(24, new Array(6, 28, 54, 80, 106), new ECBlocks(30, new ECB(6, 117), new ECB(4, 118)), new ECBlocks(28, new ECB(6, 45), new ECB(14, 46)), new ECBlocks(30, new ECB(11, 24), new ECB(16, 25)), new ECBlocks(30, new ECB(30, 16), new ECB(2, 17))), new Version(25, new Array(6, 32, 58, 84, 110), new ECBlocks(26, new ECB(8, 106), new ECB(4, 107)), new ECBlocks(28, new ECB(8, 47), new ECB(13, 48)), new ECBlocks(30, new ECB(7, 24), new ECB(22, 25)), new ECBlocks(30, new ECB(22, 15), new ECB(13, 16))), new Version(26, new Array(6, 30, 58, 86, 114), new ECBlocks(28, new ECB(10, 114), new ECB(2, 115)), new ECBlocks(28, new ECB(19, 46), new ECB(4, 47)), new ECBlocks(28, new ECB(28, 22), new ECB(6, 23)), new ECBlocks(30, new ECB(33, 16), new ECB(4, 17))), new Version(27, new Array(6, 34, 62, 90, 118), new ECBlocks(30, new ECB(8, 122), new ECB(4, 123)), new ECBlocks(28, new ECB(22, 45), new ECB(3, 46)), new ECBlocks(30, new ECB(8, 23), new ECB(26, 24)), new ECBlocks(30, new ECB(12, 15), new ECB(28, 16))), new Version(28, new Array(6, 26, 50, 74, 98, 122), new ECBlocks(30, new ECB(3, 117), new ECB(10, 118)), new ECBlocks(28, new ECB(3, 45), new ECB(23, 46)), new ECBlocks(30, new ECB(4, 24), new ECB(31, 25)), new ECBlocks(30, new ECB(11, 15), new ECB(31, 16))), new Version(29, new Array(6, 30, 54, 78, 102, 126), new ECBlocks(30, new ECB(7, 116), new ECB(7, 117)), new ECBlocks(28, new ECB(21, 45), new ECB(7, 46)), new ECBlocks(30, new ECB(1, 23), new ECB(37, 24)), new ECBlocks(30, new ECB(19, 15), new ECB(26, 16))), new Version(30, new Array(6, 26, 52, 78, 104, 130), new ECBlocks(30, new ECB(5, 115), new ECB(10, 116)), new ECBlocks(28, new ECB(19, 47), new ECB(10, 48)), new ECBlocks(30, new ECB(15, 24), new ECB(25, 25)), new ECBlocks(30, new ECB(23, 15), new ECB(25, 16))), new Version(31, new Array(6, 30, 56, 82, 108, 134), new ECBlocks(30, new ECB(13, 115), new ECB(3, 116)), new ECBlocks(28, new ECB(2, 46), new ECB(29, 47)), new ECBlocks(30, new ECB(42, 24), new ECB(1, 25)), new ECBlocks(30, new ECB(23, 15), new ECB(28, 16))), new Version(32, new Array(6, 34, 60, 86, 112, 138), new ECBlocks(30, new ECB(17, 115)), new ECBlocks(28, new ECB(10, 46), new ECB(23, 47)), new ECBlocks(30, new ECB(10, 24), new ECB(35, 25)), new ECBlocks(30, new ECB(19, 15), new ECB(35, 16))), new Version(33, new Array(6, 30, 58, 86, 114, 142), new ECBlocks(30, new ECB(17, 115), new ECB(1, 116)), new ECBlocks(28, new ECB(14, 46), new ECB(21, 47)), new ECBlocks(30, new ECB(29, 24), new ECB(19, 25)), new ECBlocks(30, new ECB(11, 15), new ECB(46, 16))), new Version(34, new Array(6, 34, 62, 90, 118, 146), new ECBlocks(30, new ECB(13, 115), new ECB(6, 116)), new ECBlocks(28, new ECB(14, 46), new ECB(23, 47)), new ECBlocks(30, new ECB(44, 24), new ECB(7, 25)), new ECBlocks(30, new ECB(59, 16), new ECB(1, 17))), new Version(35, new Array(6, 30, 54, 78, 102, 126, 150), new ECBlocks(30, new ECB(12, 121), new ECB(7, 122)), new ECBlocks(28, new ECB(12, 47), new ECB(26, 48)), new ECBlocks(30, new ECB(39, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(22, 15), new ECB(41, 16))), new Version(36, new Array(6, 24, 50, 76, 102, 128, 154), new ECBlocks(30, new ECB(6, 121), new ECB(14, 122)), new ECBlocks(28, new ECB(6, 47), new ECB(34, 48)), new ECBlocks(30, new ECB(46, 24), new ECB(10, 25)), new ECBlocks(30, new ECB(2, 15), new ECB(64, 16))), new Version(37, new Array(6, 28, 54, 80, 106, 132, 158), new ECBlocks(30, new ECB(17, 122), new ECB(4, 123)), new ECBlocks(28, new ECB(29, 46), new ECB(14, 47)), new ECBlocks(30, new ECB(49, 24), new ECB(10, 25)), new ECBlocks(30, new ECB(24, 15), new ECB(46, 16))), new Version(38, new Array(6, 32, 58, 84, 110, 136, 162), new ECBlocks(30, new ECB(4, 122), new ECB(18, 123)), new ECBlocks(28, new ECB(13, 46), new ECB(32, 47)), new ECBlocks(30, new ECB(48, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(42, 15), new ECB(32, 16))), new Version(39, new Array(6, 26, 54, 82, 110, 138, 166), new ECBlocks(30, new ECB(20, 117), new ECB(4, 118)), new ECBlocks(28, new ECB(40, 47), new ECB(7, 48)), new ECBlocks(30, new ECB(43, 24), new ECB(22, 25)), new ECBlocks(30, new ECB(10, 15), new ECB(67, 16))), new Version(40, new Array(6, 30, 58, 86, 114, 142, 170), new ECBlocks(30, new ECB(19, 118), new ECB(6, 119)), new ECBlocks(28, new ECB(18, 47), new ECB(31, 48)), new ECBlock