UNPKG

label-studio

Version:

Data Labeling Tool that is backend agnostic and can be embedded into your applications

1,445 lines (1,411 loc) 257 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["jsQR"] = factory(); else root["jsQR"] = factory(); })(typeof self !== 'undefined' ? self : this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 3); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var BitMatrix = /** @class */ (function () { function BitMatrix(data, width) { this.width = width; this.height = data.length / width; this.data = data; } BitMatrix.createEmpty = function (width, height) { return new BitMatrix(new Uint8ClampedArray(width * height), width); }; BitMatrix.prototype.get = function (x, y) { if (x < 0 || x >= this.width || y < 0 || y >= this.height) { return false; } return !!this.data[y * this.width + x]; }; BitMatrix.prototype.set = function (x, y, v) { this.data[y * this.width + x] = v ? 1 : 0; }; BitMatrix.prototype.setRegion = function (left, top, width, height, v) { for (var y = top; y < top + height; y++) { for (var x = left; x < left + width; x++) { this.set(x, y, !!v); } } }; return BitMatrix; }()); exports.BitMatrix = BitMatrix; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var GenericGFPoly_1 = __webpack_require__(2); function addOrSubtractGF(a, b) { return a ^ b; // tslint:disable-line:no-bitwise } exports.addOrSubtractGF = addOrSubtractGF; var GenericGF = /** @class */ (function () { function GenericGF(primitive, size, genBase) { this.primitive = primitive; this.size = size; this.generatorBase = genBase; this.expTable = new Array(this.size); this.logTable = new Array(this.size); var x = 1; for (var i = 0; i < this.size; i++) { this.expTable[i] = x; x = x * 2; if (x >= this.size) { x = (x ^ this.primitive) & (this.size - 1); // tslint:disable-line:no-bitwise } } for (var i = 0; i < this.size - 1; i++) { this.logTable[this.expTable[i]] = i; } this.zero = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([0])); this.one = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([1])); } GenericGF.prototype.multiply = function (a, b) { if (a === 0 || b === 0) { return 0; } return this.expTable[(this.logTable[a] + this.logTable[b]) % (this.size - 1)]; }; GenericGF.prototype.inverse = function (a) { if (a === 0) { throw new Error("Can't invert 0"); } return this.expTable[this.size - this.logTable[a] - 1]; }; GenericGF.prototype.buildMonomial = function (degree, coefficient) { if (degree < 0) { throw new Error("Invalid monomial degree less than 0"); } if (coefficient === 0) { return this.zero; } var coefficients = new Uint8ClampedArray(degree + 1); coefficients[0] = coefficient; return new GenericGFPoly_1.default(this, coefficients); }; GenericGF.prototype.log = function (a) { if (a === 0) { throw new Error("Can't take log(0)"); } return this.logTable[a]; }; GenericGF.prototype.exp = function (a) { return this.expTable[a]; }; return GenericGF; }()); exports.default = GenericGF; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var GenericGF_1 = __webpack_require__(1); var GenericGFPoly = /** @class */ (function () { function GenericGFPoly(field, coefficients) { if (coefficients.length === 0) { throw new Error("No coefficients."); } this.field = field; var coefficientsLength = coefficients.length; if (coefficientsLength > 1 && coefficients[0] === 0) { // Leading term must be non-zero for anything except the constant polynomial "0" var firstNonZero = 1; while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) { firstNonZero++; } if (firstNonZero === coefficientsLength) { this.coefficients = field.zero.coefficients; } else { this.coefficients = new Uint8ClampedArray(coefficientsLength - firstNonZero); for (var i = 0; i < this.coefficients.length; i++) { this.coefficients[i] = coefficients[firstNonZero + i]; } } } else { this.coefficients = coefficients; } } GenericGFPoly.prototype.degree = function () { return this.coefficients.length - 1; }; GenericGFPoly.prototype.isZero = function () { return this.coefficients[0] === 0; }; GenericGFPoly.prototype.getCoefficient = function (degree) { return this.coefficients[this.coefficients.length - 1 - degree]; }; GenericGFPoly.prototype.addOrSubtract = function (other) { var _a; if (this.isZero()) { return other; } if (other.isZero()) { return this; } var smallerCoefficients = this.coefficients; var largerCoefficients = other.coefficients; if (smallerCoefficients.length > largerCoefficients.length) { _a = [largerCoefficients, smallerCoefficients], smallerCoefficients = _a[0], largerCoefficients = _a[1]; } var sumDiff = new Uint8ClampedArray(largerCoefficients.length); var lengthDiff = largerCoefficients.length - smallerCoefficients.length; for (var i = 0; i < lengthDiff; i++) { sumDiff[i] = largerCoefficients[i]; } for (var i = lengthDiff; i < largerCoefficients.length; i++) { sumDiff[i] = GenericGF_1.addOrSubtractGF(smallerCoefficients[i - lengthDiff], largerCoefficients[i]); } return new GenericGFPoly(this.field, sumDiff); }; GenericGFPoly.prototype.multiply = function (scalar) { if (scalar === 0) { return this.field.zero; } if (scalar === 1) { return this; } var size = this.coefficients.length; var product = new Uint8ClampedArray(size); for (var i = 0; i < size; i++) { product[i] = this.field.multiply(this.coefficients[i], scalar); } return new GenericGFPoly(this.field, product); }; GenericGFPoly.prototype.multiplyPoly = function (other) { if (this.isZero() || other.isZero()) { return this.field.zero; } var aCoefficients = this.coefficients; var aLength = aCoefficients.length; var bCoefficients = other.coefficients; var bLength = bCoefficients.length; var product = new Uint8ClampedArray(aLength + bLength - 1); for (var i = 0; i < aLength; i++) { var aCoeff = aCoefficients[i]; for (var j = 0; j < bLength; j++) { product[i + j] = GenericGF_1.addOrSubtractGF(product[i + j], this.field.multiply(aCoeff, bCoefficients[j])); } } return new GenericGFPoly(this.field, product); }; GenericGFPoly.prototype.multiplyByMonomial = function (degree, coefficient) { if (degree < 0) { throw new Error("Invalid degree less than 0"); } if (coefficient === 0) { return this.field.zero; } var size = this.coefficients.length; var product = new Uint8ClampedArray(size + degree); for (var i = 0; i < size; i++) { product[i] = this.field.multiply(this.coefficients[i], coefficient); } return new GenericGFPoly(this.field, product); }; GenericGFPoly.prototype.evaluateAt = function (a) { var result = 0; if (a === 0) { // Just return the x^0 coefficient return this.getCoefficient(0); } var size = this.coefficients.length; if (a === 1) { // Just the sum of the coefficients this.coefficients.forEach(function (coefficient) { result = GenericGF_1.addOrSubtractGF(result, coefficient); }); return result; } result = this.coefficients[0]; for (var i = 1; i < size; i++) { result = GenericGF_1.addOrSubtractGF(this.field.multiply(a, result), this.coefficients[i]); } return result; }; return GenericGFPoly; }()); exports.default = GenericGFPoly; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var binarizer_1 = __webpack_require__(4); var decoder_1 = __webpack_require__(5); var extractor_1 = __webpack_require__(11); var locator_1 = __webpack_require__(12); function scan(matrix) { var locations = locator_1.locate(matrix); if (!locations) { return null; } for (var _i = 0, locations_1 = locations; _i < locations_1.length; _i++) { var location_1 = locations_1[_i]; var extracted = extractor_1.extract(matrix, location_1); var decoded = decoder_1.decode(extracted.matrix); if (decoded) { return { binaryData: decoded.bytes, data: decoded.text, chunks: decoded.chunks, location: { topRightCorner: extracted.mappingFunction(location_1.dimension, 0), topLeftCorner: extracted.mappingFunction(0, 0), bottomRightCorner: extracted.mappingFunction(location_1.dimension, location_1.dimension), bottomLeftCorner: extracted.mappingFunction(0, location_1.dimension), topRightFinderPattern: location_1.topRight, topLeftFinderPattern: location_1.topLeft, bottomLeftFinderPattern: location_1.bottomLeft, bottomRightAlignmentPattern: location_1.alignmentPattern, }, }; } } return null; } var defaultOptions = { inversionAttempts: "attemptBoth", }; function jsQR(data, width, height, providedOptions) { if (providedOptions === void 0) { providedOptions = {}; } var options = defaultOptions; Object.keys(options || {}).forEach(function (opt) { options[opt] = providedOptions[opt] || options[opt]; }); var shouldInvert = options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst"; var tryInvertedFirst = options.inversionAttempts === "onlyInvert" || options.inversionAttempts === "invertFirst"; var _a = binarizer_1.binarize(data, width, height, shouldInvert), binarized = _a.binarized, inverted = _a.inverted; var result = scan(tryInvertedFirst ? inverted : binarized); if (!result && (options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst")) { result = scan(tryInvertedFirst ? binarized : inverted); } return result; } jsQR.default = jsQR; exports.default = jsQR; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var BitMatrix_1 = __webpack_require__(0); var REGION_SIZE = 8; var MIN_DYNAMIC_RANGE = 24; function numBetween(value, min, max) { return value < min ? min : value > max ? max : value; } // Like BitMatrix but accepts arbitry Uint8 values var Matrix = /** @class */ (function () { function Matrix(width, height) { this.width = width; this.data = new Uint8ClampedArray(width * height); } Matrix.prototype.get = function (x, y) { return this.data[y * this.width + x]; }; Matrix.prototype.set = function (x, y, value) { this.data[y * this.width + x] = value; }; return Matrix; }()); function binarize(data, width, height, returnInverted) { if (data.length !== width * height * 4) { throw new Error("Malformed data passed to binarizer."); } // Convert image to greyscale var greyscalePixels = new Matrix(width, height); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { var r = data[((y * width + x) * 4) + 0]; var g = data[((y * width + x) * 4) + 1]; var b = data[((y * width + x) * 4) + 2]; greyscalePixels.set(x, y, 0.2126 * r + 0.7152 * g + 0.0722 * b); } } var horizontalRegionCount = Math.ceil(width / REGION_SIZE); var verticalRegionCount = Math.ceil(height / REGION_SIZE); var blackPoints = new Matrix(horizontalRegionCount, verticalRegionCount); for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) { for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) { var sum = 0; var min = Infinity; var max = 0; for (var y = 0; y < REGION_SIZE; y++) { for (var x = 0; x < REGION_SIZE; x++) { var pixelLumosity = greyscalePixels.get(hortizontalRegion * REGION_SIZE + x, verticalRegion * REGION_SIZE + y); sum += pixelLumosity; min = Math.min(min, pixelLumosity); max = Math.max(max, pixelLumosity); } } var average = sum / (Math.pow(REGION_SIZE, 2)); if (max - min <= MIN_DYNAMIC_RANGE) { // If variation within the block is low, assume this is a block with only light or only // dark pixels. In that case we do not want to use the average, as it would divide this // low contrast area into black and white pixels, essentially creating data out of noise. // // Default the blackpoint for these blocks to be half the min - effectively white them out average = min / 2; if (verticalRegion > 0 && hortizontalRegion > 0) { // Correct the "white background" assumption for blocks that have neighbors by comparing // the pixels in this block to the previously calculated black points. This is based on // the fact that dark barcode symbology is always surrounded by some amount of light // background for which reasonable black point estimates were made. The bp estimated at // the boundaries is used for the interior. // The (min < bp) is arbitrary but works better than other heuristics that were tried. var averageNeighborBlackPoint = (blackPoints.get(hortizontalRegion, verticalRegion - 1) + (2 * blackPoints.get(hortizontalRegion - 1, verticalRegion)) + blackPoints.get(hortizontalRegion - 1, verticalRegion - 1)) / 4; if (min < averageNeighborBlackPoint) { average = averageNeighborBlackPoint; } } } blackPoints.set(hortizontalRegion, verticalRegion, average); } } var binarized = BitMatrix_1.BitMatrix.createEmpty(width, height); var inverted = null; if (returnInverted) { inverted = BitMatrix_1.BitMatrix.createEmpty(width, height); } for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) { for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) { var left = numBetween(hortizontalRegion, 2, horizontalRegionCount - 3); var top_1 = numBetween(verticalRegion, 2, verticalRegionCount - 3); var sum = 0; for (var xRegion = -2; xRegion <= 2; xRegion++) { for (var yRegion = -2; yRegion <= 2; yRegion++) { sum += blackPoints.get(left + xRegion, top_1 + yRegion); } } var threshold = sum / 25; for (var xRegion = 0; xRegion < REGION_SIZE; xRegion++) { for (var yRegion = 0; yRegion < REGION_SIZE; yRegion++) { var x = hortizontalRegion * REGION_SIZE + xRegion; var y = verticalRegion * REGION_SIZE + yRegion; var lum = greyscalePixels.get(x, y); binarized.set(x, y, lum <= threshold); if (returnInverted) { inverted.set(x, y, !(lum <= threshold)); } } } } } if (returnInverted) { return { binarized: binarized, inverted: inverted }; } return { binarized: binarized }; } exports.binarize = binarize; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var BitMatrix_1 = __webpack_require__(0); var decodeData_1 = __webpack_require__(6); var reedsolomon_1 = __webpack_require__(9); var version_1 = __webpack_require__(10); // tslint:disable:no-bitwise function numBitsDiffering(x, y) { var z = x ^ y; var bitCount = 0; while (z) { bitCount++; z &= z - 1; } return bitCount; } function pushBit(bit, byte) { return (byte << 1) | bit; } // tslint:enable:no-bitwise var FORMAT_INFO_TABLE = [ { bits: 0x5412, formatInfo: { errorCorrectionLevel: 1, dataMask: 0 } }, { bits: 0x5125, formatInfo: { errorCorrectionLevel: 1, dataMask: 1 } }, { bits: 0x5E7C, formatInfo: { errorCorrectionLevel: 1, dataMask: 2 } }, { bits: 0x5B4B, formatInfo: { errorCorrectionLevel: 1, dataMask: 3 } }, { bits: 0x45F9, formatInfo: { errorCorrectionLevel: 1, dataMask: 4 } }, { bits: 0x40CE, formatInfo: { errorCorrectionLevel: 1, dataMask: 5 } }, { bits: 0x4F97, formatInfo: { errorCorrectionLevel: 1, dataMask: 6 } }, { bits: 0x4AA0, formatInfo: { errorCorrectionLevel: 1, dataMask: 7 } }, { bits: 0x77C4, formatInfo: { errorCorrectionLevel: 0, dataMask: 0 } }, { bits: 0x72F3, formatInfo: { errorCorrectionLevel: 0, dataMask: 1 } }, { bits: 0x7DAA, formatInfo: { errorCorrectionLevel: 0, dataMask: 2 } }, { bits: 0x789D, formatInfo: { errorCorrectionLevel: 0, dataMask: 3 } }, { bits: 0x662F, formatInfo: { errorCorrectionLevel: 0, dataMask: 4 } }, { bits: 0x6318, formatInfo: { errorCorrectionLevel: 0, dataMask: 5 } }, { bits: 0x6C41, formatInfo: { errorCorrectionLevel: 0, dataMask: 6 } }, { bits: 0x6976, formatInfo: { errorCorrectionLevel: 0, dataMask: 7 } }, { bits: 0x1689, formatInfo: { errorCorrectionLevel: 3, dataMask: 0 } }, { bits: 0x13BE, formatInfo: { errorCorrectionLevel: 3, dataMask: 1 } }, { bits: 0x1CE7, formatInfo: { errorCorrectionLevel: 3, dataMask: 2 } }, { bits: 0x19D0, formatInfo: { errorCorrectionLevel: 3, dataMask: 3 } }, { bits: 0x0762, formatInfo: { errorCorrectionLevel: 3, dataMask: 4 } }, { bits: 0x0255, formatInfo: { errorCorrectionLevel: 3, dataMask: 5 } }, { bits: 0x0D0C, formatInfo: { errorCorrectionLevel: 3, dataMask: 6 } }, { bits: 0x083B, formatInfo: { errorCorrectionLevel: 3, dataMask: 7 } }, { bits: 0x355F, formatInfo: { errorCorrectionLevel: 2, dataMask: 0 } }, { bits: 0x3068, formatInfo: { errorCorrectionLevel: 2, dataMask: 1 } }, { bits: 0x3F31, formatInfo: { errorCorrectionLevel: 2, dataMask: 2 } }, { bits: 0x3A06, formatInfo: { errorCorrectionLevel: 2, dataMask: 3 } }, { bits: 0x24B4, formatInfo: { errorCorrectionLevel: 2, dataMask: 4 } }, { bits: 0x2183, formatInfo: { errorCorrectionLevel: 2, dataMask: 5 } }, { bits: 0x2EDA, formatInfo: { errorCorrectionLevel: 2, dataMask: 6 } }, { bits: 0x2BED, formatInfo: { errorCorrectionLevel: 2, dataMask: 7 } }, ]; var DATA_MASKS = [ function (p) { return ((p.y + p.x) % 2) === 0; }, function (p) { return (p.y % 2) === 0; }, function (p) { return p.x % 3 === 0; }, function (p) { return (p.y + p.x) % 3 === 0; }, function (p) { return (Math.floor(p.y / 2) + Math.floor(p.x / 3)) % 2 === 0; }, function (p) { return ((p.x * p.y) % 2) + ((p.x * p.y) % 3) === 0; }, function (p) { return ((((p.y * p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; }, function (p) { return ((((p.y + p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; }, ]; function buildFunctionPatternMask(version) { var dimension = 17 + 4 * version.versionNumber; var matrix = BitMatrix_1.BitMatrix.createEmpty(dimension, dimension); matrix.setRegion(0, 0, 9, 9, true); // Top left finder pattern + separator + format matrix.setRegion(dimension - 8, 0, 8, 9, true); // Top right finder pattern + separator + format matrix.setRegion(0, dimension - 8, 9, 8, true); // Bottom left finder pattern + separator + format // Alignment patterns for (var _i = 0, _a = version.alignmentPatternCenters; _i < _a.length; _i++) { var x = _a[_i]; for (var _b = 0, _c = version.alignmentPatternCenters; _b < _c.length; _b++) { var y = _c[_b]; if (!(x === 6 && y === 6 || x === 6 && y === dimension - 7 || x === dimension - 7 && y === 6)) { matrix.setRegion(x - 2, y - 2, 5, 5, true); } } } matrix.setRegion(6, 9, 1, dimension - 17, true); // Vertical timing pattern matrix.setRegion(9, 6, dimension - 17, 1, true); // Horizontal timing pattern if (version.versionNumber > 6) { matrix.setRegion(dimension - 11, 0, 3, 6, true); // Version info, top right matrix.setRegion(0, dimension - 11, 6, 3, true); // Version info, bottom left } return matrix; } function readCodewords(matrix, version, formatInfo) { var dataMask = DATA_MASKS[formatInfo.dataMask]; var dimension = matrix.height; var functionPatternMask = buildFunctionPatternMask(version); var codewords = []; var currentByte = 0; var bitsRead = 0; // Read columns in pairs, from right to left var readingUp = true; for (var columnIndex = dimension - 1; columnIndex > 0; columnIndex -= 2) { if (columnIndex === 6) { // Skip whole column with vertical alignment pattern; columnIndex--; } for (var i = 0; i < dimension; i++) { var y = readingUp ? dimension - 1 - i : i; for (var columnOffset = 0; columnOffset < 2; columnOffset++) { var x = columnIndex - columnOffset; if (!functionPatternMask.get(x, y)) { bitsRead++; var bit = matrix.get(x, y); if (dataMask({ y: y, x: x })) { bit = !bit; } currentByte = pushBit(bit, currentByte); if (bitsRead === 8) { // Whole bytes codewords.push(currentByte); bitsRead = 0; currentByte = 0; } } } } readingUp = !readingUp; } return codewords; } function readVersion(matrix) { var dimension = matrix.height; var provisionalVersion = Math.floor((dimension - 17) / 4); if (provisionalVersion <= 6) { // 6 and under dont have version info in the QR code return version_1.VERSIONS[provisionalVersion - 1]; } var topRightVersionBits = 0; for (var y = 5; y >= 0; y--) { for (var x = dimension - 9; x >= dimension - 11; x--) { topRightVersionBits = pushBit(matrix.get(x, y), topRightVersionBits); } } var bottomLeftVersionBits = 0; for (var x = 5; x >= 0; x--) { for (var y = dimension - 9; y >= dimension - 11; y--) { bottomLeftVersionBits = pushBit(matrix.get(x, y), bottomLeftVersionBits); } } var bestDifference = Infinity; var bestVersion; for (var _i = 0, VERSIONS_1 = version_1.VERSIONS; _i < VERSIONS_1.length; _i++) { var version = VERSIONS_1[_i]; if (version.infoBits === topRightVersionBits || version.infoBits === bottomLeftVersionBits) { return version; } var difference = numBitsDiffering(topRightVersionBits, version.infoBits); if (difference < bestDifference) { bestVersion = version; bestDifference = difference; } difference = numBitsDiffering(bottomLeftVersionBits, version.infoBits); if (difference < bestDifference) { bestVersion = version; bestDifference = difference; } } // We can tolerate up to 3 bits of error since no two version info codewords will // differ in less than 8 bits. if (bestDifference <= 3) { return bestVersion; } } function readFormatInformation(matrix) { var topLeftFormatInfoBits = 0; for (var x = 0; x <= 8; x++) { if (x !== 6) { // Skip timing pattern bit topLeftFormatInfoBits = pushBit(matrix.get(x, 8), topLeftFormatInfoBits); } } for (var y = 7; y >= 0; y--) { if (y !== 6) { // Skip timing pattern bit topLeftFormatInfoBits = pushBit(matrix.get(8, y), topLeftFormatInfoBits); } } var dimension = matrix.height; var topRightBottomRightFormatInfoBits = 0; for (var y = dimension - 1; y >= dimension - 7; y--) { // bottom left topRightBottomRightFormatInfoBits = pushBit(matrix.get(8, y), topRightBottomRightFormatInfoBits); } for (var x = dimension - 8; x < dimension; x++) { // top right topRightBottomRightFormatInfoBits = pushBit(matrix.get(x, 8), topRightBottomRightFormatInfoBits); } var bestDifference = Infinity; var bestFormatInfo = null; for (var _i = 0, FORMAT_INFO_TABLE_1 = FORMAT_INFO_TABLE; _i < FORMAT_INFO_TABLE_1.length; _i++) { var _a = FORMAT_INFO_TABLE_1[_i], bits = _a.bits, formatInfo = _a.formatInfo; if (bits === topLeftFormatInfoBits || bits === topRightBottomRightFormatInfoBits) { return formatInfo; } var difference = numBitsDiffering(topLeftFormatInfoBits, bits); if (difference < bestDifference) { bestFormatInfo = formatInfo; bestDifference = difference; } if (topLeftFormatInfoBits !== topRightBottomRightFormatInfoBits) { // also try the other option difference = numBitsDiffering(topRightBottomRightFormatInfoBits, bits); if (difference < bestDifference) { bestFormatInfo = formatInfo; bestDifference = difference; } } } // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match if (bestDifference <= 3) { return bestFormatInfo; } return null; } function getDataBlocks(codewords, version, ecLevel) { var ecInfo = version.errorCorrectionLevels[ecLevel]; var dataBlocks = []; var totalCodewords = 0; ecInfo.ecBlocks.forEach(function (block) { for (var i = 0; i < block.numBlocks; i++) { dataBlocks.push({ numDataCodewords: block.dataCodewordsPerBlock, codewords: [] }); totalCodewords += block.dataCodewordsPerBlock + ecInfo.ecCodewordsPerBlock; } }); // In some cases the QR code will be malformed enough that we pull off more or less than we should. // If we pull off less there's nothing we can do. // If we pull off more we can safely truncate if (codewords.length < totalCodewords) { return null; } codewords = codewords.slice(0, totalCodewords); var shortBlockSize = ecInfo.ecBlocks[0].dataCodewordsPerBlock; // Pull codewords to fill the blocks up to the minimum size for (var i = 0; i < shortBlockSize; i++) { for (var _i = 0, dataBlocks_1 = dataBlocks; _i < dataBlocks_1.length; _i++) { var dataBlock = dataBlocks_1[_i]; dataBlock.codewords.push(codewords.shift()); } } // If there are any large blocks, pull codewords to fill the last element of those if (ecInfo.ecBlocks.length > 1) { var smallBlockCount = ecInfo.ecBlocks[0].numBlocks; var largeBlockCount = ecInfo.ecBlocks[1].numBlocks; for (var i = 0; i < largeBlockCount; i++) { dataBlocks[smallBlockCount + i].codewords.push(codewords.shift()); } } // Add the rest of the codewords to the blocks. These are the error correction codewords. while (codewords.length > 0) { for (var _a = 0, dataBlocks_2 = dataBlocks; _a < dataBlocks_2.length; _a++) { var dataBlock = dataBlocks_2[_a]; dataBlock.codewords.push(codewords.shift()); } } return dataBlocks; } function decodeMatrix(matrix) { var version = readVersion(matrix); if (!version) { return null; } var formatInfo = readFormatInformation(matrix); if (!formatInfo) { return null; } var codewords = readCodewords(matrix, version, formatInfo); var dataBlocks = getDataBlocks(codewords, version, formatInfo.errorCorrectionLevel); if (!dataBlocks) { return null; } // Count total number of data bytes var totalBytes = dataBlocks.reduce(function (a, b) { return a + b.numDataCodewords; }, 0); var resultBytes = new Uint8ClampedArray(totalBytes); var resultIndex = 0; for (var _i = 0, dataBlocks_3 = dataBlocks; _i < dataBlocks_3.length; _i++) { var dataBlock = dataBlocks_3[_i]; var correctedBytes = reedsolomon_1.decode(dataBlock.codewords, dataBlock.codewords.length - dataBlock.numDataCodewords); if (!correctedBytes) { return null; } for (var i = 0; i < dataBlock.numDataCodewords; i++) { resultBytes[resultIndex++] = correctedBytes[i]; } } try { return decodeData_1.decode(resultBytes, version.versionNumber); } catch (_a) { return null; } } function decode(matrix) { if (matrix == null) { return null; } var result = decodeMatrix(matrix); if (result) { return result; } // Decoding didn't work, try mirroring the QR across the topLeft -> bottomRight line. for (var x = 0; x < matrix.width; x++) { for (var y = x + 1; y < matrix.height; y++) { if (matrix.get(x, y) !== matrix.get(y, x)) { matrix.set(x, y, !matrix.get(x, y)); matrix.set(y, x, !matrix.get(y, x)); } } } return decodeMatrix(matrix); } exports.decode = decode; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // tslint:disable:no-bitwise var BitStream_1 = __webpack_require__(7); var shiftJISTable_1 = __webpack_require__(8); var Mode; (function (Mode) { Mode["Numeric"] = "numeric"; Mode["Alphanumeric"] = "alphanumeric"; Mode["Byte"] = "byte"; Mode["Kanji"] = "kanji"; Mode["ECI"] = "eci"; })(Mode = exports.Mode || (exports.Mode = {})); var ModeByte; (function (ModeByte) { ModeByte[ModeByte["Terminator"] = 0] = "Terminator"; ModeByte[ModeByte["Numeric"] = 1] = "Numeric"; ModeByte[ModeByte["Alphanumeric"] = 2] = "Alphanumeric"; ModeByte[ModeByte["Byte"] = 4] = "Byte"; ModeByte[ModeByte["Kanji"] = 8] = "Kanji"; ModeByte[ModeByte["ECI"] = 7] = "ECI"; // StructuredAppend = 0x3, // FNC1FirstPosition = 0x5, // FNC1SecondPosition = 0x9, })(ModeByte || (ModeByte = {})); function decodeNumeric(stream, size) { var bytes = []; var text = ""; var characterCountSize = [10, 12, 14][size]; var length = stream.readBits(characterCountSize); // Read digits in groups of 3 while (length >= 3) { var num = stream.readBits(10); if (num >= 1000) { throw new Error("Invalid numeric value above 999"); } var a = Math.floor(num / 100); var b = Math.floor(num / 10) % 10; var c = num % 10; bytes.push(48 + a, 48 + b, 48 + c); text += a.toString() + b.toString() + c.toString(); length -= 3; } // If the number of digits aren't a multiple of 3, the remaining digits are special cased. if (length === 2) { var num = stream.readBits(7); if (num >= 100) { throw new Error("Invalid numeric value above 99"); } var a = Math.floor(num / 10); var b = num % 10; bytes.push(48 + a, 48 + b); text += a.toString() + b.toString(); } else if (length === 1) { var num = stream.readBits(4); if (num >= 10) { throw new Error("Invalid numeric value above 9"); } bytes.push(48 + num); text += num.toString(); } return { bytes: bytes, text: text }; } var AlphanumericCharacterCodes = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " ", "$", "%", "*", "+", "-", ".", "/", ":", ]; function decodeAlphanumeric(stream, size) { var bytes = []; var text = ""; var characterCountSize = [9, 11, 13][size]; var length = stream.readBits(characterCountSize); while (length >= 2) { var v = stream.readBits(11); var a = Math.floor(v / 45); var b = v % 45; bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0), AlphanumericCharacterCodes[b].charCodeAt(0)); text += AlphanumericCharacterCodes[a] + AlphanumericCharacterCodes[b]; length -= 2; } if (length === 1) { var a = stream.readBits(6); bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0)); text += AlphanumericCharacterCodes[a]; } return { bytes: bytes, text: text }; } function decodeByte(stream, size) { var bytes = []; var text = ""; var characterCountSize = [8, 16, 16][size]; var length = stream.readBits(characterCountSize); for (var i = 0; i < length; i++) { var b = stream.readBits(8); bytes.push(b); } try { text += decodeURIComponent(bytes.map(function (b) { return "%" + ("0" + b.toString(16)).substr(-2); }).join("")); } catch (_a) { // failed to decode } return { bytes: bytes, text: text }; } function decodeKanji(stream, size) { var bytes = []; var text = ""; var characterCountSize = [8, 10, 12][size]; var length = stream.readBits(characterCountSize); for (var i = 0; i < length; i++) { var k = stream.readBits(13); var c = (Math.floor(k / 0xC0) << 8) | (k % 0xC0); if (c < 0x1F00) { c += 0x8140; } else { c += 0xC140; } bytes.push(c >> 8, c & 0xFF); text += String.fromCharCode(shiftJISTable_1.shiftJISTable[c]); } return { bytes: bytes, text: text }; } function decode(data, version) { var _a, _b, _c, _d; var stream = new BitStream_1.BitStream(data); // There are 3 'sizes' based on the version. 1-9 is small (0), 10-26 is medium (1) and 27-40 is large (2). var size = version <= 9 ? 0 : version <= 26 ? 1 : 2; var result = { text: "", bytes: [], chunks: [], }; while (stream.available() >= 4) { var mode = stream.readBits(4); if (mode === ModeByte.Terminator) { return result; } else if (mode === ModeByte.ECI) { if (stream.readBits(1) === 0) { result.chunks.push({ type: Mode.ECI, assignmentNumber: stream.readBits(7), }); } else if (stream.readBits(1) === 0) { result.chunks.push({ type: Mode.ECI, assignmentNumber: stream.readBits(14), }); } else if (stream.readBits(1) === 0) { result.chunks.push({ type: Mode.ECI, assignmentNumber: stream.readBits(21), }); } else { // ECI data seems corrupted result.chunks.push({ type: Mode.ECI, assignmentNumber: -1, }); } } else if (mode === ModeByte.Numeric) { var numericResult = decodeNumeric(stream, size); result.text += numericResult.text; (_a = result.bytes).push.apply(_a, numericResult.bytes); result.chunks.push({ type: Mode.Numeric, text: numericResult.text, }); } else if (mode === ModeByte.Alphanumeric) { var alphanumericResult = decodeAlphanumeric(stream, size); result.text += alphanumericResult.text; (_b = result.bytes).push.apply(_b, alphanumericResult.bytes); result.chunks.push({ type: Mode.Alphanumeric, text: alphanumericResult.text, }); } else if (mode === ModeByte.Byte) { var byteResult = decodeByte(stream, size); result.text += byteResult.text; (_c = result.bytes).push.apply(_c, byteResult.bytes); result.chunks.push({ type: Mode.Byte, bytes: byteResult.bytes, text: byteResult.text, }); } else if (mode === ModeByte.Kanji) { var kanjiResult = decodeKanji(stream, size); result.text += kanjiResult.text; (_d = result.bytes).push.apply(_d, kanjiResult.bytes); result.chunks.push({ type: Mode.Kanji, bytes: kanjiResult.bytes, text: kanjiResult.text, }); } } // If there is no data left, or the remaining bits are all 0, then that counts as a termination marker if (stream.available() === 0 || stream.readBits(stream.available()) === 0) { return result; } } exports.decode = decode; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // tslint:disable:no-bitwise Object.defineProperty(exports, "__esModule", { value: true }); var BitStream = /** @class */ (function () { function BitStream(bytes) { this.byteOffset = 0; this.bitOffset = 0; this.bytes = bytes; } BitStream.prototype.readBits = function (numBits) { if (numBits < 1 || numBits > 32 || numBits > this.available()) { throw new Error("Cannot read " + numBits.toString() + " bits"); } var result = 0; // First, read remainder from current byte if (this.bitOffset > 0) { var bitsLeft = 8 - this.bitOffset; var toRead = numBits < bitsLeft ? numBits : bitsLeft; var bitsToNotRead = bitsLeft - toRead; var mask = (0xFF >> (8 - toRead)) << bitsToNotRead; result = (this.bytes[this.byteOffset] & mask) >> bitsToNotRead; numBits -= toRead; this.bitOffset += toRead; if (this.bitOffset === 8) { this.bitOffset = 0; this.byteOffset++; } } // Next read whole bytes if (numBits > 0) { while (numBits >= 8) { result = (result << 8) | (this.bytes[this.byteOffset] & 0xFF); this.byteOffset++; numBits -= 8; } // Finally read a partial byte if (numBits > 0) { var bitsToNotRead = 8 - numBits; var mask = (0xFF >> bitsToNotRead) << bitsToNotRead; result = (result << numBits) | ((this.bytes[this.byteOffset] & mask) >> bitsToNotRead); this.bitOffset += numBits; } } return result; }; BitStream.prototype.available = function () { return 8 * (this.bytes.length - this.byteOffset) - this.bitOffset; }; return BitStream; }()); exports.BitStream = BitStream; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.shiftJISTable = { 0x20: 0x0020, 0x21: 0x0021, 0x22: 0x0022, 0x23: 0x0023, 0x24: 0x0024, 0x25: 0x0025, 0x26: 0x0026, 0x27: 0x0027, 0x28: 0x0028, 0x29: 0x0029, 0x2A: 0x002A, 0x2B: 0x002B, 0x2C: 0x002C, 0x2D: 0x002D, 0x2E: 0x002E, 0x2F: 0x002F, 0x30: 0x0030, 0x31: 0x0031, 0x32: 0x0032, 0x33: 0x0033, 0x34: 0x0034, 0x35: 0x0035, 0x36: 0x0036, 0x37: 0x0037, 0x38: 0x0038, 0x39: 0x0039, 0x3A: 0x003A, 0x3B: 0x003B, 0x3C: 0x003C, 0x3D: 0x003D, 0x3E: 0x003E, 0x3F: 0x003F, 0x40: 0x0040, 0x41: 0x0041, 0x42: 0x0042, 0x43: 0x0043, 0x44: 0x0044, 0x45: 0x0045, 0x46: 0x0046, 0x47: 0x0047, 0x48: 0x0048, 0x49: 0x0049, 0x4A: 0x004A, 0x4B: 0x004B, 0x4C: 0x004C, 0x4D: 0x004D, 0x4E: 0x004E, 0x4F: 0x004F, 0x50: 0x0050, 0x51: 0x0051, 0x52: 0x0052, 0x53: 0x0053, 0x54: 0x0054, 0x55: 0x0055, 0x56: 0x0056, 0x57: 0x0057, 0x58: 0x0058, 0x59: 0x0059, 0x5A: 0x005A, 0x5B: 0x005B, 0x5C: 0x00A5, 0x5D: 0x005D, 0x5E: 0x005E, 0x5F: 0x005F, 0x60: 0x0060, 0x61: 0x0061, 0x62: 0x0062, 0x63: 0x0063, 0x64: 0x0064, 0x65: 0x0065, 0x66: 0x0066, 0x67: 0x0067, 0x68: 0x0068, 0x69: 0x0069, 0x6A: 0x006A, 0x6B: 0x006B, 0x6C: 0x006C, 0x6D: 0x006D, 0x6E: 0x006E, 0x6F: 0x006F, 0x70: 0x0070, 0x71: 0x0071, 0x72: 0x0072, 0x73: 0x0073, 0x74: 0x0074, 0x75: 0x0075, 0x76: 0x0076, 0x77: 0x0077, 0x78: 0x0078, 0x79: 0x0079, 0x7A: 0x007A, 0x7B: 0x007B, 0x7C: 0x007C, 0x7D: 0x007D, 0x7E: 0x203E, 0x8140: 0x3000, 0x8141: 0x3001, 0x8142: 0x3002, 0x8143: 0xFF0C, 0x8144: 0xFF0E, 0x8145: 0x30FB, 0x8146: 0xFF1A, 0x8147: 0xFF1B, 0x8148: 0xFF1F, 0x8149: 0xFF01, 0x814A: 0x309B, 0x814B: 0x309C, 0x814C: 0x00B4, 0x814D: 0xFF40, 0x814E: 0x00A8, 0x814F: 0xFF3E, 0x8150: 0xFFE3, 0x8151: 0xFF3F, 0x8152: 0x30FD, 0x8153: 0x30FE, 0x8154: 0x309D, 0x8155: 0x309E, 0x8156: 0x3003, 0x8157: 0x4EDD, 0x8158: 0x3005, 0x8159: 0x3006, 0x815A: 0x3007, 0x815B: 0x30FC, 0x815C: 0x2015, 0x815D: 0x2010, 0x815E: 0xFF0F, 0x815F: 0x005C, 0x8160: 0x301C, 0x8161: 0x2016, 0x8162: 0xFF5C, 0x8163: 0x2026, 0x8164: 0x2025, 0x8165: 0x2018, 0x8166: 0x2019, 0x8167: 0x201C, 0x8168: 0x201D, 0x8169: 0xFF08, 0x816A: 0xFF09, 0x816B: 0x3014, 0x816C: 0x3015, 0x816D: 0xFF3B, 0x816E: 0xFF3D, 0x816F: 0xFF5B, 0x8170: 0xFF5D, 0x8171: 0x3008, 0x8172: 0x3009, 0x8173: 0x300A, 0x8174: 0x300B, 0x8175: 0x300C, 0x8176: 0x300D, 0x8177: 0x300E, 0x8178: 0x300F, 0x8179: 0x3010, 0x817A: 0x3011, 0x817B: 0xFF0B, 0x817C: 0x2212, 0x817D: 0x00B1, 0x817E: 0x00D7, 0x8180: 0x00F7, 0x8181: 0xFF1D, 0x8182: 0x2260, 0x8183: 0xFF1C, 0x8184: 0xFF1E, 0x8185: 0x2266, 0x8186: 0x2267, 0x8187: 0x221E, 0x8188: 0x2234, 0x8189: 0x2642, 0x818A: 0x2640, 0x818B: 0x00B0, 0x818C: 0x2032, 0x818D: 0x2033, 0x818E: 0x2103, 0x818F: 0xFFE5, 0x8190: 0xFF04, 0x8191: 0x00A2, 0x8192: 0x00A3, 0x8193: 0xFF05, 0x8194: 0xFF03, 0x8195: 0xFF06, 0x8196: 0xFF0A, 0x8197: 0xFF20, 0x8198: 0x00A7, 0x8199: 0x2606, 0x819A: 0x2605, 0x819B: 0x25CB, 0x819C: 0x25CF, 0x819D: 0x25CE, 0x819E: 0x25C7, 0x819F: 0x25C6, 0x81A0: 0x25A1, 0x81A1: 0x25A0, 0x81A2: 0x25B3, 0x81A3: 0x25B2, 0x81A4: 0x25BD, 0x81A5: 0x25BC, 0x81A6: 0x203B, 0x81A7: 0x3012, 0x81A8: 0x2192, 0x81A9: 0x2190, 0x81AA: 0x2191, 0x81AB: 0x2193, 0x81AC: 0x3013, 0x81B8: 0x2208, 0x81B9: 0x220B, 0x81BA: 0x2286, 0x81BB: 0x2287, 0x81BC: 0x2282, 0x81BD: 0x2283, 0x81BE: 0x222A, 0x81BF: 0x2229, 0x81C8: 0x2227, 0x81C9: 0x2228, 0x81CA: 0x00AC, 0x81CB: 0x21D2, 0x81CC: 0x21D4, 0x81CD: 0x2200, 0x81CE: 0x2203, 0x81DA: 0x2220, 0x81DB: 0x22A5, 0x81DC: 0x2312, 0x81DD: 0x2202, 0x81DE: 0x2207, 0x81DF: 0x2261, 0x81E0: 0x2252, 0x81E1: 0x226A, 0x81E2: 0x226B, 0x81E3: 0x221A, 0x81E4: 0x223D, 0x81E5: 0x221D, 0x81E6: 0x2235, 0x81E7: 0x222B, 0x81E8: 0x222C, 0x81F0: 0x212B, 0x81F1: 0x2030, 0x81F2: 0x266F, 0x81F3: 0x266D, 0x81F4: 0x266A, 0x81F5: 0x2020, 0x81F6: 0x2021, 0x81F7: 0x00B6, 0x81FC: 0x25EF, 0x824F: 0xFF10, 0x8250: 0xFF11, 0x8251: 0xFF12, 0x8252: 0xFF13, 0x8253: 0xFF14, 0x8254: 0xFF15, 0x8255: 0xFF16, 0x8256: 0xFF17, 0x8257: 0xFF18, 0x8258: 0xFF19, 0x8260: 0xFF21, 0x8261: 0xFF22, 0x8262: 0xFF23, 0x8263: 0xFF24, 0x8264: 0xFF25, 0x8265: 0xFF26, 0x8266: 0xFF27, 0x8267: 0xFF28, 0x8268: 0xFF29, 0x8269: 0xFF2A, 0x826A: 0xFF2B, 0x826B: 0xFF2C, 0x826C: 0xFF2D, 0x826D: 0xFF2E, 0x826E: 0xFF2F, 0x826F: 0xFF30, 0x8270: 0xFF31, 0x8271: 0xFF32, 0x8272: 0xFF33, 0x8273: 0xFF34, 0x8274: 0xFF35, 0x8275: 0xFF36, 0x8276: 0xFF37, 0x8277: 0xFF38, 0x8278: 0xFF39, 0x8279: 0xFF3A, 0x8281: 0xFF41, 0x8282: 0xFF42, 0x8283: 0xFF43, 0x8284: 0xFF44, 0x8285: 0xFF45, 0x8286: 0xFF46, 0x8287: 0xFF47, 0x8288: 0xFF48, 0x8289: 0xFF49, 0x828A: 0xFF4A, 0x828B: 0xFF4B, 0x828C: 0xFF4C, 0x828D: 0xFF4D, 0x828E: 0xFF4E, 0x828F: 0xFF4F, 0x8290: 0xFF50, 0x8291: 0xFF51, 0x8292: 0xFF52, 0x8293: 0xFF53, 0x8294: 0xFF54, 0x8295: 0xFF55, 0x8296: 0xFF56, 0x8297: 0xFF57, 0x8298: 0xFF58, 0x8299: 0xFF59, 0x829A: 0xFF5A, 0x829F: 0x3041, 0x82A0: 0x3042, 0x82A1: 0x3043, 0x82A2: 0x3044, 0x82A3: 0x3045, 0x82A4: 0x3046, 0x82A5: 0x3047, 0x82A6: 0x3048, 0x82A7: 0x3049, 0x82A8: 0x304A, 0x82A9: 0x304B, 0x82AA: 0x304C, 0x82AB: 0x304D, 0x82AC: 0x304E, 0x82AD: 0x304F, 0x82AE: 0x3050, 0x82AF: 0x3051, 0x82B0: 0x3052, 0x82B1: 0x3053, 0x82B2: 0x3054, 0x82B3: 0x3055, 0x82B4: 0x3056, 0x82B5: 0x3057, 0x82B6: 0x3058, 0x82B7: 0x3059, 0x82B8: 0x305A, 0x82B9: 0x305B, 0x82BA: 0x305C, 0x82BB: 0x305D, 0x82BC: 0x305E, 0x82BD: 0x305F, 0x82BE: 0x3060, 0x82BF: 0x3061, 0x82C0: 0x3062, 0x82C1: 0x3063, 0x82C2: 0x3064, 0x82C3: 0x30