PageSourceSearch

https://store.grupobscit.com/web/static/lib/zxing-library/zxing-library.js

js grupobscit.com collected 2026-09-25 14:51:21 UTC 1,219,187 bytes, 27,951 lines download raw bytes

vendor: 10,116 bytes, lines 1-284
1(function (global, factory) {
2  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3  typeof define === 'function' && define.amd ? define(['exports'], factory) :
4  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ZXing = {}));
5})(this, (function (exports) { 'use strict';
6
7  function fixProto(target, prototype) {
8    var setPrototypeOf = Object.setPrototypeOf;
9    setPrototypeOf ? setPrototypeOf(target, prototype) : target.__proto__ = prototype;
10  }
11  function fixStack(target, fn) {
12    if (fn === void 0) {
13      fn = target.constructor;
14    }
15
16    var captureStackTrace = Error.captureStackTrace;
17    captureStackTrace && captureStackTrace(target, fn);
18  }
19
20  var __extends = function () {
21    var _extendStatics = function extendStatics(d, b) {
22      _extendStatics = Object.setPrototypeOf || {
23        __proto__: []
24      } instanceof Array && function (d, b) {
25        d.__proto__ = b;
26      } || function (d, b) {
27        for (var p in b) {
28          if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
29        }
30      };
31
32      return _extendStatics(d, b);
33    };
34
35    return function (d, b) {
36      if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
37
38      _extendStatics(d, b);
39
40      function __() {
41        this.constructor = d;
42      }
43
44      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
45    };
46  }();
47
48  var CustomError = function (_super) {
49    __extends(CustomError, _super);
50
51    function CustomError(message, options) {
52      var _newTarget = this.constructor;
53
54      var _this = _super.call(this, message, options) || this;
55
56      Object.defineProperty(_this, 'name', {
57        value: _newTarget.name,
58        enumerable: false,
59        configurable: true
60      });
61      fixProto(_this, _newTarget.prototype);
62      fixStack(_this);
63      return _this;
64    }
65
66    return CustomError;
67  }(Error);
68
69  /**
70   * Custom Error class of type Exception.
71   */
72  class Exception extends CustomError {
73      /**
74       * Allows Exception to be constructed directly
75       * with some message and prototype definition.
76       */
77      constructor(message = undefined) {
78          super(message);
79          this.message = message;
80      }
81      getKind() {
82          const ex = this.constructor;
83          return ex.kind;
84      }
85  }
86  /**
87   * It's typed as string so it can be extended and overriden.
88   */
89  Exception.kind = 'Exception';
90
91  /**
92   * Custom Error class of type Exception.
93   */
94  class ArgumentException extends Exception {
95  }
96  ArgumentException.kind = 'ArgumentException';
97
98  /**
99   * Custom Error class of type Exception.
100   */
101  class IllegalArgumentException extends Exception {
102  }
103  IllegalArgumentException.kind = 'IllegalArgumentException';
104
105  /*
106   * Copyright 2009 ZXing authors
107   *
108   * Licensed under the Apache License, Version 2.0 (the "License");
109   * you may not use this file except in compliance with the License.
110   * You may obtain a copy of the License at
111   *
112   *      http://www.apache.org/licenses/LICENSE-2.0
113   *
114   * Unless required by applicable law or agreed to in writing, software
115   * distributed under the License is distributed on an "AS IS" BASIS,
116   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
117   * See the License for the specific language governing permissions and
118   * limitations under the License.
119   */
120  class BinaryBitmap {
121      constructor(binarizer) {
122          this.binarizer = binarizer;
123          if (binarizer === null) {
124              throw new IllegalArgumentException('Binarizer must be non-null.');
125          }
126      }
127      /**
128       * @return The width of the bitmap.
129       */
130      getWidth() {
131          return this.binarizer.getWidth();
132      }
133      /**
134       * @return The height of the bitmap.
135       */
136      getHeight() {
137          return this.binarizer.getHeight();
138      }
139      /**
140       * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
141       * cached data. Callers should assume this method is expensive and call it as seldom as possible.
142       * This method is intended for decoding 1D barcodes and may choose to apply sharpening.
143       *
144       * @param y The row to fetch, which must be in [0, bitmap height)
145       * @param row An optional preallocated array. If null or too small, it will be ignored.
146       *            If used, the Binarizer will call BitArray.clear(). Always use the returned object.
147       * @return The array of bits for this row (true means black).
148       * @throws NotFoundException if row can't be binarized
149       */
150      getBlackRow(y /*int*/, row) {
151          return this.binarizer.getBlackRow(y, row);
152      }
153      /**
154       * Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive
155       * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
156       * may not apply sharpening. Therefore, a row from this matrix may not be identical to one
157       * fetched using getBlackRow(), so don't mix and match between them.
158       *
159       * @return The 2D array of bits for the image (true means black).
160       * @throws NotFoundException if image can't be binarized to make a matrix
161       */
162      getBlackMatrix() {
163          // The matrix is created on demand the first time it is requested, then cached. There are two
164          // reasons for this:
165          // 1. This work will never be done if the caller only installs 1D Reader objects, or if a
166          //    1D Reader finds a barcode before the 2D Readers run.
167          // 2. This work will only be done once even if the caller installs multiple 2D Readers.
168          if (this.matrix === null || this.matrix === undefined) {
169              this.matrix = this.binarizer.getBlackMatrix();
170          }
171          return this.matrix;
172      }
173      /**
174       * @return Whether this bitmap can be cropped.
175       */
176      isCropSupported() {
177          return this.binarizer.getLuminanceSource().isCropSupported();
178      }
179      /**
180       * Returns a new object with cropped image data. Implementations may keep a reference to the
181       * original data rather than a copy. Only callable if isCropSupported() is true.
182       *
183       * @param left The left coordinate, which must be in [0,getWidth())
184       * @param top The top coordinate, which must be in [0,getHeight())
185       * @param width The width of the rectangle to crop.
186       * @param height The height of the rectangle to crop.
187       * @return A cropped version of this object.
188       */
189      crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
190          const newSource = this.binarizer.getLuminanceSource().crop(left, top, width, height);
191          return new BinaryBitmap(this.binarizer.createBinarizer(newSource));
192      }
193      /**
194       * @return Whether this bitmap supports counter-clockwise rotation.
195       */
196      isRotateSupported() {
197          return this.binarizer.getLuminanceSource().isRotateSupported();
198      }
199      /**
200       * Returns a new object with rotated image data by 90 degrees counterclockwise.
201       * Only callable if {@link #isRotateSupported()} is true.
202       *
203       * @return A rotated version of this object.
204       */
205      rotateCounterClockwise() {
206          const newSource = this.binarizer.getLuminanceSource().rotateCounterClockwise();
207          return new BinaryBitmap(this.binarizer.createBinarizer(newSource));
208      }
209      /**
210       * Returns a new object with rotated image data by 45 degrees counterclockwise.
211       * Only callable if {@link #isRotateSupported()} is true.
212       *
213       * @return A rotated version of this object.
214       */
215      rotateCounterClockwise45() {
216          const newSource = this.binarizer.getLuminanceSource().rotateCounterClockwise45();
217          return new BinaryBitmap(this.binarizer.createBinarizer(newSource));
218      }
219      /*@Override*/
220      toString() {
221          try {
222              return this.getBlackMatrix().toString();
223          }
224          catch (e /*: NotFoundException*/) {
225              return '';
226          }
227      }
228  }
229
230  /**
231   * Custom Error class of type Exception.
232   */
233  class ChecksumException extends Exception {
234      static getChecksumInstance() {
235          return new ChecksumException();
236      }
237  }
238  ChecksumException.kind = 'ChecksumException';
239
240  /*
241   * Copyright 2009 ZXing authors
242   *
243   * Licensed under the Apache License, Version 2.0 (the "License");
244   * you may not use this file except in compliance with the License.
245   * You may obtain a copy of the License at
246   *
247   *      http://www.apache.org/licenses/LICENSE-2.0
248   *
249   * Unless required by applicable law or agreed to in writing, software
250   * distributed under the License is distributed on an "AS IS" BASIS,
251   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
252   * See the License for the specific language governing permissions and
253   * limitations under the License.
254   */
255  /**
256   * This class hierarchy provides a set of methods to convert luminance data to 1 bit data.
257   * It allows the algorithm to vary polymorphically, for example allowing a very expensive
258   * thresholding technique for servers and a fast one for mobile. It also permits the implementation
259   * to vary, e.g. a JNI version for Android and a Java fallback version for other platforms.
260   *
261   * @author [email protected] (Daniel Switkin)
262   */
263  class Binarizer {
264      constructor(source) {
265          this.source = source;
266      }
267      getLuminanceSource() {
268          return this.source;
269      }
270      getWidth() {
271          return this.source.getWidth();
272      }
273      getHeight() {
274          return this.source.getHeight();
275      }
276  }
277
278  class System {
279      // public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
280      /**
281       * Makes a copy of a array.
282       */
283      static arraycopy(src, srcPos, dest, destPos, length) {
284          
284// TODO: better use split or set?
285          while (length--) {
286              dest[destPos++] = src[srcPos++];
vendor: 38,936 bytes, lines 286-1231
286
287          }
288      }
289      /**
290       * Returns the current time in milliseconds.
291       */
292      static currentTimeMillis() {
293          return Date.now();
294      }
295  }
296
297  /**
298   * Custom Error class of type Exception.
299   */
300  class IndexOutOfBoundsException extends Exception {
301  }
302  IndexOutOfBoundsException.kind = 'IndexOutOfBoundsException';
303
304  /**
305   * Custom Error class of type Exception.
306   */
307  class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
308      constructor(index = undefined, message = undefined) {
309          super(message);
310          this.index = index;
311          this.message = message;
312      }
313  }
314  ArrayIndexOutOfBoundsException.kind = 'ArrayIndexOutOfBoundsException';
315
316  class Arrays {
317      /**
318       * Assigns the specified int value to each element of the specified array
319       * of ints.
320       *
321       * @param a the array to be filled
322       * @param val the value to be stored in all elements of the array
323       */
324      static fill(a, val) {
325          for (let i = 0, len = a.length; i < len; i++)
326              a[i] = val;
327      }
328      /**
329       * Assigns the specified int value to each element of the specified
330       * range of the specified array of ints.  The range to be filled
331       * extends from index {@code fromIndex}, inclusive, to index
332       * {@code toIndex}, exclusive.  (If {@code fromIndex==toIndex}, the
333       * range to be filled is empty.)
334       *
335       * @param a the array to be filled
336       * @param fromIndex the index of the first element (inclusive) to be
337       *        filled with the specified value
338       * @param toIndex the index of the last element (exclusive) to be
339       *        filled with the specified value
340       * @param val the value to be stored in all elements of the array
341       * @throws IllegalArgumentException if {@code fromIndex > toIndex}
342       * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or
343       *         {@code toIndex > a.length}
344       */
345      static fillWithin(a, fromIndex, toIndex, val) {
346          Arrays.rangeCheck(a.length, fromIndex, toIndex);
347          for (let i = fromIndex; i < toIndex; i++)
348              a[i] = val;
349      }
350      /**
351       * Checks that {@code fromIndex} and {@code toIndex} are in
352       * the range and throws an exception if they aren't.
353       */
354      static rangeCheck(arrayLength, fromIndex, toIndex) {
355          if (fromIndex > toIndex) {
356              throw new IllegalArgumentException('fromIndex(' + fromIndex + ') > toIndex(' + toIndex + ')');
357          }
358          if (fromIndex < 0) {
359              throw new ArrayIndexOutOfBoundsException(fromIndex);
360          }
361          if (toIndex > arrayLength) {
362              throw new ArrayIndexOutOfBoundsException(toIndex);
363          }
364      }
365      static asList(...args) {
366          return args;
367      }
368      static create(rows, cols, value) {
369          let arr = Array.from({ length: rows });
370          return arr.map(x => Array.from({ length: cols }).fill(value));
371      }
372      static createInt32Array(rows, cols, value) {
373          let arr = Array.from({ length: rows });
374          return arr.map(x => Int32Array.from({ length: cols }).fill(value));
375      }
376      static equals(first, second) {
377          if (!first) {
378              return false;
379          }
380          if (!second) {
381              return false;
382          }
383          if (!first.length) {
384              return false;
385          }
386          if (!second.length) {
387              return false;
388          }
389          if (first.length !== second.length) {
390              return false;
391          }
392          for (let i = 0, length = first.length; i < length; i++) {
393              if (first[i] !== second[i]) {
394                  return false;
395              }
396          }
397          return true;
398      }
399      static hashCode(a) {
400          if (a === null) {
401              return 0;
402          }
403          let result = 1;
404          for (const element of a) {
405              result = 31 * result + element;
406          }
407          return result;
408      }
409      static fillUint8Array(a, value) {
410          for (let i = 0; i !== a.length; i++) {
411              a[i] = value;
412          }
413      }
414      static copyOf(original, newLength) {
415          return original.slice(0, newLength);
416      }
417      static copyOfUint8Array(original, newLength) {
418          if (original.length <= newLength) {
419              const newArray = new Uint8Array(newLength);
420              newArray.set(original);
421              return newArray;
422          }
423          return original.slice(0, newLength);
424      }
425      static copyOfRange(original, from, to) {
426          const newLength = to - from;
427          const copy = new Int32Array(newLength);
428          System.arraycopy(original, from, copy, 0, newLength);
429          return copy;
430      }
431      /*
432      * Returns the index of of the element in a sorted array or (-n-1) where n is the insertion point
433      * for the new element.
434      * Parameters:
435      *     ar - A sorted array
436      *     el - An element to search for
437      *     comparator - A comparator function. The function takes two arguments: (a, b) and returns:
438      *        a negative number  if a is less than b;
439      *        0 if a is equal to b;
440      *        a positive number of a is greater than b.
441      * The array may contain duplicate elements. If there are more than one equal elements in the array,
442      * the returned value can be the index of any one of the equal elements.
443      *
444      * http://jsfiddle.net/aryzhov/pkfst550/
445      */
446      static binarySearch(ar, el, comparator) {
447          if (undefined === comparator) {
448              comparator = Arrays.numberComparator;
449          }
450          let m = 0;
451          let n = ar.length - 1;
452          while (m <= n) {
453              const k = (n + m) >> 1;
454              const cmp = comparator(el, ar[k]);
455              if (cmp > 0) {
456                  m = k + 1;
457              }
458              else if (cmp < 0) {
459                  n = k - 1;
460              }
461              else {
462                  return k;
463              }
464          }
465          return -m - 1;
466      }
467      static numberComparator(a, b) {
468          return a - b;
469      }
470  }
471
472  /**
473   * Ponyfill for Java's Integer class.
474   */
475  class Integer {
476      static numberOfTrailingZeros(i) {
477          let y;
478          if (i === 0)
479              return 32;
480          let n = 31;
481          y = i << 16;
482          if (y !== 0) {
483              n -= 16;
484              i = y;
485          }
486          y = i << 8;
487          if (y !== 0) {
488              n -= 8;
489              i = y;
490          }
491          y = i << 4;
492          if (y !== 0) {
493              n -= 4;
494              i = y;
495          }
496          y = i << 2;
497          if (y !== 0) {
498              n -= 2;
499              i = y;
500          }
501          return n - ((i << 1) >>> 31);
502      }
503      static numberOfLeadingZeros(i) {
504          // HD, Figure 5-6
505          if (i === 0) {
506              return 32;
507          }
508          let n = 1;
509          if (i >>> 16 === 0) {
510              n += 16;
511              i <<= 16;
512          }
513          if (i >>> 24 === 0) {
514              n += 8;
515              i <<= 8;
516          }
517          if (i >>> 28 === 0) {
518              n += 4;
519              i <<= 4;
520          }
521          if (i >>> 30 === 0) {
522              n += 2;
523              i <<= 2;
524          }
525          n -= i >>> 31;
526          return n;
527      }
528      static toHexString(i) {
529          return i.toString(16);
530      }
531      static toBinaryString(intNumber) {
532          return String(parseInt(String(intNumber), 2));
533      }
534      // Returns the number of one-bits in the two's complement binary representation of the specified int value. This function is sometimes referred to as the population count.
535      // Returns:
536      // the number of one-bits in the two's complement binary representation of the specified int value.
537      static bitCount(i) {
538          // HD, Figure 5-2
539          i = i - ((i >>> 1) & 0x55555555);
540          i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
541          i = (i + (i >>> 4)) & 0x0f0f0f0f;
542          i = i + (i >>> 8);
543          i = i + (i >>> 16);
544          return i & 0x3f;
545      }
546      static truncDivision(dividend, divisor) {
547          return Math.trunc(dividend / divisor);
548      }
549      /**
550       * Converts A string to an integer.
551       * @param s A string to convert into a number.
552       * @param radix A value between 2 and 36 that specifies the base of the number in numString. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
553       */
554      static parseInt(num, radix = undefined) {
555          return parseInt(num, radix);
556      }
557  }
558  Integer.MIN_VALUE_32_BITS = -2147483648;
559  Integer.MAX_VALUE = Number.MAX_SAFE_INTEGER;
560
561  /*
562   * Copyright 2007 ZXing authors
563   *
564   * Licensed under the Apache License, Version 2.0 (the "License");
565   * you may not use this file except in compliance with the License.
566   * You may obtain a copy of the License at
567   *
568   *      http://www.apache.org/licenses/LICENSE-2.0
569   *
570   * Unless required by applicable law or agreed to in writing, software
571   * distributed under the License is distributed on an "AS IS" BASIS,
572   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
573   * See the License for the specific language governing permissions and
574   * limitations under the License.
575   */
576  /**
577   * <p>A simple, fast array of bits, represented compactly by an array of ints internally.</p>
578   *
579   * @author Sean Owen
580   */
581  class BitArray /*implements Cloneable*/ {
582      // public constructor() {
583      //   this.size = 0
584      //   this.bits = new Int32Array(1)
585      // }
586      // public constructor(size?: number /*int*/) {
587      //   if (undefined === size) {
588      //     this.size = 0
589      //   } else {
590      //     this.size = size
591      //   }
592      //   this.bits = this.makeArray(size)
593      // }
594      // For testing only
595      constructor(size /*int*/, bits) {
596          if (undefined === size) {
597              this.size = 0;
598              this.bits = new Int32Array(1);
599          }
600          else {
601              this.size = size;
602              if (undefined === bits || null === bits) {
603                  this.bits = BitArray.makeArray(size);
604              }
605              else {
606                  this.bits = bits;
607              }
608          }
609      }
610      getSize() {
611          return this.size;
612      }
613      getSizeInBytes() {
614          return Math.floor((this.size + 7) / 8);
615      }
616      ensureCapacity(size /*int*/) {
617          if (size > this.bits.length * 32) {
618              const newBits = BitArray.makeArray(size);
619              System.arraycopy(this.bits, 0, newBits, 0, this.bits.length);
620              this.bits = newBits;
621          }
622      }
623      /**
624       * @param i bit to get
625       * @return true iff bit i is set
626       */
627      get(i /*int*/) {
628          return (this.bits[Math.floor(i / 32)] & (1 << (i & 0x1F))) !== 0;
629      }
630      /**
631       * Sets bit i.
632       *
633       * @param i bit to set
634       */
635      set(i /*int*/) {
636          this.bits[Math.floor(i / 32)] |= 1 << (i & 0x1F);
637      }
638      /**
639       * Flips bit i.
640       *
641       * @param i bit to set
642       */
643      flip(i /*int*/) {
644          this.bits[Math.floor(i / 32)] ^= 1 << (i & 0x1F);
645      }
646      /**
647       * @param from first bit to check
648       * @return index of first bit that is set, starting from the given index, or size if none are set
649       *  at or beyond this given index
650       * @see #getNextUnset(int)
651       */
652      getNextSet(from /*int*/) {
653          const size = this.size;
654          if (from >= size) {
655              return size;
656          }
657          const bits = this.bits;
658          let bitsOffset = Math.floor(from / 32);
659          let currentBits = bits[bitsOffset];
660          // mask off lesser bits first
661          currentBits &= ~((1 << (from & 0x1F)) - 1);
662          const length = bits.length;
663          while (currentBits === 0) {
664              if (++bitsOffset === length) {
665                  return size;
666              }
667              currentBits = bits[bitsOffset];
668          }
669          const result = (bitsOffset * 32) + Integer.numberOfTrailingZeros(currentBits);
670          return result > size ? size : result;
671      }
672      /**
673       * @param from index to start looking for unset bit
674       * @return index of next unset bit, or {@code size} if none are unset until the end
675       * @see #getNextSet(int)
676       */
677      getNextUnset(from /*int*/) {
678          const size = this.size;
679          if (from >= size) {
680              return size;
681          }
682          const bits = this.bits;
683          let bitsOffset = Math.floor(from / 32);
684          let currentBits = ~bits[bitsOffset];
685          // mask off lesser bits first
686          currentBits &= ~((1 << (from & 0x1F)) - 1);
687          const length = bits.length;
688          while (currentBits === 0) {
689              if (++bitsOffset === length) {
690                  return size;
691              }
692              currentBits = ~bits[bitsOffset];
693          }
694          const result = (bitsOffset * 32) + Integer.numberOfTrailingZeros(currentBits);
695          return result > size ? size : result;
696      }
697      /**
698       * Sets a block of 32 bits, starting at bit i.
699       *
700       * @param i first bit to set
701       * @param newBits the new value of the next 32 bits. Note again that the least-significant bit
702       * corresponds to bit i, the next-least-significant to i+1, and so on.
703       */
704      setBulk(i /*int*/, newBits /*int*/) {
705          this.bits[Math.floor(i / 32)] = newBits;
706      }
707      /**
708       * Sets a range of bits.
709       *
710       * @param start start of range, inclusive.
711       * @param end end of range, exclusive
712       */
713      setRange(start /*int*/, end /*int*/) {
714          if (end < start || start < 0 || end > this.size) {
715              throw new IllegalArgumentException();
716          }
717          if (end === start) {
718              return;
719          }
720          end--; // will be easier to treat this as the last actually set bit -- inclusive
721          const firstInt = Math.floor(start / 32);
722          const lastInt = Math.floor(end / 32);
723          const bits = this.bits;
724          for (let i = firstInt; i <= lastInt; i++) {
725              const firstBit = i > firstInt ? 0 : start & 0x1F;
726              const lastBit = i < lastInt ? 31 : end & 0x1F;
727              // Ones from firstBit to lastBit, inclusive
728              const mask = (2 << lastBit) - (1 << firstBit);
729              bits[i] |= mask;
730          }
731      }
732      /**
733       * Clears all bits (sets to false).
734       */
735      clear() {
736          const max = this.bits.length;
737          const bits = this.bits;
738          for (let i = 0; i < max; i++) {
739              bits[i] = 0;
740          }
741      }
742      /**
743       * Efficient method to check if a range of bits is set, or not set.
744       *
745       * @param start start of range, inclusive.
746       * @param end end of range, exclusive
747       * @param value if true, checks that bits in range are set, otherwise checks that they are not set
748       * @return true iff all bits are set or not set in range, according to value argument
749       * @throws IllegalArgumentException if end is less than start or the range is not contained in the array
750       */
751      isRange(start /*int*/, end /*int*/, value) {
752          if (end < start || start < 0 || end > this.size) {
753              throw new IllegalArgumentException();
754          }
755          if (end === start) {
756              return true; // empty range matches
757          }
758          end--; // will be easier to treat this as the last actually set bit -- inclusive
759          const firstInt = Math.floor(start / 32);
760          const lastInt = Math.floor(end / 32);
761          const bits = this.bits;
762          for (let i = firstInt; i <= lastInt; i++) {
763              const firstBit = i > firstInt ? 0 : start & 0x1F;
764              const lastBit = i < lastInt ? 31 : end & 0x1F;
765              // Ones from firstBit to lastBit, inclusive
766              const mask = (2 << lastBit) - (1 << firstBit) & 0xFFFFFFFF;
767              // TYPESCRIPTPORT: & 0xFFFFFFFF added to discard anything after 32 bits, as ES has 53 bits
768              // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (is: that,
769              // equals the mask, or we're looking for 0s and the masked portion is not all 0s
770              if ((bits[i] & mask) !== (value ? mask : 0)) {
771                  return false;
772              }
773          }
774          return true;
775      }
776      appendBit(bit) {
777          this.ensureCapacity(this.size + 1);
778          if (bit) {
779              this.bits[Math.floor(this.size / 32)] |= 1 << (this.size & 0x1F);
780          }
781          this.size++;
782      }
783      /**
784       * Appends the least-significant bits, from value, in order from most-significant to
785       * least-significant. For example, appending 6 bits from 0x000001E will append the bits
786       * 0, 1, 1, 1, 1, 0 in that order.
787       *
788       * @param value {@code int} containing bits to append
789       * @param numBits bits from value to append
790       */
791      appendBits(value /*int*/, numBits /*int*/) {
792          if (numBits < 0 || numBits > 32) {
793              throw new IllegalArgumentException('Num bits must be between 0 and 32');
794          }
795          this.ensureCapacity(this.size + numBits);
796          // const appendBit = this.appendBit;
797          for (let numBitsLeft = numBits; numBitsLeft > 0; numBitsLeft--) {
798              this.appendBit(((value >> (numBitsLeft - 1)) & 0x01) === 1);
799          }
800      }
801      appendBitArray(other) {
802          const otherSize = other.size;
803          this.ensureCapacity(this.size + otherSize);
804          // const appendBit = this.appendBit;
805          for (let i = 0; i < otherSize; i++) {
806              this.appendBit(other.get(i));
807          }
808      }
809      xor(other) {
810          if (this.size !== other.size) {
811              throw new IllegalArgumentException('Sizes don\'t match');
812          }
813          const bits = this.bits;
814          for (let i = 0, length = bits.length; i < length; i++) {
815              // The last int could be incomplete (i.e. not have 32 bits in
816              // it) but there is no problem since 0 XOR 0 == 0.
817              bits[i] ^= other.bits[i];
818          }
819      }
820      /**
821       *
822       * @param bitOffset first bit to start writing
823       * @param array array to write into. Bytes are written most-significant byte first. This is the opposite
824       *  of the internal representation, which is exposed by {@link #getBitArray()}
825       * @param offset position in array to start writing
826       * @param numBytes how many bytes to write
827       */
828      toBytes(bitOffset /*int*/, array, offset /*int*/, numBytes /*int*/) {
829          for (let i = 0; i < numBytes; i++) {
830              let theByte = 0;
831              for (let j = 0; j < 8; j++) {
832                  if (this.get(bitOffset)) {
833                      theByte |= 1 << (7 - j);
834                  }
835                  bitOffset++;
836              }
837              array[offset + i] = /*(byte)*/ theByte;
838          }
839      }
840      /**
841       * @return underlying array of ints. The first element holds the first 32 bits, and the least
842       *         significant bit is bit 0.
843       */
844      getBitArray() {
845          return this.bits;
846      }
847      /**
848       * Reverses all bits in the array.
849       */
850      reverse() {
851          const newBits = new Int32Array(this.bits.length);
852          // reverse all int's first
853          const len = Math.floor((this.size - 1) / 32);
854          const oldBitsLen = len + 1;
855          const bits = this.bits;
856          for (let i = 0; i < oldBitsLen; i++) {
857              let x = bits[i];
858              x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
859              x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
860              x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
861              x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
862              x = ((x >> 16) & 0x0000ffff) | ((x & 0x0000ffff) << 16);
863              newBits[len - i] = /*(int)*/ x;
864          }
865          // now correct the int's if the bit size isn't a multiple of 32
866          if (this.size !== oldBitsLen * 32) {
867              const leftOffset = oldBitsLen * 32 - this.size;
868              let currentInt = newBits[0] >>> leftOffset;
869              for (let i = 1; i < oldBitsLen; i++) {
870                  const nextInt = newBits[i];
871                  currentInt |= nextInt << (32 - leftOffset);
872                  newBits[i - 1] = currentInt;
873                  currentInt = nextInt >>> leftOffset;
874              }
875              newBits[oldBitsLen - 1] = currentInt;
876          }
877          this.bits = newBits;
878      }
879      static makeArray(size /*int*/) {
880          return new Int32Array(Math.floor((size + 31) / 32));
881      }
882      /*@Override*/
883      equals(o) {
884          if (!(o instanceof BitArray)) {
885              return false;
886          }
887          const other = o;
888          return this.size === other.size && Arrays.equals(this.bits, other.bits);
889      }
890      /*@Override*/
891      hashCode() {
892          return 31 * this.size + Arrays.hashCode(this.bits);
893      }
894      /*@Override*/
895      toString() {
896          let result = '';
897          for (let i = 0, size = this.size; i < size; i++) {
898              if ((i & 0x07) === 0) {
899                  result += ' ';
900              }
901              result += this.get(i) ? 'X' : '.';
902          }
903          return result;
904      }
905      /*@Override*/
906      clone() {
907          return new BitArray(this.size, this.bits.slice());
908      }
909      /**
910       * converts to boolean array.
911       */
912      toArray() {
913          let result = [];
914          for (let i = 0, size = this.size; i < size; i++) {
915              result.push(this.get(i));
916          }
917          return result;
918      }
919  }
920
921  /*
922   * Copyright 2009 ZXing authors
923   *
924   * Licensed under the Apache License, Version 2.0 (the "License");
925   * you may not use this file except in compliance with the License.
926   * You may obtain a copy of the License at
927   *
928   *      http://www.apache.org/licenses/LICENSE-2.0
929   *
930   * Unless required by applicable law or agreed to in writing, software
931   * distributed under the License is distributed on an "AS IS" BASIS,
932   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
933   * See the License for the specific language governing permissions and
934   * limitations under the License.
935   */
936  /*namespace com.google.zxing {*/
937  /**
938   * Encapsulates a type of hint that a caller may pass to a barcode reader to help it
939   * more quickly or accurately decode it. It is up to implementations to decide what,
940   * if anything, to do with the information that is supplied.
941   *
942   * @author Sean Owen
943   * @author [email protected] (Daniel Switkin)
944   * @see Reader#decode(BinaryBitmap,java.util.Map)
945   */
946  var DecodeHintType;
947  (function (DecodeHintType) {
948      /**
949       * Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
950       */
951      DecodeHintType[DecodeHintType["OTHER"] = 0] = "OTHER"; /*(Object.class)*/
952      /**
953       * Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
954       * use {@link Boolean#TRUE}.
955       */
956      DecodeHintType[DecodeHintType["PURE_BARCODE"] = 1] = "PURE_BARCODE"; /*(Void.class)*/
957      /**
958       * Image is known to be of one of a few possible formats.
959       * Maps to a {@link List} of {@link BarcodeFormat}s.
960       */
961      DecodeHintType[DecodeHintType["POSSIBLE_FORMATS"] = 2] = "POSSIBLE_FORMATS"; /*(List.class)*/
962      /**
963       * Spend more time to try to find a barcode; optimize for accuracy, not speed.
964       * Doesn't matter what it maps to; use {@link Boolean#TRUE}.
965       */
966      DecodeHintType[DecodeHintType["TRY_HARDER"] = 3] = "TRY_HARDER"; /*(Void.class)*/
967      /**
968       * Specifies what character encoding to use when decoding, where applicable (type String)
969       */
970      DecodeHintType[DecodeHintType["CHARACTER_SET"] = 4] = "CHARACTER_SET"; /*(String.class)*/
971      /**
972       * Allowed lengths of encoded data -- reject anything else. Maps to an {@code Int32Array}.
973       */
974      DecodeHintType[DecodeHintType["ALLOWED_LENGTHS"] = 5] = "ALLOWED_LENGTHS"; /*(Int32Array.class)*/
975      /**
976       * Assume Code 39 codes employ a check digit. Doesn't matter what it maps to;
977       * use {@link Boolean#TRUE}.
978       */
979      DecodeHintType[DecodeHintType["ASSUME_CODE_39_CHECK_DIGIT"] = 6] = "ASSUME_CODE_39_CHECK_DIGIT"; /*(Void.class)*/
980      /**
981       * Enable extended mode for Code 39 codes. Doesn't matter what it maps to;
982       * use {@link Boolean#TRUE}.
983       */
984      DecodeHintType[DecodeHintType["ENABLE_CODE_39_EXTENDED_MODE"] = 7] = "ENABLE_CODE_39_EXTENDED_MODE"; /*(Void.class)*/
985      /**
986       * Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed.
987       * For example this affects FNC1 handling for Code 128 (aka GS1-128). Doesn't matter what it maps to;
988       * use {@link Boolean#TRUE}.
989       */
990      DecodeHintType[DecodeHintType["ASSUME_GS1"] = 8] = "ASSUME_GS1"; /*(Void.class)*/
991      /**
992       * If true, return the start and end digits in a Codabar barcode instead of stripping them. They
993       * are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them
994       * to not be. Doesn't matter what it maps to; use {@link Boolean#TRUE}.
995       */
996      DecodeHintType[DecodeHintType["RETURN_CODABAR_START_END"] = 9] = "RETURN_CODABAR_START_END"; /*(Void.class)*/
997      /**
998       * The caller needs to be notified via callback when a possible {@link ResultPoint}
999       * is found. Maps to a {@link ResultPointCallback}.
1000       */
1001      DecodeHintType[DecodeHintType["NEED_RESULT_POINT_CALLBACK"] = 10] = "NEED_RESULT_POINT_CALLBACK"; /*(ResultPointCallback.class)*/
1002      /**
1003       * Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this.
1004       * Maps to an {@code Int32Array} of the allowed extension lengths, for example [2], [5], or [2, 5].
1005       * If it is optional to have an extension, do not set this hint. If this is set,
1006       * and a UPC or EAN barcode is found but an extension is not, then no result will be returned
1007       * at all.
1008       */
1009      DecodeHintType[DecodeHintType["ALLOWED_EAN_EXTENSIONS"] = 11] = "ALLOWED_EAN_EXTENSIONS"; /*(Int32Array.class)*/
1010      // End of enumeration values.
1011      /**
1012       * Data type the hint is expecting.
1013       * Among the possible values the {@link Void} stands out as being used for
1014       * hints that do not expect a value to be supplied (flag hints). Such hints
1015       * will possibly have their value ignored, or replaced by a
1016       * {@link Boolean#TRUE}. Hint suppliers should probably use
1017       * {@link Boolean#TRUE} as directed by the actual hint documentation.
1018       */
1019      // private valueType: Class<?>
1020      // DecodeHintType(valueType: Class<?>) {
1021      //   this.valueType = valueType
1022      // }
1023      // public getValueType(): Class<?> {
1024      //   return valueType
1025      // }
1026  })(DecodeHintType || (DecodeHintType = {}));
1027  var DecodeHintType$1 = DecodeHintType;
1028
1029  /**
1030   * Custom Error class of type Exception.
1031   */
1032  class FormatException extends Exception {
1033      static getFormatInstance() {
1034          return new FormatException();
1035      }
1036  }
1037  FormatException.kind = 'FormatException';
1038
1039  /*
1040   * Copyright 2008 ZXing authors
1041   *
1042   * Licensed under the Apache License, Version 2.0 (the "License");
1043   * you may not use this file except in compliance with the License.
1044   * You may obtain a copy of the License at
1045   *
1046   *      http://www.apache.org/licenses/LICENSE-2.0
1047   *
1048   * Unless required by applicable law or agreed to in writing, software
1049   * distributed under the License is distributed on an "AS IS" BASIS,
1050   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1051   * See the License for the specific language governing permissions and
1052   * limitations under the License.
1053   */
1054  /*import java.util.HashMap;*/
1055  /*import java.util.Map;*/
1056  var CharacterSetValueIdentifiers;
1057  (function (CharacterSetValueIdentifiers) {
1058      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["Cp437"] = 0] = "Cp437";
1059      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_1"] = 1] = "ISO8859_1";
1060      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_2"] = 2] = "ISO8859_2";
1061      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_3"] = 3] = "ISO8859_3";
1062      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_4"] = 4] = "ISO8859_4";
1063      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_5"] = 5] = "ISO8859_5";
1064      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_6"] = 6] = "ISO8859_6";
1065      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_7"] = 7] = "ISO8859_7";
1066      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_8"] = 8] = "ISO8859_8";
1067      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_9"] = 9] = "ISO8859_9";
1068      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_10"] = 10] = "ISO8859_10";
1069      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_11"] = 11] = "ISO8859_11";
1070      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_13"] = 12] = "ISO8859_13";
1071      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_14"] = 13] = "ISO8859_14";
1072      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_15"] = 14] = "ISO8859_15";
1073      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ISO8859_16"] = 15] = "ISO8859_16";
1074      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["SJIS"] = 16] = "SJIS";
1075      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["Cp1250"] = 17] = "Cp1250";
1076      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["Cp1251"] = 18] = "Cp1251";
1077      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["Cp1252"] = 19] = "Cp1252";
1078      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["Cp1256"] = 20] = "Cp1256";
1079      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["UnicodeBigUnmarked"] = 21] = "UnicodeBigUnmarked";
1080      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["UTF8"] = 22] = "UTF8";
1081      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["ASCII"] = 23] = "ASCII";
1082      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["Big5"] = 24] = "Big5";
1083      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["GB18030"] = 25] = "GB18030";
1084      CharacterSetValueIdentifiers[CharacterSetValueIdentifiers["EUC_KR"] = 26] = "EUC_KR";
1085  })(CharacterSetValueIdentifiers || (CharacterSetValueIdentifiers = {}));
1086  /**
1087   * Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1
1088   * of ISO 18004.
1089   *
1090   * @author Sean Owen
1091   */
1092  class CharacterSetECI {
1093      constructor(valueIdentifier, valuesParam, name, ...otherEncodingNames) {
1094          this.valueIdentifier = valueIdentifier;
1095          this.name = name;
1096          if (typeof valuesParam === 'number') {
1097              this.values = Int32Array.from([valuesParam]);
1098          }
1099          else {
1100              this.values = valuesParam;
1101          }
1102          this.otherEncodingNames = otherEncodingNames;
1103          CharacterSetECI.VALUE_IDENTIFIER_TO_ECI.set(valueIdentifier, this);
1104          CharacterSetECI.NAME_TO_ECI.set(name, this);
1105          const values = this.values;
1106          for (let i = 0, length = values.length; i !== length; i++) {
1107              const v = values[i];
1108              CharacterSetECI.VALUES_TO_ECI.set(v, this);
1109          }
1110          for (const otherName of otherEncodingNames) {
1111              CharacterSetECI.NAME_TO_ECI.set(otherName, this);
1112          }
1113      }
1114      // CharacterSetECI(value: number /*int*/) {
1115      //   this(new Int32Array {value})
1116      // }
1117      // CharacterSetECI(value: number /*int*/, String... otherEncodingNames) {
1118      //   this.values = new Int32Array {value}
1119      //   this.otherEncodingNames = otherEncodingNames
1120      // }
1121      // CharacterSetECI(values: Int32Array, String... otherEncodingNames) {
1122      //   this.values = values
1123      //   this.otherEncodingNames = otherEncodingNames
1124      // }
1125      getValueIdentifier() {
1126          return this.valueIdentifier;
1127      }
1128      getName() {
1129          return this.name;
1130      }
1131      getValue() {
1132          return this.values[0];
1133      }
1134      /**
1135       * @param value character set ECI value
1136       * @return {@code CharacterSetECI} representing ECI of given value, or null if it is legal but
1137       *   unsupported
1138       * @throws FormatException if ECI value is invalid
1139       */
1140      static getCharacterSetECIByValue(value /*int*/) {
1141          if (value < 0 || value >= 900) {
1142              throw new FormatException('incorect value');
1143          }
1144          const characterSet = CharacterSetECI.VALUES_TO_ECI.get(value);
1145          if (undefined === characterSet) {
1146              throw new FormatException('incorect value');
1147          }
1148          return characterSet;
1149      }
1150      /**
1151       * @param name character set ECI encoding name
1152       * @return CharacterSetECI representing ECI for character encoding, or null if it is legal
1153       *   but unsupported
1154       */
1155      static getCharacterSetECIByName(name) {
1156          const characterSet = CharacterSetECI.NAME_TO_ECI.get(name);
1157          if (undefined === characterSet) {
1158              throw new FormatException('incorect value');
1159          }
1160          return characterSet;
1161      }
1162      equals(o) {
1163          if (!(o instanceof CharacterSetECI)) {
1164              return false;
1165          }
1166          const other = o;
1167          return this.getName() === other.getName();
1168      }
1169  }
1170  CharacterSetECI.VALUE_IDENTIFIER_TO_ECI = new Map();
1171  CharacterSetECI.VALUES_TO_ECI = new Map();
1172  CharacterSetECI.NAME_TO_ECI = new Map();
1173  // Enum name is a Java encoding valid for java.lang and java.io
1174  // TYPESCRIPTPORT: changed the main label for ISO as the TextEncoder did not recognized them in the form from java
1175  // (eg ISO8859_1 must be ISO88591 or ISO8859-1 or ISO-8859-1)
1176  // later on: well, except 16 wich does not work with ISO885916 so used ISO-8859-1 form for default
1177  CharacterSetECI.Cp437 = new CharacterSetECI(CharacterSetValueIdentifiers.Cp437, Int32Array.from([0, 2]), 'Cp437');
1178  CharacterSetECI.ISO8859_1 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_1, Int32Array.from([1, 3]), 'ISO-8859-1', 'ISO88591', 'ISO8859_1');
1179  CharacterSetECI.ISO8859_2 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_2, 4, 'ISO-8859-2', 'ISO88592', 'ISO8859_2');
1180  CharacterSetECI.ISO8859_3 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_3, 5, 'ISO-8859-3', 'ISO88593', 'ISO8859_3');
1181  CharacterSetECI.ISO8859_4 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_4, 6, 'ISO-8859-4', 'ISO88594', 'ISO8859_4');
1182  CharacterSetECI.ISO8859_5 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_5, 7, 'ISO-8859-5', 'ISO88595', 'ISO8859_5');
1183  CharacterSetECI.ISO8859_6 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_6, 8, 'ISO-8859-6', 'ISO88596', 'ISO8859_6');
1184  CharacterSetECI.ISO8859_7 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_7, 9, 'ISO-8859-7', 'ISO88597', 'ISO8859_7');
1185  CharacterSetECI.ISO8859_8 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_8, 10, 'ISO-8859-8', 'ISO88598', 'ISO8859_8');
1186  CharacterSetECI.ISO8859_9 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_9, 11, 'ISO-8859-9', 'ISO88599', 'ISO8859_9');
1187  CharacterSetECI.ISO8859_10 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_10, 12, 'ISO-8859-10', 'ISO885910', 'ISO8859_10');
1188  CharacterSetECI.ISO8859_11 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_11, 13, 'ISO-8859-11', 'ISO885911', 'ISO8859_11');
1189  CharacterSetECI.ISO8859_13 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_13, 15, 'ISO-8859-13', 'ISO885913', 'ISO8859_13');
1190  CharacterSetECI.ISO8859_14 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_14, 16, 'ISO-8859-14', 'ISO885914', 'ISO8859_14');
1191  CharacterSetECI.ISO8859_15 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_15, 17, 'ISO-8859-15', 'ISO885915', 'ISO8859_15');
1192  CharacterSetECI.ISO8859_16 = new CharacterSetECI(CharacterSetValueIdentifiers.ISO8859_16, 18, 'ISO-8859-16', 'ISO885916', 'ISO8859_16');
1193  CharacterSetECI.SJIS = new CharacterSetECI(CharacterSetValueIdentifiers.SJIS, 20, 'SJIS', 'Shift_JIS');
1194  CharacterSetECI.Cp1250 = new CharacterSetECI(CharacterSetValueIdentifiers.Cp1250, 21, 'Cp1250', 'windows-1250');
1195  CharacterSetECI.Cp1251 = new CharacterSetECI(CharacterSetValueIdentifiers.Cp1251, 22, 'Cp1251', 'windows-1251');
1196  CharacterSetECI.Cp1252 = new CharacterSetECI(CharacterSetValueIdentifiers.Cp1252, 23, 'Cp1252', 'windows-1252');
1197  CharacterSetECI.Cp1256 = new CharacterSetECI(CharacterSetValueIdentifiers.Cp1256, 24, 'Cp1256', 'windows-1256');
1198  CharacterSetECI.UnicodeBigUnmarked = new CharacterSetECI(CharacterSetValueIdentifiers.UnicodeBigUnmarked, 25, 'UnicodeBigUnmarked', 'UTF-16BE', 'UnicodeBig');
1199  CharacterSetECI.UTF8 = new CharacterSetECI(CharacterSetValueIdentifiers.UTF8, 26, 'UTF8', 'UTF-8');
1200  CharacterSetECI.ASCII = new CharacterSetECI(CharacterSetValueIdentifiers.ASCII, Int32Array.from([27, 170]), 'ASCII', 'US-ASCII');
1201  CharacterSetECI.Big5 = new CharacterSetECI(CharacterSetValueIdentifiers.Big5, 28, 'Big5');
1202  CharacterSetECI.GB18030 = new CharacterSetECI(CharacterSetValueIdentifiers.GB18030, 29, 'GB18030', 'GB2312', 'EUC_CN', 'GBK');
1203  CharacterSetECI.EUC_KR = new CharacterSetECI(CharacterSetValueIdentifiers.EUC_KR, 30, 'EUC_KR', 'EUC-KR');
1204
1205  /**
1206   * Custom Error class of type Exception.
1207   */
1208  class UnsupportedOperationException extends Exception {
1209  }
1210  UnsupportedOperationException.kind = 'UnsupportedOperationException';
1211
1212  /**
1213   * Responsible for en/decoding strings.
1214   */
1215  class StringEncoding {
1216      /**
1217       * Decodes some Uint8Array to a string format.
1218       */
1219      static decode(bytes, encoding) {
1220          const encodingName = this.encodingName(encoding);
1221          if (this.customDecoder) {
1222              return this.customDecoder(bytes, encodingName);
1223          }
1224          // Increases browser support.
1225          if (typeof TextDecoder === 'undefined' || this.shouldDecodeOnFallback(encodingName)) {
1226              return this.decodeFallback(bytes, encodingName);
1227          }
1228          return new TextDecoder(encodingName).decode(bytes);
1229      }
1230      /**
1231       * Checks if the decoding method should use the fallback for decoding
1231
1232       * once Node TextDecoder doesn't support all encoding formats.
1233       *
1234       * @param encodingName
1235       */
1236      static shouldDecodeOnFallback(encodingName) {
1237          return !StringEncoding.isBrowser() && encodingName === 'ISO-8859-1';
1238      }
1239      /**
1240       * Encodes some string into a Uint8Array.
1241       */
1242      static encode(s, encoding) {
1243          const encodingName = this.encodingName(encoding);
1244          if (this.customEncoder) {
1245              return this.customEncoder(s, encodingName);
1246          }
1247          // Increases browser support.
1248          if (typeof TextEncoder === 'undefined') {
1249              return this.encodeFallback(s);
1250          }
1251          // TextEncoder only encodes to UTF8 by default as specified by encoding.spec.whatwg.org
1252          return new TextEncoder().encode(s);
1253      }
1254      static isBrowser() {
1255          return (typeof window !== 'undefined' && {}.toString.call(window) === '[object Window]');
1256      }
1257      /**
1258       * Returns the string value from some encoding character set.
1259       */
1260      static encodingName(encoding) {
1261          return typeof encoding === 'string'
1262              ? encoding
1263              : encoding.getName();
1264      }
1265      /**
1266       * Returns character set from some encoding character set.
1267       */
1268      static encodingCharacterSet(encoding) {
1269          if (encoding instanceof CharacterSetECI) {
1270              return encoding;
1271          }
1272          return CharacterSetECI.getCharacterSetECIByName(encoding);
1273      }
1274      /**
1275       * Runs a fallback for the native decoding funcion.
1276       */
1277      static decodeFallback(bytes, encoding) {
1278          const characterSet = this.encodingCharacterSet(encoding);
1279          if (StringEncoding.isDecodeFallbackSupported(characterSet)) {
1280              let s = '';
1281              for (let i = 0, length = bytes.length; i < length; i++) {
1282                  let h = bytes[i].toString(16);
1283                  if (h.length < 2) {
1284                      h = '0' + h;
1285                  }
1286                  s += '%' + h;
1287              }
1288              return decodeURIComponent(s);
1289          }
1290          if (characterSet.equals(CharacterSetECI.UnicodeBigUnmarked)) {
1291              return String.fromCharCode.apply(null, new Uint16Array(bytes.buffer));
1292          }
1293          throw new UnsupportedOperationException(`Encoding ${this.encodingName(encoding)} not supported by fallback.`);
1294      }
1295      static isDecodeFallbackSupported(characterSet) {
1296          return characterSet.equals(CharacterSetECI.UTF8) ||
1297              characterSet.equals(CharacterSetECI.ISO8859_1) ||
1298              characterSet.equals(CharacterSetECI.ASCII);
1299      }
1300      /**
1301       * Runs a fallback for the native encoding funcion.
1302       *
1303       * @see https://stackoverflow.com/a/17192845/4367683
1304       */
1305      static encodeFallback(s) {
1306          const encodedURIstring = btoa(unescape(encodeURIComponent(s)));
1307          const charList = encodedURIstring.split('');
1308          const uintArray = [];
1309          for (let i = 0; i < charList.length; i++) {
1310              uintArray.push(charList[i].charCodeAt(0));
1311          }
1312          return new Uint8Array(uintArray);
1313      }
1314  }
1315
1316  /*
1317   * Copyright (C) 2010 ZXing authors
1318   *
1319   * Licensed under the Apache License, Version 2.0 (the "License");
1320   * you may not use this file except in compliance with the License.
1321   * You may obtain a copy of the License at
1322   *
1323   *      http://www.apache.org/licenses/LICENSE-2.0
1324   *
1325   * Unless required by applicable law or agreed to in writing, software
1326   * distributed under the License is distributed on an "AS IS" BASIS,
1327   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1328   * See the License for the specific language governing permissions and
1329   * limitations under the License.
1330   
vendor: 13,197 bytes, lines 1330-1662
1330*/
1331  /**
1332   * Common string-related functions.
1333   *
1334   * @author Sean Owen
1335   * @author Alex Dupre
1336   */
1337  class StringUtils {
1338      // SHIFT_JIS.equalsIgnoreCase(PLATFORM_DEFAULT_ENCODING) ||
1339      // EUC_JP.equalsIgnoreCase(PLATFORM_DEFAULT_ENCODING);
1340      static castAsNonUtf8Char(code, encoding = null) {
1341          // ISO 8859-1 is the Java default as UTF-8 is JavaScripts
1342          // you can see this method as a Java version of String.fromCharCode
1343          const e = encoding ? encoding.getName() : this.ISO88591;
1344          // use passed format (fromCharCode will return UTF8 encoding)
1345          return StringEncoding.decode(new Uint8Array([code]), e);
1346      }
1347      /**
1348       * @param bytes bytes encoding a string, whose encoding should be guessed
1349       * @param hints decode hints if applicable
1350       * @return name of guessed encoding; at the moment will only guess one of:
1351       *  {@link #SHIFT_JIS}, {@link #UTF8}, {@link #ISO88591}, or the platform
1352       *  default encoding if none of these can possibly be correct
1353       */
1354      static guessEncoding(bytes, hints) {
1355          if (hints !== null && hints !== undefined && undefined !== hints.get(DecodeHintType$1.CHARACTER_SET)) {
1356              return hints.get(DecodeHintType$1.CHARACTER_SET).toString();
1357          }
1358          // For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS,
1359          // which should be by far the most common encodings.
1360          const length = bytes.length;
1361          let canBeISO88591 = true;
1362          let canBeShiftJIS = true;
1363          let canBeUTF8 = true;
1364          let utf8BytesLeft = 0;
1365          // int utf8LowChars = 0
1366          let utf2BytesChars = 0;
1367          let utf3BytesChars = 0;
1368          let utf4BytesChars = 0;
1369          let sjisBytesLeft = 0;
1370          // int sjisLowChars = 0
1371          let sjisKatakanaChars = 0;
1372          // int sjisDoubleBytesChars = 0
1373          let sjisCurKatakanaWordLength = 0;
1374          let sjisCurDoubleBytesWordLength = 0;
1375          let sjisMaxKatakanaWordLength = 0;
1376          let sjisMaxDoubleBytesWordLength = 0;
1377          // int isoLowChars = 0
1378          // int isoHighChars = 0
1379          let isoHighOther = 0;
1380          const utf8bom = bytes.length > 3 &&
1381              bytes[0] === /*(byte) */ 0xEF &&
1382              bytes[1] === /*(byte) */ 0xBB &&
1383              bytes[2] === /*(byte) */ 0xBF;
1384          for (let i = 0; i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8); i++) {
1385              const value = bytes[i] & 0xFF;
1386              // UTF-8 stuff
1387              if (canBeUTF8) {
1388                  if (utf8BytesLeft > 0) {
1389                      if ((value & 0x80) === 0) {
1390                          canBeUTF8 = false;
1391                      }
1392                      else {
1393                          utf8BytesLeft--;
1394                      }
1395                  }
1396                  else if ((value & 0x80) !== 0) {
1397                      if ((value & 0x40) === 0) {
1398                          canBeUTF8 = false;
1399                      }
1400                      else {
1401                          utf8BytesLeft++;
1402                          if ((value & 0x20) === 0) {
1403                              utf2BytesChars++;
1404                          }
1405                          else {
1406                              utf8BytesLeft++;
1407                              if ((value & 0x10) === 0) {
1408                                  utf3BytesChars++;
1409                              }
1410                              else {
1411                                  utf8BytesLeft++;
1412                                  if ((value & 0x08) === 0) {
1413                                      utf4BytesChars++;
1414                                  }
1415                                  else {
1416                                      canBeUTF8 = false;
1417                                  }
1418                              }
1419                          }
1420                      }
1421                  } // else {
1422                  // utf8LowChars++
1423                  // }
1424              }
1425              // ISO-8859-1 stuff
1426              if (canBeISO88591) {
1427                  if (value > 0x7F && value < 0xA0) {
1428                      canBeISO88591 = false;
1429                  }
1430                  else if (value > 0x9F) {
1431                      if (value < 0xC0 || value === 0xD7 || value === 0xF7) {
1432                          isoHighOther++;
1433                      } // else {
1434                      // isoHighChars++
1435                      // }
1436                  } // else {
1437                  // isoLowChars++
1438                  // }
1439              }
1440              // Shift_JIS stuff
1441              if (canBeShiftJIS) {
1442                  if (sjisBytesLeft > 0) {
1443                      if (value < 0x40 || value === 0x7F || value > 0xFC) {
1444                          canBeShiftJIS = false;
1445                      }
1446                      else {
1447                          sjisBytesLeft--;
1448                      }
1449                  }
1450                  else if (value === 0x80 || value === 0xA0 || value > 0xEF) {
1451                      canBeShiftJIS = false;
1452                  }
1453                  else if (value > 0xA0 && value < 0xE0) {
1454                      sjisKatakanaChars++;
1455                      sjisCurDoubleBytesWordLength = 0;
1456                      sjisCurKatakanaWordLength++;
1457                      if (sjisCurKatakanaWordLength > sjisMaxKatakanaWordLength) {
1458                          sjisMaxKatakanaWordLength = sjisCurKatakanaWordLength;
1459                      }
1460                  }
1461                  else if (value > 0x7F) {
1462                      sjisBytesLeft++;
1463                      // sjisDoubleBytesChars++
1464                      sjisCurKatakanaWordLength = 0;
1465                      sjisCurDoubleBytesWordLength++;
1466                      if (sjisCurDoubleBytesWordLength > sjisMaxDoubleBytesWordLength) {
1467                          sjisMaxDoubleBytesWordLength = sjisCurDoubleBytesWordLength;
1468                      }
1469                  }
1470                  else {
1471                      // sjisLowChars++
1472                      sjisCurKatakanaWordLength = 0;
1473                      sjisCurDoubleBytesWordLength = 0;
1474                  }
1475              }
1476          }
1477          if (canBeUTF8 && utf8BytesLeft > 0) {
1478              canBeUTF8 = false;
1479          }
1480          if (canBeShiftJIS && sjisBytesLeft > 0) {
1481              canBeShiftJIS = false;
1482          }
1483          // Easy -- if there is BOM or at least 1 valid not-single byte character (and no evidence it can't be UTF-8), done
1484          if (canBeUTF8 && (utf8bom || utf2BytesChars + utf3BytesChars + utf4BytesChars > 0)) {
1485              return StringUtils.UTF8;
1486          }
1487          // Easy -- if assuming Shift_JIS or at least 3 valid consecutive not-ascii characters (and no evidence it can't be), done
1488          if (canBeShiftJIS && (StringUtils.ASSUME_SHIFT_JIS || sjisMaxKatakanaWordLength >= 3 || sjisMaxDoubleBytesWordLength >= 3)) {
1489              return StringUtils.SHIFT_JIS;
1490          }
1491          // Distinguishing Shift_JIS and ISO-8859-1 can be a little tough for short words. The crude heuristic is:
1492          // - If we saw
1493          //   - only two consecutive katakana chars in the whole text, or
1494          //   - at least 10% of bytes that could be "upper" not-alphanumeric Latin1,
1495          // - then we conclude Shift_JIS, else ISO-8859-1
1496          if (canBeISO88591 && canBeShiftJIS) {
1497              return (sjisMaxKatakanaWordLength === 2 && sjisKatakanaChars === 2) || isoHighOther * 10 >= length
1498                  ? StringUtils.SHIFT_JIS : StringUtils.ISO88591;
1499          }
1500          // Otherwise, try in order ISO-8859-1, Shift JIS, UTF-8 and fall back to default platform encoding
1501          if (canBeISO88591) {
1502              return StringUtils.ISO88591;
1503          }
1504          if (canBeShiftJIS) {
1505              return StringUtils.SHIFT_JIS;
1506          }
1507          if (canBeUTF8) {
1508              return StringUtils.UTF8;
1509          }
1510          // Otherwise, we take a wild guess with platform encoding
1511          return StringUtils.PLATFORM_DEFAULT_ENCODING;
1512      }
1513      /**
1514       *
1515       * @see https://stackoverflow.com/a/13439711/4367683
1516       *
1517       * @param append The new string to append.
1518       * @param args Argumets values to be formated.
1519       */
1520      static format(append, ...args) {
1521          let i = -1;
1522          function callback(exp, p0, p1, p2, p3, p4) {
1523              if (exp === '%%')
1524                  return '%';
1525              if (args[++i] === undefined)
1526                  return undefined;
1527              exp = p2 ? parseInt(p2.substr(1)) : undefined;
1528              let base = p3 ? parseInt(p3.substr(1)) : undefined;
1529              let val;
1530              switch (p4) {
1531                  case 's':
1532                      val = args[i];
1533                      break;
1534                  case 'c':
1535                      val = args[i][0];
1536                      break;
1537                  case 'f':
1538                      val = parseFloat(args[i]).toFixed(exp);
1539                      break;
1540                  case 'p':
1541                      val = parseFloat(args[i]).toPrecision(exp);
1542                      break;
1543                  case 'e':
1544                      val = parseFloat(args[i]).toExponential(exp);
1545                      break;
1546                  case 'x':
1547                      val = parseInt(args[i]).toString(base ? base : 16);
1548                      break;
1549                  case 'd':
1550                      val = parseFloat(parseInt(args[i], base ? base : 10).toPrecision(exp)).toFixed(0);
1551                      break;
1552              }
1553              val = typeof val === 'object' ? JSON.stringify(val) : (+val).toString(base);
1554              let size = parseInt(p1); /* padding size */
1555              let ch = p1 && (p1[0] + '') === '0' ? '0' : ' '; /* isnull? */
1556              while (val.length < size)
1557                  val = p0 !== undefined ? val + ch : ch + val; /* isminus? */
1558              return val;
1559          }
1560          let regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;
1561          return append.replace(regex, callback);
1562      }
1563      /**
1564       *
1565       */
1566      static getBytes(str, encoding) {
1567          return StringEncoding.encode(str, encoding);
1568      }
1569      /**
1570       * Returns the charcode at the specified index or at index zero.
1571       */
1572      static getCharCode(str, index = 0) {
1573          return str.charCodeAt(index);
1574      }
1575      /**
1576       * Returns char for given charcode
1577       */
1578      static getCharAt(charCode) {
1579          return String.fromCharCode(charCode);
1580      }
1581  }
1582  StringUtils.SHIFT_JIS = CharacterSetECI.SJIS.getName(); // "SJIS"
1583  StringUtils.GB2312 = 'GB2312';
1584  StringUtils.ISO88591 = CharacterSetECI.ISO8859_1.getName(); // "ISO8859_1"
1585  StringUtils.EUC_JP = 'EUC_JP';
1586  StringUtils.UTF8 = CharacterSetECI.UTF8.getName(); // "UTF8"
1587  StringUtils.PLATFORM_DEFAULT_ENCODING = StringUtils.UTF8; // "UTF8"//Charset.defaultCharset().name()
1588  StringUtils.ASSUME_SHIFT_JIS = false;
1589
1590  class StringBuilder {
1591      constructor(value = '') {
1592          this.value = value;
1593      }
1594      enableDecoding(encoding) {
1595          this.encoding = encoding;
1596          return this;
1597      }
1598      append(s) {
1599          if (typeof s === 'string') {
1600              this.value += s.toString();
1601          }
1602          else if (this.encoding) {
1603              // use passed format (fromCharCode will return UTF8 encoding)
1604              this.value += StringUtils.castAsNonUtf8Char(s, this.encoding);
1605          }
1606          else {
1607              // correctly converts from UTF-8, but not other encodings
1608              this.value += String.fromCharCode(s);
1609          }
1610          return this;
1611      }
1612      appendChars(str, offset, len) {
1613          for (let i = offset; offset < offset + len; i++) {
1614              this.append(str[i]);
1615          }
1616          return this;
1617      }
1618      length() {
1619          return this.value.length;
1620      }
1621      charAt(n) {
1622          return this.value.charAt(n);
1623      }
1624      deleteCharAt(n) {
1625          this.value = this.value.substr(0, n) + this.value.substring(n + 1);
1626      }
1627      setCharAt(n, c) {
1628          this.value = this.value.substr(0, n) + c + this.value.substr(n + 1);
1629      }
1630      substring(start, end) {
1631          return this.value.substring(start, end);
1632      }
1633      /**
1634       * @note helper method for RSS Expanded
1635       */
1636      setLengthToZero() {
1637          this.value = '';
1638      }
1639      toString() {
1640          return this.value;
1641      }
1642      insert(n, c) {
1643          this.value = this.value.substring(0, n) + c + this.value.substring(n);
1644      }
1645  }
1646
1647  /*
1648   * Copyright 2007 ZXing authors
1649   *
1650   * Licensed under the Apache License, Version 2.0 (the "License");
1651   * you may not use this file except in compliance with the License.
1652   * You may obtain a copy of the License at
1653   *
1654   *      http://www.apache.org/licenses/LICENSE-2.0
1655   *
1656   * Unless required by applicable law or agreed to in writing, software
1657   * distributed under the License is distributed on an "AS IS" BASIS,
1658   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1659   * See the License for the specific language governing permissions and
1660   * limitations under the License.
1661   */
1662  /*
1662*
1663   * <p>Represents a 2D matrix of bits. In function arguments below, and throughout the common
1664   * module, x is the column position, and y is the row position. The ordering is always x, y.
1665   * The origin is at the top-left.</p>
1666   *
1667   * <p>Internally the bits are represented in a 1-D array of 32-bit ints. However, each row begins
1668   * with a new int. This is done intentionally so that we can copy out a row into a BitArray very
1669   * efficiently.</p>
1670   *
1671   * <p>The ordering of bits is row-major. Within each int, the least significant bits are used first,
1672   * meaning they represent lower x values. This is compatible with BitArray's implementation.</p>
1673   *
1674   * @author Sean Owen
1675   * @author [email protected] (Daniel Switkin)
1676   */
1677  class BitMatrix /*implements Cloneable*/ {
1678      /**
1679       * Creates an empty square {@link BitMatrix}.
1680       *
1681       * @param dimension height and width
1682       */
1683      // public constructor(dimension: number /*int*/) {
1684      //   this(dimension, dimension)
1685      // }
1686      /**
1687       * Creates an empty {@link BitMatrix}.
1688       *
1689       * @param width bit matrix width
1690       * @param height bit matrix height
1691       */
1692      // public constructor(width: number /*int*/, height: number /*int*/) {
1693      //   if (width < 1 || height < 1) {
1694      //     throw new IllegalArgumentException("Both dimensions must be greater than 0")
1695      //   }
1696      //   this.width = width
1697      //   this.height = height
1698      //   this.rowSize = (width + 31) / 32
1699      //   bits = new int[rowSize * height];
1700      // }
1701      constructor(width /*int*/, height /*int*/, rowSize /*int*/, bits) {
1702          this.width = width;
1703          this.height = height;
1704          this.rowSize = rowSize;
1705          this.bits = bits;
1706          if (undefined === height || null === height) {
1707              height = width;
1708          }
1709          this.height = height;
1710          if (width < 1 || height < 1) {
1711              throw new IllegalArgumentException('Both dimensions must be greater than 0');
1712          }
1713          if (undefined === rowSize || null === rowSize) {
1714              rowSize = Math.floor((width + 31) / 32);
1715          }
1716          this.rowSize = rowSize;
1717          if (undefined === bits || null === bits) {
1718              this.bits = new Int32Array(this.rowSize * this.height);
1719          }
1720      }
1721      /**
1722       * Interprets a 2D array of booleans as a {@link BitMatrix}, where "true" means an "on" bit.
1723       *
1724       * @function parse
1725       * @param image bits of the image, as a row-major 2D array. Elements are arrays representing rows
1726       * @return {@link BitMatrix} representation of image
1727       */
1728      static parseFromBooleanArray(image) {
1729          const height = image.length;
1730          const width = image[0].length;
1731          const bits = new BitMatrix(width, height);
1732          for (let i = 0; i < height; i++) {
1733              const imageI = image[i];
1734              for (let j = 0; j < width; j++) {
1735                  if (imageI[j]) {
1736                      bits.set(j, i);
1737                  }
1738              }
1739          }
1740          return bits;
1741      }
1742      /**
1743       *
1744       * @function parse
1745       * @param stringRepresentation
1746       * @param setString
1747       * @param unsetString
1748       */
1749      static parseFromString(stringRepresentation, setString, unsetString) {
1750          if (stringRepresentation === null) {
vendor: 5,891 bytes, lines 1751-1898
1751              throw new IllegalArgumentException('stringRepresentation cannot be null');
1752          }
1753          const bits = new Array(stringRepresentation.length);
1754          let bitsPos = 0;
1755          let rowStartPos = 0;
1756          let rowLength = -1;
1757          let nRows = 0;
1758          let pos = 0;
1759          while (pos < stringRepresentation.length) {
1760              if (stringRepresentation.charAt(pos) === '\n' ||
1761                  stringRepresentation.charAt(pos) === '\r') {
1762                  if (bitsPos > rowStartPos) {
1763                      if (rowLength === -1) {
1764                          rowLength = bitsPos - rowStartPos;
1765                      }
1766                      else if (bitsPos - rowStartPos !== rowLength) {
1767                          throw new IllegalArgumentException('row lengths do not match');
1768                      }
1769                      rowStartPos = bitsPos;
1770                      nRows++;
1771                  }
1772                  pos++;
1773              }
1774              else if (stringRepresentation.substring(pos, pos + setString.length) === setString) {
1775                  pos += setString.length;
1776                  bits[bitsPos] = true;
1777                  bitsPos++;
1778              }
1779              else if (stringRepresentation.substring(pos, pos + unsetString.length) === unsetString) {
1780                  pos += unsetString.length;
1781                  bits[bitsPos] = false;
1782                  bitsPos++;
1783              }
1784              else {
1785                  throw new IllegalArgumentException('illegal character encountered: ' + stringRepresentation.substring(pos));
1786              }
1787          }
1788          // no EOL at end?
1789          if (bitsPos > rowStartPos) {
1790              if (rowLength === -1) {
1791                  rowLength = bitsPos - rowStartPos;
1792              }
1793              else if (bitsPos - rowStartPos !== rowLength) {
1794                  throw new IllegalArgumentException('row lengths do not match');
1795              }
1796              nRows++;
1797          }
1798          const matrix = new BitMatrix(rowLength, nRows);
1799          for (let i = 0; i < bitsPos; i++) {
1800              if (bits[i]) {
1801                  matrix.set(Math.floor(i % rowLength), Math.floor(i / rowLength));
1802              }
1803          }
1804          return matrix;
1805      }
1806      /**
1807       * <p>Gets the requested bit, where true means black.</p>
1808       *
1809       * @param x The horizontal component (i.e. which column)
1810       * @param y The vertical component (i.e. which row)
1811       * @return value of given bit in matrix
1812       */
1813      get(x /*int*/, y /*int*/) {
1814          const offset = y * this.rowSize + Math.floor(x / 32);
1815          return ((this.bits[offset] >>> (x & 0x1f)) & 1) !== 0;
1816      }
1817      /**
1818       * <p>Sets the given bit to true.</p>
1819       *
1820       * @param x The horizontal component (i.e. which column)
1821       * @param y The vertical component (i.e. which row)
1822       */
1823      set(x /*int*/, y /*int*/) {
1824          const offset = y * this.rowSize + Math.floor(x / 32);
1825          this.bits[offset] |= (1 << (x & 0x1f)) & 0xFFFFFFFF;
1826      }
1827      unset(x /*int*/, y /*int*/) {
1828          const offset = y * this.rowSize + Math.floor(x / 32);
1829          this.bits[offset] &= ~((1 << (x & 0x1f)) & 0xFFFFFFFF);
1830      }
1831      /**
1832       * <p>Flips the given bit.</p>
1833       *
1834       * @param x The horizontal component (i.e. which column)
1835       * @param y The vertical component (i.e. which row)
1836       */
1837      flip(x /*int*/, y /*int*/) {
1838          const offset = y * this.rowSize + Math.floor(x / 32);
1839          this.bits[offset] ^= ((1 << (x & 0x1f)) & 0xFFFFFFFF);
1840      }
1841      /**
1842       * Exclusive-or (XOR): Flip the bit in this {@code BitMatrix} if the corresponding
1843       * mask bit is set.
1844       *
1845       * @param mask XOR mask
1846       */
1847      xor(mask) {
1848          if (this.width !== mask.getWidth() || this.height !== mask.getHeight()
1849              || this.rowSize !== mask.getRowSize()) {
1850              throw new IllegalArgumentException('input matrix dimensions do not match');
1851          }
1852          const rowArray = new BitArray(Math.floor(this.width / 32) + 1);
1853          const rowSize = this.rowSize;
1854          const bits = this.bits;
1855          for (let y = 0, height = this.height; y < height; y++) {
1856              const offset = y * rowSize;
1857              const row = mask.getRow(y, rowArray).getBitArray();
1858              for (let x = 0; x < rowSize; x++) {
1859                  bits[offset + x] ^= row[x];
1860              }
1861          }
1862      }
1863      /**
1864       * Clears all bits (sets to false).
1865       */
1866      clear() {
1867          const bits = this.bits;
1868          const max = bits.length;
1869          for (let i = 0; i < max; i++) {
1870              bits[i] = 0;
1871          }
1872      }
1873      /**
1874       * <p>Sets a square region of the bit matrix to true.</p>
1875       *
1876       * @param left The horizontal position to begin at (inclusive)
1877       * @param top The vertical position to begin at (inclusive)
1878       * @param width The width of the region
1879       * @param height The height of the region
1880       */
1881      setRegion(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
1882          if (top < 0 || left < 0) {
1883              throw new IllegalArgumentException('Left and top must be nonnegative');
1884          }
1885          if (height < 1 || width < 1) {
1886              throw new IllegalArgumentException('Height and width must be at least 1');
1887          }
1888          const right = left + width;
1889          const bottom = top + height;
1890          if (bottom > this.height || right > this.width) {
1891              throw new IllegalArgumentException('The region must fit inside the matrix');
1892          }
1893          const rowSize = this.rowSize;
1894          const bits = this.bits;
1895          for (let y = top; y < bottom; y++) {
1896              const offset = y * rowSize;
1897              for (let x = left; x < right; x++) {
1898                  bits[offset + Math.floor(x / 32
vendor: 8,852 bytes, lines 1898-2148
1898)] |= ((1 << (x & 0x1f)) & 0xFFFFFFFF);
1899              }
1900          }
1901      }
1902      /**
1903       * A fast method to retrieve one row of data from the matrix as a BitArray.
1904       *
1905       * @param y The row to retrieve
1906       * @param row An optional caller-allocated BitArray, will be allocated if null or too small
1907       * @return The resulting BitArray - this reference should always be used even when passing
1908       *         your own row
1909       */
1910      getRow(y /*int*/, row) {
1911          if (row === null || row === undefined || row.getSize() < this.width) {
1912              row = new BitArray(this.width);
1913          }
1914          else {
1915              row.clear();
1916          }
1917          const rowSize = this.rowSize;
1918          const bits = this.bits;
1919          const offset = y * rowSize;
1920          for (let x = 0; x < rowSize; x++) {
1921              row.setBulk(x * 32, bits[offset + x]);
1922          }
1923          return row;
1924      }
1925      /**
1926       * @param y row to set
1927       * @param row {@link BitArray} to copy from
1928       */
1929      setRow(y /*int*/, row) {
1930          System.arraycopy(row.getBitArray(), 0, this.bits, y * this.rowSize, this.rowSize);
1931      }
1932      /**
1933       * Modifies this {@code BitMatrix} to represent the same but rotated 180 degrees
1934       */
1935      rotate180() {
1936          const width = this.getWidth();
1937          const height = this.getHeight();
1938          let topRow = new BitArray(width);
1939          let bottomRow = new BitArray(width);
1940          for (let i = 0, length = Math.floor((height + 1) / 2); i < length; i++) {
1941              topRow = this.getRow(i, topRow);
1942              bottomRow = this.getRow(height - 1 - i, bottomRow);
1943              topRow.reverse();
1944              bottomRow.reverse();
1945              this.setRow(i, bottomRow);
1946              this.setRow(height - 1 - i, topRow);
1947          }
1948      }
1949      /**
1950       * This is useful in detecting the enclosing rectangle of a 'pure' barcode.
1951       *
1952       * @return {@code left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white
1953       */
1954      getEnclosingRectangle() {
1955          const width = this.width;
1956          const height = this.height;
1957          const rowSize = this.rowSize;
1958          const bits = this.bits;
1959          let left = width;
1960          let top = height;
1961          let right = -1;
1962          let bottom = -1;
1963          for (let y = 0; y < height; y++) {
1964              for (let x32 = 0; x32 < rowSize; x32++) {
1965                  const theBits = bits[y * rowSize + x32];
1966                  if (theBits !== 0) {
1967                      if (y < top) {
1968                          top = y;
1969                      }
1970                      if (y > bottom) {
1971                          bottom = y;
1972                      }
1973                      if (x32 * 32 < left) {
1974                          let bit = 0;
1975                          while (((theBits << (31 - bit)) & 0xFFFFFFFF) === 0) {
1976                              bit++;
1977                          }
1978                          if ((x32 * 32 + bit) < left) {
1979                              left = x32 * 32 + bit;
1980                          }
1981                      }
1982                      if (x32 * 32 + 31 > right) {
1983                          let bit = 31;
1984                          while ((theBits >>> bit) === 0) {
1985                              bit--;
1986                          }
1987                          if ((x32 * 32 + bit) > right) {
1988                              right = x32 * 32 + bit;
1989                          }
1990                      }
1991                  }
1992              }
1993          }
1994          if (right < left || bottom < top) {
1995              return null;
1996          }
1997          return Int32Array.from([left, top, right - left + 1, bottom - top + 1]);
1998      }
1999      /**
2000       * This is useful in detecting a corner of a 'pure' barcode.
2001       *
2002       * @return {@code x,y} coordinate of top-left-most 1 bit, or null if it is all white
2003       */
2004      getTopLeftOnBit() {
2005          const rowSize = this.rowSize;
2006          const bits = this.bits;
2007          let bitsOffset = 0;
2008          while (bitsOffset < bits.length && bits[bitsOffset] === 0) {
2009              bitsOffset++;
2010          }
2011          if (bitsOffset === bits.length) {
2012              return null;
2013          }
2014          const y = bitsOffset / rowSize;
2015          let x = (bitsOffset % rowSize) * 32;
2016          const theBits = bits[bitsOffset];
2017          let bit = 0;
2018          while (((theBits << (31 - bit)) & 0xFFFFFFFF) === 0) {
2019              bit++;
2020          }
2021          x += bit;
2022          return Int32Array.from([x, y]);
2023      }
2024      getBottomRightOnBit() {
2025          const rowSize = this.rowSize;
2026          const bits = this.bits;
2027          let bitsOffset = bits.length - 1;
2028          while (bitsOffset >= 0 && bits[bitsOffset] === 0) {
2029              bitsOffset--;
2030          }
2031          if (bitsOffset < 0) {
2032              return null;
2033          }
2034          const y = Math.floor(bitsOffset / rowSize);
2035          let x = Math.floor(bitsOffset % rowSize) * 32;
2036          const theBits = bits[bitsOffset];
2037          let bit = 31;
2038          while ((theBits >>> bit) === 0) {
2039              bit--;
2040          }
2041          x += bit;
2042          return Int32Array.from([x, y]);
2043      }
2044      /**
2045       * @return The width of the matrix
2046       */
2047      getWidth() {
2048          return this.width;
2049      }
2050      /**
2051       * @return The height of the matrix
2052       */
2053      getHeight() {
2054          return this.height;
2055      }
2056      /**
2057       * @return The row size of the matrix
2058       */
2059      getRowSize() {
2060          return this.rowSize;
2061      }
2062      /*@Override*/
2063      equals(o) {
2064          if (!(o instanceof BitMatrix)) {
2065              return false;
2066          }
2067          const other = o;
2068          return this.width === other.width && this.height === other.height && this.rowSize === other.rowSize &&
2069              Arrays.equals(this.bits, other.bits);
2070      }
2071      /*@Override*/
2072      hashCode() {
2073          let hash = this.width;
2074          hash = 31 * hash + this.width;
2075          hash = 31 * hash + this.height;
2076          hash = 31 * hash + this.rowSize;
2077          hash = 31 * hash + Arrays.hashCode(this.bits);
2078          return hash;
2079      }
2080      /**
2081       * @return string representation using "X" for set and " " for unset bits
2082       */
2083      /*@Override*/
2084      // public toString(): string {
2085      //   return toString(": "X, "  ")
2086      // }
2087      /**
2088       * @param setString representation of a set bit
2089       * @param unsetString representation of an unset bit
2090       * @return string representation of entire matrix utilizing given strings
2091       */
2092      // public toString(setString: string = "X ", unsetString: string = "  "): string {
2093      //   return this.buildToString(setString, unsetString, "\n")
2094      // }
2095      /**
2096       * @param setString representation of a set bit
2097       * @param unsetString representation of an unset bit
2098       * @param lineSeparator newline character in string representation
2099       * @return string representation of entire matrix utilizing given strings and line separator
2100       * @deprecated call {@link #toString(String,String)} only, which uses \n line separator always
2101       */
2102      // @Deprecated
2103      toString(setString = 'X ', unsetString = '  ', lineSeparator = '\n') {
2104          return this.buildToString(setString, unsetString, lineSeparator);
2105      }
2106      buildToString(setString, unsetString, lineSeparator) {
2107          let result = new StringBuilder();
2108          // result.append(lineSeparator);
2109          for (let y = 0, height = this.height; y < height; y++) {
2110              for (let x = 0, width = this.width; x < width; x++) {
2111                  result.append(this.get(x, y) ? setString : unsetString);
2112              }
2113              result.append(lineSeparator);
2114          }
2115          return result.toString();
2116      }
2117      /*@Override*/
2118      clone() {
2119          return new BitMatrix(this.width, this.height, this.rowSize, this.bits.slice());
2120      }
2121  }
2122
2123  /**
2124   * Custom Error class of type Exception.
2125   */
2126  class NotFoundException extends Exception {
2127      static getNotFoundInstance() {
2128          return new NotFoundException();
2129      }
2130  }
2131  NotFoundException.kind = 'NotFoundException';
2132
2133  /*
2134   * Copyright 2009 ZXing authors
2135   *
2136   * Licensed under the Apache License, Version 2.0 (the "License");
2137   * you may not use this file except in compliance with the License.
2138   * You may obtain a copy of the License at
2139   *
2140   *      http://www.apache.org/licenses/LICENSE-2.0
2141   *
2142   * Unless required by applicable law or agreed to in writing, software
2143   * distributed under the License is distributed on an "AS IS" BASIS,
2144   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2145   * See the License for the specific language governing permissions and
2146   * limitations under the License.
2147   */
2148  /*
2148*
2149   * This Binarizer implementation uses the old ZXing global histogram approach. It is suitable
2150   * for low-end mobile devices which don't have enough CPU or memory to use a local thresholding
2151   * algorithm. However, because it picks a global black point, it cannot handle difficult shadows
2152   * and gradients.
2153   *
2154   * Faster mobile devices and all desktop applications should probably use HybridBinarizer instead.
2155   *
2156   * @author [email protected] (Daniel Switkin)
2157   * @author Sean Owen
2158   */
2159  class GlobalHistogramBinarizer extends Binarizer {
2160      constructor(source) {
2161          super(source);
2162          this.luminances = GlobalHistogramBinarizer.EMPTY;
2163          this.buckets = new Int32Array(GlobalHistogramBinarizer.LUMINANCE_BUCKETS);
2164      }
2165      // Applies simple sharpening to the row data to improve performance of the 1D Readers.
2166      /*@Override*/
2167      getBlackRow(y /*int*/, row) {
2168          const source = this.getLuminanceSource();
2169          const width = source.getWidth();
2170          if (row === undefined || row === null || row.getSize() < width) {
2171              row = new BitArray(width);
2172          }
2173          else {
2174              row.clear();
2175          }
2176          this.initArrays(width);
2177          const localLuminances = source.getRow(y, this.luminances);
2178          const localBuckets = this.buckets;
2179          for (let x = 0; x < width; x++) {
2180              localBuckets[(localLuminances[x] & 0xff) >> GlobalHistogramBinarizer.LUMINANCE_SHIFT]++;
2181          }
2182          const blackPoint = GlobalHistogramBinarizer.estimateBlackPoint(localBuckets);
2183          if (width < 3) {
2184              // Special case for very small images
2185              for (let x = 0; x < width; x++) {
2186                  if ((localLuminances[x] & 0xff) < blackPoint) {
2187                      row.set(x);
2188                  }
2189              }
2190          }
2191          else {
2192              let left = localLuminances[0] & 0xff;
2193              let center = localLuminances[1] & 0xff;
2194              for (let x = 1; x < width - 1; x++) {
2195                  const right = localLuminances[x + 1] & 0xff;
2196                  // A simple -1 4 -1 box filter with a weight of 2.
2197                  if (((center * 4) - left - right) / 2 < blackPoint) {
2198                      row.set(x);
2199                  }
2200                  left = center;
2201                  center = right;
2202              }
2203          }
2204          return row;
2205      }
2206      // Does not sharpen the data, as this call is intended to only be used by 2D Readers.
2207      /*@Override*/
2208      getBlackMatrix() {
2209          const source = this.getLuminanceSource();
2210          const width = source.getWidth();
2211          const height = source.getHeight();
2212          const matrix = new BitMatrix(width, height);
2213          // Quickly calculates the histogram by sampling four rows from the image. This proved to be
2214          // more robust on the blackbox tests than sampling a diagonal as we used to do.
2215          this.initArrays(width);
2216          const localBuckets = this.buckets;
2217          for (let y = 1; y < 5; y++) {
2218              const row = Math.floor((height * y) / 5);
2219              const localLuminances = source.getRow(row, this.luminances);
2220              const right = Math.floor((width * 4) / 5);
2221              for (let x = Math.floor(width / 5); x < right; x++) {
2222                  const pixel = localLuminances[x] & 0xff;
vendor: 1,342 bytes, lines 2223-2253
2223                  localBuckets[pixel >> GlobalHistogramBinarizer.LUMINANCE_SHIFT]++;
2224              }
2225          }
2226          const blackPoint = GlobalHistogramBinarizer.estimateBlackPoint(localBuckets);
2227          // We delay reading the entire image luminance until the black point estimation succeeds.
2228          // Although we end up reading four rows twice, it is consistent with our motto of
2229          // "fail quickly" which is necessary for continuous scanning.
2230          const localLuminances = source.getMatrix();
2231          for (let y = 0; y < height; y++) {
2232              const offset = y * width;
2233              for (let x = 0; x < width; x++) {
2234                  const pixel = localLuminances[offset + x] & 0xff;
2235                  if (pixel < blackPoint) {
2236                      matrix.set(x, y);
2237                  }
2238              }
2239          }
2240          return matrix;
2241      }
2242      /*@Override*/
2243      createBinarizer(source) {
2244          return new GlobalHistogramBinarizer(source);
2245      }
2246      initArrays(luminanceSize /*int*/) {
2247          if (this.luminances.length < luminanceSize) {
2248              this.luminances = new Uint8ClampedArray(luminanceSize);
2249          }
2250          const buckets = this.buckets;
2251          for (let x = 0; x < GlobalHistogramBinarizer.LUMINANCE_BUCKETS; x++) {
2252              buckets[x] = 0;
2253          }
vendor: 18,979 bytes, lines 2253-2660
2253
2254      }
2255      static estimateBlackPoint(buckets) {
2256          // Find the tallest peak in the histogram.
2257          const numBuckets = buckets.length;
2258          let maxBucketCount = 0;
2259          let firstPeak = 0;
2260          let firstPeakSize = 0;
2261          for (let x = 0; x < numBuckets; x++) {
2262              if (buckets[x] > firstPeakSize) {
2263                  firstPeak = x;
2264                  firstPeakSize = buckets[x];
2265              }
2266              if (buckets[x] > maxBucketCount) {
2267                  maxBucketCount = buckets[x];
2268              }
2269          }
2270          // Find the second-tallest peak which is somewhat far from the tallest peak.
2271          let secondPeak = 0;
2272          let secondPeakScore = 0;
2273          for (let x = 0; x < numBuckets; x++) {
2274              const distanceToBiggest = x - firstPeak;
2275              // Encourage more distant second peaks by multiplying by square of distance.
2276              const score = buckets[x] * distanceToBiggest * distanceToBiggest;
2277              if (score > secondPeakScore) {
2278                  secondPeak = x;
2279                  secondPeakScore = score;
2280              }
2281          }
2282          // Make sure firstPeak corresponds to the black peak.
2283          if (firstPeak > secondPeak) {
2284              const temp = firstPeak;
2285              firstPeak = secondPeak;
2286              secondPeak = temp;
2287          }
2288          // If there is too little contrast in the image to pick a meaningful black point, throw rather
2289          // than waste time trying to decode the image, and risk false positives.
2290          if (secondPeak - firstPeak <= numBuckets / 16) {
2291              throw new NotFoundException();
2292          }
2293          // Find a valley between them that is low and closer to the white peak.
2294          let bestValley = secondPeak - 1;
2295          let bestValleyScore = -1;
2296          for (let x = secondPeak - 1; x > firstPeak; x--) {
2297              const fromFirst = x - firstPeak;
2298              const score = fromFirst * fromFirst * (secondPeak - x) * (maxBucketCount - buckets[x]);
2299              if (score > bestValleyScore) {
2300                  bestValley = x;
2301                  bestValleyScore = score;
2302              }
2303          }
2304          return bestValley << GlobalHistogramBinarizer.LUMINANCE_SHIFT;
2305      }
2306  }
2307  GlobalHistogramBinarizer.LUMINANCE_BITS = 5;
2308  GlobalHistogramBinarizer.LUMINANCE_SHIFT = 8 - GlobalHistogramBinarizer.LUMINANCE_BITS;
2309  GlobalHistogramBinarizer.LUMINANCE_BUCKETS = 1 << GlobalHistogramBinarizer.LUMINANCE_BITS;
2310  GlobalHistogramBinarizer.EMPTY = Uint8ClampedArray.from([0]);
2311
2312  /*
2313   * Copyright 2009 ZXing authors
2314   *
2315   * Licensed under the Apache License, Version 2.0 (the "License");
2316   * you may not use this file except in compliance with the License.
2317   * You may obtain a copy of the License at
2318   *
2319   *      http://www.apache.org/licenses/LICENSE-2.0
2320   *
2321   * Unless required by applicable law or agreed to in writing, software
2322   * distributed under the License is distributed on an "AS IS" BASIS,
2323   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2324   * See the License for the specific language governing permissions and
2325   * limitations under the License.
2326   */
2327  /**
2328   * This class implements a local thresholding algorithm, which while slower than the
2329   * GlobalHistogramBinarizer, is fairly efficient for what it does. It is designed for
2330   * high frequency images of barcodes with black data on white backgrounds. For this application,
2331   * it does a much better job than a global blackpoint with severe shadows and gradients.
2332   * However it tends to produce artifacts on lower frequency images and is therefore not
2333   * a good general purpose binarizer for uses outside ZXing.
2334   *
2335   * This class extends GlobalHistogramBinarizer, using the older histogram approach for 1D readers,
2336   * and the newer local approach for 2D readers. 1D decoding using a per-row histogram is already
2337   * inherently local, and only fails for horizontal gradients. We can revisit that problem later,
2338   * but for now it was not a win to use local blocks for 1D.
2339   *
2340   * This Binarizer is the default for the unit tests and the recommended class for library users.
2341   *
2342   * @author [email protected] (Daniel Switkin)
2343   */
2344  class HybridBinarizer extends GlobalHistogramBinarizer {
2345      constructor(source) {
2346          super(source);
2347          this.matrix = null;
2348      }
2349      /**
2350       * Calculates the final BitMatrix once for all requests. This could be called once from the
2351       * constructor instead, but there are some advantages to doing it lazily, such as making
2352       * profiling easier, and not doing heavy lifting when callers don't expect it.
2353       */
2354      /*@Override*/
2355      getBlackMatrix() {
2356          if (this.matrix !== null) {
2357              return this.matrix;
2358          }
2359          const source = this.getLuminanceSource();
2360          const width = source.getWidth();
2361          const height = source.getHeight();
2362          if (width >= HybridBinarizer.MINIMUM_DIMENSION && height >= HybridBinarizer.MINIMUM_DIMENSION) {
2363              const luminances = source.getMatrix();
2364              let subWidth = width >> HybridBinarizer.BLOCK_SIZE_POWER;
2365              if ((width & HybridBinarizer.BLOCK_SIZE_MASK) !== 0) {
2366                  subWidth++;
2367              }
2368              let subHeight = height >> HybridBinarizer.BLOCK_SIZE_POWER;
2369              if ((height & HybridBinarizer.BLOCK_SIZE_MASK) !== 0) {
2370                  subHeight++;
2371              }
2372              const blackPoints = HybridBinarizer.calculateBlackPoints(luminances, subWidth, subHeight, width, height);
2373              const newMatrix = new BitMatrix(width, height);
2374              HybridBinarizer.calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
2375              this.matrix = newMatrix;
2376          }
2377          else {
2378              // If the image is too small, fall back to the global histogram approach.
2379              this.matrix = super.getBlackMatrix();
2380          }
2381          return this.matrix;
2382      }
2383      /*@Override*/
2384      createBinarizer(source) {
2385          return new HybridBinarizer(source);
2386      }
2387      /**
2388       * For each block in the image, calculate the average black point using a 5x5 grid
2389       * of the blocks around it. Also handles the corner cases (fractional blocks are computed based
2390       * on the last pixels in the row/column which are also used in the previous block).
2391       */
2392      static calculateThresholdForBlock(luminances, subWidth /*int*/, subHeight /*int*/, width /*int*/, height /*int*/, blackPoints, matrix) {
2393          const maxYOffset = height - HybridBinarizer.BLOCK_SIZE;
2394          const maxXOffset = width - HybridBinarizer.BLOCK_SIZE;
2395          for (let y = 0; y < subHeight; y++) {
2396              let yoffset = y << HybridBinarizer.BLOCK_SIZE_POWER;
2397              if (yoffset > maxYOffset) {
2398                  yoffset = maxYOffset;
2399              }
2400              const top = HybridBinarizer.cap(y, 2, subHeight - 3);
2401              for (let x = 0; x < subWidth; x++) {
2402                  let xoffset = x << HybridBinarizer.BLOCK_SIZE_POWER;
2403                  if (xoffset > maxXOffset) {
2404                      xoffset = maxXOffset;
2405                  }
2406                  const left = HybridBinarizer.cap(x, 2, subWidth - 3);
2407                  let sum = 0;
2408                  for (let z = -2; z <= 2; z++) {
2409                      const blackRow = blackPoints[top + z];
2410                      sum += blackRow[left - 2] + blackRow[left - 1] + blackRow[left] + blackRow[left + 1] + blackRow[left + 2];
2411                  }
2412                  const average = sum / 25;
2413                  HybridBinarizer.thresholdBlock(luminances, xoffset, yoffset, average, width, matrix);
2414              }
2415          }
2416      }
2417      static cap(value /*int*/, min /*int*/, max /*int*/) {
2418          return value < min ? min : value > max ? max : value;
2419      }
2420      /**
2421       * Applies a single threshold to a block of pixels.
2422       */
2423      static thresholdBlock(luminances, xoffset /*int*/, yoffset /*int*/, threshold /*int*/, stride /*int*/, matrix) {
2424          for (let y = 0, offset = yoffset * stride + xoffset; y < HybridBinarizer.BLOCK_SIZE; y++, offset += stride) {
2425              for (let x = 0; x < HybridBinarizer.BLOCK_SIZE; x++) {
2426                  // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.
2427                  if ((luminances[offset + x] & 0xFF) <= threshold) {
2428                      matrix.set(xoffset + x, yoffset + y);
2429                  }
2430              }
2431          }
2432      }
2433      /**
2434       * Calculates a single black point for each block of pixels and saves it away.
2435       * See the following thread for a discussion of this algorithm:
2436       *  http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
2437       */
2438      static calculateBlackPoints(luminances, subWidth /*int*/, subHeight /*int*/, width /*int*/, height /*int*/) {
2439          const maxYOffset = height - HybridBinarizer.BLOCK_SIZE;
2440          const maxXOffset = width - HybridBinarizer.BLOCK_SIZE;
2441          // tslint:disable-next-line:whitespace
2442          const blackPoints = new Array(subHeight); // subWidth
2443          for (let y = 0; y < subHeight; y++) {
2444              blackPoints[y] = new Int32Array(subWidth);
2445              let yoffset = y << HybridBinarizer.BLOCK_SIZE_POWER;
2446              if (yoffset > maxYOffset) {
2447                  yoffset = maxYOffset;
2448              }
2449              for (let x = 0; x < subWidth; x++) {
2450                  let xoffset = x << HybridBinarizer.BLOCK_SIZE_POWER;
2451                  if (xoffset > maxXOffset) {
2452                      xoffset = maxXOffset;
2453                  }
2454                  let sum = 0;
2455                  let min = 0xFF;
2456                  let max = 0;
2457                  for (let yy = 0, offset = yoffset * width + xoffset; yy < HybridBinarizer.BLOCK_SIZE; yy++, offset += width) {
2458                      for (let xx = 0; xx < HybridBinarizer.BLOCK_SIZE; xx++) {
2459                          const pixel = luminances[offset + xx] & 0xFF;
2460                          sum += pixel;
2461                          // still looking for good contrast
2462                          if (pixel < min) {
2463                              min = pixel;
2464                          }
2465                          if (pixel > max) {
2466                              max = pixel;
2467                          }
2468                      }
2469                      // short-circuit min/max tests once dynamic range is met
2470                      if (max - min > HybridBinarizer.MIN_DYNAMIC_RANGE) {
2471                          // finish the rest of the rows quickly
2472                          for (yy++, offset += width; yy < HybridBinarizer.BLOCK_SIZE; yy++, offset += width) {
2473                              for (let xx = 0; xx < HybridBinarizer.BLOCK_SIZE; xx++) {
2474                                  sum += luminances[offset + xx] & 0xFF;
2475                              }
2476                          }
2477                      }
2478                  }
2479                  // The default estimate is the average of the values in the block.
2480                  let average = sum >> (HybridBinarizer.BLOCK_SIZE_POWER * 2);
2481                  if (max - min <= HybridBinarizer.MIN_DYNAMIC_RANGE) {
2482                      // If variation within the block is low, assume this is a block with only light or only
2483                      // dark pixels. In that case we do not want to use the average, as it would divide this
2484                      // low contrast area into black and white pixels, essentially creating data out of noise.
2485                      //
2486                      // The default assumption is that the block is light/background. Since no estimate for
2487                      // the level of dark pixels exists locally, use half the min for the block.
2488                      average = min / 2;
2489                      if (y > 0 && x > 0) {
2490                          // Correct the "white background" assumption for blocks that have neighbors by comparing
2491                          // the pixels in this block to the previously calculated black points. This is based on
2492                          // the fact that dark barcode symbology is always surrounded by some amount of light
2493                          // background for which reasonable black point estimates were made. The bp estimated at
2494                          // the boundaries is used for the interior.
2495                          // The (min < bp) is arbitrary but works better than other heuristics that were tried.
2496                          const averageNeighborBlackPoint = (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) + blackPoints[y - 1][x - 1]) / 4;
2497                          if (min < averageNeighborBlackPoint) {
2498                              average = averageNeighborBlackPoint;
2499                          }
2500                      }
2501                  }
2502                  blackPoints[y][x] = average;
2503              }
2504          }
2505          return blackPoints;
2506      }
2507  }
2508  // This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.
2509  // So this is the smallest dimension in each axis we can accept.
2510  HybridBinarizer.BLOCK_SIZE_POWER = 3;
2511  HybridBinarizer.BLOCK_SIZE = 1 << HybridBinarizer.BLOCK_SIZE_POWER; // ...0100...00
2512  HybridBinarizer.BLOCK_SIZE_MASK = HybridBinarizer.BLOCK_SIZE - 1; // ...0011...11
2513  HybridBinarizer.MINIMUM_DIMENSION = HybridBinarizer.BLOCK_SIZE * 5;
2514  HybridBinarizer.MIN_DYNAMIC_RANGE = 24;
2515
2516  /*
2517   * Copyright 2009 ZXing authors
2518   *
2519   * Licensed under the Apache License, Version 2.0 (the "License");
2520   * you may not use this file except in compliance with the License.
2521   * You may obtain a copy of the License at
2522   *
2523   *      http://www.apache.org/licenses/LICENSE-2.0
2524   *
2525   * Unless required by applicable law or agreed to in writing, software
2526   * distributed under the License is distributed on an "AS IS" BASIS,
2527   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2528   * See the License for the specific language governing permissions and
2529   * limitations under the License.
2530   */
2531  /*namespace com.google.zxing {*/
2532  /**
2533   * The purpose of this class hierarchy is to abstract different bitmap implementations across
2534   * platforms into a standard interface for requesting greyscale luminance values. The interface
2535   * only provides immutable methods; therefore crop and rotation create copies. This is to ensure
2536   * that one Reader does not modify the original luminance source and leave it in an unknown state
2537   * for other Readers in the chain.
2538   *
2539   * @author [email protected] (Daniel Switkin)
2540   */
2541  class LuminanceSource {
2542      constructor(width /*int*/, height /*int*/) {
2543          this.width = width;
2544          this.height = height;
2545      }
2546      /**
2547       * @return The width of the bitmap.
2548       */
2549      getWidth() {
2550          return this.width;
2551      }
2552      /**
2553       * @return The height of the bitmap.
2554       */
2555      getHeight() {
2556          return this.height;
2557      }
2558      /**
2559       * @return Whether this subclass supports cropping.
2560       */
2561      isCropSupported() {
2562          return false;
2563      }
2564      /**
2565       * Returns a new object with cropped image data. Implementations may keep a reference to the
2566       * original data rather than a copy. Only callable if isCropSupported() is true.
2567       *
2568       * @param left The left coordinate, which must be in [0,getWidth())
2569       * @param top The top coordinate, which must be in [0,getHeight())
2570       * @param width The width of the rectangle to crop.
2571       * @param height The height of the rectangle to crop.
2572       * @return A cropped version of this object.
2573       */
2574      crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
2575          throw new UnsupportedOperationException('This luminance source does not support cropping.');
2576      }
2577      /**
2578       * @return Whether this subclass supports counter-clockwise rotation.
2579       */
2580      isRotateSupported() {
2581          return false;
2582      }
2583      /**
2584       * Returns a new object with rotated image data by 90 degrees counterclockwise.
2585       * Only callable if {@link #isRotateSupported()} is true.
2586       *
2587       * @return A rotated version of this object.
2588       */
2589      rotateCounterClockwise() {
2590          throw new UnsupportedOperationException('This luminance source does not support rotation by 90 degrees.');
2591      }
2592      /**
2593       * Returns a new object with rotated image data by 45 degrees counterclockwise.
2594       * Only callable if {@link #isRotateSupported()} is true.
2595       *
2596       * @return A rotated version of this object.
2597       */
2598      rotateCounterClockwise45() {
2599          throw new UnsupportedOperationException('This luminance source does not support rotation by 45 degrees.');
2600      }
2601      /*@Override*/
2602      toString() {
2603          const row = new Uint8ClampedArray(this.width);
2604          let result = new StringBuilder();
2605          for (let y = 0; y < this.height; y++) {
2606              const sourceRow = this.getRow(y, row);
2607              for (let x = 0; x < this.width; x++) {
2608                  const luminance = sourceRow[x] & 0xFF;
2609                  let c;
2610                  if (luminance < 0x40) {
2611                      c = '#';
2612                  }
2613                  else if (luminance < 0x80) {
2614                      c = '+';
2615                  }
2616                  else if (luminance < 0xC0) {
2617                      c = '.';
2618                  }
2619                  else {
2620                      c = ' ';
2621                  }
2622                  result.append(c);
2623              }
2624              result.append('\n');
2625          }
2626          return result.toString();
2627      }
2628  }
2629
2630  /*
2631   * Copyright 2009 ZXing authors
2632   *
2633   * Licensed under the Apache License, Version 2.0 (the "License");
2634   * you may not use this file except in compliance with the License.
2635   * You may obtain a copy of the License at
2636   *
2637   *      http://www.apache.org/licenses/LICENSE-2.0
2638   *
2639   * Unless required by applicable law or agreed to in writing, software
2640   * distributed under the License is distributed on an "AS IS" BASIS,
2641   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2642   * See the License for the specific language governing permissions and
2643   * limitations under the License.
2644   */
2645  /*namespace com.google.zxing {*/
2646  /**
2647   * A wrapper implementation of {@link LuminanceSource} which inverts the luminances it returns -- black becomes
2648   * white and vice versa, and each value becomes (255-value).
2649   *
2650   * @author Sean Owen
2651   */
2652  class InvertedLuminanceSource extends LuminanceSource {
2653      constructor(delegate) {
2654          super(delegate.getWidth(), delegate.getHeight());
2655          this.delegate = delegate;
2656      }
2657      /*@Override*/
2658      getRow(y /*int*/, row) {
2659          const sourceRow = this.delegate.getRow(y, row);
2660          const width 
2660= this.getWidth();
2661          for (let i = 0; i < width; i++) {
2662              sourceRow[i] = /*(byte)*/ (255 - (sourceRow[i] & 0xFF));
2663          }
2664          return sourceRow;
2665      }
2666      /*@Override*/
2667      getMatrix() {
2668          const matrix = this.delegate.getMatrix();
2669          const length = this.getWidth() * this.getHeight();
2670          const invertedMatrix = new Uint8ClampedArray(length);
2671          for (let i = 0; i < length; i++) {
2672              invertedMatrix[i] = /*(byte)*/ (255 - (matrix[i] & 0xFF));
2673          }
2674          return invertedMatrix;
2675      }
2676      /*@Override*/
2677      isCropSupported() {
2678          return this.delegate.isCropSupported();
2679      }
2680      /*@Override*/
2681      crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
2682          return new InvertedLuminanceSource(this.delegate.crop(left, top, width, height));
2683      }
2684      /*@Override*/
2685      isRotateSupported() {
2686          return this.delegate.isRotateSupported();
2687      }
2688      /**
2689       * @return original delegate {@link LuminanceSource} since invert undoes itself
2690       */
2691      /*@Override*/
2692      invert() {
2693          return this.delegate;
2694      }
2695      /*@Override*/
2696      rotateCounterClockwise() {
2697          return new InvertedLuminanceSource(this.delegate.rotateCounterClockwise());
2698      }
2699      /*@Override*/
2700      rotateCounterClockwise45() {
2701          return new InvertedLuminanceSource(this.delegate.rotateCounterClockwise45());
2702      }
2703  }
2704
2705  /**
2706   * @deprecated Moving to @zxing/browser
2707   */
2708  class HTMLCanvasElementLuminanceSource extends LuminanceSource {
2709      constructor(canvas, doAutoInvert = false) {
2710          super(canvas.width, canvas.height);
2711          this.canvas = canvas;
2712          this.tempCanvasElement = null;
2713          this.buffer = HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData(canvas, doAutoInvert);
2714      }
2715      static makeBufferFromCanvasImageData(canvas, doAutoInvert = false) {
2716          const imageData = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
2717          return HTMLCanvasElementLuminanceSource.toGrayscaleBuffer(imageData.data, canvas.width, canvas.height, doAutoInvert);
2718      }
2719      static toGrayscaleBuffer(imageBuffer, width, height, doAutoInvert = false) {
2720          const grayscaleBuffer = new Uint8ClampedArray(width * height);
2721          HTMLCanvasElementLuminanceSource.FRAME_INDEX = !HTMLCanvasElementLuminanceSource.FRAME_INDEX;
2722          if (HTMLCanvasElementLuminanceSource.FRAME_INDEX || !doAutoInvert) {
2723              for (let i = 0, j = 0, length = imageBuffer.length; i < length; i += 4, j++) {
2724                  let gray;
2725                  const alpha = imageBuffer[i + 3];
2726                  // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent
2727                  // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a
2728                  // barcode image. Force any such pixel to be white:
2729                  if (alpha === 0) {
2730                      gray = 0xFF;
2731                  }
2732                  else {
2733                      const pixelR = imageBuffer[i];
2734                      const pixelG = imageBuffer[i + 1];
2735                      const pixelB = imageBuffer[i + 2];
2736                      // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC),
2737                      // (306*R) >> 10 is approximately equal to R*0.299, and so on.
2738                      // 0x200 >> 10 is 0.5, it implements rounding.
2739                      gray = (306 * pixelR +
2740                          601 * pixelG +
2741                          117 * pixelB +
2742                          0x200) >> 10;
2743                  }
2744                  grayscaleBuffer[j] = gray;
2745              }
2746          }
2747          else {
2748              for (let i = 0, j = 0, length = imageBuffer.length; i < length; i += 4, j++) {
2749                  let gray;
vendor: 6,662 bytes, lines 2750-2912
2750                  const alpha = imageBuffer[i + 3];
2751                  // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent
2752                  // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a
2753                  // barcode image. Force any such pixel to be white:
2754                  if (alpha === 0) {
2755                      gray = 0xFF;
2756                  }
2757                  else {
2758                      const pixelR = imageBuffer[i];
2759                      const pixelG = imageBuffer[i + 1];
2760                      const pixelB = imageBuffer[i + 2];
2761                      // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC),
2762                      // (306*R) >> 10 is approximately equal to R*0.299, and so on.
2763                      // 0x200 >> 10 is 0.5, it implements rounding.
2764                      gray = (306 * pixelR +
2765                          601 * pixelG +
2766                          117 * pixelB +
2767                          0x200) >> 10;
2768                  }
2769                  grayscaleBuffer[j] = 0xFF - gray;
2770              }
2771          }
2772          return grayscaleBuffer;
2773      }
2774      getRow(y /*int*/, row) {
2775          if (y < 0 || y >= this.getHeight()) {
2776              throw new IllegalArgumentException('Requested row is outside the image: ' + y);
2777          }
2778          const width = this.getWidth();
2779          const start = y * width;
2780          if (row === null) {
2781              row = this.buffer.slice(start, start + width);
2782          }
2783          else {
2784              if (row.length < width) {
2785                  row = new Uint8ClampedArray(width);
2786              }
2787              // The underlying raster of image consists of bytes with the luminance values
2788              // TODO: can avoid set/slice?
2789              row.set(this.buffer.slice(start, start + width));
2790          }
2791          return row;
2792      }
2793      getMatrix() {
2794          return this.buffer;
2795      }
2796      isCropSupported() {
2797          return true;
2798      }
2799      crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
2800          super.crop(left, top, width, height);
2801          return this;
2802      }
2803      /**
2804       * This is always true, since the image is a gray-scale image.
2805       *
2806       * @return true
2807       */
2808      isRotateSupported() {
2809          return true;
2810      }
2811      rotateCounterClockwise() {
2812          this.rotate(-90);
2813          return this;
2814      }
2815      rotateCounterClockwise45() {
2816          this.rotate(-45);
2817          return this;
2818      }
2819      getTempCanvasElement() {
2820          if (null === this.tempCanvasElement) {
2821              const tempCanvasElement = this.canvas.ownerDocument.createElement('canvas');
2822              tempCanvasElement.width = this.canvas.width;
2823              tempCanvasElement.height = this.canvas.height;
2824              this.tempCanvasElement = tempCanvasElement;
2825          }
2826          return this.tempCanvasElement;
2827      }
2828      rotate(angle) {
2829          const tempCanvasElement = this.getTempCanvasElement();
2830          const tempContext = tempCanvasElement.getContext('2d');
2831          const angleRadians = angle * HTMLCanvasElementLuminanceSource.DEGREE_TO_RADIANS;
2832          // Calculate and set new dimensions for temp canvas
2833          const width = this.canvas.width;
2834          const height = this.canvas.height;
2835          const newWidth = Math.ceil(Math.abs(Math.cos(angleRadians)) * width + Math.abs(Math.sin(angleRadians)) * height);
2836          const newHeight = Math.ceil(Math.abs(Math.sin(angleRadians)) * width + Math.abs(Math.cos(angleRadians)) * height);
2837          tempCanvasElement.width = newWidth;
2838          tempCanvasElement.height = newHeight;
2839          // Draw at center of temp canvas to prevent clipping of image data
2840          tempContext.translate(newWidth / 2, newHeight / 2);
2841          tempContext.rotate(angleRadians);
2842          tempContext.drawImage(this.canvas, width / -2, height / -2);
2843          this.buffer = HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData(tempCanvasElement);
2844          return this;
2845      }
2846      invert() {
2847          return new InvertedLuminanceSource(this);
2848      }
2849  }
2850  HTMLCanvasElementLuminanceSource.DEGREE_TO_RADIANS = Math.PI / 180;
2851  HTMLCanvasElementLuminanceSource.FRAME_INDEX = true;
2852
2853  /**
2854   * @deprecated Moving to @zxing/browser
2855   *
2856   * Video input device metadata containing the id and label of the device if available.
2857   */
2858  class VideoInputDevice {
2859      /**
2860       * Creates an instance of VideoInputDevice.
2861       *
2862       * @param {string} deviceId the video input device id
2863       * @param {string} label the label of the device if available
2864       */
2865      constructor(deviceId, label, groupId) {
2866          this.deviceId = deviceId;
2867          this.label = label;
2868          /** @inheritdoc */
2869          this.kind = 'videoinput';
2870          this.groupId = groupId || undefined;
2871      }
2872      /** @inheritdoc */
2873      toJSON() {
2874          return {
2875              kind: this.kind,
2876              groupId: this.groupId,
2877              deviceId: this.deviceId,
2878              label: this.label,
2879          };
2880      }
2881  }
2882
2883  var __awaiter = ((globalThis || global || self || window || undefined) && (globalThis || global || self || window || undefined).__awaiter) || function (thisArg, _arguments, P, generator) {
2884      function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2885      return new (P || (P = Promise))(function (resolve, reject) {
2886          function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2887          function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2888          function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2889          step((generator = generator.apply(thisArg, _arguments || [])).next());
2890      });
2891  };
2892  /**
2893   * @deprecated Moving to @zxing/browser
2894   *
2895   * Base class for browser code reader.
2896   */
2897  class BrowserCodeReader {
2898      /**
2899       * Creates an instance of BrowserCodeReader.
2900       * @param {Reader} reader The reader instance to decode the barcode
2901       * @param {number} [timeBetweenScansMillis=500] the time delay between subsequent successful decode tries
2902       *
2903       * @memberOf BrowserCodeReader
2904       */
2905      constructor(reader, timeBetweenScansMillis = 500, _hints) {
2906          this.reader = reader;
2907          this.timeBetweenScansMillis = timeBetweenScansMillis;
2908          this._hints = _hints;
2909          /**
2910           * This will break the loop.
2911           */
2912          this._stopContinuousDecode = false;
2913          /**
2914           * This will break the loop.
2915           */
2916          this._stopAsyncDecode = false;
2917          /**
2918           * Delay time between decode attempts made by the scanner.
2919           */
2920          this._timeBetweenDecodingAttempts = 0;
2921      }
2922      /**
2923       * If navigator is present.
2924       */
2925      get hasNavigator() {
2926          return typeof navigator !== 'undefined';
2927      }
2928      /**
2929       * If mediaDevices under navigator is supported.
2930       */
2931      get isMediaDevicesSuported() {
2932          return this.hasNavigator && !!navigator.mediaDevices;
2933      }
2934      /**
2935       * If enumerateDevices under navigator is supported.
2936       */
2937      get canEnumerateDevices() {
2938          return !!(this.isMediaDevicesSuported && navigator.mediaDevices.enumerateDevices);
2939      }
2940      /** Time between two decoding tries in milli seconds. */
2941      get timeBetweenDecodingAttempts() {
2942          return this._timeBetweenDecodingAttempts;
2943      }
2944      /**
2945       * Change the time span the decoder waits between two decoding tries.
2946       *
2947       * @param {number} millis Time between two decoding tries in milli seconds.
2948       */
2949      set timeBetweenDecodingAttempts(millis) {
2950          this._timeBetweenDecodingAttempts = millis < 0 ? 0 : millis;
2951      }
2952      /**
2953       * Sets the hints.
2954       */
2955      set hints(hints) {
2956          this._hints = hints || null;
2957      }
2958      /**
2959       * Sets the hints.
2960       */
2961      get hints() {
2962          return this._hints
vendor: 24,925 bytes, lines 2962-3524
2962;
2963      }
2964      /**
2965       * Lists all the available video input devices.
2966       */
2967      listVideoInputDevices() {
2968          return __awaiter(this, void 0, void 0, function* () {
2969              if (!this.hasNavigator) {
2970                  throw new Error("Can't enumerate devices, navigator is not present.");
2971              }
2972              if (!this.canEnumerateDevices) {
2973                  throw new Error("Can't enumerate devices, method not supported.");
2974              }
2975              const devices = yield navigator.mediaDevices.enumerateDevices();
2976              const videoDevices = [];
2977              for (const device of devices) {
2978                  const kind = device.kind === 'video' ? 'videoinput' : device.kind;
2979                  if (kind !== 'videoinput') {
2980                      continue;
2981                  }
2982                  const deviceId = device.deviceId || device.id;
2983                  const label = device.label || `Video device ${videoDevices.length + 1}`;
2984                  const groupId = device.groupId;
2985                  const videoDevice = { deviceId, label, kind, groupId };
2986                  videoDevices.push(videoDevice);
2987              }
2988              return videoDevices;
2989          });
2990      }
2991      /**
2992       * Obtain the list of available devices with type 'videoinput'.
2993       *
2994       * @returns {Promise<VideoInputDevice[]>} an array of available video input devices
2995       *
2996       * @memberOf BrowserCodeReader
2997       *
2998       * @deprecated Use `listVideoInputDevices` instead.
2999       */
3000      getVideoInputDevices() {
3001          return __awaiter(this, void 0, void 0, function* () {
3002              const devices = yield this.listVideoInputDevices();
3003              return devices.map(d => new VideoInputDevice(d.deviceId, d.label));
3004          });
3005      }
3006      /**
3007       * Let's you find a device using it's Id.
3008       */
3009      findDeviceById(deviceId) {
3010          return __awaiter(this, void 0, void 0, function* () {
3011              const devices = yield this.listVideoInputDevices();
3012              if (!devices) {
3013                  return null;
3014              }
3015              return devices.find(x => x.deviceId === deviceId);
3016          });
3017      }
3018      /**
3019       * Decodes the barcode from the device specified by deviceId while showing the video in the specified video element.
3020       *
3021       * @param deviceId the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
3022       * @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
3023       * @returns The decoding result.
3024       *
3025       * @memberOf BrowserCodeReader
3026       *
3027       * @deprecated Use `decodeOnceFromVideoDevice` instead.
3028       */
3029      decodeFromInputVideoDevice(deviceId, videoSource) {
3030          return __awaiter(this, void 0, void 0, function* () {
3031              return yield this.decodeOnceFromVideoDevice(deviceId, videoSource);
3032          });
3033      }
3034      /**
3035       * In one attempt, tries to decode the barcode from the device specified by deviceId while showing the video in the specified video element.
3036       *
3037       * @param deviceId the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
3038       * @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
3039       * @returns The decoding result.
3040       *
3041       * @memberOf BrowserCodeReader
3042       */
3043      decodeOnceFromVideoDevice(deviceId, videoSource) {
3044          return __awaiter(this, void 0, void 0, function* () {
3045              this.reset();
3046              let videoConstraints;
3047              if (!deviceId) {
3048                  videoConstraints = { facingMode: 'environment' };
3049              }
3050              else {
3051                  videoConstraints = { deviceId: { exact: deviceId } };
3052              }
3053              const constraints = { video: videoConstraints };
3054              return yield this.decodeOnceFromConstraints(constraints, videoSource);
3055          });
3056      }
3057      /**
3058       * In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
3059       *
3060       * @param constraints the media stream constraints to get s valid media stream to decode from
3061       * @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
3062       * @returns The decoding result.
3063       *
3064       * @memberOf BrowserCodeReader
3065       */
3066      decodeOnceFromConstraints(constraints, videoSource) {
3067          return __awaiter(this, void 0, void 0, function* () {
3068              const stream = yield navigator.mediaDevices.getUserMedia(constraints);
3069              return yield this.decodeOnceFromStream(stream, videoSource);
3070          });
3071      }
3072      /**
3073       * In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
3074       *
3075       * @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
3076       * @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
3077       * @returns {Promise<Result>} The decoding result.
3078       *
3079       * @memberOf BrowserCodeReader
3080       */
3081      decodeOnceFromStream(stream, videoSource) {
3082          return __awaiter(this, void 0, void 0, function* () {
3083              this.reset();
3084              const video = yield this.attachStreamToVideo(stream, videoSource);
3085              const result = yield this.decodeOnce(video);
3086              return result;
3087          });
3088      }
3089      /**
3090       * Continuously decodes the barcode from the device specified by device while showing the video in the specified video element.
3091       *
3092       * @param {string|null} [deviceId] the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
3093       * @param {string|HTMLVideoElement|null} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
3094       * @returns {Promise<void>}
3095       *
3096       * @memberOf BrowserCodeReader
3097       *
3098       * @deprecated Use `decodeFromVideoDevice` instead.
3099       */
3100      decodeFromInputVideoDeviceContinuously(deviceId, videoSource, callbackFn) {
3101          return __awaiter(this, void 0, void 0, function* () {
3102              return yield this.decodeFromVideoDevice(deviceId, videoSource, callbackFn);
3103          });
3104      }
3105      /**
3106       * Continuously tries to decode the barcode from the device specified by device while showing the video in the specified video element.
3107       *
3108       * @param {string|null} [deviceId] the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
3109       * @param {string|HTMLVideoElement|null} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
3110       * @returns {Promise<void>}
3111       *
3112       * @memberOf BrowserCodeReader
3113       */
3114      decodeFromVideoDevice(deviceId, videoSource, callbackFn) {
3115          return __awaiter(this, void 0, void 0, function* () {
3116              let videoConstraints;
3117              if (!deviceId) {
3118                  videoConstraints = { facingMode: 'environment' };
3119              }
3120              else {
3121                  videoConstraints = { deviceId: { exact: deviceId } };
3122              }
3123              const constraints = { video: videoConstraints };
3124              return yield this.decodeFromConstraints(constraints, videoSource, callbackFn);
3125          });
3126      }
3127      /**
3128       * Continuously tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
3129       *
3130       * @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
3131       * @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
3132       * @returns {Promise<Result>} The decoding result.
3133       *
3134       * @memberOf BrowserCodeReader
3135       */
3136      decodeFromConstraints(constraints, videoSource, callbackFn) {
3137          return __awaiter(this, void 0, void 0, function* () {
3138              const stream = yield navigator.mediaDevices.getUserMedia(constraints);
3139              return yield this.decodeFromStream(stream, videoSource, callbackFn);
3140          });
3141      }
3142      /**
3143       * In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
3144       *
3145       * @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
3146       * @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
3147       * @returns {Promise<Result>} The decoding result.
3148       *
3149       * @memberOf BrowserCodeReader
3150       */
3151      decodeFromStream(stream, videoSource, callbackFn) {
3152          return __awaiter(this, void 0, void 0, function* () {
3153              this.reset();
3154              const video = yield this.attachStreamToVideo(stream, videoSource);
3155              return yield this.decodeContinuously(video, callbackFn);
3156          });
3157      }
3158      /**
3159       * Breaks the decoding loop.
3160       */
3161      stopAsyncDecode() {
3162          this._stopAsyncDecode = true;
3163      }
3164      /**
3165       * Breaks the decoding loop.
3166       */
3167      stopContinuousDecode() {
3168          this._stopContinuousDecode = true;
3169      }
3170      /**
3171       * Sets the new stream and request a new decoding-with-delay.
3172       *
3173       * @param stream The stream to be shown in the video element.
3174       * @param decodeFn A callback for the decode method.
3175       */
3176      attachStreamToVideo(stream, videoSource) {
3177          return __awaiter(this, void 0, void 0, function* () {
3178              const videoElement = this.prepareVideoElement(videoSource);
3179              this.addVideoSource(videoElement, stream);
3180              this.videoElement = videoElement;
3181              this.stream = stream;
3182              yield this.playVideoOnLoadAsync(videoElement);
3183              return videoElement;
3184          });
3185      }
3186      /**
3187       *
3188       * @param videoElement
3189       */
3190      playVideoOnLoadAsync(videoElement) {
3191          return new Promise((resolve, reject) => this.playVideoOnLoad(videoElement, () => resolve()));
3192      }
3193      /**
3194       * Binds listeners and callbacks to the videoElement.
3195       *
3196       * @param element
3197       * @param callbackFn
3198       */
3199      playVideoOnLoad(element, callbackFn) {
3200          this.videoEndedListener = () => this.stopStreams();
3201          this.videoCanPlayListener = () => this.tryPlayVideo(element);
3202          element.addEventListener('ended', this.videoEndedListener);
3203          element.addEventListener('canplay', this.videoCanPlayListener);
3204          element.addEventListener('playing', callbackFn);
3205          // if canplay was already fired, we won't know when to play, so just give it a try
3206          this.tryPlayVideo(element);
3207      }
3208      /**
3209       * Checks if the given video element is currently playing.
3210       */
3211      isVideoPlaying(video) {
3212          return (video.currentTime > 0 &&
3213              !video.paused &&
3214              !video.ended &&
3215              video.readyState > 2);
3216      }
3217      /**
3218       * Just tries to play the video and logs any errors.
3219       * The play call is only made is the video is not already playing.
3220       */
3221      tryPlayVideo(videoElement) {
3222          return __awaiter(this, void 0, void 0, function* () {
3223              if (this.isVideoPlaying(videoElement)) {
3224                  console.warn('Trying to play video that is already playing.');
3225                  return;
3226              }
3227              try {
3228                  yield videoElement.play();
3229              }
3230              catch (_a) {
3231                  console.warn('It was not possible to play the video.');
3232              }
3233          });
3234      }
3235      /**
3236       * Searches and validates a media element.
3237       */
3238      getMediaElement(mediaElementId, type) {
3239          const mediaElement = document.getElementById(mediaElementId);
3240          if (!mediaElement) {
3241              throw new ArgumentException(`element with id '${mediaElementId}' not found`);
3242          }
3243          if (mediaElement.nodeName.toLowerCase() !== type.toLowerCase()) {
3244              throw new ArgumentException(`element with id '${mediaElementId}' must be an ${type} element`);
3245          }
3246          return mediaElement;
3247      }
3248      /**
3249       * Decodes the barcode from an image.
3250       *
3251       * @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
3252       * @param {string} [url]
3253       * @returns {Promise<Result>} The decoding result.
3254       *
3255       * @memberOf BrowserCodeReader
3256       */
3257      decodeFromImage(source, url) {
3258          if (!source && !url) {
3259              throw new ArgumentException('either imageElement with a src set or an url must be provided');
3260          }
3261          if (url && !source) {
3262              return this.decodeFromImageUrl(url);
3263          }
3264          return this.decodeFromImageElement(source);
3265      }
3266      /**
3267       * Decodes the barcode from a video.
3268       *
3269       * @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
3270       * @param {string} [url]
3271       * @returns {Promise<Result>} The decoding result.
3272       *
3273       * @memberOf BrowserCodeReader
3274       */
3275      decodeFromVideo(source, url) {
3276          if (!source && !url) {
3277              throw new ArgumentException('Either an element with a src set or an URL must be provided');
3278          }
3279          if (url && !source) {
3280              return this.decodeFromVideoUrl(url);
3281          }
3282          return this.decodeFromVideoElement(source);
3283      }
3284      /**
3285       * Decodes continuously the barcode from a video.
3286       *
3287       * @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
3288       * @param {string} [url]
3289       * @returns {Promise<Result>} The decoding result.
3290       *
3291       * @memberOf BrowserCodeReader
3292       *
3293       * @experimental
3294       */
3295      decodeFromVideoContinuously(source, url, callbackFn) {
3296          if (undefined === source && undefined === url) {
3297              throw new ArgumentException('Either an element with a src set or an URL must be provided');
3298          }
3299          if (url && !source) {
3300              return this.decodeFromVideoUrlContinuously(url, callbackFn);
3301          }
3302          return this.decodeFromVideoElementContinuously(source, callbackFn);
3303      }
3304      /**
3305       * Decodes something from an image HTML element.
3306       */
3307      decodeFromImageElement(source) {
3308          if (!source) {
3309              throw new ArgumentException('An image element must be provided.');
3310          }
3311          this.reset();
3312          const element = this.prepareImageElement(source);
3313          this.imageElement = element;
3314          let task;
3315          if (this.isImageLoaded(element)) {
3316              task = this.decodeOnce(element, false, true);
3317          }
3318          else {
3319              task = this._decodeOnLoadImage(element);
3320          }
3321          return task;
3322      }
3323      /**
3324       * Decodes something from an image HTML element.
3325       */
3326      decodeFromVideoElement(source) {
3327          const element = this._decodeFromVideoElementSetup(source);
3328          return this._decodeOnLoadVideo(element);
3329      }
3330      /**
3331       * Decodes something from an image HTML element.
3332       */
3333      decodeFromVideoElementContinuously(source, callbackFn) {
3334          const element = this._decodeFromVideoElementSetup(source);
3335          return this._decodeOnLoadVideoContinuously(element, callbackFn);
3336      }
3337      /**
3338       * Sets up the video source so it can be decoded when loaded.
3339       *
3340       * @param source The video source element.
3341       */
3342      _decodeFromVideoElementSetup(source) {
3343          if (!source) {
3344              throw new ArgumentException('A video element must be provided.');
3345          }
3346          this.reset();
3347          const element = this.prepareVideoElement(source);
3348          // defines the video element before starts decoding
3349          this.videoElement = element;
3350          return element;
3351      }
3352      /**
3353       * Decodes an image from a URL.
3354       */
3355      decodeFromImageUrl(url) {
3356          if (!url) {
3357              throw new ArgumentException('An URL must be provided.');
3358          }
3359          this.reset();
3360          const element = this.prepareImageElement();
3361          this.imageElement = element;
3362          const decodeTask = this._decodeOnLoadImage(element);
3363          element.src = url;
3364          return decodeTask;
3365      }
3366      /**
3367       * Decodes an image from a URL.
3368       */
3369      decodeFromVideoUrl(url) {
3370          if (!url) {
3371              throw new ArgumentException('An URL must be provided.');
3372          }
3373          this.reset();
3374          // creates a new element
3375          const element = this.prepareVideoElement();
3376          const decodeTask = this.decodeFromVideoElement(element);
3377          element.src = url;
3378          return decodeTask;
3379      }
3380      /**
3381       * Decodes an image from a URL.
3382       *
3383       * @experimental
3384       */
3385      decodeFromVideoUrlContinuously(url, callbackFn) {
3386          if (!url) {
3387              throw new ArgumentException('An URL must be provided.');
3388          }
3389          this.reset();
3390          // creates a new element
3391          const element = this.prepareVideoElement();
3392          const decodeTask = this.decodeFromVideoElementContinuously(element, callbackFn);
3393          element.src = url;
3394          return decodeTask;
3395      }
3396      _decodeOnLoadImage(element) {
3397          return new Promise((resolve, reject) => {
3398              this.imageLoadedListener = () => this.decodeOnce(element, false, true).then(resolve, reject);
3399              element.addEventListener('load', this.imageLoadedListener);
3400          });
3401      }
3402      _decodeOnLoadVideo(videoElement) {
3403          return __awaiter(this, void 0, void 0, function* () {
3404              // plays the video
3405              yield this.playVideoOnLoadAsync(videoElement);
3406              // starts decoding after played the video
3407              return yield this.decodeOnce(videoElement);
3408          });
3409      }
3410      _decodeOnLoadVideoContinuously(videoElement, callbackFn) {
3411          return __awaiter(this, void 0, void 0, function* () {
3412              // plays the video
3413              yield this.playVideoOnLoadAsync(videoElement);
3414              // starts decoding after played the video
3415              this.decodeContinuously(videoElement, callbackFn);
3416          });
3417      }
3418      isImageLoaded(img) {
3419          // During the onload event, IE correctly identifies any images that
3420          // weren’t downloaded as not complete. Others should too. Gecko-based
3421          // browsers act like NS4 in that they report this incorrectly.
3422          if (!img.complete) {
3423              return false;
3424          }
3425          // However, they do have two very useful properties: naturalWidth and
3426          // naturalHeight. These give the true size of the image. If it failed
3427          // to load, either of these should be zero.
3428          if (img.naturalWidth === 0) {
3429              return false;
3430          }
3431          // No other way of checking: assume it’s ok.
3432          return true;
3433      }
3434      prepareImageElement(imageSource) {
3435          let imageElement;
3436          if (typeof imageSource === 'undefined') {
3437              imageElement = document.createElement('img');
3438              imageElement.width = 200;
3439              imageElement.height = 200;
3440          }
3441          if (typeof imageSource === 'string') {
3442              imageElement = this.getMediaElement(imageSource, 'img');
3443          }
3444          if (imageSource instanceof HTMLImageElement) {
3445              imageElement = imageSource;
3446          }
3447          return imageElement;
3448      }
3449      /**
3450       * Sets a HTMLVideoElement for scanning or creates a new one.
3451       *
3452       * @param videoSource The HTMLVideoElement to be set.
3453       */
3454      prepareVideoElement(videoSource) {
3455          let videoElement;
3456          if (!videoSource && typeof document !== 'undefined') {
3457              videoElement = document.createElement('video');
3458              videoElement.width = 200;
3459              videoElement.height = 200;
3460          }
3461          if (typeof videoSource === 'string') {
3462              videoElement = (this.getMediaElement(videoSource, 'video'));
3463          }
3464          if (videoSource instanceof HTMLVideoElement) {
3465              videoElement = videoSource;
3466          }
3467          // Needed for iOS 11
3468          videoElement.setAttribute('autoplay', 'true');
3469          videoElement.setAttribute('muted', 'true');
3470          videoElement.setAttribute('playsinline', 'true');
3471          return videoElement;
3472      }
3473      /**
3474       * Tries to decode from the video input until it finds some value.
3475       */
3476      decodeOnce(element, retryIfNotFound = true, retryIfChecksumOrFormatError = true) {
3477          this._stopAsyncDecode = false;
3478          const loop = (resolve, reject) => {
3479              if (this._stopAsyncDecode) {
3480                  reject(new NotFoundException('Video stream has ended before any code could be detected.'));
3481                  this._stopAsyncDecode = undefined;
3482                  return;
3483              }
3484              try {
3485                  const result = this.decode(element);
3486                  resolve(result);
3487              }
3488              catch (e) {
3489                  const ifNotFound = retryIfNotFound && e instanceof NotFoundException;
3490                  const isChecksumOrFormatError = e instanceof ChecksumException || e instanceof FormatException;
3491                  const ifChecksumOrFormat = isChecksumOrFormatError && retryIfChecksumOrFormatError;
3492                  if (ifNotFound || ifChecksumOrFormat) {
3493                      // trying again
3494                      return setTimeout(loop, this._timeBetweenDecodingAttempts, resolve, reject);
3495                  }
3496                  reject(e);
3497              }
3498          };
3499          return new Promise((resolve, reject) => loop(resolve, reject));
3500      }
3501      /**
3502       * Continuously decodes from video input.
3503       */
3504      decodeContinuously(element, callbackFn) {
3505          this._stopContinuousDecode = false;
3506          const loop = () => {
3507              if (this._stopContinuousDecode) {
3508                  this._stopContinuousDecode = undefined;
3509                  return;
3510              }
3511              try {
3512                  const result = this.decode(element);
3513                  callbackFn(result, null);
3514                  setTimeout(loop, this.timeBetweenScansMillis);
3515              }
3516              catch (e) {
3517                  callbackFn(null, e);
3518                  const isChecksumOrFormatError = e instanceof ChecksumException || e instanceof FormatException;
3519                  const isNotFound = e instanceof NotFoundException;
3520                  if (isChecksumOrFormatError || isNotFound) {
3521                      // trying again
3522                      setTimeout(loop, this._timeBetweenDecodingAttempts);
3523                  }
3524              
vendor: 13,183 bytes, lines 3524-3892
3524}
3525          };
3526          loop();
3527      }
3528      /**
3529       * Gets the BinaryBitmap for ya! (and decodes it)
3530       */
3531      decode(element) {
3532          // get binary bitmap for decode function
3533          const binaryBitmap = this.createBinaryBitmap(element);
3534          return this.decodeBitmap(binaryBitmap);
3535      }
3536      /**
3537       * Creates a binaryBitmap based in some image source.
3538       *
3539       * @param mediaElement HTML element containing drawable image source.
3540       */
3541      createBinaryBitmap(mediaElement) {
3542          this.getCaptureCanvasContext(mediaElement);
3543          // doing a scan with inverted colors on the second scan should only happen for video elements
3544          let doAutoInvert = false;
3545          if (mediaElement instanceof HTMLVideoElement) {
3546              this.drawFrameOnCanvas(mediaElement);
3547              doAutoInvert = true;
3548          }
3549          else {
3550              this.drawImageOnCanvas(mediaElement);
3551          }
3552          const canvas = this.getCaptureCanvas(mediaElement);
3553          const luminanceSource = new HTMLCanvasElementLuminanceSource(canvas, doAutoInvert);
3554          const hybridBinarizer = new HybridBinarizer(luminanceSource);
3555          return new BinaryBitmap(hybridBinarizer);
3556      }
3557      /**
3558       *
3559       */
3560      getCaptureCanvasContext(mediaElement) {
3561          if (!this.captureCanvasContext) {
3562              const elem = this.getCaptureCanvas(mediaElement);
3563              let ctx;
3564              try {
3565                  ctx = elem.getContext('2d', { willReadFrequently: true });
3566              }
3567              catch (e) {
3568                  ctx = elem.getContext('2d');
3569              }
3570              this.captureCanvasContext = ctx;
3571          }
3572          return this.captureCanvasContext;
3573      }
3574      /**
3575       *
3576       */
3577      getCaptureCanvas(mediaElement) {
3578          if (!this.captureCanvas) {
3579              const elem = this.createCaptureCanvas(mediaElement);
3580              this.captureCanvas = elem;
3581          }
3582          return this.captureCanvas;
3583      }
3584      /**
3585       * Overwriting this allows you to manipulate the next frame in anyway you want before decode.
3586       */
3587      drawFrameOnCanvas(srcElement, dimensions = {
3588          sx: 0,
3589          sy: 0,
3590          sWidth: srcElement.videoWidth,
3591          sHeight: srcElement.videoHeight,
3592          dx: 0,
3593          dy: 0,
3594          dWidth: srcElement.videoWidth,
3595          dHeight: srcElement.videoHeight,
3596      }, canvasElementContext = this.captureCanvasContext) {
3597          canvasElementContext.drawImage(srcElement, dimensions.sx, dimensions.sy, dimensions.sWidth, dimensions.sHeight, dimensions.dx, dimensions.dy, dimensions.dWidth, dimensions.dHeight);
3598      }
3599      /**
3600       * Ovewriting this allows you to manipulate the snapshot image in anyway you want before decode.
3601       */
3602      drawImageOnCanvas(srcElement, dimensions = {
3603          sx: 0,
3604          sy: 0,
3605          sWidth: srcElement.naturalWidth,
3606          sHeight: srcElement.naturalHeight,
3607          dx: 0,
3608          dy: 0,
3609          dWidth: srcElement.naturalWidth,
3610          dHeight: srcElement.naturalHeight,
3611      }, canvasElementContext = this.captureCanvasContext) {
3612          canvasElementContext.drawImage(srcElement, dimensions.sx, dimensions.sy, dimensions.sWidth, dimensions.sHeight, dimensions.dx, dimensions.dy, dimensions.dWidth, dimensions.dHeight);
3613      }
3614      /**
3615       * Call the encapsulated readers decode
3616       */
3617      decodeBitmap(binaryBitmap) {
3618          return this.reader.decode(binaryBitmap, this._hints);
3619      }
3620      /**
3621       * 🖌 Prepares the canvas for capture and scan frames.
3622       */
3623      createCaptureCanvas(mediaElement) {
3624          if (typeof document === 'undefined') {
3625              this._destroyCaptureCanvas();
3626              return null;
3627          }
3628          const canvasElement = document.createElement('canvas');
3629          let width;
3630          let height;
3631          if (typeof mediaElement !== 'undefined') {
3632              if (mediaElement instanceof HTMLVideoElement) {
3633                  width = mediaElement.videoWidth;
3634                  height = mediaElement.videoHeight;
3635              }
3636              else if (mediaElement instanceof HTMLImageElement) {
3637                  width = mediaElement.naturalWidth || mediaElement.width;
3638                  height = mediaElement.naturalHeight || mediaElement.height;
3639              }
3640          }
3641          canvasElement.style.width = width + 'px';
3642          canvasElement.style.height = height + 'px';
3643          canvasElement.width = width;
3644          canvasElement.height = height;
3645          return canvasElement;
3646      }
3647      /**
3648       * Stops the continuous scan and cleans the stream.
3649       */
3650      stopStreams() {
3651          if (this.stream) {
3652              this.stream.getVideoTracks().forEach(t => t.stop());
3653              this.stream = undefined;
3654          }
3655          if (this._stopAsyncDecode === false) {
3656              this.stopAsyncDecode();
3657          }
3658          if (this._stopContinuousDecode === false) {
3659              this.stopContinuousDecode();
3660          }
3661      }
3662      /**
3663       * Resets the code reader to the initial state. Cancels any ongoing barcode scanning from video or camera.
3664       *
3665       * @memberOf BrowserCodeReader
3666       */
3667      reset() {
3668          // stops the camera, preview and scan 🔴
3669          this.stopStreams();
3670          // clean and forget about HTML elements
3671          this._destroyVideoElement();
3672          this._destroyImageElement();
3673          this._destroyCaptureCanvas();
3674      }
3675      _destroyVideoElement() {
3676          if (!this.videoElement) {
3677              return;
3678          }
3679          // first gives freedon to the element 🕊
3680          if (typeof this.videoEndedListener !== 'undefined') {
3681              this.videoElement.removeEventListener('ended', this.videoEndedListener);
3682          }
3683          if (typeof this.videoPlayingEventListener !== 'undefined') {
3684              this.videoElement.removeEventListener('playing', this.videoPlayingEventListener);
3685          }
3686          if (typeof this.videoCanPlayListener !== 'undefined') {
3687              this.videoElement.removeEventListener('loadedmetadata', this.videoCanPlayListener);
3688          }
3689          // then forgets about that element 😢
3690          this.cleanVideoSource(this.videoElement);
3691          this.videoElement = undefined;
3692      }
3693      _destroyImageElement() {
3694          if (!this.imageElement) {
3695              return;
3696          }
3697          // first gives freedon to the element 🕊
3698          if (undefined !== this.imageLoadedListener) {
3699              this.imageElement.removeEventListener('load', this.imageLoadedListener);
3700          }
3701          // then forget about that element 😢
3702          this.imageElement.src = undefined;
3703          this.imageElement.removeAttribute('src');
3704          this.imageElement = undefined;
3705      }
3706      /**
3707       * Cleans canvas references 🖌
3708       */
3709      _destroyCaptureCanvas() {
3710          // then forget about that element 😢
3711          this.captureCanvasContext = undefined;
3712          this.captureCanvas = undefined;
3713      }
3714      /**
3715       * Defines what the videoElement src will be.
3716       *
3717       * @param videoElement
3718       * @param stream
3719       */
3720      addVideoSource(videoElement, stream) {
3721          // Older browsers may not have `srcObject`
3722          try {
3723              // @note Throws Exception if interrupted by a new loaded request
3724              videoElement.srcObject = stream;
3725          }
3726          catch (err) {
3727              // @note Avoid using this in new browsers, as it is going away.
3728              // @ts-ignore
3729              videoElement.src = URL.createObjectURL(stream);
3730          }
3731      }
3732      /**
3733       * Unbinds a HTML video src property.
3734       *
3735       * @param videoElement
3736       */
3737      cleanVideoSource(videoElement) {
3738          try {
3739              videoElement.srcObject = null;
3740          }
3741          catch (err) {
3742              videoElement.src = '';
3743          }
3744          this.videoElement.removeAttribute('src');
3745      }
3746  }
3747
3748  /*
3749   * Copyright 2007 ZXing authors
3750   *
3751   * Licensed under the Apache License, Version 2.0 (the "License");
3752   * you may not use this file except in compliance with the License.
3753   * You may obtain a copy of the License at
3754   *
3755   *      http://www.apache.org/licenses/LICENSE-2.0
3756   *
3757   * Unless required by applicable law or agreed to in writing, software
3758   * distributed under the License is distributed on an "AS IS" BASIS,
3759   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3760   * See the License for the specific language governing permissions and
3761   * limitations under the License.
3762   */
3763  /**
3764   * <p>Encapsulates the result of decoding a barcode within an image.</p>
3765   *
3766   * @author Sean Owen
3767   */
3768  class Result$1 {
3769      // public constructor(private text: string,
3770      //               Uint8Array rawBytes,
3771      //               ResultPoconst resultPoints: Int32Array,
3772      //               BarcodeFormat format) {
3773      //   this(text, rawBytes, resultPoints, format, System.currentTimeMillis())
3774      // }
3775      // public constructor(text: string,
3776      //               Uint8Array rawBytes,
3777      //               ResultPoconst resultPoints: Int32Array,
3778      //               BarcodeFormat format,
3779      //               long timestamp) {
3780      //   this(text, rawBytes, rawBytes == null ? 0 : 8 * rawBytes.length,
3781      //        resultPoints, format, timestamp)
3782      // }
3783      constructor(text, rawBytes, numBits = rawBytes == null ? 0 : 8 * rawBytes.length, resultPoints, format, timestamp = System.currentTimeMillis()) {
3784          this.text = text;
3785          this.rawBytes = rawBytes;
3786          this.numBits = numBits;
3787          this.resultPoints = resultPoints;
3788          this.format = format;
3789          this.timestamp = timestamp;
3790          this.text = text;
3791          this.rawBytes = rawBytes;
3792          if (undefined === numBits || null === numBits) {
3793              this.numBits = (rawBytes === null || rawBytes === undefined) ? 0 : 8 * rawBytes.length;
3794          }
3795          else {
3796              this.numBits = numBits;
3797          }
3798          this.resultPoints = resultPoints;
3799          this.format = format;
3800          this.resultMetadata = null;
3801          if (undefined === timestamp || null === timestamp) {
3802              this.timestamp = System.currentTimeMillis();
3803          }
3804          else {
3805              this.timestamp = timestamp;
3806          }
3807      }
3808      /**
3809       * @return raw text encoded by the barcode
3810       */
3811      getText() {
3812          return this.text;
3813      }
3814      /**
3815       * @return raw bytes encoded by the barcode, if applicable, otherwise {@code null}
3816       */
3817      getRawBytes() {
3818          return this.rawBytes;
3819      }
3820      /**
3821       * @return how many bits of {@link #getRawBytes()} are valid; typically 8 times its length
3822       * @since 3.3.0
3823       */
3824      getNumBits() {
3825          return this.numBits;
3826      }
3827      /**
3828       * @return points related to the barcode in the image. These are typically points
3829       *         identifying finder patterns or the corners of the barcode. The exact meaning is
3830       *         specific to the type of barcode that was decoded.
3831       */
3832      getResultPoints() {
3833          return this.resultPoints;
3834      }
3835      /**
3836       * @return {@link BarcodeFormat} representing the format of the barcode that was decoded
3837       */
3838      getBarcodeFormat() {
3839          return this.format;
3840      }
3841      /**
3842       * @return {@link Map} mapping {@link ResultMetadataType} keys to values. May be
3843       *   {@code null}. This contains optional metadata about what was detected about the barcode,
3844       *   like orientation.
3845       */
3846      getResultMetadata() {
3847          return this.resultMetadata;
3848      }
3849      putMetadata(type, value) {
3850          if (this.resultMetadata === null) {
3851              this.resultMetadata = new Map();
3852          }
3853          this.resultMetadata.set(type, value);
3854      }
3855      putAllMetadata(metadata) {
3856          if (metadata !== null) {
3857              if (this.resultMetadata === null) {
3858                  this.resultMetadata = metadata;
3859              }
3860              else {
3861                  this.resultMetadata = new Map(metadata);
3862              }
3863          }
3864      }
3865      addResultPoints(newPoints) {
3866          const oldPoints = this.resultPoints;
3867          if (oldPoints === null) {
3868              this.resultPoints = newPoints;
3869          }
3870          else if (newPoints !== null && newPoints.length > 0) {
3871              const allPoints = new Array(oldPoints.length + newPoints.length);
3872              System.arraycopy(oldPoints, 0, allPoints, 0, oldPoints.length);
3873              System.arraycopy(newPoints, 0, allPoints, oldPoints.length, newPoints.length);
3874              this.resultPoints = allPoints;
3875          }
3876      }
3877      getTimestamp() {
3878          return this.timestamp;
3879      }
3880      /*@Override*/
3881      toString() {
3882          return this.text;
3883      }
3884  }
3885
3886  /*
3887   * Direct port to TypeScript of ZXing by Adrian Toșcă
3888   */
3889  /*
3890   * Copyright 2009 ZXing authors
3891   *
3892   * Licensed under the Apache License, Version 2.0 (the "License");
3893   * you may not use this file except in compliance with the License.
3894   * You may obtain a copy of the License at
3895   *
3896   *      http://www.apache.org/licenses/LICENSE-2.0
3897   *
3898   * Unless required by applicable law or agreed to in writing, software
3899   * distributed under the License is distributed on an "AS IS" BASIS,
3900   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3901   * See the License for the specific language governing permissions and
3902   * limitations under the License.
3903   */
3904  /*namespace com.google.zxing {*/
3905  /**
3906   * Enumerates barcode formats known to this package. Please keep alphabetized.
3907   *
3908   * @author Sean Owen
3909   */
3910  var BarcodeFormat;
3911  (function (BarcodeFormat) {
3912      /** Aztec 2D barcode format. */
3913      BarcodeFormat[BarcodeFormat["AZTEC"] = 0] = "AZTEC";
3914      /** CODABAR 1D format. */
3915      BarcodeFormat[BarcodeFormat["CODABAR"] = 1] = "CODABAR";
3916      /** Code 39 1D format. */
3917      BarcodeFormat[BarcodeFormat["CODE_39"] = 2] = "CODE_39";
3918      /** Code 93 1D format. */
3919      BarcodeFormat[BarcodeFormat["CODE_93"] = 3] = "CODE_93";
3920      /** Code 128 1D format. */
3921      BarcodeFormat[BarcodeFormat["CODE_128"] = 4] = "CODE_128";
3922      /** Data Matrix 2D barcode format. */
3923      BarcodeFormat[BarcodeFormat["DATA_MATRIX"] = 5] = "DATA_MATRIX";
3924      /** EAN-8 1D format. */
3925      BarcodeFormat[BarcodeFormat["EAN_8"] = 6] = "EAN_8";
3926      /** EAN-13 1D format. */
3927      BarcodeFormat[BarcodeFormat["EAN_13"] = 7] = "EAN_13";
3928      /** ITF (Interleaved Two of Five) 1D format. */
3929      BarcodeFormat[BarcodeFormat["ITF"] = 8] = "ITF";
3930      /** MaxiCode 2D barcode format. */
3931      BarcodeFormat[BarcodeFormat["MAXICODE"] = 9] = "MAXICODE";
3932      /** PDF417 format. */
3933      BarcodeFormat[BarcodeFormat["PDF_417"] = 10] = "PDF_417";
3934      /** QR Code 2D barcode format. */
3935      BarcodeFormat[BarcodeFormat["QR_CODE"] = 11] = "QR_CODE";
3936      /** RSS 14 */
3937      BarcodeFormat[BarcodeFormat["RSS_14"] = 12] = "RSS_14";
3938      /** RSS EXPANDED */
3939      BarcodeFormat[BarcodeFormat["RSS_EXPANDED"] = 13] = "RSS_EXPANDED";
3940      /** UPC-A 1D format. */
3941      BarcodeFormat[BarcodeFormat["UPC_A"] = 14] = "UPC_A";
3942      /** UPC-E 1D format. */
3943      BarcodeFormat[BarcodeFormat["UPC_E"] = 15] = "UPC_E";
3944      /** UPC/EAN extension format. Not a stand-alone format. */
3945      BarcodeFormat[BarcodeFormat["UPC_EAN_EXTENSION"] = 16] = "UPC_EAN_EXTENSION";
3946  })(BarcodeFormat || (BarcodeFormat = {}));
3947  var BarcodeFormat$1 = BarcodeFormat;
3948
3949  /*
3950   * Copyright 2008 ZXing authors
3951   *
3952   * Licensed under the Apache License, Version 2.0 (the "License");
3953   * you may not use this file except in compliance with the License.
3954   * You may obtain a copy of the License at
3955   *
3956   *      http://www.apache.org/licenses/LICENSE-2.0
3957   *
3958   * Unless required by applicable law or agreed to in writing, software
3959   * distributed under the License is distributed on an "AS IS" BASIS,
3960   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3961   * See the License for the specific language governing permissions and
3962   * limitations under the License.
3963   */
3964  /*namespace com.google.zxing {*/
3965  /**
3966   * Represents some type of metadata about the result of the decoding that the decoder
3967   * wishes to communicate back to the caller.
3968   *
3969   * @author Sean Owen
3970   */
3971  var ResultMetadataType;
3972  (function (ResultMetadataType) {
3973      /**
3974       * Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
3975       */
3976      ResultMetadataType[ResultMetadataType["OTHER"] = 0] = "OTHER";
3977      /**
3978       * Denotes the likely approximate orientation of the barcode in the image. This value
3979       * is given as degrees rotated clockwise from the normal, upright orientation.
3980       * For example a 1D barcode which was found by reading top-to-bottom would be
3981       * said to have orientation "90". This key maps to an {@link Integer} whose
3982       * value is in the range [0,360).
3983       */
3984      ResultMetadataType[ResultMetadataType["ORIENTATION"] = 1] = "ORIENTATION";
3985      /**
3986       * <p>2D barcode formats typically encode text, but allow for a sort of 'byte mode'
3987       * which is sometimes used to encode binary data. While {@link Result} makes available
3988       * the complete raw bytes in the barcode for these formats, it does not offer the bytes
3989       * from the byte segments alone.</p>
3990       *
3991       * <p>This maps to a {@link java.util.List} of byte arrays corresponding to the
3992       * raw bytes in the byte segments in the barcode, in order.</p>
3993       */
3994      ResultMetadataType[ResultMetadataType["BYTE_SEGMENTS"] = 2] = "BYTE_SEGMENTS";
3995      /**
3996       * Error correction level used, if applicable. The value type depends on the
3997       * format, but is typically a String.
3998       */
3999      ResultMetadataType[ResultMetadataType["ERROR_CORRECTION_LEVEL"] = 3] = "ERROR_CORRECTION_LEVEL";
4000      /**
4001       * For some periodicals, indicates the issue number as an {@link Integer}.
4002       */
4003      ResultMetadataType[ResultMetadataType["ISSUE_NUMBER"] = 4] = "ISSUE_NUMBER";
4004      /**
4005       * For some products, indicates the suggested retail price in the barcode as a
4006       * formatted {@link String}.
4007       */
4008      ResultMetadataType[ResultMetadataType["SUGGESTED_PRICE"] = 5] = "SUGGESTED_PRICE";
4009      /**
4010       * For some products, the possible country of manufacture as a {@link String} denoting the
4011       * ISO country code. Some map to multiple possible countries, like "US/CA".
4012       */
4013      ResultMetadataType[ResultMetadataType["POSSIBLE_COUNTRY"] = 6] = "POSSIBLE_COUNTRY";
4014      /**
4015       * For some products, the extension text
4016       */
4017      ResultMetadataType[ResultMetadataType["UPC_EAN_EXTENSION"] = 7] = "UPC_EAN_EXTENSION";
4018      /**
4019       * PDF417-specific metadata
4020       */
4021      ResultMetadataType[ResultMetadataType["PDF417_EXTRA_METADATA"] = 8] = "PDF417_EXTRA_METADATA";
4022      /**
4023       * If the code format supports structured append and the current scanned code is part of one then the
4024       * sequence number is given with it.
4025       */
4026      ResultMetadataType[ResultMetadataType["STRUCTURED_APPEND_SEQUENCE"] = 9] = "STRUCTURED_APPEND_SEQUENCE";
4027      /**
4028       * If the code format supports structured append and the current scanned code is part of one then the
4029       * parity is given with it.
4030       */
4031      ResultMetadataType[ResultMetadataType["STRUCTURED_APPEND_PARITY"] = 10] = "STRUCTURED_APPEND_PARITY";
4032  })(ResultMetadataType || (ResultMetadataType = {}));
4033  var ResultMetadataType$1 = ResultMetadataType;
4034
4035  /*
4036   * Copyright 2007 ZXing authors
4037   *
4038   * Licensed under the Apache License, Version 2.0 (the "License");
4039   * you may not use this file except in compliance with the License.
4040   * You may obtain a copy of the License at
4041   *
4042   *      http://www.apache.org/licenses/LICENSE-2.0
4043   *
4044   * Unless required by applicable law or agreed to in writing, software
4045   * distributed under the License is distributed on an "AS IS" BASIS,
4046   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4047   * See the License for the specific language governing permissions and
4048   * limitations under the License.
4049   */
4050  /*namespace com.google.zxing.common {*/
4051  /*import java.util.List;*/
4052  /**
4053   * <p>Encapsulates the result of decoding a matrix of bits. This typically
4054   * applies to 2D barcode formats. For now it contains the raw bytes obtained,
4055   * as well as a String interpretation of those bytes, if applicable.</p>
4056   *
4057   * @author Sean Owen
4058   */
4059  class DecoderResult {
4060      // public constructor(rawBytes: Uint8Array,
4061      //                      text: string,
4062      //                      List<Uint8Array> byteSegments,
4063      //                      String ecLevel) {
4064      //   this(rawBytes, text, byteSegments, ecLevel, -1, -1)
4065      // }
4066      constructor(rawBytes, text, byteSegments, ecLevel, structuredAppendSequenceNumber = -1, structuredAppendParity = -1) {
4067          this.rawBytes = rawBytes;
4068          this.text = text;
4069          this.byteSegments = byteSegments;
4070          this.ecLevel = ecLevel;
4071          this.structuredAppendSequenceNumber = structuredAppendSequenceNumber;
4072          this.structuredAppendParity = structuredAppendParity;
4073          this.numBits = (rawBytes === undefined || rawBytes === null) ? 0 : 8 * rawBytes.length;
4074      }
4075      /**
4076       * @return raw bytes representing the result, or {@code null} if not applicable
4077       */
4078      getRawBytes() {
4079          return this.rawBytes;
4080      }
4081      /**
4082       * @return how many bits of {@link #getRawBytes()} are valid; typically 8 times its length
4083       * @since 3.3.0
4084       */
4085      getNumBits() {
4086          return this.numBits;
4087      }
4088      /**
4089       * @param numBits overrides the number of bits that are valid in {@link #getRawBytes()}
4090       * @since 3.3.0
4091       */
4092      setNumBits(numBits /*int*/) {
4093          this.numBits = numBits;
4094      }
4095      /**
4096       * @return text representation of the result
4097       */
4098      getText() {
4099          return this.text;
4100      }
4101      /**
vendor: 3,670 bytes, lines 4102-4217
4102       * @return list of byte segments in the result, or {@code null} if not applicable
4103       */
4104      getByteSegments() {
4105          return this.byteSegments;
4106      }
4107      /**
4108       * @return name of error correction level used, or {@code null} if not applicable
4109       */
4110      getECLevel() {
4111          return this.ecLevel;
4112      }
4113      /**
4114       * @return number of errors corrected, or {@code null} if not applicable
4115       */
4116      getErrorsCorrected() {
4117          return this.errorsCorrected;
4118      }
4119      setErrorsCorrected(errorsCorrected /*Integer*/) {
4120          this.errorsCorrected = errorsCorrected;
4121      }
4122      /**
4123       * @return number of erasures corrected, or {@code null} if not applicable
4124       */
4125      getErasures() {
4126          return this.erasures;
4127      }
4128      setErasures(erasures /*Integer*/) {
4129          this.erasures = erasures;
4130      }
4131      /**
4132       * @return arbitrary additional metadata
4133       */
4134      getOther() {
4135          return this.other;
4136      }
4137      setOther(other) {
4138          this.other = other;
4139      }
4140      hasStructuredAppend() {
4141          return this.structuredAppendParity >= 0 && this.structuredAppendSequenceNumber >= 0;
4142      }
4143      getStructuredAppendParity() {
4144          return this.structuredAppendParity;
4145      }
4146      getStructuredAppendSequenceNumber() {
4147          return this.structuredAppendSequenceNumber;
4148      }
4149  }
4150
4151  /*
4152   * Copyright 2007 ZXing authors
4153   *
4154   * Licensed under the Apache License, Version 2.0 (the "License");
4155   * you may not use this file except in compliance with the License.
4156   * You may obtain a copy of the License at
4157   *
4158   *      http://www.apache.org/licenses/LICENSE-2.0
4159   *
4160   * Unless required by applicable law or agreed to in writing, software
4161   * distributed under the License is distributed on an "AS IS" BASIS,
4162   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4163   * See the License for the specific language governing permissions and
4164   * limitations under the License.
4165   */
4166  /**
4167   * <p>This class contains utility methods for performing mathematical operations over
4168   * the Galois Fields. Operations use a given primitive polynomial in calculations.</p>
4169   *
4170   * <p>Throughout this package, elements of the GF are represented as an {@code int}
4171   * for convenience and speed (but at the cost of memory).
4172   * </p>
4173   *
4174   * @author Sean Owen
4175   * @author David Olivier
4176   */
4177  class AbstractGenericGF {
4178      /**
4179       * @return 2 to the power of a in GF(size)
4180       */
4181      exp(a) {
4182          return this.expTable[a];
4183      }
4184      /**
4185       * @return base 2 log of a in GF(size)
4186       */
4187      log(a /*int*/) {
4188          if (a === 0) {
4189              throw new IllegalArgumentException();
4190          }
4191          return this.logTable[a];
4192      }
4193      /**
4194       * Implements both addition and subtraction -- they are the same in GF(size).
4195       *
4196       * @return sum/difference of a and b
4197       */
4198      static addOrSubtract(a /*int*/, b /*int*/) {
4199          return a ^ b;
4200      }
4201  }
4202
4203  /*
4204   * Copyright 2007 ZXing authors
4205   *
4206   * Licensed under the Apache License, Version 2.0 (the "License");
4207   * you may not use this file except in compliance with the License.
4208   * You may obtain a copy of the License at
4209   *
4210   *      http://www.apache.org/licenses/LICENSE-2.0
4211   *
4212   * Unless required by applicable law or agreed to in writing, software
4213   * distributed under the License is distributed on an "AS IS" BASIS,
4214   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4215   * See the License for the specific language governing permissions and
4216   * limitations under the License.
4217   
vendor: 10,283 bytes, lines 4217-4475
4217*/
4218  /**
4219   * <p>Represents a polynomial whose coefficients are elements of a GF.
4220   * Instances of this class are immutable.</p>
4221   *
4222   * <p>Much credit is due to William Rucklidge since portions of this code are an indirect
4223   * port of his C++ Reed-Solomon implementation.</p>
4224   *
4225   * @author Sean Owen
4226   */
4227  class GenericGFPoly {
4228      /**
4229       * @param field the {@link GenericGF} instance representing the field to use
4230       * to perform computations
4231       * @param coefficients coefficients as ints representing elements of GF(size), arranged
4232       * from most significant (highest-power term) coefficient to least significant
4233       * @throws IllegalArgumentException if argument is null or empty,
4234       * or if leading coefficient is 0 and this is not a
4235       * constant polynomial (that is, it is not the monomial "0")
4236       */
4237      constructor(field, coefficients) {
4238          if (coefficients.length === 0) {
4239              throw new IllegalArgumentException();
4240          }
4241          this.field = field;
4242          const coefficientsLength = coefficients.length;
4243          if (coefficientsLength > 1 && coefficients[0] === 0) {
4244              // Leading term must be non-zero for anything except the constant polynomial "0"
4245              let firstNonZero = 1;
4246              while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) {
4247                  firstNonZero++;
4248              }
4249              if (firstNonZero === coefficientsLength) {
4250                  this.coefficients = Int32Array.from([0]);
4251              }
4252              else {
4253                  this.coefficients = new Int32Array(coefficientsLength - firstNonZero);
4254                  System.arraycopy(coefficients, firstNonZero, this.coefficients, 0, this.coefficients.length);
4255              }
4256          }
4257          else {
4258              this.coefficients = coefficients;
4259          }
4260      }
4261      getCoefficients() {
4262          return this.coefficients;
4263      }
4264      /**
4265       * @return degree of this polynomial
4266       */
4267      getDegree() {
4268          return this.coefficients.length - 1;
4269      }
4270      /**
4271       * @return true iff this polynomial is the monomial "0"
4272       */
4273      isZero() {
4274          return this.coefficients[0] === 0;
4275      }
4276      /**
4277       * @return coefficient of x^degree term in this polynomial
4278       */
4279      getCoefficient(degree /*int*/) {
4280          return this.coefficients[this.coefficients.length - 1 - degree];
4281      }
4282      /**
4283       * @return evaluation of this polynomial at a given point
4284       */
4285      evaluateAt(a /*int*/) {
4286          if (a === 0) {
4287              // Just return the x^0 coefficient
4288              return this.getCoefficient(0);
4289          }
4290          const coefficients = this.coefficients;
4291          let result;
4292          if (a === 1) {
4293              // Just the sum of the coefficients
4294              result = 0;
4295              for (let i = 0, length = coefficients.length; i !== length; i++) {
4296                  const coefficient = coefficients[i];
4297                  result = AbstractGenericGF.addOrSubtract(result, coefficient);
4298              }
4299              return result;
4300          }
4301          result = coefficients[0];
4302          const size = coefficients.length;
4303          const field = this.field;
4304          for (let i = 1; i < size; i++) {
4305              result = AbstractGenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);
4306          }
4307          return result;
4308      }
4309      addOrSubtract(other) {
4310          if (!this.field.equals(other.field)) {
4311              throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
4312          }
4313          if (this.isZero()) {
4314              return other;
4315          }
4316          if (other.isZero()) {
4317              return this;
4318          }
4319          let smallerCoefficients = this.coefficients;
4320          let largerCoefficients = other.coefficients;
4321          if (smallerCoefficients.length > largerCoefficients.length) {
4322              const temp = smallerCoefficients;
4323              smallerCoefficients = largerCoefficients;
4324              largerCoefficients = temp;
4325          }
4326          let sumDiff = new Int32Array(largerCoefficients.length);
4327          const lengthDiff = largerCoefficients.length - smallerCoefficients.length;
4328          // Copy high-order terms only found in higher-degree polynomial's coefficients
4329          System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
4330          for (let i = lengthDiff; i < largerCoefficients.length; i++) {
4331              sumDiff[i] = AbstractGenericGF.addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
4332          }
4333          return new GenericGFPoly(this.field, sumDiff);
4334      }
4335      multiply(other) {
4336          if (!this.field.equals(other.field)) {
4337              throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
4338          }
4339          if (this.isZero() || other.isZero()) {
4340              return this.field.getZero();
4341          }
4342          const aCoefficients = this.coefficients;
4343          const aLength = aCoefficients.length;
4344          const bCoefficients = other.coefficients;
4345          const bLength = bCoefficients.length;
4346          const product = new Int32Array(aLength + bLength - 1);
4347          const field = this.field;
4348          for (let i = 0; i < aLength; i++) {
4349              const aCoeff = aCoefficients[i];
4350              for (let j = 0; j < bLength; j++) {
4351                  product[i + j] = AbstractGenericGF.addOrSubtract(product[i + j], field.multiply(aCoeff, bCoefficients[j]));
4352              }
4353          }
4354          return new GenericGFPoly(field, product);
4355      }
4356      multiplyScalar(scalar /*int*/) {
4357          if (scalar === 0) {
4358              return this.field.getZero();
4359          }
4360          if (scalar === 1) {
4361              return this;
4362          }
4363          const size = this.coefficients.length;
4364          const field = this.field;
4365          const product = new Int32Array(size);
4366          const coefficients = this.coefficients;
4367          for (let i = 0; i < size; i++) {
4368              product[i] = field.multiply(coefficients[i], scalar);
4369          }
4370          return new GenericGFPoly(field, product);
4371      }
4372      multiplyByMonomial(degree /*int*/, coefficient /*int*/) {
4373          if (degree < 0) {
4374              throw new IllegalArgumentException();
4375          }
4376          if (coefficient === 0) {
4377              return this.field.getZero();
4378          }
4379          const coefficients = this.coefficients;
4380          const size = coefficients.length;
4381          const product = new Int32Array(size + degree);
4382          const field = this.field;
4383          for (let i = 0; i < size; i++) {
4384              product[i] = field.multiply(coefficients[i], coefficient);
4385          }
4386          return new GenericGFPoly(field, product);
4387      }
4388      divide(other) {
4389          if (!this.field.equals(other.field)) {
4390              throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
4391          }
4392          if (other.isZero()) {
4393              throw new IllegalArgumentException('Divide by 0');
4394          }
4395          const field = this.field;
4396          let quotient = field.getZero();
4397          let remainder = this;
4398          const denominatorLeadingTerm = other.getCoefficient(other.getDegree());
4399          const inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm);
4400          while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
4401              const degreeDifference = remainder.getDegree() - other.getDegree();
4402              const scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);
4403              const term = other.multiplyByMonomial(degreeDifference, scale);
4404              const iterationQuotient = field.buildMonomial(degreeDifference, scale);
4405              quotient = quotient.addOrSubtract(iterationQuotient);
4406              remainder = remainder.addOrSubtract(term);
4407          }
4408          return [quotient, remainder];
4409      }
4410      /*@Override*/
4411      toString() {
4412          let result = '';
4413          for (let degree = this.getDegree(); degree >= 0; degree--) {
4414              let coefficient = this.getCoefficient(degree);
4415              if (coefficient !== 0) {
4416                  if (coefficient < 0) {
4417                      result += ' - ';
4418                      coefficient = -coefficient;
4419                  }
4420                  else {
4421                      if (result.length > 0) {
4422                          result += ' + ';
4423                      }
4424                  }
4425                  if (degree === 0 || coefficient !== 1) {
4426                      const alphaPower = this.field.log(coefficient);
4427                      if (alphaPower === 0) {
4428                          result += '1';
4429                      }
4430                      else if (alphaPower === 1) {
4431                          result += 'a';
4432                      }
4433                      else {
4434                          result += 'a^';
4435                          result += alphaPower;
4436                      }
4437                  }
4438                  if (degree !== 0) {
4439                      if (degree === 1) {
4440                          result += 'x';
4441                      }
4442                      else {
4443                          result += 'x^';
4444                          result += degree;
4445                      }
4446                  }
4447              }
4448          }
4449          return result;
4450      }
4451  }
4452
4453  /**
4454   * Custom Error class of type Exception.
4455   */
4456  class ArithmeticException extends Exception {
4457  }
4458  ArithmeticException.kind = 'ArithmeticException';
4459
4460  /*
4461   * Copyright 2007 ZXing authors
4462   *
4463   * Licensed under the Apache License, Version 2.0 (the "License");
4464   * you may not use this file except in compliance with the License.
4465   * You may obtain a copy of the License at
4466   *
4467   *      http://www.apache.org/licenses/LICENSE-2.0
4468   *
4469   * Unless required by applicable law or agreed to in writing, software
4470   * distributed under the License is distributed on an "AS IS" BASIS,
4471   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4472   * See the License for the specific language governing permissions and
4473   * limitations under the License.
4474   */
4475  /*
4475*
4476   * <p>This class contains utility methods for performing mathematical operations over
4477   * the Galois Fields. Operations use a given primitive polynomial in calculations.</p>
4478   *
4479   * <p>Throughout this package, elements of the GF are represented as an {@code int}
4480   * for convenience and speed (but at the cost of memory).
4481   * </p>
4482   *
4483   * @author Sean Owen
4484   * @author David Olivier
4485   */
4486  class GenericGF extends AbstractGenericGF {
4487      /**
4488       * Create a representation of GF(size) using the given primitive polynomial.
4489       *
4490       * @param primitive irreducible polynomial whose coefficients are represented by
4491       *  the bits of an int, where the least-significant bit represents the constant
4492       *  coefficient
4493       * @param size the size of the field
4494       * @param b the factor b in the generator polynomial can be 0- or 1-based
4495       *  (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
4496       *  In most cases it should be 1, but for QR code it is 0.
4497       */
4498      constructor(primitive /*int*/, size /*int*/, generatorBase /*int*/) {
4499          super();
4500          this.primitive = primitive;
4501          this.size = size;
4502          this.generatorBase = generatorBase;
4503          const expTable = new Int32Array(size);
4504          let x = 1;
4505          for (let i = 0; i < size; i++) {
4506              expTable[i] = x;
4507              x *= 2; // we're assuming the generator alpha is 2
4508              if (x >= size) {
4509                  x ^= primitive;
4510                  x &= size - 1;
4511              }
4512          }
4513          this.expTable = expTable;
4514          const logTable = new Int32Array(size);
4515          for (let i = 0; i < size - 1; i++) {
4516              logTable[expTable[i]] = i;
4517          }
4518          this.logTable = logTable;
4519          // logTable[0] == 0 but this should never be used
4520          this.zero = new GenericGFPoly(this, Int32Array.from([0]));
4521          this.one = new GenericGFPoly(this, Int32Array.from([1]));
4522      }
4523      getZero() {
4524          return this.zero;
4525      }
4526      getOne() {
4527          return this.one;
4528      }
4529      /**
4530       * @return the monomial representing coefficient * x^degree
4531       */
4532      buildMonomial(degree /*int*/, coefficient /*int*/) {
4533          if (degree < 0) {
4534              throw new IllegalArgumentException();
4535          }
4536          if (coefficient === 0) {
4537              return this.zero;
4538          }
4539          const coefficients = new Int32Array(degree + 1);
4540          coefficients[0] = coefficient;
4541          return new GenericGFPoly(this, coefficients);
4542      }
4543      /**
4544       * @return multiplicative inverse of a
4545       */
4546      inverse(a /*int*/) {
4547          if (a === 0) {
4548              throw new ArithmeticException();
4549          }
4550          return this.expTable[this.size - this.logTable[a] - 1];
4551      }
4552      /**
4553       * @return product of a and b in GF(size)
4554       */
4555      multiply(a /*int*/, b /*int*/) {
4556          if (a === 0 || b === 0) {
4557              return 0;
4558          }
4559          return this.expTable[(this.logTable[a] + this.logTable[b]) % (this.size - 1)];
4560      }
4561      getSize() {
4562          return this.size;
4563      }
4564      getGeneratorBase() {
4565          return this.generatorBase;
4566      }
4567      /*@Override*/
4568      toString() {
4569          return ('GF(0x' + Integer.toHexString(this.primitive) + ',' + this.size + ')');
4570      }
4571      equals(o) {
4572          return o === this;
4573      }
4574  }
4575  GenericGF.AZTEC_DATA_12 = new GenericGF(0x1069, 4096, 1); // x^12 + x^6 + x^5 + x^3 + 1
4576  GenericGF.AZTEC_DATA_10 = new GenericGF(0x409, 1024, 1); // x^10 + x^3 + 1
4577  GenericGF.AZTEC_DATA_6 = new GenericGF(0x43, 64, 1); // x^6 + x + 1
4578  GenericGF.AZTEC_PARAM = new GenericGF(0x13, 16, 1); // x^4 + x + 1
4579  GenericGF.QR_CODE_FIELD_256 = new GenericGF(0x011d, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1
4580  GenericGF.DATA_MATRIX_FIELD_256 = new GenericGF(0x012d, 256, 1); // x^8 + x^5 + x^3 + x^2 + 1
4581  GenericGF.AZTEC_DATA_8 = GenericGF.DATA_MATRIX_FIELD_256;
4582  GenericGF.MAXICODE_FIELD_64 = GenericGF.AZTEC_DATA_6;
4583
4584  /**
4585   * Custom Error class of type Exception.
4586   */
vendor: 22,439 bytes, lines 4587-5116
4587  class ReedSolomonException extends Exception {
4588  }
4589  ReedSolomonException.kind = 'ReedSolomonException';
4590
4591  /**
4592   * Custom Error class of type Exception.
4593   */
4594  class IllegalStateException extends Exception {
4595  }
4596  IllegalStateException.kind = 'IllegalStateException';
4597
4598  /*
4599   * Copyright 2007 ZXing authors
4600   *
4601   * Licensed under the Apache License, Version 2.0 (the "License");
4602   * you may not use this file except in compliance with the License.
4603   * You may obtain a copy of the License at
4604   *
4605   *      http://www.apache.org/licenses/LICENSE-2.0
4606   *
4607   * Unless required by applicable law or agreed to in writing, software
4608   * distributed under the License is distributed on an "AS IS" BASIS,
4609   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4610   * See the License for the specific language governing permissions and
4611   * limitations under the License.
4612   */
4613  /**
4614   * <p>Implements Reed-Solomon decoding, as the name implies.</p>
4615   *
4616   * <p>The algorithm will not be explained here, but the following references were helpful
4617   * in creating this implementation:</p>
4618   *
4619   * <ul>
4620   * <li>Bruce Maggs.
4621   * <a href="http://www.cs.cmu.edu/afs/cs.cmu.edu/project/pscico-guyb/realworld/www/rs_decode.ps">
4622   * "Decoding Reed-Solomon Codes"</a> (see discussion of Forney's Formula)</li>
4623   * <li>J.I. Hall. <a href="www.mth.msu.edu/~jhall/classes/codenotes/GRS.pdf">
4624   * "Chapter 5. Generalized Reed-Solomon Codes"</a>
4625   * (see discussion of Euclidean algorithm)</li>
4626   * </ul>
4627   *
4628   * <p>Much credit is due to William Rucklidge since portions of this code are an indirect
4629   * port of his C++ Reed-Solomon implementation.</p>
4630   *
4631   * @author Sean Owen
4632   * @author William Rucklidge
4633   * @author sanfordsquires
4634   */
4635  class ReedSolomonDecoder {
4636      constructor(field) {
4637          this.field = field;
4638      }
4639      /**
4640       * <p>Decodes given set of received codewords, which include both data and error-correction
4641       * codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
4642       * in the input.</p>
4643       *
4644       * @param received data and error-correction codewords
4645       * @param twoS number of error-correction codewords available
4646       * @throws ReedSolomonException if decoding fails for any reason
4647       */
4648      decode(received, twoS /*int*/) {
4649          const field = this.field;
4650          const poly = new GenericGFPoly(field, received);
4651          const syndromeCoefficients = new Int32Array(twoS);
4652          let noError = true;
4653          for (let i = 0; i < twoS; i++) {
4654              const evalResult = poly.evaluateAt(field.exp(i + field.getGeneratorBase()));
4655              syndromeCoefficients[syndromeCoefficients.length - 1 - i] = evalResult;
4656              if (evalResult !== 0) {
4657                  noError = false;
4658              }
4659          }
4660          if (noError) {
4661              return;
4662          }
4663          const syndrome = new GenericGFPoly(field, syndromeCoefficients);
4664          const sigmaOmega = this.runEuclideanAlgorithm(field.buildMonomial(twoS, 1), syndrome, twoS);
4665          const sigma = sigmaOmega[0];
4666          const omega = sigmaOmega[1];
4667          const errorLocations = this.findErrorLocations(sigma);
4668          const errorMagnitudes = this.findErrorMagnitudes(omega, errorLocations);
4669          for (let i = 0; i < errorLocations.length; i++) {
4670              const position = received.length - 1 - field.log(errorLocations[i]);
4671              if (position < 0) {
4672                  throw new ReedSolomonException('Bad error location');
4673              }
4674              received[position] = GenericGF.addOrSubtract(received[position], errorMagnitudes[i]);
4675          }
4676      }
4677      runEuclideanAlgorithm(a, b, R /*int*/) {
4678          // Assume a's degree is >= b's
4679          if (a.getDegree() < b.getDegree()) {
4680              const temp = a;
4681              a = b;
4682              b = temp;
4683          }
4684          const field = this.field;
4685          let rLast = a;
4686          let r = b;
4687          let tLast = field.getZero();
4688          let t = field.getOne();
4689          // Run Euclidean algorithm until r's degree is less than R/2
4690          while (r.getDegree() >= (R / 2 | 0)) {
4691              let rLastLast = rLast;
4692              let tLastLast = tLast;
4693              rLast = r;
4694              tLast = t;
4695              // Divide rLastLast by rLast, with quotient in q and remainder in r
4696              if (rLast.isZero()) {
4697                  // Oops, Euclidean algorithm already terminated?
4698                  throw new ReedSolomonException('r_{i-1} was zero');
4699              }
4700              r = rLastLast;
4701              let q = field.getZero();
4702              const denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
4703              const dltInverse = field.inverse(denominatorLeadingTerm);
4704              while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
4705                  const degreeDiff = r.getDegree() - rLast.getDegree();
4706                  const scale = field.multiply(r.getCoefficient(r.getDegree()), dltInverse);
4707                  q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale));
4708                  r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));
4709              }
4710              t = q.multiply(tLast).addOrSubtract(tLastLast);
4711              if (r.getDegree() >= rLast.getDegree()) {
4712                  throw new IllegalStateException('Division algorithm failed to reduce polynomial?');
4713              }
4714          }
4715          const sigmaTildeAtZero = t.getCoefficient(0);
4716          if (sigmaTildeAtZero === 0) {
4717              throw new ReedSolomonException('sigmaTilde(0) was zero');
4718          }
4719          const inverse = field.inverse(sigmaTildeAtZero);
4720          const sigma = t.multiplyScalar(inverse);
4721          const omega = r.multiplyScalar(inverse);
4722          return [sigma, omega];
4723      }
4724      findErrorLocations(errorLocator) {
4725          // This is a direct application of Chien's search
4726          const numErrors = errorLocator.getDegree();
4727          if (numErrors === 1) { // shortcut
4728              return Int32Array.from([errorLocator.getCoefficient(1)]);
4729          }
4730          const result = new Int32Array(numErrors);
4731          let e = 0;
4732          const field = this.field;
4733          for (let i = 1; i < field.getSize() && e < numErrors; i++) {
4734              if (errorLocator.evaluateAt(i) === 0) {
4735                  result[e] = field.inverse(i);
4736                  e++;
4737              }
4738          }
4739          if (e !== numErrors) {
4740              throw new ReedSolomonException('Error locator degree does not match number of roots');
4741          }
4742          return result;
4743      }
4744      findErrorMagnitudes(errorEvaluator, errorLocations) {
4745          // This is directly applying Forney's Formula
4746          const s = errorLocations.length;
4747          const result = new Int32Array(s);
4748          const field = this.field;
4749          for (let i = 0; i < s; i++) {
4750              const xiInverse = field.inverse(errorLocations[i]);
4751              let denominator = 1;
4752              for (let j = 0; j < s; j++) {
4753                  if (i !== j) {
4754                      // denominator = field.multiply(denominator,
4755                      //    GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)))
4756                      // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
4757                      // Below is a funny-looking workaround from Steven Parkes
4758                      const term = field.multiply(errorLocations[j], xiInverse);
4759                      const termPlus1 = (term & 0x1) === 0 ? term | 1 : term & ~1;
4760                      denominator = field.multiply(denominator, termPlus1);
4761                  }
4762              }
4763              result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse), field.inverse(denominator));
4764              if (field.getGeneratorBase() !== 0) {
4765                  result[i] = field.multiply(result[i], xiInverse);
4766              }
4767          }
4768          return result;
4769      }
4770  }
4771
4772  /*
4773   * Copyright 2010 ZXing authors
4774   *
4775   * Licensed under the Apache License, Version 2.0 (the "License");
4776   * you may not use this file except in compliance with the License.
4777   * You may obtain a copy of the License at
4778   *
4779   *      http://www.apache.org/licenses/LICENSE-2.0
4780   *
4781   * Unless required by applicable law or agreed to in writing, software
4782   * distributed under the License is distributed on an "AS IS" BASIS,
4783   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4784   * See the License for the specific language governing permissions and
4785   * limitations under the License.
4786   */
4787  // import java.util.Arrays;
4788  var Table;
4789  (function (Table) {
4790      Table[Table["UPPER"] = 0] = "UPPER";
4791      Table[Table["LOWER"] = 1] = "LOWER";
4792      Table[Table["MIXED"] = 2] = "MIXED";
4793      Table[Table["DIGIT"] = 3] = "DIGIT";
4794      Table[Table["PUNCT"] = 4] = "PUNCT";
4795      Table[Table["BINARY"] = 5] = "BINARY";
4796  })(Table || (Table = {}));
4797  /**
4798   * <p>The main class which implements Aztec Code decoding -- as opposed to locating and extracting
4799   * the Aztec Code from an image.</p>
4800   *
4801   * @author David Olivier
4802   */
4803  class Decoder$2 {
4804      decode(detectorResult) {
4805          this.ddata = detectorResult;
4806          let matrix = detectorResult.getBits();
4807          let rawbits = this.extractBits(matrix);
4808          let correctedBits = this.correctBits(rawbits);
4809          let rawBytes = Decoder$2.convertBoolArrayToByteArray(correctedBits);
4810          let result = Decoder$2.getEncodedData(correctedBits);
4811          let decoderResult = new DecoderResult(rawBytes, result, null, null);
4812          decoderResult.setNumBits(correctedBits.length);
4813          return decoderResult;
4814      }
4815      // This method is used for testing the high-level encoder
4816      static highLevelDecode(correctedBits) {
4817          return this.getEncodedData(correctedBits);
4818      }
4819      /**
4820       * Gets the string encoded in the aztec code bits
4821       *
4822       * @return the decoded string
4823       */
4824      static getEncodedData(correctedBits) {
4825          let endIndex = correctedBits.length;
4826          let latchTable = Table.UPPER; // table most recently latched to
4827          let shiftTable = Table.UPPER; // table to use for the next read
4828          let result = '';
4829          let index = 0;
4830          while (index < endIndex) {
4831              if (shiftTable === Table.BINARY) {
4832                  if (endIndex - index < 5) {
4833                      break;
4834                  }
4835                  let length = Decoder$2.readCode(correctedBits, index, 5);
4836                  index += 5;
4837                  if (length === 0) {
4838                      if (endIndex - index < 11) {
4839                          break;
4840                      }
4841                      length = Decoder$2.readCode(correctedBits, index, 11) + 31;
4842                      index += 11;
4843                  }
4844                  for (let charCount = 0; charCount < length; charCount++) {
4845                      if (endIndex - index < 8) {
4846                          index = endIndex; // Force outer loop to exit
4847                          break;
4848                      }
4849                      const code = Decoder$2.readCode(correctedBits, index, 8);
4850                      result += /*(char)*/ StringUtils.castAsNonUtf8Char(code);
4851                      index += 8;
4852                  }
4853                  // Go back to whatever mode we had been in
4854                  shiftTable = latchTable;
4855              }
4856              else {
4857                  let size = shiftTable === Table.DIGIT ? 4 : 5;
4858                  if (endIndex - index < size) {
4859                      break;
4860                  }
4861                  let code = Decoder$2.readCode(correctedBits, index, size);
4862                  index += size;
4863                  let str = Decoder$2.getCharacter(shiftTable, code);
4864                  if (str.startsWith('CTRL_')) {
4865                      // Table changes
4866                      // ISO/IEC 24778:2008 prescribes ending a shift sequence in the mode from which it was invoked.
4867                      // That's including when that mode is a shift.
4868                      // Our test case dlusbs.png for issue #642 exercises that.
4869                      latchTable = shiftTable; // Latch the current mode, so as to return to Upper after U/S B/S
4870                      shiftTable = Decoder$2.getTable(str.charAt(5));
4871                      if (str.charAt(6) === 'L') {
4872                          latchTable = shiftTable;
4873                      }
4874                  }
4875                  else {
4876                      result += str;
4877                      // Go back to whatever mode we had been in
4878                      shiftTable = latchTable;
4879                  }
4880              }
4881          }
4882          return result;
4883      }
4884      /**
4885       * gets the table corresponding to the char passed
4886       */
4887      static getTable(t) {
4888          switch (t) {
4889              case 'L':
4890                  return Table.LOWER;
4891              case 'P':
4892                  return Table.PUNCT;
4893              case 'M':
4894                  return Table.MIXED;
4895              case 'D':
4896                  return Table.DIGIT;
4897              case 'B':
4898                  return Table.BINARY;
4899              case 'U':
4900              default:
4901                  return Table.UPPER;
4902          }
4903      }
4904      /**
4905       * Gets the character (or string) corresponding to the passed code in the given table
4906       *
4907       * @param table the table used
4908       * @param code the code of the character
4909       */
4910      static getCharacter(table, code) {
4911          switch (table) {
4912              case Table.UPPER:
4913                  return Decoder$2.UPPER_TABLE[code];
4914              case Table.LOWER:
4915                  return Decoder$2.LOWER_TABLE[code];
4916              case Table.MIXED:
4917                  return Decoder$2.MIXED_TABLE[code];
4918              case Table.PUNCT:
4919                  return Decoder$2.PUNCT_TABLE[code];
4920              case Table.DIGIT:
4921                  return Decoder$2.DIGIT_TABLE[code];
4922              default:
4923                  // Should not reach here.
4924                  throw new IllegalStateException('Bad table');
4925          }
4926      }
4927      /**
4928       * <p>Performs RS error correction on an array of bits.</p>
4929       *
4930       * @return the corrected array
4931       * @throws FormatException if the input contains too many errors
4932       */
4933      correctBits(rawbits) {
4934          let gf;
4935          let codewordSize;
4936          if (this.ddata.getNbLayers() <= 2) {
4937              codewordSize = 6;
4938              gf = GenericGF.AZTEC_DATA_6;
4939          }
4940          else if (this.ddata.getNbLayers() <= 8) {
4941              codewordSize = 8;
4942              gf = GenericGF.AZTEC_DATA_8;
4943          }
4944          else if (this.ddata.getNbLayers() <= 22) {
4945              codewordSize = 10;
4946              gf = GenericGF.AZTEC_DATA_10;
4947          }
4948          else {
4949              codewordSize = 12;
4950              gf = GenericGF.AZTEC_DATA_12;
4951          }
4952          let numDataCodewords = this.ddata.getNbDatablocks();
4953          let numCodewords = rawbits.length / codewordSize;
4954          if (numCodewords < numDataCodewords) {
4955              throw new FormatException();
4956          }
4957          let offset = rawbits.length % codewordSize;
4958          let dataWords = new Int32Array(numCodewords);
4959          for (let i = 0; i < numCodewords; i++, offset += codewordSize) {
4960              dataWords[i] = Decoder$2.readCode(rawbits, offset, codewordSize);
4961          }
4962          try {
4963              let rsDecoder = new ReedSolomonDecoder(gf);
4964              rsDecoder.decode(dataWords, numCodewords - numDataCodewords);
4965          }
4966          catch (ex) {
4967              throw new FormatException(ex);
4968          }
4969          // Now perform the unstuffing operation.
4970          // First, count how many bits are going to be thrown out as stuffing
4971          let mask = (1 << codewordSize) - 1;
4972          let stuffedBits = 0;
4973          for (let i = 0; i < numDataCodewords; i++) {
4974              let dataWord = dataWords[i];
4975              if (dataWord === 0 || dataWord === mask) {
4976                  throw new FormatException();
4977              }
4978              else if (dataWord === 1 || dataWord === mask - 1) {
4979                  stuffedBits++;
4980              }
4981          }
4982          // Now, actually unpack the bits and remove the stuffing
4983          let correctedBits = new Array(numDataCodewords * codewordSize - stuffedBits);
4984          let index = 0;
4985          for (let i = 0; i < numDataCodewords; i++) {
4986              let dataWord = dataWords[i];
4987              if (dataWord === 1 || dataWord === mask - 1) {
4988                  // next codewordSize-1 bits are all zeros or all ones
4989                  correctedBits.fill(dataWord > 1, index, index + codewordSize - 1);
4990                  // Arrays.fill(correctedBits, index, index + codewordSize - 1, dataWord > 1);
4991                  index += codewordSize - 1;
4992              }
4993              else {
4994                  for (let bit = codewordSize - 1; bit >= 0; --bit) {
4995                      correctedBits[index++] = (dataWord & (1 << bit)) !== 0;
4996                  }
4997              }
4998          }
4999          return correctedBits;
5000      }
5001      /**
5002       * Gets the array of bits from an Aztec Code matrix
5003       *
5004       * @return the array of bits
5005       */
5006      extractBits(matrix) {
5007          let compact = this.ddata.isCompact();
5008          let layers = this.ddata.getNbLayers();
5009          let baseMatrixSize = (compact ? 11 : 14) + layers * 4; // not including alignment lines
5010          let alignmentMap = new Int32Array(baseMatrixSize);
5011          let rawbits = new Array(this.totalBitsInLayer(layers, compact));
5012          if (compact) {
5013              for (let i = 0; i < alignmentMap.length; i++) {
5014                  alignmentMap[i] = i;
5015              }
5016          }
5017          else {
5018              let matrixSize = baseMatrixSize + 1 + 2 * Integer.truncDivision((Integer.truncDivision(baseMatrixSize, 2) - 1), 15);
5019              let origCenter = baseMatrixSize / 2;
5020              let center = Integer.truncDivision(matrixSize, 2);
5021              for (let i = 0; i < origCenter; i++) {
5022                  let newOffset = i + Integer.truncDivision(i, 15);
5023                  alignmentMap[origCenter - i - 1] = center - newOffset - 1;
5024                  alignmentMap[origCenter + i] = center + newOffset + 1;
5025              }
5026          }
5027          for (let i = 0, rowOffset = 0; i < layers; i++) {
5028              let rowSize = (layers - i) * 4 + (compact ? 9 : 12);
5029              // The top-left most point of this layer is <low, low> (not including alignment lines)
5030              let low = i * 2;
5031              // The bottom-right most point of this layer is <high, high> (not including alignment lines)
5032              let high = baseMatrixSize - 1 - low;
5033              // We pull bits from the two 2 x rowSize columns and two rowSize x 2 rows
5034              for (let j = 0; j < rowSize; j++) {
5035                  let columnOffset = j * 2;
5036                  for (let k = 0; k < 2; k++) {
5037                      // left column
5038                      rawbits[rowOffset + columnOffset + k] =
5039                          matrix.get(alignmentMap[low + k], alignmentMap[low + j]);
5040                      // bottom row
5041                      rawbits[rowOffset + 2 * rowSize + columnOffset + k] =
5042                          matrix.get(alignmentMap[low + j], alignmentMap[high - k]);
5043                      // right column
5044                      rawbits[rowOffset + 4 * rowSize + columnOffset + k] =
5045                          matrix.get(alignmentMap[high - k], alignmentMap[high - j]);
5046                      // top row
5047                      rawbits[rowOffset + 6 * rowSize + columnOffset + k] =
5048                          matrix.get(alignmentMap[high - j], alignmentMap[low + k]);
5049                  }
5050              }
5051              rowOffset += rowSize * 8;
5052          }
5053          return rawbits;
5054      }
5055      /**
5056       * Reads a code of given length and at given index in an array of bits
5057       */
5058      static readCode(rawbits, startIndex, length) {
5059          let res = 0;
5060          for (let i = startIndex; i < startIndex + length; i++) {
5061              res <<= 1;
5062              if (rawbits[i]) {
5063                  res |= 0x01;
5064              }
5065          }
5066          return res;
5067      }
5068      /**
5069       * Reads a code of length 8 in an array of bits, padding with zeros
5070       */
5071      static readByte(rawbits, startIndex) {
5072          let n = rawbits.length - startIndex;
5073          if (n >= 8) {
5074              return Decoder$2.readCode(rawbits, startIndex, 8);
5075          }
5076          return Decoder$2.readCode(rawbits, startIndex, n) << (8 - n);
5077      }
5078      /**
5079       * Packs a bit array into bytes, most significant bit first
5080       */
5081      static convertBoolArrayToByteArray(boolArr) {
5082          let byteArr = new Uint8Array((boolArr.length + 7) / 8);
5083          for (let i = 0; i < byteArr.length; i++) {
5084              byteArr[i] = Decoder$2.readByte(boolArr, 8 * i);
5085          }
5086          return byteArr;
5087      }
5088      totalBitsInLayer(layers, compact) {
5089          return ((compact ? 88 : 112) + 16 * layers) * layers;
5090      }
5091  }
5092  Decoder$2.UPPER_TABLE = [
5093      'CTRL_PS', ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
5094      'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'CTRL_LL', 'CTRL_ML', 'CTRL_DL', 'CTRL_BS'
5095  ];
5096  Decoder$2.LOWER_TABLE = [
5097      'CTRL_PS', ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
5098      'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'CTRL_US', 'CTRL_ML', 'CTRL_DL', 'CTRL_BS'
5099  ];
5100  Decoder$2.MIXED_TABLE = [
5101      'CTRL_PS', ' ', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\b', '\t', '\n',
5102      '\x0b', '\f', '\r', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', '@', '\\', '^', '_',
5103      '`', '|', '~', '\x7f', 'CTRL_LL', 'CTRL_UL', 'CTRL_PL', 'CTRL_BS'
5104  ];
5105  Decoder$2.PUNCT_TABLE = [
5106      '', '\r', '\r\n', '. ', ', ', ': ', '!', '"', '#', '$', '%', '&', '\'', '(', ')',
5107      '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '[', ']', '{', '}', 'CTRL_UL'
5108  ];
5109  Decoder$2.DIGIT_TABLE = [
5110      'CTRL_PS', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '.', 'CTRL_UL', 'CTRL_US'
5111  ];
5112
5113  /*
5114   * Copyright 2012 ZXing authors
5115   *
5116   * Licensed under the Apache License, Version 2.0 (the "License");
5117   * you may not use this file except in compliance with the License.
5118   * You may obtain a copy of the License at
5119   *
5120   *      http://www.apache.org/licenses/LICENSE-2.0
5121   *
5122   * Unless required by applicable law or agreed to in writing, software
5123   * distributed under the License is distributed on an "AS IS" BASIS,
5124   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5125   * See the License for the specific language governing permissions and
5126   * limitations under the License.
5127   */
5128  /*namespace com.google.zxing.common.detector {*/
5129  /**
5130   * General math-related and numeric utility functions.
5131   */
5132  class MathUtils {
5133      constructor() { }
5134      /**
5135       * Ends up being a bit faster than {@link Math#round(float)}. This merely rounds its
5136       * argument to the nearest int, where x.5 rounds up to x+1. Semantics of this shortcut
5137       * differ slightly from {@link Math#round(float)} in that half rounds down for negative
5138       * values. -2.5 rounds to -3, not -2. For purposes here it makes no difference.
5139       *
5140       * @param d real value to round
5141       * @return nearest {@code int}
5142       */
5143      static round(d /*float*/) {
5144          if (isNaN(d))
5145              return 0;
5146          if (d <= Number.MIN_SAFE_INTEGER)
5147              return Number.MIN_SAFE_INTEGER;
5148          if (d >= Number.MAX_SAFE_INTEGER)
5149              return Number.MAX_SAFE_INTEGER;
5150          return /*(int) */ (d + (d < 0.0 ? -0.5 : 0.5)) | 0;
5151      }
5152      // TYPESCRIPTPORT: maybe remove round method and call directly Math.round, it looks like it doesn't make sense for js
5153      /**
5154       * @param aX point A x coordinate
5155       * @param aY point A y coordinate
5156       * @param bX point B x coordinate
5157       * @param bY point B y coordinate
5158       * @return Euclidean distance between points A and B
5159       */
5160      static distance(aX /*float|int*/, aY /*float|int*/, bX /*float|int*/, bY /*float|int*/) {
5161          const xDiff = aX - bX;
5162          const yDiff = aY - bY;
5163          return /*(float) */ Math.sqrt(xDiff * xDiff + yDiff * yDiff);
5164      }
5165      /**
5166       * @param aX point A x coordinate
5167       * @param aY point A y coordinate
5168       * @param bX point B x coordinate
5169       * @param bY point B y coordinate
5170       * @return Euclidean distance between points A and B
5171       */
5172      // public static distance(aX: number /*int*/, aY: number /*int*/, bX: number /*int*/, bY: number /*int*/): float {
5173      //   const xDiff = aX - bX
5174      //   const yDiff = aY - bY
5175      //   return (float) Math.sqrt(xDiff * xDiff + yDiff * yDiff);
5176      // }
5177      /**
5178       * @param array values to sum
5179       * @return sum of values in array
5180       */
5181      static sum(array) {
5182          let count = 0;
5183          for (let i = 0, length = array.length; i !== length; i++) {
5184              const a = array[i];
5185              count += a;
5186          }
5187          return count;
5188      }
5189  }
5190
5191  /**
5192   * Ponyfill for Java's Float class.
5193   */
5194  class Float {
5195      /**
5196       * SincTS has no difference between int and float, there's all numbers,
5197       * this is used only to polyfill Java code.
5198       */
5199      static floatToIntBits(f) {
5200          return f;
5201      }
5202  }
5203  /**
5204   * The float max value in JS is the number max value.
5205   */
5206  Float.MAX_VALUE = Number.MAX_SAFE_INTEGER;
5207
5208  /*
5209   * Copyright 2007 ZXing authors
5210   *
5211   * Licensed under the Apache License, Version 2.0 (the "License");
5212   * you may not use this file except in compliance with the License.
5213   * You may obtain a copy of the License at
5214   *
5215   *      http://www.apache.org/licenses/LICENSE-2.0
5216   *
5217   * Unless required by applicable law or agreed to in writing, software
5218   * distributed under the License is distributed on an "AS IS" BASIS,
5219   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5220   * See the License for the specific language governing permissions and
5221   * limitations under the License.
5222   
vendor: 6,514 bytes, lines 5222-5406
5222*/
5223  /**
5224   * <p>Encapsulates a point of interest in an image containing a barcode. Typically, this
5225   * would be the location of a finder pattern or the corner of the barcode, for example.</p>
5226   *
5227   * @author Sean Owen
5228   */
5229  class ResultPoint {
5230      constructor(x, y) {
5231          this.x = x;
5232          this.y = y;
5233      }
5234      getX() {
5235          return this.x;
5236      }
5237      getY() {
5238          return this.y;
5239      }
5240      /*@Override*/
5241      equals(other) {
5242          if (other instanceof ResultPoint) {
5243              const otherPoint = other;
5244              return this.x === otherPoint.x && this.y === otherPoint.y;
5245          }
5246          return false;
5247      }
5248      /*@Override*/
5249      hashCode() {
5250          return 31 * Float.floatToIntBits(this.x) + Float.floatToIntBits(this.y);
5251      }
5252      /*@Override*/
5253      toString() {
5254          return '(' + this.x + ',' + this.y + ')';
5255      }
5256      /**
5257       * Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC
5258       * and BC is less than AC, and the angle between BC and BA is less than 180 degrees.
5259       *
5260       * @param patterns array of three {@code ResultPoint} to order
5261       */
5262      static orderBestPatterns(patterns) {
5263          // Find distances between pattern centers
5264          const zeroOneDistance = this.distance(patterns[0], patterns[1]);
5265          const oneTwoDistance = this.distance(patterns[1], patterns[2]);
5266          const zeroTwoDistance = this.distance(patterns[0], patterns[2]);
5267          let pointA;
5268          let pointB;
5269          let pointC;
5270          // Assume one closest to other two is B; A and C will just be guesses at first
5271          if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
5272              pointB = patterns[0];
5273              pointA = patterns[1];
5274              pointC = patterns[2];
5275          }
5276          else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
5277              pointB = patterns[1];
5278              pointA = patterns[0];
5279              pointC = patterns[2];
5280          }
5281          else {
5282              pointB = patterns[2];
5283              pointA = patterns[0];
5284              pointC = patterns[1];
5285          }
5286          // Use cross product to figure out whether A and C are correct or flipped.
5287          // This asks whether BC x BA has a positive z component, which is the arrangement
5288          // we want for A, B, C. If it's negative, then we've got it flipped around and
5289          // should swap A and C.
5290          if (this.crossProductZ(pointA, pointB, pointC) < 0.0) {
5291              const temp = pointA;
5292              pointA = pointC;
5293              pointC = temp;
5294          }
5295          patterns[0] = pointA;
5296          patterns[1] = pointB;
5297          patterns[2] = pointC;
5298      }
5299      /**
5300       * @param pattern1 first pattern
5301       * @param pattern2 second pattern
5302       * @return distance between two points
5303       */
5304      static distance(pattern1, pattern2) {
5305          return MathUtils.distance(pattern1.x, pattern1.y, pattern2.x, pattern2.y);
5306      }
5307      /**
5308       * Returns the z component of the cross product between vectors BC and BA.
5309       */
5310      static crossProductZ(pointA, pointB, pointC) {
5311          const bX = pointB.x;
5312          const bY = pointB.y;
5313          return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
5314      }
5315  }
5316
5317  /*
5318   * Copyright 2007 ZXing authors
5319   *
5320   * Licensed under the Apache License, Version 2.0 (the "License");
5321   * you may not use this file except in compliance with the License.
5322   * You may obtain a copy of the License at
5323   *
5324   *      http://www.apache.org/licenses/LICENSE-2.0
5325   *
5326   * Unless required by applicable law or agreed to in writing, software
5327   * distributed under the License is distributed on an "AS IS" BASIS,
5328   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5329   * See the License for the specific language governing permissions and
5330   * limitations under the License.
5331   */
5332  /**
5333   * <p>Encapsulates the result of detecting a barcode in an image. This includes the raw
5334   * matrix of black/white pixels corresponding to the barcode, and possibly points of interest
5335   * in the image, like the location of finder patterns or corners of the barcode in the image.</p>
5336   *
5337   * @author Sean Owen
5338   */
5339  class DetectorResult {
5340      constructor(bits, points) {
5341          this.bits = bits;
5342          this.points = points;
5343      }
5344      getBits() {
5345          return this.bits;
5346      }
5347      getPoints() {
5348          return this.points;
5349      }
5350  }
5351
5352  /*
5353   * Copyright 2010 ZXing authors
5354   *
5355   * Licensed under the Apache License, Version 2.0 (the "License");
5356   * you may not use this file except in compliance with the License.
5357   * You may obtain a copy of the License at
5358   *
5359   *      http://www.apache.org/licenses/LICENSE-2.0
5360   *
5361   * Unless required by applicable law or agreed to in writing, software
5362   * distributed under the License is distributed on an "AS IS" BASIS,
5363   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5364   * See the License for the specific language governing permissions and
5365   * limitations under the License.
5366   */
5367  /**
5368   * <p>Extends {@link DetectorResult} with more information specific to the Aztec format,
5369   * like the number of layers and whether it's compact.</p>
5370   *
5371   * @author Sean Owen
5372   */
5373  class AztecDetectorResult extends DetectorResult {
5374      constructor(bits, points, compact, nbDatablocks, nbLayers) {
5375          super(bits, points);
5376          this.compact = compact;
5377          this.nbDatablocks = nbDatablocks;
5378          this.nbLayers = nbLayers;
5379      }
5380      getNbLayers() {
5381          return this.nbLayers;
5382      }
5383      getNbDatablocks() {
5384          return this.nbDatablocks;
5385      }
5386      isCompact() {
5387          return this.compact;
5388      }
5389  }
5390
5391  /*
5392   * Copyright 2010 ZXing authors
5393   *
5394   * Licensed under the Apache License, Version 2.0 (the "License");
5395   * you may not use this file except in compliance with the License.
5396   * You may obtain a copy of the License at
5397   *
5398   *      http://www.apache.org/licenses/LICENSE-2.0
5399   *
5400   * Unless required by applicable law or agreed to in writing, software
5401   * distributed under the License is distributed on an "AS IS" BASIS,
5402   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5403   * See the License for the specific language governing permissions and
5404   * limitations under the License.
5405   */
5406  /*
5406*
5407   * <p>
5408   * Detects a candidate barcode-like rectangular region within an image. It
5409   * starts around the center of the image, increases the size of the candidate
5410   * region until it finds a white rectangular region. By keeping track of the
5411   * last black points it encountered, it determines the corners of the barcode.
5412   * </p>
5413   *
5414   * @author David Olivier
5415   */
5416  class WhiteRectangleDetector {
5417      // public constructor(private image: BitMatrix) /*throws NotFoundException*/ {
5418      //   this(image, INIT_SIZE, image.getWidth() / 2, image.getHeight() / 2)
5419      // }
5420      /**
5421       * @param image barcode image to find a rectangle in
5422       * @param initSize initial size of search area around center
5423       * @param x x position of search center
5424       * @param y y position of search center
5425       * @throws NotFoundException if image is too small to accommodate {@code initSize}
5426       */
5427      constructor(image, initSize /*int*/, x /*int*/, y /*int*/) {
5428          this.image = image;
5429          this.height = image.getHeight();
5430          this.width = image.getWidth();
5431          if (undefined === initSize || null === initSize) {
5432              initSize = WhiteRectangleDetector.INIT_SIZE;
5433          }
5434          if (undefined === x || null === x) {
5435              x = image.getWidth() / 2 | 0;
5436          }
5437          if (undefined === y || null === y) {
5438              y = image.getHeight() / 2 | 0;
5439          }
5440          const halfsize = initSize / 2 | 0;
5441          this.leftInit = x - halfsize;
5442          this.rightInit = x + halfsize;
5443          this.upInit = y - halfsize;
5444          this.downInit = y + halfsize;
5445          if (this.upInit < 0 || this.leftInit < 0 || this.downInit >= this.height || this.rightInit >= this.width) {
5446              throw new NotFoundException();
5447          }
5448      }
5449      /**
5450       * <p>
5451       * Detects a candidate barcode-like rectangular region within an image. It
5452       * starts around the center of the image, increases the size of the candidate
5453       * region until it finds a white rectangular region.
5454       * </p>
5455       *
5456       * @return {@link ResultPoint}[] describing the corners of the rectangular
5457       *         region. The first and last points are opposed on the diagonal, as
5458       *         are the second and third. The first point will be the topmost
5459       *         point and the last, the bottommost. The second point will be
5460       *         leftmost and the third, the rightmost
5461       * @throws NotFoundException if no Data Matrix Code can be found
5462       */
5463      detect() {
5464          let left = this.leftInit;
5465          let right = this.rightInit;
5466          let up = this.upInit;
5467          let down = this.downInit;
5468          let sizeExceeded = false;
vendor: 8,399 bytes, lines 5469-5683
5469          let aBlackPointFoundOnBorder = true;
5470          let atLeastOneBlackPointFoundOnBorder = false;
5471          let atLeastOneBlackPointFoundOnRight = false;
5472          let atLeastOneBlackPointFoundOnBottom = false;
5473          let atLeastOneBlackPointFoundOnLeft = false;
5474          let atLeastOneBlackPointFoundOnTop = false;
5475          const width = this.width;
5476          const height = this.height;
5477          while (aBlackPointFoundOnBorder) {
5478              aBlackPointFoundOnBorder = false;
5479              // .....
5480              // .   |
5481              // .....
5482              let rightBorderNotWhite = true;
5483              while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < width) {
5484                  rightBorderNotWhite = this.containsBlackPoint(up, down, right, false);
5485                  if (rightBorderNotWhite) {
5486                      right++;
5487                      aBlackPointFoundOnBorder = true;
5488                      atLeastOneBlackPointFoundOnRight = true;
5489                  }
5490                  else if (!atLeastOneBlackPointFoundOnRight) {
5491                      right++;
5492                  }
5493              }
5494              if (right >= width) {
5495                  sizeExceeded = true;
5496                  break;
5497              }
5498              // .....
5499              // .   .
5500              // .___.
5501              let bottomBorderNotWhite = true;
5502              while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < height) {
5503                  bottomBorderNotWhite = this.containsBlackPoint(left, right, down, true);
5504                  if (bottomBorderNotWhite) {
5505                      down++;
5506                      aBlackPointFoundOnBorder = true;
5507                      atLeastOneBlackPointFoundOnBottom = true;
5508                  }
5509                  else if (!atLeastOneBlackPointFoundOnBottom) {
5510                      down++;
5511                  }
5512              }
5513              if (down >= height) {
5514                  sizeExceeded = true;
5515                  break;
5516              }
5517              // .....
5518              // |   .
5519              // .....
5520              let leftBorderNotWhite = true;
5521              while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) {
5522                  leftBorderNotWhite = this.containsBlackPoint(up, down, left, false);
5523                  if (leftBorderNotWhite) {
5524                      left--;
5525                      aBlackPointFoundOnBorder = true;
5526                      atLeastOneBlackPointFoundOnLeft = true;
5527                  }
5528                  else if (!atLeastOneBlackPointFoundOnLeft) {
5529                      left--;
5530                  }
5531              }
5532              if (left < 0) {
5533                  sizeExceeded = true;
5534                  break;
5535              }
5536              // .___.
5537              // .   .
5538              // .....
5539              let topBorderNotWhite = true;
5540              while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) {
5541                  topBorderNotWhite = this.containsBlackPoint(left, right, up, true);
5542                  if (topBorderNotWhite) {
5543                      up--;
5544                      aBlackPointFoundOnBorder = true;
5545                      atLeastOneBlackPointFoundOnTop = true;
5546                  }
5547                  else if (!atLeastOneBlackPointFoundOnTop) {
5548                      up--;
5549                  }
5550              }
5551              if (up < 0) {
5552                  sizeExceeded = true;
5553                  break;
5554              }
5555              if (aBlackPointFoundOnBorder) {
5556                  atLeastOneBlackPointFoundOnBorder = true;
5557              }
5558          }
5559          if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
5560              const maxSize = right - left;
5561              let z = null;
5562              for (let i = 1; z === null && i < maxSize; i++) {
5563                  z = this.getBlackPointOnSegment(left, down - i, left + i, down);
5564              }
5565              if (z == null) {
5566                  throw new NotFoundException();
5567              }
5568              let t = null;
5569              // go down right
5570              for (let i = 1; t === null && i < maxSize; i++) {
5571                  t = this.getBlackPointOnSegment(left, up + i, left + i, up);
5572              }
5573              if (t == null) {
5574                  throw new NotFoundException();
5575              }
5576              let x = null;
5577              // go down left
5578              for (let i = 1; x === null && i < maxSize; i++) {
5579                  x = this.getBlackPointOnSegment(right, up + i, right - i, up);
5580              }
5581              if (x == null) {
5582                  throw new NotFoundException();
5583              }
5584              let y = null;
5585              // go up left
5586              for (let i = 1; y === null && i < maxSize; i++) {
5587                  y = this.getBlackPointOnSegment(right, down - i, right - i, down);
5588              }
5589              if (y == null) {
5590                  throw new NotFoundException();
5591              }
5592              return this.centerEdges(y, z, x, t);
5593          }
5594          else {
5595              throw new NotFoundException();
5596          }
5597      }
5598      getBlackPointOnSegment(aX /*float*/, aY /*float*/, bX /*float*/, bY /*float*/) {
5599          const dist = MathUtils.round(MathUtils.distance(aX, aY, bX, bY));
5600          const xStep = (bX - aX) / dist;
5601          const yStep = (bY - aY) / dist;
5602          const image = this.image;
5603          for (let i = 0; i < dist; i++) {
5604              const x = MathUtils.round(aX + i * xStep);
5605              const y = MathUtils.round(aY + i * yStep);
5606              if (image.get(x, y)) {
5607                  return new ResultPoint(x, y);
5608              }
5609          }
5610          return null;
5611      }
5612      /**
5613       * recenters the points of a constant distance towards the center
5614       *
5615       * @param y bottom most point
5616       * @param z left most point
5617       * @param x right most point
5618       * @param t top most point
5619       * @return {@link ResultPoint}[] describing the corners of the rectangular
5620       *         region. The first and last points are opposed on the diagonal, as
5621       *         are the second and third. The first point will be the topmost
5622       *         point and the last, the bottommost. The second point will be
5623       *         leftmost and the third, the rightmost
5624       */
5625      centerEdges(y, z, x, t) {
5626          //
5627          //       t            t
5628          //  z                      x
5629          //        x    OR    z
5630          //   y                    y
5631          //
5632          const yi = y.getX();
5633          const yj = y.getY();
5634          const zi = z.getX();
5635          const zj = z.getY();
5636          const xi = x.getX();
5637          const xj = x.getY();
5638          const ti = t.getX();
5639          const tj = t.getY();
5640          const CORR = WhiteRectangleDetector.CORR;
5641          if (yi < this.width / 2.0) {
5642              return [
5643                  new ResultPoint(ti - CORR, tj + CORR),
5644                  new ResultPoint(zi + CORR, zj + CORR),
5645                  new ResultPoint(xi - CORR, xj - CORR),
5646                  new ResultPoint(yi + CORR, yj - CORR)
5647              ];
5648          }
5649          else {
5650              return [
5651                  new ResultPoint(ti + CORR, tj + CORR),
5652                  new ResultPoint(zi + CORR, zj - CORR),
5653                  new ResultPoint(xi - CORR, xj + CORR),
5654                  new ResultPoint(yi - CORR, yj - CORR)
5655              ];
5656          }
5657      }
5658      /**
5659       * Determines whether a segment contains a black point
5660       *
5661       * @param a          min value of the scanned coordinate
5662       * @param b          max value of the scanned coordinate
5663       * @param fixed      value of fixed coordinate
5664       * @param horizontal set to true if scan must be horizontal, false if vertical
5665       * @return true if a black point has been found, else false.
5666       */
5667      containsBlackPoint(a /*int*/, b /*int*/, fixed /*int*/, horizontal) {
5668          const image = this.image;
5669          if (horizontal) {
5670              for (let x = a; x <= b; x++) {
5671                  if (image.get(x, fixed)) {
5672                      return true;
5673                  }
5674              }
5675          }
5676          else {
5677              for (let y = a; y <= b; y++) {
5678                  if (image.get(fixed, y)) {
5679                      return true;
5680                  }
5681              }
5682          }
5683          return false;
5684      }
5685  }
5686  WhiteRectangleDetector.INIT_SIZE = 10;
5687  WhiteRectangleDetector.CORR = 1;
5688
5689  /*
5690   * Copyright 2007 ZXing authors
5691   *
5692   * Licensed under the Apache License, Version 2.0 (the "License");
5693   * you may not use this file except in compliance with the License.
5694   * You may obtain a copy of the License at
5695   *
5696   *      http://www.apache.org/licenses/LICENSE-2.0
5697   *
5698   * Unless required by applicable law or agreed to in writing, software
5699   * distributed under the License is distributed on an "AS IS" BASIS,
5700   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5701   * See the License for the specific language governing permissions and
5702   * limitations under the License.
5703   */
5704  /**
5705   * Implementations of this class can, given locations of finder patterns for a QR code in an
5706   * image, sample the right points in the image to reconstruct the QR code, accounting for
5707   * perspective distortion. It is abstracted since it is relatively expensive and should be allowed
5708   * to take advantage of platform-specific optimized implementations, like Sun's Java Advanced
5709   * Imaging library, but which may not be available in other environments such as J2ME, and vice
5710   * versa.
5711   *
5712   * The implementation used can be controlled by calling {@link #setGridSampler(GridSampler)}
5713   * with an instance of a class which implements this interface.
5714   *
5715   * @author Sean Owen
5716   */
5717  class GridSampler {
5718      /**
5719       * <p>Checks a set of points that have been transformed to sample points on an image against
5720       * the image's dimensions to see if the point are even within the image.</p>
5721       *
5722       * <p>This method will actually "nudge" the endpoints back onto the image if they are found to be
5723       * barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder
5724       * patterns in an image where the QR Code runs all the way to the image border.</p>
5725       *
5726       * <p>For efficiency, the method will check points from either end of the line until one is found
5727       * to be within the image. Because the set of points are assumed to be linear, this is valid.</p>
5728       *
5729       * @param image image into which the points should map
5730       * @param points actual points in x1,y1,...,xn,yn form
5731       * @throws NotFoundException if an endpoint is lies outside the image boundaries
5732       */
5733      static checkAndNudgePoints(image, points) {
5734          const width = image.getWidth();
5735          const height
vendor: 8,418 bytes, lines 5735-5915
5735 = image.getHeight();
5736          // Check and nudge points from start until we see some that are OK:
5737          let nudged = true;
5738          for (let offset = 0; offset < points.length && nudged; offset += 2) {
5739              const x = Math.floor(points[offset]);
5740              const y = Math.floor(points[offset + 1]);
5741              if (x < -1 || x > width || y < -1 || y > height) {
5742                  throw new NotFoundException();
5743              }
5744              nudged = false;
5745              if (x === -1) {
5746                  points[offset] = 0.0;
5747                  nudged = true;
5748              }
5749              else if (x === width) {
5750                  points[offset] = width - 1;
5751                  nudged = true;
5752              }
5753              if (y === -1) {
5754                  points[offset + 1] = 0.0;
5755                  nudged = true;
5756              }
5757              else if (y === height) {
5758                  points[offset + 1] = height - 1;
5759                  nudged = true;
5760              }
5761          }
5762          // Check and nudge points from end:
5763          nudged = true;
5764          for (let offset = points.length - 2; offset >= 0 && nudged; offset -= 2) {
5765              const x = Math.floor(points[offset]);
5766              const y = Math.floor(points[offset + 1]);
5767              if (x < -1 || x > width || y < -1 || y > height) {
5768                  throw new NotFoundException();
5769              }
5770              nudged = false;
5771              if (x === -1) {
5772                  points[offset] = 0.0;
5773                  nudged = true;
5774              }
5775              else if (x === width) {
5776                  points[offset] = width - 1;
5777                  nudged = true;
5778              }
5779              if (y === -1) {
5780                  points[offset + 1] = 0.0;
5781                  nudged = true;
5782              }
5783              else if (y === height) {
5784                  points[offset + 1] = height - 1;
5785                  nudged = true;
5786              }
5787          }
5788      }
5789  }
5790
5791  /*
5792   * Copyright 2007 ZXing authors
5793   *
5794   * Licensed under the Apache License, Version 2.0 (the "License");
5795   * you may not use this file except in compliance with the License.
5796   * You may obtain a copy of the License at
5797   *
5798   *      http://www.apache.org/licenses/LICENSE-2.0
5799   *
5800   * Unless required by applicable law or agreed to in writing, software
5801   * distributed under the License is distributed on an "AS IS" BASIS,
5802   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5803   * See the License for the specific language governing permissions and
5804   * limitations under the License.
5805   */
5806  /*namespace com.google.zxing.common {*/
5807  /**
5808   * <p>This class implements a perspective transform in two dimensions. Given four source and four
5809   * destination points, it will compute the transformation implied between them. The code is based
5810   * directly upon section 3.4.2 of George Wolberg's "Digital Image Warping"; see pages 54-56.</p>
5811   *
5812   * @author Sean Owen
5813   */
5814  class PerspectiveTransform {
5815      constructor(a11 /*float*/, a21 /*float*/, a31 /*float*/, a12 /*float*/, a22 /*float*/, a32 /*float*/, a13 /*float*/, a23 /*float*/, a33 /*float*/) {
5816          this.a11 = a11;
5817          this.a21 = a21;
5818          this.a31 = a31;
5819          this.a12 = a12;
5820          this.a22 = a22;
5821          this.a32 = a32;
5822          this.a13 = a13;
5823          this.a23 = a23;
5824          this.a33 = a33;
5825      }
5826      static quadrilateralToQuadrilateral(x0 /*float*/, y0 /*float*/, x1 /*float*/, y1 /*float*/, x2 /*float*/, y2 /*float*/, x3 /*float*/, y3 /*float*/, x0p /*float*/, y0p /*float*/, x1p /*float*/, y1p /*float*/, x2p /*float*/, y2p /*float*/, x3p /*float*/, y3p /*float*/) {
5827          const qToS = PerspectiveTransform.quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);
5828          const sToQ = PerspectiveTransform.squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);
5829          return sToQ.times(qToS);
5830      }
5831      transformPoints(points) {
5832          const max = points.length;
5833          const a11 = this.a11;
5834          const a12 = this.a12;
5835          const a13 = this.a13;
5836          const a21 = this.a21;
5837          const a22 = this.a22;
5838          const a23 = this.a23;
5839          const a31 = this.a31;
5840          const a32 = this.a32;
5841          const a33 = this.a33;
5842          for (let i = 0; i < max; i += 2) {
5843              const x = points[i];
5844              const y = points[i + 1];
5845              const denominator = a13 * x + a23 * y + a33;
5846              points[i] = (a11 * x + a21 * y + a31) / denominator;
5847              points[i + 1] = (a12 * x + a22 * y + a32) / denominator;
5848          }
5849      }
5850      transformPointsWithValues(xValues, yValues) {
5851          const a11 = this.a11;
5852          const a12 = this.a12;
5853          const a13 = this.a13;
5854          const a21 = this.a21;
5855          const a22 = this.a22;
5856          const a23 = this.a23;
5857          const a31 = this.a31;
5858          const a32 = this.a32;
5859          const a33 = this.a33;
5860          const n = xValues.length;
5861          for (let i = 0; i < n; i++) {
5862              const x = xValues[i];
5863              const y = yValues[i];
5864              const denominator = a13 * x + a23 * y + a33;
5865              xValues[i] = (a11 * x + a21 * y + a31) / denominator;
5866              yValues[i] = (a12 * x + a22 * y + a32) / denominator;
5867          }
5868      }
5869      static squareToQuadrilateral(x0 /*float*/, y0 /*float*/, x1 /*float*/, y1 /*float*/, x2 /*float*/, y2 /*float*/, x3 /*float*/, y3 /*float*/) {
5870          const dx3 = x0 - x1 + x2 - x3;
5871          const dy3 = y0 - y1 + y2 - y3;
5872          if (dx3 === 0.0 && dy3 === 0.0) {
5873              // Affine
5874              return new PerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0.0, 0.0, 1.0);
5875          }
5876          else {
5877              const dx1 = x1 - x2;
5878              const dx2 = x3 - x2;
5879              const dy1 = y1 - y2;
5880              const dy2 = y3 - y2;
5881              const denominator = dx1 * dy2 - dx2 * dy1;
5882              const a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
5883              const a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
5884              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);
5885          }
5886      }
5887      static quadrilateralToSquare(x0 /*float*/, y0 /*float*/, x1 /*float*/, y1 /*float*/, x2 /*float*/, y2 /*float*/, x3 /*float*/, y3 /*float*/) {
5888          // Here, the adjoint serves as the inverse:
5889          return PerspectiveTransform.squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();
5890      }
5891      buildAdjoint() {
5892          // Adjoint is the transpose of the cofactor matrix:
5893          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);
5894      }
5895      times(other) {
5896          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);
5897      }
5898  }
5899
5900  /*
5901   * Copyright 2007 ZXing authors
5902   *
5903   * Licensed under the Apache License, Version 2.0 (the "License");
5904   * you may not use this file except in compliance with the License.
5905   * You may obtain a copy of the License at
5906   *
5907   *      http://www.apache.org/licenses/LICENSE-2.0
5908   *
5909   * Unless required by applicable law or agreed to in writing, software
5910   * distributed under the License is distributed on an "AS IS" BASIS,
5911   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5912   * See the License for the specific language governing permissions and
5913   * limitations under the License.
5914   */
5915  /*
vendor: 2,942 bytes, lines 5915-5967
5915*
5916   * @author Sean Owen
5917   */
5918  class DefaultGridSampler extends GridSampler {
5919      /*@Override*/
5920      sampleGrid(image, dimensionX /*int*/, dimensionY /*int*/, p1ToX /*float*/, p1ToY /*float*/, p2ToX /*float*/, p2ToY /*float*/, p3ToX /*float*/, p3ToY /*float*/, p4ToX /*float*/, p4ToY /*float*/, p1FromX /*float*/, p1FromY /*float*/, p2FromX /*float*/, p2FromY /*float*/, p3FromX /*float*/, p3FromY /*float*/, p4FromX /*float*/, p4FromY /*float*/) {
5921          const transform = PerspectiveTransform.quadrilateralToQuadrilateral(p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
5922          return this.sampleGridWithTransform(image, dimensionX, dimensionY, transform);
5923      }
5924      /*@Override*/
5925      sampleGridWithTransform(image, dimensionX /*int*/, dimensionY /*int*/, transform) {
5926          if (dimensionX <= 0 || dimensionY <= 0) {
5927              throw new NotFoundException();
5928          }
5929          const bits = new BitMatrix(dimensionX, dimensionY);
5930          const points = new Float32Array(2 * dimensionX);
5931          for (let y = 0; y < dimensionY; y++) {
5932              const max = points.length;
5933              const iValue = y + 0.5;
5934              for (let x = 0; x < max; x += 2) {
5935                  points[x] = (x / 2) + 0.5;
5936                  points[x + 1] = iValue;
5937              }
5938              transform.transformPoints(points);
5939              // Quick check to see if points transformed to something inside the image
5940              // sufficient to check the endpoints
5941              GridSampler.checkAndNudgePoints(image, points);
5942              try {
5943                  for (let x = 0; x < max; x += 2) {
5944                      if (image.get(Math.floor(points[x]), Math.floor(points[x + 1]))) {
5945                          // Black(-ish) pixel
5946                          bits.set(x / 2, y);
5947                      }
5948                  }
5949              }
5950              catch (aioobe /*: ArrayIndexOutOfBoundsException*/) {
5951                  // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
5952                  // transform gets "twisted" such that it maps a straight line of points to a set of points
5953                  // whose endpoints are in bounds, but others are not. There is probably some mathematical
5954                  // way to detect this about the transformation that I don't know yet.
5955                  // This results in an ugly runtime exception despite our clever checks above -- can't have
5956                  // that. We could check each point's coordinates but that feels duplicative. We settle for
5957                  // catching and wrapping ArrayIndexOutOfBoundsException.
5958                  throw new NotFoundException();
5959              }
5960          }
5961          return bits;
5962      }
5963  }
5964
5965  class GridSamplerInstance {
5966      /**
5967       * Sets the implementation of GridSampler used by the library. O
5967ne global
5968       * instance is stored, which may sound problematic. But, the implementation provided
5969       * ought to be appropriate for the entire platform, and all uses of this library
5970       * in the whole lifetime of the JVM. For instance, an Android activity can swap in
5971       * an implementation that takes advantage of native platform libraries.
5972       *
5973       * @param newGridSampler The platform-specific object to install.
5974       */
5975      static setGridSampler(newGridSampler) {
5976          GridSamplerInstance.gridSampler = newGridSampler;
5977      }
5978      /**
5979       * @return the current implementation of GridSampler
5980       */
5981      static getInstance() {
5982          return GridSamplerInstance.gridSampler;
5983      }
5984  }
5985  GridSamplerInstance.gridSampler = new DefaultGridSampler();
5986
5987  /*
5988   * Copyright 2010 ZXing authors
5989   *
5990   * Licensed under the Apache License, Version 2.0 (the "License");
5991   * you may not use this file except in compliance with the License.
5992   * You may obtain a copy of the License at
5993   *
5994   *      http://www.apache.org/licenses/LICENSE-2.0
5995   *
5996   * Unless required by applicable law or agreed to in writing, software
5997   * distributed under the License is distributed on an "AS IS" BASIS,
5998   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5999   * See the License for the specific language governing permissions and
6000   * limitations under the License.
6001   */
6002  class Point {
6003      constructor(x, y) {
6004          this.x = x;
6005          this.y = y;
6006      }
6007      toResultPoint() {
6008          return new ResultPoint(this.getX(), this.getY());
6009      }
6010      getX() {
6011          return this.x;
6012      }
6013      getY() {
6014          return this.y;
6015      }
6016  }
6017  /**
6018   * Encapsulates logic that can detect an Aztec Code in an image, even if the Aztec Code
6019   * is rotated or skewed, or partially obscured.
6020   *
6021   * @author David Olivier
6022   * @author Frank Yellin
6023   */
6024  class Detector$3 {
6025      constructor(image) {
6026          this.EXPECTED_CORNER_BITS = new Int32Array([
6027              0xee0,
6028              0x1dc,
6029              0x83b,
6030              0x707,
6031          ]);
6032          this.image = image;
6033      }
6034      detect() {
6035          return this.detectMirror(false);
6036      }
6037      /**
6038       * Detects an Aztec Code in an image.
6039       *
6040       * @param isMirror if true, image is a mirror-image of original
6041       * @return {@link AztecDetectorResult} encapsulating results of detecting an Aztec Code
6042       * @throws NotFoundException if no Aztec Code can be found
6043       */
6044      detectMirror(isMirror) {
6045          // 1. Get the center of the aztec matrix
6046          let pCenter = this.getMatrixCenter();
6047          // 2. Get the center points of the four diagonal points just outside the bull's eye
6048          //  [topRight, bottomRight, bottomLeft, topLeft]
6049          let bullsEyeCorners = this.getBullsEyeCorners(pCenter);
6050          if (isMirror) {
6051              let temp = bullsEyeCorners[0];
6052              bullsEyeCorners[0] = bullsEyeCorners[2];
6053              bullsEyeCorners[2] = temp;
6054          }
6055          // 3. Get the size of the matrix and other parameters from the bull's eye
6056          this.extractParameters(bullsEyeCorners);
6057          // 4. Sample the grid
6058          let bits = this.sampleGrid(this.image, bullsEyeCorners[this.shift % 4], bullsEyeCorners[(this.shift + 1) % 4], bullsEyeCorners[(this.shift + 2) % 4], bullsEyeCorners[(this.shift + 3) % 4]);
6059          // 5. Get the corners of the matrix.
6060          let corners = this.getMatrixCornerPoints(bullsEyeCorners);
6061          return new AztecDetectorResult(bits, corners, this.compact, this.nbDataBlocks, this.nbLayers);
6062      }
6063      /**
6064       * Extracts the number of data layers and data blocks from the layer around the bull's eye.
6065       *
6066       * @param bullsEyeCorners the array of bull's eye corners
6067       * @throws NotFoundException in case of too many errors or invalid parameters
6068       */
6069      extractParameters(bullsEyeCorners) {
6070          if (!this.isValidPoint(bullsEyeCorners[0]) || !this.isValidPoint(bullsEyeCorners[1]) ||
6071              !this.isValidPoint(bullsEyeCorners[2]) || !this.isValidPoint(bullsEyeCorners[3])) {
6072              throw new NotFoundException();
6073          }
6074          let length = 2 * this.nbCenterLayers;
6075          // Get the bits around the bull's eye
6076          let sides = new Int32Array([
6077              this.sampleLine(bullsEyeCorners[0], bullsEyeCorners[1], length),
6078              this.sampleLine(bullsEyeCorners[1], bullsEyeCorners[2], length),
6079              this.sampleLine(bullsEyeCorners[2], bullsEyeCorners[3], length),
vendor: 17,313 bytes, lines 6079-6462
6079
6080              this.sampleLine(bullsEyeCorners[3], bullsEyeCorners[0], length) // Top
6081          ]);
6082          // bullsEyeCorners[shift] is the corner of the bulls'eye that has three
6083          // orientation marks.
6084          // sides[shift] is the row/column that goes from the corner with three
6085          // orientation marks to the corner with two.
6086          this.shift = this.getRotation(sides, length);
6087          // Flatten the parameter bits into a single 28- or 40-bit long
6088          let parameterData = 0;
6089          for (let i = 0; i < 4; i++) {
6090              let side = sides[(this.shift + i) % 4];
6091              if (this.compact) {
6092                  // Each side of the form ..XXXXXXX. where Xs are parameter data
6093                  parameterData <<= 7;
6094                  parameterData += (side >> 1) & 0x7F;
6095              }
6096              else {
6097                  // Each side of the form ..XXXXX.XXXXX. where Xs are parameter data
6098                  parameterData <<= 10;
6099                  parameterData += ((side >> 2) & (0x1f << 5)) + ((side >> 1) & 0x1F);
6100              }
6101          }
6102          // Corrects parameter data using RS.  Returns just the data portion
6103          // without the error correction.
6104          let correctedData = this.getCorrectedParameterData(parameterData, this.compact);
6105          if (this.compact) {
6106              // 8 bits:  2 bits layers and 6 bits data blocks
6107              this.nbLayers = (correctedData >> 6) + 1;
6108              this.nbDataBlocks = (correctedData & 0x3F) + 1;
6109          }
6110          else {
6111              // 16 bits:  5 bits layers and 11 bits data blocks
6112              this.nbLayers = (correctedData >> 11) + 1;
6113              this.nbDataBlocks = (correctedData & 0x7FF) + 1;
6114          }
6115      }
6116      getRotation(sides, length) {
6117          // In a normal pattern, we expect to See
6118          //   **    .*             D       A
6119          //   *      *
6120          //
6121          //   .      *
6122          //   ..    ..             C       B
6123          //
6124          // Grab the 3 bits from each of the sides the form the locator pattern and concatenate
6125          // into a 12-bit integer.  Start with the bit at A
6126          let cornerBits = 0;
6127          sides.forEach((side, idx, arr) => {
6128              // XX......X where X's are orientation marks
6129              let t = ((side >> (length - 2)) << 1) + (side & 1);
6130              cornerBits = (cornerBits << 3) + t;
6131          });
6132          // for (var side in sides) {
6133          //     // XX......X where X's are orientation marks
6134          //     var t = ((side >> (length - 2)) << 1) + (side & 1);
6135          //     cornerBits = (cornerBits << 3) + t;
6136          // }
6137          // Mov the bottom bit to the top, so that the three bits of the locator pattern at A are
6138          // together.  cornerBits is now:
6139          //  3 orientation bits at A || 3 orientation bits at B || ... || 3 orientation bits at D
6140          cornerBits = ((cornerBits & 1) << 11) + (cornerBits >> 1);
6141          // The result shift indicates which element of BullsEyeCorners[] goes into the top-left
6142          // corner. Since the four rotation values have a Hamming distance of 8, we
6143          // can easily tolerate two errors.
6144          for (let shift = 0; shift < 4; shift++) {
6145              if (Integer.bitCount(cornerBits ^ this.EXPECTED_CORNER_BITS[shift]) <= 2) {
6146                  return shift;
6147              }
6148          }
6149          throw new NotFoundException();
6150      }
6151      /**
6152       * Corrects the parameter bits using Reed-Solomon algorithm.
6153       *
6154       * @param parameterData parameter bits
6155       * @param compact true if this is a compact Aztec code
6156       * @throws NotFoundException if the array contains too many errors
6157       */
6158      getCorrectedParameterData(parameterData, compact) {
6159          let numCodewords;
6160          let numDataCodewords;
6161          if (compact) {
6162              numCodewords = 7;
6163              numDataCodewords = 2;
6164          }
6165          else {
6166              numCodewords = 10;
6167              numDataCodewords = 4;
6168          }
6169          let numECCodewords = numCodewords - numDataCodewords;
6170          let parameterWords = new Int32Array(numCodewords);
6171          for (let i = numCodewords - 1; i >= 0; --i) {
6172              parameterWords[i] = parameterData & 0xF;
6173              parameterData >>= 4;
6174          }
6175          try {
6176              let rsDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM);
6177              rsDecoder.decode(parameterWords, numECCodewords);
6178          }
6179          catch (ignored) {
6180              throw new NotFoundException();
6181          }
6182          // Toss the error correction.  Just return the data as an integer
6183          let result = 0;
6184          for (let i = 0; i < numDataCodewords; i++) {
6185              result = (result << 4) + parameterWords[i];
6186          }
6187          return result;
6188      }
6189      /**
6190       * Finds the corners of a bull-eye centered on the passed point.
6191       * This returns the centers of the diagonal points just outside the bull's eye
6192       * Returns [topRight, bottomRight, bottomLeft, topLeft]
6193       *
6194       * @param pCenter Center point
6195       * @return The corners of the bull-eye
6196       * @throws NotFoundException If no valid bull-eye can be found
6197       */
6198      getBullsEyeCorners(pCenter) {
6199          let pina = pCenter;
6200          let pinb = pCenter;
6201          let pinc = pCenter;
6202          let pind = pCenter;
6203          let color = true;
6204          for (this.nbCenterLayers = 1; this.nbCenterLayers < 9; this.nbCenterLayers++) {
6205              let pouta = this.getFirstDifferent(pina, color, 1, -1);
6206              let poutb = this.getFirstDifferent(pinb, color, 1, 1);
6207              let poutc = this.getFirstDifferent(pinc, color, -1, 1);
6208              let poutd = this.getFirstDifferent(pind, color, -1, -1);
6209              // d      a
6210              //
6211              // c      b
6212              if (this.nbCenterLayers > 2) {
6213                  let q = (this.distancePoint(poutd, pouta) * this.nbCenterLayers) / (this.distancePoint(pind, pina) * (this.nbCenterLayers + 2));
6214                  if (q < 0.75 || q > 1.25 || !this.isWhiteOrBlackRectangle(pouta, poutb, poutc, poutd)) {
6215                      break;
6216                  }
6217              }
6218              pina = pouta;
6219              pinb = poutb;
6220              pinc = poutc;
6221              pind = poutd;
6222              color = !color;
6223          }
6224          if (this.nbCenterLayers !== 5 && this.nbCenterLayers !== 7) {
6225              throw new NotFoundException();
6226          }
6227          this.compact = this.nbCenterLayers === 5;
6228          // Expand the square by .5 pixel in each direction so that we're on the border
6229          // between the white square and the black square
6230          let pinax = new ResultPoint(pina.getX() + 0.5, pina.getY() - 0.5);
6231          let pinbx = new ResultPoint(pinb.getX() + 0.5, pinb.getY() + 0.5);
6232          let pincx = new ResultPoint(pinc.getX() - 0.5, pinc.getY() + 0.5);
6233          let pindx = new ResultPoint(pind.getX() - 0.5, pind.getY() - 0.5);
6234          // Expand the square so that its corners are the centers of the points
6235          // just outside the bull's eye.
6236          return this.expandSquare([pinax, pinbx, pincx, pindx], 2 * this.nbCenterLayers - 3, 2 * this.nbCenterLayers);
6237      }
6238      /**
6239       * Finds a candidate center point of an Aztec code from an image
6240       *
6241       * @return the center point
6242       */
6243      getMatrixCenter() {
6244          let pointA;
6245          let pointB;
6246          let pointC;
6247          let pointD;
6248          // Get a white rectangle that can be the border of the matrix in center bull's eye or
6249          try {
6250              let cornerPoints = new WhiteRectangleDetector(this.image).detect();
6251              pointA = cornerPoints[0];
6252              pointB = cornerPoints[1];
6253              pointC = cornerPoints[2];
6254              pointD = cornerPoints[3];
6255          }
6256          catch (e) {
6257              // This exception can be in case the initial rectangle is white
6258              // In that case, surely in the bull's eye, we try to expand the rectangle.
6259              let cx = this.image.getWidth() / 2;
6260              let cy = this.image.getHeight() / 2;
6261              pointA = this.getFirstDifferent(new Point(cx + 7, cy - 7), false, 1, -1).toResultPoint();
6262              pointB = this.getFirstDifferent(new Point(cx + 7, cy + 7), false, 1, 1).toResultPoint();
6263              pointC = this.getFirstDifferent(new Point(cx - 7, cy + 7), false, -1, 1).toResultPoint();
6264              pointD = this.getFirstDifferent(new Point(cx - 7, cy - 7), false, -1, -1).toResultPoint();
6265          }
6266          // Compute the center of the rectangle
6267          let cx = MathUtils.round((pointA.getX() + pointD.getX() + pointB.getX() + pointC.getX()) / 4.0);
6268          let cy = MathUtils.round((pointA.getY() + pointD.getY() + pointB.getY() + pointC.getY()) / 4.0);
6269          // Redetermine the white rectangle starting from previously computed center.
6270          // This will ensure that we end up with a white rectangle in center bull's eye
6271          // in order to compute a more accurate center.
6272          try {
6273              let cornerPoints = new WhiteRectangleDetector(this.image, 15, cx, cy).detect();
6274              pointA = cornerPoints[0];
6275              pointB = cornerPoints[1];
6276              pointC = cornerPoints[2];
6277              pointD = cornerPoints[3];
6278          }
6279          catch (e) {
6280              // This exception can be in case the initial rectangle is white
6281              // In that case we try to expand the rectangle.
6282              pointA = this.getFirstDifferent(new Point(cx + 7, cy - 7), false, 1, -1).toResultPoint();
6283              pointB = this.getFirstDifferent(new Point(cx + 7, cy + 7), false, 1, 1).toResultPoint();
6284              pointC = this.getFirstDifferent(new Point(cx - 7, cy + 7), false, -1, 1).toResultPoint();
6285              pointD = this.getFirstDifferent(new Point(cx - 7, cy - 7), false, -1, -1).toResultPoint();
6286          }
6287          // Recompute the center of the rectangle
6288          cx = MathUtils.round((pointA.getX() + pointD.getX() + pointB.getX() + pointC.getX()) / 4.0);
6289          cy = MathUtils.round((pointA.getY() + pointD.getY() + pointB.getY() + pointC.getY()) / 4.0);
6290          return new Point(cx, cy);
6291      }
6292      /**
6293       * Gets the Aztec code corners from the bull's eye corners and the parameters.
6294       *
6295       * @param bullsEyeCorners the array of bull's eye corners
6296       * @return the array of aztec code corners
6297       */
6298      getMatrixCornerPoints(bullsEyeCorners) {
6299          return this.expandSquare(bullsEyeCorners, 2 * this.nbCenterLayers, this.getDimension());
6300      }
6301      /**
6302       * Creates a BitMatrix by sampling the provided image.
6303       * topLeft, topRight, bottomRight, and bottomLeft are the centers of the squares on the
6304       * diagonal just outside the bull's eye.
6305       */
6306      sampleGrid(image, topLeft, topRight, bottomRight, bottomLeft) {
6307          let sampler = GridSamplerInstance.getInstance();
6308          let dimension = this.getDimension();
6309          let low = dimension / 2 - this.nbCenterLayers;
6310          let high = dimension / 2 + this.nbCenterLayers;
6311          return sampler.sampleGrid(image, dimension, dimension, low, low, // topleft
6312          high, low, // topright
6313          high, high, // bottomright
6314          low, high, // bottomleft
6315          topLeft.getX(), topLeft.getY(), topRight.getX(), topRight.getY(), bottomRight.getX(), bottomRight.getY(), bottomLeft.getX(), bottomLeft.getY());
6316      }
6317      /**
6318       * Samples a line.
6319       *
6320       * @param p1   start point (inclusive)
6321       * @param p2   end point (exclusive)
6322       * @param size number of bits
6323       * @return the array of bits as an int (first bit is high-order bit of result)
6324       */
6325      sampleLine(p1, p2, size) {
6326          let result = 0;
6327          let d = this.distanceResultPoint(p1, p2);
6328          let moduleSize = d / size;
6329          let px = p1.getX();
6330          let py = p1.getY();
6331          let dx = moduleSize * (p2.getX() - p1.getX()) / d;
6332          let dy = moduleSize * (p2.getY() - p1.getY()) / d;
6333          for (let i = 0; i < size; i++) {
6334              if (this.image.get(MathUtils.round(px + i * dx), MathUtils.round(py + i * dy))) {
6335                  result |= 1 << (size - i - 1);
6336              }
6337          }
6338          return result;
6339      }
6340      /**
6341       * @return true if the border of the rectangle passed in parameter is compound of white points only
6342       *         or black points only
6343       */
6344      isWhiteOrBlackRectangle(p1, p2, p3, p4) {
6345          let corr = 3;
6346          p1 = new Point(p1.getX() - corr, p1.getY() + corr);
6347          p2 = new Point(p2.getX() - corr, p2.getY() - corr);
6348          p3 = new Point(p3.getX() + corr, p3.getY() - corr);
6349          p4 = new Point(p4.getX() + corr, p4.getY() + corr);
6350          let cInit = this.getColor(p4, p1);
6351          if (cInit === 0) {
6352              return false;
6353          }
6354          let c = this.getColor(p1, p2);
6355          if (c !== cInit) {
6356              return false;
6357          }
6358          c = this.getColor(p2, p3);
6359          if (c !== cInit) {
6360              return false;
6361          }
6362          c = this.getColor(p3, p4);
6363          return c === cInit;
6364      }
6365      /**
6366       * Gets the color of a segment
6367       *
6368       * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else
6369       */
6370      getColor(p1, p2) {
6371          let d = this.distancePoint(p1, p2);
6372          let dx = (p2.getX() - p1.getX()) / d;
6373          let dy = (p2.getY() - p1.getY()) / d;
6374          let error = 0;
6375          let px = p1.getX();
6376          let py = p1.getY();
6377          let colorModel = this.image.get(p1.getX(), p1.getY());
6378          let iMax = Math.ceil(d);
6379          for (let i = 0; i < iMax; i++) {
6380              px += dx;
6381              py += dy;
6382              if (this.image.get(MathUtils.round(px), MathUtils.round(py)) !== colorModel) {
6383                  error++;
6384              }
6385          }
6386          let errRatio = error / d;
6387          if (errRatio > 0.1 && errRatio < 0.9) {
6388              return 0;
6389          }
6390          return (errRatio <= 0.1) === colorModel ? 1 : -1;
6391      }
6392      /**
6393       * Gets the coordinate of the first point with a different color in the given direction
6394       */
6395      getFirstDifferent(init, color, dx, dy) {
6396          let x = init.getX() + dx;
6397          let y = init.getY() + dy;
6398          while (this.isValid(x, y) && this.image.get(x, y) === color) {
6399              x += dx;
6400              y += dy;
6401          }
6402          x -= dx;
6403          y -= dy;
6404          while (this.isValid(x, y) && this.image.get(x, y) === color) {
6405              x += dx;
6406          }
6407          x -= dx;
6408          while (this.isValid(x, y) && this.image.get(x, y) === color) {
6409              y += dy;
6410          }
6411          y -= dy;
6412          return new Point(x, y);
6413      }
6414      /**
6415       * Expand the square represented by the corner points by pushing out equally in all directions
6416       *
6417       * @param cornerPoints the corners of the square, which has the bull's eye at its center
6418       * @param oldSide the original length of the side of the square in the target bit matrix
6419       * @param newSide the new length of the size of the square in the target bit matrix
6420       * @return the corners of the expanded square
6421       */
6422      expandSquare(cornerPoints, oldSide, newSide) {
6423          let ratio = newSide / (2.0 * oldSide);
6424          let dx = cornerPoints[0].getX() - cornerPoints[2].getX();
6425          let dy = cornerPoints[0].getY() - cornerPoints[2].getY();
6426          let centerx = (cornerPoints[0].getX() + cornerPoints[2].getX()) / 2.0;
6427          let centery = (cornerPoints[0].getY() + cornerPoints[2].getY()) / 2.0;
6428          let result0 = new ResultPoint(centerx + ratio * dx, centery + ratio * dy);
6429          let result2 = new ResultPoint(centerx - ratio * dx, centery - ratio * dy);
6430          dx = cornerPoints[1].getX() - cornerPoints[3].getX();
6431          dy = cornerPoints[1].getY() - cornerPoints[3].getY();
6432          centerx = (cornerPoints[1].getX() + cornerPoints[3].getX()) / 2.0;
6433          centery = (cornerPoints[1].getY() + cornerPoints[3].getY()) / 2.0;
6434          let result1 = new ResultPoint(centerx + ratio * dx, centery + ratio * dy);
6435          let result3 = new ResultPoint(centerx - ratio * dx, centery - ratio * dy);
6436          let results = [result0, result1, result2, result3];
6437          return results;
6438      }
6439      isValid(x, y) {
6440          return x >= 0 && x < this.image.getWidth() && y > 0 && y < this.image.getHeight();
6441      }
6442      isValidPoint(point) {
6443          let x = MathUtils.round(point.getX());
6444          let y = MathUtils.round(point.getY());
6445          return this.isValid(x, y);
6446      }
6447      distancePoint(a, b) {
6448          return MathUtils.distance(a.getX(), a.getY(), b.getX(), b.getY());
6449      }
6450      distanceResultPoint(a, b) {
6451          return MathUtils.distance(a.getX(), a.getY(), b.getX(), b.getY());
6452      }
6453      getDimension() {
6454          if (this.compact) {
6455              return 4 * this.nbLayers + 11;
6456          }
6457          if (this.nbLayers <= 4) {
6458              return 4 * this.nbLayers + 15;
6459          }
6460          return 4 * this.nbLayers + 2 * (Integer.truncDivision((this.nbLayers - 4), 8) + 1) + 15;
6461      }
6462  }
6462
6463
6464  /*
6465   * Copyright 2010 ZXing authors
6466   *
6467   * Licensed under the Apache License, Version 2.0 (the "License");
vendor: 7,877 bytes, lines 6468-6659
6468   * you may not use this file except in compliance with the License.
6469   * You may obtain a copy of the License at
6470   *
6471   *      http://www.apache.org/licenses/LICENSE-2.0
6472   *
6473   * Unless required by applicable law or agreed to in writing, software
6474   * distributed under the License is distributed on an "AS IS" BASIS,
6475   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6476   * See the License for the specific language governing permissions and
6477   * limitations under the License.
6478   */
6479  // import java.util.List;
6480  // import java.util.Map;
6481  /**
6482   * This implementation can detect and decode Aztec codes in an image.
6483   *
6484   * @author David Olivier
6485   */
6486  class AztecReader {
6487      /**
6488       * Locates and decodes a Data Matrix code in an image.
6489       *
6490       * @return a String representing the content encoded by the Data Matrix code
6491       * @throws NotFoundException if a Data Matrix code cannot be found
6492       * @throws FormatException if a Data Matrix code cannot be decoded
6493       */
6494      decode(image, hints = null) {
6495          let exception = null;
6496          let detector = new Detector$3(image.getBlackMatrix());
6497          let points = null;
6498          let decoderResult = null;
6499          try {
6500              let detectorResult = detector.detectMirror(false);
6501              points = detectorResult.getPoints();
6502              this.reportFoundResultPoints(hints, points);
6503              decoderResult = new Decoder$2().decode(detectorResult);
6504          }
6505          catch (e) {
6506              exception = e;
6507          }
6508          if (decoderResult == null) {
6509              try {
6510                  let detectorResult = detector.detectMirror(true);
6511                  points = detectorResult.getPoints();
6512                  this.reportFoundResultPoints(hints, points);
6513                  decoderResult = new Decoder$2().decode(detectorResult);
6514              }
6515              catch (e) {
6516                  if (exception != null) {
6517                      throw exception;
6518                  }
6519                  throw e;
6520              }
6521          }
6522          let result = new Result$1(decoderResult.getText(), decoderResult.getRawBytes(), decoderResult.getNumBits(), points, BarcodeFormat$1.AZTEC, System.currentTimeMillis());
6523          let byteSegments = decoderResult.getByteSegments();
6524          if (byteSegments != null) {
6525              result.putMetadata(ResultMetadataType$1.BYTE_SEGMENTS, byteSegments);
6526          }
6527          let ecLevel = decoderResult.getECLevel();
6528          if (ecLevel != null) {
6529              result.putMetadata(ResultMetadataType$1.ERROR_CORRECTION_LEVEL, ecLevel);
6530          }
6531          return result;
6532      }
6533      reportFoundResultPoints(hints, points) {
6534          if (hints != null) {
6535              let rpcb = hints.get(DecodeHintType$1.NEED_RESULT_POINT_CALLBACK);
6536              if (rpcb != null) {
6537                  points.forEach((point, idx, arr) => {
6538                      rpcb.foundPossibleResultPoint(point);
6539                  });
6540              }
6541          }
6542      }
6543      // @Override
6544      reset() {
6545          // do nothing
6546      }
6547  }
6548
6549  /**
6550   * Aztec Code reader to use from browser.
6551   *
6552   * @class BrowserAztecCodeReader
6553   * @extends {BrowserCodeReader}
6554   */
6555  class BrowserAztecCodeReader extends BrowserCodeReader {
6556      /**
6557       * Creates an instance of BrowserAztecCodeReader.
6558       * @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
6559       *
6560       * @memberOf BrowserAztecCodeReader
6561       */
6562      constructor(timeBetweenScansMillis = 500) {
6563          super(new AztecReader(), timeBetweenScansMillis);
6564      }
6565  }
6566
6567  /*
6568   * Copyright 2008 ZXing authors
6569   *
6570   * Licensed under the Apache License, Version 2.0 (the "License");
6571   * you may not use this file except in compliance with the License.
6572   * You may obtain a copy of the License at
6573   *
6574   *      http://www.apache.org/licenses/LICENSE-2.0
6575   *
6576   * Unless required by applicable law or agreed to in writing, software
6577   * distributed under the License is distributed on an "AS IS" BASIS,
6578   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6579   * See the License for the specific language governing permissions and
6580   * limitations under the License.
6581   */
6582  /**
6583   * Encapsulates functionality and implementation that is common to all families
6584   * of one-dimensional barcodes.
6585   *
6586   * @author [email protected] (Daniel Switkin)
6587   * @author Sean Owen
6588   */
6589  class OneDReader {
6590      /*
6591      @Override
6592      public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {
6593        return decode(image, null);
6594      }
6595      */
6596      // Note that we don't try rotation without the try harder flag, even if rotation was supported.
6597      // @Override
6598      decode(image, hints) {
6599          try {
6600              return this.doDecode(image, hints);
6601          }
6602          catch (nfe) {
6603              const tryHarder = hints && (hints.get(DecodeHintType$1.TRY_HARDER) === true);
6604              if (tryHarder && image.isRotateSupported()) {
6605                  const rotatedImage = image.rotateCounterClockwise();
6606                  const result = this.doDecode(rotatedImage, hints);
6607                  // Record that we found it rotated 90 degrees CCW / 270 degrees CW
6608                  const metadata = result.getResultMetadata();
6609                  let orientation = 270;
6610                  if (metadata !== null && (metadata.get(ResultMetadataType$1.ORIENTATION) === true)) {
6611                      // But if we found it reversed in doDecode(), add in that result here:
6612                      orientation = (orientation + metadata.get(ResultMetadataType$1.ORIENTATION) % 360);
6613                  }
6614                  result.putMetadata(ResultMetadataType$1.ORIENTATION, orientation);
6615                  // Update result points
6616                  const points = result.getResultPoints();
6617                  if (points !== null) {
6618                      const height = rotatedImage.getHeight();
6619                      for (let i = 0; i < points.length; i++) {
6620                          points[i] = new ResultPoint(height - points[i].getY() - 1, points[i].getX());
6621                      }
6622                  }
6623                  return result;
6624              }
6625              else {
6626                  throw new NotFoundException();
6627              }
6628          }
6629      }
6630      // @Override
6631      reset() {
6632          // do nothing
6633      }
6634      /**
6635       * We're going to examine rows from the middle outward, searching alternately above and below the
6636       * middle, and farther out each time. rowStep is the number of rows between each successive
6637       * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
6638       * middle + rowStep, then middle - (2 * rowStep), etc.
6639       * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
6640       * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
6641       * image if "trying harder".
6642       *
6643       * @param image The image to decode
6644       * @param hints Any hints that were requested
6645       * @return The contents of the decoded barcode
6646       * @throws NotFoundException Any spontaneous errors which occur
6647       */
6648      doDecode(image, hints) {
6649          const width = image.getWidth();
6650          const height = image.getHeight();
6651          let row = new BitArray(width);
6652          const tryHarder = hints && (hints.get(DecodeHintType$1.TRY_HARDER) === true);
6653          const rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
6654          let maxLines;
6655          if (tryHarder) {
6656              maxLines = height; // Look at the whole image, not just the center
6657          }
6658          else {
6659              maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
vendor: 8,080 bytes, lines 6659-6831
6659
6660          }
6661          const middle = Math.trunc(height / 2);
6662          for (let x = 0; x < maxLines; x++) {
6663              // Scanning from the middle out. Determine which row we're looking at next:
6664              const rowStepsAboveOrBelow = Math.trunc((x + 1) / 2);
6665              const isAbove = (x & 0x01) === 0; // i.e. is x even?
6666              const rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
6667              if (rowNumber < 0 || rowNumber >= height) {
6668                  // Oops, if we run off the top or bottom, stop
6669                  break;
6670              }
6671              // Estimate black point for this row and load it:
6672              try {
6673                  row = image.getBlackRow(rowNumber, row);
6674              }
6675              catch (ignored) {
6676                  continue;
6677              }
6678              // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
6679              // handle decoding upside down barcodes.
6680              for (let attempt = 0; attempt < 2; attempt++) {
6681                  if (attempt === 1) { // trying again?
6682                      row.reverse(); // reverse the row and continue
6683                      // This means we will only ever draw result points *once* in the life of this method
6684                      // since we want to avoid drawing the wrong points after flipping the row, and,
6685                      // don't want to clutter with noise from every single row scan -- just the scans
6686                      // that start on the center line.
6687                      if (hints && (hints.get(DecodeHintType$1.NEED_RESULT_POINT_CALLBACK) === true)) {
6688                          const newHints = new Map();
6689                          hints.forEach((hint, key) => newHints.set(key, hint));
6690                          newHints.delete(DecodeHintType$1.NEED_RESULT_POINT_CALLBACK);
6691                          hints = newHints;
6692                      }
6693                  }
6694                  try {
6695                      // Look for a barcode
6696                      const result = this.decodeRow(rowNumber, row, hints);
6697                      // We found our barcode
6698                      if (attempt === 1) {
6699                          // But it was upside down, so note that
6700                          result.putMetadata(ResultMetadataType$1.ORIENTATION, 180);
6701                          // And remember to flip the result points horizontally.
6702                          const points = result.getResultPoints();
6703                          if (points !== null) {
6704                              points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
6705                              points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
6706                          }
6707                      }
6708                      return result;
6709                  }
6710                  catch (re) {
6711                      // continue -- just couldn't decode this row
6712                  }
6713              }
6714          }
6715          throw new NotFoundException();
6716      }
6717      /**
6718       * Records the size of successive runs of white and black pixels in a row, starting at a given point.
6719       * The values are recorded in the given array, and the number of runs recorded is equal to the size
6720       * of the array. If the row starts on a white pixel at the given start point, then the first count
6721       * recorded is the run of white pixels starting from that point; likewise it is the count of a run
6722       * of black pixels if the row begin on a black pixels at that point.
6723       *
6724       * @param row row to count from
6725       * @param start offset into row to start at
6726       * @param counters array into which to record counts
6727       * @throws NotFoundException if counters cannot be filled entirely from row before running out
6728       *  of pixels
6729       */
6730      static recordPattern(row, start, counters) {
6731          const numCounters = counters.length;
6732          for (let index = 0; index < numCounters; index++)
6733              counters[index] = 0;
6734          const end = row.getSize();
6735          if (start >= end) {
6736              throw new NotFoundException();
6737          }
6738          let isWhite = !row.get(start);
6739          let counterPosition = 0;
6740          let i = start;
6741          while (i < end) {
6742              if (row.get(i) !== isWhite) {
6743                  counters[counterPosition]++;
6744              }
6745              else {
6746                  if (++counterPosition === numCounters) {
6747                      break;
6748                  }
6749                  else {
6750                      counters[counterPosition] = 1;
6751                      isWhite = !isWhite;
6752                  }
6753              }
6754              i++;
6755          }
6756          // If we read fully the last section of pixels and filled up our counters -- or filled
6757          // the last counter but ran off the side of the image, OK. Otherwise, a problem.
6758          if (!(counterPosition === numCounters || (counterPosition === numCounters - 1 && i === end))) {
6759              throw new NotFoundException();
6760          }
6761      }
6762      static recordPatternInReverse(row, start, counters) {
6763          // This could be more efficient I guess
6764          let numTransitionsLeft = counters.length;
6765          let last = row.get(start);
6766          while (start > 0 && numTransitionsLeft >= 0) {
6767              if (row.get(--start) !== last) {
6768                  numTransitionsLeft--;
6769                  last = !last;
6770              }
6771          }
6772          if (numTransitionsLeft >= 0) {
6773              throw new NotFoundException();
6774          }
6775          OneDReader.recordPattern(row, start + 1, counters);
6776      }
6777      /**
6778       * Determines how closely a set of observed counts of runs of black/white values matches a given
6779       * target pattern. This is reported as the ratio of the total variance from the expected pattern
6780       * proportions across all pattern elements, to the length of the pattern.
6781       *
6782       * @param counters observed counters
6783       * @param pattern expected pattern
6784       * @param maxIndividualVariance The most any counter can differ before we give up
6785       * @return ratio of total variance between counters and pattern compared to total pattern size
6786       */
6787      static patternMatchVariance(counters, pattern, maxIndividualVariance) {
6788          const numCounters = counters.length;
6789          let total = 0;
6790          let patternLength = 0;
6791          for (let i = 0; i < numCounters; i++) {
6792              total += counters[i];
6793              patternLength += pattern[i];
6794          }
6795          if (total < patternLength) {
6796              // If we don't even have one pixel per unit of bar width, assume this is too small
6797              // to reliably match, so fail:
6798              return Number.POSITIVE_INFINITY;
6799          }
6800          const unitBarWidth = total / patternLength;
6801          maxIndividualVariance *= unitBarWidth;
6802          let totalVariance = 0.0;
6803          for (let x = 0; x < numCounters; x++) {
6804              const counter = counters[x];
6805              const scaledPattern = pattern[x] * unitBarWidth;
6806              const variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
6807              if (variance > maxIndividualVariance) {
6808                  return Number.POSITIVE_INFINITY;
6809              }
6810              totalVariance += variance;
6811          }
6812          return totalVariance / total;
6813      }
6814  }
6815
6816  /*
6817   * Copyright 2008 ZXing authors
6818   *
6819   * Licensed under the Apache License, Version 2.0 (the "License");
6820   * you may not use this file except in compliance with the License.
6821   * You may obtain a copy of the License at
6822   *
6823   *      http://www.apache.org/licenses/LICENSE-2.0
6824   *
6825   * Unless required by applicable law or agreed to in writing, software
6826   * distributed under the License is distributed on an "AS IS" BASIS,
6827   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6828   * See the License for the specific language governing permissions and
6829   * limitations under the License.
6830   */
6831  /*
vendor: 22,113 bytes, lines 6831-7288
6831*
6832   * <p>Decodes Code 128 barcodes.</p>
6833   *
6834   * @author Sean Owen
6835   */
6836  class Code128Reader extends OneDReader {
6837      static findStartPattern(row) {
6838          const width = row.getSize();
6839          const rowOffset = row.getNextSet(0);
6840          let counterPosition = 0;
6841          let counters = Int32Array.from([0, 0, 0, 0, 0, 0]);
6842          let patternStart = rowOffset;
6843          let isWhite = false;
6844          const patternLength = 6;
6845          for (let i = rowOffset; i < width; i++) {
6846              if (row.get(i) !== isWhite) {
6847                  counters[counterPosition]++;
6848              }
6849              else {
6850                  if (counterPosition === (patternLength - 1)) {
6851                      let bestVariance = Code128Reader.MAX_AVG_VARIANCE;
6852                      let bestMatch = -1;
6853                      for (let startCode = Code128Reader.CODE_START_A; startCode <= Code128Reader.CODE_START_C; startCode++) {
6854                          const variance = OneDReader.patternMatchVariance(counters, Code128Reader.CODE_PATTERNS[startCode], Code128Reader.MAX_INDIVIDUAL_VARIANCE);
6855                          if (variance < bestVariance) {
6856                              bestVariance = variance;
6857                              bestMatch = startCode;
6858                          }
6859                      }
6860                      // Look for whitespace before start pattern, >= 50% of width of start pattern
6861                      if (bestMatch >= 0 &&
6862                          row.isRange(Math.max(0, patternStart - (i - patternStart) / 2), patternStart, false)) {
6863                          return Int32Array.from([patternStart, i, bestMatch]);
6864                      }
6865                      patternStart += counters[0] + counters[1];
6866                      counters = counters.slice(2, counters.length);
6867                      counters[counterPosition - 1] = 0;
6868                      counters[counterPosition] = 0;
6869                      counterPosition--;
6870                  }
6871                  else {
6872                      counterPosition++;
6873                  }
6874                  counters[counterPosition] = 1;
6875                  isWhite = !isWhite;
6876              }
6877          }
6878          throw new NotFoundException();
6879      }
6880      static decodeCode(row, counters, rowOffset) {
6881          OneDReader.recordPattern(row, rowOffset, counters);
6882          let bestVariance = Code128Reader.MAX_AVG_VARIANCE; // worst variance we'll accept
6883          let bestMatch = -1;
6884          for (let d = 0; d < Code128Reader.CODE_PATTERNS.length; d++) {
6885              const pattern = Code128Reader.CODE_PATTERNS[d];
6886              const variance = this.patternMatchVariance(counters, pattern, Code128Reader.MAX_INDIVIDUAL_VARIANCE);
6887              if (variance < bestVariance) {
6888                  bestVariance = variance;
6889                  bestMatch = d;
6890              }
6891          }
6892          // TODO We're overlooking the fact that the STOP pattern has 7 values, not 6.
6893          if (bestMatch >= 0) {
6894              return bestMatch;
6895          }
6896          else {
6897              throw new NotFoundException();
6898          }
6899      }
6900      decodeRow(rowNumber, row, hints) {
6901          const convertFNC1 = hints && (hints.get(DecodeHintType$1.ASSUME_GS1) === true);
6902          const startPatternInfo = Code128Reader.findStartPattern(row);
6903          const startCode = startPatternInfo[2];
6904          let currentRawCodesIndex = 0;
6905          const rawCodes = new Uint8Array(20);
6906          rawCodes[currentRawCodesIndex++] = startCode;
6907          let codeSet;
6908          switch (startCode) {
6909              case Code128Reader.CODE_START_A:
6910                  codeSet = Code128Reader.CODE_CODE_A;
6911                  break;
6912              case Code128Reader.CODE_START_B:
6913                  codeSet = Code128Reader.CODE_CODE_B;
6914                  break;
6915              case Code128Reader.CODE_START_C:
6916                  codeSet = Code128Reader.CODE_CODE_C;
6917                  break;
6918              default:
6919                  throw new FormatException();
6920          }
6921          let done = false;
6922          let isNextShifted = false;
6923          let result = '';
6924          let lastStart = startPatternInfo[0];
6925          let nextStart = startPatternInfo[1];
6926          const counters = Int32Array.from([0, 0, 0, 0, 0, 0]);
6927          let lastCode = 0;
6928          let code = 0;
6929          let checksumTotal = startCode;
6930          let multiplier = 0;
6931          let lastCharacterWasPrintable = true;
6932          let upperMode = false;
6933          let shiftUpperMode = false;
6934          while (!done) {
6935              const unshift = isNextShifted;
6936              isNextShifted = false;
6937              // Save off last code
6938              lastCode = code;
6939              // Decode another code from image
6940              code = Code128Reader.decodeCode(row, counters, nextStart);
6941              rawCodes[currentRawCodesIndex++] = code;
6942              // Remember whether the last code was printable or not (excluding CODE_STOP)
6943              if (code !== Code128Reader.CODE_STOP) {
6944                  lastCharacterWasPrintable = true;
6945              }
6946              // Add to checksum computation (if not CODE_STOP of course)
6947              if (code !== Code128Reader.CODE_STOP) {
6948                  multiplier++;
6949                  checksumTotal += multiplier * code;
6950              }
6951              // Advance to where the next code will to start
6952              lastStart = nextStart;
6953              nextStart += counters.reduce((previous, current) => previous + current, 0);
6954              // Take care of illegal start codes
6955              switch (code) {
6956                  case Code128Reader.CODE_START_A:
6957                  case Code128Reader.CODE_START_B:
6958                  case Code128Reader.CODE_START_C:
6959                      throw new FormatException();
6960              }
6961              switch (codeSet) {
6962                  case Code128Reader.CODE_CODE_A:
6963                      if (code < 64) {
6964                          if (shiftUpperMode === upperMode) {
6965                              result += String.fromCharCode((' '.charCodeAt(0) + code));
6966                          }
6967                          else {
6968                              result += String.fromCharCode((' '.charCodeAt(0) + code + 128));
6969                          }
6970                          shiftUpperMode = false;
6971                      }
6972                      else if (code < 96) {
6973                          if (shiftUpperMode === upperMode) {
6974                              result += String.fromCharCode((code - 64));
6975                          }
6976                          else {
6977                              result += String.fromCharCode((code + 64));
6978                          }
6979                          shiftUpperMode = false;
6980                      }
6981                      else {
6982                          // Don't let CODE_STOP, which always appears, affect whether whether we think the last
6983                          // code was printable or not.
6984                          if (code !== Code128Reader.CODE_STOP) {
6985                              lastCharacterWasPrintable = false;
6986                          }
6987                          switch (code) {
6988                              case Code128Reader.CODE_FNC_1:
6989                                  if (convertFNC1) {
6990                                      if (result.length === 0) {
6991                                          // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
6992                                          // is FNC1 then this is GS1-128. We add the symbology identifier.
6993                                          result += ']C1';
6994                                      }
6995                                      else {
6996                                          // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
6997                                          result += String.fromCharCode(29);
6998                                      }
6999                                  }
7000                                  break;
7001                              case Code128Reader.CODE_FNC_2:
7002                              case Code128Reader.CODE_FNC_3:
7003                                  // do nothing?
7004                                  break;
7005                              case Code128Reader.CODE_FNC_4_A:
7006                                  if (!upperMode && shiftUpperMode) {
7007                                      upperMode = true;
7008                                      shiftUpperMode = false;
7009                                  }
7010                                  else if (upperMode && shiftUpperMode) {
7011                                      upperMode = false;
7012                                      shiftUpperMode = false;
7013                                  }
7014                                  else {
7015                                      shiftUpperMode = true;
7016                                  }
7017                                  break;
7018                              case Code128Reader.CODE_SHIFT:
7019                                  isNextShifted = true;
7020                                  codeSet = Code128Reader.CODE_CODE_B;
7021                                  break;
7022                              case Code128Reader.CODE_CODE_B:
7023                                  codeSet = Code128Reader.CODE_CODE_B;
7024                                  break;
7025                              case Code128Reader.CODE_CODE_C:
7026                                  codeSet = Code128Reader.CODE_CODE_C;
7027                                  break;
7028                              case Code128Reader.CODE_STOP:
7029                                  done = true;
7030                                  break;
7031                          }
7032                      }
7033                      break;
7034                  case Code128Reader.CODE_CODE_B:
7035                      if (code < 96) {
7036                          if (shiftUpperMode === upperMode) {
7037                              result += String.fromCharCode((' '.charCodeAt(0) + code));
7038                          }
7039                          else {
7040                              result += String.fromCharCode((' '.charCodeAt(0) + code + 128));
7041                          }
7042                          shiftUpperMode = false;
7043                      }
7044                      else {
7045                          if (code !== Code128Reader.CODE_STOP) {
7046                              lastCharacterWasPrintable = false;
7047                          }
7048                          switch (code) {
7049                              case Code128Reader.CODE_FNC_1:
7050                                  if (convertFNC1) {
7051                                      if (result.length === 0) {
7052                                          // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
7053                                          // is FNC1 then this is GS1-128. We add the symbology identifier.
7054                                          result += ']C1';
7055                                      }
7056                                      else {
7057                                          // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
7058                                          result += String.fromCharCode(29);
7059                                      }
7060                                  }
7061                                  break;
7062                              case Code128Reader.CODE_FNC_2:
7063                              case Code128Reader.CODE_FNC_3:
7064                                  // do nothing?
7065                                  break;
7066                              case Code128Reader.CODE_FNC_4_B:
7067                                  if (!upperMode && shiftUpperMode) {
7068                                      upperMode = true;
7069                                      shiftUpperMode = false;
7070                                  }
7071                                  else if (upperMode && shiftUpperMode) {
7072                                      upperMode = false;
7073                                      shiftUpperMode = false;
7074                                  }
7075                                  else {
7076                                      shiftUpperMode = true;
7077                                  }
7078                                  break;
7079                              case Code128Reader.CODE_SHIFT:
7080                                  isNextShifted = true;
7081                                  codeSet = Code128Reader.CODE_CODE_A;
7082                                  break;
7083                              case Code128Reader.CODE_CODE_A:
7084                                  codeSet = Code128Reader.CODE_CODE_A;
7085                                  break;
7086                              case Code128Reader.CODE_CODE_C:
7087                                  codeSet = Code128Reader.CODE_CODE_C;
7088                                  break;
7089                              case Code128Reader.CODE_STOP:
7090                                  done = true;
7091                                  break;
7092                          }
7093                      }
7094                      break;
7095                  case Code128Reader.CODE_CODE_C:
7096                      if (code < 100) {
7097                          if (code < 10) {
7098                              result += '0';
7099                          }
7100                          result += code;
7101                      }
7102                      else {
7103                          if (code !== Code128Reader.CODE_STOP) {
7104                              lastCharacterWasPrintable = false;
7105                          }
7106                          switch (code) {
7107                              case Code128Reader.CODE_FNC_1:
7108                                  if (convertFNC1) {
7109                                      if (result.length === 0) {
7110                                          // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
7111                                          // is FNC1 then this is GS1-128. We add the symbology identifier.
7112                                          result += ']C1';
7113                                      }
7114                                      else {
7115                                          // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
7116                                          result += String.fromCharCode(29);
7117                                      }
7118                                  }
7119                                  break;
7120                              case Code128Reader.CODE_CODE_A:
7121                                  codeSet = Code128Reader.CODE_CODE_A;
7122                                  break;
7123                              case Code128Reader.CODE_CODE_B:
7124                                  codeSet = Code128Reader.CODE_CODE_B;
7125                                  break;
7126                              case Code128Reader.CODE_STOP:
7127                                  done = true;
7128                                  break;
7129                          }
7130                      }
7131                      break;
7132              }
7133              // Unshift back to another code set if we were shifted
7134              if (unshift) {
7135                  codeSet = codeSet === Code128Reader.CODE_CODE_A ? Code128Reader.CODE_CODE_B : Code128Reader.CODE_CODE_A;
7136              }
7137          }
7138          const lastPatternSize = nextStart - lastStart;
7139          // Check for ample whitespace following pattern, but, to do this we first need to remember that
7140          // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left
7141          // to read off. Would be slightly better to properly read. Here we just skip it:
7142          nextStart = row.getNextUnset(nextStart);
7143          if (!row.isRange(nextStart, Math.min(row.getSize(), nextStart + (nextStart - lastStart) / 2), false)) {
7144              throw new NotFoundException();
7145          }
7146          // Pull out from sum the value of the penultimate check code
7147          checksumTotal -= multiplier * lastCode;
7148          // lastCode is the checksum then:
7149          if (checksumTotal % 103 !== lastCode) {
7150              throw new ChecksumException();
7151          }
7152          // Need to pull out the check digits from string
7153          const resultLength = result.length;
7154          if (resultLength === 0) {
7155              // false positive
7156              throw new NotFoundException();
7157          }
7158          // Only bother if the result had at least one character, and if the checksum digit happened to
7159          // be a printable character. If it was just interpreted as a control code, nothing to remove.
7160          if (resultLength > 0 && lastCharacterWasPrintable) {
7161              if (codeSet === Code128Reader.CODE_CODE_C) {
7162                  result = result.substring(0, resultLength - 2);
7163              }
7164              else {
7165                  result = result.substring(0, resultLength - 1);
7166              }
7167          }
7168          const left = (startPatternInfo[1] + startPatternInfo[0]) / 2.0;
7169          const right = lastStart + lastPatternSize / 2.0;
7170          const rawCodesSize = rawCodes.length;
7171          const rawBytes = new Uint8Array(rawCodesSize);
7172          for (let i = 0; i < rawCodesSize; i++) {
7173              rawBytes[i] = rawCodes[i];
7174          }
7175          const points = [new ResultPoint(left, rowNumber), new ResultPoint(right, rowNumber)];
7176          return new Result$1(result, rawBytes, 0, points, BarcodeFormat$1.CODE_128, new Date().getTime());
7177      }
7178  }
7179  Code128Reader.CODE_PATTERNS = [
7180      Int32Array.from([2, 1, 2, 2, 2, 2]),
7181      Int32Array.from([2, 2, 2, 1, 2, 2]),
7182      Int32Array.from([2, 2, 2, 2, 2, 1]),
7183      Int32Array.from([1, 2, 1, 2, 2, 3]),
7184      Int32Array.from([1, 2, 1, 3, 2, 2]),
7185      Int32Array.from([1, 3, 1, 2, 2, 2]),
7186      Int32Array.from([1, 2, 2, 2, 1, 3]),
7187      Int32Array.from([1, 2, 2, 3, 1, 2]),
7188      Int32Array.from([1, 3, 2, 2, 1, 2]),
7189      Int32Array.from([2, 2, 1, 2, 1, 3]),
7190      Int32Array.from([2, 2, 1, 3, 1, 2]),
7191      Int32Array.from([2, 3, 1, 2, 1, 2]),
7192      Int32Array.from([1, 1, 2, 2, 3, 2]),
7193      Int32Array.from([1, 2, 2, 1, 3, 2]),
7194      Int32Array.from([1, 2, 2, 2, 3, 1]),
7195      Int32Array.from([1, 1, 3, 2, 2, 2]),
7196      Int32Array.from([1, 2, 3, 1, 2, 2]),
7197      Int32Array.from([1, 2, 3, 2, 2, 1]),
7198      Int32Array.from([2, 2, 3, 2, 1, 1]),
7199      Int32Array.from([2, 2, 1, 1, 3, 2]),
7200      Int32Array.from([2, 2, 1, 2, 3, 1]),
7201      Int32Array.from([2, 1, 3, 2, 1, 2]),
7202      Int32Array.from([2, 2, 3, 1, 1, 2]),
7203      Int32Array.from([3, 1, 2, 1, 3, 1]),
7204      Int32Array.from([3, 1, 1, 2, 2, 2]),
7205      Int32Array.from([3, 2, 1, 1, 2, 2]),
7206      Int32Array.from([3, 2, 1, 2, 2, 1]),
7207      Int32Array.from([3, 1, 2, 2, 1, 2]),
7208      Int32Array.from([3, 2, 2, 1, 1, 2]),
7209      Int32Array.from([3, 2, 2, 2, 1, 1]),
7210      Int32Array.from([2, 1, 2, 1, 2, 3]),
7211      Int32Array.from([2, 1, 2, 3, 2, 1]),
7212      Int32Array.from([2, 3, 2, 1, 2, 1]),
7213      Int32Array.from([1, 1, 1, 3, 2, 3]),
7214      Int32Array.from([1, 3, 1, 1, 2, 3]),
7215      Int32Array.from([1, 3, 1, 3, 2, 1]),
7216      Int32Array.from([1, 1, 2, 3, 1, 3]),
7217      Int32Array.from([1, 3, 2, 1, 1, 3]),
7218      Int32Array.from([1, 3, 2, 3, 1, 1]),
7219      Int32Array.from([2, 1, 1, 3, 1, 3]),
7220      Int32Array.from([2, 3, 1, 1, 1, 3]),
7221      Int32Array.from([2, 3, 1, 3, 1, 1]),
7222      Int32Array.from([1, 1, 2, 1, 3, 3]),
7223      Int32Array.from([1, 1, 2, 3, 3, 1]),
7224      Int32Array.from([1, 3, 2, 1, 3, 1]),
7225      Int32Array.from([1, 1, 3, 1, 2, 3]),
7226      Int32Array.from([1, 1, 3, 3, 2, 1]),
7227      Int32Array.from([1, 3, 3, 1, 2, 1]),
7228      Int32Array.from([3, 1, 3, 1, 2, 1]),
7229      Int32Array.from([2, 1, 1, 3, 3, 1]),
7230      Int32Array.from([2, 3, 1, 1, 3, 1]),
7231      Int32Array.from([2, 1, 3, 1, 1, 3]),
7232      Int32Array.from([2, 1, 3, 3, 1, 1]),
7233      Int32Array.from([2, 1, 3, 1, 3, 1]),
7234      Int32Array.from([3, 1, 1, 1, 2, 3]),
7235      Int32Array.from([3, 1, 1, 3, 2, 1]),
7236      Int32Array.from([3, 3, 1, 1, 2, 1]),
7237      Int32Array.from([3, 1, 2, 1, 1, 3]),
7238      Int32Array.from([3, 1, 2, 3, 1, 1]),
7239      Int32Array.from([3, 3, 2, 1, 1, 1]),
7240      Int32Array.from([3, 1, 4, 1, 1, 1]),
7241      Int32Array.from([2, 2, 1, 4, 1, 1]),
7242      Int32Array.from([4, 3, 1, 1, 1, 1]),
7243      Int32Array.from([1, 1, 1, 2, 2, 4]),
7244      Int32Array.from([1, 1, 1, 4, 2, 2]),
7245      Int32Array.from([1, 2, 1, 1, 2, 4]),
7246      Int32Array.from([1, 2, 1, 4, 2, 1]),
7247      Int32Array.from([1, 4, 1, 1, 2, 2]),
7248      Int32Array.from([1, 4, 1, 2, 2, 1]),
7249      Int32Array.from([1, 1, 2, 2, 1, 4]),
7250      Int32Array.from([1, 1, 2, 4, 1, 2]),
7251      Int32Array.from([1, 2, 2, 1, 1, 4]),
7252      Int32Array.from([1, 2, 2, 4, 1, 1]),
7253      Int32Array.from([1, 4, 2, 1, 1, 2]),
7254      Int32Array.from([1, 4, 2, 2, 1, 1]),
7255      Int32Array.from([2, 4, 1, 2, 1, 1]),
7256      Int32Array.from([2, 2, 1, 1, 1, 4]),
7257      Int32Array.from([4, 1, 3, 1, 1, 1]),
7258      Int32Array.from([2, 4, 1, 1, 1, 2]),
7259      Int32Array.from([1, 3, 4, 1, 1, 1]),
7260      Int32Array.from([1, 1, 1, 2, 4, 2]),
7261      Int32Array.from([1, 2, 1, 1, 4, 2]),
7262      Int32Array.from([1, 2, 1, 2, 4, 1]),
7263      Int32Array.from([1, 1, 4, 2, 1, 2]),
7264      Int32Array.from([1, 2, 4, 1, 1, 2]),
7265      Int32Array.from([1, 2, 4, 2, 1, 1]),
7266      Int32Array.from([4, 1, 1, 2, 1, 2]),
7267      Int32Array.from([4, 2, 1, 1, 1, 2]),
7268      Int32Array.from([4, 2, 1, 2, 1, 1]),
7269      Int32Array.from([2, 1, 2, 1, 4, 1]),
7270      Int32Array.from([2, 1, 4, 1, 2, 1]),
7271      Int32Array.from([4, 1, 2, 1, 2, 1]),
7272      Int32Array.from([1, 1, 1, 1, 4, 3]),
7273      Int32Array.from([1, 1, 1, 3, 4, 1]),
7274      Int32Array.from([1, 3, 1, 1, 4, 1]),
7275      Int32Array.from([1, 1, 4, 1, 1, 3]),
7276      Int32Array.from([1, 1, 4, 3, 1, 1]),
7277      Int32Array.from([4, 1, 1, 1, 1, 3]),
7278      Int32Array.from([4, 1, 1, 3, 1, 1]),
7279      Int32Array.from([1, 1, 3, 1, 4, 1]),
7280      Int32Array.from([1, 1, 4, 1, 3, 1]),
7281      Int32Array.from([3, 1, 1, 1, 4, 1]),
7282      Int32Array.from([4, 1, 1, 1, 3, 1]),
7283      Int32Array.from([2, 1, 1, 4, 1, 2]),
7284      Int32Array.from([2, 1, 1, 2, 1, 4]),
7285      Int32Array.from([2, 1, 1, 2, 3, 2]),
7286      Int32Array.from([2, 3, 3, 1, 1, 1, 2]),
7287  ];
7288  Code128Reader.MAX_AVG_VARIANCE = 0.25;
7289  Code128Reader.MAX_INDIVIDUAL_VARIANCE = 0.7;
7290  Code128Reader.CODE_SHIFT = 98;
7291  Code128Reader.CODE_CODE_C = 99;
7292  Code128Reader.CODE_CODE_B = 100;
7293  Code128Reader.CODE_CODE_A = 101;
7294  Code128Reader.CODE_FNC_1 = 102;
7295  Code128Reader.CODE_FNC_2 = 97;
7296  Code128Reader.CODE_FNC_3 = 96;
7297  Code128Reader.CODE_FNC_4_A = 101;
7298  Code128Reader.CODE_FNC_4_B = 100;
7299  Code128Reader.CODE_START_A = 103;
7300  Code128Reader.CODE_START_B = 104;
7301  Code128Reader.CODE_START_C = 105;
7302  Code128Reader.CODE_STOP = 106;
7303
7304  /*
7305   * Copyright 2008 ZXing authors
7306   *
7307   * Licensed under the Apache License, Version 2.0 (the "License");
7308   * you may not use this file except in compliance with the License.
7309   * You may obtain a copy of the License at
7310   *
7311   *      http://www.apache.org/licenses/LICENSE-2.0
7312   *
7313   * Unless required by applicable law or agreed to in writing, software
7314   * distributed under the License is distributed on an "AS IS" BASIS,
7315   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7316   * See the License for the specific language governing permissions and
7317   * limitations under the License.
7318   
vendor: 12,585 bytes, lines 7318-7599
7318*/
7319  /**
7320   * <p>Decodes Code 39 barcodes. Supports "Full ASCII Code 39" if USE_CODE_39_EXTENDED_MODE is set.</p>
7321   *
7322   * @author Sean Owen
7323   * @see Code93Reader
7324   */
7325  class Code39Reader extends OneDReader {
7326      /**
7327       * Creates a reader that assumes all encoded data is data, and does not treat the final
7328       * character as a check digit. It will not decoded "extended Code 39" sequences.
7329       */
7330      // public Code39Reader() {
7331      //   this(false);
7332      // }
7333      /**
7334       * Creates a reader that can be configured to check the last character as a check digit.
7335       * It will not decoded "extended Code 39" sequences.
7336       *
7337       * @param usingCheckDigit if true, treat the last data character as a check digit, not
7338       * data, and verify that the checksum passes.
7339       */
7340      // public Code39Reader(boolean usingCheckDigit) {
7341      //   this(usingCheckDigit, false);
7342      // }
7343      /**
7344       * Creates a reader that can be configured to check the last character as a check digit,
7345       * or optionally attempt to decode "extended Code 39" sequences that are used to encode
7346       * the full ASCII character set.
7347       *
7348       * @param usingCheckDigit if true, treat the last data character as a check digit, not
7349       * data, and verify that the checksum passes.
7350       * @param extendedMode if true, will attempt to decode extended Code 39 sequences in the
7351       * text.
7352       */
7353      constructor(usingCheckDigit = false, extendedMode = false) {
7354          super();
7355          this.usingCheckDigit = usingCheckDigit;
7356          this.extendedMode = extendedMode;
7357          this.decodeRowResult = '';
7358          this.counters = new Int32Array(9);
7359      }
7360      decodeRow(rowNumber, row, hints) {
7361          let theCounters = this.counters;
7362          theCounters.fill(0);
7363          this.decodeRowResult = '';
7364          let start = Code39Reader.findAsteriskPattern(row, theCounters);
7365          // Read off white space
7366          let nextStart = row.getNextSet(start[1]);
7367          let end = row.getSize();
7368          let decodedChar;
7369          let lastStart;
7370          do {
7371              Code39Reader.recordPattern(row, nextStart, theCounters);
7372              let pattern = Code39Reader.toNarrowWidePattern(theCounters);
7373              if (pattern < 0) {
7374                  throw new NotFoundException();
7375              }
7376              decodedChar = Code39Reader.patternToChar(pattern);
7377              this.decodeRowResult += decodedChar;
7378              lastStart = nextStart;
7379              for (let counter of theCounters) {
7380                  nextStart += counter;
7381              }
7382              // Read off white space
7383              nextStart = row.getNextSet(nextStart);
7384          } while (decodedChar !== '*');
7385          this.decodeRowResult = this.decodeRowResult.substring(0, this.decodeRowResult.length - 1); // remove asterisk
7386          // Look for whitespace after pattern:
7387          let lastPatternSize = 0;
7388          for (let counter of theCounters) {
7389              lastPatternSize += counter;
7390          }
7391          let whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
7392          // If 50% of last pattern size, following last pattern, is not whitespace, fail
7393          // (but if it's whitespace to the very end of the image, that's OK)
7394          if (nextStart !== end && (whiteSpaceAfterEnd * 2) < lastPatternSize) {
7395              throw new NotFoundException();
7396          }
7397          if (this.usingCheckDigit) {
7398              let max = this.decodeRowResult.length - 1;
7399              let total = 0;
7400              for (let i = 0; i < max; i++) {
7401                  total += Code39Reader.ALPHABET_STRING.indexOf(this.decodeRowResult.charAt(i));
7402              }
7403              if (this.decodeRowResult.charAt(max) !== Code39Reader.ALPHABET_STRING.charAt(total % 43)) {
7404                  throw new ChecksumException();
7405              }
7406              this.decodeRowResult = this.decodeRowResult.substring(0, max);
7407          }
7408          if (this.decodeRowResult.length === 0) {
7409              // false positive
7410              throw new NotFoundException();
7411          }
7412          let resultString;
7413          if (this.extendedMode) {
7414              resultString = Code39Reader.decodeExtended(this.decodeRowResult);
7415          }
7416          else {
7417              resultString = this.decodeRowResult;
7418          }
7419          let left = (start[1] + start[0]) / 2.0;
7420          let right = lastStart + lastPatternSize / 2.0;
7421          return new Result$1(resultString, null, 0, [new ResultPoint(left, rowNumber), new ResultPoint(right, rowNumber)], BarcodeFormat$1.CODE_39, new Date().getTime());
7422      }
7423      static findAsteriskPattern(row, counters) {
7424          let width = row.getSize();
7425          let rowOffset = row.getNextSet(0);
7426          let counterPosition = 0;
7427          let patternStart = rowOffset;
7428          let isWhite = false;
7429          let patternLength = counters.length;
7430          for (let i = rowOffset; i < width; i++) {
7431              if (row.get(i) !== isWhite) {
7432                  counters[counterPosition]++;
7433              }
7434              else {
7435                  if (counterPosition === patternLength - 1) {
7436                      // Look for whitespace before start pattern, >= 50% of width of start pattern
7437                      if (this.toNarrowWidePattern(counters) === Code39Reader.ASTERISK_ENCODING &&
7438                          row.isRange(Math.max(0, patternStart - Math.floor((i - patternStart) / 2)), patternStart, false)) {
7439                          return [patternStart, i];
7440                      }
7441                      patternStart += counters[0] + counters[1];
7442                      counters.copyWithin(0, 2, 2 + counterPosition - 1);
7443                      counters[counterPosition - 1] = 0;
7444                      counters[counterPosition] = 0;
7445                      counterPosition--;
7446                  }
7447                  else {
7448                      counterPosition++;
7449                  }
7450                  counters[counterPosition] = 1;
7451                  isWhite = !isWhite;
7452              }
7453          }
7454          throw new NotFoundException();
7455      }
7456      // For efficiency, returns -1 on failure. Not throwing here saved as many as 700 exceptions
7457      // per image when using some of our blackbox images.
7458      static toNarrowWidePattern(counters) {
7459          let numCounters = counters.length;
7460          let maxNarrowCounter = 0;
7461          let wideCounters;
7462          do {
7463              let minCounter = 0x7fffffff;
7464              for (let counter of counters) {
7465                  if (counter < minCounter && counter > maxNarrowCounter) {
7466                      minCounter = counter;
7467                  }
7468              }
7469              maxNarrowCounter = minCounter;
7470              wideCounters = 0;
7471              let totalWideCountersWidth = 0;
7472              let pattern = 0;
7473              for (let i = 0; i < numCounters; i++) {
7474                  let counter = counters[i];
7475                  if (counter > maxNarrowCounter) {
7476                      pattern |= 1 << (numCounters - 1 - i);
7477                      wideCounters++;
7478                      totalWideCountersWidth += counter;
7479                  }
7480              }
7481              if (wideCounters === 3) {
7482                  // Found 3 wide counters, but are they close enough in width?
7483                  // We can perform a cheap, conservative check to see if any individual
7484                  // counter is more than 1.5 times the average:
7485                  for (let i = 0; i < numCounters && wideCounters > 0; i++) {
7486                      let counter = counters[i];
7487                      if (counter > maxNarrowCounter) {
7488                          wideCounters--;
7489                          // totalWideCountersWidth = 3 * average, so this checks if counter >= 3/2 * average
7490                          if ((counter * 2) >= totalWideCountersWidth) {
7491                              return -1;
7492                          }
7493                      }
7494                  }
7495                  return pattern;
7496              }
7497          } while (wideCounters > 3);
7498          return -1;
7499      }
7500      static patternToChar(pattern) {
7501          for (let i = 0; i < Code39Reader.CHARACTER_ENCODINGS.length; i++) {
7502              if (Code39Reader.CHARACTER_ENCODINGS[i] === pattern) {
7503                  return Code39Reader.ALPHABET_STRING.charAt(i);
7504              }
7505          }
7506          if (pattern === Code39Reader.ASTERISK_ENCODING) {
7507              return '*';
7508          }
7509          throw new NotFoundException();
7510      }
7511      static decodeExtended(encoded) {
7512          let length = encoded.length;
7513          let decoded = '';
7514          for (let i = 0; i < length; i++) {
7515              let c = encoded.charAt(i);
7516              if (c === '+' || c === '$' || c === '%' || c === '/') {
7517                  let next = encoded.charAt(i + 1);
7518                  let decodedChar = '\0';
7519                  switch (c) {
7520                      case '+':
7521                          // +A to +Z map to a to z
7522                          if (next >= 'A' && next <= 'Z') {
7523                              decodedChar = String.fromCharCode(next.charCodeAt(0) + 32);
7524                          }
7525                          else {
7526                              throw new FormatException();
7527                          }
7528                          break;
7529                      case '$':
7530                          // $A to $Z map to control codes SH to SB
7531                          if (next >= 'A' && next <= 'Z') {
7532                              decodedChar = String.fromCharCode(next.charCodeAt(0) - 64);
7533                          }
7534                          else {
7535                              throw new FormatException();
7536                          }
7537                          break;
7538                      case '%':
7539                          // %A to %E map to control codes ESC to US
7540                          if (next >= 'A' && next <= 'E') {
7541                              decodedChar = String.fromCharCode(next.charCodeAt(0) - 38);
7542                          }
7543                          else if (next >= 'F' && next <= 'J') {
7544                              decodedChar = String.fromCharCode(next.charCodeAt(0) - 11);
7545                          }
7546                          else if (next >= 'K' && next <= 'O') {
7547                              decodedChar = String.fromCharCode(next.charCodeAt(0) + 16);
7548                          }
7549                          else if (next >= 'P' && next <= 'T') {
7550                              decodedChar = String.fromCharCode(next.charCodeAt(0) + 43);
7551                          }
7552                          else if (next === 'U') {
7553                              decodedChar = '\0';
7554                          }
7555                          else if (next === 'V') {
7556                              decodedChar = '@';
7557                          }
7558                          else if (next === 'W') {
7559                              decodedChar = '`';
7560                          }
7561                          else if (next === 'X' || next === 'Y' || next === 'Z') {
7562                              decodedChar = '\x7f';
7563                          }
7564                          else {
7565                              throw new FormatException();
7566                          }
7567                          break;
7568                      case '/':
7569                          // /A to /O map to ! to , and /Z maps to :
7570                          if (next >= 'A' && next <= 'O') {
7571                              decodedChar = String.fromCharCode(next.charCodeAt(0) - 32);
7572                          }
7573                          else if (next === 'Z') {
7574                              decodedChar = ':';
7575                          }
7576                          else {
7577                              throw new FormatException();
7578                          }
7579                          break;
7580                  }
7581                  decoded += decodedChar;
7582                  // bump up i again since we read two characters
7583                  i++;
7584              }
7585              else {
7586                  decoded += c;
7587              }
7588          }
7589          return decoded;
7590      }
7591  }
7592  Code39Reader.ALPHABET_STRING = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%';
7593  /**
7594   * These represent the encodings of characters, as patterns of wide and narrow bars.
7595   * The 9 least-significant bits of each int correspond to the pattern of wide and narrow,
7596   * with 1s representing "wide" and 0s representing narrow.
7597   */
7598  Code39Reader.CHARACTER_ENCODINGS = [
7599      0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064,
7599
7600      0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C,
7601      0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016,
7602      0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x0A8,
7603      0x0A2, 0x08A, 0x02A // /-%
7604  ];
7605  Code39Reader.ASTERISK_ENCODING = 0x094;
7606
7607  /*
7608   * Copyright 2010 ZXing authors
7609   *
7610   * Licensed under the Apache License, Version 2.0 (the "License");
7611   * you may not use this file except in compliance with the License.
7612   * You may obtain a copy of the License at
7613   *
7614   *      http://www.apache.org/licenses/LICENSE-2.0
7615   *
7616   * Unless required by applicable law or agreed to in writing, softw
vendor: 10,679 bytes, lines 7616-7868
7616are
7617   * distributed under the License is distributed on an "AS IS" BASIS,
7618   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7619   * See the License for the specific language governing permissions and
7620   * limitations under the License.
7621   */
7622  /**
7623   * <p>Decodes Code 93 barcodes.</p>
7624   *
7625   * @author Sean Owen
7626   * @see Code39Reader
7627   */
7628  class Code93Reader extends OneDReader {
7629      //public Code93Reader() {
7630      //  decodeRowResult = new StringBuilder(20);
7631      //  counters = new int[6];
7632      //}
7633      constructor() {
7634          super();
7635          this.decodeRowResult = '';
7636          this.counters = new Int32Array(6);
7637      }
7638      decodeRow(rowNumber, row, hints) {
7639          let start = this.findAsteriskPattern(row);
7640          // Read off white space
7641          let nextStart = row.getNextSet(start[1]);
7642          let end = row.getSize();
7643          let theCounters = this.counters;
7644          theCounters.fill(0);
7645          this.decodeRowResult = '';
7646          let decodedChar;
7647          let lastStart;
7648          do {
7649              Code93Reader.recordPattern(row, nextStart, theCounters);
7650              let pattern = this.toPattern(theCounters);
7651              if (pattern < 0) {
7652                  throw new NotFoundException();
7653              }
7654              decodedChar = this.patternToChar(pattern);
7655              this.decodeRowResult += decodedChar;
7656              lastStart = nextStart;
7657              for (let counter of theCounters) {
7658                  nextStart += counter;
7659              }
7660              // Read off white space
7661              nextStart = row.getNextSet(nextStart);
7662          } while (decodedChar !== '*');
7663          this.decodeRowResult = this.decodeRowResult.substring(0, this.decodeRowResult.length - 1); // remove asterisk
7664          let lastPatternSize = 0;
7665          for (let counter of theCounters) {
7666              lastPatternSize += counter;
7667          }
7668          // Should be at least one more black module
7669          if (nextStart === end || !row.get(nextStart)) {
7670              throw new NotFoundException();
7671          }
7672          if (this.decodeRowResult.length < 2) {
7673              // false positive -- need at least 2 checksum digits
7674              throw new NotFoundException();
7675          }
7676          this.checkChecksums(this.decodeRowResult);
7677          // Remove checksum digits
7678          this.decodeRowResult = this.decodeRowResult.substring(0, this.decodeRowResult.length - 2);
7679          let resultString = this.decodeExtended(this.decodeRowResult);
7680          let left = (start[1] + start[0]) / 2.0;
7681          let right = lastStart + lastPatternSize / 2.0;
7682          return new Result$1(resultString, null, 0, [new ResultPoint(left, rowNumber), new ResultPoint(right, rowNumber)], BarcodeFormat$1.CODE_93, new Date().getTime());
7683      }
7684      findAsteriskPattern(row) {
7685          let width = row.getSize();
7686          let rowOffset = row.getNextSet(0);
7687          this.counters.fill(0);
7688          let theCounters = this.counters;
7689          let patternStart = rowOffset;
7690          let isWhite = false;
7691          let patternLength = theCounters.length;
7692          let counterPosition = 0;
7693          for (let i = rowOffset; i < width; i++) {
7694              if (row.get(i) !== isWhite) {
7695                  theCounters[counterPosition]++;
7696              }
7697              else {
7698                  if (counterPosition === patternLength - 1) {
7699                      if (this.toPattern(theCounters) === Code93Reader.ASTERISK_ENCODING) {
7700                          return new Int32Array([patternStart, i]);
7701                      }
7702                      patternStart += theCounters[0] + theCounters[1];
7703                      theCounters.copyWithin(0, 2, 2 + counterPosition - 1);
7704                      theCounters[counterPosition - 1] = 0;
7705                      theCounters[counterPosition] = 0;
7706                      counterPosition--;
7707                  }
7708                  else {
7709                      counterPosition++;
7710                  }
7711                  theCounters[counterPosition] = 1;
7712                  isWhite = !isWhite;
7713              }
7714          }
7715          throw new NotFoundException;
7716      }
7717      toPattern(counters) {
7718          let sum = 0;
7719          for (const counter of counters) {
7720              sum += counter;
7721          }
7722          let pattern = 0;
7723          let max = counters.length;
7724          for (let i = 0; i < max; i++) {
7725              let scaled = Math.round(counters[i] * 9.0 / sum);
7726              if (scaled < 1 || scaled > 4) {
7727                  return -1;
7728              }
7729              if ((i & 0x01) === 0) {
7730                  for (let j = 0; j < scaled; j++) {
7731                      pattern = (pattern << 1) | 0x01;
7732                  }
7733              }
7734              else {
7735                  pattern <<= scaled;
7736              }
7737          }
7738          return pattern;
7739      }
7740      patternToChar(pattern) {
7741          for (let i = 0; i < Code93Reader.CHARACTER_ENCODINGS.length; i++) {
7742              if (Code93Reader.CHARACTER_ENCODINGS[i] === pattern) {
7743                  return Code93Reader.ALPHABET_STRING.charAt(i);
7744              }
7745          }
7746          throw new NotFoundException();
7747      }
7748      decodeExtended(encoded) {
7749          let length = encoded.length;
7750          let decoded = '';
7751          for (let i = 0; i < length; i++) {
7752              let c = encoded.charAt(i);
7753              if (c >= 'a' && c <= 'd') {
7754                  if (i >= length - 1) {
7755                      throw new FormatException();
7756                  }
7757                  let next = encoded.charAt(i + 1);
7758                  let decodedChar = '\0';
7759                  switch (c) {
7760                      case 'd':
7761                          // +A to +Z map to a to z
7762                          if (next >= 'A' && next <= 'Z') {
7763                              decodedChar = String.fromCharCode(next.charCodeAt(0) + 32);
7764                          }
7765                          else {
7766                              throw new FormatException();
7767                          }
7768                          break;
7769                      case 'a':
7770                          // $A to $Z map to control codes SH to SB
7771                          if (next >= 'A' && next <= 'Z') {
7772                              decodedChar = String.fromCharCode(next.charCodeAt(0) - 64);
7773                          }
7774                          else {
7775                              throw new FormatException();
7776                          }
7777                          break;
7778                      case 'b':
7779                          if (next >= 'A' && next <= 'E') {
7780                              // %A to %E map to control codes ESC to USep
7781                              decodedChar = String.fromCharCode(next.charCodeAt(0) - 38);
7782                          }
7783                          else if (next >= 'F' && next <= 'J') {
7784                              // %F to %J map to ; < = > ?
7785                              decodedChar = String.fromCharCode(next.charCodeAt(0) - 11);
7786                          }
7787                          else if (next >= 'K' && next <= 'O') {
7788                              // %K to %O map to [ \ ] ^ _
7789                              decodedChar = String.fromCharCode(next.charCodeAt(0) + 16);
7790                          }
7791                          else if (next >= 'P' && next <= 'T') {
7792                              // %P to %T map to { | } ~ DEL
7793                              decodedChar = String.fromCharCode(next.charCodeAt(0) + 43);
7794                          }
7795                          else if (next === 'U') {
7796                              // %U map to NUL
7797                              decodedChar = '\0';
7798                          }
7799                          else if (next === 'V') {
7800                              // %V map to @
7801                              decodedChar = '@';
7802                          }
7803                          else if (next === 'W') {
7804                              // %W map to `
7805                              decodedChar = '`';
7806                          }
7807                          else if (next >= 'X' && next <= 'Z') {
7808                              // %X to %Z all map to DEL (127)
7809                              decodedChar = String.fromCharCode(127);
7810                          }
7811                          else {
7812                              throw new FormatException();
7813                          }
7814                          break;
7815                      case 'c':
7816                          // /A to /O map to ! to , and /Z maps to :
7817                          if (next >= 'A' && next <= 'O') {
7818                              decodedChar = String.fromCharCode(next.charCodeAt(0) - 32);
7819                          }
7820                          else if (next === 'Z') {
7821                              decodedChar = ':';
7822                          }
7823                          else {
7824                              throw new FormatException();
7825                          }
7826                          break;
7827                  }
7828                  decoded += decodedChar;
7829                  // bump up i again since we read two characters
7830                  i++;
7831              }
7832              else {
7833                  decoded += c;
7834              }
7835          }
7836          return decoded;
7837      }
7838      checkChecksums(result) {
7839          let length = result.length;
7840          this.checkOneChecksum(result, length - 2, 20);
7841          this.checkOneChecksum(result, length - 1, 15);
7842      }
7843      checkOneChecksum(result, checkPosition, weightMax) {
7844          let weight = 1;
7845          let total = 0;
7846          for (let i = checkPosition - 1; i >= 0; i--) {
7847              total += weight * Code93Reader.ALPHABET_STRING.indexOf(result.charAt(i));
7848              if (++weight > weightMax) {
7849                  weight = 1;
7850              }
7851          }
7852          if (result.charAt(checkPosition) !== Code93Reader.ALPHABET_STRING[total % 47]) {
7853              throw new ChecksumException;
7854          }
7855      }
7856  }
7857  // Note that 'abcd' are dummy characters in place of control characters.
7858  Code93Reader.ALPHABET_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*";
7859  /**
7860   * These represent the encodings of characters, as patterns of wide and narrow bars.
7861   * The 9 least-significant bits of each int correspond to the pattern of wide and narrow.
7862   */
7863  Code93Reader.CHARACTER_ENCODINGS = [
7864      0x114, 0x148, 0x144, 0x142, 0x128, 0x124, 0x122, 0x150, 0x112, 0x10A,
7865      0x1A8, 0x1A4, 0x1A2, 0x194, 0x192, 0x18A, 0x168, 0x164, 0x162, 0x134,
7866      0x11A, 0x158, 0x14C, 0x146, 0x12C, 0x116, 0x1B4, 0x1B2, 0x1AC, 0x1A6,
7867      0x196, 0x19A, 0x16C, 0x166, 0x136, 0x13A,
7868      0x12E, 0x1D4, 0x1D2, 0x1CA, 0x16E, 0x176, 0x1AE,
7869      0x126, 0x1DA, 0x1D6, 0x132, 0x15E,
7870  ];
7871  Code93Reader.ASTERISK_ENCODING = Code93Reader.CHARACTER_ENCODINGS[47];
7872
7873  /*
7874   * Copyright 2008 ZXing authors
7875   *
7876   * Licensed under the Apache License, Version 2.0 (the "License");
7877   * you may not use this file except in compliance with the License.
7878   * You may obtain a copy of the License at
7879   *
7880   *      http://www.apache.org/licenses/LICENSE-2.0
7881   *
7882   * Unless required by applicable law or agreed to in writing, software
7883   * distributed under the License is distributed on an "AS IS" BASIS,
7884   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7885   * See the License for the specific language governing permissions and
7886   * limitations under the License.
7887   
vendor: 11,661 bytes, lines 7887-8162
7887*/
7888  /**
7889   * <p>Decodes ITF barcodes.</p>
7890   *
7891   * @author Tjieco
7892   */
7893  class ITFReader extends OneDReader {
7894      constructor() {
7895          // private static W = 3; // Pixel width of a 3x wide line
7896          // private static w = 2; // Pixel width of a 2x wide line
7897          // private static N = 1; // Pixed width of a narrow line
7898          super(...arguments);
7899          // Stores the actual narrow line width of the image being decoded.
7900          this.narrowLineWidth = -1;
7901      }
7902      // See ITFWriter.PATTERNS
7903      /*
7904    
7905      /!**
7906       * Patterns of Wide / Narrow lines to indicate each digit
7907       *!/
7908      */
7909      decodeRow(rowNumber, row, hints) {
7910          // Find out where the Middle section (payload) starts & ends
7911          let startRange = this.decodeStart(row);
7912          let endRange = this.decodeEnd(row);
7913          let result = new StringBuilder();
7914          ITFReader.decodeMiddle(row, startRange[1], endRange[0], result);
7915          let resultString = result.toString();
7916          let allowedLengths = null;
7917          if (hints != null) {
7918              allowedLengths = hints.get(DecodeHintType$1.ALLOWED_LENGTHS);
7919          }
7920          if (allowedLengths == null) {
7921              allowedLengths = ITFReader.DEFAULT_ALLOWED_LENGTHS;
7922          }
7923          // To avoid false positives with 2D barcodes (and other patterns), make
7924          // an assumption that the decoded string must be a 'standard' length if it's short
7925          let length = resultString.length;
7926          let lengthOK = false;
7927          let maxAllowedLength = 0;
7928          for (let value of allowedLengths) {
7929              if (length === value) {
7930                  lengthOK = true;
7931                  break;
7932              }
7933              if (value > maxAllowedLength) {
7934                  maxAllowedLength = value;
7935              }
7936          }
7937          if (!lengthOK && length > maxAllowedLength) {
7938              lengthOK = true;
7939          }
7940          if (!lengthOK) {
7941              throw new FormatException();
7942          }
7943          const points = [new ResultPoint(startRange[1], rowNumber), new ResultPoint(endRange[0], rowNumber)];
7944          let resultReturn = new Result$1(resultString, null, // no natural byte representation for these barcodes
7945          0, points, BarcodeFormat$1.ITF, new Date().getTime());
7946          return resultReturn;
7947      }
7948      /*
7949      /!**
7950       * @param row          row of black/white values to search
7951       * @param payloadStart offset of start pattern
7952       * @param resultString {@link StringBuilder} to append decoded chars to
7953       * @throws NotFoundException if decoding could not complete successfully
7954       *!/*/
7955      static decodeMiddle(row, payloadStart, payloadEnd, resultString) {
7956          // Digits are interleaved in pairs - 5 black lines for one digit, and the
7957          // 5
7958          // interleaved white lines for the second digit.
7959          // Therefore, need to scan 10 lines and then
7960          // split these into two arrays
7961          let counterDigitPair = new Int32Array(10); // 10
7962          let counterBlack = new Int32Array(5); // 5
7963          let counterWhite = new Int32Array(5); // 5
7964          counterDigitPair.fill(0);
7965          counterBlack.fill(0);
7966          counterWhite.fill(0);
7967          while (payloadStart < payloadEnd) {
7968              // Get 10 runs of black/white.
7969              OneDReader.recordPattern(row, payloadStart, counterDigitPair);
7970              // Split them into each array
7971              for (let k = 0; k < 5; k++) {
7972                  let twoK = 2 * k;
7973                  counterBlack[k] = counterDigitPair[twoK];
7974                  counterWhite[k] = counterDigitPair[twoK + 1];
7975              }
7976              let bestMatch = ITFReader.decodeDigit(counterBlack);
7977              resultString.append(bestMatch.toString());
7978              bestMatch = this.decodeDigit(counterWhite);
7979              resultString.append(bestMatch.toString());
7980              counterDigitPair.forEach(function (counterDigit) {
7981                  payloadStart += counterDigit;
7982              });
7983          }
7984      }
7985      /*/!**
7986       * Identify where the start of the middle / payload section starts.
7987       *
7988       * @param row row of black/white values to search
7989       * @return Array, containing index of start of 'start block' and end of
7990       *         'start block'
7991       *!/*/
7992      decodeStart(row) {
7993          let endStart = ITFReader.skipWhiteSpace(row);
7994          let startPattern = ITFReader.findGuardPattern(row, endStart, ITFReader.START_PATTERN);
7995          // Determine the width of a narrow line in pixels. We can do this by
7996          // getting the width of the start pattern and dividing by 4 because its
7997          // made up of 4 narrow lines.
7998          this.narrowLineWidth = (startPattern[1] - startPattern[0]) / 4;
7999          this.validateQuietZone(row, startPattern[0]);
8000          return startPattern;
8001      }
8002      /*/!**
8003       * The start & end patterns must be pre/post fixed by a quiet zone. This
8004       * zone must be at least 10 times the width of a narrow line.  Scan back until
8005       * we either get to the start of the barcode or match the necessary number of
8006       * quiet zone pixels.
8007       *
8008       * Note: Its assumed the row is reversed when using this method to find
8009       * quiet zone after the end pattern.
8010       *
8011       * ref: http://www.barcode-1.net/i25code.html
8012       *
8013       * @param row bit array representing the scanned barcode.
8014       * @param startPattern index into row of the start or end pattern.
8015       * @throws NotFoundException if the quiet zone cannot be found
8016       *!/*/
8017      validateQuietZone(row, startPattern) {
8018          let quietCount = this.narrowLineWidth * 10; // expect to find this many pixels of quiet zone
8019          // if there are not so many pixel at all let's try as many as possible
8020          quietCount = quietCount < startPattern ? quietCount : startPattern;
8021          for (let i = startPattern - 1; quietCount > 0 && i >= 0; i--) {
8022              if (row.get(i)) {
8023                  break;
8024              }
8025              quietCount--;
8026          }
8027          if (quietCount !== 0) {
8028              // Unable to find the necessary number of quiet zone pixels.
8029              throw new NotFoundException();
8030          }
8031      }
8032      /*
8033      /!**
8034       * Skip all whitespace until we get to the first black line.
8035       *
8036       * @param row row of black/white values to search
8037       * @return index of the first black line.
8038       * @throws NotFoundException Throws exception if no black lines are found in the row
8039       *!/*/
8040      static skipWhiteSpace(row) {
8041          const width = row.getSize();
8042          const endStart = row.getNextSet(0);
8043          if (endStart === width) {
8044              throw new NotFoundException();
8045          }
8046          return endStart;
8047      }
8048      /*/!**
8049       * Identify where the end of the middle / payload section ends.
8050       *
8051       * @param row row of black/white values to search
8052       * @return Array, containing index of start of 'end block' and end of 'end
8053       *         block'
8054       *!/*/
8055      decodeEnd(row) {
8056          // For convenience, reverse the row and then
8057          // search from 'the start' for the end block
8058          row.reverse();
8059          try {
8060              let endStart = ITFReader.skipWhiteSpace(row);
8061              let endPattern;
8062              try {
8063                  endPattern = ITFReader.findGuardPattern(row, endStart, ITFReader.END_PATTERN_REVERSED[0]);
8064              }
8065              catch (error) {
8066                  if (error instanceof NotFoundException) {
8067                      endPattern = ITFReader.findGuardPattern(row, endStart, ITFReader.END_PATTERN_REVERSED[1]);
8068                  }
8069              }
8070              // The start & end patterns must be pre/post fixed by a quiet zone. This
8071              // zone must be at least 10 times the width of a narrow line.
8072              // ref: http://www.barcode-1.net/i25code.html
8073              this.validateQuietZone(row, endPattern[0]);
8074              // Now recalculate the indices of where the 'endblock' starts & stops to
8075              // accommodate
8076              // the reversed nature of the search
8077              let temp = endPattern[0];
8078              endPattern[0] = row.getSize() - endPattern[1];
8079              endPattern[1] = row.getSize() - temp;
8080              return endPattern;
8081          }
8082          finally {
8083              // Put the row back the right way.
8084              row.reverse();
8085          }
8086      }
8087      /*
8088      /!**
8089       * @param row       row of black/white values to search
8090       * @param rowOffset position to start search
8091       * @param pattern   pattern of counts of number of black and white pixels that are
8092       *                  being searched for as a pattern
8093       * @return start/end horizontal offset of guard pattern, as an array of two
8094       *         ints
8095       * @throws NotFoundException if pattern is not found
8096       *!/*/
8097      static findGuardPattern(row, rowOffset, pattern) {
8098          let patternLength = pattern.length;
8099          let counters = new Int32Array(patternLength);
8100          let width = row.getSize();
8101          let isWhite = false;
8102          let counterPosition = 0;
8103          let patternStart = rowOffset;
8104          counters.fill(0);
8105          for (let x = rowOffset; x < width; x++) {
8106              if (row.get(x) !== isWhite) {
8107                  counters[counterPosition]++;
8108              }
8109              else {
8110                  if (counterPosition === patternLength - 1) {
8111                      if (OneDReader.patternMatchVariance(counters, pattern, ITFReader.MAX_INDIVIDUAL_VARIANCE) < ITFReader.MAX_AVG_VARIANCE) {
8112                          return [patternStart, x];
8113                      }
8114                      patternStart += counters[0] + counters[1];
8115                      System.arraycopy(counters, 2, counters, 0, counterPosition - 1);
8116                      counters[counterPosition - 1] = 0;
8117                      counters[counterPosition] = 0;
8118                      counterPosition--;
8119                  }
8120                  else {
8121                      counterPosition++;
8122                  }
8123                  counters[counterPosition] = 1;
8124                  isWhite = !isWhite;
8125              }
8126          }
8127          throw new NotFoundException();
8128      }
8129      /*/!**
8130       * Attempts to decode a sequence of ITF black/white lines into single
8131       * digit.
8132       *
8133       * @param counters the counts of runs of observed black/white/black/... values
8134       * @return The decoded digit
8135       * @throws NotFoundException if digit cannot be decoded
8136       *!/*/
8137      static decodeDigit(counters) {
8138          let bestVariance = ITFReader.MAX_AVG_VARIANCE; // worst variance we'll accept
8139          let bestMatch = -1;
8140          let max = ITFReader.PATTERNS.length;
8141          for (let i = 0; i < max; i++) {
8142              let pattern = ITFReader.PATTERNS[i];
8143              let variance = OneDReader.patternMatchVariance(counters, pattern, ITFReader.MAX_INDIVIDUAL_VARIANCE);
8144              if (variance < bestVariance) {
8145                  bestVariance = variance;
8146                  bestMatch = i;
8147              }
8148              else if (variance === bestVariance) {
8149                  // if we find a second 'best match' with the same variance, we can not reliably report to have a suitable match
8150                  bestMatch = -1;
8151              }
8152          }
8153          if (bestMatch >= 0) {
8154              return bestMatch % 10;
8155          }
8156          else {
8157              throw new NotFoundException();
8158          }
8159      }
8160  }
8161  ITFReader.PATTERNS = [
8162      Int32Array.from([1, 1, 2, 2, 1]),
8162
8163      Int32Array.from([2, 1, 1, 1, 2]),
8164      Int32Array.from([1, 2, 1, 1, 2]),
8165      Int32Array.from([2, 2, 1, 1, 1]),
8166      Int32Array.from([1, 1, 2, 1, 2]),
8167      Int32Array.from([2, 1, 2, 1, 1]),
8168      Int32Array.from([1, 2, 2, 1, 1]),
8169      Int32Array.from([1, 1, 1, 2, 2]),
8170      Int32Array.from([2, 1, 1, 2, 1]),
8171      Int32Array.from([1, 2, 1, 2, 1]),
8172      Int32Array.from([1, 1, 3, 3, 1]),
8173      Int32Array.from([3, 1, 1, 1, 3]),
8174      Int32Array.from([1, 3, 1, 1, 3]),
8175      Int32Array.from([3, 3, 1, 1, 1]),
8176      Int32Array.from([1, 1, 3, 1, 3]),
8177      Int32Array.from([3, 1, 3, 1, 1]),
8178      Int32Array.from([1, 3, 3, 1, 1]),
8179      Int32Array.from([1, 1, 1, 3, 3]),
8180      Int32Array.from([3, 1, 1, 3, 1]),
8181      Int32Array.from([1, 3, 1, 3, 1]) // 9
8182  ];
8183  ITFReader.MAX_AVG_VARIANCE = 0.38;
8184  ITFReader.MAX_INDIVIDUAL_VARIANCE = 0.5;
8185  /* /!** Valid ITF lengths. Anything longer than the largest value is also allowed. *!/*/
8186  ITFReader.DEFAULT_ALLOWED_LENGTHS = [6, 8, 10, 12, 14];
8187  /*/!**
8188   * Start/end guard pattern.
8189   *
8190   * Note: The end pattern is reversed because the row is reversed before
8191   * searching for the END_PATTERN
8192   *!/*/
8193  ITFReader.START_PATTERN = Int32Array.from([1, 1, 1, 1]);
8194  ITFReader.END_PATTERN_REVERSED = [
8195      Int32Array.from([1, 1, 2]),
vendor: 7,622 bytes, lines 8195-8379
8195
8196      Int32Array.from([1, 1, 3]) // 3x
8197  ];
8198
8199  /*
8200   * Copyright 2008 ZXing authors
8201   *
8202   * Licensed under the Apache License, Version 2.0 (the "License");
8203   * you may not use this file except in compliance with the License.
8204   * You may obtain a copy of the License at
8205   *
8206   *      http://www.apache.org/licenses/LICENSE-2.0
8207   *
8208   * Unless required by applicable law or agreed to in writing, software
8209   * distributed under the License is distributed on an "AS IS" BASIS,
8210   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8211   * See the License for the specific language governing permissions and
8212   * limitations under the License.
8213   */
8214  /**
8215   * <p>Encapsulates functionality and implementation that is common to UPC and EAN families
8216   * of one-dimensional barcodes.</p>
8217   *
8218   * @author [email protected] (Daniel Switkin)
8219   * @author Sean Owen
8220   * @author [email protected] (Alasdair Mackintosh)
8221   */
8222  class AbstractUPCEANReader extends OneDReader {
8223      constructor() {
8224          super(...arguments);
8225          this.decodeRowStringBuffer = '';
8226      }
8227      // private final UPCEANExtensionSupport extensionReader;
8228      // private final EANManufacturerOrgSupport eanManSupport;
8229      /*
8230      protected UPCEANReader() {
8231          decodeRowStringBuffer = new StringBuilder(20);
8232          extensionReader = new UPCEANExtensionSupport();
8233          eanManSupport = new EANManufacturerOrgSupport();
8234      }
8235      */
8236      static findStartGuardPattern(row) {
8237          let foundStart = false;
8238          let startRange;
8239          let nextStart = 0;
8240          let counters = Int32Array.from([0, 0, 0]);
8241          while (!foundStart) {
8242              counters = Int32Array.from([0, 0, 0]);
8243              startRange = AbstractUPCEANReader.findGuardPattern(row, nextStart, false, this.START_END_PATTERN, counters);
8244              let start = startRange[0];
8245              nextStart = startRange[1];
8246              let quietStart = start - (nextStart - start);
8247              if (quietStart >= 0) {
8248                  foundStart = row.isRange(quietStart, start, false);
8249              }
8250          }
8251          return startRange;
8252      }
8253      static checkChecksum(s) {
8254          return AbstractUPCEANReader.checkStandardUPCEANChecksum(s);
8255      }
8256      static checkStandardUPCEANChecksum(s) {
8257          let length = s.length;
8258          if (length === 0)
8259              return false;
8260          let check = parseInt(s.charAt(length - 1), 10);
8261          return AbstractUPCEANReader.getStandardUPCEANChecksum(s.substring(0, length - 1)) === check;
8262      }
8263      static getStandardUPCEANChecksum(s) {
8264          let length = s.length;
8265          let sum = 0;
8266          for (let i = length - 1; i >= 0; i -= 2) {
8267              let digit = s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
8268              if (digit < 0 || digit > 9) {
8269                  throw new FormatException();
8270              }
8271              sum += digit;
8272          }
8273          sum *= 3;
8274          for (let i = length - 2; i >= 0; i -= 2) {
8275              let digit = s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
8276              if (digit < 0 || digit > 9) {
8277                  throw new FormatException();
8278              }
8279              sum += digit;
8280          }
8281          return (1000 - sum) % 10;
8282      }
8283      static decodeEnd(row, endStart) {
8284          return AbstractUPCEANReader.findGuardPattern(row, endStart, false, AbstractUPCEANReader.START_END_PATTERN, new Int32Array(AbstractUPCEANReader.START_END_PATTERN.length).fill(0));
8285      }
8286      /**
8287       * @throws NotFoundException
8288       */
8289      static findGuardPatternWithoutCounters(row, rowOffset, whiteFirst, pattern) {
8290          return this.findGuardPattern(row, rowOffset, whiteFirst, pattern, new Int32Array(pattern.length));
8291      }
8292      /**
8293       * @param row row of black/white values to search
8294       * @param rowOffset position to start search
8295       * @param whiteFirst if true, indicates that the pattern specifies white/black/white/...
8296       * pixel counts, otherwise, it is interpreted as black/white/black/...
8297       * @param pattern pattern of counts of number of black and white pixels that are being
8298       * searched for as a pattern
8299       * @param counters array of counters, as long as pattern, to re-use
8300       * @return start/end horizontal offset of guard pattern, as an array of two ints
8301       * @throws NotFoundException if pattern is not found
8302       */
8303      static findGuardPattern(row, rowOffset, whiteFirst, pattern, counters) {
8304          let width = row.getSize();
8305          rowOffset = whiteFirst ? row.getNextUnset(rowOffset) : row.getNextSet(rowOffset);
8306          let counterPosition = 0;
8307          let patternStart = rowOffset;
8308          let patternLength = pattern.length;
8309          let isWhite = whiteFirst;
8310          for (let x = rowOffset; x < width; x++) {
8311              if (row.get(x) !== isWhite) {
8312                  counters[counterPosition]++;
8313              }
8314              else {
8315                  if (counterPosition === patternLength - 1) {
8316                      if (OneDReader.patternMatchVariance(counters, pattern, AbstractUPCEANReader.MAX_INDIVIDUAL_VARIANCE) < AbstractUPCEANReader.MAX_AVG_VARIANCE) {
8317                          return Int32Array.from([patternStart, x]);
8318                      }
8319                      patternStart += counters[0] + counters[1];
8320                      let slice = counters.slice(2, counters.length);
8321                      for (let i = 0; i < counterPosition - 1; i++) {
8322                          counters[i] = slice[i];
8323                      }
8324                      counters[counterPosition - 1] = 0;
8325                      counters[counterPosition] = 0;
8326                      counterPosition--;
8327                  }
8328                  else {
8329                      counterPosition++;
8330                  }
8331                  counters[counterPosition] = 1;
8332                  isWhite = !isWhite;
8333              }
8334          }
8335          throw new NotFoundException();
8336      }
8337      static decodeDigit(row, counters, rowOffset, patterns) {
8338          this.recordPattern(row, rowOffset, counters);
8339          let bestVariance = this.MAX_AVG_VARIANCE;
8340          let bestMatch = -1;
8341          let max = patterns.length;
8342          for (let i = 0; i < max; i++) {
8343              let pattern = patterns[i];
8344              let variance = OneDReader.patternMatchVariance(counters, pattern, AbstractUPCEANReader.MAX_INDIVIDUAL_VARIANCE);
8345              if (variance < bestVariance) {
8346                  bestVariance = variance;
8347                  bestMatch = i;
8348              }
8349          }
8350          if (bestMatch >= 0) {
8351              return bestMatch;
8352          }
8353          else {
8354              throw new NotFoundException();
8355          }
8356      }
8357  }
8358  // These two values are critical for determining how permissive the decoding will be.
8359  // We've arrived at these values through a lot of trial and error. Setting them any higher
8360  // lets false positives creep in quickly.
8361  AbstractUPCEANReader.MAX_AVG_VARIANCE = 0.48;
8362  AbstractUPCEANReader.MAX_INDIVIDUAL_VARIANCE = 0.7;
8363  /**
8364   * Start/end guard pattern.
8365   */
8366  AbstractUPCEANReader.START_END_PATTERN = Int32Array.from([1, 1, 1]);
8367  /**
8368   * Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
8369   */
8370  AbstractUPCEANReader.MIDDLE_PATTERN = Int32Array.from([1, 1, 1, 1, 1]);
8371  /**
8372   * end guard pattern.
8373   */
8374  AbstractUPCEANReader.END_PATTERN = Int32Array.from([1, 1, 1, 1, 1, 1]);
8375  /**
8376   * "Odd", or "L" patterns used to encode UPC/EAN digits.
8377   */
8378  AbstractUPCEANReader.L_PATTERNS = [
8379      Int32Array.from([3, 2, 1, 1]),
8379
8380      Int32Array.from([2, 2, 2, 1]),
8381      Int32Array.from([2, 1, 2, 2]),
8382      Int32Array.from([1, 4, 1, 1]),
8383      Int32Array.from([1, 1, 3, 2]),
8384      Int32Array.from([1, 2, 3, 1]),
8385      Int32Array.from([1, 1, 1, 4]),
8386      Int32Array.from([1, 3, 1, 2]),
8387      Int32Array.from([1, 2, 1, 3]),
8388      Int32Array.from([3, 1, 1, 2]),
vendor: 22,263 bytes, lines 8388-8921
8388
8389  ];
8390
8391  /*
8392   * Copyright (C) 2010 ZXing authors
8393   *
8394   * Licensed under the Apache License, Version 2.0 (the "License");
8395   * you may not use this file except in compliance with the License.
8396   * You may obtain a copy of the License at
8397   *
8398   *      http://www.apache.org/licenses/LICENSE-2.0
8399   *
8400   * Unless required by applicable law or agreed to in writing, software
8401   * distributed under the License is distributed on an "AS IS" BASIS,
8402   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8403   * See the License for the specific language governing permissions and
8404   * limitations under the License.
8405   */
8406  /**
8407   * @see UPCEANExtension2Support
8408   */
8409  class UPCEANExtension5Support {
8410      constructor() {
8411          this.CHECK_DIGIT_ENCODINGS = [0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05];
8412          this.decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
8413          this.decodeRowStringBuffer = '';
8414      }
8415      decodeRow(rowNumber, row, extensionStartRange) {
8416          let result = this.decodeRowStringBuffer;
8417          let end = this.decodeMiddle(row, extensionStartRange, result);
8418          let resultString = result.toString();
8419          let extensionData = UPCEANExtension5Support.parseExtensionString(resultString);
8420          let resultPoints = [
8421              new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0, rowNumber),
8422              new ResultPoint(end, rowNumber)
8423          ];
8424          let extensionResult = new Result$1(resultString, null, 0, resultPoints, BarcodeFormat$1.UPC_EAN_EXTENSION, new Date().getTime());
8425          if (extensionData != null) {
8426              extensionResult.putAllMetadata(extensionData);
8427          }
8428          return extensionResult;
8429      }
8430      decodeMiddle(row, startRange, resultString) {
8431          let counters = this.decodeMiddleCounters;
8432          counters[0] = 0;
8433          counters[1] = 0;
8434          counters[2] = 0;
8435          counters[3] = 0;
8436          let end = row.getSize();
8437          let rowOffset = startRange[1];
8438          let lgPatternFound = 0;
8439          for (let x = 0; x < 5 && rowOffset < end; x++) {
8440              let bestMatch = AbstractUPCEANReader.decodeDigit(row, counters, rowOffset, AbstractUPCEANReader.L_AND_G_PATTERNS);
8441              resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch % 10));
8442              for (let counter of counters) {
8443                  rowOffset += counter;
8444              }
8445              if (bestMatch >= 10) {
8446                  lgPatternFound |= 1 << (4 - x);
8447              }
8448              if (x !== 4) {
8449                  // Read off separator if not last
8450                  rowOffset = row.getNextSet(rowOffset);
8451                  rowOffset = row.getNextUnset(rowOffset);
8452              }
8453          }
8454          if (resultString.length !== 5) {
8455              throw new NotFoundException();
8456          }
8457          let checkDigit = this.determineCheckDigit(lgPatternFound);
8458          if (UPCEANExtension5Support.extensionChecksum(resultString.toString()) !== checkDigit) {
8459              throw new NotFoundException();
8460          }
8461          return rowOffset;
8462      }
8463      static extensionChecksum(s) {
8464          let length = s.length;
8465          let sum = 0;
8466          for (let i = length - 2; i >= 0; i -= 2) {
8467              sum += s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
8468          }
8469          sum *= 3;
8470          for (let i = length - 1; i >= 0; i -= 2) {
8471              sum += s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
8472          }
8473          sum *= 3;
8474          return sum % 10;
8475      }
8476      determineCheckDigit(lgPatternFound) {
8477          for (let d = 0; d < 10; d++) {
8478              if (lgPatternFound === this.CHECK_DIGIT_ENCODINGS[d]) {
8479                  return d;
8480              }
8481          }
8482          throw new NotFoundException();
8483      }
8484      static parseExtensionString(raw) {
8485          if (raw.length !== 5) {
8486              return null;
8487          }
8488          let value = UPCEANExtension5Support.parseExtension5String(raw);
8489          if (value == null) {
8490              return null;
8491          }
8492          return new Map([[ResultMetadataType$1.SUGGESTED_PRICE, value]]);
8493      }
8494      static parseExtension5String(raw) {
8495          let currency;
8496          switch (raw.charAt(0)) {
8497              case '0':
8498                  currency = '£';
8499                  break;
8500              case '5':
8501                  currency = '$';
8502                  break;
8503              case '9':
8504                  // Reference: http://www.jollytech.com
8505                  switch (raw) {
8506                      case '90000':
8507                          // No suggested retail price
8508                          return null;
8509                      case '99991':
8510                          // Complementary
8511                          return '0.00';
8512                      case '99990':
8513                          return 'Used';
8514                  }
8515                  // Otherwise... unknown currency?
8516                  currency = '';
8517                  break;
8518              default:
8519                  currency = '';
8520                  break;
8521          }
8522          let rawAmount = parseInt(raw.substring(1));
8523          let unitsString = (rawAmount / 100).toString();
8524          let hundredths = rawAmount % 100;
8525          let hundredthsString = hundredths < 10 ? '0' + hundredths : hundredths.toString(); // fixme
8526          return currency + unitsString + '.' + hundredthsString;
8527      }
8528  }
8529
8530  /*
8531   * Copyright (C) 2012 ZXing authors
8532   *
8533   * Licensed under the Apache License, Version 2.0 (the "License");
8534   * you may not use this file except in compliance with the License.
8535   * You may obtain a copy of the License at
8536   *
8537   *      http://www.apache.org/licenses/LICENSE-2.0
8538   *
8539   * Unless required by applicable law or agreed to in writing, software
8540   * distributed under the License is distributed on an "AS IS" BASIS,
8541   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8542   * See the License for the specific language governing permissions and
8543   * limitations under the License.
8544   */
8545  /**
8546   * @see UPCEANExtension5Support
8547   */
8548  class UPCEANExtension2Support {
8549      constructor() {
8550          this.decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
8551          this.decodeRowStringBuffer = '';
8552      }
8553      decodeRow(rowNumber, row, extensionStartRange) {
8554          let result = this.decodeRowStringBuffer;
8555          let end = this.decodeMiddle(row, extensionStartRange, result);
8556          let resultString = result.toString();
8557          let extensionData = UPCEANExtension2Support.parseExtensionString(resultString);
8558          let resultPoints = [
8559              new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0, rowNumber),
8560              new ResultPoint(end, rowNumber)
8561          ];
8562          let extensionResult = new Result$1(resultString, null, 0, resultPoints, BarcodeFormat$1.UPC_EAN_EXTENSION, new Date().getTime());
8563          if (extensionData != null) {
8564              extensionResult.putAllMetadata(extensionData);
8565          }
8566          return extensionResult;
8567      }
8568      decodeMiddle(row, startRange, resultString) {
8569          let counters = this.decodeMiddleCounters;
8570          counters[0] = 0;
8571          counters[1] = 0;
8572          counters[2] = 0;
8573          counters[3] = 0;
8574          let end = row.getSize();
8575          let rowOffset = startRange[1];
8576          let checkParity = 0;
8577          for (let x = 0; x < 2 && rowOffset < end; x++) {
8578              let bestMatch = AbstractUPCEANReader.decodeDigit(row, counters, rowOffset, AbstractUPCEANReader.L_AND_G_PATTERNS);
8579              resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch % 10));
8580              for (let counter of counters) {
8581                  rowOffset += counter;
8582              }
8583              if (bestMatch >= 10) {
8584                  checkParity |= 1 << (1 - x);
8585              }
8586              if (x !== 1) {
8587                  // Read off separator if not last
8588                  rowOffset = row.getNextSet(rowOffset);
8589                  rowOffset = row.getNextUnset(rowOffset);
8590              }
8591          }
8592          if (resultString.length !== 2) {
8593              throw new NotFoundException();
8594          }
8595          if (parseInt(resultString.toString()) % 4 !== checkParity) {
8596              throw new NotFoundException();
8597          }
8598          return rowOffset;
8599      }
8600      static parseExtensionString(raw) {
8601          if (raw.length !== 2) {
8602              return null;
8603          }
8604          return new Map([[ResultMetadataType$1.ISSUE_NUMBER, parseInt(raw)]]);
8605      }
8606  }
8607
8608  /*
8609   * Copyright (C) 2010 ZXing authors
8610   *
8611   * Licensed under the Apache License, Version 2.0 (the "License");
8612   * you may not use this file except in compliance with the License.
8613   * You may obtain a copy of the License at
8614   *
8615   *      http://www.apache.org/licenses/LICENSE-2.0
8616   *
8617   * Unless required by applicable law or agreed to in writing, software
8618   * distributed under the License is distributed on an "AS IS" BASIS,
8619   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8620   * See the License for the specific language governing permissions and
8621   * limitations under the License.
8622   */
8623  class UPCEANExtensionSupport {
8624      static decodeRow(rowNumber, row, rowOffset) {
8625          let extensionStartRange = AbstractUPCEANReader.findGuardPattern(row, rowOffset, false, this.EXTENSION_START_PATTERN, new Int32Array(this.EXTENSION_START_PATTERN.length).fill(0));
8626          try {
8627              // return null;
8628              let fiveSupport = new UPCEANExtension5Support();
8629              return fiveSupport.decodeRow(rowNumber, row, extensionStartRange);
8630          }
8631          catch (err) {
8632              // return null;
8633              let twoSupport = new UPCEANExtension2Support();
8634              return twoSupport.decodeRow(rowNumber, row, extensionStartRange);
8635          }
8636      }
8637  }
8638  UPCEANExtensionSupport.EXTENSION_START_PATTERN = Int32Array.from([1, 1, 2]);
8639
8640  /*
8641   * Copyright 2008 ZXing authors
8642   *
8643   * Licensed under the Apache License, Version 2.0 (the "License");
8644   * you may not use this file except in compliance with the License.
8645   * You may obtain a copy of the License at
8646   *
8647   *      http://www.apache.org/licenses/LICENSE-2.0
8648   *
8649   * Unless required by applicable law or agreed to in writing, software
8650   * distributed under the License is distributed on an "AS IS" BASIS,
8651   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8652   * See the License for the specific language governing permissions and
8653   * limitations under the License.
8654   */
8655  /**
8656   * <p>Encapsulates functionality and implementation that is common to UPC and EAN families
8657   * of one-dimensional barcodes.</p>
8658   *
8659   * @author [email protected] (Daniel Switkin)
8660   * @author Sean Owen
8661   * @author [email protected] (Alasdair Mackintosh)
8662   */
8663  class UPCEANReader extends AbstractUPCEANReader {
8664      constructor() {
8665          super();
8666          this.decodeRowStringBuffer = '';
8667          UPCEANReader.L_AND_G_PATTERNS = UPCEANReader.L_PATTERNS.map(arr => Int32Array.from(arr));
8668          for (let i = 10; i < 20; i++) {
8669              let widths = UPCEANReader.L_PATTERNS[i - 10];
8670              let reversedWidths = new Int32Array(widths.length);
8671              for (let j = 0; j < widths.length; j++) {
8672                  reversedWidths[j] = widths[widths.length - j - 1];
8673              }
8674              UPCEANReader.L_AND_G_PATTERNS[i] = reversedWidths;
8675          }
8676      }
8677      decodeRow(rowNumber, row, hints) {
8678          let startGuardRange = UPCEANReader.findStartGuardPattern(row);
8679          let resultPointCallback = hints == null ? null : hints.get(DecodeHintType$1.NEED_RESULT_POINT_CALLBACK);
8680          if (resultPointCallback != null) {
8681              const resultPoint = new ResultPoint((startGuardRange[0] + startGuardRange[1]) / 2.0, rowNumber);
8682              resultPointCallback.foundPossibleResultPoint(resultPoint);
8683          }
8684          let budello = this.decodeMiddle(row, startGuardRange, this.decodeRowStringBuffer);
8685          let endStart = budello.rowOffset;
8686          let result = budello.resultString;
8687          if (resultPointCallback != null) {
8688              const resultPoint = new ResultPoint(endStart, rowNumber);
8689              resultPointCallback.foundPossibleResultPoint(resultPoint);
8690          }
8691          let endRange = UPCEANReader.decodeEnd(row, endStart);
8692          if (resultPointCallback != null) {
8693              const resultPoint = new ResultPoint((endRange[0] + endRange[1]) / 2.0, rowNumber);
8694              resultPointCallback.foundPossibleResultPoint(resultPoint);
8695          }
8696          // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
8697          // spec might want more whitespace, but in practice this is the maximum we can count on.
8698          let end = endRange[1];
8699          let quietEnd = end + (end - endRange[0]);
8700          if (quietEnd >= row.getSize() || !row.isRange(end, quietEnd, false)) {
8701              throw new NotFoundException();
8702          }
8703          let resultString = result.toString();
8704          // UPC/EAN should never be less than 8 chars anyway
8705          if (resultString.length < 8) {
8706              throw new FormatException();
8707          }
8708          if (!UPCEANReader.checkChecksum(resultString)) {
8709              throw new ChecksumException();
8710          }
8711          let left = (startGuardRange[1] + startGuardRange[0]) / 2.0;
8712          let right = (endRange[1] + endRange[0]) / 2.0;
8713          let format = this.getBarcodeFormat();
8714          let resultPoint = [new ResultPoint(left, rowNumber), new ResultPoint(right, rowNumber)];
8715          let decodeResult = new Result$1(resultString, null, 0, resultPoint, format, new Date().getTime());
8716          let extensionLength = 0;
8717          try {
8718              let extensionResult = UPCEANExtensionSupport.decodeRow(rowNumber, row, endRange[1]);
8719              decodeResult.putMetadata(ResultMetadataType$1.UPC_EAN_EXTENSION, extensionResult.getText());
8720              decodeResult.putAllMetadata(extensionResult.getResultMetadata());
8721              decodeResult.addResultPoints(extensionResult.getResultPoints());
8722              extensionLength = extensionResult.getText().length;
8723          }
8724          catch (err) {
8725          }
8726          let allowedExtensions = hints == null ? null : hints.get(DecodeHintType$1.ALLOWED_EAN_EXTENSIONS);
8727          if (allowedExtensions != null) {
8728              let valid = false;
8729              for (let length in allowedExtensions) {
8730                  if (extensionLength.toString() === length) { // check me
8731                      valid = true;
8732                      break;
8733                  }
8734              }
8735              if (!valid) {
8736                  throw new NotFoundException();
8737              }
8738          }
8739          if (format === BarcodeFormat$1.EAN_13 || format === BarcodeFormat$1.UPC_A) ;
8740          return decodeResult;
8741      }
8742      static checkChecksum(s) {
8743          return UPCEANReader.checkStandardUPCEANChecksum(s);
8744      }
8745      static checkStandardUPCEANChecksum(s) {
8746          let length = s.length;
8747          if (length === 0)
8748              return false;
8749          let check = parseInt(s.charAt(length - 1), 10);
8750          return UPCEANReader.getStandardUPCEANChecksum(s.substring(0, length - 1)) === check;
8751      }
8752      static getStandardUPCEANChecksum(s) {
8753          let length = s.length;
8754          let sum = 0;
8755          for (let i = length - 1; i >= 0; i -= 2) {
8756              let digit = s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
8757              if (digit < 0 || digit > 9) {
8758                  throw new FormatException();
8759              }
8760              sum += digit;
8761          }
8762          sum *= 3;
8763          for (let i = length - 2; i >= 0; i -= 2) {
8764              let digit = s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
8765              if (digit < 0 || digit > 9) {
8766                  throw new FormatException();
8767              }
8768              sum += digit;
8769          }
8770          return (1000 - sum) % 10;
8771      }
8772      static decodeEnd(row, endStart) {
8773          return UPCEANReader.findGuardPattern(row, endStart, false, UPCEANReader.START_END_PATTERN, new Int32Array(UPCEANReader.START_END_PATTERN.length).fill(0));
8774      }
8775  }
8776
8777  /*
8778   * Copyright 2008 ZXing authors
8779   *
8780   * Licensed under the Apache License, Version 2.0 (the "License");
8781   * you may not use this file except in compliance with the License.
8782   * You may obtain a copy of the License at
8783   *
8784   *      http://www.apache.org/licenses/LICENSE-2.0
8785   *
8786   * Unless required by applicable law or agreed to in writing, software
8787   * distributed under the License is distributed on an "AS IS" BASIS,
8788   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8789   * See the License for the specific language governing permissions and
8790   * limitations under the License.
8791   */
8792  /**
8793   * <p>Implements decoding of the EAN-13 format.</p>
8794   *
8795   * @author [email protected] (Daniel Switkin)
8796   * @author Sean Owen
8797   * @author [email protected] (Alasdair Mackintosh)
8798   */
8799  class EAN13Reader extends UPCEANReader {
8800      constructor() {
8801          super();
8802          this.decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
8803      }
8804      decodeMiddle(row, startRange, resultString) {
8805          let counters = this.decodeMiddleCounters;
8806          counters[0] = 0;
8807          counters[1] = 0;
8808          counters[2] = 0;
8809          counters[3] = 0;
8810          let end = row.getSize();
8811          let rowOffset = startRange[1];
8812          let lgPatternFound = 0;
8813          for (let x = 0; x < 6 && rowOffset < end; x++) {
8814              let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_AND_G_PATTERNS);
8815              resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch % 10));
8816              for (let counter of counters) {
8817                  rowOffset += counter;
8818              }
8819              if (bestMatch >= 10) {
8820                  lgPatternFound |= 1 << (5 - x);
8821              }
8822          }
8823          resultString = EAN13Reader.determineFirstDigit(resultString, lgPatternFound);
8824          let middleRange = UPCEANReader.findGuardPattern(row, rowOffset, true, UPCEANReader.MIDDLE_PATTERN, new Int32Array(UPCEANReader.MIDDLE_PATTERN.length).fill(0));
8825          rowOffset = middleRange[1];
8826          for (let x = 0; x < 6 && rowOffset < end; x++) {
8827              let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
8828              resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch));
8829              for (let counter of counters) {
8830                  rowOffset += counter;
8831              }
8832          }
8833          return { rowOffset, resultString };
8834      }
8835      getBarcodeFormat() {
8836          return BarcodeFormat$1.EAN_13;
8837      }
8838      static determineFirstDigit(resultString, lgPatternFound) {
8839          for (let d = 0; d < 10; d++) {
8840              if (lgPatternFound === this.FIRST_DIGIT_ENCODINGS[d]) {
8841                  resultString = String.fromCharCode(('0'.charCodeAt(0) + d)) + resultString;
8842                  return resultString;
8843              }
8844          }
8845          throw new NotFoundException();
8846      }
8847  }
8848  EAN13Reader.FIRST_DIGIT_ENCODINGS = [0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A];
8849
8850  /*
8851   * Copyright 2008 ZXing authors
8852   *
8853   * Licensed under the Apache License, Version 2.0 (the "License");
8854   * you may not use this file except in compliance with the License.
8855   * You may obtain a copy of the License at
8856   *
8857   *      http://www.apache.org/licenses/LICENSE-2.0
8858   *
8859   * Unless required by applicable law or agreed to in writing, software
8860   * distributed under the License is distributed on an "AS IS" BASIS,
8861   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8862   * See the License for the specific language governing permissions and
8863   * limitations under the License.
8864   */
8865  /**
8866   * <p>Implements decoding of the EAN-8 format.</p>
8867   *
8868   * @author Sean Owen
8869   */
8870  class EAN8Reader extends UPCEANReader {
8871      constructor() {
8872          super();
8873          this.decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
8874      }
8875      decodeMiddle(row, startRange, resultString) {
8876          const counters = this.decodeMiddleCounters;
8877          counters[0] = 0;
8878          counters[1] = 0;
8879          counters[2] = 0;
8880          counters[3] = 0;
8881          let end = row.getSize();
8882          let rowOffset = startRange[1];
8883          for (let x = 0; x < 4 && rowOffset < end; x++) {
8884              let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
8885              resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch));
8886              for (let counter of counters) {
8887                  rowOffset += counter;
8888              }
8889          }
8890          let middleRange = UPCEANReader.findGuardPattern(row, rowOffset, true, UPCEANReader.MIDDLE_PATTERN, new Int32Array(UPCEANReader.MIDDLE_PATTERN.length).fill(0));
8891          rowOffset = middleRange[1];
8892          for (let x = 0; x < 4 && rowOffset < end; x++) {
8893              let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
8894              resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch));
8895              for (let counter of counters) {
8896                  rowOffset += counter;
8897              }
8898          }
8899          return { rowOffset, resultString };
8900      }
8901      getBarcodeFormat() {
8902          return BarcodeFormat$1.EAN_8;
8903      }
8904  }
8905
8906  /*
8907   * Copyright 2008 ZXing authors
8908   *
8909   * Licensed under the Apache License, Version 2.0 (the "License");
8910   * you may not use this file except in compliance with the License.
8911   * You may obtain a copy of the License at
8912   *
8913   *      http://www.apache.org/licenses/LICENSE-2.0
8914   *
8915   * Unless required by applicable law or agreed to in writing, software
8916   * distributed under the License is distributed on an "AS IS" BASIS,
8917   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8918   * See the License for the specific language governing permissions and
8919   * limitations under the License.
8920   */
8921  /*
8921*
8922   * Encapsulates functionality and implementation that is common to all families
8923   * of one-dimensional barcodes.
8924   *
8925   * @author [email protected] (Daniel Switkin)
8926   * @author Sean Owen
8927   * @author sam2332 (Sam Rudloff)
8928   *
8929   * @source https://github.com/zxing/zxing/blob/3c96923276dd5785d58eb970b6ba3f80d36a9505/core/src/main/java/com/google/zxing/oned/UPCAReader.java
8930   *
8931   * @experimental
8932   */
8933  class UPCAReader extends UPCEANReader {
8934      constructor() {
8935          super(...arguments);
8936          this.ean13Reader = new EAN13Reader();
8937      }
8938      // @Override
8939      getBarcodeFormat() {
8940          return BarcodeFormat$1.UPC_A;
8941      }
8942      // Note that we don't try rotation without the try harder flag, even if rotation was supported.
8943      // @Override
8944      decode(image, hints) {
8945          return this.maybeReturnResult(this.ean13Reader.decode(image));
8946      }
8947      // @Override
8948      decodeRow(rowNumber, row, hints) {
8949          return this.maybeReturnResult(this.ean13Reader.decodeRow(rowNumber, row, hints));
8950      }
8951      // @Override
8952      decodeMiddle(row, startRange, resultString) {
8953          return this.ean13Reader.decodeMiddle(row, startRange, resultString);
8954      }
8955      maybeReturnResult(result) {
8956          let text = result.getText();
8957          if (text.charAt(0) === '0') {
8958              let upcaResult = new Result$1(text.substring(1), null, null, result.getResultPoints(), BarcodeFormat$1.UPC_A);
8959              if (result.getResultMetadata() != null) {
8960                  upcaResult.putAllMetadata(result.getResultMetadata());
8961              }
8962              return upcaResult;
8963          }
8964          else {
8965              throw new NotFoundException();
8966          }
8967      }
8968      reset() {
8969          this.ean13Reader.reset();
8970      }
8971  }
8972
8973  /*
8974   * Copyright 2008 ZXing authors
8975   *
8976   * Licensed under the Apache License, Version 2.0 (the "License");
8977   * you may not use this file except in compliance with the License.
8978   * You may obtain a copy of the License at
8979   *
8980   *      http://www.apache.org/licenses/LICENSE-2.0
8981   *
8982   * Unless required by applicable law or agreed to in writing, software
8983   * distributed under the License is distributed on an "AS IS" BASIS,
8984   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8985   * See the License for the specific language governing permissions and
8986   * limitations under the License.
8987   */
8988  // package com.google.zxing.oned;
8989  // import com.google.zxing.BarcodeFormat;
8990  // import com.google.zxing.FormatException;
8991  // import com.google.zxing.NotFoundException;
8992  // import com.google.zxing.common.BitArray;
8993  /**
8994   * <p>Implements decoding of the UPC-E format.</p>
8995   * <p><a href="http://www.barcodeisland.com/upce.phtml">This</a> is a great reference for
8996   * UPC-E information.</p>
8997   *
8998   * @author Sean Owen
8999   *
9000   * @source https://github.com/zxing/zxing/blob/3c96923276dd5785d58eb970b6ba3f80d36a9505/core/src/main/java/com/google/zxing/oned/UPCEReader.java
9001   *
9002   * @experimental
9003   */
9004  /* final */
vendor: 10,636 bytes, lines 9004-9258
9004 class UPCEReader extends UPCEANReader {
9005      constructor() {
9006          super();
9007          this.decodeMiddleCounters = new Int32Array(4);
9008      }
9009      /**
9010       * @throws NotFoundException
9011       */
9012      // @Override
9013      decodeMiddle(row, startRange, result) {
9014          const counters = this.decodeMiddleCounters.map(x => x);
9015          counters[0] = 0;
9016          counters[1] = 0;
9017          counters[2] = 0;
9018          counters[3] = 0;
9019          const end = row.getSize();
9020          let rowOffset = startRange[1];
9021          let lgPatternFound = 0;
9022          for (let x = 0; x < 6 && rowOffset < end; x++) {
9023              const bestMatch = UPCEReader.decodeDigit(row, counters, rowOffset, UPCEReader.L_AND_G_PATTERNS);
9024              result += String.fromCharCode(('0'.charCodeAt(0) + bestMatch % 10));
9025              for (let counter of counters) {
9026                  rowOffset += counter;
9027              }
9028              if (bestMatch >= 10) {
9029                  lgPatternFound |= 1 << (5 - x);
9030              }
9031          }
9032          UPCEReader.determineNumSysAndCheckDigit(new StringBuilder(result), lgPatternFound);
9033          return rowOffset;
9034      }
9035      /**
9036       * @throws NotFoundException
9037       */
9038      // @Override
9039      decodeEnd(row, endStart) {
9040          return UPCEReader.findGuardPatternWithoutCounters(row, endStart, true, UPCEReader.MIDDLE_END_PATTERN);
9041      }
9042      /**
9043       * @throws FormatException
9044       */
9045      // @Override
9046      checkChecksum(s) {
9047          return UPCEANReader.checkChecksum(UPCEReader.convertUPCEtoUPCA(s));
9048      }
9049      /**
9050       * @throws NotFoundException
9051       */
9052      static determineNumSysAndCheckDigit(resultString, lgPatternFound) {
9053          for (let numSys = 0; numSys <= 1; numSys++) {
9054              for (let d = 0; d < 10; d++) {
9055                  if (lgPatternFound === this.NUMSYS_AND_CHECK_DIGIT_PATTERNS[numSys][d]) {
9056                      resultString.insert(0, /*(char)*/ ('0' + numSys));
9057                      resultString.append(/*(char)*/ ('0' + d));
9058                      return;
9059                  }
9060              }
9061          }
9062          throw NotFoundException.getNotFoundInstance();
9063      }
9064      // @Override
9065      getBarcodeFormat() {
9066          return BarcodeFormat$1.UPC_E;
9067      }
9068      /**
9069       * Expands a UPC-E value back into its full, equivalent UPC-A code value.
9070       *
9071       * @param upce UPC-E code as string of digits
9072       * @return equivalent UPC-A code as string of digits
9073       */
9074      static convertUPCEtoUPCA(upce) {
9075          // the following line is equivalent to upce.getChars(1, 7, upceChars, 0);
9076          const upceChars = upce.slice(1, 7).split('').map(x => x.charCodeAt(0));
9077          const result = new StringBuilder( /*12*/);
9078          result.append(upce.charAt(0));
9079          let lastChar = upceChars[5];
9080          switch (lastChar) {
9081              case 0:
9082              case 1:
9083              case 2:
9084                  result.appendChars(upceChars, 0, 2);
9085                  result.append(lastChar);
9086                  result.append('0000');
9087                  result.appendChars(upceChars, 2, 3);
9088                  break;
9089              case 3:
9090                  result.appendChars(upceChars, 0, 3);
9091                  result.append('00000');
9092                  result.appendChars(upceChars, 3, 2);
9093                  break;
9094              case 4:
9095                  result.appendChars(upceChars, 0, 4);
9096                  result.append('00000');
9097                  result.append(upceChars[4]);
9098                  break;
9099              default:
9100                  result.appendChars(upceChars, 0, 5);
9101                  result.append('0000');
9102                  result.append(lastChar);
9103                  break;
9104          }
9105          // Only append check digit in conversion if supplied
9106          if (upce.length >= 8) {
9107              result.append(upce.charAt(7));
9108          }
9109          return result.toString();
9110      }
9111  }
9112  /**
9113   * The pattern that marks the middle, and end, of a UPC-E pattern.
9114   * There is no "second half" to a UPC-E barcode.
9115   */
9116  UPCEReader.MIDDLE_END_PATTERN = Int32Array.from([1, 1, 1, 1, 1, 1]);
9117  // For an UPC-E barcode, the final digit is represented by the parities used
9118  // to encode the middle six digits, according to the table below.
9119  //
9120  //                Parity of next 6 digits
9121  //    Digit   0     1     2     3     4     5
9122  //       0    Even   Even  Even Odd  Odd   Odd
9123  //       1    Even   Even  Odd  Even Odd   Odd
9124  //       2    Even   Even  Odd  Odd  Even  Odd
9125  //       3    Even   Even  Odd  Odd  Odd   Even
9126  //       4    Even   Odd   Even Even Odd   Odd
9127  //       5    Even   Odd   Odd  Even Even  Odd
9128  //       6    Even   Odd   Odd  Odd  Even  Even
9129  //       7    Even   Odd   Even Odd  Even  Odd
9130  //       8    Even   Odd   Even Odd  Odd   Even
9131  //       9    Even   Odd   Odd  Even Odd   Even
9132  //
9133  // The encoding is represented by the following array, which is a bit pattern
9134  // using Odd = 0 and Even = 1. For example, 5 is represented by:
9135  //
9136  //              Odd Even Even Odd Odd Even
9137  // in binary:
9138  //                0    1    1   0   0    1   == 0x19
9139  //
9140  /**
9141   * See {@link #L_AND_G_PATTERNS}; these values similarly represent patterns of
9142   * even-odd parity encodings of digits that imply both the number system (0 or 1)
9143   * used, and the check digit.
9144   */
9145  UPCEReader.NUMSYS_AND_CHECK_DIGIT_PATTERNS = [
9146      Int32Array.from([0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25]),
9147      Int32Array.from([0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1]),
9148  ];
9149
9150  /*
9151   * Copyright 2008 ZXing authors
9152   *
9153   * Licensed under the Apache License, Version 2.0 (the "License");
9154   * you may not use this file except in compliance with the License.
9155   * You may obtain a copy of the License at
9156   *
9157   *      http://www.apache.org/licenses/LICENSE-2.0
9158   *
9159   * Unless required by applicable law or agreed to in writing, software
9160   * distributed under the License is distributed on an "AS IS" BASIS,
9161   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9162   * See the License for the specific language governing permissions and
9163   * limitations under the License.
9164   */
9165  /**
9166   * <p>A reader that can read all available UPC/EAN formats. If a caller wants to try to
9167   * read all such formats, it is most efficient to use this implementation rather than invoke
9168   * individual readers.</p>
9169   *
9170   * @author Sean Owen
9171   */
9172  class MultiFormatUPCEANReader extends OneDReader {
9173      constructor(hints) {
9174          super();
9175          let possibleFormats = hints == null ? null : hints.get(DecodeHintType$1.POSSIBLE_FORMATS);
9176          let readers = [];
9177          if (possibleFormats != null) {
9178              if (possibleFormats.indexOf(BarcodeFormat$1.EAN_13) > -1) {
9179                  readers.push(new EAN13Reader());
9180              }
9181              if (possibleFormats.indexOf(BarcodeFormat$1.UPC_A) > -1) {
9182                  readers.push(new UPCAReader());
9183              }
9184              if (possibleFormats.indexOf(BarcodeFormat$1.EAN_8) > -1) {
9185                  readers.push(new EAN8Reader());
9186              }
9187              if (possibleFormats.indexOf(BarcodeFormat$1.UPC_E) > -1) {
9188                  readers.push(new UPCEReader());
9189              }
9190          }
9191          if (readers.length === 0) {
9192              readers.push(new EAN13Reader());
9193              readers.push(new UPCAReader());
9194              readers.push(new EAN8Reader());
9195              readers.push(new UPCEReader());
9196          }
9197          this.readers = readers;
9198      }
9199      decodeRow(rowNumber, row, hints) {
9200          for (let reader of this.readers) {
9201              try {
9202                  // const result: Result = reader.decodeRow(rowNumber, row, startGuardPattern, hints);
9203                  const result = reader.decodeRow(rowNumber, row, hints);
9204                  // Special case: a 12-digit code encoded in UPC-A is identical to a "0"
9205                  // followed by those 12 digits encoded as EAN-13. Each will recognize such a code,
9206                  // UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with "0".
9207                  // Individually these are correct and their readers will both read such a code
9208                  // and correctly call it EAN-13, or UPC-A, respectively.
9209                  //
9210                  // In this case, if we've been looking for both types, we'd like to call it
9211                  // a UPC-A code. But for efficiency we only run the EAN-13 decoder to also read
9212                  // UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A
9213                  // result if appropriate.
9214                  //
9215                  // But, don't return UPC-A if UPC-A was not a requested format!
9216                  const ean13MayBeUPCA = result.getBarcodeFormat() === BarcodeFormat$1.EAN_13 &&
9217                      result.getText().charAt(0) === '0';
9218                  // @SuppressWarnings("unchecked")
9219                  const possibleFormats = hints == null ? null : hints.get(DecodeHintType$1.POSSIBLE_FORMATS);
9220                  const canReturnUPCA = possibleFormats == null || possibleFormats.includes(BarcodeFormat$1.UPC_A);
9221                  if (ean13MayBeUPCA && canReturnUPCA) {
9222                      const rawBytes = result.getRawBytes();
9223                      // Transfer the metadata across
9224                      const resultUPCA = new Result$1(result.getText().substring(1), rawBytes, (rawBytes ? rawBytes.length : null), result.getResultPoints(), BarcodeFormat$1.UPC_A);
9225                      resultUPCA.putAllMetadata(result.getResultMetadata());
9226                      return resultUPCA;
9227                  }
9228                  return result;
9229              }
9230              catch (err) {
9231                  // continue;
9232              }
9233          }
9234          throw new NotFoundException();
9235      }
9236      reset() {
9237          for (let reader of this.readers) {
9238              reader.reset();
9239          }
9240      }
9241  }
9242
9243  /*
9244   * Copyright 2008 ZXing authors
9245   *
9246   * Licensed under the Apache License, Version 2.0 (the "License");
9247   * you may not use this file except in compliance with the License.
9248   * You may obtain a copy of the License at
9249   *
9250   *      http://www.apache.org/licenses/LICENSE-2.0
9251   *
9252   * Unless required by applicable law or agreed to in writing, software
9253   * distributed under the License is distributed on an "AS IS" BASIS,
9254   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9255   * See the License for the specific language governing permissions and
9256   * limitations under the License.
9257   */
9258  /*
vendor: 9,412 bytes, lines 9258-9533
9258*
9259   * <p>Decodes CodaBar barcodes. </p>
9260   *
9261   * @author Evan @dodobelieve
9262   * @see CodaBarReader
9263   */
9264  class CodaBarReader extends OneDReader {
9265      constructor() {
9266          super(...arguments);
9267          this.CODA_BAR_CHAR_SET = {
9268              nnnnnww: '0',
9269              nnnnwwn: '1',
9270              nnnwnnw: '2',
9271              wwnnnnn: '3',
9272              nnwnnwn: '4',
9273              wnnnnwn: '5',
9274              nwnnnnw: '6',
9275              nwnnwnn: '7',
9276              nwwnnnn: '8',
9277              wnnwnnn: '9',
9278              nnnwwnn: '-',
9279              nnwwnnn: '$',
9280              wnnnwnw: ':',
9281              wnwnnnw: '/',
9282              wnwnwnn: '.',
9283              nnwwwww: '+',
9284              nnwwnwn: 'A',
9285              nwnwnnw: 'B',
9286              nnnwnww: 'C',
9287              nnnwwwn: 'D'
9288          };
9289      }
9290      decodeRow(rowNumber, row, hints) {
9291          let validRowData = this.getValidRowData(row);
9292          if (!validRowData)
9293              throw new NotFoundException();
9294          let retStr = this.codaBarDecodeRow(validRowData.row);
9295          if (!retStr)
9296              throw new NotFoundException();
9297          return new Result$1(retStr, null, 0, [new ResultPoint(validRowData.left, rowNumber), new ResultPoint(validRowData.right, rowNumber)], BarcodeFormat$1.CODABAR, new Date().getTime());
9298      }
9299      /**
9300       * converts bit array to valid data array(lengths of black bits and white bits)
9301       * @param row bit array to convert
9302       */
9303      getValidRowData(row) {
9304          let booleanArr = row.toArray();
9305          let startIndex = booleanArr.indexOf(true);
9306          if (startIndex === -1)
9307              return null;
9308          let lastIndex = booleanArr.lastIndexOf(true);
9309          if (lastIndex <= startIndex)
9310              return null;
9311          booleanArr = booleanArr.slice(startIndex, lastIndex + 1);
9312          let result = [];
9313          let lastBit = booleanArr[0];
9314          let bitLength = 1;
9315          for (let i = 1; i < booleanArr.length; i++) {
9316              if (booleanArr[i] === lastBit) {
9317                  bitLength++;
9318              }
9319              else {
9320                  lastBit = booleanArr[i];
9321                  result.push(bitLength);
9322                  bitLength = 1;
9323              }
9324          }
9325          result.push(bitLength);
9326          // CodaBar code data valid
9327          if (result.length < 23 && (result.length + 1) % 8 !== 0)
9328              return null;
9329          return { row: result, left: startIndex, right: lastIndex };
9330      }
9331      /**
9332       * decode codabar code
9333       * @param row row to cecode
9334       */
9335      codaBarDecodeRow(row) {
9336          const code = [];
9337          const barThreshold = Math.ceil(row.reduce((pre, item) => (pre + item) / 2, 0));
9338          // Read one encoded character at a time.
9339          while (row.length > 0) {
9340              const seg = row.splice(0, 8).splice(0, 7);
9341              const key = seg.map(len => (len < barThreshold ? 'n' : 'w')).join('');
9342              if (this.CODA_BAR_CHAR_SET[key] === undefined)
9343                  return null;
9344              code.push(this.CODA_BAR_CHAR_SET[key]);
9345          }
9346          let strCode = code.join('');
9347          if (this.validCodaBarString(strCode))
9348              return strCode;
9349          return null;
9350      }
9351      /**
9352       * check if the string is a CodaBar string
9353       * @param src string to determine
9354       */
9355      validCodaBarString(src) {
9356          let reg = /^[A-D].{1,}[A-D]$/;
9357          return reg.test(src);
9358      }
9359  }
9360
9361  // import Integer from '../../util/Integer';
9362  // import Float from '../../util/Float';
9363  class AbstractRSSReader extends OneDReader {
9364      constructor() {
9365          super();
9366          this.decodeFinderCounters = new Int32Array(4);
9367          this.dataCharacterCounters = new Int32Array(8);
9368          this.oddRoundingErrors = new Array(4);
9369          this.evenRoundingErrors = new Array(4);
9370          this.oddCounts = new Array(this.dataCharacterCounters.length / 2);
9371          this.evenCounts = new Array(this.dataCharacterCounters.length / 2);
9372      }
9373      getDecodeFinderCounters() {
9374          return this.decodeFinderCounters;
9375      }
9376      getDataCharacterCounters() {
9377          return this.dataCharacterCounters;
9378      }
9379      getOddRoundingErrors() {
9380          return this.oddRoundingErrors;
9381      }
9382      getEvenRoundingErrors() {
9383          return this.evenRoundingErrors;
9384      }
9385      getOddCounts() {
9386          return this.oddCounts;
9387      }
9388      getEvenCounts() {
9389          return this.evenCounts;
9390      }
9391      parseFinderValue(counters, finderPatterns) {
9392          for (let value = 0; value < finderPatterns.length; value++) {
9393              if (OneDReader.patternMatchVariance(counters, finderPatterns[value], AbstractRSSReader.MAX_INDIVIDUAL_VARIANCE) < AbstractRSSReader.MAX_AVG_VARIANCE) {
9394                  return value;
9395              }
9396          }
9397          throw new NotFoundException();
9398      }
9399      /**
9400       * @param array values to sum
9401       * @return sum of values
9402       * @deprecated call {@link MathUtils#sum(int[])}
9403       */
9404      static count(array) {
9405          return MathUtils.sum(new Int32Array(array));
9406      }
9407      static increment(array, errors) {
9408          let index = 0;
9409          let biggestError = errors[0];
9410          for (let i = 1; i < array.length; i++) {
9411              if (errors[i] > biggestError) {
9412                  biggestError = errors[i];
9413                  index = i;
9414              }
9415          }
9416          array[index]++;
9417      }
9418      static decrement(array, errors) {
9419          let index = 0;
9420          let biggestError = errors[0];
9421          for (let i = 1; i < array.length; i++) {
9422              if (errors[i] < biggestError) {
9423                  biggestError = errors[i];
9424                  index = i;
9425              }
9426          }
9427          array[index]--;
9428      }
9429      static isFinderPattern(counters) {
9430          let firstTwoSum = counters[0] + counters[1];
9431          let sum = firstTwoSum + counters[2] + counters[3];
9432          let ratio = firstTwoSum / sum;
9433          if (ratio >= AbstractRSSReader.MIN_FINDER_PATTERN_RATIO && ratio <= AbstractRSSReader.MAX_FINDER_PATTERN_RATIO) {
9434              // passes ratio test in spec, but see if the counts are unreasonable
9435              let minCounter = Number.MAX_SAFE_INTEGER;
9436              let maxCounter = Number.MIN_SAFE_INTEGER;
9437              for (let counter of counters) {
9438                  if (counter > maxCounter) {
9439                      maxCounter = counter;
9440                  }
9441                  if (counter < minCounter) {
9442                      minCounter = counter;
9443                  }
9444              }
9445              return maxCounter < 10 * minCounter;
9446          }
9447          return false;
9448      }
9449  }
9450  AbstractRSSReader.MAX_AVG_VARIANCE = 0.2;
9451  AbstractRSSReader.MAX_INDIVIDUAL_VARIANCE = 0.45;
9452  AbstractRSSReader.MIN_FINDER_PATTERN_RATIO = 9.5 / 12.0;
9453  AbstractRSSReader.MAX_FINDER_PATTERN_RATIO = 12.5 / 14.0;
9454
9455  class DataCharacter {
9456      constructor(value, checksumPortion) {
9457          this.value = value;
9458          this.checksumPortion = checksumPortion;
9459      }
9460      getValue() {
9461          return this.value;
9462      }
9463      getChecksumPortion() {
9464          return this.checksumPortion;
9465      }
9466      toString() {
9467          return this.value + '(' + this.checksumPortion + ')';
9468      }
9469      equals(o) {
9470          if (!(o instanceof DataCharacter)) {
9471              return false;
9472          }
9473          const that = o;
9474          return this.value === that.value && this.checksumPortion === that.checksumPortion;
9475      }
9476      hashCode() {
9477          return this.value ^ this.checksumPortion;
9478      }
9479  }
9480
9481  class FinderPattern$1 {
9482      constructor(value, startEnd, start, end, rowNumber) {
9483          this.value = value;
9484          this.startEnd = startEnd;
9485          this.value = value;
9486          this.startEnd = startEnd;
9487          this.resultPoints = new Array();
9488          this.resultPoints.push(new ResultPoint(start, rowNumber));
9489          this.resultPoints.push(new ResultPoint(end, rowNumber));
9490      }
9491      getValue() {
9492          return this.value;
9493      }
9494      getStartEnd() {
9495          return this.startEnd;
9496      }
9497      getResultPoints() {
9498          return this.resultPoints;
9499      }
9500      equals(o) {
9501          if (!(o instanceof FinderPattern$1)) {
9502              return false;
9503          }
9504          const that = o;
9505          return this.value === that.value;
9506      }
9507      hashCode() {
9508          return this.value;
9509      }
9510  }
9511
9512  /**
9513   * RSS util functions.
9514   */
9515  class RSSUtils {
9516      constructor() { }
9517      static getRSSvalue(widths, maxWidth, noNarrow) {
9518          let n = 0;
9519          for (let width of widths) {
9520              n += width;
9521          }
9522          let val = 0;
9523          let narrowMask = 0;
9524          let elements = widths.length;
9525          for (let bar = 0; bar < elements - 1; bar++) {
9526              let elmWidth;
9527              for (elmWidth = 1, narrowMask |= 1 << bar; elmWidth < widths[bar]; elmWidth++, narrowMask &= ~(1 << bar)) {
9528                  let subVal = RSSUtils.combins(n - elmWidth - 1, elements - bar - 2);
9529                  if (noNarrow && (narrowMask === 0) && (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
9530                      subVal -= RSSUtils.combins(n - elmWidth - (elements - bar), elements - bar - 2);
9531                  }
9532                  if (elements - bar - 1 > 1) {
9533                      let lessVal = 0;
9534                      for (let mxwElement = n - elmWidth - (elements - bar - 2); mxwElement > maxWidth; mxwElement--) {
9535                          lessVal += RSSUtils.combins(n - elmWidth - mxwElement - 1, elements - bar - 3);
9536                      }
9537                      subVal -= lessVal * (elements - 1 - bar);
9538                  }
9539                  else if (n - elmWidth > maxWidth) {
9540                      subVal--;
9541                  }
9542                  val += subVal;
9543              }
9544              n -= elmWidth;
9545          }
9546          return val;
9547      }
9548      static combins(n, r) {
9549          let maxDenom;
9550          let minDenom;
9551          if (n - r > r) {
9552              minDenom = r;
9553              maxDenom = n - r;
9554          }
9555          else {
9556              minDenom = n - r;
9557              maxDenom = r;
9558          }
9559          let val = 1;
9560          let j = 1;
9561          for (let i = n; i > maxDenom; i--) {
9562              val *= i;
9563              if (j <= minDenom) {
9564                  val /= j;
9565                  j++;
9566              }
9567          }
9568          while ((j <= minDenom)) {
9569              val /= j;
9570              j++;
9571          }
9572          return val;
9573      }
9574  }
9575
9576  class BitArrayBuilder {
9577      static buildBitArray(pairs) {
9578          let charNumber = pairs.length * 2 - 1;
9579          if (pairs[pairs.length - 1].getRightChar() == null) {
9580              charNumber -= 1;
9581          }
9582          let size = 12 * charNumber;
9583          let binary = new BitArray(size);
9584          let accPos = 0;
9585          let firstPair = pairs[0];
9586          let firstValue = firstPair.getRightChar().getValue();
9587          for (let i = 11; i >= 0; --i) {
9588              if ((firstValue & (1 << i)) !== 0) {
9589                  binary.set(accPos);
9590              }
9591              accPos++;
9592          }
9593          for (let i = 1; i < pairs.length; ++i) {
9594              let currentPair = pairs[i];
9595              let leftValue = currentPair.getLeftChar().getValue();
9596              for (let j = 11; j >= 0; --j) {
9597                  if ((leftValue & (1 << j)) !== 0) {
9598                      binary.set(accPos);
9599                  }
9600                  accPos++;
9601              }
9602              if (currentPair.getRightChar() !== null) {
9603                  let rightValue = currentPair.getRightChar().getValue();
9604                  for (let j = 11; j >= 0; --j) {
9605                      if ((rightValue & (1 << j)) !== 0) {
9606                          binary.set(accPos);
9607                      }
9608                      accPos++;
9609                  }
9610              }
9611          }
9612          return binary;
9613      }
9614  }
9615
9616  class BlockParsedResult {
9617      constructor(finished, decodedInformation) {
9618          if (decodedInformation) {
9619              this.decodedInformation = null;
9620          }
9621          else {
9622              this.finished = finished;
9623              this.decodedInformation = decodedInformation;
9624          }
9625      }
9626      getDecodedInformation() {
9627          return this.decodedInformation;
9628      }
9629      isFinished() {
9630          return this.finished;
9631      }
9632  }
9633
9634  class DecodedObject {
9635      constructor(newPosition) {
9636          this.newPosition = newPosition;
9637      }
9638      getNewPosition() {
9639          return this.newPosition;
9640      }
9641  }
9642
9643  class DecodedChar extends DecodedObject {
9644      constructor(newPosition, value) {
9645          super(newPosition);
9646          this.value = value;
9647      }
9648      getValue() {
9649          return this.value;
9650      }
9651      isFNC1() {
9652          return this.value === DecodedChar.FNC1;
9653      }
9654  }
9655  DecodedChar.FNC1 = '$';
9656
9657  class DecodedInformation extends DecodedObject {
9658      constructor(newPosition, newString, remainingValue) {
9659          super(newPosition);
9660          if (remainingValue) {
9661              this.remaining = true;
9662              this.remainingValue = this.remainingValue;
9663          }
9664          else {
9665              this.remaining = false;
9666              this.remainingValue = 0;
9667          }
9668          this.newString = newString;
9669      }
9670      getNewString() {
9671          return this.newString;
9672      }
9673      isRemaining() {
9674          return this.remaining;
9675      }
9676      getRemainingValue() {
9677          return this.remainingValue;
9678      }
9679  }
9680
9681  class DecodedNumeric extends DecodedObject {
9682      constructor(newPosition, firstDigit, secondDigit) {
9683          super(newPosition);
9684          if (firstDigit < 0 || firstDigit > 10 || secondDigit < 0 || secondDigit > 10) {
9685              throw new FormatException();
9686          }
9687          this.firstDigit = firstDigit;
9688          this.secondDigit = secondDigit;
9689      }
9690      getFirstDigit() {
9691          return this.firstDigit;
9692      }
9693      getSecondDigit() {
9694          return this.secondDigit;
9695      }
9696      getValue() {
9697          return this.firstDigit * 10 + this.secondDigit;
9698      }
9699      isFirstDigitFNC1() {
9700          return this.firstDigit === DecodedNumeric.FNC1;
9701      }
9702      isSecondDigitFNC1() {
9703          return this.secondDigit === DecodedNumeric.FNC1;
9704      }
9705      isAnyFNC1() {
9706          return this.firstDigit === DecodedNumeric.FNC1 || this.secondDigit === DecodedNumeric.FNC1;
9707      }
9708  }
9709  DecodedNumeric.FNC1 = 10;
9710
9711  class FieldParser {
9712      constructor() {
9713      }
9714      static parseFieldsInGeneralPurpose(rawInformation) {
9715          if (!rawInformation) {
9716              return null;
9717          }
9718          // Processing 2-digit AIs
9719          if (rawInformation.length < 2) {
9720              throw new NotFoundException();
9721          }
9722          let firstTwoDigits = rawInformation.substring(0, 2);
9723          for (let dataLength of FieldParser.TWO_DIGIT_DATA_LENGTH) {
9724              if (dataLength[0] === firstTwoDigits) {
9725                  if (dataLength[1] === FieldParser.VARIABLE_LENGTH) {
9726                      return FieldParser.processVariableAI(2, dataLength[2], rawInformation);
9727                  }
9728                  return FieldParser.processFixedAI(2, dataLength[1], rawInformation);
9729              }
9730          }
9731          if (rawInformation.length < 3) {
9732              throw new NotFoundException();
9733          }
9734          let firstThreeDigits = rawInformation.substring(0, 3);
9735          for (let dataLength of FieldParser.THREE_DIGIT_DATA_LENGTH) {
9736              if (dataLength[0] === firstThreeDigits) {
9737                  if (dataLength[1] === FieldParser.VARIABLE_LENGTH) {
9738                      return FieldParser.processVariableAI(3, dataLength[2], rawInformation);
9739                  }
9740                  return FieldParser.processFixedAI(3, dataLength[1], rawInformation);
9741              }
9742          }
9743          for (let dataLength of FieldParser.THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH) {
9744              if (dataLength[0] === firstThreeDigits) {
9745                  if (dataLength[1] === FieldParser.VARIABLE_LENGTH) {
9746                      return FieldParser.processVariableAI(4, dataLength[2], rawInformation);
9747                  }
9748                  return FieldParser.processFixedAI(4, dataLength[1], rawInformation);
9749              }
9750          }
9751          if (rawInformation.length < 4) {
9752              throw new NotFoundException();
9753          }
9754          let firstFourDigits = rawInformation.substring(0, 4);
9755          for (let dataLength of FieldParser.FOUR_DIGIT_DATA_LENGTH) {
9756              if (dataLength[0] === firstFourDigits) {
9757                  if (dataLength[1] === FieldParser.VARIABLE_LENGTH) {
9758                      return FieldParser.processVariableAI(4, dataLength[2], rawInformation);
9759                  }
9760                  return FieldParser.processFixedAI(4, dataLength[1], rawInformation);
9761              }
9762          }
9763          throw new NotFoundException();
9764      }
9765      static processFixedAI(aiSize, fieldSize, rawInformation) {
9766          if (rawInformation.length < aiSize) {
9767              throw new NotFoundException();
9768          }
9769          let ai = rawInformation.substring(0, aiSize);
9770          if (rawInformation.length < aiSize + fieldSize) {
9771              throw new NotFoundException();
9772          }
9773          let field = rawInformation.substring(aiSize, aiSize + fieldSize);
9774          let remaining = rawInformation.substring(aiSize + fieldSize);
9775          let result = '(' + ai + ')' + field;
9776          let parsedAI = FieldParser.parseFieldsInGeneralPurpose(remaining);
9777          return parsedAI == null ? result : result + parsedAI;
9778      }
9779      static processVariableAI(aiSize, variableFieldSize, rawInformation) {
9780          let ai = rawInformation.substring(0, aiSize);
9781          let maxSize;
9782          if (rawInformation.length < aiSize + variableFieldSize) {
9783              maxSize = rawInformation.length;
9784          }
9785          else {
9786              maxSize = aiSize + variableFieldSize;
9787          }
9788          let field = rawInformation.substring(aiSize, maxSize);
9789          let remaining = rawInformation.substring(maxSize);
9790          let result = '(' + ai + ')' + field;
9791          let parsedAI = FieldParser.parseFieldsInGeneralPurpose(remaining);
9792          return parsedAI == null ? result : result + parsedAI;
9793      }
9794  }
9795  FieldParser.VARIABLE_LENGTH = [];
9796  FieldParser.TWO_DIGIT_DATA_LENGTH = [
9797      ['00', 18],
9798      ['01', 14],
9799      ['02', 14],
9800      ['10', FieldParser.VARIABLE_LENGTH, 20],
9801      ['11', 6],
9802      ['12', 6],
9803      ['13', 6],
9804      ['15', 6],
9805      ['17', 6],
9806      ['20', 2],
9807      ['21', FieldParser.VARIABLE_LENGTH, 20],
9808      ['22', FieldParser.VARIABLE_LENGTH, 29],
9809      ['30', FieldParser.VARIABLE_LENGTH, 8],
9810      ['37', FieldParser.VARIABLE_LENGTH, 8],
9811      // internal company codes
9812      ['90', FieldParser.VARIABLE_LENGTH, 30],
9813      ['91', FieldParser.VARIABLE_LENGTH, 30],
9814      ['92', FieldParser.VARIABLE_LENGTH, 30],
9815      ['93', FieldParser.VARIABLE_LENGTH, 30],
9816      ['94', FieldParser.VARIABLE_LENGTH, 30],
9817      ['95', FieldParser.VARIABLE_LENGTH, 30],
9818      ['96', FieldParser.VARIABLE_LENGTH, 30],
9819      ['97', FieldParser.VARIABLE_LENGTH, 3],
9820      ['98', FieldParser.VARIABLE_LENGTH, 30],
9821      ['99', FieldParser.VARIABLE_LENGTH, 30],
9822  ];
9823  FieldParser.THREE_DIGIT_DATA_LENGTH = [
9824      // Same format as above
9825      ['240', FieldParser.VARIABLE_LENGTH, 30],
9826      ['241', FieldParser.VARIABLE_LENGTH, 30],
9827      ['242', FieldParser.VARIABLE_LENGTH, 6],
9828      ['250', FieldParser.VARIABLE_LENGTH, 30],
9829      ['251', FieldParser.VARIABLE_LENGTH, 30],
9830      ['253', FieldParser.VARIABLE_LENGTH, 17],
9831      ['254', FieldParser.VARIABLE_LENGTH, 20],
9832      ['400', FieldParser.VARIABLE_LENGTH, 30],
9833      ['401', FieldParser.VARIABLE_LENGTH, 30],
9834      ['402', 17],
9835      ['403', FieldParser.VARIABLE_LENGTH, 30],
9836      ['410', 13],
9837      ['411', 13],
9838      ['412', 13],
9839      ['413', 13],
9840      ['414', 13],
9841      ['420', FieldParser.VARIABLE_LENGTH, 20],
9842      ['421', FieldParser.VARIABLE_LENGTH, 15],
9843      ['422', 3],
9844      ['423', FieldParser.VARIABLE_LENGTH, 15],
9845      ['424', 3],
9846      ['425', 3],
9847      ['426', 3],
9848  ];
9849  FieldParser.THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH = [
9850      // Same format as above
9851      ['310', 6],
9852      ['311', 6],
9853      ['312', 6],
9854      ['313', 6],
9855      ['314', 6],
9856      ['315', 6],
9857      ['316', 6],
9858      ['320', 6],
9859      ['321', 6],
9860      ['322', 6],
9861      ['323', 6],
9862      ['324', 6],
9863      ['325', 6],
9864      ['326', 6],
9865      ['327', 6],
9866      ['328', 6],
9867      ['329', 6],
9868      ['330', 6],
9869      ['331', 6],
9870      ['332', 6],
9871      ['333', 6],
9872      ['334', 6],
9873      ['335', 6],
9874      ['336', 6],
9875      ['340', 6],
9876      ['341', 6],
9877      ['342', 6],
9878      ['343', 6],
9879      ['344', 6],
9880      ['345', 6],
9881      ['346', 6],
9882      ['347', 6],
9883      ['348', 6],
9884      ['349', 6],
9885      ['350', 6],
9886      ['351', 6],
9887      ['352', 6],
9888      ['353', 6],
9889      ['354', 6],
9890      ['355', 6],
9891      ['356', 6],
9892      ['357', 6],
9893      ['360', 6],
9894      ['361', 6],
9895      ['362', 6],
9896      ['363', 6],
9897      ['364', 6],
9898      ['365', 6],
9899      ['366', 6],
9900      ['367', 6],
9901      ['368', 6],
9902      ['369', 6],
9903      ['390', FieldParser.VARIABLE_LENGTH, 15],
9904      ['391', FieldParser.VARIABLE_LENGTH, 18],
9905      ['392', FieldParser.VARIABLE_LENGTH, 15],
9906      ['393', FieldParser.VARIABLE_LENGTH, 18],
9907      ['703', FieldParser.VARIABLE_LENGTH, 30],
9908  ];
9909  FieldParser.FOUR_DIGIT_DATA_LENGTH = [
9910      // Same format as above
9911      ['7001', 13],
9912      ['7002', FieldParser.VARIABLE_LENGTH, 30],
9913      ['7003', 10],
9914      ['8001', 14],
9915      ['8002', FieldParser.VARIABLE_LENGTH, 20],
9916      ['8003', FieldParser.VARIABLE_LENGTH, 30],
9917      ['8004', FieldParser.VARIABLE_LENGTH, 30],
9918      ['8005', 6],
9919      ['8006', 18],
9920      ['8007', FieldParser.VARIABLE_LENGTH, 30],
9921      ['8008', FieldParser.VARIABLE_LENGTH, 12],
9922      ['8018', 18],
9923      ['8020', FieldParser.VARIABLE_LENGTH, 25],
9924      ['8100', 6],
9925      ['8101', 10],
9926      ['8102', 2],
9927      ['8110', FieldParser.VARIABLE_LENGTH, 70],
9928      ['8200', FieldParser.VARIABLE_LENGTH, 70],
9929  ];
9930
9931  class GeneralAppIdDecoder {
9932      constructor(information) {
9933          this.buffer = new StringBuilder();
9934          this.information = information;
9935      }
9936      decodeAllCodes(buff, initialPosition) {
9937          let currentPosition = initialPosition;
9938          let remaining = null;
9939          do {
9940              let info = this.decodeGeneralPurposeField(currentPosition, remaining);
9941              let parsedFields = FieldParser.parseFieldsInGeneralPurpose(info.getNewString());
9942              if (parsedFields != null) {
9943                  buff.append(parsedFields);
9944              }
9945              if (info.isRemaining()) {
9946                  remaining = '' + info.getRemainingValue();
9947              }
9948              else {
9949                  remaining = null;
9950              }
9951              if (currentPosition === info.getNewPosition()) { // No step forward!
9952                  break;
9953              }
9954              currentPosition = info.getNewPosition();
9955          } while (true);
9956          return buff.toString();
9957      }
9958      isStillNumeric(pos) {
9959          // It's numeric if it still has 7 positions
9960          // and one of the first 4 bits is "1".
9961          if (pos + 7 > this.information.getSize()) {
9962              return pos + 4 <= this.information.getSize();
9963          }
9964          for (let i = pos; i < pos + 3; ++i) {
9965              if (this.information.get(i)) {
9966                  return true;
9967              }
9968          }
9969          return this.information.get(pos + 3);
9970      }
9971      decodeNumeric(pos) {
9972          if (pos + 7 > this.information.getSize()) {
9973              let numeric = this.extractNumericValueFromBitArray(pos, 4);
9974              if (numeric === 0) {
9975                  return new DecodedNumeric(this.information.getSize(), DecodedNumeric.FNC1, DecodedNumeric.FNC1);
9976              }
9977              return new DecodedNumeric(this.information.getSize(), numeric - 1, DecodedNumeric.FNC1);
9978          }
9979          let numeric = this.extractNumericValueFromBitArray(pos, 7);
9980          let digit1 = (numeric - 8) / 11;
9981          let digit2 = (numeric - 8) % 11;
9982          return new DecodedNumeric(pos + 7, digit1, digit2);
9983      }
9984      extractNumericValueFromBitArray(pos, bits) {
9985          return GeneralAppIdDecoder.extractNumericValueFromBitArray(this.information, pos, bits);
9986      }
9987      static extractNumericValueFromBitArray(information, pos, bits) {
9988          let value = 0;
9989          for (let i = 0; i < bits; ++i) {
9990              if (information.get(pos + i)) {
9991                  value |= 1 << (bits - i - 1);
9992              }
9993          }
9994          return value;
9995      }
9996      decodeGeneralPurposeField(pos, remaining) {
9997          // this.buffer.setLength(0);
9998          this.buffer.setLengthToZero();
9999          if (remaining != null) {
10000              this.buffer.append(remaining);
10001          }
10002          this.current.setPosition(pos);
10003          let lastDecoded = this.parseBlocks();
10004          if (lastDecoded != null && lastDecoded.isRemaining()) {
10005              return new DecodedInformation(this.current.getPosition(), this.buffer.toString(), lastDecoded.getRemainingValue());
10006          }
10007          return new DecodedInformation(this.current.getPosition(), this.buffer.toString());
10008      }
10009      parseBlocks() {
10010          let isFinished;
10011          let result;
10012          do {
10013              let initialPosition = this.current.getPosition();
10014              if (this.current.isAlpha()) {
10015                  result = this.parseAlphaBlock();
10016                  isFinished = result.isFinished();
10017              }
10018              else if (this.current.isIsoIec646()) {
10019                  result = this.parseIsoIec646Block();
10020                  isFinished = result.isFinished();
10021              }
10022              else { // it must be numeric
10023                  result = this.parseNumericBlock();
10024                  isFinished = result.isFinished();
10025              }
10026              let positionChanged = initialPosition !== this.current.getPosition();
10027              if (!positionChanged && !isFinished) {
10028                  break;
10029              }
10030          } while (!isFinished);
10031          return result.getDecodedInformation();
10032      }
10033      parseNumericBlock() {
10034          while (this.isStillNumeric(this.current.getPosition())) {
10035              let numeric = this.decodeNumeric(this.current.getPosition());
10036              this.current.setPosition(numeric.getNewPosition());
10037              if (numeric.isFirstDigitFNC1()) {
10038                  let information;
10039                  if (numeric.isSecondDigitFNC1()) {
10040                      information = new DecodedInformation(this.current.getPosition(), this.buffer.toString());
10041                  }
10042                  else {
10043                      information = new DecodedInformation(this.current.getPosition(), this.buffer.toString(), numeric.get
10043SecondDigit());
10044                  }
10045                  return new BlockParsedResult(true, information);
10046              }
10047              this.buffer.append(numeric.getFirstDigit());
10048              if (numeric.isSecondDigitFNC1()) {
10049                  let information = new DecodedInformation(this.current.getPosition(), this.buffer.toString());
10050                  return new BlockParsedResult(true, information);
10051              }
10052              this.buffer.append(numeric.getSecondDigit());
10053          }
10054          if (this.isNumericToAlphaNumericLatch(this.current.getPosition())) {
10055              this.current.setAlpha();
10056              this.current.incrementPosition(4);
10057          }
10058          return new BlockParsedResult(false);
10059      }
10060      parseIsoIec646Block() {
10061          while (this.isStillIsoIec646(this.current.getPosition())) {
10062              let iso = this.decodeIsoIec646(this.current.getPosition());
10063              this.current.setPosition(iso.getNewPosition());
10064              if (iso.isFNC1()) {
10065                  let information = new DecodedInformation(this.current.getPosition(), this.buffer.toString());
10066                  return new BlockParsedResult(true, information);
10067              }
10068              this.buffer.append(iso.getValue());
10069          }
10070          if (this.isAlphaOr646ToNumericLatch(this.current.getPosition())) {
10071              this.current.incrementPosition(3);
10072              this.current.setNumeric();
10073          }
10074          else if (this.isAlphaTo646ToAlphaLatch(this.current.getPosition())) {
10075              if (this.current.getPosition() + 5 < this.information.getSize()) {
10076                  this.current.incrementPosition(5);
10077              }
10078              else {
10079                  this.current.setPosition(this.information.getSize());
10080              }
10081              this.current.setAlpha();
10082          }
10083          return new BlockParsedResult(false);
10084      }
10085      parseAlphaBlock() {
10086          while (this.isStillAlpha(this.current.getPosition())) {
10087              let alpha = this.decodeAlphanumeric(this.current.getPosition());
10088              this.current.setPosition(alpha.getNewPosition());
10089              if (alpha.isFNC1()) {
10090                  let information = new DecodedInformation(this.current.getPosition(), this.buffer.toString());
10091                  return new BlockParsedResult(true, information); // end of the char block
10092              }
10093              this.buffer.append(alpha.getValue());
10094          }
10095          if (this.isAlphaOr646ToNumericLatch(this.current.getPosition())) {
10096              this.current.incrementPosition(3);
10097              this.current.setNumeric();
10098          }
10099          else if (this.isAlphaTo646ToAlphaLatch(this.current.getPosition())) {
10100              if (this.current.getPosition() + 5 < this.information.getSize()) {
10101                  this.current.incrementPosition(5);
10102              }
10103              else {
10104                  this.current.setPosition(this.information.getSize());
10105              }
10106              this.current.setIsoIec646();
10107          }
10108          return new BlockParsedResult(false);
10109      }
10110      isStillIsoIec646(pos) {
10111          if (pos + 5 > this.information.getSize()) {
10112              return false;
10113          }
10114          let fiveBitValue = this.extractNumericValueFromBitArray(pos, 5);
10115          if (fiveBitValue >= 5 && fiveBitValue < 16) {
10116              return true;
10117          }
10118          if (pos + 7 > this.information.getSize()) {
10119              return false;
10120          }
10121          let sevenBitValue = this.extractNumericValueFromBitArray(pos, 7);
10122          if (sevenBitValue >= 64 && sevenBitValue < 116) {
10123              return true;
10124          }
10125          if (pos + 8 > this.information.getSize()) {
10126              return false;
10127          }
10128          let eightBitValue = this.extractNumericValueFromBitArray(pos, 8);
10129          return eightBitValue >= 232 && eightBitValue < 253;
10130      }
10131      decodeIsoIec646(pos) {
10132          let fiveBitValue = this.extractNumericValueFromBitArray(pos, 5);
10133          if (fiveBitValue === 15) {
10134              return new DecodedChar(pos + 5, DecodedChar.FNC1);
10135          }
10136          if (fiveBitValue >= 5 && fiveBitValue < 15) {
10137              return new DecodedChar(pos + 5, ('0' + (fiveBitValue - 5)));
10138          }
10139          let sevenBitValue = this.extractNumericValueFromBitArray(pos, 7);
10140          if (sevenBitValue >= 64 && sevenBitValue < 90) {
10141              return new DecodedChar(pos + 7, ('' + (sevenBitValue + 1)));
10142          }
10143          if (sevenBitValue >= 90 && sevenBitValue < 116) {
10144              return new DecodedChar(pos + 7, ('' + (sevenBitValue + 7)));
10145          }
10146          let eightBitValue = this.extractNumericValueFromBitArray(pos, 8);
10147          let c;
10148          switch (eightBitValue) {
10149              case 232:
10150                  c = '!';
10151                  break;
10152              case 233:
10153                  c = '"';
10154                  break;
10155              case 234:
10156                  c = '%';
10157                  break;
10158              case 235:
10159                  c = '&';
10160                  break;
10161              case 236:
10162                  c = '\'';
10163                  break;
10164              case 237:
10165                  c = '(';
10166                  break;
10167              case 238:
10168                  c = ')';
10169                  break;
10170              case 239:
10171                  c = '*';
10172                  break;
10173              case 240:
10174                  c = '+';
10175                  break;
10176              case 241:
10177                  c = ',';
10178                  break;
10179              case 242:
10180                  c = '-';
10181                  break;
10182              case 243:
10183                  c = '.';
10184                  break;
10185              case 244:
10186                  c = '/';
10187                  break;
10188              case 245:
10189                  c = ':';
10190                  break;
10191              case 246:
10192                  c = ';';
10193                  break;
10194              case 247:
10195                  c = '<';
10196                  break;
10197              case 248:
10198                  c = '=';
10199                  break;
10200              case 249:
10201                  c = '>';
10202                  break;
10203              case 250:
10204                  c = '?';
10205                  break;
10206              case 251:
10207                  c = '_';
10208                  break;
10209              case 252:
10210                  c = ' ';
10211                  break;
10212              default:
10213                  throw new FormatException();
10214          }
10215          return new DecodedChar(pos + 8, c);
10216      }
10217      isStillAlpha(pos) {
10218          if (pos + 5 > this.information.getSize()) {
10219              return false;
10220          }
10221          // We now check if it's a valid 5-bit value (0..9 and FNC1)
10222          let fiveBitValue = this.extractNumericValueFromBitArray(pos, 5);
10223          if (fiveBitValue >= 5 && fiveBitValue < 16) {
10224              return true;
10225          }
10226          if (pos + 6 > this.information.getSize()) {
10227              return false;
10228          }
10229          let sixBitValue = this.extractNumericValueFromBitArray(pos, 6);
10230          return sixBitValue >= 16 && sixBitValue < 63; // 63 not included
10231      }
10232      decodeAlphanumeric(pos) {
10233          let fiveBitValue = this.extractNumericValueFromBitArray(pos, 5);
10234          if (fiveBitValue === 15) {
10235              return new DecodedChar(pos + 5, DecodedChar.FNC1);
10236          }
10237          if (fiveBitValue >= 5 && fiveBitValue < 15) {
10238              return new DecodedChar(pos + 5, ('0' + (fiveBitValue - 5)));
10239          }
10240          let sixBitValue = this.extractNumericValueFromBitArray(pos, 6);
10241          if (sixBitValue >= 32 && sixBitValue < 58) {
10242              return new DecodedChar(pos + 6, ('' + (sixBitValue + 33)));
10243          }
10244          let c;
10245          switch (sixBitValue) {
10246              case 58:
10247                  c = '*';
10248                  break;
10249              case 59:
10250                  c = ',';
10251                  break;
10252              case 60:
10253                  c = '-';
10254                  break;
10255              case 61:
10256                  c = '.';
10257                  break;
10258              case 62:
10259                  c = '/';
10260                  break;
10261              default:
10262                  throw new IllegalStateException('Decoding invalid alphanumeric value: ' + sixBitValue);
10263          }
10264          return new DecodedChar(pos + 6, c);
10265      }
10266      isAlphaTo646ToAlphaLatch(pos) {
10267          if (pos + 1 > this.information.getSize()) {
10268              return false;
10269          }
10270          for (let i = 0; i < 5 && i + pos < this.information.getSize(); ++i) {
10271              if (i === 2) {
10272                  if (!this.information.get(pos + 2)) {
10273                      return false;
10274                  }
10275              }
10276              else if (this.information.get(pos + i)) {
10277                  return false;
10278              }
10279          }
10280          return true;
10281      }
10282      isAlphaOr646ToNumericLatch(pos) {
10283          // Next is alphanumeric if there are 3 positions and they are all zeros
10284          if (pos + 3 > this.information.getSize()) {
10285              return false;
10286          }
10287          for (let i = pos; i < pos + 3; ++i) {
10288              if (this.information.get(i)) {
10289                  return false;
10290              }
10291          }
10292          return true;
10293      }
10294      isNumericToAlphaNumericLatch(pos) {
10295          // Next is alphanumeric if there are 4 positions and they are all zeros, or
10296          // if there is a subset of this just before the end of the symbol
10297          if (pos + 1 > this.information.getSize()) {
10298              return false;
10299          }
10300          for (let i = 0; i < 4 && i + pos < this.information.getSize(); ++i) {
10301              if (this.information.get(pos + i)) {
10302                  return false;
10303              }
10304          }
10305          return true;
10306      }
10307  }
10308
10309  class AbstractExpandedDecoder {
10310      constructor(information) {
10311          this.information = information;
10312          this.generalDecoder = new GeneralAppIdDecoder(information);
10313      }
10314      getInformation() {
10315          return this.information;
10316      }
10317      getGeneralDecoder() {
10318          return this.generalDecoder;
10319      }
10320  }
10321
10322  class AI01decoder extends AbstractExpandedDecoder {
10323      constructor(information) {
10324          super(information);
10325      }
10326      encodeCompressedGtin(buf, currentPos) {
10327          buf.append('(01)');
10328          let initialPosition = buf.length();
10329          buf.append('9');
10330          this.encodeCompressedGtinWithoutAI(buf, currentPos, initialPosition);
10331      }
10332      encodeCompressedGtinWithoutAI(buf, currentPos, initialBufferPosition) {
10333          for (let i = 0; i < 4; ++i) {
10334              let currentBlock = this.getGeneralDecoder().extractNumericValueFromBitArray(currentPos + 10 * i, 10);
10335              if (currentBlock / 100 === 0) {
10336                  buf.append('0');
10337              }
10338              if (currentBlock / 10 === 0) {
10339                  buf.append('0');
10340              }
10341              buf.append(currentBlock);
10342          }
10343          AI01decoder.appendCheckDigit(buf, initialBufferPosition);
10344      }
10345      static appendCheckDigit(buf, currentPos) {
10346          let checkDigit = 0;
10347          for (let i = 0; i < 13; i++) {
10348              // let digit = buf.charAt(i + currentPos) - '0';
10349              // To be checked
10350              let digit = buf.charAt(i + currentPos).charCodeAt(0) - '0'.charCodeAt(0);
10351              checkDigit += (i & 0x01) === 0 ? 3 * digit : digit;
10352          }
10353          checkDigit = 10 - (checkDigit % 10);
10354          if (checkDigit === 10) {
10355              checkDigit = 0;
10356          }
10357          buf.append(checkDigit);
10358      }
10359  }
10360  AI01decoder.GTIN_SIZE = 40;
10361
10362  class AI01AndOtherAIs extends AI01decoder {
10363      // the second one is the encodation method, and the other two are for the variable length
10364      constructor(information) {
10365          super(information);
10366      }
10367      parseInformation() {
10368          let buff = new StringBuilder();
10369          buff.append('(01)');
10370          let initialGtinPosition = buff.length();
10371          let firstGtinDigit = this.getGeneralDecoder().extractNumericValueFromBitArray(AI01AndOtherAIs.HEADER_SIZE, 4);
10372          buff.append(firstGtinDigit);
10373          this.encodeCompressedGtinWithoutAI(buff, AI01AndOtherAIs.HEADER_SIZE + 4, initialGtinPosition);
10374          return this.getGeneralDecoder().decodeAllCodes(buff, AI01AndOtherAIs.HEADER_SIZE + 44);
10375      }
10376  }
10377  AI01AndOtherAIs.HEADER_SIZE = 1 + 1 + 2; // first bit encodes the linkage flag,
10378
10379  class AnyAIDecoder extends AbstractExpandedDecoder {
10380      constructor(information) {
10381          super(information);
10382      }
10383      parseInformation() {
10384          let buf = new StringBuilder();
10385          return this.getGeneralDecoder().decodeAllCodes(buf, AnyAIDecoder.HEADER_SIZE);
10386      }
10387  }
10388  AnyAIDecoder.HEADER_SIZE = 2 + 1 + 2;
10389
10390  class AI01weightDecoder extends AI01decoder {
10391      constructor(information) {
10392          super(information);
10393      }
10394      encodeCompressedWeight(buf, currentPos, weightSize) {
10395          let originalWeightNumeric = this.getGeneralDecoder().extractNumericValueFromBitArray(currentPos, weightSize);
10396          this.addWeightCode(buf, originalWeightNumeric);
10397          let weightNumeric = this.checkWeight(originalWeightNumeric);
10398          let currentDivisor = 100000;
10399          for (let i = 0; i < 5; ++i) {
10400              if (weightNumeric / currentDivisor === 0) {
10401                  buf.append('0');
10402              }
10403              currentDivisor /= 10;
10404          }
10405          buf.append(weightNumeric);
10406      }
10407  }
10408
10409  class AI013x0xDecoder extends AI01weightDecoder {
10410      constructor(information) {
10411          super(information);
10412      }
10413      parseInformation() {
10414          if (this.getInformation().getSize() !==
10415              AI013x0xDecoder.HEADER_SIZE +
10416                  AI01weightDecoder.GTIN_SIZE +
10417                  AI013x0xDecoder.WEIGHT_SIZE) {
10418              throw new NotFoundException();
10419          }
10420          let buf = new StringBuilder();
10421          this.encodeCompressedGtin(buf, AI013x0xDecoder.HEADER_SIZE);
10422          this.encodeCompressedWeight(buf, AI013x0xDecoder.HEADER_SIZE + AI01weightDecoder.GTIN_SIZE, AI013x0xDecoder.WEIGHT_SIZE);
10423          return buf.toString();
10424      }
10425  }
10426  AI013x0xDecoder.HEADER_SIZE = 4 + 1;
10427  AI013x0xDecoder.WEIGHT_SIZE = 15;
10428
10429  class AI013103decoder extends AI013x0xDecoder {
10430      constructor(information) {
10431          super(information);
10432      }
10433      addWeightCode(buf, weight) {
10434          buf.append('(3103)');
10435      }
10436      checkWeight(weight) {
10437          return weight;
10438      }
10439  }
10440
10441  class AI01320xDecoder extends AI013x0xDecoder {
10442      constructor(information) {
10443          super(information);
10444      }
10445      addWeightCode(buf, weight) {
10446          if (weight < 10000) {
10447              buf.append('(3202)');
10448          }
10449          else {
10450              buf.append('(3203)');
10451          }
10452      }
10453      checkWeight(weight) {
10454          if (weight < 10000) {
10455              return weight;
10456          }
10457          return weight - 10000;
10458      }
10459  }
10460
10461  class AI01392xDecoder extends AI01decoder {
10462      constructor(information) {
10463          super(information);
10464      }
10465      parseInformation() {
10466          if (this.getInformation().getSize() < AI01392xDecoder.HEADER_SIZE + AI01decoder.GTIN_SIZE) {
10467              throw new NotFoundException();
10468          }
10469          let buf = new StringBuilder();
10470          this.encodeCompressedGtin(buf, AI01392xDecoder.HEADER_SIZE);
10471          let lastAIdigit = this.getGeneralDecoder().extractNumericValueFromBitArray(AI01392xDecoder.HEADER_SIZE + AI01decoder.GTIN_SIZE, AI01392xDecoder.LAST_DIGIT_SIZE);
10472          buf.append('(392');
10473          buf.append(lastAIdigit);
10474          buf.append(')');
10475          let decodedInformation = this.getGeneralDecoder().decodeGeneralPurposeField(AI01392xDecoder.HEADER_SIZE + AI01decoder.GTIN_SIZE + AI01392xDecoder.LAST_DIGIT_SIZE, null);
10476          buf.append(decodedInformation.getNewString());
10477          return buf.toString();
10478      }
10479  }
10480  AI01392xDecoder.HEADER_SIZE = 5 + 1 + 2;
10481  AI01392xDecoder.LAST_DIGIT_SIZE = 2;
10482
10483  class AI01393xDecoder extends AI01decoder {
10484      constructor(information) {
10485          super(information);
10486      }
10487      parseInformation() {
10488          if (this.getInformation().getSize() <
10489              AI01393xDecoder.HEADER_SIZE + AI01decoder.GTIN_SIZE) {
10490              throw new NotFoundException();
10491          }
10492          let buf = new StringBuilder();
10493          this.encodeCompressedGtin(buf, AI01393xDecoder.HEADER_SIZE);
10494          let lastAIdigit = this.getGeneralDecoder().extractNumericValueFromBitArray(AI01393xDecoder.HEADER_SIZE + AI01decoder.GTIN_SIZE, AI01393xDecoder.LAST_DIGIT_SIZE);
10495          buf.append('(393');
10496          buf.append(lastAIdigit);
10497          buf.append(')');
10498          let firstThreeDigits = this.getGeneralDecoder().extractNumericValueFromBitArray(AI01393xDecoder.HEADER_SIZE +
10499              AI01decoder.GTIN_SIZE +
10500              AI01393xDecoder.LAST_DIGIT_SIZE, AI01393xDecoder.FIRST_THREE_DIGITS_SIZE);
10501          if (firstThreeDigits / 100 === 0) {
10502              buf.append('0');
10503          }
10504          if (firstThreeDigits / 10 === 0) {
10505              buf.append('0');
10506          }
10507          buf.append(firstThreeDigits);
10508          let generalInformation = this.getGeneralDecoder().decodeGeneralPurposeField(AI01393xDecoder.HEADER_SIZE +
10509              AI01decoder.GTIN_SIZE +
10510              AI01393xDecoder.LAST_DIGIT_SIZE +
10511              AI01393xDecoder.FIRST_THREE_DIGITS_SIZE, null);
10512          buf.append(generalInformation.getNewString());
10513          return buf.toString();
10514      }
10515  }
10516  AI01393xDecoder.HEADER_SIZE = 5 + 1 + 2;
10517  AI01393xDecoder.LAST_DIGIT_SIZE = 2;
10518  AI01393xDecoder.FIRST_THREE_DIGITS_SIZE = 10;
10519
10520  class AI013x0x1xDecoder extends AI01weightDecoder {
10521      constructor(information, firstAIdigits, dateCode) {
10522          super(information);
10523          this.dateCode = dateCode;
10524          this.firstAIdigits = firstAIdigits;
10525      }
10526      parseInformation() {
10527          if (this.getInformation().getSize() !==
10528              AI013x0x1xDecoder.HEADER_SIZE +
10529                  AI013x0x1xDecoder.GTIN_SIZE +
10530                  AI013x0x1xDecoder.WEIGHT_SIZE +
10531                  AI013x0x1xDecoder.DATE_SIZE) {
10532              throw new NotFoundException();
10533          }
10534          let buf = new StringBuilder();
10535          this.encodeCompressedGtin(buf, AI013x0x1xDecoder.HEADER_SIZE);
10536          this.encodeCompressedWeight(buf, AI013x0x1xDecoder.HEADER_SIZE + AI013x0x1xDecoder.GTIN_SIZE, AI013x0x1xDecoder.WEIGHT_SIZE);
10537          this.encodeCompressedDate(buf, AI013x0x1xDecoder.HEADER_SIZE +
10538              AI013x0x1xDecoder.GTIN_SIZE +
10539              AI013x0x1xDecoder.WEIGHT_SIZE);
10540          return buf.toString();
10541      }
10542      encodeCompressedDate(buf, currentPos) {
10543          let numericDate = this.getGeneralDecoder().extractNumericValueFromBitArray(currentPos, AI013x0x1xDecoder.DATE_SIZE);
10544          if (numericDate === 38400) {
10545              return;
10546          }
10547          buf.append('(');
10548          buf.append(this.dateCode);
10549          buf.append(')');
10550          let day = numericDate % 32;
10551          numericDate /= 32;
10552          let month = (numericDate % 12) + 1;
10553          numericDate /= 12;
10554          let year = numericDate;
10555          if (year / 10 === 0) {
10556              buf.append('0');
10557          }
10558          buf.append(year);
10559          if (month / 10 === 0) {
10560              buf.append('0');
10561          }
10562          buf.append(month);
10563          if (day / 10 === 0) {
10564              buf.append('0');
10565          }
10566          buf.append(day);
10567      }
10568      addWeightCode(buf, weight) {
10569          buf.append('(');
10570          buf.append(this.firstAIdigits);
10571          buf.append(weight / 100000);
10572          buf.append(')');
10573      }
10574      checkWeight(weight) {
10575          return weight % 100000;
10576      }
10577  }
10578  AI013x0x1xDecoder.HEADER_SIZE = 7 + 1;
10579  AI013x0x1xDecoder.WEIGHT_SIZE = 20;
10580  AI013x0x1xDecoder.DATE_SIZE = 16;
10581
10582  function createDecoder(information) {
10583      try {
10584          if (information.get(1)) {
10585              return new AI01AndOtherAIs(information);
10586          }
10587          if (!information.get(2)) {
10588              return new AnyAIDecoder(information);
10589          }
10590          let fourBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 4);
10591          switch (fourBitEncodationMethod) {
10592              case 4: return new AI013103decoder(information);
10593              case 5: return new AI01320xDecoder(information);
10594          }
10595          let fiveBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 5);
10596          switch (fiveBitEncodationMethod) {
10597              case 12: return new AI01392xDecoder(information);
10598              case 13: return new AI01393xDecoder(information);
10599          }
10600          let sevenBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 7);
10601          switch (sevenBitEncodationMethod) {
10602              case 56: return new AI013x0x1xDecoder(information, '310', '11');
10603              case 57: return new AI013x0x1xDecoder(information, '320', '11');
10604              case 58: return new AI013x0x1xDecoder(information, '310', '13');
10605              case 59: return new AI013x0x1xDecoder(information, '320', '13');
10606              case 60: return new AI013x0x1xDecoder(information, '310', '15');
10607              case 61: return new AI013x0x1xDecoder(information, '320', '15');
10608              case 62: return new AI013x0x1xDecoder(information, '310', '17');
10609              case 63: return new AI013x0x1xDecoder(information, '320', '17');
10610          }
10611      }
10612      catch (e) {
10613          console.log(e);
10614          throw new IllegalStateException('unknown decoder: ' + information);
10615      }
10616  }
10617
10618  class ExpandedPair {
10619      constructor(leftChar, rightChar, finderPatter, mayBeLast) {
10620          this.leftchar = leftChar;
10621          this.rightchar = rightChar;
10622          this.finderpattern = finderPatter;
10623          this.maybeLast = mayBeLast;
10624      }
10625      mayBeLast() {
10626          return this.maybeLast;
10627      }
10628      getLeftChar() {
10629          return this.leftchar;
10630      }
10631      getRightChar() {
10632          return this.rightchar;
10633      }
10634      getFinderPattern() {
10635          return this.finderpattern;
10636      }
10637      mustBeLast() {
10638          return this.rightchar == null;
10639      }
10640      toString() {
10641          return '[ ' + this.leftchar + ', ' + this.rightchar + ' : ' + (this.finderpattern == null ? 'null' : this.finderpattern.getValue()) + ' ]';
10642      }
10643      static equals(o1, o2) {
10644          if (!(o1 instanceof ExpandedPair)) {
10645              return false;
10646          }
10647          return ExpandedPair.equalsOrNull(o1.leftchar, o2.leftchar) &&
10648              ExpandedPair.equalsOrNull(o1.rightchar, o2.rightchar) &&
10649              ExpandedPair.equalsOrNull(o1.finderpattern, o2.finderpattern);
10650      }
10651      static equalsOrNull(o1, o2) {
10652          return o1 === null ? o2 === null : ExpandedPair.equals(o1, o2);
10653      }
10654      hashCode() {
10655          // return ExpandedPair.hashNotNull(leftChar) ^ hashNotNull(rightChar) ^ hashNotNull(finderPattern);
10656          let value = this.leftchar.getValue() ^ this.rightchar.getValue() ^ this.finderpattern.getValue();
10657          return value;
10658      }
10659  }
10660
10661  class ExpandedRow {
10662      constructor(pairs, rowNumber, wasReversed) {
10663          this.pairs = pairs;
10664          this.rowNumber = rowNumber;
10665          this.wasReversed = wasReversed;
10666      }
10667      getPairs() {
10668          return this.pairs;
10669      }
10670      getRowNumber() {
10671          return this.rowNumber;
10672      }
10673      isReversed() {
10674          return this.wasReversed;
10675      }
10676      // check implementation
10677      isEquivalent(otherPairs) {
10678          return this.checkEqualitity(this, otherPairs);
10679      }
10680      // @Override
10681      toString() {
10682          return '{ ' + this.pairs + ' }';
10683      }
10684      /**
10685       * Two rows are equal if they contain the same pairs in the same order.
10686       */
10687      // @Override
10688      // check implementation
10689      equals(o1, o2) {
10690          if (!(o1 instanceof ExpandedRow)) {
10691              return false;
10692          }
10693          return this.checkEqualitity(o1, o2) && o1.wasReversed === o2.wasReversed;
10694      }
10695      checkEqualitity(pair1, pair2) {
10696          if (!pair1 || !pair2)
10697              return;
10698          let result;
10699          pair1.forEach((e1, i) => {
10700              pair2.forEach(e2 => {
10701                  if (e1.getLeftChar().getValue() === e2.getLeftChar().getValue() && e1.getRightChar().getValue() === e2.getRightChar().getValue() && e1.getFinderPatter().getValue() === e2.getFinderPatter().getValue()) {
10702                      result = true;
10703                  }
10704              });
10705          });
10706          return result;
10707      }
10708  }
10709
10710  // import java.util.ArrayList;
10711  // import java.util.Iterator;
10712  // import java.util.List;
10713  // import java.util.Map;
10714  // import java.util.Collections;
10715  /** @experimental */
10716  class RSSExpandedReader extends AbstractRSSReader {
10717      constructor() {
10718          super(...arguments);
10719          this.pairs = new Array(RSSExpandedReader.MAX_PAIRS);
10720          this.rows = new Array();
10721          this.startEnd = [2];
10722      }
10723      decodeRow(rowNumber, row, hints) {
10724          // Rows can start with even pattern in case in prev rows there where odd number of patters.
10725          // So lets try twice
10726          // this.pairs.clear();
10727          this.pairs.length = 0;
10728          this.startFromEven = false;
10729          try {
10730              return RSSExpandedReader.constructResult(this.decodeRow2pairs(rowNumber, row));
10731          }
10732          catch (e) {
10733              // OK
10734              // console.log(e);
10735          }
10736          this.pairs.length = 0;
10737          this.startFromEven = true;
10738          return RSSExpandedReader.constructResult(this.decodeRow2pairs(rowNumber, row));
10739      }
10740      reset() {
10741          this.pairs.length = 0;
10742          this.rows.length = 0;
10743      }
10744      // Not private for testing
10745      decodeRow2pairs(rowNumber, row) {
10746          let done = false;
10747          while (!done) {
10748              try {
10749                  this.pairs.push(this.retrieveNextPair(row, this.pairs, rowNumber));
10750              }
10751              catch (error) {
10752                  if (error instanceof NotFoundException) {
10753                      if (!this.pairs.length) {
10754                          throw new NotFoundException();
10755                      }
10756                      // exit this loop when retrieveNextPair() fails and throws
10757                      done = true;
10758                  }
10759              }
10760          }
10761          // TODO: verify sequence of finder patterns as in checkPairSequence()
10762          if (this.checkChecksum()) {
10763              return this.pairs;
10764          }
10765          let tryStackedDecode;
10766          if (this.rows.length) {
10767              tryStackedDecode = true;
10768          }
10769          else {
10770              tryStackedDecode = false;
10771          }
10772          // let tryStackedDecode = !this.rows.isEmpty();
10773          this.storeRow(rowNumber, false); // TODO: deal with reversed rows
10774          if (tryStackedDecode) {
10775              // When the image is 180-rotated, then rows are sorted in wrong direction.
10776              // Try twice with both the directions.
10777              let ps = this.checkRowsBoolean(false);
10778              if (ps != null) {
10779                  return ps;
10780              }
10781              ps = this.checkRowsBoolean(true);
10782              if (ps != null) {
10783                  return ps;
10784              }
10785          }
10786          throw new NotFoundException();
10787      }
10788      // Need to Verify
10789      checkRowsBoolean(reverse) {
10790          // Limit number of rows we are checking
10791          // We use recursive algorithm with pure complexity and don't want it to take forever
10792          // Stacked barcode can have up to 11 rows, so 25 seems reasonable enough
10793          if (this.rows.length > 25) {
10794              this.rows.length = 0; // We will never have a chance to get result, so clear it
10795              return null;
10796          }
10797          this.pairs.length = 0;
10798          if (reverse) {
10799              this.rows = this.rows.reverse();
10800              // Collections.reverse(this.rows);
10801          }
10802          let ps = null;
10803          try {
10804              ps = this.checkRows(new Array(), 0);
10805          }
10806          catch (e) {
10807              // OK
10808              console.log(e);
10809          }
10810          if (reverse) {
10811              this.rows = this.rows.reverse();
10812              // Collections.reverse(this.rows);
10813          }
10814          return ps;
10815      }
10816      // Try to construct a valid rows sequence
10817      // Recursion is used to implement backtracking
10818      checkRows(collectedRows, currentRow) {
10819          for (let i = currentRow; i < this.rows.length; i++) {
10820              let row = this.rows[i];
10821              this.pairs.length = 0;
10822              for (let collectedRow of collectedRows) {
10823                  this.pairs.push(collectedRow.getPairs());
10824              }
10825              this.pairs.push(row.getPairs());
10826              if (!RSSExpandedReader.isValidSequence(this.pairs)) {
10827                  continue;
10828              }
10829              if (this.checkChecksum()) {
10830                  return this.pairs;
10831              }
10832              let rs = new Array(collectedRows);
10833              rs.push(row);
10834              try {
10835                  // Recursion: try to add more rows
10836                  return this.checkRows(rs, i + 1);
10837              }
10838              catch (e) {
10839                  // We failed, try the next candidate
10840                  console.log(e);
10841              }
10842          }
10843          throw new NotFoundException();
10844      }
10845      // Whether the pairs form a valid find pattern sequence,
10846      // either complete or a prefix
10847      static isValidSequence(pairs) {
10848          for (let sequence of RSSExpandedReader.FINDER_PATTERN_SEQUENCES) {
10849              if (pairs.length > sequence.length) {
10850                  continue;
10851              }
10852              let stop = true;
10853              for (let j = 0; j < pairs.length; j++) {
10854                  if (pairs[j].getFinderPattern().getValue() !== sequence[j]) {
10855                      stop = false;
10856                      break;
10857                  }
10858              }
10859              if (stop) {
10860                  return true;
10861              }
10862          }
10863          return false;
10864      }
10865      storeRow(rowNumber, wasReversed) {
10866          // Discard if duplicate above or below; otherwise insert in order by row number.
10867          let insertPos = 0;
10868          let prevIsSame = false;
10869          let nextIsSame = false;
10870          while (insertPos < this.rows.length) {
10871              let erow = this.rows[insertPos];
10872              if (erow.getRowNumber() > rowNumber) {
10873                  nextIsSame = erow.isEquivalent(this.pairs);
10874                  break;
10875              }
10876              prevIsSame = erow.isEquivalent(this.pairs);
10877              insertPos++;
10878          }
10879          if (nextIsSame || prevIsSame) {
10880              return;
10881          }
10882          // When the row was partially decoded (e.g. 2 pairs found instead of 3),
10883          // it will prevent us from detecting the barcode.
10884          // Try to merge partial rows
10885          // Check whether the row is part of an allready detected row
10886          if (RSSExpandedReader.isPartialRow(this.pairs, this.rows)) {
10887              return;
10888          }
10889          this.rows.push(insertPos, new ExpandedRow(this.pairs, rowNumber, wasReversed));
10890          this.removePartialRows(this.pairs, this.rows);
10891      }
10892      // Remove all the rows that contains only specified pairs
10893      removePartialRows(pairs, rows) {
10894          // for (Iterator<ExpandedRow> iterator = rows.iterator(); iterator.hasNext();) {
10895          //   ExpandedRow r = iterator.next();
10896          //   if (r.getPairs().size() == pairs.size()) {
10897          //     continue;
10898          //   }
10899          //   boolean allFound = true;
10900          //   for (ExpandedPair p : r.getPairs()) {
10901          //     boolean found = false;
10902          //     for (ExpandedPair pp : pairs) {
10903          //       if (p.equals(pp)) {
10904          //         found = true;
10905          //         break;
10906          //       }
10907          //     }
10908          //     if (!found) {
10909          //       allFound = false;
10910          //       break;
10911          //     }
10912          //   }
10913          //   if (allFound) {
10914          //     // 'pairs' contains all the pairs from the row 'r'
10915          //     iterator.remove();
10916          //   }
10917          // }
10918          for (let row of rows) {
10919              if (row.getPairs().length === pairs.length) {
10920                  continue;
10921              }
10922              for (let p of row.getPairs()) {
10923                  for (let pp of pairs) {
10924                      if (ExpandedPair.equals(p, pp)) {
10925                          break;
10926                      }
10927                  }
10928              }
10929          }
10930      }
10931      // Returns true when one of the rows already contains all the pairs
10932      static isPartialRow(pairs, rows) {
10933          for (let r of rows) {
10934              let allFound = true;
10935              for (let p of pairs) {
10936                  let found = false;
10937                  for (let pp of r.getPairs()) {
10938                      if (p.equals(pp)) {
10939                          found = true;
10940                          break;
10941                      }
10942                  }
10943                  if (!found) {
10944                      allFound = false;
10945                      break;
10946                  }
10947              }
10948              if (allFound) {
10949                  // the row 'r' contain all the pairs from 'pairs'
10950                  return true;
10951              }
10952          }
10953          return false;
10954      }
10955      // Only used for unit testing
10956      getRows() {
10957          return this.rows;
10958      }
10959      // Not private for unit testing
10960      static constructResult(pairs) {
10961          let binary = BitArrayBuilder.buildBitArray(pairs);
10962          let decoder = createDecoder(binary);
10963          let resultingString = decoder.parseInformation();
10964          let firstPoints = pairs[0].getFinderPattern().getResultPoints();
10965          let lastPoints = pairs[pairs.length - 1]
10966              .getFinderPattern()
10967              .getResultPoints();
10968          let points = [firstPoints[0], firstPoints[1], lastPoints[0], lastPoints[1]];
10969          return new Result$1(resultingString, null, null, points, BarcodeFormat$1.RSS_EXPANDED, null);
10970      }
10971      checkChecksum() {
10972          let firstPair = this.pairs.get(0);
10973          let checkCharacter = firstPair.getLeftChar();
10974          let firstCharacter = firstPair.getRightChar();
10975          if (firstCharacter === null) {
10976              return false;
10977          }
10978          let checksum = firstCharacter.getChecksumPortion();
10979          let s = 2;
10980          for (let i = 1; i < this.pairs.size(); ++i) {
10981              let currentPair = this.pairs.get(i);
10982              checksum += currentPair.getLeftChar().getChecksumPortion();
10983              s++;
10984              let currentRightChar = currentPair.getRightChar();
10985              if (currentRightChar != null) {
10986                  checksum += currentRightChar.getChecksumPortion();
10987                  s++;
10988              }
10989          }
10990          checksum %= 211;
10991          let checkCharacterValue = 211 * (s - 4) + checksum;
10992          return checkCharacterValue === checkCharacter.getValue();
10993      }
10994      static getNextSecondBar(row, initialPos) {
10995          let currentPos;
10996          if (row.get(initialPos)) {
10997              currentPos = row.getNextUnset(initialPos);
10998              currentPos = row.getNextSet(currentPos);
10999          }
11000          else {
11001              currentPos = row.getNextSet(initialPos);
11002              currentPos = row.getNextUnset(currentPos);
11003          }
11004          return currentPos;
11005      }
11006      // not private for testing
11007      retrieveNextPair(row, previousPairs, rowNumber) {
11008          let isOddPattern = previousPairs.length % 2 === 0;
11009          if (this.startFromEven) {
11010              isOddPattern = !isOddPattern;
11011          }
11012          let pattern;
11013          let keepFinding = true;
11014          let forcedOffset = -1;
11015          do {
11016              this.findNextPair(row, previousPairs, forcedOffset);
11017              pattern = this.parseFoundFinderPattern(row, rowNumber, isOddPattern);
11018              if (pattern === null) {
11019                  forcedOffset = RSSExpandedReader.getNextSecondBar(row, this.startEnd[0]);
11020              }
11021              else {
11022                  keepFinding = false;
11023              }
11024          } while (keepFinding);
11025          // When stacked symbol is split over multiple rows, there's no way to guess if this pair can be last or not.
11026          // boolean mayBeLast = checkPairSequence(previousPairs, pattern);
11027          let leftChar = this.decodeDataCharacter(row, pattern, isOddPattern, true);
11028          if (!this.isEmptyPair(previousPairs) &&
11029              previousPairs[previousPairs.length - 1].mustBeLast()) {
11030              throw new NotFoundException();
11031          }
11032          let rightChar;
11033          try {
11034              rightChar = this.decodeDataCharacter(row, pattern, isOddPattern, false);
11035          }
11036          catch (e) {
11037              rightChar = null;
11038              console.log(e);
11039          }
11040          return new ExpandedPair(leftChar, rightChar, pattern, true);
11041      }
11042      isEmptyPair(pairs) {
11043          if (pairs.length === 0) {
11044              return true;
11045          }
11046          return false;
11047      }
11048      findNextPair(row, previousPairs, forcedOffset) {
11049          let counters = this.getDecodeFinderCounters();
11050          counters[0] = 0;
11051          counters[1] = 0;
11052          counters[2] = 0;
11053          counters[3] = 0;
11054          let width = row.getSize();
11055          let rowOffset;
11056          if (forcedOffset >= 0) {
11057              rowOffset = forcedOffset;
11058          }
11059          else if (this.isEmptyPair(previousPairs)) {
11060              rowOffset = 0;
11061          }
11062          else {
11063              let lastPair = previousPairs[previousPairs.length - 1];
11064              rowOffset = lastPair.getFinderPattern().getStartEnd()[1];
11065          }
11066          let searchingEvenPair = previousPairs.length % 2 !== 0;
11067          if (this.startFromEven) {
11068              searchingEvenPair = !searchingEvenPair;
11069          }
11070          let isWhite = false;
11071          while (rowOffset < width) {
11072              isWhite = !row.get(rowOffset);
11073              if (!isWhite) {
11074                  break;
11075              }
11076              rowOffset++;
11077          }
11078          let counterPosition = 0;
11079          let patternStart = rowOffset;
11080          for (let x = rowOffset; x < width; x++) {
11081              if (row.get(x) !== isWhite) {
11082                  counters[counterPosition]++;
11083              }
11084              else {
11085                  if (counterPosition === 3) {
11086                      if (searchingEvenPair) {
11087                          RSSExpandedReader.reverseCounters(counters);
11088                      }
11089                      if (RSSExpandedReader.isFinderPattern(counters)) {
11090                          this.startEnd[0] = patternStart;
11091                          this.startEnd[1] = x;
11092                          return;
11093                      }
11094                      if (searchingEvenPair) {
11095                          RSSExpandedReader.reverseCounters(counters);
11096                      }
11097                      patternStart += counters[0] + counters[1];
11098                      counters[0] = counters[2];
11099                      counters[1] = counters[3];
11100                      counters[2] = 0;
11101                      counters[3] = 0;
11102                      counterPosition--;
11103                  }
11104                  else {
11105                      counterPosition++;
11106                  }
11107                  counters[counterPosition] = 1;
11108                  isWhite = !isWhite;
11109              }
11110          }
11111          throw new NotFoundException();
11112      }
11113      static reverseCounters(counters) {
11114          let length = counters.length;
11115          for (let i = 0; i < length / 2; ++i) {
11116              let tmp = counters[i];
11117              counters[i] = counters[length - i - 1];
11118              counters[length - i - 1] = tmp;
11119          }
11120      }
11121      parseFoundFinderPattern(row, rowNumber, oddPattern) {
11122          // Actually we found elements 2-5.
11123          let firstCounter;
11124          let start;
11125          let end;
11126          if (oddPattern) {
11127              // If pattern number is odd, we need to locate element 1 *before* the current block.
11128              let firstElementStart = this.startEnd[0] - 1;
11129              // Locate element 1
11130              while (firstElementStart >= 0 && !row.get(firstElementStart)) {
11131                  firstElementStart--;
11132              }
11133              firstElementStart++;
11134              firstCounter = this.startEnd[0] - firstElementStart;
11135              start = firstElementStart;
11136              end = this.startEnd[1];
11137          }
11138          else {
11139              // If pattern number is even, the pattern is reversed, so we need to locate element 1 *after* the current block.
11140              start = this.startEnd[0];
11141              end = row.getNextUnset(this.startEnd[1] + 1);
11142              firstCounter = end - this.startEnd[1];
11143          }
11144          // Make 'counters' hold 1-4
11145          let counters = this.getDecodeFinderCounters();
11146          System.arraycopy(counters, 0, counters, 1, counters.length - 1);
11147          counters[0] = firstCounter;
11148          let value;
11149          try {
11150              value = this.parseFinderValue(counters, RSSExpandedReader.FINDER_PATTERNS);
11151          }
11152          catch (e) {
11153              return null;
11154          }
11155          // return new FinderPattern(value, new int[] { start, end }, start, end, rowNumber});
11156          return new FinderPattern$1(value, [start, end], start, end, rowNumber);
11157      }
11158      decodeDataCharacter(row, pattern, isOddPattern, leftChar) {
11159          let counters = this.getDataCharacterCounters();
11160          for (let x = 0; x < counters.length; x++) {
11161              counters[x] = 0;
11162          }
11163          if (leftChar) {
11164              RSSExpandedReader.recordPatternInReverse(row, pattern.getStartEnd()[0], counters);
11165          }
11166          else {
11167              RSSExpandedReader.recordPattern(row, pattern.getStartEnd()[1], counters);
11168              // reverse it
11169              for (let i = 0, j = counters.length - 1; i < j; i++, j--) {
11170                  let temp = counters[i];
11171                  counters[i] = counters[j];
11172                  counters[j] = temp;
11173              }
11174          } // counters[] has the pixels of the module
11175          let numModules = 17; // left and right data characters have all the same length
11176          let elementWidth = MathUtils.sum(new Int32Array(counters)) / numModules;
11177          // Sanity check: element width for pattern and the character should match
11178          let expectedElementWidth = (pattern.getStartEnd()[1] - pattern.getStartEnd()[0]) / 15.0;
11179          if (Math.abs(elementWidth - expectedElementWidth) / expectedElementWidth >
11180              0.3) {
11181              throw new NotFoundException();
11182          }
11183          let oddCounts = this.getOddCounts();
11184          let evenCounts = this.getEvenCounts();
11185          let oddRoundingErrors = this.getOddRoundingErrors();
11186          let evenRoundingErrors = this.getEvenRoundingErrors();
11187          for (let i = 0; i < counters.length; i++) {
11188              let value = (1.0 * counters[i]) / elementWidth;
11189              let count = value + 0.5; // Round
11190              if (count < 1) {
11191                  if (value < 0.3) {
11192                      throw new NotFoundException();
11193                  }
11194                  count = 1;
11195              }
11196              else if (count > 8) {
11197                  if (value > 8.7) {
11198                      throw new NotFoundException();
11199                  }
11200                  count = 8;
11201              }
11202              let offset = i / 2;
11203              if ((i & 0x01) === 0) {
11204                  oddCounts[offset] = count;
11205                  oddRoundingErrors[offset] = value - count;
11206              }
11207              else {
11208                  evenCounts[offset] = count;
11209                  evenRoundingErrors[offset] = value - count;
11210              }
11211          }
11212          this.adjustOddEvenCounts(numModules);
11213          let weightRowNumber = 4 * pattern.getValue() + (isOddPattern ? 0 : 2) + (leftChar ? 0 : 1) - 1;
11214          let oddSum = 0;
11215          let oddChecksumPortion = 0;
11216          for (let i = oddCounts.length - 1; i >= 0; i--) {
11217              if (RSSExpandedReader.isNotA1left(pattern, isOddPattern, leftChar)) {
11218                  let weight = RSSExpandedReader.WEIGHTS[weightRowNumber][2 * i];
11219                  oddChecksumPortion += oddCounts[i] * weight;
11220              }
11221              oddSum += oddCounts[i];
11222          }
11223          let evenChecksumPortion = 0;
11224          // int evenSum = 0;
11225          for (let i = evenCounts.length - 1; i >= 0; i--) {
11226              if (RSSExpandedReader.isNotA1left(pattern, isOddPattern, leftChar)) {
11227                  let weight = RSSExpandedReader.WEIGHTS[weightRowNumber][2 * i + 1];
11228                  evenChecksumPortion += evenCounts[i] * weight;
11229              }
11230              // evenSum += evenCounts[i];
11231          }
11232          let checksumPortion = oddChecksumPortion + evenChecksumPortion;
11233          if ((oddSum & 0x01) !== 0 || oddSum > 13 || oddSum < 4) {
11234              throw new NotFoundException();
11235          }
11236          let group = (13 - oddSum) / 2;
11237          let oddWidest = RSSExpandedReader.SYMBOL_WIDEST[group];
11238          let evenWidest = 9 - oddWidest;
11239          let vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
11240          let vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
11241          let tEven = RSSExpandedReader.EVEN_TOTAL_SUBSET[group];
11242          let gSum = RSSExpandedReader.GSUM[group];
11243          let value = vOdd * tEven + vEven + gSum;
11244          return new DataCharacter(value, checksumPortion);
11245      }
11246      static isNotA1left(pattern, isOddPattern, leftChar) {
11247          // A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char
11248          return !(pattern.getValue() === 0 && isOddPattern && leftChar);
11249      }
11250      adjustOddEvenCounts(numModules) {
11251          let oddSum = MathUtils.sum(new Int32Array(this.getOddCounts()));
11252          let evenSum = MathUtils.sum(new Int32Array(this.getEvenCounts()));
11253          let incrementOdd = false;
vendor: 9,232 bytes, lines 11254-11518
11254          let decrementOdd = false;
11255          if (oddSum > 13) {
11256              decrementOdd = true;
11257          }
11258          else if (oddSum < 4) {
11259              incrementOdd = true;
11260          }
11261          let incrementEven = false;
11262          let decrementEven = false;
11263          if (evenSum > 13) {
11264              decrementEven = true;
11265          }
11266          else if (evenSum < 4) {
11267              incrementEven = true;
11268          }
11269          let mismatch = oddSum + evenSum - numModules;
11270          let oddParityBad = (oddSum & 0x01) === 1;
11271          let evenParityBad = (evenSum & 0x01) === 0;
11272          if (mismatch === 1) {
11273              if (oddParityBad) {
11274                  if (evenParityBad) {
11275                      throw new NotFoundException();
11276                  }
11277                  decrementOdd = true;
11278              }
11279              else {
11280                  if (!evenParityBad) {
11281                      throw new NotFoundException();
11282                  }
11283                  decrementEven = true;
11284              }
11285          }
11286          else if (mismatch === -1) {
11287              if (oddParityBad) {
11288                  if (evenParityBad) {
11289                      throw new NotFoundException();
11290                  }
11291                  incrementOdd = true;
11292              }
11293              else {
11294                  if (!evenParityBad) {
11295                      throw new NotFoundException();
11296                  }
11297                  incrementEven = true;
11298              }
11299          }
11300          else if (mismatch === 0) {
11301              if (oddParityBad) {
11302                  if (!evenParityBad) {
11303                      throw new NotFoundException();
11304                  }
11305                  // Both bad
11306                  if (oddSum < evenSum) {
11307                      incrementOdd = true;
11308                      decrementEven = true;
11309                  }
11310                  else {
11311                      decrementOdd = true;
11312                      incrementEven = true;
11313                  }
11314              }
11315              else {
11316                  if (evenParityBad) {
11317                      throw new NotFoundException();
11318                  }
11319                  // Nothing to do!
11320              }
11321          }
11322          else {
11323              throw new NotFoundException();
11324          }
11325          if (incrementOdd) {
11326              if (decrementOdd) {
11327                  throw new NotFoundException();
11328              }
11329              RSSExpandedReader.increment(this.getOddCounts(), this.getOddRoundingErrors());
11330          }
11331          if (decrementOdd) {
11332              RSSExpandedReader.decrement(this.getOddCounts(), this.getOddRoundingErrors());
11333          }
11334          if (incrementEven) {
11335              if (decrementEven) {
11336                  throw new NotFoundException();
11337              }
11338              RSSExpandedReader.increment(this.getEvenCounts(), this.getOddRoundingErrors());
11339          }
11340          if (decrementEven) {
11341              RSSExpandedReader.decrement(this.getEvenCounts(), this.getEvenRoundingErrors());
11342          }
11343      }
11344  }
11345  RSSExpandedReader.SYMBOL_WIDEST = [7, 5, 4, 3, 1];
11346  RSSExpandedReader.EVEN_TOTAL_SUBSET = [4, 20, 52, 104, 204];
11347  RSSExpandedReader.GSUM = [0, 348, 1388, 2948, 3988];
11348  RSSExpandedReader.FINDER_PATTERNS = [
11349      Int32Array.from([1, 8, 4, 1]),
11350      Int32Array.from([3, 6, 4, 1]),
11351      Int32Array.from([3, 4, 6, 1]),
11352      Int32Array.from([3, 2, 8, 1]),
11353      Int32Array.from([2, 6, 5, 1]),
11354      Int32Array.from([2, 2, 9, 1]),
11355  ];
11356  RSSExpandedReader.WEIGHTS = [
11357      [1, 3, 9, 27, 81, 32, 96, 77],
11358      [20, 60, 180, 118, 143, 7, 21, 63],
11359      [189, 145, 13, 39, 117, 140, 209, 205],
11360      [193, 157, 49, 147, 19, 57, 171, 91],
11361      [62, 186, 136, 197, 169, 85, 44, 132],
11362      [185, 133, 188, 142, 4, 12, 36, 108],
11363      [113, 128, 173, 97, 80, 29, 87, 50],
11364      [150, 28, 84, 41, 123, 158, 52, 156],
11365      [46, 138, 203, 187, 139, 206, 196, 166],
11366      [76, 17, 51, 153, 37, 111, 122, 155],
11367      [43, 129, 176, 106, 107, 110, 119, 146],
11368      [16, 48, 144, 10, 30, 90, 59, 177],
11369      [109, 116, 137, 200, 178, 112, 125, 164],
11370      [70, 210, 208, 202, 184, 130, 179, 115],
11371      [134, 191, 151, 31, 93, 68, 204, 190],
11372      [148, 22, 66, 198, 172, 94, 71, 2],
11373      [6, 18, 54, 162, 64, 192, 154, 40],
11374      [120, 149, 25, 75, 14, 42, 126, 167],
11375      [79, 26, 78, 23, 69, 207, 199, 175],
11376      [103, 98, 83, 38, 114, 131, 182, 124],
11377      [161, 61, 183, 127, 170, 88, 53, 159],
11378      [55, 165, 73, 8, 24, 72, 5, 15],
11379      [45, 135, 194, 160, 58, 174, 100, 89],
11380  ];
11381  RSSExpandedReader.FINDER_PAT_A = 0;
11382  RSSExpandedReader.FINDER_PAT_B = 1;
11383  RSSExpandedReader.FINDER_PAT_C = 2;
11384  RSSExpandedReader.FINDER_PAT_D = 3;
11385  RSSExpandedReader.FINDER_PAT_E = 4;
11386  RSSExpandedReader.FINDER_PAT_F = 5;
11387  RSSExpandedReader.FINDER_PATTERN_SEQUENCES = [
11388      [RSSExpandedReader.FINDER_PAT_A, RSSExpandedReader.FINDER_PAT_A],
11389      [
11390          RSSExpandedReader.FINDER_PAT_A,
11391          RSSExpandedReader.FINDER_PAT_B,
11392          RSSExpandedReader.FINDER_PAT_B,
11393      ],
11394      [
11395          RSSExpandedReader.FINDER_PAT_A,
11396          RSSExpandedReader.FINDER_PAT_C,
11397          RSSExpandedReader.FINDER_PAT_B,
11398          RSSExpandedReader.FINDER_PAT_D,
11399      ],
11400      [
11401          RSSExpandedReader.FINDER_PAT_A,
11402          RSSExpandedReader.FINDER_PAT_E,
11403          RSSExpandedReader.FINDER_PAT_B,
11404          RSSExpandedReader.FINDER_PAT_D,
11405          RSSExpandedReader.FINDER_PAT_C,
11406      ],
11407      [
11408          RSSExpandedReader.FINDER_PAT_A,
11409          RSSExpandedReader.FINDER_PAT_E,
11410          RSSExpandedReader.FINDER_PAT_B,
11411          RSSExpandedReader.FINDER_PAT_D,
11412          RSSExpandedReader.FINDER_PAT_D,
11413          RSSExpandedReader.FINDER_PAT_F,
11414      ],
11415      [
11416          RSSExpandedReader.FINDER_PAT_A,
11417          RSSExpandedReader.FINDER_PAT_E,
11418          RSSExpandedReader.FINDER_PAT_B,
11419          RSSExpandedReader.FINDER_PAT_D,
11420          RSSExpandedReader.FINDER_PAT_E,
11421          RSSExpandedReader.FINDER_PAT_F,
11422          RSSExpandedReader.FINDER_PAT_F,
11423      ],
11424      [
11425          RSSExpandedReader.FINDER_PAT_A,
11426          RSSExpandedReader.FINDER_PAT_A,
11427          RSSExpandedReader.FINDER_PAT_B,
11428          RSSExpandedReader.FINDER_PAT_B,
11429          RSSExpandedReader.FINDER_PAT_C,
11430          RSSExpandedReader.FINDER_PAT_C,
11431          RSSExpandedReader.FINDER_PAT_D,
11432          RSSExpandedReader.FINDER_PAT_D,
11433      ],
11434      [
11435          RSSExpandedReader.FINDER_PAT_A,
11436          RSSExpandedReader.FINDER_PAT_A,
11437          RSSExpandedReader.FINDER_PAT_B,
11438          RSSExpandedReader.FINDER_PAT_B,
11439          RSSExpandedReader.FINDER_PAT_C,
11440          RSSExpandedReader.FINDER_PAT_C,
11441          RSSExpandedReader.FINDER_PAT_D,
11442          RSSExpandedReader.FINDER_PAT_E,
11443          RSSExpandedReader.FINDER_PAT_E,
11444      ],
11445      [
11446          RSSExpandedReader.FINDER_PAT_A,
11447          RSSExpandedReader.FINDER_PAT_A,
11448          RSSExpandedReader.FINDER_PAT_B,
11449          RSSExpandedReader.FINDER_PAT_B,
11450          RSSExpandedReader.FINDER_PAT_C,
11451          RSSExpandedReader.FINDER_PAT_C,
11452          RSSExpandedReader.FINDER_PAT_D,
11453          RSSExpandedReader.FINDER_PAT_E,
11454          RSSExpandedReader.FINDER_PAT_F,
11455          RSSExpandedReader.FINDER_PAT_F,
11456      ],
11457      [
11458          RSSExpandedReader.FINDER_PAT_A,
11459          RSSExpandedReader.FINDER_PAT_A,
11460          RSSExpandedReader.FINDER_PAT_B,
11461          RSSExpandedReader.FINDER_PAT_B,
11462          RSSExpandedReader.FINDER_PAT_C,
11463          RSSExpandedReader.FINDER_PAT_D,
11464          RSSExpandedReader.FINDER_PAT_D,
11465          RSSExpandedReader.FINDER_PAT_E,
11466          RSSExpandedReader.FINDER_PAT_E,
11467          RSSExpandedReader.FINDER_PAT_F,
11468          RSSExpandedReader.FINDER_PAT_F,
11469      ],
11470  ];
11471  RSSExpandedReader.MAX_PAIRS = 11;
11472
11473  class Pair extends DataCharacter {
11474      constructor(value, checksumPortion, finderPattern) {
11475          super(value, checksumPortion);
11476          this.count = 0;
11477          this.finderPattern = finderPattern;
11478      }
11479      getFinderPattern() {
11480          return this.finderPattern;
11481      }
11482      getCount() {
11483          return this.count;
11484      }
11485      incrementCount() {
11486          this.count++;
11487      }
11488  }
11489
11490  class RSS14Reader extends AbstractRSSReader {
11491      constructor() {
11492          super(...arguments);
11493          this.possibleLeftPairs = [];
11494          this.possibleRightPairs = [];
11495      }
11496      decodeRow(rowNumber, row, hints) {
11497          const leftPair = this.decodePair(row, false, rowNumber, hints);
11498          RSS14Reader.addOrTally(this.possibleLeftPairs, leftPair);
11499          row.reverse();
11500          let rightPair = this.decodePair(row, true, rowNumber, hints);
11501          RSS14Reader.addOrTally(this.possibleRightPairs, rightPair);
11502          row.reverse();
11503          for (let left of this.possibleLeftPairs) {
11504              if (left.getCount() > 1) {
11505                  for (let right of this.possibleRightPairs) {
11506                      if (right.getCount() > 1 && RSS14Reader.checkChecksum(left, right)) {
11507                          return RSS14Reader.constructResult(left, right);
11508                      }
11509                  }
11510              }
11511          }
11512          throw new NotFoundException();
11513      }
11514      static addOrTally(possiblePairs, pair) {
11515          if (pair == null) {
11516              return;
11517          }
11518          let found = false;
11519          for (let other of possiblePairs) {
11520              if (other.getValue() === pair.getValue()) {
11521                  other.incrementCount();
11522                  found = true;
11523                  break;
11524              }
11525          }
11526          if (!found) {
11527              possiblePairs.push(pair);
11528          }
11529      }
11530      reset() {
11531          this.possibleLeftPairs.length = 0;
11532          this.possibleRightPairs.length = 0;
11533      }
11534      static constructResult(leftPair, rightPair) {
11535          let symbolValue = 4537077 * leftPair.getValue() + rightPair.getValue();
11536          let text = new String(symbolValue).toString();
11537          let buffer = new StringBuilder();
11538          for (let i = 13 - text.length; i > 0; i--) {
11539              buffer.append('0');
11540          }
11541          buffer.append(text);
11542          let checkDigit = 0;
11543          for (let i = 0; i < 13; i++) {
11544              let digit = buffer.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
11545              checkDigit += ((i & 0x01) === 0) ? 3 * digit : digit;
11546          }
11547          checkDigit = 10 - (checkDigit % 10);
11548          if (checkDigit === 10) {
11549              checkDigit = 0;
11550          }
11551          buffer.append(checkDigit.toString());
11552          let leftPoints = leftPair.getFinderPattern().getResultPoints();
11553          let rightPoints = rightPair.getFinderPattern().getResultPoints();
11554          return new Result$1(buffer.toString(), null, 0, [leftPoints[0], leftPoints[1], rightPoints[0], rightPoints[1]], BarcodeFormat$1.RSS_14, new Date().getTime());
11555      }
11556      static checkChecksum(leftPair, rightPair) {
11557          let checkValue = (leftPair.getChecksumPortion() + 16 * rightPair.getChecksumPortion()) % 79;
11558          let targetCheckValue = 9 * leftPair.getFinderPattern().getValue() + rightPair.getFinderPattern().getValue();
11559          if (targetCheckValue > 72) {
11560              targetCheckValue--;
11561          }
11562          if (targetCheckValue > 8) {
11563              targetCheckValue--;
11564          }
11565          return checkValue === targetCheckValue;
11566      }
11567      decodePair(row, right, rowNumber, hints) {
11568          try {
11569              let startEnd = this.findFinderPattern(row, right);
11570              let pattern = this.parseFoundFinderPattern(row, rowNumber, right, startEnd);
11571              let resultPointCallback = hints == null ? null : hints.get(DecodeHintType$1.NEED_RESULT_POINT_CALLBACK);
11572              if (resultPointCallback != null) {
11573                  let center = (startEnd[0] + startEnd[1]) / 2.0;
11574                  if (right) {
11575                      // row is actually reversed
11576                      center = row.getSize() - 1 - center;
11577                  }
11578                  resultPointCallback.foundPossibleResultPoint(new ResultPoint(center, rowNumber));
11579              }
11580              let outside = this.decodeDataCharacter(row, pattern, true);
11581              let inside = this.decodeDataCharacter(row, pattern, false);
11582              return new Pair(1597 * outside.getValue() + inside.getValue(), outside.getChecksumPortion() + 4 * inside.getChecksumPortion(), pattern);
11583          }
11584          catch (err) {
11585              return null;
11586          }
11587      }
11588      decodeDataCharacter(row, pattern, outsideChar) {
11589          let counters = this.getDataCharacterCounters();
11590          for (let x = 0; x < counters.length; x++) {
11591              counters[x] = 0;
11592          }
11593          if (outsideChar) {
11594              OneDReader.recordPatternInReverse(row, pattern.getStartEnd()[0], counters);
11595          }
11596          else {
11597              OneDReader.recordPattern(row, pattern.getStartEnd()[1] + 1, counters);
11598              // reverse it
11599              for (let i = 0, j = counters.length - 1; i < j; i++, j--) {
11600                  let temp = counters[i];
11601                  counters[i] = counters[j];
11602                  counters[j] = temp;
11603              }
11604          }
11605          let numModules = outsideChar ? 16 : 15;
11606          let elementWidth = MathUtils.sum(new Int32Array(counters)) / numModules;
11607          let oddCounts = this.getOddCounts();
11608          let evenCounts = this.getEvenCounts();
11609          let oddRoundingErrors = this.getOddRoundingErrors();
11610          let evenRoundingErrors = this.getEvenRoundingErrors();
11611          for (let i = 0; i < counters.length; i++) {
11612              let value = counters[i] / elementWidth;
11613              let count = Math.floor(value + 0.5);
11614              if (count < 1) {
11615                  count = 1;
11616              }
11617              else if (count > 8) {
11618                  count = 8;
11619              }
11620              let offset = Math.floor(i / 2);
11621              if ((i & 0x01) === 0) {
11622                  oddCounts[offset] = count;
11623                  oddRoundingErrors[offset] = value - count;
11624              }
11625              else {
11626                  evenCounts[offset] = count;
11627                  evenRoundingErrors[offset] = value - count;
11628              }
11629          }
11630          this.adjustOddEvenCounts(outsideChar, numModules);
11631          let oddSum = 0;
11632          let oddChecksumPortion = 0;
11633          for (let i = oddCounts.length - 1; i >= 0; i--) {
11634              oddChecksumPortion *= 9;
11635              oddChecksumPortion += oddCounts[i];
11636              oddSum += oddCounts[i];
11637          }
11638          let evenChecksumPortion = 0;
11639          let evenSum = 0;
11640          for (let i = evenCounts.length - 1; i >= 0; i--) {
11641              evenChecksumPortion *= 9;
11642              evenChecksumPortion += evenCounts[i];
11643              evenSum += evenCounts[i];
11644          }
11645          let checksumPortion = oddChecksumPortion + 3 * evenChecksumPortion;
11646          if (outsideChar) {
11647              if ((oddSum & 0x01) !== 0 || oddSum > 12 || oddSum < 4) {
11648                  throw new NotFoundException();
11649              }
11650              let group = (12 - oddSum) / 2;
11651              let oddWidest = RSS14Reader.OUTSIDE_ODD_WIDEST[group];
11652              let evenWidest = 9 - oddWidest;
11653              let vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, false);
11654              let vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, true);
11655              let tEven = RSS14Reader.OUTSIDE_EVEN_TOTAL_SUBSET[group];
11656              let gSum = RSS14Reader.OUTSIDE_GSUM[group];
11657              return new DataCharacter(vOdd * tEven + vEven + gSum, checksumPortion);
11658          }
11659          else {
11660              if ((evenSum & 0x01) !== 0 || evenSum > 10 || evenSum < 4) {
11661                  throw new NotFoundException();
11662              }
11663              let group = (10 - evenSum) / 2;
11664              let oddWidest = RSS14Reader.INSIDE_ODD_WIDEST[group];
11665              let evenWidest = 9 - oddWidest;
11666              let vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
11667              let vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
11668              let tOdd = RSS14Reader.INSIDE_ODD_TOTAL_SUBSET[group];
11669              let gSum = RSS14Reader.INSIDE_GSUM[group];
11670              return new DataCharacter(vEven * tOdd + vOdd + gSum, checksumPortion);
11671          }
11672      }
11673      findFinderPattern(row, rightFinderPattern) {
11674          let counters = this.getDecodeFinderCounters();
11675          counters[0] = 0;
11676          counters[1] = 0;
11677          counters[2] = 0;
11678          counters[3] = 0;
11679          let width = row.getSize();
11680          let isWhite = false;
vendor: 18,521 bytes, lines 11681-12134
11681          let rowOffset = 0;
11682          while (rowOffset < width) {
11683              isWhite = !row.get(rowOffset);
11684              if (rightFinderPattern === isWhite) {
11685                  // Will encounter white first when searching for right finder pattern
11686                  break;
11687              }
11688              rowOffset++;
11689          }
11690          let counterPosition = 0;
11691          let patternStart = rowOffset;
11692          for (let x = rowOffset; x < width; x++) {
11693              if (row.get(x) !== isWhite) {
11694                  counters[counterPosition]++;
11695              }
11696              else {
11697                  if (counterPosition === 3) {
11698                      if (AbstractRSSReader.isFinderPattern(counters)) {
11699                          return [patternStart, x];
11700                      }
11701                      patternStart += counters[0] + counters[1];
11702                      counters[0] = counters[2];
11703                      counters[1] = counters[3];
11704                      counters[2] = 0;
11705                      counters[3] = 0;
11706                      counterPosition--;
11707                  }
11708                  else {
11709                      counterPosition++;
11710                  }
11711                  counters[counterPosition] = 1;
11712                  isWhite = !isWhite;
11713              }
11714          }
11715          throw new NotFoundException();
11716      }
11717      parseFoundFinderPattern(row, rowNumber, right, startEnd) {
11718          // Actually we found elements 2-5
11719          let firstIsBlack = row.get(startEnd[0]);
11720          let firstElementStart = startEnd[0] - 1;
11721          // Locate element 1
11722          while (firstElementStart >= 0 && firstIsBlack !== row.get(firstElementStart)) {
11723              firstElementStart--;
11724          }
11725          firstElementStart++;
11726          const firstCounter = startEnd[0] - firstElementStart;
11727          // Make 'counters' hold 1-4
11728          const counters = this.getDecodeFinderCounters();
11729          const copy = new Int32Array(counters.length);
11730          System.arraycopy(counters, 0, copy, 1, counters.length - 1);
11731          copy[0] = firstCounter;
11732          const value = this.parseFinderValue(copy, RSS14Reader.FINDER_PATTERNS);
11733          let start = firstElementStart;
11734          let end = startEnd[1];
11735          if (right) {
11736              // row is actually reversed
11737              start = row.getSize() - 1 - start;
11738              end = row.getSize() - 1 - end;
11739          }
11740          return new FinderPattern$1(value, [firstElementStart, startEnd[1]], start, end, rowNumber);
11741      }
11742      adjustOddEvenCounts(outsideChar, numModules) {
11743          let oddSum = MathUtils.sum(new Int32Array(this.getOddCounts()));
11744          let evenSum = MathUtils.sum(new Int32Array(this.getEvenCounts()));
11745          let incrementOdd = false;
11746          let decrementOdd = false;
11747          let incrementEven = false;
11748          let decrementEven = false;
11749          if (outsideChar) {
11750              if (oddSum > 12) {
11751                  decrementOdd = true;
11752              }
11753              else if (oddSum < 4) {
11754                  incrementOdd = true;
11755              }
11756              if (evenSum > 12) {
11757                  decrementEven = true;
11758              }
11759              else if (evenSum < 4) {
11760                  incrementEven = true;
11761              }
11762          }
11763          else {
11764              if (oddSum > 11) {
11765                  decrementOdd = true;
11766              }
11767              else if (oddSum < 5) {
11768                  incrementOdd = true;
11769              }
11770              if (evenSum > 10) {
11771                  decrementEven = true;
11772              }
11773              else if (evenSum < 4) {
11774                  incrementEven = true;
11775              }
11776          }
11777          let mismatch = oddSum + evenSum - numModules;
11778          let oddParityBad = (oddSum & 0x01) === (outsideChar ? 1 : 0);
11779          let evenParityBad = (evenSum & 0x01) === 1;
11780          if (mismatch === 1) {
11781              if (oddParityBad) {
11782                  if (evenParityBad) {
11783                      throw new NotFoundException();
11784                  }
11785                  decrementOdd = true;
11786              }
11787              else {
11788                  if (!evenParityBad) {
11789                      throw new NotFoundException();
11790                  }
11791                  decrementEven = true;
11792              }
11793          }
11794          else if (mismatch === -1) {
11795              if (oddParityBad) {
11796                  if (evenParityBad) {
11797                      throw new NotFoundException();
11798                  }
11799                  incrementOdd = true;
11800              }
11801              else {
11802                  if (!evenParityBad) {
11803                      throw new NotFoundException();
11804                  }
11805                  incrementEven = true;
11806              }
11807          }
11808          else if (mismatch === 0) {
11809              if (oddParityBad) {
11810                  if (!evenParityBad) {
11811                      throw new NotFoundException();
11812                  }
11813                  // Both bad
11814                  if (oddSum < evenSum) {
11815                      incrementOdd = true;
11816                      decrementEven = true;
11817                  }
11818                  else {
11819                      decrementOdd = true;
11820                      incrementEven = true;
11821                  }
11822              }
11823              else {
11824                  if (evenParityBad) {
11825                      throw new NotFoundException();
11826                  }
11827                  // Nothing to do!
11828              }
11829          }
11830          else {
11831              throw new NotFoundException();
11832          }
11833          if (incrementOdd) {
11834              if (decrementOdd) {
11835                  throw new NotFoundException();
11836              }
11837              AbstractRSSReader.increment(this.getOddCounts(), this.getOddRoundingErrors());
11838          }
11839          if (decrementOdd) {
11840              AbstractRSSReader.decrement(this.getOddCounts(), this.getOddRoundingErrors());
11841          }
11842          if (incrementEven) {
11843              if (decrementEven) {
11844                  throw new NotFoundException();
11845              }
11846              AbstractRSSReader.increment(this.getEvenCounts(), this.getOddRoundingErrors());
11847          }
11848          if (decrementEven) {
11849              AbstractRSSReader.decrement(this.getEvenCounts(), this.getEvenRoundingErrors());
11850          }
11851      }
11852  }
11853  RSS14Reader.OUTSIDE_EVEN_TOTAL_SUBSET = [1, 10, 34, 70, 126];
11854  RSS14Reader.INSIDE_ODD_TOTAL_SUBSET = [4, 20, 48, 81];
11855  RSS14Reader.OUTSIDE_GSUM = [0, 161, 961, 2015, 2715];
11856  RSS14Reader.INSIDE_GSUM = [0, 336, 1036, 1516];
11857  RSS14Reader.OUTSIDE_ODD_WIDEST = [8, 6, 4, 3, 1];
11858  RSS14Reader.INSIDE_ODD_WIDEST = [2, 4, 6, 8];
11859  RSS14Reader.FINDER_PATTERNS = [
11860      Int32Array.from([3, 8, 2, 1]),
11861      Int32Array.from([3, 5, 5, 1]),
11862      Int32Array.from([3, 3, 7, 1]),
11863      Int32Array.from([3, 1, 9, 1]),
11864      Int32Array.from([2, 7, 4, 1]),
11865      Int32Array.from([2, 5, 6, 1]),
11866      Int32Array.from([2, 3, 8, 1]),
11867      Int32Array.from([1, 5, 7, 1]),
11868      Int32Array.from([1, 3, 9, 1]),
11869  ];
11870
11871  /*
11872   * Copyright 2008 ZXing authors
11873   *
11874   * Licensed under the Apache License, Version 2.0 (the "License");
11875   * you may not use this file except in compliance with the License.
11876   * You may obtain a copy of the License at
11877   *
11878   *      http://www.apache.org/licenses/LICENSE-2.0
11879   *
11880   * Unless required by applicable law or agreed to in writing, software
11881   * distributed under the License is distributed on an "AS IS" BASIS,
11882   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11883   * See the License for the specific language governing permissions and
11884   * limitations under the License.
11885   */
11886  /**
11887   * @author Daniel Switkin <[email protected]>
11888   * @author Sean Owen
11889   */
11890  class MultiFormatOneDReader extends OneDReader {
11891      constructor(hints) {
11892          super();
11893          this.readers = [];
11894          const possibleFormats = !hints ? null : hints.get(DecodeHintType$1.POSSIBLE_FORMATS);
11895          const useCode39CheckDigit = hints && hints.get(DecodeHintType$1.ASSUME_CODE_39_CHECK_DIGIT) !== undefined;
11896          const useCode39ExtendedMode = hints && hints.get(DecodeHintType$1.ENABLE_CODE_39_EXTENDED_MODE) !== undefined;
11897          if (possibleFormats) {
11898              if (possibleFormats.includes(BarcodeFormat$1.EAN_13) ||
11899                  possibleFormats.includes(BarcodeFormat$1.UPC_A) ||
11900                  possibleFormats.includes(BarcodeFormat$1.EAN_8) ||
11901                  possibleFormats.includes(BarcodeFormat$1.UPC_E)) {
11902                  this.readers.push(new MultiFormatUPCEANReader(hints));
11903              }
11904              if (possibleFormats.includes(BarcodeFormat$1.CODE_39)) {
11905                  this.readers.push(new Code39Reader(useCode39CheckDigit, useCode39ExtendedMode));
11906              }
11907              if (possibleFormats.includes(BarcodeFormat$1.CODE_93)) {
11908                  this.readers.push(new Code93Reader());
11909              }
11910              if (possibleFormats.includes(BarcodeFormat$1.CODE_128)) {
11911                  this.readers.push(new Code128Reader());
11912              }
11913              if (possibleFormats.includes(BarcodeFormat$1.ITF)) {
11914                  this.readers.push(new ITFReader());
11915              }
11916              if (possibleFormats.includes(BarcodeFormat$1.CODABAR)) {
11917                  this.readers.push(new CodaBarReader());
11918              }
11919              if (possibleFormats.includes(BarcodeFormat$1.RSS_14)) {
11920                  this.readers.push(new RSS14Reader());
11921              }
11922              if (possibleFormats.includes(BarcodeFormat$1.RSS_EXPANDED)) {
11923                  console.warn('RSS Expanded reader IS NOT ready for production yet! use at your own risk.');
11924                  this.readers.push(new RSSExpandedReader());
11925              }
11926          }
11927          if (this.readers.length === 0) {
11928              this.readers.push(new MultiFormatUPCEANReader(hints));
11929              this.readers.push(new Code39Reader());
11930              // this.readers.push(new CodaBarReader());
11931              this.readers.push(new Code93Reader());
11932              this.readers.push(new MultiFormatUPCEANReader(hints));
11933              this.readers.push(new Code128Reader());
11934              this.readers.push(new ITFReader());
11935              this.readers.push(new RSS14Reader());
11936              // this.readers.push(new RSSExpandedReader());
11937          }
11938      }
11939      // @Override
11940      decodeRow(rowNumber, row, hints) {
11941          for (let i = 0; i < this.readers.length; i++) {
11942              try {
11943                  return this.readers[i].decodeRow(rowNumber, row, hints);
11944              }
11945              catch (re) {
11946                  // continue
11947              }
11948          }
11949          throw new NotFoundException();
11950      }
11951      // @Override
11952      reset() {
11953          this.readers.forEach(reader => reader.reset());
11954      }
11955  }
11956
11957  /**
11958   * @deprecated Moving to @zxing/browser
11959   *
11960   * Barcode reader reader to use from browser.
11961   */
11962  class BrowserBarcodeReader extends BrowserCodeReader {
11963      /**
11964       * Creates an instance of BrowserBarcodeReader.
11965       * @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
11966       * @param {Map<DecodeHintType, any>} hints
11967       */
11968      constructor(timeBetweenScansMillis = 500, hints) {
11969          super(new MultiFormatOneDReader(hints), timeBetweenScansMillis, hints);
11970      }
11971  }
11972
11973  /*
11974   * Copyright 2007 ZXing authors
11975   *
11976   * Licensed under the Apache License, Version 2.0 (the "License");
11977   * you may not use this file except in compliance with the License.
11978   * You may obtain a copy of the License at
11979   *
11980   *      http://www.apache.org/licenses/LICENSE-2.0
11981   *
11982   * Unless required by applicable law or agreed to in writing, software
11983   * distributed under the License is distributed on an "AS IS" BASIS,
11984   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11985   * See the License for the specific language governing permissions and
11986   * limitations under the License.
11987   */
11988  /**
11989   * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will
11990   * use blocks of differing sizes within one version, so, this encapsulates the parameters for
11991   * each set of blocks. It also holds the number of error-correction codewords per block since it
11992   * will be the same across all blocks within one version.</p>
11993   */
11994  class ECBlocks$1 {
11995      constructor(ecCodewords, ecBlocks1, ecBlocks2) {
11996          this.ecCodewords = ecCodewords;
11997          this.ecBlocks = [ecBlocks1];
11998          ecBlocks2 && this.ecBlocks.push(ecBlocks2);
11999      }
12000      getECCodewords() {
12001          return this.ecCodewords;
12002      }
12003      getECBlocks() {
12004          return this.ecBlocks;
12005      }
12006  }
12007  /**
12008   * <p>Encapsulates the parameters for one error-correction block in one symbol version.
12009   * This includes the number of data codewords, and the number of times a block with these
12010   * parameters is used consecutively in the Data Matrix code version's format.</p>
12011   */
12012  class ECB$1 {
12013      constructor(count, dataCodewords) {
12014          this.count = count;
12015          this.dataCodewords = dataCodewords;
12016      }
12017      getCount() {
12018          return this.count;
12019      }
12020      getDataCodewords() {
12021          return this.dataCodewords;
12022      }
12023  }
12024  /**
12025   * The Version object encapsulates attributes about a particular
12026   * size Data Matrix Code.
12027   *
12028   * @author [email protected] (Brian Brown)
12029   */
12030  class Version$1 {
12031      constructor(versionNumber, symbolSizeRows, symbolSizeColumns, dataRegionSizeRows, dataRegionSizeColumns, ecBlocks) {
12032          this.versionNumber = versionNumber;
12033          this.symbolSizeRows = symbolSizeRows;
12034          this.symbolSizeColumns = symbolSizeColumns;
12035          this.dataRegionSizeRows = dataRegionSizeRows;
12036          this.dataRegionSizeColumns = dataRegionSizeColumns;
12037          this.ecBlocks = ecBlocks;
12038          // Calculate the total number of codewords
12039          let total = 0;
12040          const ecCodewords = ecBlocks.getECCodewords();
12041          const ecbArray = ecBlocks.getECBlocks();
12042          for (let ecBlock of ecbArray) {
12043              total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);
12044          }
12045          this.totalCodewords = total;
12046      }
12047      getVersionNumber() {
12048          return this.versionNumber;
12049      }
12050      getSymbolSizeRows() {
12051          return this.symbolSizeRows;
12052      }
12053      getSymbolSizeColumns() {
12054          return this.symbolSizeColumns;
12055      }
12056      getDataRegionSizeRows() {
12057          return this.dataRegionSizeRows;
12058      }
12059      getDataRegionSizeColumns() {
12060          return this.dataRegionSizeColumns;
12061      }
12062      getTotalCodewords() {
12063          return this.totalCodewords;
12064      }
12065      getECBlocks() {
12066          return this.ecBlocks;
12067      }
12068      /**
12069       * <p>Deduces version information from Data Matrix dimensions.</p>
12070       *
12071       * @param numRows Number of rows in modules
12072       * @param numColumns Number of columns in modules
12073       * @return Version for a Data Matrix Code of those dimensions
12074       * @throws FormatException if dimensions do correspond to a valid Data Matrix size
12075       */
12076      static getVersionForDimensions(numRows, numColumns) {
12077          if ((numRows & 0x01) !== 0 || (numColumns & 0x01) !== 0) {
12078              throw new FormatException();
12079          }
12080          for (let version of Version$1.VERSIONS) {
12081              if (version.symbolSizeRows === numRows && version.symbolSizeColumns === numColumns) {
12082                  return version;
12083              }
12084          }
12085          throw new FormatException();
12086      }
12087      //  @Override
12088      toString() {
12089          return '' + this.versionNumber;
12090      }
12091      /**
12092       * See ISO 16022:2006 5.5.1 Table 7
12093       */
12094      static buildVersions() {
12095          return [
12096              new Version$1(1, 10, 10, 8, 8, new ECBlocks$1(5, new ECB$1(1, 3))),
12097              new Version$1(2, 12, 12, 10, 10, new ECBlocks$1(7, new ECB$1(1, 5))),
12098              new Version$1(3, 14, 14, 12, 12, new ECBlocks$1(10, new ECB$1(1, 8))),
12099              new Version$1(4, 16, 16, 14, 14, new ECBlocks$1(12, new ECB$1(1, 12))),
12100              new Version$1(5, 18, 18, 16, 16, new ECBlocks$1(14, new ECB$1(1, 18))),
12101              new Version$1(6, 20, 20, 18, 18, new ECBlocks$1(18, new ECB$1(1, 22))),
12102              new Version$1(7, 22, 22, 20, 20, new ECBlocks$1(20, new ECB$1(1, 30))),
12103              new Version$1(8, 24, 24, 22, 22, new ECBlocks$1(24, new ECB$1(1, 36))),
12104              new Version$1(9, 26, 26, 24, 24, new ECBlocks$1(28, new ECB$1(1, 44))),
12105              new Version$1(10, 32, 32, 14, 14, new ECBlocks$1(36, new ECB$1(1, 62))),
12106              new Version$1(11, 36, 36, 16, 16, new ECBlocks$1(42, new ECB$1(1, 86))),
12107              new Version$1(12, 40, 40, 18, 18, new ECBlocks$1(48, new ECB$1(1, 114))),
12108              new Version$1(13, 44, 44, 20, 20, new ECBlocks$1(56, new ECB$1(1, 144))),
12109              new Version$1(14, 48, 48, 22, 22, new ECBlocks$1(68, new ECB$1(1, 174))),
12110              new Version$1(15, 52, 52, 24, 24, new ECBlocks$1(42, new ECB$1(2, 102))),
12111              new Version$1(16, 64, 64, 14, 14, new ECBlocks$1(56, new ECB$1(2, 140))),
12112              new Version$1(17, 72, 72, 16, 16, new ECBlocks$1(36, new ECB$1(4, 92))),
12113              new Version$1(18, 80, 80, 18, 18, new ECBlocks$1(48, new ECB$1(4, 114))),
12114              new Version$1(19, 88, 88, 20, 20, new ECBlocks$1(56, new ECB$1(4, 144))),
12115              new Version$1(20, 96, 96, 22, 22, new ECBlocks$1(68, new ECB$1(4, 174))),
12116              new Version$1(21, 104, 104, 24, 24, new ECBlocks$1(56, new ECB$1(6, 136))),
12117              new Version$1(22, 120, 120, 18, 18, new ECBlocks$1(68, new ECB$1(6, 175))),
12118              new Version$1(23, 132, 132, 20, 20, new ECBlocks$1(62, new ECB$1(8, 163))),
12119              new Version$1(24, 144, 144, 22, 22, new ECBlocks$1(62, new ECB$1(8, 156), new ECB$1(2, 155))),
12120              new Version$1(25, 8, 18, 6, 16, new ECBlocks$1(7, new ECB$1(1, 5))),
12121              new Version$1(26, 8, 32, 6, 14, new ECBlocks$1(11, new ECB$1(1, 10))),
12122              new Version$1(27, 12, 26, 10, 24, new ECBlocks$1(14, new ECB$1(1, 16))),
12123              new Version$1(28, 12, 36, 10, 16, new ECBlocks$1(18, new ECB$1(1, 22))),
12124              new Version$1(29, 16, 36, 14, 16, new ECBlocks$1(24, new ECB$1(1, 32))),
12125              new Version$1(30, 16, 48, 14, 22, new ECBlocks$1(28, new ECB$1(1, 49)))
12126          ];
12127      }
12128  }
12129  Version$1.VERSIONS = Version$1.buildVersions();
12130
12131  /*
12132   * Copyright 2007 ZXing authors
12133   *
12134   * Licensed under the Apache License, Version 2.0 (the "License");
12135   * you may not use this file except in compliance with the License.
12136   * You may obtain a copy of the License at
12137   *
12138   *      http://www.apache.org/licenses/LICENSE-2.0
12139   *
12140   * Unless required by applicable law or agreed to in writing, software
12141   * distributed under the License is distributed on an "AS IS" BASIS,
12142   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12143   * See the License for the specific language governing permissions and
12144   * limitations under the License.
12145   */
12146  /**
12147   * @author [email protected] (Brian Brown)
12148   */
12149  class BitMatrixParser$1 {
12150      /**
12151       * @param bitMatrix {@link BitMatrix} to parse
12152       * @throws FormatException if dimension is < 8 or > 144 or not 0 mod 2
12153       */
12154      constructor(bitMatrix) {
12155          const dimension = bitMatrix.getHeight();
12156          if (dimension < 8 || dimension > 144 || (dimension & 0x01) !== 0) {
12157              throw new FormatException();
12158          }
12159          this.version = BitMatrixParser$1
vendor: 15,862 bytes, lines 12159-12539
12159.readVersion(bitMatrix);
12160          this.mappingBitMatrix = this.extractDataRegion(bitMatrix);
12161          this.readMappingMatrix = new BitMatrix(this.mappingBitMatrix.getWidth(), this.mappingBitMatrix.getHeight());
12162      }
12163      getVersion() {
12164          return this.version;
12165      }
12166      /**
12167       * <p>Creates the version object based on the dimension of the original bit matrix from
12168       * the datamatrix code.</p>
12169       *
12170       * <p>See ISO 16022:2006 Table 7 - ECC 200 symbol attributes</p>
12171       *
12172       * @param bitMatrix Original {@link BitMatrix} including alignment patterns
12173       * @return {@link Version} encapsulating the Data Matrix Code's "version"
12174       * @throws FormatException if the dimensions of the mapping matrix are not valid
12175       * Data Matrix dimensions.
12176       */
12177      static readVersion(bitMatrix) {
12178          const numRows = bitMatrix.getHeight();
12179          const numColumns = bitMatrix.getWidth();
12180          return Version$1.getVersionForDimensions(numRows, numColumns);
12181      }
12182      /**
12183       * <p>Reads the bits in the {@link BitMatrix} representing the mapping matrix (No alignment patterns)
12184       * in the correct order in order to reconstitute the codewords bytes contained within the
12185       * Data Matrix Code.</p>
12186       *
12187       * @return bytes encoded within the Data Matrix Code
12188       * @throws FormatException if the exact number of bytes expected is not read
12189       */
12190      readCodewords() {
12191          const result = new Int8Array(this.version.getTotalCodewords());
12192          let resultOffset = 0;
12193          let row = 4;
12194          let column = 0;
12195          const numRows = this.mappingBitMatrix.getHeight();
12196          const numColumns = this.mappingBitMatrix.getWidth();
12197          let corner1Read = false;
12198          let corner2Read = false;
12199          let corner3Read = false;
12200          let corner4Read = false;
12201          // Read all of the codewords
12202          do {
12203              // Check the four corner cases
12204              if ((row === numRows) && (column === 0) && !corner1Read) {
12205                  result[resultOffset++] = this.readCorner1(numRows, numColumns) & 0xff;
12206                  row -= 2;
12207                  column += 2;
12208                  corner1Read = true;
12209              }
12210              else if ((row === numRows - 2) && (column === 0) && ((numColumns & 0x03) !== 0) && !corner2Read) {
12211                  result[resultOffset++] = this.readCorner2(numRows, numColumns) & 0xff;
12212                  row -= 2;
12213                  column += 2;
12214                  corner2Read = true;
12215              }
12216              else if ((row === numRows + 4) && (column === 2) && ((numColumns & 0x07) === 0) && !corner3Read) {
12217                  result[resultOffset++] = this.readCorner3(numRows, numColumns) & 0xff;
12218                  row -= 2;
12219                  column += 2;
12220                  corner3Read = true;
12221              }
12222              else if ((row === numRows - 2) && (column === 0) && ((numColumns & 0x07) === 4) && !corner4Read) {
12223                  result[resultOffset++] = this.readCorner4(numRows, numColumns) & 0xff;
12224                  row -= 2;
12225                  column += 2;
12226                  corner4Read = true;
12227              }
12228              else {
12229                  // Sweep upward diagonally to the right
12230                  do {
12231                      if ((row < numRows) && (column >= 0) && !this.readMappingMatrix.get(column, row)) {
12232                          result[resultOffset++] = this.readUtah(row, column, numRows, numColumns) & 0xff;
12233                      }
12234                      row -= 2;
12235                      column += 2;
12236                  } while ((row >= 0) && (column < numColumns));
12237                  row += 1;
12238                  column += 3;
12239                  // Sweep downward diagonally to the left
12240                  do {
12241                      if ((row >= 0) && (column < numColumns) && !this.readMappingMatrix.get(column, row)) {
12242                          result[resultOffset++] = this.readUtah(row, column, numRows, numColumns) & 0xff;
12243                      }
12244                      row += 2;
12245                      column -= 2;
12246                  } while ((row < numRows) && (column >= 0));
12247                  row += 3;
12248                  column += 1;
12249              }
12250          } while ((row < numRows) || (column < numColumns));
12251          if (resultOffset !== this.version.getTotalCodewords()) {
12252              throw new FormatException();
12253          }
12254          return result;
12255      }
12256      /**
12257       * <p>Reads a bit of the mapping matrix accounting for boundary wrapping.</p>
12258       *
12259       * @param row Row to read in the mapping matrix
12260       * @param column Column to read in the mapping matrix
12261       * @param numRows Number of rows in the mapping matrix
12262       * @param numColumns Number of columns in the mapping matrix
12263       * @return value of the given bit in the mapping matrix
12264       */
12265      readModule(row, column, numRows, numColumns) {
12266          // Adjust the row and column indices based on boundary wrapping
12267          if (row < 0) {
12268              row += numRows;
12269              column += 4 - ((numRows + 4) & 0x07);
12270          }
12271          if (column < 0) {
12272              column += numColumns;
12273              row += 4 - ((numColumns + 4) & 0x07);
12274          }
12275          this.readMappingMatrix.set(column, row);
12276          return this.mappingBitMatrix.get(column, row);
12277      }
12278      /**
12279       * <p>Reads the 8 bits of the standard Utah-shaped pattern.</p>
12280       *
12281       * <p>See ISO 16022:2006, 5.8.1 Figure 6</p>
12282       *
12283       * @param row Current row in the mapping matrix, anchored at the 8th bit (LSB) of the pattern
12284       * @param column Current column in the mapping matrix, anchored at the 8th bit (LSB) of the pattern
12285       * @param numRows Number of rows in the mapping matrix
12286       * @param numColumns Number of columns in the mapping matrix
12287       * @return byte from the utah shape
12288       */
12289      readUtah(row, column, numRows, numColumns) {
12290          let currentByte = 0;
12291          if (this.readModule(row - 2, column - 2, numRows, numColumns)) {
12292              currentByte |= 1;
12293          }
12294          currentByte <<= 1;
12295          if (this.readModule(row - 2, column - 1, numRows, numColumns)) {
12296              currentByte |= 1;
12297          }
12298          currentByte <<= 1;
12299          if (this.readModule(row - 1, column - 2, numRows, numColumns)) {
12300              currentByte |= 1;
12301          }
12302          currentByte <<= 1;
12303          if (this.readModule(row - 1, column - 1, numRows, numColumns)) {
12304              currentByte |= 1;
12305          }
12306          currentByte <<= 1;
12307          if (this.readModule(row - 1, column, numRows, numColumns)) {
12308              currentByte |= 1;
12309          }
12310          currentByte <<= 1;
12311          if (this.readModule(row, column - 2, numRows, numColumns)) {
12312              currentByte |= 1;
12313          }
12314          currentByte <<= 1;
12315          if (this.readModule(row, column - 1, numRows, numColumns)) {
12316              currentByte |= 1;
12317          }
12318          currentByte <<= 1;
12319          if (this.readModule(row, column, numRows, numColumns)) {
12320              currentByte |= 1;
12321          }
12322          return currentByte;
12323      }
12324      /**
12325       * <p>Reads the 8 bits of the special corner condition 1.</p>
12326       *
12327       * <p>See ISO 16022:2006, Figure F.3</p>
12328       *
12329       * @param numRows Number of rows in the mapping matrix
12330       * @param numColumns Number of columns in the mapping matrix
12331       * @return byte from the Corner condition 1
12332       */
12333      readCorner1(numRows, numColumns) {
12334          let currentByte = 0;
12335          if (this.readModule(numRows - 1, 0, numRows, numColumns)) {
12336              currentByte |= 1;
12337          }
12338          currentByte <<= 1;
12339          if (this.readModule(numRows - 1, 1, numRows, numColumns)) {
12340              currentByte |= 1;
12341          }
12342          currentByte <<= 1;
12343          if (this.readModule(numRows - 1, 2, numRows, numColumns)) {
12344              currentByte |= 1;
12345          }
12346          currentByte <<= 1;
12347          if (this.readModule(0, numColumns - 2, numRows, numColumns)) {
12348              currentByte |= 1;
12349          }
12350          currentByte <<= 1;
12351          if (this.readModule(0, numColumns - 1, numRows, numColumns)) {
12352              currentByte |= 1;
12353          }
12354          currentByte <<= 1;
12355          if (this.readModule(1, numColumns - 1, numRows, numColumns)) {
12356              currentByte |= 1;
12357          }
12358          currentByte <<= 1;
12359          if (this.readModule(2, numColumns - 1, numRows, numColumns)) {
12360              currentByte |= 1;
12361          }
12362          currentByte <<= 1;
12363          if (this.readModule(3, numColumns - 1, numRows, numColumns)) {
12364              currentByte |= 1;
12365          }
12366          return currentByte;
12367      }
12368      /**
12369       * <p>Reads the 8 bits of the special corner condition 2.</p>
12370       *
12371       * <p>See ISO 16022:2006, Figure F.4</p>
12372       *
12373       * @param numRows Number of rows in the mapping matrix
12374       * @param numColumns Number of columns in the mapping matrix
12375       * @return byte from the Corner condition 2
12376       */
12377      readCorner2(numRows, numColumns) {
12378          let currentByte = 0;
12379          if (this.readModule(numRows - 3, 0, numRows, numColumns)) {
12380              currentByte |= 1;
12381          }
12382          currentByte <<= 1;
12383          if (this.readModule(numRows - 2, 0, numRows, numColumns)) {
12384              currentByte |= 1;
12385          }
12386          currentByte <<= 1;
12387          if (this.readModule(numRows - 1, 0, numRows, numColumns)) {
12388              currentByte |= 1;
12389          }
12390          currentByte <<= 1;
12391          if (this.readModule(0, numColumns - 4, numRows, numColumns)) {
12392              currentByte |= 1;
12393          }
12394          currentByte <<= 1;
12395          if (this.readModule(0, numColumns - 3, numRows, numColumns)) {
12396              currentByte |= 1;
12397          }
12398          currentByte <<= 1;
12399          if (this.readModule(0, numColumns - 2, numRows, numColumns)) {
12400              currentByte |= 1;
12401          }
12402          currentByte <<= 1;
12403          if (this.readModule(0, numColumns - 1, numRows, numColumns)) {
12404              currentByte |= 1;
12405          }
12406          currentByte <<= 1;
12407          if (this.readModule(1, numColumns - 1, numRows, numColumns)) {
12408              currentByte |= 1;
12409          }
12410          return currentByte;
12411      }
12412      /**
12413       * <p>Reads the 8 bits of the special corner condition 3.</p>
12414       *
12415       * <p>See ISO 16022:2006, Figure F.5</p>
12416       *
12417       * @param numRows Number of rows in the mapping matrix
12418       * @param numColumns Number of columns in the mapping matrix
12419       * @return byte from the Corner condition 3
12420       */
12421      readCorner3(numRows, numColumns) {
12422          let currentByte = 0;
12423          if (this.readModule(numRows - 1, 0, numRows, numColumns)) {
12424              currentByte |= 1;
12425          }
12426          currentByte <<= 1;
12427          if (this.readModule(numRows - 1, numColumns - 1, numRows, numColumns)) {
12428              currentByte |= 1;
12429          }
12430          currentByte <<= 1;
12431          if (this.readModule(0, numColumns - 3, numRows, numColumns)) {
12432              currentByte |= 1;
12433          }
12434          currentByte <<= 1;
12435          if (this.readModule(0, numColumns - 2, numRows, numColumns)) {
12436              currentByte |= 1;
12437          }
12438          currentByte <<= 1;
12439          if (this.readModule(0, numColumns - 1, numRows, numColumns)) {
12440              currentByte |= 1;
12441          }
12442          currentByte <<= 1;
12443          if (this.readModule(1, numColumns - 3, numRows, numColumns)) {
12444              currentByte |= 1;
12445          }
12446          currentByte <<= 1;
12447          if (this.readModule(1, numColumns - 2, numRows, numColumns)) {
12448              currentByte |= 1;
12449          }
12450          currentByte <<= 1;
12451          if (this.readModule(1, numColumns - 1, numRows, numColumns)) {
12452              currentByte |= 1;
12453          }
12454          return currentByte;
12455      }
12456      /**
12457       * <p>Reads the 8 bits of the special corner condition 4.</p>
12458       *
12459       * <p>See ISO 16022:2006, Figure F.6</p>
12460       *
12461       * @param numRows Number of rows in the mapping matrix
12462       * @param numColumns Number of columns in the mapping matrix
12463       * @return byte from the Corner condition 4
12464       */
12465      readCorner4(numRows, numColumns) {
12466          let currentByte = 0;
12467          if (this.readModule(numRows - 3, 0, numRows, numColumns)) {
12468              currentByte |= 1;
12469          }
12470          currentByte <<= 1;
12471          if (this.readModule(numRows - 2, 0, numRows, numColumns)) {
12472              currentByte |= 1;
12473          }
12474          currentByte <<= 1;
12475          if (this.readModule(numRows - 1, 0, numRows, numColumns)) {
12476              currentByte |= 1;
12477          }
12478          currentByte <<= 1;
12479          if (this.readModule(0, numColumns - 2, numRows, numColumns)) {
12480              currentByte |= 1;
12481          }
12482          currentByte <<= 1;
12483          if (this.readModule(0, numColumns - 1, numRows, numColumns)) {
12484              currentByte |= 1;
12485          }
12486          currentByte <<= 1;
12487          if (this.readModule(1, numColumns - 1, numRows, numColumns)) {
12488              currentByte |= 1;
12489          }
12490          currentByte <<= 1;
12491          if (this.readModule(2, numColumns - 1, numRows, numColumns)) {
12492              currentByte |= 1;
12493          }
12494          currentByte <<= 1;
12495          if (this.readModule(3, numColumns - 1, numRows, numColumns)) {
12496              currentByte |= 1;
12497          }
12498          return currentByte;
12499      }
12500      /**
12501       * <p>Extracts the data region from a {@link BitMatrix} that contains
12502       * alignment patterns.</p>
12503       *
12504       * @param bitMatrix Original {@link BitMatrix} with alignment patterns
12505       * @return BitMatrix that has the alignment patterns removed
12506       */
12507      extractDataRegion(bitMatrix) {
12508          const symbolSizeRows = this.version.getSymbolSizeRows();
12509          const symbolSizeColumns = this.version.getSymbolSizeColumns();
12510          if (bitMatrix.getHeight() !== symbolSizeRows) {
12511              throw new IllegalArgumentException('Dimension of bitMatrix must match the version size');
12512          }
12513          const dataRegionSizeRows = this.version.getDataRegionSizeRows();
12514          const dataRegionSizeColumns = this.version.getDataRegionSizeColumns();
12515          const numDataRegionsRow = symbolSizeRows / dataRegionSizeRows | 0;
12516          const numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns | 0;
12517          const sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;
12518          const sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;
12519          const bitMatrixWithoutAlignment = new BitMatrix(sizeDataRegionColumn, sizeDataRegionRow);
12520          for (let dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) {
12521              const dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;
12522              for (let dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn; ++dataRegionColumn) {
12523                  const dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns;
12524                  for (let i = 0; i < dataRegionSizeRows; ++i) {
12525                      const readRowOffset = dataRegionRow * (dataRegionSizeRows + 2) + 1 + i;
12526                      const writeRowOffset = dataRegionRowOffset + i;
12527                      for (let j = 0; j < dataRegionSizeColumns; ++j) {
12528                          const readColumnOffset = dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;
12529                          if (bitMatrix.get(readColumnOffset, readRowOffset)) {
12530                              const writeColumnOffset = dataRegionColumnOffset + j;
12531                              bitMatrixWithoutAlignment.set(writeColumnOffset, writeRowOffset);
12532                          }
12533                      }
12534                  }
12535              }
12536          }
12537          return bitMatrixWithoutAlignment;
12538      }
12539  }
vendor: 8,913 bytes, lines 12539-12744
12539
12540
12541  /*
12542   * Copyright 2008 ZXing authors
12543   *
12544   * Licensed under the Apache License, Version 2.0 (the "License");
12545   * you may not use this file except in compliance with the License.
12546   * You may obtain a copy of the License at
12547   *
12548   *      http://www.apache.org/licenses/LICENSE-2.0
12549   *
12550   * Unless required by applicable law or agreed to in writing, software
12551   * distributed under the License is distributed on an "AS IS" BASIS,
12552   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12553   * See the License for the specific language governing permissions and
12554   * limitations under the License.
12555   */
12556  /**
12557   * <p>Encapsulates a block of data within a Data Matrix Code. Data Matrix Codes may split their data into
12558   * multiple blocks, each of which is a unit of data and error-correction codewords. Each
12559   * is represented by an instance of this class.</p>
12560   *
12561   * @author [email protected] (Brian Brown)
12562   */
12563  class DataBlock$1 {
12564      constructor(numDataCodewords, codewords) {
12565          this.numDataCodewords = numDataCodewords;
12566          this.codewords = codewords;
12567      }
12568      /**
12569       * <p>When Data Matrix Codes use multiple data blocks, they actually interleave the bytes of each of them.
12570       * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
12571       * method will separate the data into original blocks.</p>
12572       *
12573       * @param rawCodewords bytes as read directly from the Data Matrix Code
12574       * @param version version of the Data Matrix Code
12575       * @return DataBlocks containing original bytes, "de-interleaved" from representation in the
12576       *         Data Matrix Code
12577       */
12578      static getDataBlocks(rawCodewords, version) {
12579          // Figure out the number and size of data blocks used by this version
12580          const ecBlocks = version.getECBlocks();
12581          // First count the total number of data blocks
12582          let totalBlocks = 0;
12583          const ecBlockArray = ecBlocks.getECBlocks();
12584          for (let ecBlock of ecBlockArray) {
12585              totalBlocks += ecBlock.getCount();
12586          }
12587          // Now establish DataBlocks of the appropriate size and number of data codewords
12588          const result = new Array(totalBlocks);
12589          let numResultBlocks = 0;
12590          for (let ecBlock of ecBlockArray) {
12591              for (let i = 0; i < ecBlock.getCount(); i++) {
12592                  const numDataCodewords = ecBlock.getDataCodewords();
12593                  const numBlockCodewords = ecBlocks.getECCodewords() + numDataCodewords;
12594                  result[numResultBlocks++] = new DataBlock$1(numDataCodewords, new Uint8Array(numBlockCodewords));
12595              }
12596          }
12597          // All blocks have the same amount of data, except that the last n
12598          // (where n may be 0) have 1 less byte. Figure out where these start.
12599          // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144
12600          const longerBlocksTotalCodewords = result[0].codewords.length;
12601          // int shorterBlocksTotalCodewords = longerBlocksTotalCodewords - 1;
12602          const longerBlocksNumDataCodewords = longerBlocksTotalCodewords - ecBlocks.getECCodewords();
12603          const shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1;
12604          // The last elements of result may be 1 element shorter for 144 matrix
12605          // first fill out as many elements as all of them have minus 1
12606          let rawCodewordsOffset = 0;
12607          for (let i = 0; i < shorterBlocksNumDataCodewords; i++) {
12608              for (let j = 0; j < numResultBlocks; j++) {
12609                  result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];
12610              }
12611          }
12612          // Fill out the last data block in the longer ones
12613          const specialVersion = version.getVersionNumber() === 24;
12614          const numLongerBlocks = specialVersion ? 8 : numResultBlocks;
12615          for (let j = 0; j < numLongerBlocks; j++) {
12616              result[j].codewords[longerBlocksNumDataCodewords - 1] = rawCodewords[rawCodewordsOffset++];
12617          }
12618          // Now add in error correction blocks
12619          const max = result[0].codewords.length;
12620          for (let i = longerBlocksNumDataCodewords; i < max; i++) {
12621              for (let j = 0; j < numResultBlocks; j++) {
12622                  const jOffset = specialVersion ? (j + 8) % numResultBlocks : j;
12623                  const iOffset = specialVersion && jOffset > 7 ? i - 1 : i;
12624                  result[jOffset].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];
12625              }
12626          }
12627          if (rawCodewordsOffset !== rawCodewords.length) {
12628              throw new IllegalArgumentException();
12629          }
12630          return result;
12631      }
12632      getNumDataCodewords() {
12633          return this.numDataCodewords;
12634      }
12635      getCodewords() {
12636          return this.codewords;
12637      }
12638  }
12639
12640  /*
12641   * Copyright 2007 ZXing authors
12642   *
12643   * Licensed under the Apache License, Version 2.0 (the "License");
12644   * you may not use this file except in compliance with the License.
12645   * You may obtain a copy of the License at
12646   *
12647   *      http://www.apache.org/licenses/LICENSE-2.0
12648   *
12649   * Unless required by applicable law or agreed to in writing, software
12650   * distributed under the License is distributed on an "AS IS" BASIS,
12651   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12652   * See the License for the specific language governing permissions and
12653   * limitations under the License.
12654   */
12655  /**
12656   * <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the
12657   * number of bits read is not often a multiple of 8.</p>
12658   *
12659   * <p>This class is thread-safe but not reentrant -- unless the caller modifies the bytes array
12660   * it passed in, in which case all bets are off.</p>
12661   *
12662   * @author Sean Owen
12663   */
12664  class BitSource {
12665      /**
12666       * @param bytes bytes from which this will read bits. Bits will be read from the first byte first.
12667       * Bits are read within a byte from most-significant to least-significant bit.
12668       */
12669      constructor(bytes) {
12670          this.bytes = bytes;
12671          this.byteOffset = 0;
12672          this.bitOffset = 0;
12673      }
12674      /**
12675       * @return index of next bit in current byte which would be read by the next call to {@link #readBits(int)}.
12676       */
12677      getBitOffset() {
12678          return this.bitOffset;
12679      }
12680      /**
12681       * @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}.
12682       */
12683      getByteOffset() {
12684          return this.byteOffset;
12685      }
12686      /**
12687       * @param numBits number of bits to read
12688       * @return int representing the bits read. The bits will appear as the least-significant
12689       *         bits of the int
12690       * @throws IllegalArgumentException if numBits isn't in [1,32] or more than is available
12691       */
12692      readBits(numBits /*int*/) {
12693          if (numBits < 1 || numBits > 32 || numBits > this.available()) {
12694              throw new IllegalArgumentException('' + numBits);
12695          }
12696          let result = 0;
12697          let bitOffset = this.bitOffset;
12698          let byteOffset = this.byteOffset;
12699          const bytes = this.bytes;
12700          // First, read remainder from current byte
12701          if (bitOffset > 0) {
12702              const bitsLeft = 8 - bitOffset;
12703              const toRead = numBits < bitsLeft ? numBits : bitsLeft;
12704              const bitsToNotRead = bitsLeft - toRead;
12705              const mask = (0xFF >> (8 - toRead)) << bitsToNotRead;
12706              result = (bytes[byteOffset] & mask) >> bitsToNotRead;
12707              numBits -= toRead;
12708              bitOffset += toRead;
12709              if (bitOffset === 8) {
12710                  bitOffset = 0;
12711                  byteOffset++;
12712              }
12713          }
12714          // Next read whole bytes
12715          if (numBits > 0) {
12716              while (numBits >= 8) {
12717                  result = (result << 8) | (bytes[byteOffset] & 0xFF);
12718                  byteOffset++;
12719                  numBits -= 8;
12720              }
12721              // Finally read a partial byte
12722              if (numBits > 0) {
12723                  const bitsToNotRead = 8 - numBits;
12724                  const mask = (0xFF >> bitsToNotRead) << bitsToNotRead;
12725                  result = (result << numBits) | ((bytes[byteOffset] & mask) >> bitsToNotRead);
12726                  bitOffset += numBits;
12727              }
12728          }
12729          this.bitOffset = bitOffset;
12730          this.byteOffset = byteOffset;
12731          return result;
12732      }
12733      /**
12734       * @return number of bits that can be read successfully
12735       */
12736      available() {
12737          return 8 * (this.bytes.length - this.byteOffset) - this.bitOffset;
12738      }
12739  }
12740
12741  /*
12742   * Copyright 2008 ZXing authors
12743   *
12744   * Licensed under the Apache License, Version 2.0 (the "License");
12745   * you may not use this file except in compliance with the License.
12746   * You may obtain a copy of the License at
12747   *
12748   *      http://www.apache.org/licenses/LICENSE-2.0
12749   *
12750   * Unless required by applicable law or agreed to in writing, software
12751   * distributed under the License is distributed on an "AS IS" BASIS,
12752   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12753   * See the License for the specific language governing permissions and
12754   * limitations under the License.
12755   */
12756  var Mode$3;
12757  (function (Mode) {
12758      Mode[Mode["PAD_ENCODE"] = 0] = "PAD_ENCODE";
12759      Mode[Mode["ASCII_ENCODE"] = 1] = "ASCII_ENCODE";
12760      Mode[Mode["C40_ENCODE"] = 2] = "C40_ENCODE";
12761      Mode[Mode["TEXT_ENCODE"] = 3] = "TEXT_ENCODE";
12762      Mode[Mode["ANSIX12_ENCODE"] = 4] = "ANSIX12_ENCODE";
12763      Mode[Mode["EDIFACT_ENCODE"] = 5] = "EDIFACT_ENCODE";
12764      Mode[Mode["BASE256_ENCODE"] = 6] = "BASE256_ENCODE";
12765  })(Mode$3 || (Mode$3 = {}));
12766  /**
12767   * <p>Data Matrix Codes can encode text as bits in one of several modes, and can use multiple modes
12768   * in one Data Matrix Code. This class decodes the bits back into text.</p>
12769   *
12770   * <p>See ISO 16022:2006, 5.2.1 - 5.2.9.2</p>
12771   *
12772   * @author [email protected] (Brian Brown)
12773   * @author Sean Owen
12774   */
12775  class DecodedBitStreamParser$2
vendor: 19,369 bytes, lines 12775-13210
12775 {
12776      static decode(bytes) {
12777          const bits = new BitSource(bytes);
12778          const result = new StringBuilder();
12779          const resultTrailer = new StringBuilder();
12780          const byteSegments = new Array();
12781          let mode = Mode$3.ASCII_ENCODE;
12782          do {
12783              if (mode === Mode$3.ASCII_ENCODE) {
12784                  mode = this.decodeAsciiSegment(bits, result, resultTrailer);
12785              }
12786              else {
12787                  switch (mode) {
12788                      case Mode$3.C40_ENCODE:
12789                          this.decodeC40Segment(bits, result);
12790                          break;
12791                      case Mode$3.TEXT_ENCODE:
12792                          this.decodeTextSegment(bits, result);
12793                          break;
12794                      case Mode$3.ANSIX12_ENCODE:
12795                          this.decodeAnsiX12Segment(bits, result);
12796                          break;
12797                      case Mode$3.EDIFACT_ENCODE:
12798                          this.decodeEdifactSegment(bits, result);
12799                          break;
12800                      case Mode$3.BASE256_ENCODE:
12801                          this.decodeBase256Segment(bits, result, byteSegments);
12802                          break;
12803                      default:
12804                          throw new FormatException();
12805                  }
12806                  mode = Mode$3.ASCII_ENCODE;
12807              }
12808          } while (mode !== Mode$3.PAD_ENCODE && bits.available() > 0);
12809          if (resultTrailer.length() > 0) {
12810              result.append(resultTrailer.toString());
12811          }
12812          return new DecoderResult(bytes, result.toString(), byteSegments.length === 0 ? null : byteSegments, null);
12813      }
12814      /**
12815       * See ISO 16022:2006, 5.2.3 and Annex C, Table C.2
12816       */
12817      static decodeAsciiSegment(bits, result, resultTrailer) {
12818          let upperShift = false;
12819          do {
12820              let oneByte = bits.readBits(8);
12821              if (oneByte === 0) {
12822                  throw new FormatException();
12823              }
12824              else if (oneByte <= 128) { // ASCII data (ASCII value + 1)
12825                  if (upperShift) {
12826                      oneByte += 128;
12827                      // upperShift = false;
12828                  }
12829                  result.append(String.fromCharCode(oneByte - 1));
12830                  return Mode$3.ASCII_ENCODE;
12831              }
12832              else if (oneByte === 129) { // Pad
12833                  return Mode$3.PAD_ENCODE;
12834              }
12835              else if (oneByte <= 229) { // 2-digit data 00-99 (Numeric Value + 130)
12836                  const value = oneByte - 130;
12837                  if (value < 10) { // pad with '0' for single digit values
12838                      result.append('0');
12839                  }
12840                  result.append('' + value);
12841              }
12842              else {
12843                  switch (oneByte) {
12844                      case 230: // Latch to C40 encodation
12845                          return Mode$3.C40_ENCODE;
12846                      case 231: // Latch to Base 256 encodation
12847                          return Mode$3.BASE256_ENCODE;
12848                      case 232: // FNC1
12849                          result.append(String.fromCharCode(29)); // translate as ASCII 29
12850                          break;
12851                      case 233: // Structured Append
12852                      case 234: // Reader Programming
12853                          // Ignore these symbols for now
12854                          // throw ReaderException.getInstance();
12855                          break;
12856                      case 235: // Upper Shift (shift to Extended ASCII)
12857                          upperShift = true;
12858                          break;
12859                      case 236: // 05 Macro
12860                          result.append('[)>\u001E05\u001D');
12861                          resultTrailer.insert(0, '\u001E\u0004');
12862                          break;
12863                      case 237: // 06 Macro
12864                          result.append('[)>\u001E06\u001D');
12865                          resultTrailer.insert(0, '\u001E\u0004');
12866                          break;
12867                      case 238: // Latch to ANSI X12 encodation
12868                          return Mode$3.ANSIX12_ENCODE;
12869                      case 239: // Latch to Text encodation
12870                          return Mode$3.TEXT_ENCODE;
12871                      case 240: // Latch to EDIFACT encodation
12872                          return Mode$3.EDIFACT_ENCODE;
12873                      case 241: // ECI Character
12874                          // TODO(bbrown): I think we need to support ECI
12875                          // throw ReaderException.getInstance();
12876                          // Ignore this symbol for now
12877                          break;
12878                      default:
12879                          // Not to be used in ASCII encodation
12880                          // but work around encoders that end with 254, latch back to ASCII
12881                          if (oneByte !== 254 || bits.available() !== 0) {
12882                              throw new FormatException();
12883                          }
12884                          break;
12885                  }
12886              }
12887          } while (bits.available() > 0);
12888          return Mode$3.ASCII_ENCODE;
12889      }
12890      /**
12891       * See ISO 16022:2006, 5.2.5 and Annex C, Table C.1
12892       */
12893      static decodeC40Segment(bits, result) {
12894          // Three C40 values are encoded in a 16-bit value as
12895          // (1600 * C1) + (40 * C2) + C3 + 1
12896          // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time
12897          let upperShift = false;
12898          const cValues = [];
12899          let shift = 0;
12900          do {
12901              // If there is only one byte left then it will be encoded as ASCII
12902              if (bits.available() === 8) {
12903                  return;
12904              }
12905              const firstByte = bits.readBits(8);
12906              if (firstByte === 254) { // Unlatch codeword
12907                  return;
12908              }
12909              this.parseTwoBytes(firstByte, bits.readBits(8), cValues);
12910              for (let i = 0; i < 3; i++) {
12911                  const cValue = cValues[i];
12912                  switch (shift) {
12913                      case 0:
12914                          if (cValue < 3) {
12915                              shift = cValue + 1;
12916                          }
12917                          else if (cValue < this.C40_BASIC_SET_CHARS.length) {
12918                              const c40char = this.C40_BASIC_SET_CHARS[cValue];
12919                              if (upperShift) {
12920                                  result.append(String.fromCharCode(c40char.charCodeAt(0) + 128));
12921                                  upperShift = false;
12922                              }
12923                              else {
12924                                  result.append(c40char);
12925                              }
12926                          }
12927                          else {
12928                              throw new FormatException();
12929                          }
12930                          break;
12931                      case 1:
12932                          if (upperShift) {
12933                              result.append(String.fromCharCode(cValue + 128));
12934                              upperShift = false;
12935                          }
12936                          else {
12937                              result.append(String.fromCharCode(cValue));
12938                          }
12939                          shift = 0;
12940                          break;
12941                      case 2:
12942                          if (cValue < this.C40_SHIFT2_SET_CHARS.length) {
12943                              const c40char = this.C40_SHIFT2_SET_CHARS[cValue];
12944                              if (upperShift) {
12945                                  result.append(String.fromCharCode(c40char.charCodeAt(0) + 128));
12946                                  upperShift = false;
12947                              }
12948                              else {
12949                                  result.append(c40char);
12950                              }
12951                          }
12952                          else {
12953                              switch (cValue) {
12954                                  case 27: // FNC1
12955                                      result.append(String.fromCharCode(29)); // translate as ASCII 29
12956                                      break;
12957                                  case 30: // Upper Shift
12958                                      upperShift = true;
12959                                      break;
12960                                  default:
12961                                      throw new FormatException();
12962                              }
12963                          }
12964                          shift = 0;
12965                          break;
12966                      case 3:
12967                          if (upperShift) {
12968                              result.append(String.fromCharCode(cValue + 224));
12969                              upperShift = false;
12970                          }
12971                          else {
12972                              result.append(String.fromCharCode(cValue + 96));
12973                          }
12974                          shift = 0;
12975                          break;
12976                      default:
12977                          throw new FormatException();
12978                  }
12979              }
12980          } while (bits.available() > 0);
12981      }
12982      /**
12983       * See ISO 16022:2006, 5.2.6 and Annex C, Table C.2
12984       */
12985      static decodeTextSegment(bits, result) {
12986          // Three Text values are encoded in a 16-bit value as
12987          // (1600 * C1) + (40 * C2) + C3 + 1
12988          // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time
12989          let upperShift = false;
12990          let cValues = [];
12991          let shift = 0;
12992          do {
12993              // If there is only one byte left then it will be encoded as ASCII
12994              if (bits.available() === 8) {
12995                  return;
12996              }
12997              const firstByte = bits.readBits(8);
12998              if (firstByte === 254) { // Unlatch codeword
12999                  return;
13000              }
13001              this.parseTwoBytes(firstByte, bits.readBits(8), cValues);
13002              for (let i = 0; i < 3; i++) {
13003                  const cValue = cValues[i];
13004                  switch (shift) {
13005                      case 0:
13006                          if (cValue < 3) {
13007                              shift = cValue + 1;
13008                          }
13009                          else if (cValue < this.TEXT_BASIC_SET_CHARS.length) {
13010                              const textChar = this.TEXT_BASIC_SET_CHARS[cValue];
13011                              if (upperShift) {
13012                                  result.append(String.fromCharCode(textChar.charCodeAt(0) + 128));
13013                                  upperShift = false;
13014                              }
13015                              else {
13016                                  result.append(textChar);
13017                              }
13018                          }
13019                          else {
13020                              throw new FormatException();
13021                          }
13022                          break;
13023                      case 1:
13024                          if (upperShift) {
13025                              result.append(String.fromCharCode(cValue + 128));
13026                              upperShift = false;
13027                          }
13028                          else {
13029                              result.append(String.fromCharCode(cValue));
13030                          }
13031                          shift = 0;
13032                          break;
13033                      case 2:
13034                          // Shift 2 for Text is the same encoding as C40
13035                          if (cValue < this.TEXT_SHIFT2_SET_CHARS.length) {
13036                              const textChar = this.TEXT_SHIFT2_SET_CHARS[cValue];
13037                              if (upperShift) {
13038                                  result.append(String.fromCharCode(textChar.charCodeAt(0) + 128));
13039                                  upperShift = false;
13040                              }
13041                              else {
13042                                  result.append(textChar);
13043                              }
13044                          }
13045                          else {
13046                              switch (cValue) {
13047                                  case 27: // FNC1
13048                                      result.append(String.fromCharCode(29)); // translate as ASCII 29
13049                                      break;
13050                                  case 30: // Upper Shift
13051                                      upperShift = true;
13052                                      break;
13053                                  default:
13054                                      throw new FormatException();
13055                              }
13056                          }
13057                          shift = 0;
13058                          break;
13059                      case 3:
13060                          if (cValue < this.TEXT_SHIFT3_SET_CHARS.length) {
13061                              const textChar = this.TEXT_SHIFT3_SET_CHARS[cValue];
13062                              if (upperShift) {
13063                                  result.append(String.fromCharCode(textChar.charCodeAt(0) + 128));
13064                                  upperShift = false;
13065                              }
13066                              else {
13067                                  result.append(textChar);
13068                              }
13069                              shift = 0;
13070                          }
13071                          else {
13072                              throw new FormatException();
13073                          }
13074                          break;
13075                      default:
13076                          throw new FormatException();
13077                  }
13078              }
13079          } while (bits.available() > 0);
13080      }
13081      /**
13082       * See ISO 16022:2006, 5.2.7
13083       */
13084      static decodeAnsiX12Segment(bits, result) {
13085          // Three ANSI X12 values are encoded in a 16-bit value as
13086          // (1600 * C1) + (40 * C2) + C3 + 1
13087          const cValues = [];
13088          do {
13089              // If there is only one byte left then it will be encoded as ASCII
13090              if (bits.available() === 8) {
13091                  return;
13092              }
13093              const firstByte = bits.readBits(8);
13094              if (firstByte === 254) { // Unlatch codeword
13095                  return;
13096              }
13097              this.parseTwoBytes(firstByte, bits.readBits(8), cValues);
13098              for (let i = 0; i < 3; i++) {
13099                  const cValue = cValues[i];
13100                  switch (cValue) {
13101                      case 0: // X12 segment terminator <CR>
13102                          result.append('\r');
13103                          break;
13104                      case 1: // X12 segment separator *
13105                          result.append('*');
13106                          break;
13107                      case 2: // X12 sub-element separator >
13108                          result.append('>');
13109                          break;
13110                      case 3: // space
13111                          result.append(' ');
13112                          break;
13113                      default:
13114                          if (cValue < 14) { // 0 - 9
13115                              result.append(String.fromCharCode(cValue + 44));
13116                          }
13117                          else if (cValue < 40) { // A - Z
13118                              result.append(String.fromCharCode(cValue + 51));
13119                          }
13120                          else {
13121                              throw new FormatException();
13122                          }
13123                          break;
13124                  }
13125              }
13126          } while (bits.available() > 0);
13127      }
13128      static parseTwoBytes(firstByte, secondByte, result) {
13129          let fullBitValue = (firstByte << 8) + secondByte - 1;
13130          let temp = Math.floor(fullBitValue / 1600);
13131          result[0] = temp;
13132          fullBitValue -= temp * 1600;
13133          temp = Math.floor(fullBitValue / 40);
13134          result[1] = temp;
13135          result[2] = fullBitValue - temp * 40;
13136      }
13137      /**
13138       * See ISO 16022:2006, 5.2.8 and Annex C Table C.3
13139       */
13140      static decodeEdifactSegment(bits, result) {
13141          do {
13142              // If there is only two or less bytes left then it will be encoded as ASCII
13143              if (bits.available() <= 16) {
13144                  return;
13145              }
13146              for (let i = 0; i < 4; i++) {
13147                  let edifactValue = bits.readBits(6);
13148                  // Check for the unlatch character
13149                  if (edifactValue === 0x1F) { // 011111
13150                      // Read rest of byte, which should be 0, and stop
13151                      const bitsLeft = 8 - bits.getBitOffset();
13152                      if (bitsLeft !== 8) {
13153                          bits.readBits(bitsLeft);
13154                      }
13155                      return;
13156                  }
13157                  if ((edifactValue & 0x20) === 0) { // no 1 in the leading (6th) bit
13158                      edifactValue |= 0x40; // Add a leading 01 to the 6 bit binary value
13159                  }
13160                  result.append(String.fromCharCode(edifactValue));
13161              }
13162          } while (bits.available() > 0);
13163      }
13164      /**
13165       * See ISO 16022:2006, 5.2.9 and Annex B, B.2
13166       */
13167      static decodeBase256Segment(bits, result, byteSegments) {
13168          // Figure out how long the Base 256 Segment is.
13169          let codewordPosition = 1 + bits.getByteOffset(); // position is 1-indexed
13170          const d1 = this.unrandomize255State(bits.readBits(8), codewordPosition++);
13171          let count;
13172          if (d1 === 0) { // Read the remainder of the symbol
13173              count = bits.available() / 8 | 0;
13174          }
13175          else if (d1 < 250) {
13176              count = d1;
13177          }
13178          else {
13179              count = 250 * (d1 - 249) + this.unrandomize255State(bits.readBits(8), codewordPosition++);
13180          }
13181          // We're seeing NegativeArraySizeException errors from users.
13182          if (count < 0) {
13183              throw new FormatException();
13184          }
13185          const bytes = new Uint8Array(count);
13186          for (let i = 0; i < count; i++) {
13187              // Have seen this particular error in the wild, such as at
13188              // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2
13189              if (bits.available() < 8) {
13190                  throw new FormatException();
13191              }
13192              bytes[i] = this.unrandomize255State(bits.readBits(8), codewordPosition++);
13193          }
13194          byteSegments.push(bytes);
13195          try {
13196              result.append(StringEncoding.decode(bytes, StringUtils.ISO88591));
13197          }
13198          catch (uee) {
13199              throw new IllegalStateException('Platform does not support required encoding: ' + uee.message);
13200          }
13201      }
13202      /**
13203       * See ISO 16022:2006, Annex B, B.2
13204       */
13205      static unrandomize255State(randomizedBase256Codeword, base256CodewordPosition) {
13206          const pseudoRandomNumber = ((149 * base256CodewordPosition) % 255) + 1;
13207          const tempVariable = randomizedBase256Codeword - pseudoRandomNumber;
13208          return tempVariable >= 0 ? tempVariable : tempVariable + 256;
13209      }
13210  }
13210
13211  /**
13212   * See ISO 16022:2006, Annex C Table C.1
13213   * The C40 Basic Character Set (*'s used for placeholders for the shift values)
13214   */
13215  DecodedBitStreamParser$2.C40_BASIC_SET_CHARS = [
13216      '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
13217      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
13218      'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
13219  ];
13220  DecodedBitStreamParser$2.C40_SHIFT2_SET_CHARS = [
13221      '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
13222      '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
13223  ];
13224  /**
13225   * See ISO 16022:2006, Annex C Table C.2
13226   * The Text Basic Character Set (*'s used for placeholders for the shift values)
13227   */
13228  DecodedBitStreamParser$2.TEXT_BASIC_SET_CHARS = [
13229      '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
13230      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
13231      'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
13232  ];
13233  // Shift 2 for Text is the same encoding as C40
13234  DecodedBitStreamParser$2.TEXT_SHIFT2_SET_CHARS = DecodedBitStreamParser$2.C40_SHIFT2_SET_CHARS;
13235  DecodedBitStreamParser$2.TEXT_SHIFT3_SET_CHARS = [
13236      '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
13237      'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', String.fromCharCode(127)
13238  ];
13239
13240  /*
13241   * Copyright 2007 ZXing authors
13242   *
13243   * Licensed under the Apache License, Version 2.0 (the "License");
13244   * you may not use this file except in compliance with the License.
13245   * You may obtain a copy of the License at
13246   *
13247   *      http://www.apache.org/licenses/LICENSE-2.0
13248   *
13249   * Unless required by applicable law or agreed to in writing, software
13250   * distributed under the License is distributed on an "AS IS" BASIS,
13251   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13252   * See the License for the specific language governing permissions and
13253   * limitations under the License.
13254   */
13255  /**
13256   * <p>The main class which implements Data Matrix Code decoding -- as opposed to locating and extracting
13257   * the Data Matrix Code from an image.</p>
13258   *
13259   * @author [email protected] (Brian Brown)
13260   */
13261  class Decoder$1 {
13262      constructor() {
13263          this.rsDecoder = new ReedSolomonDecoder(GenericGF.DATA_MATRIX_FIELD_256);
13264      }
13265      /**
13266       * <p>Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or "true" is taken
13267       * to mean a black module.</p>
13268       *
13269       * @param bits booleans representing white/black Data Matrix Code modules
13270       * @return text and bytes encoded within the Data Matrix Code
13271       * @throws FormatException if the Data Matrix Code cannot be decoded
13272       * @throws ChecksumException if error correction fails
13273       */
13274      decode(bits) {
13275          // Construct a parser and read version, error-correction level
13276          const parser = new BitMatrixParser$1(bits);
13277          const version = parser.getVersion();
13278          // Read codewords
13279          const codewords = parser.readCodewords();
13280          // Separate into data blocks
13281          const dataBlocks = DataBlock$1.getDataBlocks(codewords, version);
13282          // Count total number of data bytes
13283          let totalBytes = 0;
13284          for (let db of dataBlocks) {
13285              totalBytes += db.getNumDataCodewords();
13286          }
13287          const resultBytes = new Uint8Array(totalBytes);
13288          const dataBlocksCount = dataBlocks.length;
13289          // Error-correct and copy data blocks together into a stream of bytes
13290          for (let j = 0; j < dataBlocksCount; j++) {
13291              const dataBlock = dataBlocks[j];
13292              const codewordBytes = dataBlock.getCodewords();
13293              const numDataCodewords = dataBlock.getNumDataCodewords();
13294              this.correctErrors(codewordBytes, numDataCodewords);
13295              for (let i = 0; i < numDataCodewords; i++) {
13296                  // De-interlace data blocks.
13297                  resultBytes[i * dataBlocksCount + j] = codewordBytes[i];
13298              }
13299          }
13300          // Decode the contents of that stream of bytes
13301          return DecodedBitStreamParser$2.decode(resultBytes);
13302      }
13303      /**
13304       * <p>
13304Given data and error-correction codewords received, possibly corrupted by errors, attempts to
13305       * correct the errors in-place using Reed-Solomon error correction.</p>
13306       *
13307       * @param codewordBytes data and error correction codewords
13308       * @param numDataCodewords number of codewords that are data bytes
13309       * @throws ChecksumException if error correction fails
13310       */
13311      correctErrors(codewordBytes, numDataCodewords) {
13312          // const numCodewords = codewordBytes.length;
13313          // First read into an array of ints
13314          const codewordsInts = new Int32Array(codewordBytes);
13315          // for (let i = 0; i < numCodewords; i++) {
13316          //   codewordsInts[i] = codewordBytes[i] & 0xFF;
13317          // }
13318          try {
13319              this.rsDecoder.decode(codewordsInts, codewordBytes.length - numDataCodewords);
13320          }
13321          catch (ignored /* ReedSolomonException */) {
13322              throw new ChecksumException();
13323          }
13324          // Copy back into array of bytes -- only need to worry about the bytes that were data
13325          // We don't care about errors in the error-correction codewords
13326          for (let i = 0; i < numDataCodewords; i++) {
13327              codewordBytes[i] = codewordsInts[i];
13328          }
13329      }
13330  }
13331
13332  /*
13333   * Copyright 2008 ZXing authors
13334   *
13335   * Licensed under the Apache License, Version 2.0 (the "License");
13336   * you may not use this file except in compliance with the License.
13337   * You may obtain a copy of the License at
13338   *
13339   *      http://www.apache.org/licenses/LICENSE-2.0
13340   *
13341   * Unless required by applicable law or agreed to in writing, software
13342   * distributed under the License is distributed on an "AS IS" BASIS,
13343   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13344   * See the License for the specific language governing permissions and
13345   * limitations under the License.
13346   */
13347  /**
13348   * <p>Encapsulates logic that can detect a Data Matrix Code in an image, even if the Data Matrix Code
13349   * is rotated or skewed, or partially obscured.</p>
13350   *
13351   * @author Sean Owen
13352   */
13353  class Detector$2 {
13354      constructor(image) {
13355          this.image = image;
13356          this.rectangleDetector = new WhiteRectangleDetector(this.image);
13357      }
13358      /**
13359       * <p>Detects a Data Matrix Code in an image.</p>
13360       *
13361       * @return {@link DetectorResult} encapsulating results of detecting a Data Matrix Code
13362       * @throws NotFoundException if no Data Matrix Code can be found
13363       */
13364      detect() {
13365          const cornerPoints = this.rectangleDetector.detect();
13366          let points = this.detectSolid1(cornerPoints);
13367          points = this.detectSolid2(points);
13368          points[3] = this.correctTopRight(points);
13369          if (!points[3]) {
13370              throw new NotFoundException();
13371          }
13372          points = this.shiftToModuleCenter(points);
13373          const topLeft = points[0];
13374          const bottomLeft = points[1];
13375          const bottomRight = points[2];
13376          const topRight = points[3];
13377          let dimensionTop = this.transitionsBetween(topLeft, top
vendor: 27,114 bytes, lines 13377-14055
13377Right) + 1;
13378          let dimensionRight = this.transitionsBetween(bottomRight, topRight) + 1;
13379          if ((dimensionTop & 0x01) === 1) {
13380              dimensionTop += 1;
13381          }
13382          if ((dimensionRight & 0x01) === 1) {
13383              dimensionRight += 1;
13384          }
13385          if (4 * dimensionTop < 7 * dimensionRight && 4 * dimensionRight < 7 * dimensionTop) {
13386              // The matrix is square
13387              dimensionTop = dimensionRight = Math.max(dimensionTop, dimensionRight);
13388          }
13389          let bits = Detector$2.sampleGrid(this.image, topLeft, bottomLeft, bottomRight, topRight, dimensionTop, dimensionRight);
13390          return new DetectorResult(bits, [topLeft, bottomLeft, bottomRight, topRight]);
13391      }
13392      static shiftPoint(point, to, div) {
13393          let x = (to.getX() - point.getX()) / (div + 1);
13394          let y = (to.getY() - point.getY()) / (div + 1);
13395          return new ResultPoint(point.getX() + x, point.getY() + y);
13396      }
13397      static moveAway(point, fromX, fromY) {
13398          let x = point.getX();
13399          let y = point.getY();
13400          if (x < fromX) {
13401              x -= 1;
13402          }
13403          else {
13404              x += 1;
13405          }
13406          if (y < fromY) {
13407              y -= 1;
13408          }
13409          else {
13410              y += 1;
13411          }
13412          return new ResultPoint(x, y);
13413      }
13414      /**
13415       * Detect a solid side which has minimum transition.
13416       */
13417      detectSolid1(cornerPoints) {
13418          // 0  2
13419          // 1  3
13420          let pointA = cornerPoints[0];
13421          let pointB = cornerPoints[1];
13422          let pointC = cornerPoints[3];
13423          let pointD = cornerPoints[2];
13424          let trAB = this.transitionsBetween(pointA, pointB);
13425          let trBC = this.transitionsBetween(pointB, pointC);
13426          let trCD = this.transitionsBetween(pointC, pointD);
13427          let trDA = this.transitionsBetween(pointD, pointA);
13428          // 0..3
13429          // :  :
13430          // 1--2
13431          let min = trAB;
13432          let points = [pointD, pointA, pointB, pointC];
13433          if (min > trBC) {
13434              min = trBC;
13435              points[0] = pointA;
13436              points[1] = pointB;
13437              points[2] = pointC;
13438              points[3] = pointD;
13439          }
13440          if (min > trCD) {
13441              min = trCD;
13442              points[0] = pointB;
13443              points[1] = pointC;
13444              points[2] = pointD;
13445              points[3] = pointA;
13446          }
13447          if (min > trDA) {
13448              points[0] = pointC;
13449              points[1] = pointD;
13450              points[2] = pointA;
13451              points[3] = pointB;
13452          }
13453          return points;
13454      }
13455      /**
13456       * Detect a second solid side next to first solid side.
13457       */
13458      detectSolid2(points) {
13459          // A..D
13460          // :  :
13461          // B--C
13462          let pointA = points[0];
13463          let pointB = points[1];
13464          let pointC = points[2];
13465          let pointD = points[3];
13466          // Transition detection on the edge is not stable.
13467          // To safely detect, shift the points to the module center.
13468          let tr = this.transitionsBetween(pointA, pointD);
13469          let pointBs = Detector$2.shiftPoint(pointB, pointC, (tr + 1) * 4);
13470          let pointCs = Detector$2.shiftPoint(pointC, pointB, (tr + 1) * 4);
13471          let trBA = this.transitionsBetween(pointBs, pointA);
13472          let trCD = this.transitionsBetween(pointCs, pointD);
13473          // 0..3
13474          // |  :
13475          // 1--2
13476          if (trBA < trCD) {
13477              // solid sides: A-B-C
13478              points[0] = pointA;
13479              points[1] = pointB;
13480              points[2] = pointC;
13481              points[3] = pointD;
13482          }
13483          else {
13484              // solid sides: B-C-D
13485              points[0] = pointB;
13486              points[1] = pointC;
13487              points[2] = pointD;
13488              points[3] = pointA;
13489          }
13490          return points;
13491      }
13492      /**
13493       * Calculates the corner position of the white top right module.
13494       */
13495      correctTopRight(points) {
13496          // A..D
13497          // |  :
13498          // B--C
13499          let pointA = points[0];
13500          let pointB = points[1];
13501          let pointC = points[2];
13502          let pointD = points[3];
13503          // shift points for safe transition detection.
13504          let trTop = this.transitionsBetween(pointA, pointD);
13505          let trRight = this.transitionsBetween(pointB, pointD);
13506          let pointAs = Detector$2.shiftPoint(pointA, pointB, (trRight + 1) * 4);
13507          let pointCs = Detector$2.shiftPoint(pointC, pointB, (trTop + 1) * 4);
13508          trTop = this.transitionsBetween(pointAs, pointD);
13509          trRight = this.transitionsBetween(pointCs, pointD);
13510          let candidate1 = new ResultPoint(pointD.getX() + (pointC.getX() - pointB.getX()) / (trTop + 1), pointD.getY() + (pointC.getY() - pointB.getY()) / (trTop + 1));
13511          let candidate2 = new ResultPoint(pointD.getX() + (pointA.getX() - pointB.getX()) / (trRight + 1), pointD.getY() + (pointA.getY() - pointB.getY()) / (trRight + 1));
13512          if (!this.isValid(candidate1)) {
13513              if (this.isValid(candidate2)) {
13514                  return candidate2;
13515              }
13516              return null;
13517          }
13518          if (!this.isValid(candidate2)) {
13519              return candidate1;
13520          }
13521          let sumc1 = this.transitionsBetween(pointAs, candidate1) + this.transitionsBetween(pointCs, candidate1);
13522          let sumc2 = this.transitionsBetween(pointAs, candidate2) + this.transitionsBetween(pointCs, candidate2);
13523          if (sumc1 > sumc2) {
13524              return candidate1;
13525          }
13526          else {
13527              return candidate2;
13528          }
13529      }
13530      /**
13531       * Shift the edge points to the module center.
13532       */
13533      shiftToModuleCenter(points) {
13534          // A..D
13535          // |  :
13536          // B--C
13537          let pointA = points[0];
13538          let pointB = points[1];
13539          let pointC = points[2];
13540          let pointD = points[3];
13541          // calculate pseudo dimensions
13542          let dimH = this.transitionsBetween(pointA, pointD) + 1;
13543          let dimV = this.transitionsBetween(pointC, pointD) + 1;
13544          // shift points for safe dimension detection
13545          let pointAs = Detector$2.shiftPoint(pointA, pointB, dimV * 4);
13546          let pointCs = Detector$2.shiftPoint(pointC, pointB, dimH * 4);
13547          //  calculate more precise dimensions
13548          dimH = this.transitionsBetween(pointAs, pointD) + 1;
13549          dimV = this.transitionsBetween(pointCs, pointD) + 1;
13550          if ((dimH & 0x01) === 1) {
13551              dimH += 1;
13552          }
13553          if ((dimV & 0x01) === 1) {
13554              dimV += 1;
13555          }
13556          // WhiteRectangleDetector returns points inside of the rectangle.
13557          // I want points on the edges.
13558          let centerX = (pointA.getX() + pointB.getX() + pointC.getX() + pointD.getX()) / 4;
13559          let centerY = (pointA.getY() + pointB.getY() + pointC.getY() + pointD.getY()) / 4;
13560          pointA = Detector$2.moveAway(pointA, centerX, centerY);
13561          pointB = Detector$2.moveAway(pointB, centerX, centerY);
13562          pointC = Detector$2.moveAway(pointC, centerX, centerY);
13563          pointD = Detector$2.moveAway(pointD, centerX, centerY);
13564          let pointBs;
13565          let pointDs;
13566          // shift points to the center of each modules
13567          pointAs = Detector$2.shiftPoint(pointA, pointB, dimV * 4);
13568          pointAs = Detector$2.shiftPoint(pointAs, pointD, dimH * 4);
13569          pointBs = Detector$2.shiftPoint(pointB, pointA, dimV * 4);
13570          pointBs = Detector$2.shiftPoint(pointBs, pointC, dimH * 4);
13571          pointCs = Detector$2.shiftPoint(pointC, pointD, dimV * 4);
13572          pointCs = Detector$2.shiftPoint(pointCs, pointB, dimH * 4);
13573          pointDs = Detector$2.shiftPoint(pointD, pointC, dimV * 4);
13574          pointDs = Detector$2.shiftPoint(pointDs, pointA, dimH * 4);
13575          return [pointAs, pointBs, pointCs, pointDs];
13576      }
13577      isValid(p) {
13578          return p.getX() >= 0 && p.getX() < this.image.getWidth() && p.getY() > 0 && p.getY() < this.image.getHeight();
13579      }
13580      static sampleGrid(image, topLeft, bottomLeft, bottomRight, topRight, dimensionX, dimensionY) {
13581          const sampler = GridSamplerInstance.getInstance();
13582          return sampler.sampleGrid(image, dimensionX, dimensionY, 0.5, 0.5, dimensionX - 0.5, 0.5, dimensionX - 0.5, dimensionY - 0.5, 0.5, dimensionY - 0.5, topLeft.getX(), topLeft.getY(), topRight.getX(), topRight.getY(), bottomRight.getX(), bottomRight.getY(), bottomLeft.getX(), bottomLeft.getY());
13583      }
13584      /**
13585       * Counts the number of black/white transitions between two points, using something like Bresenham's algorithm.
13586       */
13587      transitionsBetween(from, to) {
13588          // See QR Code Detector, sizeOfBlackWhiteBlackRun()
13589          let fromX = Math.trunc(from.getX());
13590          let fromY = Math.trunc(from.getY());
13591          let toX = Math.trunc(to.getX());
13592          let toY = Math.trunc(to.getY());
13593          let steep = Math.abs(toY - fromY) > Math.abs(toX - fromX);
13594          if (steep) {
13595              let temp = fromX;
13596              fromX = fromY;
13597              fromY = temp;
13598              temp = toX;
13599              toX = toY;
13600              toY = temp;
13601          }
13602          let dx = Math.abs(toX - fromX);
13603          let dy = Math.abs(toY - fromY);
13604          let error = -dx / 2;
13605          let ystep = fromY < toY ? 1 : -1;
13606          let xstep = fromX < toX ? 1 : -1;
13607          let transitions = 0;
13608          let inBlack = this.image.get(steep ? fromY : fromX, steep ? fromX : fromY);
13609          for (let x = fromX, y = fromY; x !== toX; x += xstep) {
13610              let isBlack = this.image.get(steep ? y : x, steep ? x : y);
13611              if (isBlack !== inBlack) {
13612                  transitions++;
13613                  inBlack = isBlack;
13614              }
13615              error += dy;
13616              if (error > 0) {
13617                  if (y === toY) {
13618                      break;
13619                  }
13620                  y += ystep;
13621                  error -= dx;
13622              }
13623          }
13624          return transitions;
13625      }
13626  }
13627
13628  /*
13629   * Copyright 2007 ZXing authors
13630   *
13631   * Licensed under the Apache License, Version 2.0 (the "License");
13632   * you may not use this file except in compliance with the License.
13633   * You may obtain a copy of the License at
13634   *
13635   *      http://www.apache.org/licenses/LICENSE-2.0
13636   *
13637   * Unless required by applicable law or agreed to in writing, software
13638   * distributed under the License is distributed on an "AS IS" BASIS,
13639   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13640   * See the License for the specific language governing permissions and
13641   * limitations under the License.
13642   */
13643  /**
13644   * This implementation can detect and decode Data Matrix codes in an image.
13645   *
13646   * @author [email protected] (Brian Brown)
13647   */
13648  class DataMatrixReader {
13649      constructor() {
13650          this.decoder = new Decoder$1();
13651      }
13652      /**
13653       * Locates and decodes a Data Matrix code in an image.
13654       *
13655       * @return a String representing the content encoded by the Data Matrix code
13656       * @throws NotFoundException if a Data Matrix code cannot be found
13657       * @throws FormatException if a Data Matrix code cannot be decoded
13658       * @throws ChecksumException if error correction fails
13659       */
13660      // @Override
13661      // public Result decode(BinaryBitmap image) throws NotFoundException, ChecksumException, FormatException {
13662      //   return decode(image, null);
13663      // }
13664      // @Override
13665      decode(image, hints = null) {
13666          let decoderResult;
13667          let points;
13668          if (hints != null && hints.has(DecodeHintType$1.PURE_BARCODE)) {
13669              const bits = DataMatrixReader.extractPureBits(image.getBlackMatrix());
13670              decoderResult = this.decoder.decode(bits);
13671              points = DataMatrixReader.NO_POINTS;
13672          }
13673          else {
13674              const detectorResult = new Detector$2(image.getBlackMatrix()).detect();
13675              decoderResult = this.decoder.decode(detectorResult.getBits());
13676              points = detectorResult.getPoints();
13677          }
13678          const rawBytes = decoderResult.getRawBytes();
13679          const result = new Result$1(decoderResult.getText(), rawBytes, 8 * rawBytes.length, points, BarcodeFormat$1.DATA_MATRIX, System.currentTimeMillis());
13680          const byteSegments = decoderResult.getByteSegments();
13681          if (byteSegments != null) {
13682              result.putMetadata(ResultMetadataType$1.BYTE_SEGMENTS, byteSegments);
13683          }
13684          const ecLevel = decoderResult.getECLevel();
13685          if (ecLevel != null) {
13686              result.putMetadata(ResultMetadataType$1.ERROR_CORRECTION_LEVEL, ecLevel);
13687          }
13688          return result;
13689      }
13690      // @Override
13691      reset() {
13692          // do nothing
13693      }
13694      /**
13695       * This method detects a code in a "pure" image -- that is, pure monochrome image
13696       * which contains only an unrotated, unskewed, image of a code, with some white border
13697       * around it. This is a specialized method that works exceptionally fast in this special
13698       * case.
13699       *
13700       * @see com.google.zxing.qrcode.QRCodeReader#extractPureBits(BitMatrix)
13701       */
13702      static extractPureBits(image) {
13703          const leftTopBlack = image.getTopLeftOnBit();
13704          const rightBottomBlack = image.getBottomRightOnBit();
13705          if (leftTopBlack == null || rightBottomBlack == null) {
13706              throw new NotFoundException();
13707          }
13708          const moduleSize = this.moduleSize(leftTopBlack, image);
13709          let top = leftTopBlack[1];
13710          const bottom = rightBottomBlack[1];
13711          let left = leftTopBlack[0];
13712          const right = rightBottomBlack[0];
13713          const matrixWidth = (right - left + 1) / moduleSize;
13714          const matrixHeight = (bottom - top + 1) / moduleSize;
13715          if (matrixWidth <= 0 || matrixHeight <= 0) {
13716              throw new NotFoundException();
13717          }
13718          // Push in the "border" by half the module width so that we start
13719          // sampling in the middle of the module. Just in case the image is a
13720          // little off, this will help recover.
13721          const nudge = moduleSize / 2;
13722          top += nudge;
13723          left += nudge;
13724          // Now just read off the bits
13725          const bits = new BitMatrix(matrixWidth, matrixHeight);
13726          for (let y = 0; y < matrixHeight; y++) {
13727              const iOffset = top + y * moduleSize;
13728              for (let x = 0; x < matrixWidth; x++) {
13729                  if (image.get(left + x * moduleSize, iOffset)) {
13730                      bits.set(x, y);
13731                  }
13732              }
13733          }
13734          return bits;
13735      }
13736      static moduleSize(leftTopBlack, image) {
13737          const width = image.getWidth();
13738          let x = leftTopBlack[0];
13739          const y = leftTopBlack[1];
13740          while (x < width && image.get(x, y)) {
13741              x++;
13742          }
13743          if (x === width) {
13744              throw new NotFoundException();
13745          }
13746          const moduleSize = x - leftTopBlack[0];
13747          if (moduleSize === 0) {
13748              throw new NotFoundException();
13749          }
13750          return moduleSize;
13751      }
13752  }
13753  DataMatrixReader.NO_POINTS = [];
13754
13755  /**
13756   * @deprecated Moving to @zxing/browser
13757   *
13758   * QR Code reader to use from browser.
13759   */
13760  class BrowserDatamatrixCodeReader extends BrowserCodeReader {
13761      /**
13762       * Creates an instance of BrowserQRCodeReader.
13763       * @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
13764       */
13765      constructor(timeBetweenScansMillis = 500) {
13766          super(new DataMatrixReader(), timeBetweenScansMillis);
13767      }
13768  }
13769
13770  /*
13771   * Copyright 2007 ZXing authors
13772   *
13773   * Licensed under the Apache License, Version 2.0 (the "License");
13774   * you may not use this file except in compliance with the License.
13775   * You may obtain a copy of the License at
13776   *
13777   *      http://www.apache.org/licenses/LICENSE-2.0
13778   *
13779   * Unless required by applicable law or agreed to in writing, software
13780   * distributed under the License is distributed on an "AS IS" BASIS,
13781   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13782   * See the License for the specific language governing permissions and
13783   * limitations under the License.
13784   */
13785  var ErrorCorrectionLevelValues;
13786  (function (ErrorCorrectionLevelValues) {
13787      ErrorCorrectionLevelValues[ErrorCorrectionLevelValues["L"] = 0] = "L";
13788      ErrorCorrectionLevelValues[ErrorCorrectionLevelValues["M"] = 1] = "M";
13789      ErrorCorrectionLevelValues[ErrorCorrectionLevelValues["Q"] = 2] = "Q";
13790      ErrorCorrectionLevelValues[ErrorCorrectionLevelValues["H"] = 3] = "H";
13791  })(ErrorCorrectionLevelValues || (ErrorCorrectionLevelValues = {}));
13792  /**
13793   * <p>See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels
13794   * defined by the QR code standard.</p>
13795   *
13796   * @author Sean Owen
13797   */
13798  class ErrorCorrectionLevel {
13799      constructor(value, stringValue, bits /*int*/) {
13800          this.value = value;
13801          this.stringValue = stringValue;
13802          this.bits = bits;
13803          ErrorCorrectionLevel.FOR_BITS.set(bits, this);
13804          ErrorCorrectionLevel.FOR_VALUE.set(value, this);
13805      }
13806      getValue() {
13807          return this.value;
13808      }
13809      getBits() {
13810          return this.bits;
13811      }
13812      static fromString(s) {
13813          switch (s) {
13814              case 'L': return ErrorCorrectionLevel.L;
13815              case 'M': return ErrorCorrectionLevel.M;
13816              case 'Q': return ErrorCorrectionLevel.Q;
13817              case 'H': return ErrorCorrectionLevel.H;
13818              default: throw new ArgumentException(s + 'not available');
13819          }
13820      }
13821      toString() {
13822          return this.stringValue;
13823      }
13824      equals(o) {
13825          if (!(o instanceof ErrorCorrectionLevel)) {
13826              return false;
13827          }
13828          const other = o;
13829          return this.value === other.value;
13830      }
13831      /**
13832       * @param bits int containing the two bits encoding a QR Code's error correction level
13833       * @return ErrorCorrectionLevel representing the encoded error correction level
13834       */
13835      static forBits(bits /*int*/) {
13836          if (bits < 0 || bits >= ErrorCorrectionLevel.FOR_BITS.size) {
13837              throw new IllegalArgumentException();
13838          }
13839          return ErrorCorrectionLevel.FOR_BITS.get(bits);
13840      }
13841  }
13842  ErrorCorrectionLevel.FOR_BITS = new Map();
13843  ErrorCorrectionLevel.FOR_VALUE = new Map();
13844  /** L = ~7% correction */
13845  ErrorCorrectionLevel.L = new ErrorCorrectionLevel(ErrorCorrectionLevelValues.L, 'L', 0x01);
13846  /** M = ~15% correction */
13847  ErrorCorrectionLevel.M = new ErrorCorrectionLevel(ErrorCorrectionLevelValues.M, 'M', 0x00);
13848  /** Q = ~25% correction */
13849  ErrorCorrectionLevel.Q = new ErrorCorrectionLevel(ErrorCorrectionLevelValues.Q, 'Q', 0x03);
13850  /** H = ~30% correction */
13851  ErrorCorrectionLevel.H = new ErrorCorrectionLevel(ErrorCorrectionLevelValues.H, 'H', 0x02);
13852
13853  /*
13854   * Copyright 2007 ZXing authors
13855   *
13856   * Licensed under the Apache License, Version 2.0 (the "License");
13857   * you may not use this file except in compliance with the License.
13858   * You may obtain a copy of the License at
13859   *
13860   *      http://www.apache.org/licenses/LICENSE-2.0
13861   *
13862   * Unless required by applicable law or agreed to in writing, software
13863   * distributed under the License is distributed on an "AS IS" BASIS,
13864   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13865   * See the License for the specific language governing permissions and
13866   * limitations under the License.
13867   */
13868  /**
13869   * <p>Encapsulates a QR Code's format information, including the data mask used and
13870   * error correction level.</p>
13871   *
13872   * @author Sean Owen
13873   * @see DataMask
13874   * @see ErrorCorrectionLevel
13875   */
13876  class FormatInformation {
13877      constructor(formatInfo /*int*/) {
13878          // Bits 3,4
13879          this.errorCorrectionLevel = ErrorCorrectionLevel.forBits((formatInfo >> 3) & 0x03);
13880          // Bottom 3 bits
13881          this.dataMask = /*(byte) */ (formatInfo & 0x07);
13882      }
13883      static numBitsDiffering(a /*int*/, b /*int*/) {
13884          return Integer.bitCount(a ^ b);
13885      }
13886      /**
13887       * @param maskedFormatInfo1 format info indicator, with mask still applied
13888       * @param maskedFormatInfo2 second copy of same info; both are checked at the same time
13889       *  to establish best match
13890       * @return information about the format it specifies, or {@code null}
13891       *  if doesn't seem to match any known pattern
13892       */
13893      static decodeFormatInformation(maskedFormatInfo1 /*int*/, maskedFormatInfo2 /*int*/) {
13894          const formatInfo = FormatInformation.doDecodeFormatInformation(maskedFormatInfo1, maskedFormatInfo2);
13895          if (formatInfo !== null) {
13896              return formatInfo;
13897          }
13898          // Should return null, but, some QR codes apparently
13899          // do not mask this info. Try again by actually masking the pattern
13900          // first
13901          return FormatInformation.doDecodeFormatInformation(maskedFormatInfo1 ^ FormatInformation.FORMAT_INFO_MASK_QR, maskedFormatInfo2 ^ FormatInformation.FORMAT_INFO_MASK_QR);
13902      }
13903      static doDecodeFormatInformation(maskedFormatInfo1 /*int*/, maskedFormatInfo2 /*int*/) {
13904          // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing
13905          let bestDifference = Number.MAX_SAFE_INTEGER;
13906          let bestFormatInfo = 0;
13907          for (const decodeInfo of FormatInformation.FORMAT_INFO_DECODE_LOOKUP) {
13908              const targetInfo = decodeInfo[0];
13909              if (targetInfo === maskedFormatInfo1 || targetInfo === maskedFormatInfo2) {
13910                  // Found an exact match
13911                  return new FormatInformation(decodeInfo[1]);
13912              }
13913              let bitsDifference = FormatInformation.numBitsDiffering(maskedFormatInfo1, targetInfo);
13914              if (bitsDifference < bestDifference) {
13915                  bestFormatInfo = decodeInfo[1];
13916                  bestDifference = bitsDifference;
13917              }
13918              if (maskedFormatInfo1 !== maskedFormatInfo2) {
13919                  // also try the other option
13920                  bitsDifference = FormatInformation.numBitsDiffering(maskedFormatInfo2, targetInfo);
13921                  if (bitsDifference < bestDifference) {
13922                      bestFormatInfo = decodeInfo[1];
13923                      bestDifference = bitsDifference;
13924                  }
13925              }
13926          }
13927          // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits
13928          // differing means we found a match
13929          if (bestDifference <= 3) {
13930              return new FormatInformation(bestFormatInfo);
13931          }
13932          return null;
13933      }
13934      getErrorCorrectionLevel() {
13935          return this.errorCorrectionLevel;
13936      }
13937      getDataMask() {
13938          return this.dataMask;
13939      }
13940      /*@Override*/
13941      hashCode() {
13942          return (this.errorCorrectionLevel.getBits() << 3) | this.dataMask;
13943      }
13944      /*@Override*/
13945      equals(o) {
13946          if (!(o instanceof FormatInformation)) {
13947              return false;
13948          }
13949          const other = o;
13950          return this.errorCorrectionLevel === other.errorCorrectionLevel &&
13951              this.dataMask === other.dataMask;
13952      }
13953  }
13954  FormatInformation.FORMAT_INFO_MASK_QR = 0x5412;
13955  /**
13956   * See ISO 18004:2006, Annex C, Table C.1
13957   */
13958  FormatInformation.FORMAT_INFO_DECODE_LOOKUP = [
13959      Int32Array.from([0x5412, 0x00]),
13960      Int32Array.from([0x5125, 0x01]),
13961      Int32Array.from([0x5E7C, 0x02]),
13962      Int32Array.from([0x5B4B, 0x03]),
13963      Int32Array.from([0x45F9, 0x04]),
13964      Int32Array.from([0x40CE, 0x05]),
13965      Int32Array.from([0x4F97, 0x06]),
13966      Int32Array.from([0x4AA0, 0x07]),
13967      Int32Array.from([0x77C4, 0x08]),
13968      Int32Array.from([0x72F3, 0x09]),
13969      Int32Array.from([0x7DAA, 0x0A]),
13970      Int32Array.from([0x789D, 0x0B]),
13971      Int32Array.from([0x662F, 0x0C]),
13972      Int32Array.from([0x6318, 0x0D]),
13973      Int32Array.from([0x6C41, 0x0E]),
13974      Int32Array.from([0x6976, 0x0F]),
13975      Int32Array.from([0x1689, 0x10]),
13976      Int32Array.from([0x13BE, 0x11]),
13977      Int32Array.from([0x1CE7, 0x12]),
13978      Int32Array.from([0x19D0, 0x13]),
13979      Int32Array.from([0x0762, 0x14]),
13980      Int32Array.from([0x0255, 0x15]),
13981      Int32Array.from([0x0D0C, 0x16]),
13982      Int32Array.from([0x083B, 0x17]),
13983      Int32Array.from([0x355F, 0x18]),
13984      Int32Array.from([0x3068, 0x19]),
13985      Int32Array.from([0x3F31, 0x1A]),
13986      Int32Array.from([0x3A06, 0x1B]),
13987      Int32Array.from([0x24B4, 0x1C]),
13988      Int32Array.from([0x2183, 0x1D]),
13989      Int32Array.from([0x2EDA, 0x1E]),
13990      Int32Array.from([0x2BED, 0x1F]),
13991  ];
13992
13993  /**
13994   * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will
13995   * use blocks of differing sizes within one version, so, this encapsulates the parameters for
13996   * each set of blocks. It also holds the number of error-correction codewords per block since it
13997   * will be the same across all blocks within one version.</p>
13998   */
13999  class ECBlocks {
14000      constructor(ecCodewordsPerBlock /*int*/, ...ecBlocks) {
14001          this.ecCodewordsPerBlock = ecCodewordsPerBlock;
14002          this.ecBlocks = ecBlocks;
14003      }
14004      getECCodewordsPerBlock() {
14005          return this.ecCodewordsPerBlock;
14006      }
14007      getNumBlocks() {
14008          let total = 0;
14009          const ecBlocks = this.ecBlocks;
14010          for (const ecBlock of ecBlocks) {
14011              total += ecBlock.getCount();
14012          }
14013          return total;
14014      }
14015      getTotalECCodewords() {
14016          return this.ecCodewordsPerBlock * this.getNumBlocks();
14017      }
14018      getECBlocks() {
14019          return this.ecBlocks;
14020      }
14021  }
14022
14023  /**
14024   * <p>Encapsulates the parameters for one error-correction block in one symbol version.
14025   * This includes the number of data codewords, and the number of times a block with these
14026   * parameters is used consecutively in the QR code version's format.</p>
14027   */
14028  class ECB {
14029      constructor(count /*int*/, dataCodewords /*int*/) {
14030          this.count = count;
14031          this.dataCodewords = dataCodewords;
14032      }
14033      getCount() {
14034          return this.count;
14035      }
14036      getDataCodewords() {
14037          return this.dataCodewords;
14038      }
14039  }
14040
14041  /*
14042   * Copyright 2007 ZXing authors
14043   *
14044   * Licensed under the Apache License, Version 2.0 (the "License");
14045   * you may not use this file except in compliance with the License.
14046   * You may obtain a copy of the License at
14047   *
14048   *      http://www.apache.org/licenses/LICENSE-2.0
14049   *
14050   * Unless required by applicable law or agreed to in writing, software
14051   * distributed under the License is distributed on an "AS IS" BASIS,
14052   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14053   * See the License for the specific language governing permissions and
14054   * limitations under the License.
14055   
vendor: 21,154 bytes, lines 14055-14357
14055*/
14056  /**
14057   * See ISO 18004:2006 Annex D
14058   *
14059   * @author Sean Owen
14060   */
14061  class Version {
14062      constructor(versionNumber /*int*/, alignmentPatternCenters, ...ecBlocks) {
14063          this.versionNumber = versionNumber;
14064          this.alignmentPatternCenters = alignmentPatternCenters;
14065          this.ecBlocks = ecBlocks;
14066          let total = 0;
14067          const ecCodewords = ecBlocks[0].getECCodewordsPerBlock();
14068          const ecbArray = ecBlocks[0].getECBlocks();
14069          for (const ecBlock of ecbArray) {
14070              total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);
14071          }
14072          this.totalCodewords = total;
14073      }
14074      getVersionNumber() {
14075          return this.versionNumber;
14076      }
14077      getAlignmentPatternCenters() {
14078          return this.alignmentPatternCenters;
14079      }
14080      getTotalCodewords() {
14081          return this.totalCodewords;
14082      }
14083      getDimensionForVersion() {
14084          return 17 + 4 * this.versionNumber;
14085      }
14086      getECBlocksForLevel(ecLevel) {
14087          return this.ecBlocks[ecLevel.getValue()];
14088          // TYPESCRIPTPORT: original was using ordinal, and using the order of levels as defined in ErrorCorrectionLevel enum (LMQH)
14089          // I will use the direct value from ErrorCorrectionLevelValues enum which in typescript goes to a number
14090      }
14091      /**
14092       * <p>Deduces version information purely from QR Code dimensions.</p>
14093       *
14094       * @param dimension dimension in modules
14095       * @return Version for a QR Code of that dimension
14096       * @throws FormatException if dimension is not 1 mod 4
14097       */
14098      static getProvisionalVersionForDimension(dimension /*int*/) {
14099          if (dimension % 4 !== 1) {
14100              throw new FormatException();
14101          }
14102          try {
14103              return this.getVersionForNumber((dimension - 17) / 4);
14104          }
14105          catch (ignored /*: IllegalArgumentException*/) {
14106              throw new FormatException();
14107          }
14108      }
14109      static getVersionForNumber(versionNumber /*int*/) {
14110          if (versionNumber < 1 || versionNumber > 40) {
14111              throw new IllegalArgumentException();
14112          }
14113          return Version.VERSIONS[versionNumber - 1];
14114      }
14115      static decodeVersionInformation(versionBits /*int*/) {
14116          let bestDifference = Number.MAX_SAFE_INTEGER;
14117          let bestVersion = 0;
14118          for (let i = 0; i < Version.VERSION_DECODE_INFO.length; i++) {
14119              const targetVersion = Version.VERSION_DECODE_INFO[i];
14120              // Do the version info bits match exactly? done.
14121              if (targetVersion === versionBits) {
14122                  return Version.getVersionForNumber(i + 7);
14123              }
14124              // Otherwise see if this is the closest to a real version info bit string
14125              // we have seen so far
14126              const bitsDifference = FormatInformation.numBitsDiffering(versionBits, targetVersion);
14127              if (bitsDifference < bestDifference) {
14128                  bestVersion = i + 7;
14129                  bestDifference = bitsDifference;
14130              }
14131          }
14132          // We can tolerate up to 3 bits of error since no two version info codewords will
14133          // differ in less than 8 bits.
14134          if (bestDifference <= 3) {
14135              return Version.getVersionForNumber(bestVersion);
14136          }
14137          // If we didn't find a close enough match, fail
14138          return null;
14139      }
14140      /**
14141       * See ISO 18004:2006 Annex E
14142       */
14143      buildFunctionPattern() {
14144          const dimension = this.getDimensionForVersion();
14145          const bitMatrix = new BitMatrix(dimension);
14146          // Top left finder pattern + separator + format
14147          bitMatrix.setRegion(0, 0, 9, 9);
14148          // Top right finder pattern + separator + format
14149          bitMatrix.setRegion(dimension - 8, 0, 8, 9);
14150          // Bottom left finder pattern + separator + format
14151          bitMatrix.setRegion(0, dimension - 8, 9, 8);
14152          // Alignment patterns
14153          const max = this.alignmentPatternCenters.length;
14154          for (let x = 0; x < max; x++) {
14155              const i = this.alignmentPatternCenters[x] - 2;
14156              for (let y = 0; y < max; y++) {
14157                  if ((x === 0 && (y === 0 || y === max - 1)) || (x === max - 1 && y === 0)) {
14158                      // No alignment patterns near the three finder patterns
14159                      continue;
14160                  }
14161                  bitMatrix.setRegion(this.alignmentPatternCenters[y] - 2, i, 5, 5);
14162              }
14163          }
14164          // Vertical timing pattern
14165          bitMatrix.setRegion(6, 9, 1, dimension - 17);
14166          // Horizontal timing pattern
14167          bitMatrix.setRegion(9, 6, dimension - 17, 1);
14168          if (this.versionNumber > 6) {
14169              // Version info, top right
14170              bitMatrix.setRegion(dimension - 11, 0, 3, 6);
14171              // Version info, bottom left
14172              bitMatrix.setRegion(0, dimension - 11, 6, 3);
14173          }
14174          return bitMatrix;
14175      }
14176      /*@Override*/
14177      toString() {
14178          return '' + this.versionNumber;
14179      }
14180  }
14181  /**
14182     * See ISO 18004:2006 Annex D.
14183     * Element i represents the raw version bits that specify version i + 7
14184     */
14185  Version.VERSION_DECODE_INFO = Int32Array.from([
14186      0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,
14187      0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,
14188      0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,
14189      0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,
14190      0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,
14191      0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,
14192      0x2542E, 0x26A64, 0x27541, 0x28C69
14193  ]);
14194  /**
14195     * See ISO 18004:2006 6.5.1 Table 9
14196     */
14197  Version.VERSIONS = [
14198      new Version(1, new Int32Array(0), 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))),
14199      new Version(2, Int32Array.from([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))),
14200      new Version(3, Int32Array.from([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))),
14201      new Version(4, Int32Array.from([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))),
14202      new Version(5, Int32Array.from([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))),
14203      new Version(6, Int32Array.from([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))),
14204      new Version(7, Int32Array.from([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))),
14205      new Version(8, Int32Array.from([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))),
14206      new Version(9, Int32Array.from([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))),
14207      new Version(10, Int32Array.from([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))),
14208      new Version(11, Int32Array.from([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))),
14209      new Version(12, Int32Array.from([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))),
14210      new Version(13, Int32Array.from([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))),
14211      new Version(14, Int32Array.from([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))),
14212      new Version(15, Int32Array.from([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))),
14213      new Version(16, Int32Array.from([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))),
14214      new Version(17, Int32Array.from([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))),
14215      new Version(18, Int32Array.from([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))),
14216      new Version(19, Int32Array.from([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))),
14217      new Version(20, Int32Array.from([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))),
14218      new Version(21, Int32Array.from([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))),
14219      new Version(22, Int32Array.from([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))),
14220      new Version(23, Int32Array.from([6, 30, 54, 78, 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))),
14221      new Version(24, Int32Array.from([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))),
14222      new Version(25, Int32Array.from([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))),
14223      new Version(26, Int32Array.from([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))),
14224      new Version(27, Int32Array.from([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))),
14225      new Version(28, Int32Array.from([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))),
14226      new Version(29, Int32Array.from([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))),
14227      new Version(30, Int32Array.from([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))),
14228      new Version(31, Int32Array.from([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))),
14229      new Version(32, Int32Array.from([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))),
14230      new Version(33, Int32Array.from([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))),
14231      new Version(34, Int32Array.from([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))),
14232      new Version(35, Int32Array.from([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))),
14233      new Version(36, Int32Array.from([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))),
14234      new Version(37, Int32Array.from([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))),
14235      new Version(38, Int32Array.from([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))),
14236      new Version(39, Int32Array.from([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))),
14237      new Version(40, Int32Array.from([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 ECBlocks(30, new ECB(34, 24), new ECB(34, 25)), new ECBlocks(30, new ECB(20, 15), new ECB(61, 16)))
14238  ];
14239
14240  /*
14241   * Copyright 2007 ZXing authors
14242   *
14243   * Licensed under the Apache License, Version 2.0 (the "License");
14244   * you may not use this file except in compliance with the License.
14245   * You may obtain a copy of the License at
14246   *
14247   *      http://www.apache.org/licenses/LICENSE-2.0
14248   *
14249   * Unless required by applicable law or agreed to in writing, software
14250   * distributed under the License is distributed on an "AS IS" BASIS,
14251   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14252   * See the License for the specific language governing permissions and
14253   * limitations under the License.
14254   */
14255  var DataMaskValues;
14256  (function (DataMaskValues) {
14257      DataMaskValues[DataMaskValues["DATA_MASK_000"] = 0] = "DATA_MASK_000";
14258      DataMaskValues[DataMaskValues["DATA_MASK_001"] = 1] = "DATA_MASK_001";
14259      DataMaskValues[DataMaskValues["DATA_MASK_010"] = 2] = "DATA_MASK_010";
14260      DataMaskValues[DataMaskValues["DATA_MASK_011"] = 3] = "DATA_MASK_011";
14261      DataMaskValues[DataMaskValues["DATA_MASK_100"] = 4] = "DATA_MASK_100";
14262      DataMaskValues[DataMaskValues["DATA_MASK_101"] = 5] = "DATA_MASK_101";
14263      DataMaskValues[DataMaskValues["DATA_MASK_110"] = 6] = "DATA_MASK_110";
14264      DataMaskValues[DataMaskValues["DATA_MASK_111"] = 7] = "DATA_MASK_111";
14265  })(DataMaskValues || (DataMaskValues = {}));
14266  /**
14267   * <p>Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations
14268   * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix,
14269   * including areas used for finder patterns, timing patterns, etc. These areas should be unused
14270   * after the point they are unmasked anyway.</p>
14271   *
14272   * <p>Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position
14273   * and j is row position. In fact, as the text says, i is row position and j is column position.</p>
14274   *
14275   * @author Sean Owen
14276   */
14277  class DataMask {
14278      // See ISO 18004:2006 6.8.1
14279      constructor(value, isMasked) {
14280          this.value = value;
14281          this.isMasked = isMasked;
14282      }
14283      // End of enum constants.
14284      /**
14285       * <p>Implementations of this method reverse the data masking process applied to a QR Code and
14286       * make its bits ready to read.</p>
14287       *
14288       * @param bits representation of QR Code bits
14289       * @param dimension dimension of QR Code, represented by bits, being unmasked
14290       */
14291      unmaskBitMatrix(bits, dimension /*int*/) {
14292          for (let i = 0; i < dimension; i++) {
14293              for (let j = 0; j < dimension; j++) {
14294                  if (this.isMasked(i, j)) {
14295                      bits.flip(j, i);
14296                  }
14297              }
14298          }
14299      }
14300  }
14301  DataMask.values = new Map([
14302      /**
14303       * 000: mask bits for which (x + y) mod 2 == 0
14304       */
14305      [DataMaskValues.DATA_MASK_000, new DataMask(DataMaskValues.DATA_MASK_000, (i /*int*/, j /*int*/) => { return ((i + j) & 0x01) === 0; })],
14306      /**
14307       * 001: mask bits for which x mod 2 == 0
14308       */
14309      [DataMaskValues.DATA_MASK_001, new DataMask(DataMaskValues.DATA_MASK_001, (i /*int*/, j /*int*/) => { return (i & 0x01) === 0; })],
14310      /**
14311       * 010: mask bits for which y mod 3 == 0
14312       */
14313      [DataMaskValues.DATA_MASK_010, new DataMask(DataMaskValues.DATA_MASK_010, (i /*int*/, j /*int*/) => { return j % 3 === 0; })],
14314      /**
14315       * 011: mask bits for which (x + y) mod 3 == 0
14316       */
14317      [DataMaskValues.DATA_MASK_011, new DataMask(DataMaskValues.DATA_MASK_011, (i /*int*/, j /*int*/) => { return (i + j) % 3 === 0; })],
14318      /**
14319       * 100: mask bits for which (x/2 + y/3) mod 2 == 0
14320       */
14321      [DataMaskValues.DATA_MASK_100, new DataMask(DataMaskValues.DATA_MASK_100, (i /*int*/, j /*int*/) => { return ((Math.floor(i / 2) + Math.floor(j / 3)) & 0x01) === 0; })],
14322      /**
14323       * 101: mask bits for which xy mod 2 + xy mod 3 == 0
14324       * equivalently, such that xy mod 6 == 0
14325       */
14326      [DataMaskValues.DATA_MASK_101, new DataMask(DataMaskValues.DATA_MASK_101, (i /*int*/, j /*int*/) => { return (i * j) % 6 === 0; })],
14327      /**
14328       * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
14329       * equivalently, such that xy mod 6 < 3
14330       */
14331      [DataMaskValues.DATA_MASK_110, new DataMask(DataMaskValues.DATA_MASK_110, (i /*int*/, j /*int*/) => { return ((i * j) % 6) < 3; })],
14332      /**
14333       * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
14334       * equivalently, such that (x + y + xy mod 3) mod 2 == 0
14335       */
14336      [DataMaskValues.DATA_MASK_111, new DataMask(DataMaskValues.DATA_MASK_111, (i /*int*/, j /*int*/) => { return ((i + j + ((i * j) % 3)) & 0x01) === 0; })],
14337  ]);
14338
14339  /*
14340   * Copyright 2007 ZXing authors
14341   *
14342   * Licensed under the Apache License, Version 2.0 (the "License");
14343   * you may not use this file except in compliance with the License.
14344   * You may obtain a copy of the License at
14345   *
14346   *      http://www.apache.org/licenses/LICENSE-2.0
14347   *
14348   * Unless required by applicable law or agreed to in writing, software
14349   * distributed under the License is distributed on an "AS IS" BASIS,
14350   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14351   * See the License for the specific language governing permissions and
14352   * limitations under the License.
14353   */
14354  /**
14355   * @author Sean Owen
14356   */
14357  
vendor: 33,785 bytes, lines 14357-15095
14357class BitMatrixParser {
14358      /**
14359       * @param bitMatrix {@link BitMatrix} to parse
14360       * @throws FormatException if dimension is not >= 21 and 1 mod 4
14361       */
14362      constructor(bitMatrix) {
14363          const dimension = bitMatrix.getHeight();
14364          if (dimension < 21 || (dimension & 0x03) !== 1) {
14365              throw new FormatException();
14366          }
14367          this.bitMatrix = bitMatrix;
14368      }
14369      /**
14370       * <p>Reads format information from one of its two locations within the QR Code.</p>
14371       *
14372       * @return {@link FormatInformation} encapsulating the QR Code's format info
14373       * @throws FormatException if both format information locations cannot be parsed as
14374       * the valid encoding of format information
14375       */
14376      readFormatInformation() {
14377          if (this.parsedFormatInfo !== null && this.parsedFormatInfo !== undefined) {
14378              return this.parsedFormatInfo;
14379          }
14380          // Read top-left format info bits
14381          let formatInfoBits1 = 0;
14382          for (let i = 0; i < 6; i++) {
14383              formatInfoBits1 = this.copyBit(i, 8, formatInfoBits1);
14384          }
14385          // .. and skip a bit in the timing pattern ...
14386          formatInfoBits1 = this.copyBit(7, 8, formatInfoBits1);
14387          formatInfoBits1 = this.copyBit(8, 8, formatInfoBits1);
14388          formatInfoBits1 = this.copyBit(8, 7, formatInfoBits1);
14389          // .. and skip a bit in the timing pattern ...
14390          for (let j = 5; j >= 0; j--) {
14391              formatInfoBits1 = this.copyBit(8, j, formatInfoBits1);
14392          }
14393          // Read the top-right/bottom-left pattern too
14394          const dimension = this.bitMatrix.getHeight();
14395          let formatInfoBits2 = 0;
14396          const jMin = dimension - 7;
14397          for (let j = dimension - 1; j >= jMin; j--) {
14398              formatInfoBits2 = this.copyBit(8, j, formatInfoBits2);
14399          }
14400          for (let i = dimension - 8; i < dimension; i++) {
14401              formatInfoBits2 = this.copyBit(i, 8, formatInfoBits2);
14402          }
14403          this.parsedFormatInfo = FormatInformation.decodeFormatInformation(formatInfoBits1, formatInfoBits2);
14404          if (this.parsedFormatInfo !== null) {
14405              return this.parsedFormatInfo;
14406          }
14407          throw new FormatException();
14408      }
14409      /**
14410       * <p>Reads version information from one of its two locations within the QR Code.</p>
14411       *
14412       * @return {@link Version} encapsulating the QR Code's version
14413       * @throws FormatException if both version information locations cannot be parsed as
14414       * the valid encoding of version information
14415       */
14416      readVersion() {
14417          if (this.parsedVersion !== null && this.parsedVersion !== undefined) {
14418              return this.parsedVersion;
14419          }
14420          const dimension = this.bitMatrix.getHeight();
14421          const provisionalVersion = Math.floor((dimension - 17) / 4);
14422          if (provisionalVersion <= 6) {
14423              return Version.getVersionForNumber(provisionalVersion);
14424          }
14425          // Read top-right version info: 3 wide by 6 tall
14426          let versionBits = 0;
14427          const ijMin = dimension - 11;
14428          for (let j = 5; j >= 0; j--) {
14429              for (let i = dimension - 9; i >= ijMin; i--) {
14430                  versionBits = this.copyBit(i, j, versionBits);
14431              }
14432          }
14433          let theParsedVersion = Version.decodeVersionInformation(versionBits);
14434          if (theParsedVersion !== null && theParsedVersion.getDimensionForVersion() === dimension) {
14435              this.parsedVersion = theParsedVersion;
14436              return theParsedVersion;
14437          }
14438          // Hmm, failed. Try bottom left: 6 wide by 3 tall
14439          versionBits = 0;
14440          for (let i = 5; i >= 0; i--) {
14441              for (let j = dimension - 9; j >= ijMin; j--) {
14442                  versionBits = this.copyBit(i, j, versionBits);
14443              }
14444          }
14445          theParsedVersion = Version.decodeVersionInformation(versionBits);
14446          if (theParsedVersion !== null && theParsedVersion.getDimensionForVersion() === dimension) {
14447              this.parsedVersion = theParsedVersion;
14448              return theParsedVersion;
14449          }
14450          throw new FormatException();
14451      }
14452      copyBit(i /*int*/, j /*int*/, versionBits /*int*/) {
14453          const bit = this.isMirror ? this.bitMatrix.get(j, i) : this.bitMatrix.get(i, j);
14454          return bit ? (versionBits << 1) | 0x1 : versionBits << 1;
14455      }
14456      /**
14457       * <p>Reads the bits in the {@link BitMatrix} representing the finder pattern in the
14458       * correct order in order to reconstruct the codewords bytes contained within the
14459       * QR Code.</p>
14460       *
14461       * @return bytes encoded within the QR Code
14462       * @throws FormatException if the exact number of bytes expected is not read
14463       */
14464      readCodewords() {
14465          const formatInfo = this.readFormatInformation();
14466          const version = this.readVersion();
14467          // Get the data mask for the format used in this QR Code. This will exclude
14468          // some bits from reading as we wind through the bit matrix.
14469          const dataMask = DataMask.values.get(formatInfo.getDataMask());
14470          const dimension = this.bitMatrix.getHeight();
14471          dataMask.unmaskBitMatrix(this.bitMatrix, dimension);
14472          const functionPattern = version.buildFunctionPattern();
14473          let readingUp = true;
14474          const result = new Uint8Array(version.getTotalCodewords());
14475          let resultOffset = 0;
14476          let currentByte = 0;
14477          let bitsRead = 0;
14478          // Read columns in pairs, from right to left
14479          for (let j = dimension - 1; j > 0; j -= 2) {
14480              if (j === 6) {
14481                  // Skip whole column with vertical alignment pattern
14482                  // saves time and makes the other code proceed more cleanly
14483                  j--;
14484              }
14485              // Read alternatingly from bottom to top then top to bottom
14486              for (let count = 0; count < dimension; count++) {
14487                  const i = readingUp ? dimension - 1 - count : count;
14488                  for (let col = 0; col < 2; col++) {
14489                      // Ignore bits covered by the function pattern
14490                      if (!functionPattern.get(j - col, i)) {
14491                          // Read a bit
14492                          bitsRead++;
14493                          currentByte <<= 1;
14494                          if (this.bitMatrix.get(j - col, i)) {
14495                              currentByte |= 1;
14496                          }
14497                          // If we've made a whole byte, save it off
14498                          if (bitsRead === 8) {
14499                              result[resultOffset++] = /*(byte) */ currentByte;
14500                              bitsRead = 0;
14501                              currentByte = 0;
14502                          }
14503                      }
14504                  }
14505              }
14506              readingUp = !readingUp; // readingUp ^= true; // readingUp = !readingUp; // switch directions
14507          }
14508          if (resultOffset !== version.getTotalCodewords()) {
14509              throw new FormatException();
14510          }
14511          return result;
14512      }
14513      /**
14514       * Revert the mask removal done while reading the code words. The bit matrix should revert to its original state.
14515       */
14516      remask() {
14517          if (this.parsedFormatInfo === null) {
14518              return; // We have no format information, and have no data mask
14519          }
14520          const dataMask = DataMask.values.get(this.parsedFormatInfo.getDataMask());
14521          const dimension = this.bitMatrix.getHeight();
14522          dataMask.unmaskBitMatrix(this.bitMatrix, dimension);
14523      }
14524      /**
14525       * Prepare the parser for a mirrored operation.
14526       * This flag has effect only on the {@link #readFormatInformation()} and the
14527       * {@link #readVersion()}. Before proceeding with {@link #readCodewords()} the
14528       * {@link #mirror()} method should be called.
14529       *
14530       * @param mirror Whether to read version and format information mirrored.
14531       */
14532      setMirror(isMirror) {
14533          this.parsedVersion = null;
14534          this.parsedFormatInfo = null;
14535          this.isMirror = isMirror;
14536      }
14537      /** Mirror the bit matrix in order to attempt a second reading. */
14538      mirror() {
14539          const bitMatrix = this.bitMatrix;
14540          for (let x = 0, width = bitMatrix.getWidth(); x < width; x++) {
14541              for (let y = x + 1, height = bitMatrix.getHeight(); y < height; y++) {
14542                  if (bitMatrix.get(x, y) !== bitMatrix.get(y, x)) {
14543                      bitMatrix.flip(y, x);
14544                      bitMatrix.flip(x, y);
14545                  }
14546              }
14547          }
14548      }
14549  }
14550
14551  /*
14552   * Copyright 2007 ZXing authors
14553   *
14554   * Licensed under the Apache License, Version 2.0 (the "License");
14555   * you may not use this file except in compliance with the License.
14556   * You may obtain a copy of the License at
14557   *
14558   *      http://www.apache.org/licenses/LICENSE-2.0
14559   *
14560   * Unless required by applicable law or agreed to in writing, software
14561   * distributed under the License is distributed on an "AS IS" BASIS,
14562   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14563   * See the License for the specific language governing permissions and
14564   * limitations under the License.
14565   */
14566  /**
14567   * <p>Encapsulates a block of data within a QR Code. QR Codes may split their data into
14568   * multiple blocks, each of which is a unit of data and error-correction codewords. Each
14569   * is represented by an instance of this class.</p>
14570   *
14571   * @author Sean Owen
14572   */
14573  class DataBlock {
14574      constructor(numDataCodewords /*int*/, codewords) {
14575          this.numDataCodewords = numDataCodewords;
14576          this.codewords = codewords;
14577      }
14578      /**
14579       * <p>When QR Codes use multiple data blocks, they are actually interleaved.
14580       * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
14581       * method will separate the data into original blocks.</p>
14582       *
14583       * @param rawCodewords bytes as read directly from the QR Code
14584       * @param version version of the QR Code
14585       * @param ecLevel error-correction level of the QR Code
14586       * @return DataBlocks containing original bytes, "de-interleaved" from representation in the
14587       *         QR Code
14588       */
14589      static getDataBlocks(rawCodewords, version, ecLevel) {
14590          if (rawCodewords.length !== version.getTotalCodewords()) {
14591              throw new IllegalArgumentException();
14592          }
14593          // Figure out the number and size of data blocks used by this version and
14594          // error correction level
14595          const ecBlocks = version.getECBlocksForLevel(ecLevel);
14596          // First count the total number of data blocks
14597          let totalBlocks = 0;
14598          const ecBlockArray = ecBlocks.getECBlocks();
14599          for (const ecBlock of ecBlockArray) {
14600              totalBlocks += ecBlock.getCount();
14601          }
14602          // Now establish DataBlocks of the appropriate size and number of data codewords
14603          const result = new Array(totalBlocks);
14604          let numResultBlocks = 0;
14605          for (const ecBlock of ecBlockArray) {
14606              for (let i = 0; i < ecBlock.getCount(); i++) {
14607                  const numDataCodewords = ecBlock.getDataCodewords();
14608                  const numBlockCodewords = ecBlocks.getECCodewordsPerBlock() + numDataCodewords;
14609                  result[numResultBlocks++] = new DataBlock(numDataCodewords, new Uint8Array(numBlockCodewords));
14610              }
14611          }
14612          // All blocks have the same amount of data, except that the last n
14613          // (where n may be 0) have 1 more byte. Figure out where these start.
14614          const shorterBlocksTotalCodewords = result[0].codewords.length;
14615          let longerBlocksStartAt = result.length - 1;
14616          // TYPESCRIPTPORT: check length is correct here
14617          while (longerBlocksStartAt >= 0) {
14618              const numCodewords = result[longerBlocksStartAt].codewords.length;
14619              if (numCodewords === shorterBlocksTotalCodewords) {
14620                  break;
14621              }
14622              longerBlocksStartAt--;
14623          }
14624          longerBlocksStartAt++;
14625          const shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.getECCodewordsPerBlock();
14626          // The last elements of result may be 1 element longer
14627          // first fill out as many elements as all of them have
14628          let rawCodewordsOffset = 0;
14629          for (let i = 0; i < shorterBlocksNumDataCodewords; i++) {
14630              for (let j = 0; j < numResultBlocks; j++) {
14631                  result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];
14632              }
14633          }
14634          // Fill out the last data block in the longer ones
14635          for (let j = longerBlocksStartAt; j < numResultBlocks; j++) {
14636              result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
14637          }
14638          // Now add in error correction blocks
14639          const max = result[0].codewords.length;
14640          for (let i = shorterBlocksNumDataCodewords; i < max; i++) {
14641              for (let j = 0; j < numResultBlocks; j++) {
14642                  const iOffset = j < longerBlocksStartAt ? i : i + 1;
14643                  result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];
14644              }
14645          }
14646          return result;
14647      }
14648      getNumDataCodewords() {
14649          return this.numDataCodewords;
14650      }
14651      getCodewords() {
14652          return this.codewords;
14653      }
14654  }
14655
14656  /*
14657   * Copyright 2007 ZXing authors
14658   *
14659   * Licensed under the Apache License, Version 2.0 (the "License");
14660   * you may not use this file except in compliance with the License.
14661   * You may obtain a copy of the License at
14662   *
14663   *      http://www.apache.org/licenses/LICENSE-2.0
14664   *
14665   * Unless required by applicable law or agreed to in writing, software
14666   * distributed under the License is distributed on an "AS IS" BASIS,
14667   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14668   * See the License for the specific language governing permissions and
14669   * limitations under the License.
14670   */
14671  var ModeValues;
14672  (function (ModeValues) {
14673      ModeValues[ModeValues["TERMINATOR"] = 0] = "TERMINATOR";
14674      ModeValues[ModeValues["NUMERIC"] = 1] = "NUMERIC";
14675      ModeValues[ModeValues["ALPHANUMERIC"] = 2] = "ALPHANUMERIC";
14676      ModeValues[ModeValues["STRUCTURED_APPEND"] = 3] = "STRUCTURED_APPEND";
14677      ModeValues[ModeValues["BYTE"] = 4] = "BYTE";
14678      ModeValues[ModeValues["ECI"] = 5] = "ECI";
14679      ModeValues[ModeValues["KANJI"] = 6] = "KANJI";
14680      ModeValues[ModeValues["FNC1_FIRST_POSITION"] = 7] = "FNC1_FIRST_POSITION";
14681      ModeValues[ModeValues["FNC1_SECOND_POSITION"] = 8] = "FNC1_SECOND_POSITION";
14682      /** See GBT 18284-2000; "Hanzi" is a transliteration of this mode name. */
14683      ModeValues[ModeValues["HANZI"] = 9] = "HANZI";
14684  })(ModeValues || (ModeValues = {}));
14685  /**
14686   * <p>See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which
14687   * data can be encoded to bits in the QR code standard.</p>
14688   *
14689   * @author Sean Owen
14690   */
14691  class Mode$2 {
14692      constructor(value, stringValue, characterCountBitsForVersions, bits /*int*/) {
14693          this.value = value;
14694          this.stringValue = stringValue;
14695          this.characterCountBitsForVersions = characterCountBitsForVersions;
14696          this.bits = bits;
14697          Mode$2.FOR_BITS.set(bits, this);
14698          Mode$2.FOR_VALUE.set(value, this);
14699      }
14700      /**
14701       * @param bits four bits encoding a QR Code data mode
14702       * @return Mode encoded by these bits
14703       * @throws IllegalArgumentException if bits do not correspond to a known mode
14704       */
14705      static forBits(bits /*int*/) {
14706          const mode = Mode$2.FOR_BITS.get(bits);
14707          if (undefined === mode) {
14708              throw new IllegalArgumentException();
14709          }
14710          return mode;
14711      }
14712      /**
14713       * @param version version in question
14714       * @return number of bits used, in this QR Code symbol {@link Version}, to encode the
14715       *         count of characters that will follow encoded in this Mode
14716       */
14717      getCharacterCountBits(version) {
14718          const versionNumber = version.getVersionNumber();
14719          let offset;
14720          if (versionNumber <= 9) {
14721              offset = 0;
14722          }
14723          else if (versionNumber <= 26) {
14724              offset = 1;
14725          }
14726          else {
14727              offset = 2;
14728          }
14729          return this.characterCountBitsForVersions[offset];
14730      }
14731      getValue() {
14732          return this.value;
14733      }
14734      getBits() {
14735          return this.bits;
14736      }
14737      equals(o) {
14738          if (!(o instanceof Mode$2)) {
14739              return false;
14740          }
14741          const other = o;
14742          return this.value === other.value;
14743      }
14744      toString() {
14745          return this.stringValue;
14746      }
14747  }
14748  Mode$2.FOR_BITS = new Map();
14749  Mode$2.FOR_VALUE = new Map();
14750  Mode$2.TERMINATOR = new Mode$2(ModeValues.TERMINATOR, 'TERMINATOR', Int32Array.from([0, 0, 0]), 0x00); // Not really a mode...
14751  Mode$2.NUMERIC = new Mode$2(ModeValues.NUMERIC, 'NUMERIC', Int32Array.from([10, 12, 14]), 0x01);
14752  Mode$2.ALPHANUMERIC = new Mode$2(ModeValues.ALPHANUMERIC, 'ALPHANUMERIC', Int32Array.from([9, 11, 13]), 0x02);
14753  Mode$2.STRUCTURED_APPEND = new Mode$2(ModeValues.STRUCTURED_APPEND, 'STRUCTURED_APPEND', Int32Array.from([0, 0, 0]), 0x03); // Not supported
14754  Mode$2.BYTE = new Mode$2(ModeValues.BYTE, 'BYTE', Int32Array.from([8, 16, 16]), 0x04);
14755  Mode$2.ECI = new Mode$2(ModeValues.ECI, 'ECI', Int32Array.from([0, 0, 0]), 0x07); // character counts don't apply
14756  Mode$2.KANJI = new Mode$2(ModeValues.KANJI, 'KANJI', Int32Array.from([8, 10, 12]), 0x08);
14757  Mode$2.FNC1_FIRST_POSITION = new Mode$2(ModeValues.FNC1_FIRST_POSITION, 'FNC1_FIRST_POSITION', Int32Array.from([0, 0, 0]), 0x05);
14758  Mode$2.FNC1_SECOND_POSITION = new Mode$2(ModeValues.FNC1_SECOND_POSITION, 'FNC1_SECOND_POSITION', Int32Array.from([0, 0, 0]), 0x09);
14759  /** See GBT 18284-2000; "Hanzi" is a transliteration of this mode name. */
14760  Mode$2.HANZI = new Mode$2(ModeValues.HANZI, 'HANZI', Int32Array.from([8, 10, 12]), 0x0D);
14761
14762  /*
14763   * Copyright 2007 ZXing authors
14764   *
14765   * Licensed under the Apache License, Version 2.0 (the "License");
14766   * you may not use this file except in compliance with the License.
14767   * You may obtain a copy of the License at
14768   *
14769   *      http://www.apache.org/licenses/LICENSE-2.0
14770   *
14771   * Unless required by applicable law or agreed to in writing, software
14772   * distributed under the License is distributed on an "AS IS" BASIS,
14773   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14774   * See the License for the specific language governing permissions and
14775   * limitations under the License.
14776   */
14777  /*import java.io.UnsupportedEncodingException;*/
14778  /*import java.util.ArrayList;*/
14779  /*import java.util.Collection;*/
14780  /*import java.util.List;*/
14781  /*import java.util.Map;*/
14782  /**
14783   * <p>QR Codes can encode text as bits in one of several modes, and can use multiple modes
14784   * in one QR Code. This class decodes the bits back into text.</p>
14785   *
14786   * <p>See ISO 18004:2006, 6.4.3 - 6.4.7</p>
14787   *
14788   * @author Sean Owen
14789   */
14790  class DecodedBitStreamParser$1 {
14791      static decode(bytes, version, ecLevel, hints) {
14792          const bits = new BitSource(bytes);
14793          let result = new StringBuilder();
14794          const byteSegments = new Array(); // 1
14795          // TYPESCRIPTPORT: I do not use constructor with size 1 as in original Java means capacity and the array length is checked below
14796          let symbolSequence = -1;
14797          let parityData = -1;
14798          try {
14799              let currentCharacterSetECI = null;
14800              let fc1InEffect = false;
14801              let mode;
14802              do {
14803                  // While still another segment to read...
14804                  if (bits.available() < 4) {
14805                      // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
14806                      mode = Mode$2.TERMINATOR;
14807                  }
14808                  else {
14809                      const modeBits = bits.readBits(4);
14810                      mode = Mode$2.forBits(modeBits); // mode is encoded by 4 bits
14811                  }
14812                  switch (mode) {
14813                      case Mode$2.TERMINATOR:
14814                          break;
14815                      case Mode$2.FNC1_FIRST_POSITION:
14816                      case Mode$2.FNC1_SECOND_POSITION:
14817                          // We do little with FNC1 except alter the parsed result a bit according to the spec
14818                          fc1InEffect = true;
14819                          break;
14820                      case Mode$2.STRUCTURED_APPEND:
14821                          if (bits.available() < 16) {
14822                              throw new FormatException();
14823                          }
14824                          // sequence number and parity is added later to the result metadata
14825                          // Read next 8 bits (symbol sequence #) and 8 bits (data: parity), then continue
14826                          symbolSequence = bits.readBits(8);
14827                          parityData = bits.readBits(8);
14828                          break;
14829                      case Mode$2.ECI:
14830                          // Count doesn't apply to ECI
14831                          const value = DecodedBitStreamParser$1.parseECIValue(bits);
14832                          currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
14833                          if (currentCharacterSetECI === null) {
14834                              throw new FormatException();
14835                          }
14836                          break;
14837                      case Mode$2.HANZI:
14838                          // First handle Hanzi mode which does not start with character count
14839                          // Chinese mode contains a sub set indicator right after mode indicator
14840                          const subset = bits.readBits(4);
14841                          const countHanzi = bits.readBits(mode.getCharacterCountBits(version));
14842                          if (subset === DecodedBitStreamParser$1.GB2312_SUBSET) {
14843                              DecodedBitStreamParser$1.decodeHanziSegment(bits, result, countHanzi);
14844                          }
14845                          break;
14846                      default:
14847                          // "Normal" QR code modes:
14848                          // How many characters will follow, encoded in this mode?
14849                          const count = bits.readBits(mode.getCharacterCountBits(version));
14850                          switch (mode) {
14851                              case Mode$2.NUMERIC:
14852                                  DecodedBitStreamParser$1.decodeNumericSegment(bits, result, count);
14853                                  break;
14854                              case Mode$2.ALPHANUMERIC:
14855                                  DecodedBitStreamParser$1.decodeAlphanumericSegment(bits, result, count, fc1InEffect);
14856                                  break;
14857                              case Mode$2.BYTE:
14858                                  DecodedBitStreamParser$1.decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints);
14859                                  break;
14860                              case Mode$2.KANJI:
14861                                  DecodedBitStreamParser$1.decodeKanjiSegment(bits, result, count);
14862                                  break;
14863                              default:
14864                                  throw new FormatException();
14865                          }
14866                          break;
14867                  }
14868              } while (mode !== Mode$2.TERMINATOR);
14869          }
14870          catch (iae /*: IllegalArgumentException*/) {
14871              // from readBits() calls
14872              throw new FormatException();
14873          }
14874          return new DecoderResult(bytes, result.toString(), byteSegments.length === 0 ? null : byteSegments, ecLevel === null ? null : ecLevel.toString(), symbolSequence, parityData);
14875      }
14876      /**
14877       * See specification GBT 18284-2000
14878       */
14879      static decodeHanziSegment(bits, result, count /*int*/) {
14880          // Don't crash trying to read more bits than we have available.
14881          if (count * 13 > bits.available()) {
14882              throw new FormatException();
14883          }
14884          // Each character will require 2 bytes. Read the characters as 2-byte pairs
14885          // and decode as GB2312 afterwards
14886          const buffer = new Uint8Array(2 * count);
14887          let offset = 0;
14888          while (count > 0) {
14889              // Each 13 bits encodes a 2-byte character
14890              const twoBytes = bits.readBits(13);
14891              let assembledTwoBytes = (((twoBytes / 0x060) << 8) & 0xFFFFFFFF) | (twoBytes % 0x060);
14892              if (assembledTwoBytes < 0x003BF) {
14893                  // In the 0xA1A1 to 0xAAFE range
14894                  assembledTwoBytes += 0x0A1A1;
14895              }
14896              else {
14897                  // In the 0xB0A1 to 0xFAFE range
14898                  assembledTwoBytes += 0x0A6A1;
14899              }
14900              buffer[offset] = /*(byte) */ ((assembledTwoBytes >> 8) & 0xFF);
14901              buffer[offset + 1] = /*(byte) */ (assembledTwoBytes & 0xFF);
14902              offset += 2;
14903              count--;
14904          }
14905          try {
14906              result.append(StringEncoding.decode(buffer, StringUtils.GB2312));
14907              // TYPESCRIPTPORT: TODO: implement GB2312 decode. StringView from MDN could be a starting point
14908          }
14909          catch (ignored /*: UnsupportedEncodingException*/) {
14910              throw new FormatException(ignored);
14911          }
14912      }
14913      static decodeKanjiSegment(bits, result, count /*int*/) {
14914          // Don't crash trying to read more bits than we have available.
14915          if (count * 13 > bits.available()) {
14916              throw new FormatException();
14917          }
14918          // Each character will require 2 bytes. Read the characters as 2-byte pairs
14919          // and decode as Shift_JIS afterwards
14920          const buffer = new Uint8Array(2 * count);
14921          let offset = 0;
14922          while (count > 0) {
14923              // Each 13 bits encodes a 2-byte character
14924              const twoBytes = bits.readBits(13);
14925              let assembledTwoBytes = (((twoBytes / 0x0C0) << 8) & 0xFFFFFFFF) | (twoBytes % 0x0C0);
14926              if (assembledTwoBytes < 0x01F00) {
14927                  // In the 0x8140 to 0x9FFC range
14928                  assembledTwoBytes += 0x08140;
14929              }
14930              else {
14931                  // In the 0xE040 to 0xEBBF range
14932                  assembledTwoBytes += 0x0C140;
14933              }
14934              buffer[offset] = /*(byte) */ (assembledTwoBytes >> 8);
14935              buffer[offset + 1] = /*(byte) */ assembledTwoBytes;
14936              offset += 2;
14937              count--;
14938          }
14939          // Shift_JIS may not be supported in some environments:
14940          try {
14941              result.append(StringEncoding.decode(buffer, StringUtils.SHIFT_JIS));
14942              // TYPESCRIPTPORT: TODO: implement SHIFT_JIS decode. StringView from MDN could be a starting point
14943          }
14944          catch (ignored /*: UnsupportedEncodingException*/) {
14945              throw new FormatException(ignored);
14946          }
14947      }
14948      static decodeByteSegment(bits, result, count /*int*/, currentCharacterSetECI, byteSegments, hints) {
14949          // Don't crash trying to read more bits than we have available.
14950          if (8 * count > bits.available()) {
14951              throw new FormatException();
14952          }
14953          const readBytes = new Uint8Array(count);
14954          for (let i = 0; i < count; i++) {
14955              readBytes[i] = /*(byte) */ bits.readBits(8);
14956          }
14957          let encoding;
14958          if (currentCharacterSetECI === null) {
14959              // The spec isn't clear on this mode; see
14960              // section 6.4.5: t does not say which encoding to assuming
14961              // upon decoding. I have seen ISO-8859-1 used as well as
14962              // Shift_JIS -- without anything like an ECI designator to
14963              // give a hint.
14964              encoding = StringUtils.guessEncoding(readBytes, hints);
14965          }
14966          else {
14967              encoding = currentCharacterSetECI.getName();
14968          }
14969          try {
14970              result.append(StringEncoding.decode(readBytes, encoding));
14971          }
14972          catch (ignored /*: UnsupportedEncodingException*/) {
14973              throw new FormatException(ignored);
14974          }
14975          byteSegments.push(readBytes);
14976      }
14977      static toAlphaNumericChar(value /*int*/) {
14978          if (value >= DecodedBitStreamParser$1.ALPHANUMERIC_CHARS.length) {
14979              throw new FormatException();
14980          }
14981          return DecodedBitStreamParser$1.ALPHANUMERIC_CHARS[value];
14982      }
14983      static decodeAlphanumericSegment(bits, result, count /*int*/, fc1InEffect) {
14984          // Read two characters at a time
14985          const start = result.length();
14986          while (count > 1) {
14987              if (bits.available() < 11) {
14988                  throw new FormatException();
14989              }
14990              const nextTwoCharsBits = bits.readBits(11);
14991              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(Math.floor(nextTwoCharsBits / 45)));
14992              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(nextTwoCharsBits % 45));
14993              count -= 2;
14994          }
14995          if (count === 1) {
14996              // special case: one character left
14997              if (bits.available() < 6) {
14998                  throw new FormatException();
14999              }
15000              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(bits.readBits(6)));
15001          }
15002          // See section 6.4.8.1, 6.4.8.2
15003          if (fc1InEffect) {
15004              // We need to massage the result a bit if in an FNC1 mode:
15005              for (let i = start; i < result.length(); i++) {
15006                  if (result.charAt(i) === '%') {
15007                      if (i < result.length() - 1 && result.charAt(i + 1) === '%') {
15008                          // %% is rendered as %
15009                          result.deleteCharAt(i + 1);
15010                      }
15011                      else {
15012                          // In alpha mode, % should be converted to FNC1 separator 0x1D
15013                          result.setCharAt(i, String.fromCharCode(0x1D));
15014                      }
15015                  }
15016              }
15017          }
15018      }
15019      static decodeNumericSegment(bits, result, count /*int*/) {
15020          // Read three digits at a time
15021          while (count >= 3) {
15022              // Each 10 bits encodes three digits
15023              if (bits.available() < 10) {
15024                  throw new FormatException();
15025              }
15026              const threeDigitsBits = bits.readBits(10);
15027              if (threeDigitsBits >= 1000) {
15028                  throw new FormatException();
15029              }
15030              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(Math.floor(threeDigitsBits / 100)));
15031              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(Math.floor(threeDigitsBits / 10) % 10));
15032              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(threeDigitsBits % 10));
15033              count -= 3;
15034          }
15035          if (count === 2) {
15036              // Two digits left over to read, encoded in 7 bits
15037              if (bits.available() < 7) {
15038                  throw new FormatException();
15039              }
15040              const twoDigitsBits = bits.readBits(7);
15041              if (twoDigitsBits >= 100) {
15042                  throw new FormatException();
15043              }
15044              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(Math.floor(twoDigitsBits / 10)));
15045              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(twoDigitsBits % 10));
15046          }
15047          else if (count === 1) {
15048              // One digit left over to read
15049              if (bits.available() < 4) {
15050                  throw new FormatException();
15051              }
15052              const digitBits = bits.readBits(4);
15053              if (digitBits >= 10) {
15054                  throw new FormatException();
15055              }
15056              result.append(DecodedBitStreamParser$1.toAlphaNumericChar(digitBits));
15057          }
15058      }
15059      static parseECIValue(bits) {
15060          const firstByte = bits.readBits(8);
15061          if ((firstByte & 0x80) === 0) {
15062              // just one byte
15063              return firstByte & 0x7F;
15064          }
15065          if ((firstByte & 0xC0) === 0x80) {
15066              // two bytes
15067              const secondByte = bits.readBits(8);
15068              return (((firstByte & 0x3F) << 8) & 0xFFFFFFFF) | secondByte;
15069          }
15070          if ((firstByte & 0xE0) === 0xC0) {
15071              // three bytes
15072              const secondThirdBytes = bits.readBits(16);
15073              return (((firstByte & 0x1F) << 16) & 0xFFFFFFFF) | secondThirdBytes;
15074          }
15075          throw new FormatException();
15076      }
15077  }
15078  /**
15079   * See ISO 18004:2006, 6.4.4 Table 5
15080   */
15081  DecodedBitStreamParser$1.ALPHANUMERIC_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';
15082  DecodedBitStreamParser$1.GB2312_SUBSET = 1;
15083  // function Uint8ArrayToString(a: Uint8Array): string {
15084  //     const CHUNK_SZ = 0x8000;
15085  //     const c = new StringBuilder();
15086  //     for (let i = 0, length = a.length; i < length; i += CHUNK_SZ) {
15087  //         c.append(String.fromCharCode.apply(null, a.subarray(i, i + CHUNK_SZ)));
15088  //     }
15089  //     return c.toString();
15090  // }
15091
15092  /*
15093   * Copyright 2013 ZXing authors
15094   *
15095   * Licensed under the Apache License, Version 2.0 (the "License");
15096   * you may not use this file except in compliance with the License.
15097   * You may obtain a copy of the License at
15098   *
15099   *      http://www.apache.org/licenses/LICENSE-2.0
15100   *
15101   * Unless required by applicable law or agreed to in writing, software
15102   * distributed under the License is distributed on an "AS IS" BASIS,
15103   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15104   * See the License for the specific language governing permissions and
15105   * limitations under the License.
15106   */
15107  /**
15108   * Meta-data container for QR Code decoding. Instances of this class may be used to convey information back to the
15109   * decoding caller. Callers are expected to process this.
15110   *
15111   * @see com.google.zxing.common.DecoderResult#getOther()
15112   */
15113  class QRCodeDecoderMetaData {
15114      constructor(mirrored) {
15115          this.mirrored = mirrored;
15116      }
15117      /**
15118       * @return true if the QR Code was mirrored.
15119       */
15120      isMirrored() {
15121          return this.mirrored;
15122      }
15123      /**
15124       * Apply the result points' order correction due to mirroring.
15125       *
15126       * @param points Array of points to apply mirror correction to.
15127       */
15128      applyMirroredCorrection(points) {
15129          if (!this.mirrored || points === null || points.length < 3) {
15130              return;
15131          }
15132          const bottomLeft = points[0];
15133          points[0] = points[2];
15134          points[2] = bottomLeft;
15135          // No need to 'fix' top-left and alignment pattern.
15136      }
15137  }
15138
15139  /*
15140   * Copyright 2007 ZXing authors
15141   *
15142   * Licensed under the Apache License, Version 2.0 (the "License");
15143   * you may not use this file except in compliance with the License.
15144   * You may obtain a copy of the License at
15145   *
15146   *      http://www.apache.org/licenses/LICENSE-2.0
15147   *
15148   * Unless required by applicable law or agreed to in writing, software
15149   * distributed under the License is distributed on an "AS IS" BASIS,
15150   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15151   * See the License for the specific language governing permissions and
15152   * limitations under the License.
15153   */
15154  /*import java.util.Map;*/
15155  /**
15156   * <p>The main class which implements QR Code decoding -- as opposed to locating and extracting
15157   * the QR Code from an image.</p>
15158   *
15159   * @author Sean Owen
15160   */
15161  class Decoder {
15162      constructor() {
15163          this.rsDecoder = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256);
15164      }
15165      // public decode(image: boolean[][]): DecoderResult /*throws ChecksumException, FormatException*/ {
15166      //   return decode(image, null)
15167      // }
15168      /**
15169       * <p>Convenience method that can decode a QR Code represented as a 2D array of booleans.
15170       * "true" is taken to mean a black module.</p>
15171       *
15172       * @param image booleans representing white/black QR Code modules
15173       * @param hints decoding hints that should be used to influence decoding
15174       * @return text and bytes encoded within the QR Code
15175       * @throws FormatException if the QR Code cannot be decoded
15176       * @throws ChecksumException if error correction fails
15177       */
15178      decodeBooleanArray(image, hints) {
15179          return this.decodeBitMatrix(BitMatrix.parseFromBooleanArray(image), hints);
15180      }
15181      // public decodeBitMatrix(bits: BitMatrix): DecoderResult /*throws ChecksumException, FormatException*/ {
15182      //   return decode(bits, null)
15183      // }
15184      /**
15185       * <p>Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module.</p>
15186       *
15187       * @param bits booleans representing white/black QR Code modules
15188       * @param hints decoding hints that should be used to influence decoding
15189       * @return text and bytes encoded within the QR Code
15190       * @throws FormatException if the QR Code cannot be decoded
15191       * @throws ChecksumException if error correction fails
15192       */
15193      decodeBitMatrix(bits, hints) {
15194          // Construct a parser and read version, error-correction level
15195          const parser = new BitMatrixParser(bits);
15196          let ex = null;
15197          try {
15198              return this.decodeBitMatrixParser(parser, hints);
15199          }
15200          catch (e /*: FormatException, ChecksumException*/) {
15201              ex = e;
15202          }
15203          try {
15204              // Revert the bit matrix
15205              parser.remask();
vendor: 2,540 bytes, lines 15206-15260
15206              // Will be attempting a mirrored reading of the version and format info.
15207              parser.setMirror(true);
15208              // Preemptively read the version.
15209              parser.readVersion();
15210              // Preemptively read the format information.
15211              parser.readFormatInformation();
15212              /*
15213               * Since we're here, this means we have successfully detected some kind
15214               * of version and format information when mirrored. This is a good sign,
15215               * that the QR code may be mirrored, and we should try once more with a
15216               * mirrored content.
15217               */
15218              // Prepare for a mirrored reading.
15219              parser.mirror();
15220              const result = this.decodeBitMatrixParser(parser, hints);
15221              // Success! Notify the caller that the code was mirrored.
15222              result.setOther(new QRCodeDecoderMetaData(true));
15223              return result;
15224          }
15225          catch (e /*FormatException | ChecksumException*/) {
15226              // Throw the exception from the original reading
15227              if (ex !== null) {
15228                  throw ex;
15229              }
15230              throw e;
15231          }
15232      }
15233      decodeBitMatrixParser(parser, hints) {
15234          const version = parser.readVersion();
15235          const ecLevel = parser.readFormatInformation().getErrorCorrectionLevel();
15236          // Read codewords
15237          const codewords = parser.readCodewords();
15238          // Separate into data blocks
15239          const dataBlocks = DataBlock.getDataBlocks(codewords, version, ecLevel);
15240          // Count total number of data bytes
15241          let totalBytes = 0;
15242          for (const dataBlock of dataBlocks) {
15243              totalBytes += dataBlock.getNumDataCodewords();
15244          }
15245          const resultBytes = new Uint8Array(totalBytes);
15246          let resultOffset = 0;
15247          // Error-correct and copy data blocks together into a stream of bytes
15248          for (const dataBlock of dataBlocks) {
15249              const codewordBytes = dataBlock.getCodewords();
15250              const numDataCodewords = dataBlock.getNumDataCodewords();
15251              this.correctErrors(codewordBytes, numDataCodewords);
15252              for (let i = 0; i < numDataCodewords; i++) {
15253                  resultBytes[resultOffset++] = codewordBytes[i];
15254              }
15255          }
15256          // Decode the contents of that stream of bytes
15257          return DecodedBitStreamParser$1.decode(resultBytes, version, ecLevel, hints);
15258      }
15259      /**
15260       * <p>
15260Given data and error-correction codewords received, possibly corrupted by errors, attempts to
15261       * correct the errors in-place using Reed-Solomon error correction.</p>
15262       *
15263       * @param codewordBytes data and error correction codewords
15264       * @param numDataCodewords number of codewords that are data bytes
15265       * @throws ChecksumException if error correction fails
15266       */
15267      correctErrors(codewordBytes, numDataCodewords /*int*/) {
15268          // const numCodewords = codewordBytes.length;
15269          // First read into an array of ints
15270          const codewordsInts = new Int32Array(codewordBytes);
15271          // TYPESCRIPTPORT: not realy necessary to transform to ints? could redesign everything to work with unsigned bytes?
15272          // const codewordsInts = new Int32Array(numCodewords)
15273          // for (let i = 0; i < numCodewords; i++) {
15274          //   codewordsInts[i] = codewordBytes[i] & 0xFF
15275          // }
15276          try {
15277              this.rsDecoder.decode(codewordsInts, codewordBytes.length - numDataCodewords);
15278          }
15279          catch (ignored /*: ReedSolomonException*/) {
15280              throw new ChecksumException();
15281          }
15282          // Copy back into array of bytes -- only need to worry about the bytes that were data
15283          // We don't care about errors in the error-correction codewords
15284          for (let i = 0; i < numDataCodewords; i++) {
15285              codewordBytes[i] = /*(byte) */ codewordsInts[i];
15286          }
15287      }
15288  }
15289
15290  /*
15291   * Copyright 2007 ZXing authors
15292   *
15293   * Licensed under the Apache License, Version 2.0 (the "License");
15294   * you may not use this file except in compliance with the License.
15295   * You may obtain a copy of the License at
15296   *
15297   *      http://www.apache.org/licenses/LICENSE-2.0
15298   *
15299   * Unless required by applicable law or agreed to in writing, software
15300   * distributed under the License is distributed on an "AS IS" BASIS,
15301   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15302   * See the License for the specific language governing permissions and
15303   * limitations under the License.
15304   */
15305  /**
15306   * <p>Encapsulates an alignment pattern, which are the smaller square patterns found in
15307   * all but the simplest QR Codes.</p>
15308   *
15309   * @author Sean Owen
15310   */
15311  class AlignmentPattern extends ResultPoint {
15312      constructor(posX /*float*/, posY /*float*/, estimatedModuleSize /*float*/) {
15313          super(posX, posY);
15314          this.estimatedModuleSize = estimatedModuleSize;
15315      }
15316      /**
15317       * <p>Determines if this alignment pattern "about equals" an alignment pattern at the stated
15318       * position and size -- meaning, it is at nearly the same center with nearly the same size.</p>
15319       */
15320      aboutEquals(moduleSize /*float*/, i /*float*/, j /*float*/) {
15321          if (Math.abs(i - this.getY()) <= moduleSize && Math.abs(j - this.getX()) <= moduleSize) {
15322              const moduleSizeDiff = Math.abs(moduleSize - this.estimatedModuleSize);
15323              return moduleSizeDiff <= 1.0 || moduleSizeDiff <= this.estimatedModuleSize;
15324          }
15325          return false;
15326      }
15327      /**
15328       * Combines this object's current estimate of a finder pattern position and module size
15329       * with a new estimate. It returns a new {@code FinderPattern} containing an average of the two.
15330       */
15331      combineEstimate(i /*float*/, j /*float*/, newModuleSize /*float*/) {
15332          const combinedX = (this.getX() + j) / 2.0;
15333          const combinedY = (this.getY() + i) / 2.0;
15334          const combinedModuleSize = (this.estimatedModuleSize + newModuleSize) / 2.0;
15335          return new AlignmentPattern(combinedX, combinedY, combinedModuleSize);
15336      }
15337  }
15338
15339  /*
15340   * Copyright 2007 ZXing authors
15341   *
15342   * Licensed under the Apache License, Version 2.0 (the "License");
15343   * you may not use this file except in compliance with the License.
15344   * You may obtain a copy of the License at
15345   *
15346   *      http://www.apache.org/licenses/LICENSE-2.0
15347   *
15348   * Unless required by applicable law or agreed to in writing, software
15349   * distributed under the License is distributed on an "AS IS" BASIS,
15350   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15351   * See the License for the specific language governing permissions and
15352   * limitations under the License.
15353   */
15354  /*import java.util.ArrayList;*/
15355  /*import java.util.List;*/
15356  /**
15357   * <p>This class attempts to find alignment patterns in a QR Code. Alignment patterns look like finder
15358   * patterns but are smaller and appear at regular intervals throughout the image.</p>
15359   *
15360   * <p>
15360At the moment this only looks for the bottom-right alignment pattern.</p>
15361   *
15362   * <p>This is mostly a simplified copy of {@link FinderPatternFinder}. It is copied,
15363   * pasted and stripped down here for maximum performance but does unfortunately duplicate
15364   * some code.</p>
15365   *
15366   * <p>This class is thread-safe but not reentrant. Each thread must allocate its own object.</p>
15367   *
15368   * @author Sean Owen
15369   */
15370  class AlignmentPatternFinder {
15371      /**
15372       * <p>Creates a finder that will look in a portion of the whole image.</p>
15373       *
15374       * @param image image to search
15375       * @param startX left column from which to start searching
15376       * @param startY top row from which to start searching
15377       * @param width width of region to search
15378       * @param height height of region to search
15379       * @param moduleSize estimated module size so far
15380       */
15381      constructor(image, startX /*int*/, startY /*int*/, width /*int*/, height /*int*/, moduleSize /*float*/, resultPointCallback) {
15382          this.image = image;
15383          this.startX = startX;
15384          this.startY = startY;
15385          this.width = width;
15386          this.height = height;
15387          this.moduleSize = moduleSize;
15388          this.resultPointCallback = resultPointCallback;
15389          this.possibleCenters = []; // new Array<any>(5))
15390          // TYPESCRIPTPORT: array initialization without size as the length is checked below
15391          this.crossCheckStateCount = new Int32Array(3);
15392      }
15393      /**
15394       * <p>This method attempts to find the bottom-right alignment pattern in the image. It is a bit messy since
15395       * it's pretty performance-critical and so is written to be fast foremost.</p>
15396       *
15397       * @return {@link AlignmentPattern} if found
15398       * @throws NotFoundException if not found
15399       */
15400      find() {
15401          const startX = this.startX;
15402          const height = this.height;
15403          const width = this.width;
15404          const maxJ = startX + width;
15405          const middleI = this.startY + (height / 2);
15406          // We are looking for black/white/black modules in 1:1:1 ratio
15407          // this tracks the number of black/white/black modules seen so far
15408          const stateCount = new Int32Array(3);
15409          const image = this.image;
15410          for (let iGen = 0; iGen < height; iGen++) {
15411              // Search from middle outwards
15412              const i = middleI + ((iGen & 0x01) === 0 ? Math.floor((iGen + 1) / 2) : -Math.floor((iGen + 1) / 2));
15413              stateCount[0] = 0;
15414              stateCount[1] = 0;
15415              stateCount[2] = 0;
15416              let j = startX;
15417              // Burn off leading white pixels before anything else; if we start in the middle of
15418              // a white run, it doesn't make sense to count its length, since we don't know if the
15419              // white run continued to the left of the start point
15420              while (j < maxJ && !image.get(j, i)) {
15421                  j++;
15422              }
15423              let currentState = 0;
15424              while (j < maxJ) {
15425                  if (image.get(j, i)) {
15426                      // Black pixel
15427                      if (currentState === 1) { // Counting black pixels
15428                          stateCount[1]++;
15429                      }
15430                      else { // Counting white pixels
15431                          if (currentState === 2) { // A winner?
vendor: 11,165 bytes, lines 15432-15694
15432                              if (this.foundPatternCross(stateCount)) { // Yes
15433                                  const confirmed = this.handlePossibleCenter(stateCount, i, j);
15434                                  if (confirmed !== null) {
15435                                      return confirmed;
15436                                  }
15437                              }
15438                              stateCount[0] = stateCount[2];
15439                              stateCount[1] = 1;
15440                              stateCount[2] = 0;
15441                              currentState = 1;
15442                          }
15443                          else {
15444                              stateCount[++currentState]++;
15445                          }
15446                      }
15447                  }
15448                  else { // White pixel
15449                      if (currentState === 1) { // Counting black pixels
15450                          currentState++;
15451                      }
15452                      stateCount[currentState]++;
15453                  }
15454                  j++;
15455              }
15456              if (this.foundPatternCross(stateCount)) {
15457                  const confirmed = this.handlePossibleCenter(stateCount, i, maxJ);
15458                  if (confirmed !== null) {
15459                      return confirmed;
15460                  }
15461              }
15462          }
15463          // Hmm, nothing we saw was observed and confirmed twice. If we had
15464          // any guess at all, return it.
15465          if (this.possibleCenters.length !== 0) {
15466              return this.possibleCenters[0];
15467          }
15468          throw new NotFoundException();
15469      }
15470      /**
15471       * Given a count of black/white/black pixels just seen and an end position,
15472       * figures the location of the center of this black/white/black run.
15473       */
15474      static centerFromEnd(stateCount, end /*int*/) {
15475          return (end - stateCount[2]) - stateCount[1] / 2.0;
15476      }
15477      /**
15478       * @param stateCount count of black/white/black pixels just read
15479       * @return true iff the proportions of the counts is close enough to the 1/1/1 ratios
15480       *         used by alignment patterns to be considered a match
15481       */
15482      foundPatternCross(stateCount) {
15483          const moduleSize = this.moduleSize;
15484          const maxVariance = moduleSize / 2.0;
15485          for (let i = 0; i < 3; i++) {
15486              if (Math.abs(moduleSize - stateCount[i]) >= maxVariance) {
15487                  return false;
15488              }
15489          }
15490          return true;
15491      }
15492      /**
15493       * <p>After a horizontal scan finds a potential alignment pattern, this method
15494       * "cross-checks" by scanning down vertically through the center of the possible
15495       * alignment pattern to see if the same proportion is detected.</p>
15496       *
15497       * @param startI row where an alignment pattern was detected
15498       * @param centerJ center of the section that appears to cross an alignment pattern
15499       * @param maxCount maximum reasonable number of modules that should be
15500       * observed in any reading state, based on the results of the horizontal scan
15501       * @return vertical center of alignment pattern, or {@link Float#NaN} if not found
15502       */
15503      crossCheckVertical(startI /*int*/, centerJ /*int*/, maxCount /*int*/, originalStateCountTotal /*int*/) {
15504          const image = this.image;
15505          const maxI = image.getHeight();
15506          const stateCount = this.crossCheckStateCount;
15507          stateCount[0] = 0;
15508          stateCount[1] = 0;
15509          stateCount[2] = 0;
15510          // Start counting up from center
15511          let i = startI;
15512          while (i >= 0 && image.get(centerJ, i) && stateCount[1] <= maxCount) {
15513              stateCount[1]++;
15514              i--;
15515          }
15516          // If already too many modules in this state or ran off the edge:
15517          if (i < 0 || stateCount[1] > maxCount) {
15518              return NaN;
15519          }
15520          while (i >= 0 && !image.get(centerJ, i) && stateCount[0] <= maxCount) {
15521              stateCount[0]++;
15522              i--;
15523          }
15524          if (stateCount[0] > maxCount) {
15525              return NaN;
15526          }
15527          // Now also count down from center
15528          i = startI + 1;
15529          while (i < maxI && image.get(centerJ, i) && stateCount[1] <= maxCount) {
15530              stateCount[1]++;
15531              i++;
15532          }
15533          if (i === maxI || stateCount[1] > maxCount) {
15534              return NaN;
15535          }
15536          while (i < maxI && !image.get(centerJ, i) && stateCount[2] <= maxCount) {
15537              stateCount[2]++;
15538              i++;
15539          }
15540          if (stateCount[2] > maxCount) {
15541              return NaN;
15542          }
15543          const stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
15544          if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {
15545              return NaN;
15546          }
15547          return this.foundPatternCross(stateCount) ? AlignmentPatternFinder.centerFromEnd(stateCount, i) : NaN;
15548      }
15549      /**
15550       * <p>This is called when a horizontal scan finds a possible alignment pattern. It will
15551       * cross check with a vertical scan, and if successful, will see if this pattern had been
15552       * found on a previous horizontal scan. If so, we consider it confirmed and conclude we have
15553       * found the alignment pattern.</p>
15554       *
15555       * @param stateCount reading state module counts from horizontal scan
15556       * @param i row where alignment pattern may be found
15557       * @param j end of possible alignment pattern in row
15558       * @return {@link AlignmentPattern} if we have found the same pattern twice, or null if not
15559       */
15560      handlePossibleCenter(stateCount, i /*int*/, j /*int*/) {
15561          const stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
15562          const centerJ = AlignmentPatternFinder.centerFromEnd(stateCount, j);
15563          const centerI = this.crossCheckVertical(i, /*(int) */ centerJ, 2 * stateCount[1], stateCountTotal);
15564          if (!isNaN(centerI)) {
15565              const estimatedModuleSize = (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0;
15566              for (const center of this.possibleCenters) {
15567                  // Look for about the same center and module size:
15568                  if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) {
15569                      return center.combineEstimate(centerI, centerJ, estimatedModuleSize);
15570                  }
15571              }
15572              // Hadn't found this before; save it
15573              const point = new AlignmentPattern(centerJ, centerI, estimatedModuleSize);
15574              this.possibleCenters.push(point);
15575              if (this.resultPointCallback !== null && this.resultPointCallback !== undefined) {
15576                  this.resultPointCallback.foundPossibleResultPoint(point);
15577              }
15578          }
15579          return null;
15580      }
15581  }
15582
15583  /*
15584   * Copyright 2007 ZXing authors
15585   *
15586   * Licensed under the Apache License, Version 2.0 (the "License");
15587   * you may not use this file except in compliance with the License.
15588   * You may obtain a copy of the License at
15589   *
15590   *      http://www.apache.org/licenses/LICENSE-2.0
15591   *
15592   * Unless required by applicable law or agreed to in writing, software
15593   * distributed under the License is distributed on an "AS IS" BASIS,
15594   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15595   * See the License for the specific language governing permissions and
15596   * limitations under the License.
15597   */
15598  /**
15599   * <p>Encapsulates a finder pattern, which are the three square patterns found in
15600   * the corners of QR Codes. It also encapsulates a count of similar finder patterns,
15601   * as a convenience to the finder's bookkeeping.</p>
15602   *
15603   * @author Sean Owen
15604   */
15605  class FinderPattern extends ResultPoint {
15606      // FinderPattern(posX: number/*float*/, posY: number/*float*/, estimatedModuleSize: number/*float*/) {
15607      //   this(posX, posY, estimatedModuleSize, 1)
15608      // }
15609      constructor(posX /*float*/, posY /*float*/, estimatedModuleSize /*float*/, count /*int*/) {
15610          super(posX, posY);
15611          this.estimatedModuleSize = estimatedModuleSize;
15612          this.count = count;
15613          if (undefined === count) {
15614              this.count = 1;
15615          }
15616      }
15617      getEstimatedModuleSize() {
15618          return this.estimatedModuleSize;
15619      }
15620      getCount() {
15621          return this.count;
15622      }
15623      /*
15624      void incrementCount() {
15625        this.count++
15626      }
15627       */
15628      /**
15629       * <p>Determines if this finder pattern "about equals" a finder pattern at the stated
15630       * position and size -- meaning, it is at nearly the same center with nearly the same size.</p>
15631       */
15632      aboutEquals(moduleSize /*float*/, i /*float*/, j /*float*/) {
15633          if (Math.abs(i - this.getY()) <= moduleSize && Math.abs(j - this.getX()) <= moduleSize) {
15634              const moduleSizeDiff = Math.abs(moduleSize - this.estimatedModuleSize);
15635              return moduleSizeDiff <= 1.0 || moduleSizeDiff <= this.estimatedModuleSize;
15636          }
15637          return false;
15638      }
15639      /**
15640       * Combines this object's current estimate of a finder pattern position and module size
15641       * with a new estimate. It returns a new {@code FinderPattern} containing a weighted average
15642       * based on count.
15643       */
15644      combineEstimate(i /*float*/, j /*float*/, newModuleSize /*float*/) {
15645          const combinedCount = this.count + 1;
15646          const combinedX = (this.count * this.getX() + j) / combinedCount;
15647          const combinedY = (this.count * this.getY() + i) / combinedCount;
15648          const combinedModuleSize = (this.count * this.estimatedModuleSize + newModuleSize) / combinedCount;
15649          return new FinderPattern(combinedX, combinedY, combinedModuleSize, combinedCount);
15650      }
15651  }
15652
15653  /*
15654   * Copyright 2007 ZXing authors
15655   *
15656   * Licensed under the Apache License, Version 2.0 (the "License");
15657   * you may not use this file except in compliance with the License.
15658   * You may obtain a copy of the License at
15659   *
15660   *      http://www.apache.org/licenses/LICENSE-2.0
15661   *
15662   * Unless required by applicable law or agreed to in writing, software
15663   * distributed under the License is distributed on an "AS IS" BASIS,
15664   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15665   * See the License for the specific language governing permissions and
15666   * limitations under the License.
15667   */
15668  /**
15669   * <p>Encapsulates information about finder patterns in an image, including the location of
15670   * the three finder patterns, and their estimated module size.</p>
15671   *
15672   * @author Sean Owen
15673   */
15674  class FinderPatternInfo {
15675      constructor(patternCenters) {
15676          this.bottomLeft = patternCenters[0];
15677          this.topLeft = patternCenters[1];
15678          this.topRight = patternCenters[2];
15679      }
15680      getBottomLeft() {
15681          return this.bottomLeft;
15682      }
15683      getTopLeft() {
15684          return this.topLeft;
15685      }
15686      getTopRight() {
15687          return this.topRight;
15688      }
15689  }
15690
15691  /*
15692   * Copyright 2007 ZXing authors
15693   *
15694   * Licensed under the Apache License, Version 2.0 (the "License");
15695   * you may not use this file except in compliance with the License.
15696   * You may obtain a copy of the License at
15697   *
15698   *      http://www.apache.org/licenses/LICENSE-2.0
15699   *
15700   * Unless required by applicable law or agreed to in writing, software
15701   * distributed under the License is distributed on an "AS IS" BASIS,
15702   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15703   * See the License for the specific language governing permissions and
15704   * limitations under the License.
15705   */
15706  /*import java.io.Serializable;*/
15707  /*import java.util.ArrayList;*/
15708  /*import java.util.Collections;*/
15709  /*import java.util.Comparator;*/
15710  /*import java.util.List;*/
15711  /*import java.util.Map;*/
15712  /**
15713   * <p>This class attempts to find finder patterns in a QR Code. Finder patterns are the square
15714   * markers at three corners of a QR Code.</p>
15715   *
15716   * <p>This class is thread-safe but not reentrant. Each thread must allocate its own object.
15717   *
15718   * @author Sean Owen
15719   */
15720  class FinderPatternFinder {
15721      /**
15722       * <p>Creates a finder that will search the image for three finder patterns.</p>
15723       *
15724       * @param image image to search
15725       */
15726      // public constructor(image: BitMatrix) {
15727      //   this(image, null)
15728      // }
15729      constructor(image, resultPointCallback) {
15730          this.image = image;
15731          this.resultPointCallback = resultPointCallback;
15732          this.possibleCenters = [];
15733          this.crossCheckStateCount = new Int32Array(5);
15734          this.resultPointCallback = resultPointCallback;
15735      }
15736      getImage() {
15737          return this.image;
15738      }
15739      getPossibleCenters() {
15740          return this.possibleCenters;
15741      }
15742      find(hints) {
15743          const tryHarder = (hints !== null && hints !== undefined) && undefined !== hints.get(DecodeHintType$1.TRY_HARDER);
15744          const pureBarcode = (hints !== null && hints !== undefined) && undefined !== hints.get(DecodeHintType$1.PURE_BARCODE);
15745          const image = this.image;
15746          const maxI = image.getHeight();
15747          const maxJ = image.getWidth();
15748          // We are looking for black/white/black/white/black modules in
15749          // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far
15750          // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
15751          // image, and then account for the center being 3 modules in size. This gives the smallest
15752          // number of pixels the center could be, so skip this often. When trying harder, look for all
15753          // QR versions regardless of how dense they are.
15754          let iSkip = Math.floor((3 * maxI) / (4 * FinderPatternFinder.MAX_MODULES));
15755          if (iSkip < FinderPatternFinder.MIN_SKIP || tryHarder) {
15756              iSkip = FinderPatternFinder.MIN_SKIP;
15757          }
15758          let done = false;
15759          const stateCount = new Int32Array(5);
15760          for (let i = iSkip - 1; i < maxI && !done; i += iSkip) {
15761              // Get a row of black/white values
15762              stateCount[0] = 0;
15763              stateCount[1] = 0;
15764              stateCount[2] = 0;
15765              stateCount[3] = 0;
15766              stateCount[4] = 0;
15767              let currentState = 0;
15768              for (let j = 0; j < maxJ; j++) {
15769                  if (image.get(j, i)) {
15770                      // Black pixel
15771                      if ((currentState & 1) === 1) { // Counting white pixels
15772                          currentState++;
15773                      }
15774                      stateCount[currentState]++;
15775                  }
15776                  else { // White pixel
15777                      if ((currentState & 1) === 0) { // Counting black pixels
15778                          if (currentState === 4) { // A winner?
vendor: 29,339 bytes, lines 15779-16391
15779                              if (FinderPatternFinder.foundPatternCross(stateCount)) { // Yes
15780                                  const confirmed = this.handlePossibleCenter(stateCount, i, j, pureBarcode);
15781                                  if (confirmed === true) {
15782                                      // Start examining every other line. Checking each line turned out to be too
15783                                      // expensive and didn't improve performance.
15784                                      iSkip = 2;
15785                                      if (this.hasSkipped === true) {
15786                                          done = this.haveMultiplyConfirmedCenters();
15787                                      }
15788                                      else {
15789                                          const rowSkip = this.findRowSkip();
15790                                          if (rowSkip > stateCount[2]) {
15791                                              // Skip rows between row of lower confirmed center
15792                                              // and top of presumed third confirmed center
15793                                              // but back up a bit to get a full chance of detecting
15794                                              // it, entire width of center of finder pattern
15795                                              // Skip by rowSkip, but back off by stateCount[2] (size of last center
15796                                              // of pattern we saw) to be conservative, and also back off by iSkip which
15797                                              // is about to be re-added
15798                                              i += rowSkip - stateCount[2] - iSkip;
15799                                              j = maxJ - 1;
15800                                          }
15801                                      }
15802                                  }
15803                                  else {
15804                                      stateCount[0] = stateCount[2];
15805                                      stateCount[1] = stateCount[3];
15806                                      stateCount[2] = stateCount[4];
15807                                      stateCount[3] = 1;
15808                                      stateCount[4] = 0;
15809                                      currentState = 3;
15810                                      continue;
15811                                  }
15812                                  // Clear state to start looking again
15813                                  currentState = 0;
15814                                  stateCount[0] = 0;
15815                                  stateCount[1] = 0;
15816                                  stateCount[2] = 0;
15817                                  stateCount[3] = 0;
15818                                  stateCount[4] = 0;
15819                              }
15820                              else { // No, shift counts back by two
15821                                  stateCount[0] = stateCount[2];
15822                                  stateCount[1] = stateCount[3];
15823                                  stateCount[2] = stateCount[4];
15824                                  stateCount[3] = 1;
15825                                  stateCount[4] = 0;
15826                                  currentState = 3;
15827                              }
15828                          }
15829                          else {
15830                              stateCount[++currentState]++;
15831                          }
15832                      }
15833                      else { // Counting white pixels
15834                          stateCount[currentState]++;
15835                      }
15836                  }
15837              }
15838              if (FinderPatternFinder.foundPatternCross(stateCount)) {
15839                  const confirmed = this.handlePossibleCenter(stateCount, i, maxJ, pureBarcode);
15840                  if (confirmed === true) {
15841                      iSkip = stateCount[0];
15842                      if (this.hasSkipped) {
15843                          // Found a third one
15844                          done = this.haveMultiplyConfirmedCenters();
15845                      }
15846                  }
15847              }
15848          }
15849          const patternInfo = this.selectBestPatterns();
15850          ResultPoint.orderBestPatterns(patternInfo);
15851          return new FinderPatternInfo(patternInfo);
15852      }
15853      /**
15854       * Given a count of black/white/black/white/black pixels just seen and an end position,
15855       * figures the location of the center of this run.
15856       */
15857      static centerFromEnd(stateCount, end /*int*/) {
15858          return (end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0;
15859      }
15860      /**
15861       * @param stateCount count of black/white/black/white/black pixels just read
15862       * @return true iff the proportions of the counts is close enough to the 1/1/3/1/1 ratios
15863       *         used by finder patterns to be considered a match
15864       */
15865      static foundPatternCross(stateCount) {
15866          let totalModuleSize = 0;
15867          for (let i = 0; i < 5; i++) {
15868              const count = stateCount[i];
15869              if (count === 0) {
15870                  return false;
15871              }
15872              totalModuleSize += count;
15873          }
15874          if (totalModuleSize < 7) {
15875              return false;
15876          }
15877          const moduleSize = totalModuleSize / 7.0;
15878          const maxVariance = moduleSize / 2.0;
15879          // Allow less than 50% variance from 1-1-3-1-1 proportions
15880          return Math.abs(moduleSize - stateCount[0]) < maxVariance &&
15881              Math.abs(moduleSize - stateCount[1]) < maxVariance &&
15882              Math.abs(3.0 * moduleSize - stateCount[2]) < 3 * maxVariance &&
15883              Math.abs(moduleSize - stateCount[3]) < maxVariance &&
15884              Math.abs(moduleSize - stateCount[4]) < maxVariance;
15885      }
15886      getCrossCheckStateCount() {
15887          const crossCheckStateCount = this.crossCheckStateCount;
15888          crossCheckStateCount[0] = 0;
15889          crossCheckStateCount[1] = 0;
15890          crossCheckStateCount[2] = 0;
15891          crossCheckStateCount[3] = 0;
15892          crossCheckStateCount[4] = 0;
15893          return crossCheckStateCount;
15894      }
15895      /**
15896       * After a vertical and horizontal scan finds a potential finder pattern, this method
15897       * "cross-cross-cross-checks" by scanning down diagonally through the center of the possible
15898       * finder pattern to see if the same proportion is detected.
15899       *
15900       * @param startI row where a finder pattern was detected
15901       * @param centerJ center of the section that appears to cross a finder pattern
15902       * @param maxCount maximum reasonable number of modules that should be
15903       *  observed in any reading state, based on the results of the horizontal scan
15904       * @param originalStateCountTotal The original state count total.
15905       * @return true if proportions are withing expected limits
15906       */
15907      crossCheckDiagonal(startI /*int*/, centerJ /*int*/, maxCount /*int*/, originalStateCountTotal /*int*/) {
15908          const stateCount = this.getCrossCheckStateCount();
15909          // Start counting up, left from center finding black center mass
15910          let i = 0;
15911          const image = this.image;
15912          while (startI >= i && centerJ >= i && image.get(centerJ - i, startI - i)) {
15913              stateCount[2]++;
15914              i++;
15915          }
15916          if (startI < i || centerJ < i) {
15917              return false;
15918          }
15919          // Continue up, left finding white space
15920          while (startI >= i && centerJ >= i && !image.get(centerJ - i, startI - i) &&
15921              stateCount[1] <= maxCount) {
15922              stateCount[1]++;
15923              i++;
15924          }
15925          // If already too many modules in this state or ran off the edge:
15926          if (startI < i || centerJ < i || stateCount[1] > maxCount) {
15927              return false;
15928          }
15929          // Continue up, left finding black border
15930          while (startI >= i && centerJ >= i && image.get(centerJ - i, startI - i) &&
15931              stateCount[0] <= maxCount) {
15932              stateCount[0]++;
15933              i++;
15934          }
15935          if (stateCount[0] > maxCount) {
15936              return false;
15937          }
15938          const maxI = image.getHeight();
15939          const maxJ = image.getWidth();
15940          // Now also count down, right from center
15941          i = 1;
15942          while (startI + i < maxI && centerJ + i < maxJ && image.get(centerJ + i, startI + i)) {
15943              stateCount[2]++;
15944              i++;
15945          }
15946          // Ran off the edge?
15947          if (startI + i >= maxI || centerJ + i >= maxJ) {
15948              return false;
15949          }
15950          while (startI + i < maxI && centerJ + i < maxJ && !image.get(centerJ + i, startI + i) &&
15951              stateCount[3] < maxCount) {
15952              stateCount[3]++;
15953              i++;
15954          }
15955          if (startI + i >= maxI || centerJ + i >= maxJ || stateCount[3] >= maxCount) {
15956              return false;
15957          }
15958          while (startI + i < maxI && centerJ + i < maxJ && image.get(centerJ + i, startI + i) &&
15959              stateCount[4] < maxCount) {
15960              stateCount[4]++;
15961              i++;
15962          }
15963          if (stateCount[4] >= maxCount) {
15964              return false;
15965          }
15966          // If we found a finder-pattern-like section, but its size is more than 100% different than
15967          // the original, assume it's a false positive
15968          const stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
15969          return Math.abs(stateCountTotal - originalStateCountTotal) < 2 * originalStateCountTotal &&
15970              FinderPatternFinder.foundPatternCross(stateCount);
15971      }
15972      /**
15973       * <p>After a horizontal scan finds a potential finder pattern, this method
15974       * "cross-checks" by scanning down vertically through the center of the possible
15975       * finder pattern to see if the same proportion is detected.</p>
15976       *
15977       * @param startI row where a finder pattern was detected
15978       * @param centerJ center of the section that appears to cross a finder pattern
15979       * @param maxCount maximum reasonable number of modules that should be
15980       * observed in any reading state, based on the results of the horizontal scan
15981       * @return vertical center of finder pattern, or {@link Float#NaN} if not found
15982       */
15983      crossCheckVertical(startI /*int*/, centerJ /*int*/, maxCount /*int*/, originalStateCountTotal /*int*/) {
15984          const image = this.image;
15985          const maxI = image.getHeight();
15986          const stateCount = this.getCrossCheckStateCount();
15987          // Start counting up from center
15988          let i = startI;
15989          while (i >= 0 && image.get(centerJ, i)) {
15990              stateCount[2]++;
15991              i--;
15992          }
15993          if (i < 0) {
15994              return NaN;
15995          }
15996          while (i >= 0 && !image.get(centerJ, i) && stateCount[1] <= maxCount) {
15997              stateCount[1]++;
15998              i--;
15999          }
16000          // If already too many modules in this state or ran off the edge:
16001          if (i < 0 || stateCount[1] > maxCount) {
16002              return NaN;
16003          }
16004          while (i >= 0 && image.get(centerJ, i) && stateCount[0] <= maxCount) {
16005              stateCount[0]++;
16006              i--;
16007          }
16008          if (stateCount[0] > maxCount) {
16009              return NaN;
16010          }
16011          // Now also count down from center
16012          i = startI + 1;
16013          while (i < maxI && image.get(centerJ, i)) {
16014              stateCount[2]++;
16015              i++;
16016          }
16017          if (i === maxI) {
16018              return NaN;
16019          }
16020          while (i < maxI && !image.get(centerJ, i) && stateCount[3] < maxCount) {
16021              stateCount[3]++;
16022              i++;
16023          }
16024          if (i === maxI || stateCount[3] >= maxCount) {
16025              return NaN;
16026          }
16027          while (i < maxI && image.get(centerJ, i) && stateCount[4] < maxCount) {
16028              stateCount[4]++;
16029              i++;
16030          }
16031          if (stateCount[4] >= maxCount) {
16032              return NaN;
16033          }
16034          // If we found a finder-pattern-like section, but its size is more than 40% different than
16035          // the original, assume it's a false positive
16036          const stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] +
16037              stateCount[4];
16038          if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {
16039              return NaN;
16040          }
16041          return FinderPatternFinder.foundPatternCross(stateCount) ? FinderPatternFinder.centerFromEnd(stateCount, i) : NaN;
16042      }
16043      /**
16044       * <p>Like {@link #crossCheckVertical(int, int, int, int)}, and in fact is basically identical,
16045       * except it reads horizontally instead of vertically. This is used to cross-cross
16046       * check a vertical cross check and locate the real center of the alignment pattern.</p>
16047       */
16048      crossCheckHorizontal(startJ /*int*/, centerI /*int*/, maxCount /*int*/, originalStateCountTotal /*int*/) {
16049          const image = this.image;
16050          const maxJ = image.getWidth();
16051          const stateCount = this.getCrossCheckStateCount();
16052          let j = startJ;
16053          while (j >= 0 && image.get(j, centerI)) {
16054              stateCount[2]++;
16055              j--;
16056          }
16057          if (j < 0) {
16058              return NaN;
16059          }
16060          while (j >= 0 && !image.get(j, centerI) && stateCount[1] <= maxCount) {
16061              stateCount[1]++;
16062              j--;
16063          }
16064          if (j < 0 || stateCount[1] > maxCount) {
16065              return NaN;
16066          }
16067          while (j >= 0 && image.get(j, centerI) && stateCount[0] <= maxCount) {
16068              stateCount[0]++;
16069              j--;
16070          }
16071          if (stateCount[0] > maxCount) {
16072              return NaN;
16073          }
16074          j = startJ + 1;
16075          while (j < maxJ && image.get(j, centerI)) {
16076              stateCount[2]++;
16077              j++;
16078          }
16079          if (j === maxJ) {
16080              return NaN;
16081          }
16082          while (j < maxJ && !image.get(j, centerI) && stateCount[3] < maxCount) {
16083              stateCount[3]++;
16084              j++;
16085          }
16086          if (j === maxJ || stateCount[3] >= maxCount) {
16087              return NaN;
16088          }
16089          while (j < maxJ && image.get(j, centerI) && stateCount[4] < maxCount) {
16090              stateCount[4]++;
16091              j++;
16092          }
16093          if (stateCount[4] >= maxCount) {
16094              return NaN;
16095          }
16096          // If we found a finder-pattern-like section, but its size is significantly different than
16097          // the original, assume it's a false positive
16098          const stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] +
16099              stateCount[4];
16100          if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
16101              return NaN;
16102          }
16103          return FinderPatternFinder.foundPatternCross(stateCount) ? FinderPatternFinder.centerFromEnd(stateCount, j) : NaN;
16104      }
16105      /**
16106       * <p>This is called when a horizontal scan finds a possible alignment pattern. It will
16107       * cross check with a vertical scan, and if successful, will, ah, cross-cross-check
16108       * with another horizontal scan. This is needed primarily to locate the real horizontal
16109       * center of the pattern in cases of extreme skew.
16110       * And then we cross-cross-cross check with another diagonal scan.</p>
16111       *
16112       * <p>If that succeeds the finder pattern location is added to a list that tracks
16113       * the number of times each location has been nearly-matched as a finder pattern.
16114       * Each additional find is more evidence that the location is in fact a finder
16115       * pattern center
16116       *
16117       * @param stateCount reading state module counts from horizontal scan
16118       * @param i row where finder pattern may be found
16119       * @param j end of possible finder pattern in row
16120       * @param pureBarcode true if in "pure barcode" mode
16121       * @return true if a finder pattern candidate was found this time
16122       */
16123      handlePossibleCenter(stateCount, i /*int*/, j /*int*/, pureBarcode) {
16124          const stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] +
16125              stateCount[4];
16126          let centerJ = FinderPatternFinder.centerFromEnd(stateCount, j);
16127          let centerI = this.crossCheckVertical(i, /*(int) */ Math.floor(centerJ), stateCount[2], stateCountTotal);
16128          if (!isNaN(centerI)) {
16129              // Re-cross check
16130              centerJ = this.crossCheckHorizontal(/*(int) */ Math.floor(centerJ), /*(int) */ Math.floor(centerI), stateCount[2], stateCountTotal);
16131              if (!isNaN(centerJ) &&
16132                  (!pureBarcode || this.crossCheckDiagonal(/*(int) */ Math.floor(centerI), /*(int) */ Math.floor(centerJ), stateCount[2], stateCountTotal))) {
16133                  const estimatedModuleSize = stateCountTotal / 7.0;
16134                  let found = false;
16135                  const possibleCenters = this.possibleCenters;
16136                  for (let index = 0, length = possibleCenters.length; index < length; index++) {
16137                      const center = possibleCenters[index];
16138                      // Look for about the same center and module size:
16139                      if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) {
16140                          possibleCenters[index] = center.combineEstimate(centerI, centerJ, estimatedModuleSize);
16141                          found = true;
16142                          break;
16143                      }
16144                  }
16145                  if (!found) {
16146                      const point = new FinderPattern(centerJ, centerI, estimatedModuleSize);
16147                      possibleCenters.push(point);
16148                      if (this.resultPointCallback !== null && this.resultPointCallback !== undefined) {
16149                          this.resultPointCallback.foundPossibleResultPoint(point);
16150                      }
16151                  }
16152                  return true;
16153              }
16154          }
16155          return false;
16156      }
16157      /**
16158       * @return number of rows we could safely skip during scanning, based on the first
16159       *         two finder patterns that have been located. In some cases their position will
16160       *         allow us to infer that the third pattern must lie below a certain point farther
16161       *         down in the image.
16162       */
16163      findRowSkip() {
16164          const max = this.possibleCenters.length;
16165          if (max <= 1) {
16166              return 0;
16167          }
16168          let firstConfirmedCenter = null;
16169          for (const center of this.possibleCenters) {
16170              if (center.getCount() >= FinderPatternFinder.CENTER_QUORUM) {
16171                  if (firstConfirmedCenter == null) {
16172                      firstConfirmedCenter = center;
16173                  }
16174                  else {
16175                      // We have two confirmed centers
16176                      // How far down can we skip before resuming looking for the next
16177                      // pattern? In the worst case, only the difference between the
16178                      // difference in the x / y coordinates of the two centers.
16179                      // This is the case where you find top left last.
16180                      this.hasSkipped = true;
16181                      return /*(int) */ Math.floor((Math.abs(firstConfirmedCenter.getX() - center.getX()) -
16182                          Math.abs(firstConfirmedCenter.getY() - center.getY())) / 2);
16183                  }
16184              }
16185          }
16186          return 0;
16187      }
16188      /**
16189       * @return true iff we have found at least 3 finder patterns that have been detected
16190       *         at least {@link #CENTER_QUORUM} times each, and, the estimated module size of the
16191       *         candidates is "pretty similar"
16192       */
16193      haveMultiplyConfirmedCenters() {
16194          let confirmedCount = 0;
16195          let totalModuleSize = 0.0;
16196          const max = this.possibleCenters.length;
16197          for (const pattern of this.possibleCenters) {
16198              if (pattern.getCount() >= FinderPatternFinder.CENTER_QUORUM) {
16199                  confirmedCount++;
16200                  totalModuleSize += pattern.getEstimatedModuleSize();
16201              }
16202          }
16203          if (confirmedCount < 3) {
16204              return false;
16205          }
16206          // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive"
16207          // and that we need to keep looking. We detect this by asking if the estimated module sizes
16208          // vary too much. We arbitrarily say that when the total deviation from average exceeds
16209          // 5% of the total module size estimates, it's too much.
16210          const average = totalModuleSize / max;
16211          let totalDeviation = 0.0;
16212          for (const pattern of this.possibleCenters) {
16213              totalDeviation += Math.abs(pattern.getEstimatedModuleSize() - average);
16214          }
16215          return totalDeviation <= 0.05 * totalModuleSize;
16216      }
16217      /**
16218       * @return the 3 best {@link FinderPattern}s from our list of candidates. The "best" are
16219       *         those that have been detected at least {@link #CENTER_QUORUM} times, and whose module
16220       *         size differs from the average among those patterns the least
16221       * @throws NotFoundException if 3 such finder patterns do not exist
16222       */
16223      selectBestPatterns() {
16224          const startSize = this.possibleCenters.length;
16225          if (startSize < 3) {
16226              // Couldn't find enough finder patterns
16227              throw new NotFoundException();
16228          }
16229          const possibleCenters = this.possibleCenters;
16230          let average;
16231          // Filter outlier possibilities whose module size is too different
16232          if (startSize > 3) {
16233              // But we can only afford to do so if we have at least 4 possibilities to choose from
16234              let totalModuleSize = 0.0;
16235              let square = 0.0;
16236              for (const center of this.possibleCenters) {
16237                  const size = center.getEstimatedModuleSize();
16238                  totalModuleSize += size;
16239                  square += size * size;
16240              }
16241              average = totalModuleSize / startSize;
16242              let stdDev = Math.sqrt(square / startSize - average * average);
16243              possibleCenters.sort(
16244              /**
16245               * <p>Orders by furthest from average</p>
16246               */
16247              // FurthestFromAverageComparator implements Comparator<FinderPattern>
16248              (center1, center2) => {
16249                  const dA = Math.abs(center2.getEstimatedModuleSize() - average);
16250                  const dB = Math.abs(center1.getEstimatedModuleSize() - average);
16251                  return dA < dB ? -1 : dA > dB ? 1 : 0;
16252              });
16253              const limit = Math.max(0.2 * average, stdDev);
16254              for (let i = 0; i < possibleCenters.length && possibleCenters.length > 3; i++) {
16255                  const pattern = possibleCenters[i];
16256                  if (Math.abs(pattern.getEstimatedModuleSize() - average) > limit) {
16257                      possibleCenters.splice(i, 1);
16258                      i--;
16259                  }
16260              }
16261          }
16262          if (possibleCenters.length > 3) {
16263              // Throw away all but those first size candidate points we found.
16264              let totalModuleSize = 0.0;
16265              for (const possibleCenter of possibleCenters) {
16266                  totalModuleSize += possibleCenter.getEstimatedModuleSize();
16267              }
16268              average = totalModuleSize / possibleCenters.length;
16269              possibleCenters.sort(
16270              /**
16271               * <p>Orders by {@link FinderPattern#getCount()}, descending.</p>
16272               */
16273              // CenterComparator implements Comparator<FinderPattern>
16274              (center1, center2) => {
16275                  if (center2.getCount() === center1.getCount()) {
16276                      const dA = Math.abs(center2.getEstimatedModuleSize() - average);
16277                      const dB = Math.abs(center1.getEstimatedModuleSize() - average);
16278                      return dA < dB ? 1 : dA > dB ? -1 : 0;
16279                  }
16280                  else {
16281                      return center2.getCount() - center1.getCount();
16282                  }
16283              });
16284              possibleCenters.splice(3); // this is not realy necessary as we only return first 3 anyway
16285          }
16286          return [
16287              possibleCenters[0],
16288              possibleCenters[1],
16289              possibleCenters[2]
16290          ];
16291      }
16292  }
16293  FinderPatternFinder.CENTER_QUORUM = 2;
16294  FinderPatternFinder.MIN_SKIP = 3; // 1 pixel/module times 3 modules/center
16295  FinderPatternFinder.MAX_MODULES = 57; // support up to version 10 for mobile clients
16296
16297  /*
16298   * Copyright 2007 ZXing authors
16299   *
16300   * Licensed under the Apache License, Version 2.0 (the "License");
16301   * you may not use this file except in compliance with the License.
16302   * You may obtain a copy of the License at
16303   *
16304   *      http://www.apache.org/licenses/LICENSE-2.0
16305   *
16306   * Unless required by applicable law or agreed to in writing, software
16307   * distributed under the License is distributed on an "AS IS" BASIS,
16308   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16309   * See the License for the specific language governing permissions and
16310   * limitations under the License.
16311   */
16312  /*import java.util.Map;*/
16313  /**
16314   * <p>Encapsulates logic that can detect a QR Code in an image, even if the QR Code
16315   * is rotated or skewed, or partially obscured.</p>
16316   *
16317   * @author Sean Owen
16318   */
16319  class Detector$1 {
16320      constructor(image) {
16321          this.image = image;
16322      }
16323      getImage() {
16324          return this.image;
16325      }
16326      getResultPointCallback() {
16327          return this.resultPointCallback;
16328      }
16329      /**
16330       * <p>Detects a QR Code in an image.</p>
16331       *
16332       * @return {@link DetectorResult} encapsulating results of detecting a QR Code
16333       * @throws NotFoundException if QR Code cannot be found
16334       * @throws FormatException if a QR Code cannot be decoded
16335       */
16336      // public detect(): DetectorResult /*throws NotFoundException, FormatException*/ {
16337      //   return detect(null)
16338      // }
16339      /**
16340       * <p>Detects a QR Code in an image.</p>
16341       *
16342       * @param hints optional hints to detector
16343       * @return {@link DetectorResult} encapsulating results of detecting a QR Code
16344       * @throws NotFoundException if QR Code cannot be found
16345       * @throws FormatException if a QR Code cannot be decoded
16346       */
16347      detect(hints) {
16348          this.resultPointCallback = (hints === null || hints === undefined) ? null :
16349              /*(ResultPointCallback) */ hints.get(DecodeHintType$1.NEED_RESULT_POINT_CALLBACK);
16350          const finder = new FinderPatternFinder(this.image, this.resultPointCallback);
16351          const info = finder.find(hints);
16352          return this.processFinderPatternInfo(info);
16353      }
16354      processFinderPatternInfo(info) {
16355          const topLeft = info.getTopLeft();
16356          const topRight = info.getTopRight();
16357          const bottomLeft = info.getBottomLeft();
16358          const moduleSize = this.calculateModuleSize(topLeft, topRight, bottomLeft);
16359          if (moduleSize < 1.0) {
16360              throw new NotFoundException('No pattern found in proccess finder.');
16361          }
16362          const dimension = Detector$1.computeDimension(topLeft, topRight, bottomLeft, moduleSize);
16363          const provisionalVersion = Version.getProvisionalVersionForDimension(dimension);
16364          const modulesBetweenFPCenters = provisionalVersion.getDimensionForVersion() - 7;
16365          let alignmentPattern = null;
16366          // Anything above version 1 has an alignment pattern
16367          if (provisionalVersion.getAlignmentPatternCenters().length > 0) {
16368              // Guess where a "bottom right" finder pattern would have been
16369              const bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX();
16370              const bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY();
16371              // Estimate that alignment pattern is closer by 3 modules
16372              // from "bottom right" to known top left location
16373              const correctionToTopLeft = 1.0 - 3.0 / modulesBetweenFPCenters;
16374              const estAlignmentX = /*(int) */ Math.floor(topLeft.getX() + correctionToTopLeft * (bottomRightX - topLeft.getX()));
16375              const estAlignmentY = /*(int) */ Math.floor(topLeft.getY() + correctionToTopLeft * (bottomRightY - topLeft.getY()));
16376              // Kind of arbitrary -- expand search radius before giving up
16377              for (let i = 4; i <= 16; i <<= 1) {
16378                  try {
16379                      alignmentPattern = this.findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, i);
16380                      break;
16381                  }
16382                  catch (re /*NotFoundException*/) {
16383                      if (!(re instanceof NotFoundException)) {
16384                          throw re;
16385                      }
16386                      // try next round
16387                  }
16388              }
16389              // If we didn't find alignment pattern... well try anyway without it
16390          }
16391          const transform = Detector$1.createTransform(topLeft, top
16391Right, bottomLeft, alignmentPattern, dimension);
16392          const bits = Detector$1.sampleGrid(this.image, transform, dimension);
16393          let points;
16394          if (alignmentPattern === null) {
16395              points = [bottomLeft, topLeft, topRight];
16396          }
16397          else {
16398              points = [bottomLeft, topLeft, topRight, alignmentPattern];
16399          }
16400          return new DetectorResult(bits, points);
16401      }
16402      static createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension /*int*/) {
16403          const dimMinusThree
vendor: 3,328 bytes, lines 16403-16468
16403 = dimension - 3.5;
16404          let bottomRightX; /*float*/
16405          let bottomRightY; /*float*/
16406          let sourceBottomRightX; /*float*/
16407          let sourceBottomRightY; /*float*/
16408          if (alignmentPattern !== null) {
16409              bottomRightX = alignmentPattern.getX();
16410              bottomRightY = alignmentPattern.getY();
16411              sourceBottomRightX = dimMinusThree - 3.0;
16412              sourceBottomRightY = sourceBottomRightX;
16413          }
16414          else {
16415              // Don't have an alignment pattern, just make up the bottom-right point
16416              bottomRightX = (topRight.getX() - topLeft.getX()) + bottomLeft.getX();
16417              bottomRightY = (topRight.getY() - topLeft.getY()) + bottomLeft.getY();
16418              sourceBottomRightX = dimMinusThree;
16419              sourceBottomRightY = dimMinusThree;
16420          }
16421          return PerspectiveTransform.quadrilateralToQuadrilateral(3.5, 3.5, dimMinusThree, 3.5, sourceBottomRightX, sourceBottomRightY, 3.5, dimMinusThree, topLeft.getX(), topLeft.getY(), topRight.getX(), topRight.getY(), bottomRightX, bottomRightY, bottomLeft.getX(), bottomLeft.getY());
16422      }
16423      static sampleGrid(image, transform, dimension /*int*/) {
16424          const sampler = GridSamplerInstance.getInstance();
16425          return sampler.sampleGridWithTransform(image, dimension, dimension, transform);
16426      }
16427      /**
16428       * <p>Computes the dimension (number of modules on a size) of the QR Code based on the position
16429       * of the finder patterns and estimated module size.</p>
16430       */
16431      static computeDimension(topLeft, topRight, bottomLeft, moduleSize /*float*/) {
16432          const tltrCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize);
16433          const tlblCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize);
16434          let dimension = Math.floor((tltrCentersDimension + tlblCentersDimension) / 2) + 7;
16435          switch (dimension & 0x03) { // mod 4
16436              case 0:
16437                  dimension++;
16438                  break;
16439              // 1? do nothing
16440              case 2:
16441                  dimension--;
16442                  break;
16443              case 3:
16444                  throw new NotFoundException('Dimensions could be not found.');
16445          }
16446          return dimension;
16447      }
16448      /**
16449       * <p>Computes an average estimated module size based on estimated derived from the positions
16450       * of the three finder patterns.</p>
16451       *
16452       * @param topLeft detected top-left finder pattern center
16453       * @param topRight detected top-right finder pattern center
16454       * @param bottomLeft detected bottom-left finder pattern center
16455       * @return estimated module size
16456       */
16457      calculateModuleSize(topLeft, topRight, bottomLeft) {
16458          // Take the average
16459          return (this.calculateModuleSizeOneWay(topLeft, topRight) +
16460              this.calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0;
16461      }
16462      /**
16463       * <p>Estimates module size based on two finder patterns -- it uses
16464       * {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the
16465       * width of each, measuring along the axis between their centers.</p>
16466       */
16467      calculateModuleSizeOneWay(pattern, otherPattern) {
16468          const moduleSizeEst1 
vendor: 5,400 bytes, lines 16468-16579
16468= this.sizeOfBlackWhiteBlackRunBothWays(/*(int) */ Math.floor(pattern.getX()), 
16469          /*(int) */ Math.floor(pattern.getY()), 
16470          /*(int) */ Math.floor(otherPattern.getX()), 
16471          /*(int) */ Math.floor(otherPattern.getY()));
16472          const moduleSizeEst2 = this.sizeOfBlackWhiteBlackRunBothWays(/*(int) */ Math.floor(otherPattern.getX()), 
16473          /*(int) */ Math.floor(otherPattern.getY()), 
16474          /*(int) */ Math.floor(pattern.getX()), 
16475          /*(int) */ Math.floor(pattern.getY()));
16476          if (isNaN(moduleSizeEst1)) {
16477              return moduleSizeEst2 / 7.0;
16478          }
16479          if (isNaN(moduleSizeEst2)) {
16480              return moduleSizeEst1 / 7.0;
16481          }
16482          // Average them, and divide by 7 since we've counted the width of 3 black modules,
16483          // and 1 white and 1 black module on either side. Ergo, divide sum by 14.
16484          return (moduleSizeEst1 + moduleSizeEst2) / 14.0;
16485      }
16486      /**
16487       * See {@link #sizeOfBlackWhiteBlackRun(int, int, int, int)}; computes the total width of
16488       * a finder pattern by looking for a black-white-black run from the center in the direction
16489       * of another point (another finder pattern center), and in the opposite direction too.
16490       */
16491      sizeOfBlackWhiteBlackRunBothWays(fromX /*int*/, fromY /*int*/, toX /*int*/, toY /*int*/) {
16492          let result = this.sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
16493          // Now count other way -- don't run off image though of course
16494          let scale = 1.0;
16495          let otherToX = fromX - (toX - fromX);
16496          if (otherToX < 0) {
16497              scale = fromX / /*(float) */ (fromX - otherToX);
16498              otherToX = 0;
16499          }
16500          else if (otherToX >= this.image.getWidth()) {
16501              scale = (this.image.getWidth() - 1 - fromX) / /*(float) */ (otherToX - fromX);
16502              otherToX = this.image.getWidth() - 1;
16503          }
16504          let otherToY = /*(int) */ Math.floor(fromY - (toY - fromY) * scale);
16505          scale = 1.0;
16506          if (otherToY < 0) {
16507              scale = fromY / /*(float) */ (fromY - otherToY);
16508              otherToY = 0;
16509          }
16510          else if (otherToY >= this.image.getHeight()) {
16511              scale = (this.image.getHeight() - 1 - fromY) / /*(float) */ (otherToY - fromY);
16512              otherToY = this.image.getHeight() - 1;
16513          }
16514          otherToX = /*(int) */ Math.floor(fromX + (otherToX - fromX) * scale);
16515          result += this.sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
16516          // Middle pixel is double-counted this way; subtract 1
16517          return result - 1.0;
16518      }
16519      /**
16520       * <p>This method traces a line from a point in the image, in the direction towards another point.
16521       * It begins in a black region, and keeps going until it finds white, then black, then white again.
16522       * It reports the distance from the start to this point.</p>
16523       *
16524       * <p>This is used when figuring out how wide a finder pattern is, when the finder pattern
16525       * may be skewed or rotated.</p>
16526       */
16527      sizeOfBlackWhiteBlackRun(fromX /*int*/, fromY /*int*/, toX /*int*/, toY /*int*/) {
16528          // Mild variant of Bresenham's algorithm
16529          // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
16530          const steep = Math.abs(toY - fromY) > Math.abs(toX - fromX);
16531          if (steep) {
16532              let temp = fromX;
16533              fromX = fromY;
16534              fromY = temp;
16535              temp = toX;
16536              toX = toY;
16537              toY = temp;
16538          }
16539          const dx = Math.abs(toX - fromX);
16540          const dy = Math.abs(toY - fromY);
16541          let error = -dx / 2;
16542          const xstep = fromX < toX ? 1 : -1;
16543          const ystep = fromY < toY ? 1 : -1;
16544          // In black pixels, looking for white, first or second time.
16545          let state = 0;
16546          // Loop up until x == toX, but not beyond
16547          const xLimit = toX + xstep;
16548          for (let x = fromX, y = fromY; x !== xLimit; x += xstep) {
16549              const realX = steep ? y : x;
16550              const realY = steep ? x : y;
16551              // Does current pixel mean we have moved white to black or vice versa?
16552              // Scanning black in state 0,2 and white in state 1, so if we find the wrong
16553              // color, advance to next state or end if we are in state 2 already
16554              if ((state === 1) === this.image.get(realX, realY)) {
16555                  if (state === 2) {
16556                      return MathUtils.distance(x, y, fromX, fromY);
16557                  }
16558                  state++;
16559              }
16560              error += dy;
16561              if (error > 0) {
16562                  if (y === toY) {
16563                      break;
16564                  }
16565                  y += ystep;
16566                  error -= dx;
16567              }
16568          }
16569          // Found black-white-black; give the benefit of the doubt that the next pixel outside the image
16570          // is "white" so this last point at (toX+xStep,toY) is the right ending. This is really a
16571          // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this.
16572          if (state === 2) {
16573              return MathUtils.distance(toX + xstep, toY, fromX, fromY);
16574          }
16575          // else we didn't find even black-white-black; no estimate is really possible
16576          return NaN;
16577      }
16578      /**
16579       * <p>
16579Attempts to locate an alignment pattern in a limited region of the image, which is
16580       * guessed to contain it. This method uses {@link AlignmentPattern}.</p>
16581       *
16582       * @param overallEstModuleSize estimated module size so far
16583       * @param estAlignmentX x coordinate of center of area probably containing alignment pattern
16584       * @param estAlignmentY y coordinate of above
16585       * @param allowanceFactor number of pixels in all directions to search from the center
16586       * @return {@link AlignmentPattern} if found, or null otherwise
16587       * @throws NotFoundException if an unexpected error occurs during detection
16588       */
16589      findAlignmentInRegion(overallEstModuleSize /*float*/, estAlignmentX /*int*/, estAlignmentY /*int*/, allowanceFactor /*float*/) {
16590          // Look for an alignment pattern (3 modules in size) around where it
16591          // should be
16592          const allowance = /*(int) */ Math.floor(allowanceFactor * overallEstModuleSize);
16593          const alignmentAreaLeftX = Math.max(0, estAlignmentX - allowance);
16594          const alignmentAreaRightX = Math.min(this.image.getWidth() - 1, estAlignmentX + allowance);
16595          if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {
16596              throw new NotFoundException('Alignment top exceeds estimated module size.');
16597          }
16598          const alignmentAreaTopY = Math.max(0, estAlignmentY - allowance);
16599          const alignmentAreaBottomY = Math.min(this.image.getHeight() - 1, estAlignmentY + allowance);
16600          if (alignmentAreaBottomY - alignmentAreaTopY < overallEstModuleSize * 3) {
16601              throw new NotFoundException('Alignment bottom exceeds estimated module size.');
16602          }
16603          const alignmentFinder = new AlignmentPatternFinder(this.image, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX - alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize, this.resultPointCallback);
16604          return alignmentFinder.find();
16605      }
16606  }
16607
16608  /*
16609   * Copyright 2007 ZXing authors
16610   *
16611   * Licensed under the Apache License, Version 2.0 (the "License");
16612   * you may not use this file except in compliance with the License.
16613   * You may obtain a copy of the License at
16614   *
16615   *      http://www.apache.org/licenses/LICENSE-2.0
16616   *
16617   * Unless required by applicable law or agreed to in writing, software
16618   * distributed under the License is distributed on an "AS IS" BASIS,
16619   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16620   * See the License for the specific language governing permissions and
16621   * limitations under the License.
16622   */
16623  /*import java.util.List;*/
16624  /*import java.util.Map;*/
16625  /**
16626   * This implementation can detect and decode QR Codes in an image.
16627   *
16628   * @author Sean Owen
16629   */
16630  class QRCodeReader {
16631      constructor() {
16632          this.decoder = new Decoder();
16633      }
16634      getDecoder() {
16635          return this.decoder;
16636      }
16637      /**
16638       * Locates and decodes a QR code in an image.
16639       *
16640       * @return a representing: string the content encoded by the QR code
16641       * @throws NotFoundException if a QR code cannot be found
16642       * @throws FormatException if a QR code cannot be decoded
16643       * @throws ChecksumException if error correction fails
16644       */
16645      /*@Override*/
16646      // public decode(image: BinaryBitmap): Result /*throws NotFoundException, ChecksumException, FormatException */ {
16647      //   return this.decode(image, null)
16648      // }
16649      /*@Override*/
16650      decode(image, hints) {
16651          let decoderResult;
16652          let points;
16653          if (hints !== undefined && hints !== null && undefined !== hints.get(DecodeHintType$1.PURE_BARCODE)) {
16654              const bits = QRCodeReader.extractPureBits(image.getBlackMatrix());
16655              decoderResult = this.decoder.decodeBitMatrix(bits, hints);
16656              points = QRCodeReader.NO_POINTS;
16657          }
16658          else {
16659              const detectorResult = new Detector$1(image.getBlackMatrix()).detect(hints);
16660              decoderResult = this.decoder.decodeBitMatrix(detectorResult.getBits(), hints);
16661              points = detectorResult.getPoints();
16662          }
16663          // If the code was mirrored: swap the bottom-left and the top-right points.
16664          if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) {
16665              decoderResult.getOther().applyMirroredCorrection(points);
16666          }
16667          const result = new Result$1(decoderResult.getText(), decoderResult.getRawBytes(), undefined, points, BarcodeFormat$1.QR_CODE, undefined);
16668          const byteSegments = decoderResult.getByteSegments();
16669          if (byteSegments !== null) {
16670              result.putMetadata(ResultMetadataType$1.BYTE_SEGMENTS, byteSegments);
16671          }
16672          const ecLevel = decoderResult.getECLevel();
16673          if (ecLevel !== null) {
16674              result.putMetadata(ResultMetadataType$1.ERROR_CORRECTION_LEVEL, ecLevel);
16675          }
vendor: 5,010 bytes, lines 16676-16793
16676          if (decoderResult.hasStructuredAppend()) {
16677              result.putMetadata(ResultMetadataType$1.STRUCTURED_APPEND_SEQUENCE, decoderResult.getStructuredAppendSequenceNumber());
16678              result.putMetadata(ResultMetadataType$1.STRUCTURED_APPEND_PARITY, decoderResult.getStructuredAppendParity());
16679          }
16680          return result;
16681      }
16682      /*@Override*/
16683      reset() {
16684          // do nothing
16685      }
16686      /**
16687       * This method detects a code in a "pure" image -- that is, pure monochrome image
16688       * which contains only an unrotated, unskewed, image of a code, with some white border
16689       * around it. This is a specialized method that works exceptionally fast in this special
16690       * case.
16691       *
16692       * @see com.google.zxing.datamatrix.DataMatrixReader#extractPureBits(BitMatrix)
16693       */
16694      static extractPureBits(image) {
16695          const leftTopBlack = image.getTopLeftOnBit();
16696          const rightBottomBlack = image.getBottomRightOnBit();
16697          if (leftTopBlack === null || rightBottomBlack === null) {
16698              throw new NotFoundException();
16699          }
16700          const moduleSize = this.moduleSize(leftTopBlack, image);
16701          let top = leftTopBlack[1];
16702          let bottom = rightBottomBlack[1];
16703          let left = leftTopBlack[0];
16704          let right = rightBottomBlack[0];
16705          // Sanity check!
16706          if (left >= right || top >= bottom) {
16707              throw new NotFoundException();
16708          }
16709          if (bottom - top !== right - left) {
16710              // Special case, where bottom-right module wasn't black so we found something else in the last row
16711              // Assume it's a square, so use height as the width
16712              right = left + (bottom - top);
16713              if (right >= image.getWidth()) {
16714                  // Abort if that would not make sense -- off image
16715                  throw new NotFoundException();
16716              }
16717          }
16718          const matrixWidth = Math.round((right - left + 1) / moduleSize);
16719          const matrixHeight = Math.round((bottom - top + 1) / moduleSize);
16720          if (matrixWidth <= 0 || matrixHeight <= 0) {
16721              throw new NotFoundException();
16722          }
16723          if (matrixHeight !== matrixWidth) {
16724              // Only possibly decode square regions
16725              throw new NotFoundException();
16726          }
16727          // Push in the "border" by half the module width so that we start
16728          // sampling in the middle of the module. Just in case the image is a
16729          // little off, this will help recover.
16730          const nudge = /*(int) */ Math.floor(moduleSize / 2.0);
16731          top += nudge;
16732          left += nudge;
16733          // But careful that this does not sample off the edge
16734          // "right" is the farthest-right valid pixel location -- right+1 is not necessarily
16735          // This is positive by how much the inner x loop below would be too large
16736          const nudgedTooFarRight = left + /*(int) */ Math.floor((matrixWidth - 1) * moduleSize) - right;
16737          if (nudgedTooFarRight > 0) {
16738              if (nudgedTooFarRight > nudge) {
16739                  // Neither way fits; abort
16740                  throw new NotFoundException();
16741              }
16742              left -= nudgedTooFarRight;
16743          }
16744          // See logic above
16745          const nudgedTooFarDown = top + /*(int) */ Math.floor((matrixHeight - 1) * moduleSize) - bottom;
16746          if (nudgedTooFarDown > 0) {
16747              if (nudgedTooFarDown > nudge) {
16748                  // Neither way fits; abort
16749                  throw new NotFoundException();
16750              }
16751              top -= nudgedTooFarDown;
16752          }
16753          // Now just read off the bits
16754          const bits = new BitMatrix(matrixWidth, matrixHeight);
16755          for (let y = 0; y < matrixHeight; y++) {
16756              const iOffset = top + /*(int) */ Math.floor(y * moduleSize);
16757              for (let x = 0; x < matrixWidth; x++) {
16758                  if (image.get(left + /*(int) */ Math.floor(x * moduleSize), iOffset)) {
16759                      bits.set(x, y);
16760                  }
16761              }
16762          }
16763          return bits;
16764      }
16765      static moduleSize(leftTopBlack, image) {
16766          const height = image.getHeight();
16767          const width = image.getWidth();
16768          let x = leftTopBlack[0];
16769          let y = leftTopBlack[1];
16770          let inBlack = true;
16771          let transitions = 0;
16772          while (x < width && y < height) {
16773              if (inBlack !== image.get(x, y)) {
16774                  if (++transitions === 5) {
16775                      break;
16776                  }
16777                  inBlack = !inBlack;
16778              }
16779              x++;
16780              y++;
16781          }
16782          if (x === width || y === height) {
16783              throw new NotFoundException();
16784          }
16785          return (x - leftTopBlack[0]) / 7.0;
16786      }
16787  }
16788  QRCodeReader.NO_POINTS = new Array();
16789
16790  /*
16791  * Copyright 2009 ZXing authors
16792  *
16793  * Licensed under the Apache License, Version 2.0 (the "License");
16794  * you may not use this file except in compliance with the License.
16795  * You may obtain a copy of the License at
16796  *
16797  *      http://www.apache.org/licenses/LICENSE-2.0
16798  *
16799  * Unless required by applicable law or agreed to in writing, software
16800  * distributed under the License is distributed on an "AS IS" BASIS,
16801  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16802  * See the License for the specific language governing permissions and
16803  * limitations under the License.
16804  */
16805  /**
16806   * @author SITA Lab ([email protected])
16807   * @author Guenther Grau
16808   */
16809  /*public final*/
vendor: 46,561 bytes, lines 16809-17288
16809 class PDF417Common {
16810      PDF417Common() {
16811      }
16812      /**
16813       * @param moduleBitCount values to sum
16814       * @return sum of values
16815       * @deprecated call {@link MathUtils#sum(int[])}
16816       */
16817      // @Deprecated
16818      static getBitCountSum(moduleBitCount) {
16819          return MathUtils.sum(moduleBitCount);
16820      }
16821      static toIntArray(list) {
16822          if (list == null || !list.length) {
16823              return PDF417Common.EMPTY_INT_ARRAY;
16824          }
16825          const result = new Int32Array(list.length);
16826          let i = 0;
16827          for (const integer of list) {
16828              result[i++] = integer;
16829          }
16830          return result;
16831      }
16832      /**
16833       * @param symbol encoded symbol to translate to a codeword
16834       * @return the codeword corresponding to the symbol.
16835       */
16836      static getCodeword(symbol /*int*/) {
16837          const i = Arrays.binarySearch(PDF417Common.SYMBOL_TABLE, symbol & 0x3FFFF);
16838          if (i < 0) {
16839              return -1;
16840          }
16841          return (PDF417Common.CODEWORD_TABLE[i] - 1) % PDF417Common.NUMBER_OF_CODEWORDS;
16842      }
16843  }
16844  PDF417Common.NUMBER_OF_CODEWORDS = 929;
16845  // Maximum Codewords (Data + Error).
16846  PDF417Common.MAX_CODEWORDS_IN_BARCODE = PDF417Common.NUMBER_OF_CODEWORDS - 1;
16847  PDF417Common.MIN_ROWS_IN_BARCODE = 3;
16848  PDF417Common.MAX_ROWS_IN_BARCODE = 90;
16849  // One left row indication column + max 30 data columns + one right row indicator column
16850  // public static /*final*/ MAX_CODEWORDS_IN_ROW: /*int*/ number = 32;
16851  PDF417Common.MODULES_IN_CODEWORD = 17;
16852  PDF417Common.MODULES_IN_STOP_PATTERN = 18;
16853  PDF417Common.BARS_IN_MODULE = 8;
16854  PDF417Common.EMPTY_INT_ARRAY = new Int32Array([]);
16855  /**
16856   * The sorted table of all possible symbols. Extracted from the PDF417
16857   * specification. The index of a symbol in this table corresponds to the
16858   * index into the codeword table.
16859   */
16860  PDF417Common.SYMBOL_TABLE = Int32Array.from([
16861      0x1025e, 0x1027a, 0x1029e, 0x102bc, 0x102f2, 0x102f4, 0x1032e, 0x1034e, 0x1035c, 0x10396, 0x103a6, 0x103ac,
16862      0x10422, 0x10428, 0x10436, 0x10442, 0x10444, 0x10448, 0x10450, 0x1045e, 0x10466, 0x1046c, 0x1047a, 0x10482,
16863      0x1049e, 0x104a0, 0x104bc, 0x104c6, 0x104d8, 0x104ee, 0x104f2, 0x104f4, 0x10504, 0x10508, 0x10510, 0x1051e,
16864      0x10520, 0x1053c, 0x10540, 0x10578, 0x10586, 0x1058c, 0x10598, 0x105b0, 0x105be, 0x105ce, 0x105dc, 0x105e2,
16865      0x105e4, 0x105e8, 0x105f6, 0x1062e, 0x1064e, 0x1065c, 0x1068e, 0x1069c, 0x106b8, 0x106de, 0x106fa, 0x10716,
16866      0x10726, 0x1072c, 0x10746, 0x1074c, 0x10758, 0x1076e, 0x10792, 0x10794, 0x107a2, 0x107a4, 0x107a8, 0x107b6,
16867      0x10822, 0x10828, 0x10842, 0x10848, 0x10850, 0x1085e, 0x10866, 0x1086c, 0x1087a, 0x10882, 0x10884, 0x10890,
16868      0x1089e, 0x108a0, 0x108bc, 0x108c6, 0x108cc, 0x108d8, 0x108ee, 0x108f2, 0x108f4, 0x10902, 0x10908, 0x1091e,
16869      0x10920, 0x1093c, 0x10940, 0x10978, 0x10986, 0x10998, 0x109b0, 0x109be, 0x109ce, 0x109dc, 0x109e2, 0x109e4,
16870      0x109e8, 0x109f6, 0x10a08, 0x10a10, 0x10a1e, 0x10a20, 0x10a3c, 0x10a40, 0x10a78, 0x10af0, 0x10b06, 0x10b0c,
16871      0x10b18, 0x10b30, 0x10b3e, 0x10b60, 0x10b7c, 0x10b8e, 0x10b9c, 0x10bb8, 0x10bc2, 0x10bc4, 0x10bc8, 0x10bd0,
16872      0x10bde, 0x10be6, 0x10bec, 0x10c2e, 0x10c4e, 0x10c5c, 0x10c62, 0x10c64, 0x10c68, 0x10c76, 0x10c8e, 0x10c9c,
16873      0x10cb8, 0x10cc2, 0x10cc4, 0x10cc8, 0x10cd0, 0x10cde, 0x10ce6, 0x10cec, 0x10cfa, 0x10d0e, 0x10d1c, 0x10d38,
16874      0x10d70, 0x10d7e, 0x10d82, 0x10d84, 0x10d88, 0x10d90, 0x10d9e, 0x10da0, 0x10dbc, 0x10dc6, 0x10dcc, 0x10dd8,
16875      0x10dee, 0x10df2, 0x10df4, 0x10e16, 0x10e26, 0x10e2c, 0x10e46, 0x10e58, 0x10e6e, 0x10e86, 0x10e8c, 0x10e98,
16876      0x10eb0, 0x10ebe, 0x10ece, 0x10edc, 0x10f0a, 0x10f12, 0x10f14, 0x10f22, 0x10f28, 0x10f36, 0x10f42, 0x10f44,
16877      0x10f48, 0x10f50, 0x10f5e, 0x10f66, 0x10f6c, 0x10fb2, 0x10fb4, 0x11022, 0x11028, 0x11042, 0x11048, 0x11050,
16878      0x1105e, 0x1107a, 0x11082, 0x11084, 0x11090, 0x1109e, 0x110a0, 0x110bc, 0x110c6, 0x110cc, 0x110d8, 0x110ee,
16879      0x110f2, 0x110f4, 0x11102, 0x1111e, 0x11120, 0x1113c, 0x11140, 0x11178, 0x11186, 0x11198, 0x111b0, 0x111be,
16880      0x111ce, 0x111dc, 0x111e2, 0x111e4, 0x111e8, 0x111f6, 0x11208, 0x1121e, 0x11220, 0x11278, 0x112f0, 0x1130c,
16881      0x11330, 0x1133e, 0x11360, 0x1137c, 0x1138e, 0x1139c, 0x113b8, 0x113c2, 0x113c8, 0x113d0, 0x113de, 0x113e6,
16882      0x113ec, 0x11408, 0x11410, 0x1141e, 0x11420, 0x1143c, 0x11440, 0x11478, 0x114f0, 0x115e0, 0x1160c, 0x11618,
16883      0x11630, 0x1163e, 0x11660, 0x1167c, 0x116c0, 0x116f8, 0x1171c, 0x11738, 0x11770, 0x1177e, 0x11782, 0x11784,
16884      0x11788, 0x11790, 0x1179e, 0x117a0, 0x117bc, 0x117c6, 0x117cc, 0x117d8, 0x117ee, 0x1182e, 0x11834, 0x1184e,
16885      0x1185c, 0x11862, 0x11864, 0x11868, 0x11876, 0x1188e, 0x1189c, 0x118b8, 0x118c2, 0x118c8, 0x118d0, 0x118de,
16886      0x118e6, 0x118ec, 0x118fa, 0x1190e, 0x1191c, 0x11938, 0x11970, 0x1197e, 0x11982, 0x11984, 0x11990, 0x1199e,
16887      0x119a0, 0x119bc, 0x119c6, 0x119cc, 0x119d8, 0x119ee, 0x119f2, 0x119f4, 0x11a0e, 0x11a1c, 0x11a38, 0x11a70,
16888      0x11a7e, 0x11ae0, 0x11afc, 0x11b08, 0x11b10, 0x11b1e, 0x11b20, 0x11b3c, 0x11b40, 0x11b78, 0x11b8c, 0x11b98,
16889      0x11bb0, 0x11bbe, 0x11bce, 0x11bdc, 0x11be2, 0x11be4, 0x11be8, 0x11bf6, 0x11c16, 0x11c26, 0x11c2c, 0x11c46,
16890      0x11c4c, 0x11c58, 0x11c6e, 0x11c86, 0x11c98, 0x11cb0, 0x11cbe, 0x11cce, 0x11cdc, 0x11ce2, 0x11ce4, 0x11ce8,
16891      0x11cf6, 0x11d06, 0x11d0c, 0x11d18, 0x11d30, 0x11d3e, 0x11d60, 0x11d7c, 0x11d8e, 0x11d9c, 0x11db8, 0x11dc4,
16892      0x11dc8, 0x11dd0, 0x11dde, 0x11de6, 0x11dec, 0x11dfa, 0x11e0a, 0x11e12, 0x11e14, 0x11e22, 0x11e24, 0x11e28,
16893      0x11e36, 0x11e42, 0x11e44, 0x11e50, 0x11e5e, 0x11e66, 0x11e6c, 0x11e82, 0x11e84, 0x11e88, 0x11e90, 0x11e9e,
16894      0x11ea0, 0x11ebc, 0x11ec6, 0x11ecc, 0x11ed8, 0x11eee, 0x11f1a, 0x11f2e, 0x11f32, 0x11f34, 0x11f4e, 0x11f5c,
16895      0x11f62, 0x11f64, 0x11f68, 0x11f76, 0x12048, 0x1205e, 0x12082, 0x12084, 0x12090, 0x1209e, 0x120a0, 0x120bc,
16896      0x120d8, 0x120f2, 0x120f4, 0x12108, 0x1211e, 0x12120, 0x1213c, 0x12140, 0x12178, 0x12186, 0x12198, 0x121b0,
16897      0x121be, 0x121e2, 0x121e4, 0x121e8, 0x121f6, 0x12204, 0x12210, 0x1221e, 0x12220, 0x12278, 0x122f0, 0x12306,
16898      0x1230c, 0x12330, 0x1233e, 0x12360, 0x1237c, 0x1238e, 0x1239c, 0x123b8, 0x123c2, 0x123c8, 0x123d0, 0x123e6,
16899      0x123ec, 0x1241e, 0x12420, 0x1243c, 0x124f0, 0x125e0, 0x12618, 0x1263e, 0x12660, 0x1267c, 0x126c0, 0x126f8,
16900      0x12738, 0x12770, 0x1277e, 0x12782, 0x12784, 0x12790, 0x1279e, 0x127a0, 0x127bc, 0x127c6, 0x127cc, 0x127d8,
16901      0x127ee, 0x12820, 0x1283c, 0x12840, 0x12878, 0x128f0, 0x129e0, 0x12bc0, 0x12c18, 0x12c30, 0x12c3e, 0x12c60,
16902      0x12c7c, 0x12cc0, 0x12cf8, 0x12df0, 0x12e1c, 0x12e38, 0x12e70, 0x12e7e, 0x12ee0, 0x12efc, 0x12f04, 0x12f08,
16903      0x12f10, 0x12f20, 0x12f3c, 0x12f40, 0x12f78, 0x12f86, 0x12f8c, 0x12f98, 0x12fb0, 0x12fbe, 0x12fce, 0x12fdc,
16904      0x1302e, 0x1304e, 0x1305c, 0x13062, 0x13068, 0x1308e, 0x1309c, 0x130b8, 0x130c2, 0x130c8, 0x130d0, 0x130de,
16905      0x130ec, 0x130fa, 0x1310e, 0x13138, 0x13170, 0x1317e, 0x13182, 0x13184, 0x13190, 0x1319e, 0x131a0, 0x131bc,
16906      0x131c6, 0x131cc, 0x131d8, 0x131f2, 0x131f4, 0x1320e, 0x1321c, 0x13270, 0x1327e, 0x132e0, 0x132fc, 0x13308,
16907      0x1331e, 0x13320, 0x1333c, 0x13340, 0x13378, 0x13386, 0x13398, 0x133b0, 0x133be, 0x133ce, 0x133dc, 0x133e2,
16908      0x133e4, 0x133e8, 0x133f6, 0x1340e, 0x1341c, 0x13438, 0x13470, 0x1347e, 0x134e0, 0x134fc, 0x135c0, 0x135f8,
16909      0x13608, 0x13610, 0x1361e, 0x13620, 0x1363c, 0x13640, 0x13678, 0x136f0, 0x1370c, 0x13718, 0x13730, 0x1373e,
16910      0x13760, 0x1377c, 0x1379c, 0x137b8, 0x137c2, 0x137c4, 0x137c8, 0x137d0, 0x137de, 0x137e6, 0x137ec, 0x13816,
16911      0x13826, 0x1382c, 0x13846, 0x1384c, 0x13858, 0x1386e, 0x13874, 0x13886, 0x13898, 0x138b0, 0x138be, 0x138ce,
16912      0x138dc, 0x138e2, 0x138e4, 0x138e8, 0x13906, 0x1390c, 0x13930, 0x1393e, 0x13960, 0x1397c, 0x1398e, 0x1399c,
16913      0x139b8, 0x139c8, 0x139d0, 0x139de, 0x139e6, 0x139ec, 0x139fa, 0x13a06, 0x13a0c, 0x13a18, 0x13a30, 0x13a3e,
16914      0x13a60, 0x13a7c, 0x13ac0, 0x13af8, 0x13b0e, 0x13b1c, 0x13b38, 0x13b70, 0x13b7e, 0x13b88, 0x13b90, 0x13b9e,
16915      0x13ba0, 0x13bbc, 0x13bcc, 0x13bd8, 0x13bee, 0x13bf2, 0x13bf4, 0x13c12, 0x13c14, 0x13c22, 0x13c24, 0x13c28,
16916      0x13c36, 0x13c42, 0x13c48, 0x13c50, 0x13c5e, 0x13c66, 0x13c6c, 0x13c82, 0x13c84, 0x13c90, 0x13c9e, 0x13ca0,
16917      0x13cbc, 0x13cc6, 0x13ccc, 0x13cd8, 0x13cee, 0x13d02, 0x13d04, 0x13d08, 0x13d10, 0x13d1e, 0x13d20, 0x13d3c,
16918      0x13d40, 0x13d78, 0x13d86, 0x13d8c, 0x13d98, 0x13db0, 0x13dbe, 0x13dce, 0x13ddc, 0x13de4, 0x13de8, 0x13df6,
16919      0x13e1a, 0x13e2e, 0x13e32, 0x13e34, 0x13e4e, 0x13e5c, 0x13e62, 0x13e64, 0x13e68, 0x13e76, 0x13e8e, 0x13e9c,
16920      0x13eb8, 0x13ec2, 0x13ec4, 0x13ec8, 0x13ed0, 0x13ede, 0x13ee6, 0x13eec, 0x13f26, 0x13f2c, 0x13f3a, 0x13f46,
16921      0x13f4c, 0x13f58, 0x13f6e, 0x13f72, 0x13f74, 0x14082, 0x1409e, 0x140a0, 0x140bc, 0x14104, 0x14108, 0x14110,
16922      0x1411e, 0x14120, 0x1413c, 0x14140, 0x14178, 0x1418c, 0x14198, 0x141b0, 0x141be, 0x141e2, 0x141e4, 0x141e8,
16923      0x14208, 0x14210, 0x1421e, 0x14220, 0x1423c, 0x14240, 0x14278, 0x142f0, 0x14306, 0x1430c, 0x14318, 0x14330,
16924      0x1433e, 0x14360, 0x1437c, 0x1438e, 0x143c2, 0x143c4, 0x143c8, 0x143d0, 0x143e6, 0x143ec, 0x14408, 0x14410,
16925      0x1441e, 0x14420, 0x1443c, 0x14440, 0x14478, 0x144f0, 0x145e0, 0x1460c, 0x14618, 0x14630, 0x1463e, 0x14660,
16926      0x1467c, 0x146c0, 0x146f8, 0x1471c, 0x14738, 0x14770, 0x1477e, 0x14782, 0x14784, 0x14788, 0x14790, 0x147a0,
16927      0x147bc, 0x147c6, 0x147cc, 0x147d8, 0x147ee, 0x14810, 0x14820, 0x1483c, 0x14840, 0x14878, 0x148f0, 0x149e0,
16928      0x14bc0, 0x14c30, 0x14c3e, 0x14c60, 0x14c7c, 0x14cc0, 0x14cf8, 0x14df0, 0x14e38, 0x14e70, 0x14e7e, 0x14ee0,
16929      0x14efc, 0x14f04, 0x14f08, 0x14f10, 0x14f1e, 0x14f20, 0x14f3c, 0x14f40, 0x14f78, 0x14f86, 0x14f8c, 0x14f98,
16930      0x14fb0, 0x14fce, 0x14fdc, 0x15020, 0x15040, 0x15078, 0x150f0, 0x151e0, 0x153c0, 0x15860, 0x1587c, 0x158c0,
16931      0x158f8, 0x159f0, 0x15be0, 0x15c70, 0x15c7e, 0x15ce0, 0x15cfc, 0x15dc0, 0x15df8, 0x15e08, 0x15e10, 0x15e20,
16932      0x15e40, 0x15e78, 0x15ef0, 0x15f0c, 0x15f18, 0x15f30, 0x15f60, 0x15f7c, 0x15f8e, 0x15f9c, 0x15fb8, 0x1604e,
16933      0x1605c, 0x1608e, 0x1609c, 0x160b8, 0x160c2, 0x160c4, 0x160c8, 0x160de, 0x1610e, 0x1611c, 0x16138, 0x16170,
16934      0x1617e, 0x16184, 0x16188, 0x16190, 0x1619e, 0x161a0, 0x161bc, 0x161c6, 0x161cc, 0x161d8, 0x161f2, 0x161f4,
16935      0x1620e, 0x1621c, 0x16238, 0x16270, 0x1627e, 0x162e0, 0x162fc, 0x16304, 0x16308, 0x16310, 0x1631e, 0x16320,
16936      0x1633c, 0x16340, 0x16378, 0x16386, 0x1638c, 0x16398, 0x163b0, 0x163be, 0x163ce, 0x163dc, 0x163e2, 0x163e4,
16937      0x163e8, 0x163f6, 0x1640e, 0x1641c, 0x16438, 0x16470, 0x1647e, 0x164e0, 0x164fc, 0x165c0, 0x165f8, 0x16610,
16938      0x1661e, 0x16620, 0x1663c, 0x16640, 0x16678, 0x166f0, 0x16718, 0x16730, 0x1673e, 0x16760, 0x1677c, 0x1678e,
16939      0x1679c, 0x167b8, 0x167c2, 0x167c4, 0x167c8, 0x167d0, 0x167de, 0x167e6, 0x167ec, 0x1681c, 0x16838, 0x16870,
16940      0x168e0, 0x168fc, 0x169c0, 0x169f8, 0x16bf0, 0x16c10, 0x16c1e, 0x16c20, 0x16c3c, 0x16c40, 0x16c78, 0x16cf0,
16941      0x16de0, 0x16e18, 0x16e30, 0x16e3e, 0x16e60, 0x16e7c, 0x16ec0, 0x16ef8, 0x16f1c, 0x16f38, 0x16f70, 0x16f7e,
16942      0x16f84, 0x16f88, 0x16f90, 0x16f9e, 0x16fa0, 0x16fbc, 0x16fc6, 0x16fcc, 0x16fd8, 0x17026, 0x1702c, 0x17046,
16943      0x1704c, 0x17058, 0x1706e, 0x17086, 0x1708c, 0x17098, 0x170b0, 0x170be, 0x170ce, 0x170dc, 0x170e8, 0x17106,
16944      0x1710c, 0x17118, 0x17130, 0x1713e, 0x17160, 0x1717c, 0x1718e, 0x1719c, 0x171b8, 0x171c2, 0x171c4, 0x171c8,
16945      0x171d0, 0x171de, 0x171e6, 0x171ec, 0x171fa, 0x17206, 0x1720c, 0x17218, 0x17230, 0x1723e, 0x17260, 0x1727c,
16946      0x172c0, 0x172f8, 0x1730e, 0x1731c, 0x17338, 0x17370, 0x1737e, 0x17388, 0x17390, 0x1739e, 0x173a0, 0x173bc,
16947      0x173cc, 0x173d8, 0x173ee, 0x173f2, 0x173f4, 0x1740c, 0x17418, 0x17430, 0x1743e, 0x17460, 0x1747c, 0x174c0,
16948      0x174f8, 0x175f0, 0x1760e, 0x1761c, 0x17638, 0x17670, 0x1767e, 0x176e0, 0x176fc, 0x17708, 0x17710, 0x1771e,
16949      0x17720, 0x1773c, 0x17740, 0x17778, 0x17798, 0x177b0, 0x177be, 0x177dc, 0x177e2, 0x177e4, 0x177e8, 0x17822,
16950      0x17824, 0x17828, 0x17836, 0x17842, 0x17844, 0x17848, 0x17850, 0x1785e, 0x17866, 0x1786c, 0x17882, 0x17884,
16951      0x17888, 0x17890, 0x1789e, 0x178a0, 0x178bc, 0x178c6, 0x178cc, 0x178d8, 0x178ee, 0x178f2, 0x178f4, 0x17902,
16952      0x17904, 0x17908, 0x17910, 0x1791e, 0x17920, 0x1793c, 0x17940, 0x17978, 0x17986, 0x1798c, 0x17998, 0x179b0,
16953      0x179be, 0x179ce, 0x179dc, 0x179e2, 0x179e4, 0x179e8, 0x179f6, 0x17a04, 0x17a08, 0x17a10, 0x17a1e, 0x17a20,
16954      0x17a3c, 0x17a40, 0x17a78, 0x17af0, 0x17b06, 0x17b0c, 0x17b18, 0x17b30, 0x17b3e, 0x17b60, 0x17b7c, 0x17b8e,
16955      0x17b9c, 0x17bb8, 0x17bc4, 0x17bc8, 0x17bd0, 0x17bde, 0x17be6, 0x17bec, 0x17c2e, 0x17c32, 0x17c34, 0x17c4e,
16956      0x17c5c, 0x17c62, 0x17c64, 0x17c68, 0x17c76, 0x17c8e, 0x17c9c, 0x17cb8, 0x17cc2, 0x17cc4, 0x17cc8, 0x17cd0,
16957      0x17cde, 0x17ce6, 0x17cec, 0x17d0e, 0x17d1c, 0x17d38, 0x17d70, 0x17d82, 0x17d84, 0x17d88, 0x17d90, 0x17d9e,
16958      0x17da0, 0x17dbc, 0x17dc6, 0x17dcc, 0x17dd8, 0x17dee, 0x17e26, 0x17e2c, 0x17e3a, 0x17e46, 0x17e4c, 0x17e58,
16959      0x17e6e, 0x17e72, 0x17e74, 0x17e86, 0x17e8c, 0x17e98, 0x17eb0, 0x17ece, 0x17edc, 0x17ee2, 0x17ee4, 0x17ee8,
16960      0x17ef6, 0x1813a, 0x18172, 0x18174, 0x18216, 0x18226, 0x1823a, 0x1824c, 0x18258, 0x1826e, 0x18272, 0x18274,
16961      0x18298, 0x182be, 0x182e2, 0x182e4, 0x182e8, 0x182f6, 0x1835e, 0x1837a, 0x183ae, 0x183d6, 0x18416, 0x18426,
16962      0x1842c, 0x1843a, 0x18446, 0x18458, 0x1846e, 0x18472, 0x18474, 0x18486, 0x184b0, 0x184be, 0x184ce, 0x184dc,
16963      0x184e2, 0x184e4, 0x184e8, 0x184f6, 0x18506, 0x1850c, 0x18518, 0x18530, 0x1853e, 0x18560, 0x1857c, 0x1858e,
16964      0x1859c, 0x185b8, 0x185c2, 0x185c4, 0x185c8, 0x185d0, 0x185de, 0x185e6, 0x185ec, 0x185fa, 0x18612, 0x18614,
16965      0x18622, 0x18628, 0x18636, 0x18642, 0x18650, 0x1865e, 0x1867a, 0x18682, 0x18684, 0x18688, 0x18690, 0x1869e,
16966      0x186a0, 0x186bc, 0x186c6, 0x186cc, 0x186d8, 0x186ee, 0x186f2, 0x186f4, 0x1872e, 0x1874e, 0x1875c, 0x18796,
16967      0x187a6, 0x187ac, 0x187d2, 0x187d4, 0x18826, 0x1882c, 0x1883a, 0x18846, 0x1884c, 0x18858, 0x1886e, 0x18872,
16968      0x18874, 0x18886, 0x18898, 0x188b0, 0x188be, 0x188ce, 0x188dc, 0x188e2, 0x188e4, 0x188e8, 0x188f6, 0x1890c,
16969      0x18930, 0x1893e, 0x18960, 0x1897c, 0x1898e, 0x189b8, 0x189c2, 0x189c8, 0x189d0, 0x189de, 0x189e6, 0x189ec,
16970      0x189fa, 0x18a18, 0x18a30, 0x18a3e, 0x18a60, 0x18a7c, 0x18ac0, 0x18af8, 0x18b1c, 0x18b38, 0x18b70, 0x18b7e,
16971      0x18b82, 0x18b84, 0x18b88, 0x18b90, 0x18b9e, 0x18ba0, 0x18bbc, 0x18bc6, 0x18bcc, 0x18bd8, 0x18bee, 0x18bf2,
16972      0x18bf4, 0x18c22, 0x18c24, 0x18c28, 0x18c36, 0x18c42, 0x18c48, 0x18c50, 0x18c5e, 0x18c66, 0x18c7a, 0x18c82,
16973      0x18c84, 0x18c90, 0x18c9e, 0x18ca0, 0x18cbc, 0x18ccc, 0x18cf2, 0x18cf4, 0x18d04, 0x18d08, 0x18d10, 0x18d1e,
16974      0x18d20, 0x18d3c, 0x18d40, 0x18d78, 0x18d86, 0x18d98, 0x18dce, 0x18de2, 0x18de4, 0x18de8, 0x18e2e, 0x18e32,
16975      0x18e34, 0x18e4e, 0x18e5c, 0x18e62, 0x18e64, 0x18e68, 0x18e8e, 0x18e9c, 0x18eb8, 0x18ec2, 0x18ec4, 0x18ec8,
16976      0x18ed0, 0x18efa, 0x18f16, 0x18f26, 0x18f2c, 0x18f46, 0x18f4c, 0x18f58, 0x18f6e, 0x18f8a, 0x18f92, 0x18f94,
16977      0x18fa2, 0x18fa4, 0x18fa8, 0x18fb6, 0x1902c, 0x1903a, 0x19046, 0x1904c, 0x19058, 0x19072, 0x19074, 0x19086,
16978      0x19098, 0x190b0, 0x190be, 0x190ce, 0x190dc, 0x190e2, 0x190e8, 0x190f6, 0x19106, 0x1910c, 0x19130, 0x1913e,
16979      0x19160, 0x1917c, 0x1918e, 0x1919c, 0x191b8, 0x191c2, 0x191c8, 0x191d0, 0x191de, 0x191e6, 0x191ec, 0x191fa,
16980      0x19218, 0x1923e, 0x19260, 0x1927c, 0x192c0, 0x192f8, 0x19338, 0x19370, 0x1937e, 0x19382, 0x19384, 0x19390,
16981      0x1939e, 0x193a0, 0x193bc, 0x193c6, 0x193cc, 0x193d8, 0x193ee, 0x193f2, 0x193f4, 0x19430, 0x1943e, 0x19460,
16982      0x1947c, 0x194c0, 0x194f8, 0x195f0, 0x19638, 0x19670, 0x1967e, 0x196e0, 0x196fc, 0x19702, 0x19704, 0x19708,
16983      0x19710, 0x19720, 0x1973c, 0x19740, 0x19778, 0x19786, 0x1978c, 0x19798, 0x197b0, 0x197be, 0x197ce, 0x197dc,
16984      0x197e2, 0x197e4, 0x197e8, 0x19822, 0x19824, 0x19842, 0x19848, 0x19850, 0x1985e, 0x19866, 0x1987a, 0x19882,
16985      0x19884, 0x19890, 0x1989e, 0x198a0, 0x198bc, 0x198cc, 0x198f2, 0x198f4, 0x19902, 0x19908, 0x1991e, 0x19920,
16986      0x1993c, 0x19940, 0x19978, 0x19986, 0x19998, 0x199ce, 0x199e2, 0x199e4, 0x199e8, 0x19a08, 0x19a10, 0x19a1e,
16987      0x19a20, 0x19a3c, 0x19a40, 0x19a78, 0x19af0, 0x19b18, 0x19b3e, 0x19b60, 0x19b9c, 0x19bc2, 0x19bc4, 0x19bc8,
16988      0x19bd0, 0x19be6, 0x19c2e, 0x19c34, 0x19c4e, 0x19c5c, 0x19c62, 0x19c64, 0x19c68, 0x19c8e, 0x19c9c, 0x19cb8,
16989      0x19cc2, 0x19cc8, 0x19cd0, 0x19ce6, 0x19cfa, 0x19d0e, 0x19d1c, 0x19d38, 0x19d70, 0x19d7e, 0x19d82, 0x19d84,
16990      0x19d88, 0x19d90, 0x19da0, 0x19dcc, 0x19df2, 0x19df4, 0x19e16, 0x19e26, 0x19e2c, 0x19e46, 0x19e4c, 0x19e58,
16991      0x19e74, 0x19e86, 0x19e8c, 0x19e98, 0x19eb0, 0x19ebe, 0x19ece, 0x19ee2, 0x19ee4, 0x19ee8, 0x19f0a, 0x19f12,
16992      0x19f14, 0x19f22, 0x19f24, 0x19f28, 0x19f42, 0x19f44, 0x19f48, 0x19f50, 0x19f5e, 0x19f6c, 0x19f9a, 0x19fae,
16993      0x19fb2, 0x19fb4, 0x1a046, 0x1a04c, 0x1a072, 0x1a074, 0x1a086, 0x1a08c, 0x1a098, 0x1a0b0, 0x1a0be, 0x1a0e2,
16994      0x1a0e4, 0x1a0e8, 0x1a0f6, 0x1a106, 0x1a10c, 0x1a118, 0x1a130, 0x1a13e, 0x1a160, 0x1a17c, 0x1a18e, 0x1a19c,
16995      0x1a1b8, 0x1a1c2, 0x1a1c4, 0x1a1c8, 0x1a1d0, 0x1a1de, 0x1a1e6, 0x1a1ec, 0x1a218, 0x1a230, 0x1a23e, 0x1a260,
16996      0x1a27c, 0x1a2c0, 0x1a2f8, 0x1a31c, 0x1a338, 0x1a370, 0x1a37e, 0x1a382, 0x1a384, 0x1a388, 0x1a390, 0x1a39e,
16997      0x1a3a0, 0x1a3bc, 0x1a3c6, 0x1a3cc, 0x1a3d8, 0x1a3ee, 0x1a3f2, 0x1a3f4, 0x1a418, 0x1a430, 0x1a43e, 0x1a460,
16998      0x1a47c, 0x1a4c0, 0x1a4f8, 0x1a5f0, 0x1a61c, 0x1a638, 0x1a670, 0x1a67e, 0x1a6e0, 0x1a6fc, 0x1a702, 0x1a704,
16999      0x1a708, 0x1a710, 0x1a71e, 0x1a720, 0x1a73c, 0x1a740, 0x1a778, 0x1a786, 0x1a78c, 0x1a798, 0x1a7b0, 0x1a7be,
17000      0x1a7ce, 0x1a7dc, 0x1a7e2, 0x1a7e4, 0x1a7e8, 0x1a830, 0x1a860, 0x1a87c, 0x1a8c0, 0x1a8f8, 0x1a9f0, 0x1abe0,
17001      0x1ac70, 0x1ac7e, 0x1ace0, 0x1acfc, 0x1adc0, 0x1adf8, 0x1ae04, 0x1ae08, 0x1ae10, 0x1ae20, 0x1ae3c, 0x1ae40,
17002      0x1ae78, 0x1aef0, 0x1af06, 0x1af0c, 0x1af18, 0x1af30, 0x1af3e, 0x1af60, 0x1af7c, 0x1af8e, 0x1af9c, 0x1afb8,
17003      0x1afc4, 0x1afc8, 0x1afd0, 0x1afde, 0x1b042, 0x1b05e, 0x1b07a, 0x1b082, 0x1b084, 0x1b088, 0x1b090, 0x1b09e,
17004      0x1b0a0, 0x1b0bc, 0x1b0cc, 0x1b0f2, 0x1b0f4, 0x1b102, 0x1b104, 0x1b108, 0x1b110, 0x1b11e, 0x1b120, 0x1b13c,
17005      0x1b140, 0x1b178, 0x1b186, 0x1b198, 0x1b1ce, 0x1b1e2, 0x1b1e4, 0x1b1e8, 0x1b204, 0x1b208, 0x1b210, 0x1b21e,
17006      0x1b220, 0x1b23c, 0x1b240, 0x1b278, 0x1b2f0, 0x1b30c, 0x1b33e, 0x1b360, 0x1b39c, 0x1b3c2, 0x1b3c4, 0x1b3c8,
17007      0x1b3d0, 0x1b3e6, 0x1b410, 0x1b41e, 0x1b420, 0x1b43c, 0x1b440, 0x1b478, 0x1b4f0, 0x1b5e0, 0x1b618, 0x1b660,
17008      0x1b67c, 0x1b6c0, 0x1b738, 0x1b782, 0x1b784, 0x1b788, 0x1b790, 0x1b79e, 0x1b7a0, 0x1b7cc, 0x1b82e, 0x1b84e,
17009      0x1b85c, 0x1b88e, 0x1b89c, 0x1b8b8, 0x1b8c2, 0x1b8c4, 0x1b8c8, 0x1b8d0, 0x1b8e6, 0x1b8fa, 0x1b90e, 0x1b91c,
17010      0x1b938, 0x1b970, 0x1b97e, 0x1b982, 0x1b984, 0x1b988, 0x1b990, 0x1b99e, 0x1b9a0, 0x1b9cc, 0x1b9f2, 0x1b9f4,
17011      0x1ba0e, 0x1ba1c, 0x1ba38, 0x1ba70, 0x1ba7e, 0x1bae0, 0x1bafc, 0x1bb08, 0x1bb10, 0x1bb20, 0x1bb3c, 0x1bb40,
17012      0x1bb98, 0x1bbce, 0x1bbe2, 0x1bbe4, 0x1bbe8, 0x1bc16, 0x1bc26, 0x1bc2c, 0x1bc46, 0x1bc4c, 0x1bc58, 0x1bc72,
17013      0x1bc74, 0x1bc86, 0x1bc8c, 0x1bc98, 0x1bcb0, 0x1bcbe, 0x1bcce, 0x1bce2, 0x1bce4, 0x1bce8, 0x1bd06, 0x1bd0c,
17014      0x1bd18, 0x1bd30, 0x1bd3e, 0x1bd60, 0x1bd7c, 0x1bd9c, 0x1bdc2, 0x1bdc4, 0x1bdc8, 0x1bdd0, 0x1bde6, 0x1bdfa,
17015      0x1be12, 0x1be14, 0x1be22, 0x1be24, 0x1be28, 0x1be42, 0x1be44, 0x1be48, 0x1be50, 0x1be5e, 0x1be66, 0x1be82,
17016      0x1be84, 0x1be88, 0x1be90, 0x1be9e, 0x1bea0, 0x1bebc, 0x1becc, 0x1bef4, 0x1bf1a, 0x1bf2e, 0x1bf32, 0x1bf34,
17017      0x1bf4e, 0x1bf5c, 0x1bf62, 0x1bf64, 0x1bf68, 0x1c09a, 0x1c0b2, 0x1c0b4, 0x1c11a, 0x1c132, 0x1c134, 0x1c162,
17018      0x1c164, 0x1c168, 0x1c176, 0x1c1ba, 0x1c21a, 0x1c232, 0x1c234, 0x1c24e, 0x1c25c, 0x1c262, 0x1c264, 0x1c268,
17019      0x1c276, 0x1c28e, 0x1c2c2, 0x1c2c4, 0x1c2c8, 0x1c2d0, 0x1c2de, 0x1c2e6, 0x1c2ec, 0x1c2fa, 0x1c316, 0x1c326,
17020      0x1c33a, 0x1c346, 0x1c34c, 0x1c372, 0x1c374, 0x1c41a, 0x1c42e, 0x1c432, 0x1c434, 0x1c44e, 0x1c45c, 0x1c462,
17021      0x1c464, 0x1c468, 0x1c476, 0x1c48e, 0x1c49c, 0x1c4b8, 0x1c4c2, 0x1c4c8, 0x1c4d0, 0x1c4de, 0x1c4e6, 0x1c4ec,
17022      0x1c4fa, 0x1c51c, 0x1c538, 0x1c570, 0x1c57e, 0x1c582, 0x1c584, 0x1c588, 0x1c590, 0x1c59e, 0x1c5a0, 0x1c5bc,
17023      0x1c5c6, 0x1c5cc, 0x1c5d8, 0x1c5ee, 0x1c5f2, 0x1c5f4, 0x1c616, 0x1c626, 0x1c62c, 0x1c63a, 0x1c646, 0x1c64c,
17024      0x1c658, 0x1c66e, 0x1c672, 0x1c674, 0x1c686, 0x1c68c, 0x1c698, 0x1c6b0, 0x1c6be, 0x1c6ce, 0x1c6dc, 0x1c6e2,
17025      0x1c6e4, 0x1c6e8, 0x1c712, 0x1c714, 0x1c722, 0x1c728, 0x1c736, 0x1c742, 0x1c744, 0x1c748, 0x1c750, 0x1c75e,
17026      0x1c766, 0x1c76c, 0x1c77a, 0x1c7ae, 0x1c7d6, 0x1c7ea, 0x1c81a, 0x1c82e, 0x1c832, 0x1c834, 0x1c84e, 0x1c85c,
17027      0x1c862, 0x1c864, 0x1c868, 0x1c876, 0x1c88e, 0x1c89c, 0x1c8b8, 0x1c8c2, 0x1c8c8, 0x1c8d0, 0x1c8de, 0x1c8e6,
17028      0x1c8ec, 0x1c8fa, 0x1c90e, 0x1c938, 0x1c970, 0x1c97e, 0x1c982, 0x1c984, 0x1c990, 0x1c99e, 0x1c9a0, 0x1c9bc,
17029      0x1c9c6, 0x1c9cc, 0x1c9d8, 0x1c9ee, 0x1c9f2, 0x1c9f4, 0x1ca38, 0x1ca70, 0x1ca7e, 0x1cae0, 0x1cafc, 0x1cb02,
17030      0x1cb04, 0x1cb08, 0x1cb10, 0x1cb20, 0x1cb3c, 0x1cb40, 0x1cb78, 0x1cb86, 0x1cb8c, 0x1cb98, 0x1cbb0, 0x1cbbe,
17031      0x1cbce, 0x1cbdc, 0x1cbe2, 0x1cbe4, 0x1cbe8, 0x1cbf6, 0x1cc16, 0x1cc26, 0x1cc2c, 0x1cc3a, 0x1cc46, 0x1cc58,
17032      0x1cc72, 0x1cc74, 0x1cc86, 0x1ccb0, 0x1ccbe, 0x1ccce, 0x1cce2, 0x1cce4, 0x1cce8, 0x1cd06, 0x1cd0c, 0x1cd18,
17033      0x1cd30, 0x1cd3e, 0x1cd60, 0x1cd7c, 0x1cd9c, 0x1cdc2, 0x1cdc4, 0x1cdc8, 0x1cdd0, 0x1cdde, 0x1cde6, 0x1cdfa,
17034      0x1ce22, 0x1ce28, 0x1ce42, 0x1ce50, 0x1ce5e, 0x1ce66, 0x1ce7a, 0x1ce82, 0x1ce84, 0x1ce88, 0x1ce90, 0x1ce9e,
17035      0x1cea0, 0x1cebc, 0x1cecc, 0x1cef2, 0x1cef4, 0x1cf2e, 0x1cf32, 0x1cf34, 0x1cf4e, 0x1cf5c, 0x1cf62, 0x1cf64,
17036      0x1cf68, 0x1cf96, 0x1cfa6, 0x1cfac, 0x1cfca, 0x1cfd2, 0x1cfd4, 0x1d02e, 0x1d032, 0x1d034, 0x1d04e, 0x1d05c,
17037      0x1d062, 0x1d064, 0x1d068, 0x1d076, 0x1d08e, 0x1d09c, 0x1d0b8, 0x1d0c2, 0x1d0c4, 0x1d0c8, 0x1d0d0, 0x1d0de,
17038      0x1d0e6, 0x1d0ec, 0x1d0fa, 0x1d11c, 0x1d138, 0x1d170, 0x1d17e, 0x1d182, 0x1d184, 0x1d188, 0x1d190, 0x1d19e,
17039      0x1d1a0, 0x1d1bc, 0x1d1c6, 0x1d1cc, 0x1d1d8, 0x1d1ee, 0x1d1f2, 0x1d1f4, 0x1d21c, 0x1d238, 0x1d270, 0x1d27e,
17040      0x1d2e0, 0x1d2fc, 0x1d302, 0x1d304, 0x1d308, 0x1d310, 0x1d31e, 0x1d320, 0x1d33c, 0x1d340, 0x1d378, 0x1d386,
17041      0x1d38c, 0x1d398, 0x1d3b0, 0x1d3be, 0x1d3ce, 0x1d3dc, 0x1d3e2, 0x1d3e4, 0x1d3e8, 0x1d3f6, 0x1d470, 0x1d47e,
17042      0x1d4e0, 0x1d4fc, 0x1d5c0, 0x1d5f8, 0x1d604, 0x1d608, 0x1d610, 0x1d620, 0x1d640, 0x1d678, 0x1d6f0, 0x1d706,
17043      0x1d70c, 0x1d718, 0x1d730, 0x1d73e, 0x1d760, 0x1d77c, 0x1d78e, 0x1d79c, 0x1d7b8, 0x1d7c2, 0x1d7c4, 0x1d7c8,
17044      0x1d7d0, 0x1d7de, 0x1d7e6, 0x1d7ec, 0x1d826, 0x1d82c, 0x1d83a, 0x1d846, 0x1d84c, 0x1d858, 0x1d872, 0x1d874,
17045      0x1d886, 0x1d88c, 0x1d898, 0x1d8b0, 0x1d8be, 0x1d8ce, 0x1d8e2, 0x1d8e4, 0x1d8e8, 0x1d8f6, 0x1d90c, 0x1d918,
17046      0x1d930, 0x1d93e, 0x1d960, 0x1d97c, 0x1d99c, 0x1d9c2, 0x1d9c4, 0x1d9c8, 0x1d9d0, 0x1d9e6, 0x1d9fa, 0x1da0c,
17047      0x1da18, 0x1da30, 0x1da3e, 0x1da60, 0x1da7c, 0x1dac0, 0x1daf8, 0x1db38, 0x1db82, 0x1db84, 0x1db88, 0x1db90,
17048      0x1db9e, 0x1dba0, 0x1dbcc, 0x1dbf2, 0x1dbf4, 0x1dc22, 0x1dc42, 0x1dc44, 0x1dc48, 0x1dc50, 0x1dc5e, 0x1dc66,
17049      0x1dc7a, 0x1dc82, 0x1dc84, 0x1dc88, 0x1dc90, 0x1dc9e, 0x1dca0, 0x1dcbc, 0x1dccc, 0x1dcf2, 0x1dcf4, 0x1dd04,
17050      0x1dd08, 0x1dd10, 0x1dd1e, 0x1dd20, 0x1dd3c, 0x1dd40, 0x1dd78, 0x1dd86, 0x1dd98, 0x1ddce, 0x1dde2, 0x1dde4,
17051      0x1dde8, 0x1de2e, 0x1de32, 0x1de34, 0x1de4e, 0x1de5c, 0x1de62, 0x1de64, 0x1de68, 0x1de8e, 0x1de9c, 0x1deb8,
17052      0x1dec2, 0x1dec4, 0x1dec8, 0x1ded0, 0x1dee6, 0x1defa, 0x1df16, 0x1df26, 0x1df2c, 0x1df46, 0x1df4c, 0x1df58,
17053      0x1df72, 0x1df74, 0x1df8a, 0x1df92, 0x1df94, 0x1dfa2, 0x1dfa4, 0x1dfa8, 0x1e08a, 0x1e092, 0x1e094, 0x1e0a2,
17054      0x1e0a4, 0x1e0a8, 0x1e0b6, 0x1e0da, 0x1e10a, 0x1e112, 0x1e114, 0x1e122, 0x1e124, 0x1e128, 0x1e136, 0x1e142,
17055      0x1e144, 0x1e148, 0x1e150, 0x1e166, 0x1e16c, 0x1e17a, 0x1e19a, 0x1e1b2, 0x1e1b4, 0x1e20a, 0x1e212, 0x1e214,
17056      0x1e222, 0x1e224, 0x1e228, 0x1e236, 0x1e242, 0x1e248, 0x1e250, 0x1e25e, 0x1e266, 0x1e26c, 0x1e27a, 0x1e282,
17057      0x1e284, 0x1e288, 0x1e290, 0x1e2a0, 0x1e2bc, 0x1e2c6, 0x1e2cc, 0x1e2d8, 0x1e2ee, 0x1e2f2, 0x1e2f4, 0x1e31a,
17058      0x1e332, 0x1e334, 0x1e35c, 0x1e362, 0x1e364, 0x1e368, 0x1e3ba, 0x1e40a, 0x1e412, 0x1e414, 0x1e422, 0x1e428,
17059      0x1e436, 0x1e442, 0x1e448, 0x1e450, 0x1e45e, 0x1e466, 0x1e46c, 0x1e47a, 0x1e482, 0x1e484, 0x1e490, 0x1e49e,
17060      0x1e4a0, 0x1e4bc, 0x1e4c6, 0x1e4cc, 0x1e4d8, 0x1e4ee, 0x1e4f2, 0x1e4f4, 0x1e502, 0x1e504, 0x1e508, 0x1e510,
17061      0x1e51e, 0x1e520, 0x1e53c, 0x1e540, 0x1e578, 0x1e586, 0x1e58c, 0x1e598, 0x1e5b0, 0x1e5be, 0x1e5ce, 0x1e5dc,
17062      0x1e5e2, 0x1e5e4, 0x1e5e8, 0x1e5f6, 0x1e61a, 0x1e62e, 0x1e632, 0x1e634, 0x1e64e, 0x1e65c, 0x1e662, 0x1e668,
17063      0x1e68e, 0x1e69c, 0x1e6b8, 0x1e6c2, 0x1e6c4, 0x1e6c8, 0x1e6d0, 0x1e6e6, 0x1e6fa, 0x1e716, 0x1e726, 0x1e72c,
17064      0x1e73a, 0x1e746, 0x1e74c, 0x1e758, 0x1e772, 0x1e774, 0x1e792, 0x1e794, 0x1e7a2, 0x1e7a4, 0x1e7a8, 0x1e7b6,
17065      0x1e812, 0x1e814, 0x1e822, 0x1e824, 0x1e828, 0x1e836, 0x1e842, 0x1e844, 0x1e848, 0x1e850, 0x1e85e, 0x1e866,
17066      0x1e86c, 0x1e87a, 0x1e882, 0x1e884, 0x1e888, 0x1e890, 0x1e89e, 0x1e8a0, 0x1e8bc, 0x1e8c6, 0x1e8cc, 0x1e8d8,
17067      0x1e8ee, 0x1e8f2, 0x1e8f4, 0x1e902, 0x1e904, 0x1e908, 0x1e910, 0x1e920, 0x1e93c, 0x1e940, 0x1e978, 0x1e986,
17068      0x1e98c, 0x1e998, 0x1e9b0, 0x1e9be, 0x1e9ce, 0x1e9dc, 0x1e9e2, 0x1e9e4, 0x1e9e8, 0x1e9f6, 0x1ea04, 0x1ea08,
17069      0x1ea10, 0x1ea20, 0x1ea40, 0x1ea78, 0x1eaf0, 0x1eb06, 0x1eb0c, 0x1eb18, 0x1eb30, 0x1eb3e, 0x1eb60, 0x1eb7c,
17070      0x1eb8e, 0x1eb9c, 0x1ebb8, 0x1ebc2, 0x1ebc4, 0x1ebc8, 0x1ebd0, 0x1ebde, 0x1ebe6, 0x1ebec, 0x1ec1a, 0x1ec2e,
17071      0x1ec32, 0x1ec34, 0x1ec4e, 0x1ec5c, 0x1ec62, 0x1ec64, 0x1ec68, 0x1ec8e, 0x1ec9c, 0x1ecb8, 0x1ecc2, 0x1ecc4,
17072      0x1ecc8, 0x1ecd0, 0x1ece6, 0x1ecfa, 0x1ed0e, 0x1ed1c, 0x1ed38, 0x1ed70, 0x1ed7e, 0x1ed82, 0x1ed84, 0x1ed88,
17073      0x1ed90, 0x1ed9e, 0x1eda0, 0x1edcc, 0x1edf2, 0x1edf4, 0x1ee16, 0x1ee26, 0x1ee2c, 0x1ee3a, 0x1ee46, 0x1ee4c,
17074      0x1ee58, 0x1ee6e, 0x1ee72, 0x1ee74, 0x1ee86, 0x1ee8c, 0x1ee98, 0x1eeb0, 0x1eebe, 0x1eece, 0x1eedc, 0x1eee2,
17075      0x1eee4, 0x1eee8, 0x1ef12, 0x1ef22, 0x1ef24, 0x1ef28, 0x1ef36, 0x1ef42, 0x1ef44, 0x1ef48, 0x1ef50, 0x1ef5e,
17076      0x1ef66, 0x1ef6c, 0x1ef7a, 0x1efae, 0x1efb2, 0x1efb4, 0x1efd6, 0x1f096, 0x1f0a6, 0x1f0ac, 0x1f0ba, 0x1f0ca,
17077      0x1f0d2, 0x1f0d4, 0x1f116, 0x1f126, 0x1f12c, 0x1f13a, 0x1f146, 0x1f14c, 0x1f158, 0x1f16e, 0x1f172, 0x1f174,
17078      0x1f18a, 0x1f192, 0x1f194, 0x1f1a2, 0x1f1a4, 0x1f1a8, 0x1f1da, 0x1f216, 0x1f226, 0x1f22c, 0x1f23a, 0x1f246,
17079      0x1f258, 0x1f26e, 0x1f272, 0x1f274, 0x1f286, 0x1f28c, 0x1f298, 0x1f2b0, 0x1f2be, 0x1f2ce, 0x1f2dc, 0x1f2e2,
17080      0x1f2e4, 0x1f2e8, 0x1f2f6, 0x1f30a, 0x1f312, 0x1f314, 0x1f322, 0x1f328, 0x1f342, 0x1f344, 0x1f348, 0x1f350,
17081      0x1f35e, 0x1f366, 0x1f37a, 0x1f39a, 0x1f3ae, 0x1f3b2, 0x1f3b4, 0x1f416, 0x1f426, 0x1f42c, 0x1f43a, 0x1f446,
17082      0x1f44c, 0x1f458, 0x1f46e, 0x1f472, 0x1f474, 0x1f486, 0x1f48c, 0x1f498, 0x1f4b0, 0x1f4be, 0x1f4ce, 0x1f4dc,
17083      0x1f4e2, 0x1f4e4, 0x1f4e8, 0x1f4f6, 0x1f506, 0x1f50c, 0x1f518, 0x1f530, 0x1f53e, 0x1f560, 0x1f57c, 0x1f58e,
17084      0x1f59c, 0x1f5b8, 0x1f5c2, 0x1f5c4, 0x1f5c8, 0x1f5d0, 0x1f5de, 0x1f5e6, 0x1f5ec, 0x1f5fa, 0x1f60a, 0x1f612,
17085      0x1f614, 0x1f622, 0x1f624, 0x1f628, 0x1f636, 0x1f642, 0x1f644, 0x1f648, 0x1f650, 0x1f65e, 0x1f666, 0x1f67a,
17086      0x1f682, 0x1f684, 0x1f688, 0x1f690, 0x1f69e, 0x1f6a0, 0x1f6bc, 0x1f6cc, 0x1f6f2, 0x1f6f4, 0x1f71a, 0x1f72e,
17087      0x1f732, 0x1f734, 0x1f74e, 0x1f75c, 0x1f762, 0x1f764, 0x1f768, 0x1f776, 0x1f796, 0x1f7a6, 0x1f7ac, 0x1f7ba,
17088      0x1f7d2, 0x1f7d4, 0x1f89a, 0x1f8ae, 0x1f8b2, 0x1f8b4, 0x1f8d6, 0x1f8ea, 0x1f91a, 0x1f92e, 0x1f932, 0x1f934,
17089      0x1f94e, 0x1f95c, 0x1f962, 0x1f964, 0x1f968, 0x1f976, 0x1f996, 0x1f9a6, 0x1f9ac, 0x1f9ba, 0x1f9ca, 0x1f9d2,
17090      0x1f9d4, 0x1fa1a, 0x1fa2e, 0x1fa32, 0x1fa34, 0x1fa4e, 0x1fa5c, 0x1fa62, 0x1fa64, 0x1fa68, 0x1fa76, 0x1fa8e,
17091      0x1fa9c, 0x1fab8, 0x1fac2, 0x1fac4, 0x1fac8, 0x1fad0, 0x1fade, 0x1fae6, 0x1faec, 0x1fb16, 0x1fb26, 0x1fb2c,
17092      0x1fb3a, 0x1fb46, 0x1fb4c, 0x1fb58, 0x1fb6e, 0x1fb72, 0x1fb74, 0x1fb8a, 0x1fb92, 0x1fb94, 0x1fba2, 0x1fba4,
17093      0x1fba8, 0x1fbb6, 0x1fbda
17094  ]);
17095  /**
17096   * This table contains to codewords for all symbols.
17097   */
17098  PDF417Common.CODEWORD_TABLE = Int32Array.from([
17099      2627, 1819, 2622, 2621, 1813, 1812, 2729, 2724, 2723, 2779, 2774, 2773, 902, 896, 908, 868, 865, 861, 859, 2511,
17100      873, 871, 1780, 835, 2493, 825, 2491, 842, 837, 844, 1764, 1762, 811, 810, 809, 2483, 807, 2482, 806, 2480, 815,
17101      814, 813, 812, 2484, 817, 816, 1745, 1744, 1742, 1746, 2655, 2637, 2635, 2626, 2625, 2623, 2628, 1820, 2752,
17102      2739, 2737, 2728, 2727, 2725, 2730, 2785, 2783, 2778, 2777, 2775, 2780, 787, 781, 747, 739, 736, 2413, 754, 752,
17103      1719, 692, 689, 681, 2371, 678, 2369, 700, 697, 694, 703, 1688, 1686, 642, 638, 2343, 631, 2341, 627, 2338, 651,
17104      646, 643, 2345, 654, 652, 1652, 1650, 1647, 1654, 601, 599, 2322, 596, 2321, 594, 2319, 2317, 611, 610, 608, 606,
17105      2324, 603, 2323, 615, 614, 612, 1617, 1616, 1614, 1612, 616, 1619, 1618, 2575, 2538, 2536, 905, 901, 898, 909,
17106      2509, 2507, 2504, 870, 867, 864, 860, 2512, 875, 872, 1781, 2490, 2489, 2487, 2485, 1748, 836, 834, 832, 830,
17107      2494, 827, 2492, 843, 841, 839, 845, 1765, 1763, 2701, 2676, 2674, 2653, 2648, 2656, 2634, 2633, 2631, 2629,
17108      1821, 2638, 2636, 2770, 2763, 2761, 2750, 2745, 2753, 2736, 2735, 2733, 2731, 1848, 2740, 2738, 2786, 2784, 591,
17109      588, 576, 569, 566, 2296, 1590, 537, 534, 526, 2276, 522, 2274, 545, 542, 539, 548, 1572, 1570, 481, 2245, 466,
17110      2242, 462, 2239, 492, 485, 482, 2249, 496, 494, 1534, 1531, 1528, 1538, 413, 2196, 406, 2191, 2188, 425, 419,
17111      2202, 415, 2199, 432, 430, 427, 1472, 1467, 1464, 433, 1476, 1474, 368, 367, 2160, 365, 2159, 362, 2157, 2155,
17112      2152, 378, 377, 375, 2166, 372, 2165, 369, 2162, 383, 381, 379, 2168, 1419, 1418, 1416, 1414, 385, 1411, 384,
17113      1423, 1422, 1420, 1424, 2461, 802, 2441, 2439, 790, 786, 783, 794, 2409, 2406, 2403, 750, 742, 738, 2414, 756,
17114      753, 1720, 2367, 2365, 2362, 2359, 1663, 693, 691, 684, 2373, 680, 2370, 702, 699, 696, 704, 1690, 1687, 2337,
17115      2336, 2334, 2332, 1624, 2329, 1622, 640, 637, 2344, 634, 2342, 630, 2340, 650, 648, 645, 2346, 655, 653, 1653,
17116      1651, 1649, 1655, 2612, 2597, 2595, 2571, 2568, 2565, 2576, 2534, 2529, 2526, 1787, 2540, 2537, 907, 904, 900,
17117      910, 2503, 2502, 2500, 2498, 1768, 2495, 1767, 2510, 2508, 2506, 869, 866, 863, 2513, 876, 874, 1782, 2720, 2713,
17118      2711, 2697, 2694, 2691, 2702, 2672, 2670, 2664, 1828, 2678, 2675, 2647, 2646, 2644, 2642, 1823, 2639, 1822, 2654,
17119      2652, 2650, 2657, 2771, 1855, 2765, 2762, 1850, 1849, 2751, 2749, 2747, 2754, 353, 2148, 344, 342, 336, 2142,
17120      332, 2140, 345, 1375, 1373, 306, 2130, 299, 2128, 295, 2125, 319, 314, 311, 2132, 1354, 1352, 1349, 1356, 262,
17121      257, 2101, 253, 2096, 2093, 274, 273, 267, 2107, 263, 2104, 280, 278, 275, 1316, 1311, 1308, 1320, 1318, 2052,
17122      202, 2050, 2044, 2040, 219, 2063, 212, 2060, 208, 2055, 224, 221, 2066, 1260, 1258, 1252, 231, 1248, 229, 1266,
17123      1264, 1261, 1268, 155, 1998, 153, 1996, 1994, 1991, 1988, 165, 164, 2007, 162, 2006, 159, 2003, 2000, 172, 171,
17124      169, 2012, 166, 2010, 1186, 1184, 1182, 1179, 175, 1176, 173, 1192, 1191, 1189, 1187, 176, 1194, 1193, 2313,
17125      2307, 2305, 592, 589, 2294, 2292, 2289, 578, 572, 568, 2297, 580, 1591, 2272, 2267, 2264, 1547, 538, 536, 529,
17126      2278, 525, 2275, 547, 544, 541, 1574, 1571, 2237, 2235, 2229, 1493, 2225, 1489, 478, 2247, 470, 2244, 465, 2241,
17127      493, 488, 484, 2250, 498, 495, 1536, 1533, 1530, 1539, 2187, 2186, 2184, 2182, 1432, 2179, 1430, 2176, 1427, 414,
17128      412, 2197, 409, 2195, 405, 2193, 2190, 426, 424, 421, 2203, 418, 2201, 431, 429, 1473, 1471, 1469, 1466, 434,
17129      1477, 1475, 2478, 2472, 2470, 2459, 2457, 2454, 2462, 803, 2437, 2432, 2429, 1726, 2443, 2440, 792, 789, 785,
17130      2401, 2399, 2393, 1702, 2389, 1699, 2411, 2408, 2405, 745, 741, 2415, 758, 755, 1721, 2358, 2357, 2355, 2353,
17131      1661, 2350, 1660, 2347, 1657, 2368, 2366, 2364, 2361, 1666, 690, 687, 2374, 683, 2372, 701, 698, 705, 1691, 1689,
17132      2619, 2617, 2610, 2608, 2605, 2613, 2593, 2588, 2585, 1803, 2599, 2596, 2563, 2561, 2555, 1797, 2551, 1795, 2573,
17133      2570, 2567, 2577, 2525, 2524, 2522, 2520, 1786, 2517, 1785, 2514, 1783, 2535, 2533, 2531, 2528, 1788, 2541, 2539,
17134      906, 903, 911, 2721, 1844, 2715, 2712, 1838, 1836, 2699, 2696, 2693, 2703, 1827, 1826, 1824, 2673, 2671, 2669,
17135      2666, 1829, 2679, 2677, 1858, 1857, 2772, 1854, 1853, 1851, 1856, 2766, 2764, 143, 1987, 139, 1986, 135, 133,
17136      131, 1984, 128, 1983, 125, 1981, 138, 137, 136, 1985, 1133, 1132, 1130, 112, 110, 1974, 107, 1973, 104, 1971,
17137      1969, 122, 121, 119, 117, 1977, 114, 1976, 124, 1115, 1114, 1112, 1110, 1117, 1116, 84, 83, 1953, 81, 1952, 78,
17138      1950, 1948, 1945, 94, 93, 91, 1959, 88, 1958, 85, 1955, 99, 97, 95, 1961, 1086, 1085, 1083, 1081, 1078, 100,
17139      1090, 1089, 1087, 1091, 49, 47, 1917, 44, 1915, 1913, 1910, 1907, 59, 1926, 56, 1925, 53, 1922, 1919, 66, 64,
17140      1931, 61, 1929, 1042, 1040, 1038, 71, 1035, 70, 1032, 68, 1048, 1047, 1045, 1043, 1050, 1049, 12, 10, 1869, 1867,
17141      1864, 1861, 21, 1880, 19, 1877, 1874, 1871, 28, 1888, 25, 1886, 22, 1883, 982, 980, 977, 974, 32, 30, 991, 989,
17142      987, 984, 34, 995, 994, 992, 2151, 2150, 2147, 2146, 2144, 356, 355, 354, 2149, 2139, 2138, 2136, 2134, 1359,
17143      343, 341, 338, 2143, 335, 2141, 348, 347, 346, 1376, 1374, 2124, 2123, 2121, 2119, 1326, 2116, 1324, 310, 308,
17144      305, 2131, 302, 2129, 298, 2127, 320, 318, 316, 313, 2133, 322, 321, 1355, 1353, 1351, 1357, 2092, 2091, 2089,
17145      2087, 1276, 2084, 1274, 2081, 1271, 259, 2102, 256, 2100, 252, 2098, 2095, 272, 269, 2108, 266, 2106, 281, 279,
17146      277, 1317, 1315, 1313, 1310, 282, 1321, 1319, 2039, 2037, 2035, 2032, 1203, 2029, 1200, 1197, 207, 2053, 205,
17147      2051, 201, 2049, 2046, 2043, 220, 218, 2064, 215, 2062, 211, 2059, 228, 226, 223, 2069, 1259, 1257, 1254, 232,
17148      1251, 230, 1267, 1265, 1263, 2316, 2315, 2312, 2311, 2309, 2314, 2304, 2303, 2301, 2299, 1593, 2308, 2306, 590,
17149      2288, 2287, 2285, 2283, 1578, 2280, 1577, 2295, 2293, 2291, 579, 577, 574, 571, 2298, 582, 581, 1592, 2263, 2262,
17150      2260, 2258, 1545, 2255, 1544, 2252, 1541, 2273, 2271, 2269, 2266, 1550, 535, 532, 2279, 528, 2277, 546, 543, 549,
17151      1575, 1573, 2224, 2222, 2220, 1486, 2217, 1485, 2214, 1482, 1479, 2238, 2236, 2234, 2231, 1496, 2228, 1492, 480,
17152      477, 2248, 473, 2246, 469, 2243, 490, 487, 2251, 497, 1537, 1535, 1532, 2477, 2476, 2474, 2479, 2469, 2468, 2466,
17153      2464, 1730, 2473, 2471, 2453, 2452, 2450, 2448, 1729, 2445, 1728, 2460, 2458, 2456, 2463, 805, 804, 2428, 2427,
17154      2425, 2423, 1725, 2420, 1724, 2417, 1722, 2438, 2436, 2434, 2431, 1727, 2444, 2442, 793, 791, 788, 795, 2388,
17155      2386, 2384, 1697, 2381, 1696, 2378, 1694, 1692, 2402, 2400, 2398, 2395, 1703, 2392, 1701, 2412, 2410, 2407, 751,
17156      748, 744, 2416, 759, 757, 1807, 2620, 2618, 1806, 1805, 2611, 2609, 2607, 2614, 1802, 1801, 1799, 2594, 2592,
17157      2590, 2587, 1804, 2600, 2598, 1794, 1793, 1791, 1789, 2564, 2562, 2560, 2557, 1798, 2554, 1796, 2574, 2572, 2569,
17158      2578, 1847, 1846, 2722, 1843, 1842, 1840, 1845, 2716, 2714, 1835, 1834, 1832, 1830, 1839, 1837, 2700, 2698, 2695,
17159      2704, 1817, 1811, 1810, 897, 862, 1777, 829, 826, 838, 1760, 1758, 808, 2481, 1741, 1740, 1738, 1743, 2624, 1818,
17160      2726, 2776, 782, 740, 737, 1715, 686, 679, 695, 1682, 1680, 639, 628, 2339, 647, 644, 1645, 1643, 1640, 1648,
17161      602, 600, 597, 595, 2320, 593, 2318, 609, 607, 604, 1611, 1610, 1608, 1606, 613, 1615, 1613, 2328, 926, 924, 892,
17162      886, 899, 857, 850, 2505, 1778, 824, 823, 821, 819, 2488, 818, 2486, 833, 831, 828, 840, 1761, 1759, 2649, 2632,
17163      2630, 2746, 2734, 2732, 2782, 2781, 570, 567, 1587, 531, 527, 523, 540, 1566, 1564, 476, 467, 463, 2240, 486,
17164      483, 1524, 1521, 1518, 1529, 411, 403, 2192, 399, 2189, 423, 416, 1462, 1457, 1454, 428, 1468, 1465, 2210, 366,
17165      363, 2158, 360, 2156, 357, 2153, 376, 373, 370, 2163, 1410, 1409, 1407, 1405, 382, 1402, 380, 1417, 1415, 1412,
17166      1421, 2175, 2174, 777, 774, 771, 784, 732, 725, 722, 2404, 743, 1716, 676, 674, 668, 2363, 665, 2360, 685, 1684,
17167      1681, 626, 624, 622, 2335, 620, 2333, 617, 2330, 641, 635, 649, 1646, 1644, 1642, 2566, 928, 925, 2530, 2527,
17168      894, 891, 888, 2501, 2499, 2496, 858, 856, 854, 851, 1779, 2692, 2668, 2665, 2645, 2643, 2640, 2651, 2768, 2759,
17169      2757, 2744, 2743, 2741, 2748, 352, 1382, 340, 337, 333, 1371, 1369, 307, 300, 296, 2126, 315, 312, 1347, 1342,
17170      1350, 261, 258, 250, 2097, 246, 2094, 271, 268, 264, 1306, 1301, 1298, 276, 1312, 1309, 2115, 203, 2048, 195,
17171      2045, 191, 2041, 213, 209, 2056, 1246, 1244, 1238, 225, 1234, 222, 1256, 1253, 1249, 1262, 2080, 2079, 154, 1997,
17172      150, 1995, 147, 1992, 1989, 163, 160, 2004, 156, 2001, 1175, 1174, 1172, 1170, 1167, 170, 1164, 167, 1185, 1183,
17173      1180, 1177, 174, 1190, 1188, 2025, 2024, 2022, 587, 586, 564, 559, 556, 2290, 573, 1588, 520, 518, 512, 2268,
17174      508, 2265, 530, 1568, 1565, 461, 457, 2233, 450, 2230, 446, 2226, 479, 471, 489, 1526, 1523, 1520, 397, 395,
17175      2185, 392, 2183, 389, 2180, 2177, 410, 2194, 402, 422, 1463, 1461, 1459, 1456, 1470, 2455, 799, 2433, 2430, 779,
17176      776, 773, 2397, 2394, 2390, 734, 728, 724, 746, 1717, 2356, 2354, 2351, 2348, 1658, 677, 675, 673, 670, 667, 688,
17177      1685, 1683, 2606, 2589, 2586, 2559, 2556, 2552, 927, 2523, 2521, 2518, 2515, 1784, 2532, 895, 893, 890, 2718,
17178      2709, 2707, 2689, 2687, 2684, 2663, 2662, 2660, 2658, 1825, 2667, 2769, 1852, 2760, 2758, 142, 141, 1139, 1138,
17179      134, 132, 129, 126, 1982, 1129, 1128, 1126, 1131, 113, 111, 108, 105, 1972, 101, 1970, 120, 118, 115, 1109, 1108,
17180      1106, 1104, 123, 1113, 1111, 82, 79, 1951, 75, 1949, 72, 1946, 92, 89, 86, 1956, 1077, 1076, 1074, 1072, 98,
17181      1069, 96, 1084, 1082, 1079, 1088, 1968, 1967, 48, 45, 1916, 42, 1914, 39, 1911, 1908, 60, 57, 54, 1923, 50, 1920,
17182      1031, 1030, 1028, 1026, 67, 1023, 65, 1020, 62, 1041, 1039, 1036, 1033, 69, 1046, 1044, 1944, 1943, 1941, 11, 9,
17183      1868, 7, 1865, 1862, 1859, 20, 1878, 16, 1875, 13, 1872, 970, 968, 966, 963, 29, 960, 26, 23, 983, 981, 978, 975,
17184      33, 971, 31, 990, 988, 985, 1906, 1904, 1902, 993, 351, 2145, 1383, 331, 330, 328, 326, 2137, 323, 2135, 339,
17185      1372, 1370, 294, 293, 291, 289, 2122, 286, 2120, 283, 2117, 309, 303, 317, 1348, 1346, 1344, 245, 244, 242, 2090,
17186      239, 2088, 236, 2085, 2082, 260, 2099, 249, 270, 1307, 1305, 1303, 1300, 1314, 189, 2038, 186, 2036, 183, 2033,
17187      2030, 2026, 206, 198, 2047, 194, 216, 1247, 1245, 1243, 1240, 227, 1237, 1255, 2310, 2302, 2300, 2286, 2284,
17188      2281, 565, 563, 561, 558, 575, 1589, 2261, 2259, 2256, 2253, 1542, 521, 519, 517, 514, 2270, 511, 533, 1569,
17189      1567, 2223, 2221, 2218, 2215, 1483, 2211, 1480, 459, 456, 453, 2232, 449, 474, 491, 1527, 1525, 1522, 2475, 2467,
17190      2465, 2451, 2449, 2446, 801, 800, 2426, 2424, 2421, 2418, 1723, 2435, 780, 778, 775, 2387, 2385, 2382, 2379,
17191      1695, 2375, 1693, 2396, 735, 733, 730, 727, 749, 1718, 2616, 2615, 2604, 2603, 2601, 2584, 2583, 2581, 2579,
17192      1800, 2591, 2550, 2549, 2547, 2545, 1792, 2542, 1790, 2558, 929, 2719, 1841, 2710, 2708, 1833, 1831, 2690, 2688,
17193      2686, 1815, 1809, 1808, 1774, 1756, 1754, 1737, 1736, 1734, 1739, 1816, 1711, 1676, 1674, 633, 629, 1638, 1636,
17194      1633, 1641, 598, 1605, 1604, 1602, 1600, 605, 1609, 1607, 2327, 887, 853, 1775, 822, 820, 1757, 1755, 1584, 524,
17195      1560, 1558, 468, 464, 1514, 1511, 1508, 1519, 408, 404, 400, 1452, 1447, 1444, 417, 1458, 1455, 2208, 364, 361,
17196      358, 2154, 1401, 1400, 1398, 1396, 374, 1393, 371, 1408, 1406, 1403, 1413, 2173, 2172, 772, 726, 723, 1712, 672,
17197      669, 666, 682, 1678, 1675, 625, 623, 621, 618, 2331, 636, 632, 1639, 1637, 1635, 920, 918, 884, 880, 889, 849,
17198      848, 847, 846, 2497, 855, 852, 1776, 2641, 2742, 2787, 1380, 334, 1367, 1365, 301, 297, 1340, 1338, 1335, 1343,
17199      255, 251, 247, 1296, 1291, 1288, 265, 1302, 1299, 2113, 204, 196, 192, 2042, 1232, 1230, 1224, 214, 1220, 210,
17200      1242, 1239, 1235, 1250, 2077, 2075, 151, 148, 1993, 144, 1990, 1163, 1162, 1160, 1158, 1155, 161, 1152, 157,
17201      1173, 1171, 1168, 1165, 168, 1181, 1178, 2021, 2020, 2018, 2023, 585, 560, 557, 1585, 516, 509, 1562, 1559, 458,
17202      447, 2227, 472, 1516, 1513, 1510, 398, 396, 393, 390, 2181, 386, 2178, 407, 1453, 1451, 1449, 1446, 420, 1460,
17203      2209, 769, 764, 720, 712, 2391, 729, 1713, 664, 663, 661, 659, 2352, 656, 2349, 671, 1679, 1677, 2553, 922, 919,
17204      2519, 2516, 885, 883, 881, 2685, 2661, 2659, 2767, 2756, 2755, 140, 1137, 1136, 130, 127, 1125, 1124, 1122, 1127,
17205      109, 106, 102, 1103, 1102, 1100, 1098, 116, 1107, 1105, 1980, 80, 76, 73, 1947, 1068, 1067, 1065, 1063, 90, 1060,
17206      87, 1075, 1073, 1070, 1080, 1966, 1965, 46, 43, 40, 1912, 36, 1909, 1019, 1018, 1016, 1014, 58, 1011, 55, 1008,
17207      51, 1029, 1027, 1024, 1021, 63, 1037, 1034, 1940, 1939, 1937, 1942, 8, 1866, 4, 1863, 1, 1860, 956, 954, 952,
17208      949, 946, 17, 14, 969, 967, 964, 961, 27, 957, 24, 979, 976, 972, 1901, 1900, 1898, 1896, 986, 1905, 1903, 350,
17209      349, 1381, 329, 327, 324, 1368, 1366, 292, 290, 287, 284, 2118, 304, 1341, 1339, 1337, 1345, 243, 240, 237, 2086,
17210      233, 2083, 254, 1297, 1295, 1293, 1290, 1304, 2114, 190, 187, 184, 2034, 180, 2031, 177, 2027, 199, 1233, 1231,
17211      1229, 1226, 217, 1223, 1241, 2078, 2076, 584, 555, 554, 552, 550, 2282, 562, 1586, 507, 506, 504, 502, 2257, 499,
17212      2254, 515, 1563, 1561, 445, 443, 441, 2219, 438, 2216, 435, 2212, 460, 454, 475, 1517, 1515, 1512, 2447, 798,
17213      797, 2422, 2419, 770, 768, 766, 2383, 2380, 2376, 721, 719, 717, 714, 731, 1714, 2602, 2582, 2580, 2548, 2546,
17214      2543, 923, 921, 2717, 2706, 2705, 2683, 2682, 2680, 1771, 1752, 1750, 1733, 1732, 1731, 1735, 1814, 1707, 1670,
17215      1668, 1631, 1629, 1626, 1634, 1599, 1598, 1596, 1594, 1603, 1601, 2326, 1772, 1753, 1751, 1581, 1554, 1552, 1504,
17216      1501, 1498, 1509, 1442, 1437, 1434, 401, 1448, 1445, 2206, 1392, 1391, 1389, 1387, 1384, 359, 1399, 1397, 1394,
17217      1404, 2171, 2170, 1708, 1672, 1669, 619, 1632, 1630, 1628, 1773, 1378, 1363, 1361, 1333, 1328, 1336, 1286, 1281,
17218      1278, 248, 1292, 1289, 2111, 1218, 1216, 1210, 197, 1206, 193, 1228, 1225, 1221, 1236, 2073, 2071, 1151, 1150,
17219      1148, 1146, 152, 1143, 149, 1140, 145, 1161, 1159, 1156, 1153, 158, 1169, 1166, 2017, 2016, 2014, 2019, 1582,
17220      510, 1556, 1553, 452, 448, 1506, 1500, 394, 391, 387, 1443, 1441, 1439, 1436, 1450, 2207, 765, 716, 713, 1709,
17221      662, 660, 657, 1673, 1671, 916, 914, 879, 878, 877, 882, 1135, 1134, 1121, 1120, 1118, 1123, 1097, 1096, 1094,
17222      1092, 103, 1101, 1099, 1979, 1059, 1058, 1056, 1054, 77, 1051, 74, 1066, 1064, 1061, 1071, 1964, 1963, 1007,
17223      1006, 1004, 1002, 999, 41, 996, 37, 1017, 1015, 1012, 1009, 52, 1025, 1022, 1936, 1935, 1933, 1938, 942, 940,
17224      938, 935, 932, 5, 2, 955, 953, 950, 947, 18, 943, 15, 965, 962, 958, 1895, 1894, 1892, 1890, 973, 1899, 1897,
17225      1379, 325, 1364, 1362, 288, 285, 1334, 1332, 1330, 241, 238, 234, 1287, 1285, 1283, 1280, 1294, 2112, 188, 185,
17226      181, 178, 2028, 1219, 1217, 1215, 1212, 200, 1209, 1227, 2074, 2072, 583, 553, 551, 1583, 505, 503, 500, 513,
17227      1557, 1555, 444, 442, 439, 436, 2213, 455, 451, 1507, 1505, 1502, 796, 763, 762, 760, 767, 711, 710, 708, 706,
17228      2377, 718, 715, 1710, 2544, 917, 915, 2681, 1627, 1597, 1595, 2325, 1769, 1749, 1747, 1499, 1438, 1435, 2204,
17229      1390, 1388, 1385, 1395, 2169, 2167, 1704, 1665, 1662, 1625, 1623, 1620, 1770, 1329, 1282, 1279, 2109, 1214, 1207,
17230      1222, 2068, 2065, 1149, 1147, 1144, 1141, 146, 1157, 1154, 2013, 2011, 2008, 2015, 1579, 1549, 1546, 1495, 1487,
17231      1433, 1431, 1428, 1425, 388, 1440, 2205, 1705, 658, 1667, 1664, 1119, 1095, 1093, 1978, 1057, 1055, 1052, 1062,
17232      1962, 1960, 1005, 1003, 1000, 997, 38, 1013, 1010, 1932, 1930, 1927, 1934, 941, 939, 936, 933, 6, 930, 3, 951,
17233      948, 944, 1889, 1887, 1884, 1881, 959, 1893, 1891, 35, 1377, 1360, 1358, 1327, 1325, 1322, 1331, 1277, 1275,
17234      1272, 1269, 235, 1284, 2110, 1205, 1204, 1201, 1198, 182, 1195, 179, 1213, 2070, 2067, 1580, 501, 1551, 1548,
17235      440, 437, 1497, 1494, 1490, 1503, 761, 709, 707, 1706, 913, 912, 2198, 1386, 2164, 2161, 1621, 1766, 2103, 1208,
17236      2058, 2054, 1145, 1142, 2005, 2002, 1999, 2009, 1488, 1429, 1426, 2200, 1698, 1659, 1656, 1975, 1053, 1957, 1954,
17237      1001, 998, 1924, 1921, 1918, 1928, 937, 934, 931, 1879, 1876, 1873, 1870, 945, 1885, 1882, 1323, 1273, 1270,
17238      2105, 1202, 1199, 1196, 1211, 2061, 2057, 1576, 1543, 1540, 1484, 1481, 1478, 1491, 1700
17239  ]);
17240
17241  /*
17242  * Copyright 2007 ZXing authors
17243  *
17244  * Licensed under the Apache License, Version 2.0 (the "License");
17245  * you may not use this file except in compliance with the License.
17246  * You may obtain a copy of the License at
17247  *
17248  *      http://www.apache.org/licenses/LICENSE-2.0
17249  *
17250  * Unless required by applicable law or agreed to in writing, software
17251  * distributed under the License is distributed on an "AS IS" BASIS,
17252  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17253  * See the License for the specific language governing permissions and
17254  * limitations under the License.
17255  */
17256  // import java.util.List;
17257  /**
17258   * @author Guenther Grau
17259   */
17260  /*public final*/ class PDF417DetectorResult {
17261      constructor(bits, points) {
17262          this.bits = bits;
17263          this.points = points;
17264      }
17265      getBits() {
17266          return this.bits;
17267      }
17268      getPoints() {
17269          return this.points;
17270      }
17271  }
17272
17273  /*
17274  * Copyright 2009 ZXing authors
17275  *
17276  * Licensed under the Apache License, Version 2.0 (the "License");
17277  * you may not use this file except in compliance with the License.
17278  * You may obtain a copy of the License at
17279  *
17280  *      http://www.apache.org/licenses/LICENSE-2.0
17281  *
17282  * Unless required by applicable law or agreed to in writing, software
17283  * distributed under the License is distributed on an "AS IS" BASIS,
17284  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17285  * See the License for the specific language governing permissions and
17286  * limitations under the License.
17287  */
17288  // import 
17288java.util.ArrayList;
17289  // import java.util.Arrays;
17290  // import java.util.List;
17291  // import java.util.Map;
17292  /**
17293   * <p>Encapsulates logic that can detect a PDF417 Code in an image, even if the
17294   * PDF417 Code is rotated or skewed, or partially obscured.</p>
17295   *
17296   * @author SITA Lab ([email protected])
17297   * @author [email protected] (Daniel Switkin)
17298   * @author Guenther Grau
17299   */
17300  /*public*/ /*final*/
vendor: 14,616 bytes, lines 17300-17594
17300 class Detector {
17301      /**
17302       * <p>Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.</p>
17303       *
17304       * @param image barcode image to decode
17305       * @param hints optional hints to detector
17306       * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will
17307       * be found and returned
17308       * @return {@link PDF417DetectorResult} encapsulating results of detecting a PDF417 code
17309       * @throws NotFoundException if no PDF417 Code can be found
17310       */
17311      static detectMultiple(image, hints, multiple) {
17312          // TODO detection improvement, tryHarder could try several different luminance thresholds/blackpoints or even
17313          // different binarizers
17314          // boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
17315          let bitMatrix = image.getBlackMatrix();
17316          let barcodeCoordinates = Detector.detect(multiple, bitMatrix);
17317          if (!barcodeCoordinates.length) {
17318              bitMatrix = bitMatrix.clone();
17319              bitMatrix.rotate180();
17320              barcodeCoordinates = Detector.detect(multiple, bitMatrix);
17321          }
17322          return new PDF417DetectorResult(bitMatrix, barcodeCoordinates);
17323      }
17324      /**
17325       * Detects PDF417 codes in an image. Only checks 0 degree rotation
17326       * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will
17327       * be found and returned
17328       * @param bitMatrix bit matrix to detect barcodes in
17329       * @return List of ResultPoint arrays containing the coordinates of found barcodes
17330       */
17331      static detect(multiple, bitMatrix) {
17332          const barcodeCoordinates = new Array();
17333          let row = 0;
17334          let column = 0;
17335          let foundBarcodeInRow = false;
17336          while (row < bitMatrix.getHeight()) {
17337              const vertices = Detector.findVertices(bitMatrix, row, column);
17338              if (vertices[0] == null && vertices[3] == null) {
17339                  if (!foundBarcodeInRow) {
17340                      // we didn't find any barcode so that's the end of searching
17341                      break;
17342                  }
17343                  // we didn't find a barcode starting at the given column and row. Try again from the first column and slightly
17344                  // below the lowest barcode we found so far.
17345                  foundBarcodeInRow = false;
17346                  column = 0;
17347                  for (const barcodeCoordinate of barcodeCoordinates) {
17348                      if (barcodeCoordinate[1] != null) {
17349                          row = Math.trunc(Math.max(row, barcodeCoordinate[1].getY()));
17350                      }
17351                      if (barcodeCoordinate[3] != null) {
17352                          row = Math.max(row, Math.trunc(barcodeCoordinate[3].getY()));
17353                      }
17354                  }
17355                  row += Detector.ROW_STEP;
17356                  continue;
17357              }
17358              foundBarcodeInRow = true;
17359              barcodeCoordinates.push(vertices);
17360              if (!multiple) {
17361                  break;
17362              }
17363              // if we didn't find a right row indicator column, then continue the search for the next barcode after the
17364              // start pattern of the barcode just found.
17365              if (vertices[2] != null) {
17366                  column = Math.trunc(vertices[2].getX());
17367                  row = Math.trunc(vertices[2].getY());
17368              }
17369              else {
17370                  column = Math.trunc(vertices[4].getX());
17371                  row = Math.trunc(vertices[4].getY());
17372              }
17373          }
17374          return barcodeCoordinates;
17375      }
17376      /**
17377       * Locate the vertices and the codewords area of a black blob using the Start
17378       * and Stop patterns as locators.
17379       *
17380       * @param matrix the scanned barcode image.
17381       * @return an array containing the vertices:
17382       *           vertices[0] x, y top left barcode
17383       *           vertices[1] x, y bottom left barcode
17384       *           vertices[2] x, y top right barcode
17385       *           vertices[3] x, y bottom right barcode
17386       *           vertices[4] x, y top left codeword area
17387       *           vertices[5] x, y bottom left codeword area
17388       *           vertices[6] x, y top right codeword area
17389       *           vertices[7] x, y bottom right codeword area
17390       */
17391      static findVertices(matrix, startRow, startColumn) {
17392          const height = matrix.getHeight();
17393          const width = matrix.getWidth();
17394          // const result = new ResultPoint[8];
17395          const result = new Array(8);
17396          Detector.copyToResult(result, Detector.findRowsWithPattern(matrix, height, width, startRow, startColumn, Detector.START_PATTERN), Detector.INDEXES_START_PATTERN);
17397          if (result[4] != null) {
17398              startColumn = Math.trunc(result[4].getX());
17399              startRow = Math.trunc(result[4].getY());
17400          }
17401          Detector.copyToResult(result, Detector.findRowsWithPattern(matrix, height, width, startRow, startColumn, Detector.STOP_PATTERN), Detector.INDEXES_STOP_PATTERN);
17402          return result;
17403      }
17404      static copyToResult(result, tmpResult, destinationIndexes) {
17405          for (let i = 0; i < destinationIndexes.length; i++) {
17406              result[destinationIndexes[i]] = tmpResult[i];
17407          }
17408      }
17409      static findRowsWithPattern(matrix, height, width, startRow, startColumn, pattern) {
17410          // const result = new ResultPoint[4];
17411          const result = new Array(4);
17412          let found = false;
17413          const counters = new Int32Array(pattern.length);
17414          for (; startRow < height; startRow += Detector.ROW_STEP) {
17415              let loc = Detector.findGuardPattern(matrix, startColumn, startRow, width, false, pattern, counters);
17416              if (loc != null) {
17417                  while (startRow > 0) {
17418                      const previousRowLoc = Detector.findGuardPattern(matrix, startColumn, --startRow, width, false, pattern, counters);
17419                      if (previousRowLoc != null) {
17420                          loc = previousRowLoc;
17421                      }
17422                      else {
17423                          startRow++;
17424                          break;
17425                      }
17426                  }
17427                  result[0] = new ResultPoint(loc[0], startRow);
17428                  result[1] = new ResultPoint(loc[1], startRow);
17429                  found = true;
17430                  break;
17431              }
17432          }
17433          let stopRow = startRow + 1;
17434          // Last row of the current symbol that contains pattern
17435          if (found) {
17436              let skippedRowCount = 0;
17437              let previousRowLoc = Int32Array.from([Math.trunc(result[0].getX()), Math.trunc(result[1].getX())]);
17438              for (; stopRow < height; stopRow++) {
17439                  const loc = Detector.findGuardPattern(matrix, previousRowLoc[0], stopRow, width, false, pattern, counters);
17440                  // a found pattern is only considered to belong to the same barcode if the start and end positions
17441                  // don't differ too much. Pattern drift should be not bigger than two for consecutive rows. With
17442                  // a higher number of skipped rows drift could be larger. To keep it simple for now, we allow a slightly
17443                  // larger drift and don't check for skipped rows.
17444                  if (loc != null &&
17445                      Math.abs(previousRowLoc[0] - loc[0]) < Detector.MAX_PATTERN_DRIFT &&
17446                      Math.abs(previousRowLoc[1] - loc[1]) < Detector.MAX_PATTERN_DRIFT) {
17447                      previousRowLoc = loc;
17448                      skippedRowCount = 0;
17449                  }
17450                  else {
17451                      if (skippedRowCount > Detector.SKIPPED_ROW_COUNT_MAX) {
17452                          break;
17453                      }
17454                      else {
17455                          skippedRowCount++;
17456                      }
17457                  }
17458              }
17459              stopRow -= skippedRowCount + 1;
17460              result[2] = new ResultPoint(previousRowLoc[0], stopRow);
17461              result[3] = new ResultPoint(previousRowLoc[1], stopRow);
17462          }
17463          if (stopRow - startRow < Detector.BARCODE_MIN_HEIGHT) {
17464              Arrays.fill(result, null);
17465          }
17466          return result;
17467      }
17468      /**
17469       * @param matrix row of black/white values to search
17470       * @param column x position to start search
17471       * @param row y position to start search
17472       * @param width the number of pixels to search on this row
17473       * @param pattern pattern of counts of number of black and white pixels that are
17474       *                 being searched for as a pattern
17475       * @param counters array of counters, as long as pattern, to re-use
17476       * @return start/end horizontal offset of guard pattern, as an array of two ints.
17477       */
17478      static findGuardPattern(matrix, column, row, width, whiteFirst, pattern, counters) {
17479          Arrays.fillWithin(counters, 0, counters.length, 0);
17480          let patternStart = column;
17481          let pixelDrift = 0;
17482          // if there are black pixels left of the current pixel shift to the left, but only for MAX_PIXEL_DRIFT pixels
17483          while (matrix.get(patternStart, row) && patternStart > 0 && pixelDrift++ < Detector.MAX_PIXEL_DRIFT) {
17484              patternStart--;
17485          }
17486          let x = patternStart;
17487          let counterPosition = 0;
17488          let patternLength = pattern.length;
17489          for (let isWhite = whiteFirst; x < width; x++) {
17490              let pixel = matrix.get(x, row);
17491              if (pixel !== isWhite) {
17492                  counters[counterPosition]++;
17493              }
17494              else {
17495                  if (counterPosition === patternLength - 1) {
17496                      if (Detector.patternMatchVariance(counters, pattern, Detector.MAX_INDIVIDUAL_VARIANCE) < Detector.MAX_AVG_VARIANCE) {
17497                          return new Int32Array([patternStart, x]);
17498                      }
17499                      patternStart += counters[0] + counters[1];
17500                      System.arraycopy(counters, 2, counters, 0, counterPosition - 1);
17501                      counters[counterPosition - 1] = 0;
17502                      counters[counterPosition] = 0;
17503                      counterPosition--;
17504                  }
17505                  else {
17506                      counterPosition++;
17507                  }
17508                  counters[counterPosition] = 1;
17509                  isWhite = !isWhite;
17510              }
17511          }
17512          if (counterPosition === patternLength - 1 &&
17513              Detector.patternMatchVariance(counters, pattern, Detector.MAX_INDIVIDUAL_VARIANCE) < Detector.MAX_AVG_VARIANCE) {
17514              return new Int32Array([patternStart, x - 1]);
17515          }
17516          return null;
17517      }
17518      /**
17519       * Determines how closely a set of observed counts of runs of black/white
17520       * values matches a given target pattern. This is reported as the ratio of
17521       * the total variance from the expected pattern proportions across all
17522       * pattern elements, to the length of the pattern.
17523       *
17524       * @param counters observed counters
17525       * @param pattern expected pattern
17526       * @param maxIndividualVariance The most any counter can differ before we give up
17527       * @return ratio of total variance between counters and pattern compared to total pattern size
17528       */
17529      static patternMatchVariance(counters, pattern, maxIndividualVariance) {
17530          let numCounters = counters.length;
17531          let total = 0;
17532          let patternLength = 0;
17533          for (let i = 0; i < numCounters; i++) {
17534              total += counters[i];
17535              patternLength += pattern[i];
17536          }
17537          if (total < patternLength) {
17538              // If we don't even have one pixel per unit of bar width, assume this
17539              // is too small to reliably match, so fail:
17540              return /*Float.POSITIVE_INFINITY*/ Infinity;
17541          }
17542          // We're going to fake floating-point math in integers. We just need to use more bits.
17543          // Scale up patternLength so that intermediate values below like scaledCounter will have
17544          // more "significant digits".
17545          let unitBarWidth = total / patternLength;
17546          maxIndividualVariance *= unitBarWidth;
17547          let totalVariance = 0.0;
17548          for (let x = 0; x < numCounters; x++) {
17549              let counter = counters[x];
17550              let scaledPattern = pattern[x] * unitBarWidth;
17551              let variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
17552              if (variance > maxIndividualVariance) {
17553                  return /*Float.POSITIVE_INFINITY*/ Infinity;
17554              }
17555              totalVariance += variance;
17556          }
17557          return totalVariance / total;
17558      }
17559  }
17560  Detector.INDEXES_START_PATTERN = Int32Array.from([0, 4, 1, 5]);
17561  Detector.INDEXES_STOP_PATTERN = Int32Array.from([6, 2, 7, 3]);
17562  Detector.MAX_AVG_VARIANCE = 0.42;
17563  Detector.MAX_INDIVIDUAL_VARIANCE = 0.8;
17564  // B S B S B S B S Bar/Space pattern
17565  // 11111111 0 1 0 1 0 1 000
17566  Detector.START_PATTERN = Int32Array.from([8, 1, 1, 1, 1, 1, 1, 3]);
17567  // 1111111 0 1 000 1 0 1 00 1
17568  Detector.STOP_PATTERN = Int32Array.from([7, 1, 1, 3, 1, 1, 1, 2, 1]);
17569  Detector.MAX_PIXEL_DRIFT = 3;
17570  Detector.MAX_PATTERN_DRIFT = 5;
17571  // if we set the value too low, then we don't detect the correct height of the bar if the start patterns are damaged.
17572  // if we set the value too high, then we might detect the start pattern from a neighbor barcode.
17573  Detector.SKIPPED_ROW_COUNT_MAX = 25;
17574  // A PDF471 barcode should have at least 3 rows, with each row being >= 3 times the module width. Therefore it should be at least
17575  // 9 pixels tall. To be conservative, we use about half the size to ensure we don't miss it.
17576  Detector.ROW_STEP = 5;
17577  Detector.BARCODE_MIN_HEIGHT = 10;
17578
17579  /*
17580  * Copyright 2012 ZXing authors
17581  *
17582  * Licensed under the Apache License, Version 2.0 (the "License");
17583  * you may not use this file except in compliance with the License.
17584  * You may obtain a copy of the License at
17585  *
17586  *      http://www.apache.org/licenses/LICENSE-2.0
17587  *
17588  * Unless required by applicable law or agreed to in writing, software
17589  * distributed under the License is distributed on an "AS IS" BASIS,
17590  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17591  * See the License for the specific language governing permissions and
17592  * limitations under the License.
17593  */
17594  /
vendor: 20,053 bytes, lines 17594-18105
17594**
17595   * @author Sean Owen
17596   * @see com.google.zxing.common.reedsolomon.GenericGFPoly
17597   */
17598  /*final*/ class ModulusPoly {
17599      constructor(field, coefficients) {
17600          if (coefficients.length === 0) {
17601              throw new IllegalArgumentException();
17602          }
17603          this.field = field;
17604          let coefficientsLength = /*int*/ coefficients.length;
17605          if (coefficientsLength > 1 && coefficients[0] === 0) {
17606              // Leading term must be non-zero for anything except the constant polynomial "0"
17607              let firstNonZero = /*int*/ 1;
17608              while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) {
17609                  firstNonZero++;
17610              }
17611              if (firstNonZero === coefficientsLength) {
17612                  this.coefficients = new Int32Array([0]);
17613              }
17614              else {
17615                  this.coefficients = new Int32Array(coefficientsLength - firstNonZero);
17616                  System.arraycopy(coefficients, firstNonZero, this.coefficients, 0, this.coefficients.length);
17617              }
17618          }
17619          else {
17620              this.coefficients = coefficients;
17621          }
17622      }
17623      getCoefficients() {
17624          return this.coefficients;
17625      }
17626      /**
17627       * @return degree of this polynomial
17628       */
17629      getDegree() {
17630          return this.coefficients.length - 1;
17631      }
17632      /**
17633       * @return true iff this polynomial is the monomial "0"
17634       */
17635      isZero() {
17636          return this.coefficients[0] === 0;
17637      }
17638      /**
17639       * @return coefficient of x^degree term in this polynomial
17640       */
17641      getCoefficient(degree) {
17642          return this.coefficients[this.coefficients.length - 1 - degree];
17643      }
17644      /**
17645       * @return evaluation of this polynomial at a given point
17646       */
17647      evaluateAt(a) {
17648          if (a === 0) {
17649              // Just return the x^0 coefficient
17650              return this.getCoefficient(0);
17651          }
17652          if (a === 1) {
17653              // Just the sum of the coefficients
17654              let sum = /*int*/ 0;
17655              for (let coefficient /*int*/ of this.coefficients) {
17656                  sum = this.field.add(sum, coefficient);
17657              }
17658              return sum;
17659          }
17660          let result = /*int*/ this.coefficients[0];
17661          let size = /*int*/ this.coefficients.length;
17662          for (let i /*int*/ = 1; i < size; i++) {
17663              result = this.field.add(this.field.multiply(a, result), this.coefficients[i]);
17664          }
17665          return result;
17666      }
17667      add(other) {
17668          if (!this.field.equals(other.field)) {
17669              throw new IllegalArgumentException('ModulusPolys do not have same ModulusGF field');
17670          }
17671          if (this.isZero()) {
17672              return other;
17673          }
17674          if (other.isZero()) {
17675              return this;
17676          }
17677          let smallerCoefficients = this.coefficients;
17678          let largerCoefficients = other.coefficients;
17679          if (smallerCoefficients.length > largerCoefficients.length) {
17680              let temp = smallerCoefficients;
17681              smallerCoefficients = largerCoefficients;
17682              largerCoefficients = temp;
17683          }
17684          let sumDiff = new Int32Array(largerCoefficients.length);
17685          let lengthDiff = /*int*/ largerCoefficients.length - smallerCoefficients.length;
17686          // Copy high-order terms only found in higher-degree polynomial's coefficients
17687          System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
17688          for (let i /*int*/ = lengthDiff; i < largerCoefficients.length; i++) {
17689              sumDiff[i] = this.field.add(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
17690          }
17691          return new ModulusPoly(this.field, sumDiff);
17692      }
17693      subtract(other) {
17694          if (!this.field.equals(other.field)) {
17695              throw new IllegalArgumentException('ModulusPolys do not have same ModulusGF field');
17696          }
17697          if (other.isZero()) {
17698              return this;
17699          }
17700          return this.add(other.negative());
17701      }
17702      multiply(other) {
17703          if (other instanceof ModulusPoly) {
17704              return this.multiplyOther(other);
17705          }
17706          return this.multiplyScalar(other);
17707      }
17708      multiplyOther(other) {
17709          if (!this.field.equals(other.field)) {
17710              throw new IllegalArgumentException('ModulusPolys do not have same ModulusGF field');
17711          }
17712          if (this.isZero() || other.isZero()) {
17713              // return this.field.getZero();
17714              return new ModulusPoly(this.field, new Int32Array([0]));
17715          }
17716          let aCoefficients = this.coefficients;
17717          let aLength = /*int*/ aCoefficients.length;
17718          let bCoefficients = other.coefficients;
17719          let bLength = /*int*/ bCoefficients.length;
17720          let product = new Int32Array(aLength + bLength - 1);
17721          for (let i /*int*/ = 0; i < aLength; i++) {
17722              let aCoeff = /*int*/ aCoefficients[i];
17723              for (let j /*int*/ = 0; j < bLength; j++) {
17724                  product[i + j] = this.field.add(product[i + j], this.field.multiply(aCoeff, bCoefficients[j]));
17725              }
17726          }
17727          return new ModulusPoly(this.field, product);
17728      }
17729      negative() {
17730          let size = /*int*/ this.coefficients.length;
17731          let negativeCoefficients = new Int32Array(size);
17732          for (let i /*int*/ = 0; i < size; i++) {
17733              negativeCoefficients[i] = this.field.subtract(0, this.coefficients[i]);
17734          }
17735          return new ModulusPoly(this.field, negativeCoefficients);
17736      }
17737      multiplyScalar(scalar) {
17738          if (scalar === 0) {
17739              return new ModulusPoly(this.field, new Int32Array([0]));
17740          }
17741          if (scalar === 1) {
17742              return this;
17743          }
17744          let size = /*int*/ this.coefficients.length;
17745          let product = new Int32Array(size);
17746          for (let i /*int*/ = 0; i < size; i++) {
17747              product[i] = this.field.multiply(this.coefficients[i], scalar);
17748          }
17749          return new ModulusPoly(this.field, product);
17750      }
17751      multiplyByMonomial(degree, coefficient) {
17752          if (degree < 0) {
17753              throw new IllegalArgumentException();
17754          }
17755          if (coefficient === 0) {
17756              return new ModulusPoly(this.field, new Int32Array([0]));
17757          }
17758          let size = /*int*/ this.coefficients.length;
17759          let product = new Int32Array(size + degree);
17760          for (let i /*int*/ = 0; i < size; i++) {
17761              product[i] = this.field.multiply(this.coefficients[i], coefficient);
17762          }
17763          return new ModulusPoly(this.field, product);
17764      }
17765      /*
17766      ModulusPoly[] divide(other: ModulusPoly) {
17767        if (!field.equals(other.field)) {
17768          throw new IllegalArgumentException("ModulusPolys do not have same ModulusGF field");
17769        }
17770        if (other.isZero()) {
17771          throw new IllegalArgumentException("Divide by 0");
17772        }
17773    
17774        let quotient: ModulusPoly = field.getZero();
17775        let remainder: ModulusPoly = this;
17776    
17777        let denominatorLeadingTerm: /*int/ number = other.getCoefficient(other.getDegree());
17778        let inverseDenominatorLeadingTerm: /*int/ number = field.inverse(denominatorLeadingTerm);
17779    
17780        while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
17781          let degreeDifference: /*int/ number = remainder.getDegree() - other.getDegree();
17782          let scale: /*int/ number = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);
17783          let term: ModulusPoly = other.multiplyByMonomial(degreeDifference, scale);
17784          let iterationQuotient: ModulusPoly = field.buildMonomial(degreeDifference, scale);
17785          quotient = quotient.add(iterationQuotient);
17786          remainder = remainder.subtract(term);
17787        }
17788    
17789        return new ModulusPoly[] { quotient, remainder };
17790      }
17791      */
17792      // @Override
17793      toString() {
17794          let result = new StringBuilder( /*8 * this.getDegree()*/); // dynamic string size in JS
17795          for (let degree /*int*/ = this.getDegree(); degree >= 0; degree--) {
17796              let coefficient = /*int*/ this.getCoefficient(degree);
17797              if (coefficient !== 0) {
17798                  if (coefficient < 0) {
17799                      result.append(' - ');
17800                      coefficient = -coefficient;
17801                  }
17802                  else {
17803                      if (result.length() > 0) {
17804                          result.append(' + ');
17805                      }
17806                  }
17807                  if (degree === 0 || coefficient !== 1) {
17808                      result.append(coefficient);
17809                  }
17810                  if (degree !== 0) {
17811                      if (degree === 1) {
17812                          result.append('x');
17813                      }
17814                      else {
17815                          result.append('x^');
17816                          result.append(degree);
17817                      }
17818                  }
17819              }
17820          }
17821          return result.toString();
17822      }
17823  }
17824
17825  class ModulusBase {
17826      add(a, b) {
17827          return (a + b) % this.modulus;
17828      }
17829      subtract(a, b) {
17830          return (this.modulus + a - b) % this.modulus;
17831      }
17832      exp(a) {
17833          return this.expTable[a];
17834      }
17835      log(a) {
17836          if (a === 0) {
17837              throw new IllegalArgumentException();
17838          }
17839          return this.logTable[a];
17840      }
17841      inverse(a) {
17842          if (a === 0) {
17843              throw new ArithmeticException();
17844          }
17845          return this.expTable[this.modulus - this.logTable[a] - 1];
17846      }
17847      multiply(a, b) {
17848          if (a === 0 || b === 0) {
17849              return 0;
17850          }
17851          return this.expTable[(this.logTable[a] + this.logTable[b]) % (this.modulus - 1)];
17852      }
17853      getSize() {
17854          return this.modulus;
17855      }
17856      equals(o) {
17857          return o === this;
17858      }
17859  }
17860
17861  /*
17862   * Copyright 2012 ZXing authors
17863   *
17864   * Licensed under the Apache License, Version 2.0 (the "License");
17865   * you may not use this file except in compliance with the License.
17866   * You may obtain a copy of the License at
17867   *
17868   *      http://www.apache.org/licenses/LICENSE-2.0
17869   *
17870   * Unless required by applicable law or agreed to in writing, software
17871   * distributed under the License is distributed on an "AS IS" BASIS,
17872   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17873   * See the License for the specific language governing permissions and
17874   * limitations under the License.
17875   */
17876  /**
17877   * <p>A field based on powers of a generator integer, modulo some modulus.</p>
17878   *
17879   * @author Sean Owen
17880   * @see com.google.zxing.common.reedsolomon.GenericGF
17881   */
17882  /*public final*/ class ModulusGF extends ModulusBase {
17883      // private /*final*/ modulus: /*int*/ number;
17884      constructor(modulus, generator) {
17885          super();
17886          this.modulus = modulus;
17887          this.expTable = new Int32Array(modulus);
17888          this.logTable = new Int32Array(modulus);
17889          let x = /*int*/ 1;
17890          for (let i /*int*/ = 0; i < modulus; i++) {
17891              this.expTable[i] = x;
17892              x = (x * generator) % modulus;
17893          }
17894          for (let i /*int*/ = 0; i < modulus - 1; i++) {
17895              this.logTable[this.expTable[i]] = i;
17896          }
17897          // logTable[0] == 0 but this should never be used
17898          this.zero = new ModulusPoly(this, new Int32Array([0]));
17899          this.one = new ModulusPoly(this, new Int32Array([1]));
17900      }
17901      getZero() {
17902          return this.zero;
17903      }
17904      getOne() {
17905          return this.one;
17906      }
17907      buildMonomial(degree, coefficient) {
17908          if (degree < 0) {
17909              throw new IllegalArgumentException();
17910          }
17911          if (coefficient === 0) {
17912              return this.zero;
17913          }
17914          let coefficients = new Int32Array(degree + 1);
17915          coefficients[0] = coefficient;
17916          return new ModulusPoly(this, coefficients);
17917      }
17918  }
17919  ModulusGF.PDF417_GF = new ModulusGF(PDF417Common.NUMBER_OF_CODEWORDS, 3);
17920
17921  /*
17922  * Copyright 2012 ZXing authors
17923  *
17924  * Licensed under the Apache License, Version 2.0 (the "License");
17925  * you may not use this file except in compliance with the License.
17926  * You may obtain a copy of the License at
17927  *
17928  *      http://www.apache.org/licenses/LICENSE-2.0
17929  *
17930  * Unless required by applicable law or agreed to in writing, software
17931  * distributed under the License is distributed on an "AS IS" BASIS,
17932  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17933  * See the License for the specific language governing permissions and
17934  * limitations under the License.
17935  */
17936  /**
17937   * <p>PDF417 error correction implementation.</p>
17938   *
17939   * <p>This <a href="http://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction#Example">example</a>
17940   * is quite useful in understanding the algorithm.</p>
17941   *
17942   * @author Sean Owen
17943   * @see com.google.zxing.common.reedsolomon.ReedSolomonDecoder
17944   */
17945  /*public final*/ class ErrorCorrection$1 {
17946      constructor() {
17947          this.field = ModulusGF.PDF417_GF;
17948      }
17949      /**
17950       * @param received received codewords
17951       * @param numECCodewords number of those codewords used for EC
17952       * @param erasures location of erasures
17953       * @return number of errors
17954       * @throws ChecksumException if errors cannot be corrected, maybe because of too many errors
17955       */
17956      decode(received, numECCodewords, erasures) {
17957          let poly = new ModulusPoly(this.field, received);
17958          let S = new Int32Array(numECCodewords);
17959          let error = false;
17960          for (let i /*int*/ = numECCodewords; i > 0; i--) {
17961              let evaluation = poly.evaluateAt(this.field.exp(i));
17962              S[numECCodewords - i] = evaluation;
17963              if (evaluation !== 0) {
17964                  error = true;
17965              }
17966          }
17967          if (!error) {
17968              return 0;
17969          }
17970          let knownErrors = this.field.getOne();
17971          if (erasures != null) {
17972              for (const erasure of erasures) {
17973                  let b = this.field.exp(received.length - 1 - erasure);
17974                  // Add (1 - bx) term:
17975                  let term = new ModulusPoly(this.field, new Int32Array([this.field.subtract(0, b), 1]));
17976                  knownErrors = knownErrors.multiply(term);
17977              }
17978          }
17979          let syndrome = new ModulusPoly(this.field, S);
17980          // syndrome = syndrome.multiply(knownErrors);
17981          let sigmaOmega = this.runEuclideanAlgorithm(this.field.buildMonomial(numECCodewords, 1), syndrome, numECCodewords);
17982          let sigma = sigmaOmega[0];
17983          let omega = sigmaOmega[1];
17984          // sigma = sigma.multiply(knownErrors);
17985          let errorLocations = this.findErrorLocations(sigma);
17986          let errorMagnitudes = this.findErrorMagnitudes(omega, sigma, errorLocations);
17987          for (let i /*int*/ = 0; i < errorLocations.length; i++) {
17988              let position = received.length - 1 - this.field.log(errorLocations[i]);
17989              if (position < 0) {
17990                  throw ChecksumException.getChecksumInstance();
17991              }
17992              received[position] = this.field.subtract(received[position], errorMagnitudes[i]);
17993          }
17994          return errorLocations.length;
17995      }
17996      /**
17997       *
17998       * @param ModulusPoly
17999       * @param a
18000       * @param ModulusPoly
18001       * @param b
18002       * @param int
18003       * @param R
18004       * @throws ChecksumException
18005       */
18006      runEuclideanAlgorithm(a, b, R) {
18007          // Assume a's degree is >= b's
18008          if (a.getDegree() < b.getDegree()) {
18009              let temp = a;
18010              a = b;
18011              b = temp;
18012          }
18013          let rLast = a;
18014          let r = b;
18015          let tLast = this.field.getZero();
18016          let t = this.field.getOne();
18017          // Run Euclidean algorithm until r's degree is less than R/2
18018          while (r.getDegree() >= Math.round(R / 2)) {
18019              let rLastLast = rLast;
18020              let tLastLast = tLast;
18021              rLast = r;
18022              tLast = t;
18023              // Divide rLastLast by rLast, with quotient in q and remainder in r
18024              if (rLast.isZero()) {
18025                  // Oops, Euclidean algorithm already terminated?
18026                  throw ChecksumException.getChecksumInstance();
18027              }
18028              r = rLastLast;
18029              let q = this.field.getZero();
18030              let denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
18031              let dltInverse = this.field.inverse(denominatorLeadingTerm);
18032              while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
18033                  let degreeDiff = r.getDegree() - rLast.getDegree();
18034                  let scale = this.field.multiply(r.getCoefficient(r.getDegree()), dltInverse);
18035                  q = q.add(this.field.buildMonomial(degreeDiff, scale));
18036                  r = r.subtract(rLast.multiplyByMonomial(degreeDiff, scale));
18037              }
18038              t = q.multiply(tLast).subtract(tLastLast).negative();
18039          }
18040          let sigmaTildeAtZero = t.getCoefficient(0);
18041          if (sigmaTildeAtZero === 0) {
18042              throw ChecksumException.getChecksumInstance();
18043          }
18044          let inverse = this.field.inverse(sigmaTildeAtZero);
18045          let sigma = t.multiply(inverse);
18046          let omega = r.multiply(inverse);
18047          return [sigma, omega];
18048      }
18049      /**
18050       *
18051       * @param errorLocator
18052       * @throws ChecksumException
18053       */
18054      findErrorLocations(errorLocator) {
18055          // This is a direct application of Chien's search
18056          let numErrors = errorLocator.getDegree();
18057          let result = new Int32Array(numErrors);
18058          let e = 0;
18059          for (let i /*int*/ = 1; i < this.field.getSize() && e < numErrors; i++) {
18060              if (errorLocator.evaluateAt(i) === 0) {
18061                  result[e] = this.field.inverse(i);
18062                  e++;
18063              }
18064          }
18065          if (e !== numErrors) {
18066              throw ChecksumException.getChecksumInstance();
18067          }
18068          return result;
18069      }
18070      findErrorMagnitudes(errorEvaluator, errorLocator, errorLocations) {
18071          let errorLocatorDegree = errorLocator.getDegree();
18072          let formalDerivativeCoefficients = new Int32Array(errorLocatorDegree);
18073          for (let i /*int*/ = 1; i <= errorLocatorDegree; i++) {
18074              formalDerivativeCoefficients[errorLocatorDegree - i] =
18075                  this.field.multiply(i, errorLocator.getCoefficient(i));
18076          }
18077          let formalDerivative = new ModulusPoly(this.field, formalDerivativeCoefficients);
18078          // This is directly applying Forney's Formula
18079          let s = errorLocations.length;
18080          let result = new Int32Array(s);
18081          for (let i /*int*/ = 0; i < s; i++) {
18082              let xiInverse = this.field.inverse(errorLocations[i]);
18083              let numerator = this.field.subtract(0, errorEvaluator.evaluateAt(xiInverse));
18084              let denominator = this.field.inverse(formalDerivative.evaluateAt(xiInverse));
18085              result[i] = this.field.multiply(numerator, denominator);
18086          }
18087          return result;
18088      }
18089  }
18090
18091  /*
18092  * Copyright 2013 ZXing authors
18093  *
18094  * Licensed under the Apache License, Version 2.0 (the "License");
18095  * you may not use this file except in compliance with the License.
18096  * You may obtain a copy of the License at
18097  *
18098  *      http://www.apache.org/licenses/LICENSE-2.0
18099  *
18100  * Unless required by applicable law or agreed to in writing, software
18101  * distributed under the License is distributed on an "AS IS" BASIS,
18102  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18103  * See the License for the specific language governing permissions and
18104  * limitations under the License.
18105  */
vendor: 9,180 bytes, lines 18105-18371
18105
18106  /**
18107   * @author Guenther Grau
18108   */
18109  /*final*/ class BoundingBox {
18110      constructor(image, topLeft, bottomLeft, topRight, bottomRight) {
18111          if (image instanceof BoundingBox) {
18112              this.constructor_2(image);
18113          }
18114          else {
18115              this.constructor_1(image, topLeft, bottomLeft, topRight, bottomRight);
18116          }
18117      }
18118      /**
18119       *
18120       * @param image
18121       * @param topLeft
18122       * @param bottomLeft
18123       * @param topRight
18124       * @param bottomRight
18125       *
18126       * @throws NotFoundException
18127       */
18128      constructor_1(image, topLeft, bottomLeft, topRight, bottomRight) {
18129          const leftUnspecified = topLeft == null || bottomLeft == null;
18130          const rightUnspecified = topRight == null || bottomRight == null;
18131          if (leftUnspecified && rightUnspecified) {
18132              throw new NotFoundException();
18133          }
18134          if (leftUnspecified) {
18135              topLeft = new ResultPoint(0, topRight.getY());
18136              bottomLeft = new ResultPoint(0, bottomRight.getY());
18137          }
18138          else if (rightUnspecified) {
18139              topRight = new ResultPoint(image.getWidth() - 1, topLeft.getY());
18140              bottomRight = new ResultPoint(image.getWidth() - 1, bottomLeft.getY());
18141          }
18142          this.image = image;
18143          this.topLeft = topLeft;
18144          this.bottomLeft = bottomLeft;
18145          this.topRight = topRight;
18146          this.bottomRight = bottomRight;
18147          this.minX = Math.trunc(Math.min(topLeft.getX(), bottomLeft.getX()));
18148          this.maxX = Math.trunc(Math.max(topRight.getX(), bottomRight.getX()));
18149          this.minY = Math.trunc(Math.min(topLeft.getY(), topRight.getY()));
18150          this.maxY = Math.trunc(Math.max(bottomLeft.getY(), bottomRight.getY()));
18151      }
18152      constructor_2(boundingBox) {
18153          this.image = boundingBox.image;
18154          this.topLeft = boundingBox.getTopLeft();
18155          this.bottomLeft = boundingBox.getBottomLeft();
18156          this.topRight = boundingBox.getTopRight();
18157          this.bottomRight = boundingBox.getBottomRight();
18158          this.minX = boundingBox.getMinX();
18159          this.maxX = boundingBox.getMaxX();
18160          this.minY = boundingBox.getMinY();
18161          this.maxY = boundingBox.getMaxY();
18162      }
18163      /**
18164       * @throws NotFoundException
18165       */
18166      static merge(leftBox, rightBox) {
18167          if (leftBox == null) {
18168              return rightBox;
18169          }
18170          if (rightBox == null) {
18171              return leftBox;
18172          }
18173          return new BoundingBox(leftBox.image, leftBox.topLeft, leftBox.bottomLeft, rightBox.topRight, rightBox.bottomRight);
18174      }
18175      /**
18176       * @throws NotFoundException
18177       */
18178      addMissingRows(missingStartRows, missingEndRows, isLeft) {
18179          let newTopLeft = this.topLeft;
18180          let newBottomLeft = this.bottomLeft;
18181          let newTopRight = this.topRight;
18182          let newBottomRight = this.bottomRight;
18183          if (missingStartRows > 0) {
18184              let top = isLeft ? this.topLeft : this.topRight;
18185              let newMinY = Math.trunc(top.getY() - missingStartRows);
18186              if (newMinY < 0) {
18187                  newMinY = 0;
18188              }
18189              let newTop = new ResultPoint(top.getX(), newMinY);
18190              if (isLeft) {
18191                  newTopLeft = newTop;
18192              }
18193              else {
18194                  newTopRight = newTop;
18195              }
18196          }
18197          if (missingEndRows > 0) {
18198              let bottom = isLeft ? this.bottomLeft : this.bottomRight;
18199              let newMaxY = Math.trunc(bottom.getY() + missingEndRows);
18200              if (newMaxY >= this.image.getHeight()) {
18201                  newMaxY = this.image.getHeight() - 1;
18202              }
18203              let newBottom = new ResultPoint(bottom.getX(), newMaxY);
18204              if (isLeft) {
18205                  newBottomLeft = newBottom;
18206              }
18207              else {
18208                  newBottomRight = newBottom;
18209              }
18210          }
18211          return new BoundingBox(this.image, newTopLeft, newBottomLeft, newTopRight, newBottomRight);
18212      }
18213      getMinX() {
18214          return this.minX;
18215      }
18216      getMaxX() {
18217          return this.maxX;
18218      }
18219      getMinY() {
18220          return this.minY;
18221      }
18222      getMaxY() {
18223          return this.maxY;
18224      }
18225      getTopLeft() {
18226          return this.topLeft;
18227      }
18228      getTopRight() {
18229          return this.topRight;
18230      }
18231      getBottomLeft() {
18232          return this.bottomLeft;
18233      }
18234      getBottomRight() {
18235          return this.bottomRight;
18236      }
18237  }
18238
18239  /*
18240   * Copyright 2013 ZXing authors
18241   *
18242   * Licensed under the Apache License, Version 2.0 (the "License");
18243   * you may not use this file except in compliance with the License.
18244   * You may obtain a copy of the License at
18245   *
18246   *      http://www.apache.org/licenses/LICENSE-2.0
18247   *
18248   * Unless required by applicable law or agreed to in writing, software
18249   * distributed under the License is distributed on an "AS IS" BASIS,
18250   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18251   * See the License for the specific language governing permissions and
18252   * limitations under the License.
18253   */
18254  // package com.google.zxing.pdf417.decoder;
18255  /**
18256   * @author Guenther Grau
18257   */
18258  /*final*/ class BarcodeMetadata {
18259      constructor(columnCount, rowCountUpperPart, rowCountLowerPart, errorCorrectionLevel) {
18260          this.columnCount = columnCount;
18261          this.errorCorrectionLevel = errorCorrectionLevel;
18262          this.rowCountUpperPart = rowCountUpperPart;
18263          this.rowCountLowerPart = rowCountLowerPart;
18264          this.rowCount = rowCountUpperPart + rowCountLowerPart;
18265      }
18266      getColumnCount() {
18267          return this.columnCount;
18268      }
18269      getErrorCorrectionLevel() {
18270          return this.errorCorrectionLevel;
18271      }
18272      getRowCount() {
18273          return this.rowCount;
18274      }
18275      getRowCountUpperPart() {
18276          return this.rowCountUpperPart;
18277      }
18278      getRowCountLowerPart() {
18279          return this.rowCountLowerPart;
18280      }
18281  }
18282
18283  /**
18284   * Java Formatter class polyfill that works in the JS way.
18285   */
18286  class Formatter {
18287      constructor() {
18288          this.buffer = '';
18289      }
18290      /**
18291       *
18292       * @see https://stackoverflow.com/a/13439711/4367683
18293       *
18294       * @param str
18295       * @param arr
18296       */
18297      static form(str, arr) {
18298          let i = -1;
18299          function callback(exp, p0, p1, p2, p3, p4) {
18300              if (exp === '%%')
18301                  return '%';
18302              if (arr[++i] === undefined)
18303                  return undefined;
18304              exp = p2 ? parseInt(p2.substr(1)) : undefined;
18305              let base = p3 ? parseInt(p3.substr(1)) : undefined;
18306              let val;
18307              switch (p4) {
18308                  case 's':
18309                      val = arr[i];
18310                      break;
18311                  case 'c':
18312                      val = arr[i][0];
18313                      break;
18314                  case 'f':
18315                      val = parseFloat(arr[i]).toFixed(exp);
18316                      break;
18317                  case 'p':
18318                      val = parseFloat(arr[i]).toPrecision(exp);
18319                      break;
18320                  case 'e':
18321                      val = parseFloat(arr[i]).toExponential(exp);
18322                      break;
18323                  case 'x':
18324                      val = parseInt(arr[i]).toString(base ? base : 16);
18325                      break;
18326                  case 'd':
18327                      val = parseFloat(parseInt(arr[i], base ? base : 10).toPrecision(exp)).toFixed(0);
18328                      break;
18329              }
18330              val = typeof val === 'object' ? JSON.stringify(val) : (+val).toString(base);
18331              let size = parseInt(p1); /* padding size */
18332              let ch = p1 && (p1[0] + '') === '0' ? '0' : ' '; /* isnull? */
18333              while (val.length < size)
18334                  val = p0 !== undefined ? val + ch : ch + val; /* isminus? */
18335              return val;
18336          }
18337          let regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;
18338          return str.replace(regex, callback);
18339      }
18340      /**
18341       *
18342       * @param append The new string to append.
18343       * @param args Argumets values to be formated.
18344       */
18345      format(append, ...args) {
18346          this.buffer += Formatter.form(append, args);
18347      }
18348      /**
18349       * Returns the Formatter string value.
18350       */
18351      toString() {
18352          return this.buffer;
18353      }
18354  }
18355
18356  /*
18357   * Copyright 2013 ZXing authors
18358   *
18359   * Licensed under the Apache License, Version 2.0 (the "License");
18360   * you may not use this file except in compliance with the License.
18361   * You may obtain a copy of the License at
18362   *
18363   *      http://www.apache.org/licenses/LICENSE-2.0
18364   *
18365   * Unless required by applicable law or agreed to in writing, software
18366   * distributed under the License is distributed on an "AS IS" BASIS,
18367   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18368   * See the License for the specific language governing permissions and
18369   * limitations under the License.
18370   */
18371  /
vendor: 16,950 bytes, lines 18371-18757
18371**
18372   * @author Guenther Grau
18373   */
18374  class DetectionResultColumn {
18375      constructor(boundingBox) {
18376          this.boundingBox = new BoundingBox(boundingBox);
18377          // this.codewords = new Codeword[boundingBox.getMaxY() - boundingBox.getMinY() + 1];
18378          this.codewords = new Array(boundingBox.getMaxY() - boundingBox.getMinY() + 1);
18379      }
18380      /*final*/ getCodewordNearby(imageRow) {
18381          let codeword = this.getCodeword(imageRow);
18382          if (codeword != null) {
18383              return codeword;
18384          }
18385          for (let i = 1; i < DetectionResultColumn.MAX_NEARBY_DISTANCE; i++) {
18386              let nearImageRow = this.imageRowToCodewordIndex(imageRow) - i;
18387              if (nearImageRow >= 0) {
18388                  codeword = this.codewords[nearImageRow];
18389                  if (codeword != null) {
18390                      return codeword;
18391                  }
18392              }
18393              nearImageRow = this.imageRowToCodewordIndex(imageRow) + i;
18394              if (nearImageRow < this.codewords.length) {
18395                  codeword = this.codewords[nearImageRow];
18396                  if (codeword != null) {
18397                      return codeword;
18398                  }
18399              }
18400          }
18401          return null;
18402      }
18403      /*final int*/ imageRowToCodewordIndex(imageRow) {
18404          return imageRow - this.boundingBox.getMinY();
18405      }
18406      /*final void*/ setCodeword(imageRow, codeword) {
18407          this.codewords[this.imageRowToCodewordIndex(imageRow)] = codeword;
18408      }
18409      /*final*/ getCodeword(imageRow) {
18410          return this.codewords[this.imageRowToCodewordIndex(imageRow)];
18411      }
18412      /*final*/ getBoundingBox() {
18413          return this.boundingBox;
18414      }
18415      /*final*/ getCodewords() {
18416          return this.codewords;
18417      }
18418      // @Override
18419      toString() {
18420          const formatter = new Formatter();
18421          let row = 0;
18422          for (const codeword of this.codewords) {
18423              if (codeword == null) {
18424                  formatter.format('%3d:    |   %n', row++);
18425                  continue;
18426              }
18427              formatter.format('%3d: %3d|%3d%n', row++, codeword.getRowNumber(), codeword.getValue());
18428          }
18429          return formatter.toString();
18430      }
18431  }
18432  DetectionResultColumn.MAX_NEARBY_DISTANCE = 5;
18433
18434  /*
18435   * Copyright 2013 ZXing authors
18436   *
18437   * Licensed under the Apache License, Version 2.0 (the "License");
18438   * you may not use this file except in compliance with the License.
18439   * You may obtain a copy of the License at
18440   *
18441   *      http://www.apache.org/licenses/LICENSE-2.0
18442   *
18443   * Unless required by applicable law or agreed to in writing, software
18444   * distributed under the License is distributed on an "AS IS" BASIS,
18445   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18446   * See the License for the specific language governing permissions and
18447   * limitations under the License.
18448   */
18449  // import java.util.ArrayList;
18450  // import java.util.Collection;
18451  // import java.util.HashMap;
18452  // import java.util.Map;
18453  // import java.util.Map.Entry;
18454  /**
18455   * @author Guenther Grau
18456   */
18457  /*final*/ class BarcodeValue {
18458      constructor() {
18459          this.values = new Map();
18460      }
18461      /**
18462       * Add an occurrence of a value
18463       */
18464      setValue(value) {
18465          value = Math.trunc(value);
18466          let confidence = this.values.get(value);
18467          if (confidence == null) {
18468              confidence = 0;
18469          }
18470          confidence++;
18471          this.values.set(value, confidence);
18472      }
18473      /**
18474       * Determines the maximum occurrence of a set value and returns all values which were set with this occurrence.
18475       * @return an array of int, containing the values with the highest occurrence, or null, if no value was set
18476       */
18477      getValue() {
18478          let maxConfidence = -1;
18479          let result = new Array();
18480          for (const [key, value] of this.values.entries()) {
18481              const entry = {
18482                  getKey: () => key,
18483                  getValue: () => value,
18484              };
18485              if (entry.getValue() > maxConfidence) {
18486                  maxConfidence = entry.getValue();
18487                  result = [];
18488                  result.push(entry.getKey());
18489              }
18490              else if (entry.getValue() === maxConfidence) {
18491                  result.push(entry.getKey());
18492              }
18493          }
18494          return PDF417Common.toIntArray(result);
18495      }
18496      getConfidence(value) {
18497          return this.values.get(value);
18498      }
18499  }
18500
18501  /*
18502   * Copyright 2013 ZXing authors
18503   *
18504   * Licensed under the Apache License, Version 2.0 (the "License");
18505   * you may not use this file except in compliance with the License.
18506   * You may obtain a copy of the License at
18507   *
18508   *      http://www.apache.org/licenses/LICENSE-2.0
18509   *
18510   * Unless required by applicable law or agreed to in writing, software
18511   * distributed under the License is distributed on an "AS IS" BASIS,
18512   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18513   * See the License for the specific language governing permissions and
18514   * limitations under the License.
18515   */
18516  /**
18517   * @author Guenther Grau
18518   */
18519  /*final*/ class DetectionResultRowIndicatorColumn extends DetectionResultColumn {
18520      constructor(boundingBox, isLeft) {
18521          super(boundingBox);
18522          this._isLeft = isLeft;
18523      }
18524      setRowNumbers() {
18525          for (let codeword /*Codeword*/ of this.getCodewords()) {
18526              if (codeword != null) {
18527                  codeword.setRowNumberAsRowIndicatorColumn();
18528              }
18529          }
18530      }
18531      // TODO implement properly
18532      // TODO maybe we should add missing codewords to store the correct row number to make
18533      // finding row numbers for other columns easier
18534      // use row height count to make detection of invalid row numbers more reliable
18535      adjustCompleteIndicatorColumnRowNumbers(barcodeMetadata) {
18536          let codewords = this.getCodewords();
18537          this.setRowNumbers();
18538          this.removeIncorrectCodewords(codewords, barcodeMetadata);
18539          let boundingBox = this.getBoundingBox();
18540          let top = this._isLeft ? boundingBox.getTopLeft() : boundingBox.getTopRight();
18541          let bottom = this._isLeft ? boundingBox.getBottomLeft() : boundingBox.getBottomRight();
18542          let firstRow = this.imageRowToCodewordIndex(Math.trunc(top.getY()));
18543          let lastRow = this.imageRowToCodewordIndex(Math.trunc(bottom.getY()));
18544          // We need to be careful using the average row height. Barcode could be skewed so that we have smaller and
18545          // taller rows
18546          // float averageRowHeight = (lastRow - firstRow) / /*(float)*/ barcodeMetadata.getRowCount();
18547          let barcodeRow = -1;
18548          let maxRowHeight = 1;
18549          let currentRowHeight = 0;
18550          for (let codewordsRow /*int*/ = firstRow; codewordsRow < lastRow; codewordsRow++) {
18551              if (codewords[codewordsRow] == null) {
18552                  continue;
18553              }
18554              let codeword = codewords[codewordsRow];
18555              //      float expectedRowNumber = (codewordsRow - firstRow) / averageRowHeight;
18556              //      if (Math.abs(codeword.getRowNumber() - expectedRowNumber) > 2) {
18557              //        SimpleLog.log(LEVEL.WARNING,
18558              //            "Removing codeword, rowNumberSkew too high, codeword[" + codewordsRow + "]: Expected Row: " +
18559              //                expectedRowNumber + ", RealRow: " + codeword.getRowNumber() + ", value: " + codeword.getValue());
18560              //        codewords[codewordsRow] = null;
18561              //      }
18562              let rowDifference = codeword.getRowNumber() - barcodeRow;
18563              // TODO improve handling with case where first row indicator doesn't start with 0
18564              if (rowDifference === 0) {
18565                  currentRowHeight++;
18566              }
18567              else if (rowDifference === 1) {
18568                  maxRowHeight = Math.max(maxRowHeight, currentRowHeight);
18569                  currentRowHeight = 1;
18570                  barcodeRow = codeword.getRowNumber();
18571              }
18572              else if (rowDifference < 0 ||
18573                  codeword.getRowNumber() >= barcodeMetadata.getRowCount() ||
18574                  rowDifference > codewordsRow) {
18575                  codewords[codewordsRow] = null;
18576              }
18577              else {
18578                  let checkedRows;
18579                  if (maxRowHeight > 2) {
18580                      checkedRows = (maxRowHeight - 2) * rowDifference;
18581                  }
18582                  else {
18583                      checkedRows = rowDifference;
18584                  }
18585                  let closePreviousCodewordFound = checkedRows >= codewordsRow;
18586                  for (let i /*int*/ = 1; i <= checkedRows && !closePreviousCodewordFound; i++) {
18587                      // there must be (height * rowDifference) number of codewords missing. For now we assume height = 1.
18588                      // This should hopefully get rid of most problems already.
18589                      closePreviousCodewordFound = codewords[codewordsRow - i] != null;
18590                  }
18591                  if (closePreviousCodewordFound) {
18592                      codewords[codewordsRow] = null;
18593                  }
18594                  else {
18595                      barcodeRow = codeword.getRowNumber();
18596                      currentRowHeight = 1;
18597                  }
18598              }
18599          }
18600          // return (int) (averageRowHeight + 0.5);
18601      }
18602      getRowHeights() {
18603          let barcodeMetadata = this.getBarcodeMetadata();
18604          if (barcodeMetadata == null) {
18605              return null;
18606          }
18607          this.adjustIncompleteIndicatorColumnRowNumbers(barcodeMetadata);
18608          let result = new Int32Array(barcodeMetadata.getRowCount());
18609          for (let codeword /*Codeword*/ of this.getCodewords()) {
18610              if (codeword != null) {
18611                  let rowNumber = codeword.getRowNumber();
18612                  if (rowNumber >= result.length) {
18613                      // We have more rows than the barcode metadata allows for, ignore them.
18614                      continue;
18615                  }
18616                  result[rowNumber]++;
18617              } // else throw exception?
18618          }
18619          return result;
18620      }
18621      // TODO maybe we should add missing codewords to store the correct row number to make
18622      // finding row numbers for other columns easier
18623      // use row height count to make detection of invalid row numbers more reliable
18624      adjustIncompleteIndicatorColumnRowNumbers(barcodeMetadata) {
18625          let boundingBox = this.getBoundingBox();
18626          let top = this._isLeft ? boundingBox.getTopLeft() : boundingBox.getTopRight();
18627          let bottom = this._isLeft ? boundingBox.getBottomLeft() : boundingBox.getBottomRight();
18628          let firstRow = this.imageRowToCodewordIndex(Math.trunc(top.getY()));
18629          let lastRow = this.imageRowToCodewordIndex(Math.trunc(bottom.getY()));
18630          // float averageRowHeight = (lastRow - firstRow) / /*(float)*/ barcodeMetadata.getRowCount();
18631          let codewords = this.getCodewords();
18632          let barcodeRow = -1;
18633          for (let codewordsRow /*int*/ = firstRow; codewordsRow < lastRow; codewordsRow++) {
18634              if (codewords[codewordsRow] == null) {
18635                  continue;
18636              }
18637              let codeword = codewords[codewordsRow];
18638              codeword.setRowNumberAsRowIndicatorColumn();
18639              let rowDifference = codeword.getRowNumber() - barcodeRow;
18640              // TODO improve handling with case where first row indicator doesn't start with 0
18641              if (rowDifference === 0) ;
18642              else if (rowDifference === 1) {
18643                  barcodeRow = codeword.getRowNumber();
18644              }
18645              else if (codeword.getRowNumber() >= barcodeMetadata.getRowCount()) {
18646                  codewords[codewordsRow] = null;
18647              }
18648              else {
18649                  barcodeRow = codeword.getRowNumber();
18650              }
18651          }
18652          // return (int) (averageRowHeight + 0.5);
18653      }
18654      getBarcodeMetadata() {
18655          let codewords = this.getCodewords();
18656          let barcodeColumnCount = new BarcodeValue();
18657          let barcodeRowCountUpperPart = new BarcodeValue();
18658          let barcodeRowCountLowerPart = new BarcodeValue();
18659          let barcodeECLevel = new BarcodeValue();
18660          for (let codeword /*Codeword*/ of codewords) {
18661              if (codeword == null) {
18662                  continue;
18663              }
18664              codeword.setRowNumberAsRowIndicatorColumn();
18665              let rowIndicatorValue = codeword.getValue() % 30;
18666              let codewordRowNumber = codeword.getRowNumber();
18667              if (!this._isLeft) {
18668                  codewordRowNumber += 2;
18669              }
18670              switch (codewordRowNumber % 3) {
18671                  case 0:
18672                      barcodeRowCountUpperPart.setValue(rowIndicatorValue * 3 + 1);
18673                      break;
18674                  case 1:
18675                      barcodeECLevel.setValue(rowIndicatorValue / 3);
18676                      barcodeRowCountLowerPart.setValue(rowIndicatorValue % 3);
18677                      break;
18678                  case 2:
18679                      barcodeColumnCount.setValue(rowIndicatorValue + 1);
18680                      break;
18681              }
18682          }
18683          // Maybe we should check if we have ambiguous values?
18684          if ((barcodeColumnCount.getValue().length === 0) ||
18685              (barcodeRowCountUpperPart.getValue().length === 0) ||
18686              (barcodeRowCountLowerPart.getValue().length === 0) ||
18687              (barcodeECLevel.getValue().length === 0) ||
18688              barcodeColumnCount.getValue()[0] < 1 ||
18689              barcodeRowCountUpperPart.getValue()[0] + barcodeRowCountLowerPart.getValue()[0] < PDF417Common.MIN_ROWS_IN_BARCODE ||
18690              barcodeRowCountUpperPart.getValue()[0] + barcodeRowCountLowerPart.getValue()[0] > PDF417Common.MAX_ROWS_IN_BARCODE) {
18691              return null;
18692          }
18693          let barcodeMetadata = new BarcodeMetadata(barcodeColumnCount.getValue()[0], barcodeRowCountUpperPart.getValue()[0], barcodeRowCountLowerPart.getValue()[0], barcodeECLevel.getValue()[0]);
18694          this.removeIncorrectCodewords(codewords, barcodeMetadata);
18695          return barcodeMetadata;
18696      }
18697      removeIncorrectCodewords(codewords, barcodeMetadata) {
18698          // Remove codewords which do not match the metadata
18699          // TODO Maybe we should keep the incorrect codewords for the start and end positions?
18700          for (let codewordRow /*int*/ = 0; codewordRow < codewords.length; codewordRow++) {
18701              let codeword = codewords[codewordRow];
18702              if (codewords[codewordRow] == null) {
18703                  continue;
18704              }
18705              let rowIndicatorValue = codeword.getValue() % 30;
18706              let codewordRowNumber = codeword.getRowNumber();
18707              if (codewordRowNumber > barcodeMetadata.getRowCount()) {
18708                  codewords[codewordRow] = null;
18709                  continue;
18710              }
18711              if (!this._isLeft) {
18712                  codewordRowNumber += 2;
18713              }
18714              switch (codewordRowNumber % 3) {
18715                  case 0:
18716                      if (rowIndicatorValue * 3 + 1 !== barcodeMetadata.getRowCountUpperPart()) {
18717                          codewords[codewordRow] = null;
18718                      }
18719                      break;
18720                  case 1:
18721                      if (Math.trunc(rowIndicatorValue / 3) !== barcodeMetadata.getErrorCorrectionLevel() ||
18722                          rowIndicatorValue % 3 !== barcodeMetadata.getRowCountLowerPart()) {
18723                          codewords[codewordRow] = null;
18724                      }
18725                      break;
18726                  case 2:
18727                      if (rowIndicatorValue + 1 !== barcodeMetadata.getColumnCount()) {
18728                          codewords[codewordRow] = null;
18729                      }
18730                      break;
18731              }
18732          }
18733      }
18734      isLeft() {
18735          return this._isLeft;
18736      }
18737      // @Override
18738      toString() {
18739          return 'IsLeft: ' + this._isLeft + '\n' + super.toString();
18740      }
18741  }
18742
18743  /*
18744   * Copyright 2013 ZXing authors
18745   *
18746   * Licensed under the Apache License, Version 2.0 (the "License");
18747   * you may not use this file except in compliance with the License.
18748   * You may obtain a copy of the License at
18749   *
18750   *      http://www.apache.org/licenses/LICENSE-2.0
18751   *
18752   * Unless required by applicable law or agreed to in writing, software
18753   * distributed under the License is distributed on an "AS IS" BASIS,
18754   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18755   * See the License for the specific language governing permissions and
18756   * limitations under the License.
18757   */
vendor: 12,980 bytes, lines 18757-19030
18757
18758  /**
18759   * @author Guenther Grau
18760   */
18761  /*final*/ class DetectionResult {
18762      constructor(barcodeMetadata, boundingBox) {
18763          /*final*/ this.ADJUST_ROW_NUMBER_SKIP = 2;
18764          this.barcodeMetadata = barcodeMetadata;
18765          this.barcodeColumnCount = barcodeMetadata.getColumnCount();
18766          this.boundingBox = boundingBox;
18767          // this.detectionResultColumns = new DetectionResultColumn[this.barcodeColumnCount + 2];
18768          this.detectionResultColumns = new Array(this.barcodeColumnCount + 2);
18769      }
18770      getDetectionResultColumns() {
18771          this.adjustIndicatorColumnRowNumbers(this.detectionResultColumns[0]);
18772          this.adjustIndicatorColumnRowNumbers(this.detectionResultColumns[this.barcodeColumnCount + 1]);
18773          let unadjustedCodewordCount = PDF417Common.MAX_CODEWORDS_IN_BARCODE;
18774          let previousUnadjustedCount;
18775          do {
18776              previousUnadjustedCount = unadjustedCodewordCount;
18777              unadjustedCodewordCount = this.adjustRowNumbersAndGetCount();
18778          } while (unadjustedCodewordCount > 0 && unadjustedCodewordCount < previousUnadjustedCount);
18779          return this.detectionResultColumns;
18780      }
18781      adjustIndicatorColumnRowNumbers(detectionResultColumn) {
18782          if (detectionResultColumn != null) {
18783              detectionResultColumn
18784                  .adjustCompleteIndicatorColumnRowNumbers(this.barcodeMetadata);
18785          }
18786      }
18787      // TODO ensure that no detected codewords with unknown row number are left
18788      // we should be able to estimate the row height and use it as a hint for the row number
18789      // we should also fill the rows top to bottom and bottom to top
18790      /**
18791       * @return number of codewords which don't have a valid row number. Note that the count is not accurate as codewords
18792       * will be counted several times. It just serves as an indicator to see when we can stop adjusting row numbers
18793       */
18794      adjustRowNumbersAndGetCount() {
18795          let unadjustedCount = this.adjustRowNumbersByRow();
18796          if (unadjustedCount === 0) {
18797              return 0;
18798          }
18799          for (let barcodeColumn /*int*/ = 1; barcodeColumn < this.barcodeColumnCount + 1; barcodeColumn++) {
18800              let codewords = this.detectionResultColumns[barcodeColumn].getCodewords();
18801              for (let codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) {
18802                  if (codewords[codewordsRow] == null) {
18803                      continue;
18804                  }
18805                  if (!codewords[codewordsRow].hasValidRowNumber()) {
18806                      this.adjustRowNumbers(barcodeColumn, codewordsRow, codewords);
18807                  }
18808              }
18809          }
18810          return unadjustedCount;
18811      }
18812      adjustRowNumbersByRow() {
18813          this.adjustRowNumbersFromBothRI();
18814          // TODO we should only do full row adjustments if row numbers of left and right row indicator column match.
18815          // Maybe it's even better to calculated the height (rows: d) and divide it by the number of barcode
18816          // rows. This, together with the LRI and RRI row numbers should allow us to get a good estimate where a row
18817          // number starts and ends.
18818          let unadjustedCount = this.adjustRowNumbersFromLRI();
18819          return unadjustedCount + this.adjustRowNumbersFromRRI();
18820      }
18821      adjustRowNumbersFromBothRI() {
18822          if (this.detectionResultColumns[0] == null || this.detectionResultColumns[this.barcodeColumnCount + 1] == null) {
18823              return;
18824          }
18825          let LRIcodewords = this.detectionResultColumns[0].getCodewords();
18826          let RRIcodewords = this.detectionResultColumns[this.barcodeColumnCount + 1].getCodewords();
18827          for (let codewordsRow /*int*/ = 0; codewordsRow < LRIcodewords.length; codewordsRow++) {
18828              if (LRIcodewords[codewordsRow] != null &&
18829                  RRIcodewords[codewordsRow] != null &&
18830                  LRIcodewords[codewordsRow].getRowNumber() === RRIcodewords[codewordsRow].getRowNumber()) {
18831                  for (let barcodeColumn /*int*/ = 1; barcodeColumn <= this.barcodeColumnCount; barcodeColumn++) {
18832                      let codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow];
18833                      if (codeword == null) {
18834                          continue;
18835                      }
18836                      codeword.setRowNumber(LRIcodewords[codewordsRow].getRowNumber());
18837                      if (!codeword.hasValidRowNumber()) {
18838                          this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow] = null;
18839                      }
18840                  }
18841              }
18842          }
18843      }
18844      adjustRowNumbersFromRRI() {
18845          if (this.detectionResultColumns[this.barcodeColumnCount + 1] == null) {
18846              return 0;
18847          }
18848          let unadjustedCount = 0;
18849          let codewords = this.detectionResultColumns[this.barcodeColumnCount + 1].getCodewords();
18850          for (let codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) {
18851              if (codewords[codewordsRow] == null) {
18852                  continue;
18853              }
18854              let rowIndicatorRowNumber = codewords[codewordsRow].getRowNumber();
18855              let invalidRowCounts = 0;
18856              for (let barcodeColumn /*int*/ = this.barcodeColumnCount + 1; barcodeColumn > 0 && invalidRowCounts < this.ADJUST_ROW_NUMBER_SKIP; barcodeColumn--) {
18857                  let codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow];
18858                  if (codeword != null) {
18859                      invalidRowCounts = DetectionResult.adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
18860                      if (!codeword.hasValidRowNumber()) {
18861                          unadjustedCount++;
18862                      }
18863                  }
18864              }
18865          }
18866          return unadjustedCount;
18867      }
18868      adjustRowNumbersFromLRI() {
18869          if (this.detectionResultColumns[0] == null) {
18870              return 0;
18871          }
18872          let unadjustedCount = 0;
18873          let codewords = this.detectionResultColumns[0].getCodewords();
18874          for (let codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) {
18875              if (codewords[codewordsRow] == null) {
18876                  continue;
18877              }
18878              let rowIndicatorRowNumber = codewords[codewordsRow].getRowNumber();
18879              let invalidRowCounts = 0;
18880              for (let barcodeColumn /*int*/ = 1; barcodeColumn < this.barcodeColumnCount + 1 && invalidRowCounts < this.ADJUST_ROW_NUMBER_SKIP; barcodeColumn++) {
18881                  let codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow];
18882                  if (codeword != null) {
18883                      invalidRowCounts = DetectionResult.adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
18884                      if (!codeword.hasValidRowNumber()) {
18885                          unadjustedCount++;
18886                      }
18887                  }
18888              }
18889          }
18890          return unadjustedCount;
18891      }
18892      static adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword) {
18893          if (codeword == null) {
18894              return invalidRowCounts;
18895          }
18896          if (!codeword.hasValidRowNumber()) {
18897              if (codeword.isValidRowNumber(rowIndicatorRowNumber)) {
18898                  codeword.setRowNumber(rowIndicatorRowNumber);
18899                  invalidRowCounts = 0;
18900              }
18901              else {
18902                  ++invalidRowCounts;
18903              }
18904          }
18905          return invalidRowCounts;
18906      }
18907      adjustRowNumbers(barcodeColumn, codewordsRow, codewords) {
18908          if (this.detectionResultColumns[barcodeColumn - 1] == null) {
18909              return;
18910          }
18911          let codeword = codewords[codewordsRow];
18912          let previousColumnCodewords = this.detectionResultColumns[barcodeColumn - 1].getCodewords();
18913          let nextColumnCodewords = previousColumnCodewords;
18914          if (this.detectionResultColumns[barcodeColumn + 1] != null) {
18915              nextColumnCodewords = this.detectionResultColumns[barcodeColumn + 1].getCodewords();
18916          }
18917          // let otherCodewords: Codeword[] = new Codeword[14];
18918          let otherCodewords = new Array(14);
18919          otherCodewords[2] = previousColumnCodewords[codewordsRow];
18920          otherCodewords[3] = nextColumnCodewords[codewordsRow];
18921          if (codewordsRow > 0) {
18922              otherCodewords[0] = codewords[codewordsRow - 1];
18923              otherCodewords[4] = previousColumnCodewords[codewordsRow - 1];
18924              otherCodewords[5] = nextColumnCodewords[codewordsRow - 1];
18925          }
18926          if (codewordsRow > 1) {
18927              otherCodewords[8] = codewords[codewordsRow - 2];
18928              otherCodewords[10] = previousColumnCodewords[codewordsRow - 2];
18929              otherCodewords[11] = nextColumnCodewords[codewordsRow - 2];
18930          }
18931          if (codewordsRow < codewords.length - 1) {
18932              otherCodewords[1] = codewords[codewordsRow + 1];
18933              otherCodewords[6] = previousColumnCodewords[codewordsRow + 1];
18934              otherCodewords[7] = nextColumnCodewords[codewordsRow + 1];
18935          }
18936          if (codewordsRow < codewords.length - 2) {
18937              otherCodewords[9] = codewords[codewordsRow + 2];
18938              otherCodewords[12] = previousColumnCodewords[codewordsRow + 2];
18939              otherCodewords[13] = nextColumnCodewords[codewordsRow + 2];
18940          }
18941          for (let otherCodeword of otherCodewords) {
18942              if (DetectionResult.adjustRowNumber(codeword, otherCodeword)) {
18943                  return;
18944              }
18945          }
18946      }
18947      /**
18948       * @return true, if row number was adjusted, false otherwise
18949       */
18950      static adjustRowNumber(codeword, otherCodeword) {
18951          if (otherCodeword == null) {
18952              return false;
18953          }
18954          if (otherCodeword.hasValidRowNumber() && otherCodeword.getBucket() === codeword.getBucket()) {
18955              codeword.setRowNumber(otherCodeword.getRowNumber());
18956              return true;
18957          }
18958          return false;
18959      }
18960      getBarcodeColumnCount() {
18961          return this.barcodeColumnCount;
18962      }
18963      getBarcodeRowCount() {
18964          return this.barcodeMetadata.getRowCount();
18965      }
18966      getBarcodeECLevel() {
18967          return this.barcodeMetadata.getErrorCorrectionLevel();
18968      }
18969      setBoundingBox(boundingBox) {
18970          this.boundingBox = boundingBox;
18971      }
18972      getBoundingBox() {
18973          return this.boundingBox;
18974      }
18975      setDetectionResultColumn(barcodeColumn, detectionResultColumn) {
18976          this.detectionResultColumns[barcodeColumn] = detectionResultColumn;
18977      }
18978      getDetectionResultColumn(barcodeColumn) {
18979          return this.detectionResultColumns[barcodeColumn];
18980      }
18981      // @Override
18982      toString() {
18983          let rowIndicatorColumn = this.detectionResultColumns[0];
18984          if (rowIndicatorColumn == null) {
18985              rowIndicatorColumn = this.detectionResultColumns[this.barcodeColumnCount + 1];
18986          }
18987          // try (
18988          let formatter = new Formatter();
18989          // ) {
18990          for (let codewordsRow /*int*/ = 0; codewordsRow < rowIndicatorColumn.getCodewords().length; codewordsRow++) {
18991              formatter.format('CW %3d:', codewordsRow);
18992              for (let barcodeColumn /*int*/ = 0; barcodeColumn < this.barcodeColumnCount + 2; barcodeColumn++) {
18993                  if (this.detectionResultColumns[barcodeColumn] == null) {
18994                      formatter.format('    |   ');
18995                      continue;
18996                  }
18997                  let codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow];
18998                  if (codeword == null) {
18999                      formatter.format('    |   ');
19000                      continue;
19001                  }
19002                  formatter.format(' %3d|%3d', codeword.getRowNumber(), codeword.getValue());
19003              }
19004              formatter.format('%n');
19005          }
19006          return formatter.toString();
19007          // }
19008      }
19009  }
19010
19011  /*
19012   * Copyright 2013 ZXing authors
19013   *
19014   * Licensed under the Apache License, Version 2.0 (the "License");
19015   * you may not use this file except in compliance with the License.
19016   * You may obtain a copy of the License at
19017   *
19018   *      http://www.apache.org/licenses/LICENSE-2.0
19019   *
19020   * Unless required by applicable law or agreed to in writing, software
19021   * distributed under the License is distributed on an "AS IS" BASIS,
19022   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19023   * See the License for the specific language governing permissions and
19024   * limitations under the License.
19025   */
19026  // package com.google.zxing.pdf417.decoder;
19027  /**
19028   * @author Guenther Grau
19029   */
19030  
vendor: 4,643 bytes, lines 19030-19148
19030/*final*/ class Codeword {
19031      constructor(startX, endX, bucket, value) {
19032          this.rowNumber = Codeword.BARCODE_ROW_UNKNOWN;
19033          this.startX = Math.trunc(startX);
19034          this.endX = Math.trunc(endX);
19035          this.bucket = Math.trunc(bucket);
19036          this.value = Math.trunc(value);
19037      }
19038      hasValidRowNumber() {
19039          return this.isValidRowNumber(this.rowNumber);
19040      }
19041      isValidRowNumber(rowNumber) {
19042          return rowNumber !== Codeword.BARCODE_ROW_UNKNOWN && this.bucket === (rowNumber % 3) * 3;
19043      }
19044      setRowNumberAsRowIndicatorColumn() {
19045          this.rowNumber = Math.trunc((Math.trunc(this.value / 30)) * 3 + Math.trunc(this.bucket / 3));
19046      }
19047      getWidth() {
19048          return this.endX - this.startX;
19049      }
19050      getStartX() {
19051          return this.startX;
19052      }
19053      getEndX() {
19054          return this.endX;
19055      }
19056      getBucket() {
19057          return this.bucket;
19058      }
19059      getValue() {
19060          return this.value;
19061      }
19062      getRowNumber() {
19063          return this.rowNumber;
19064      }
19065      setRowNumber(rowNumber) {
19066          this.rowNumber = rowNumber;
19067      }
19068      //   @Override
19069      toString() {
19070          return this.rowNumber + '|' + this.value;
19071      }
19072  }
19073  Codeword.BARCODE_ROW_UNKNOWN = -1;
19074
19075  /*
19076  * Copyright 2013 ZXing authors
19077  *
19078  * Licensed under the Apache License, Version 2.0 (the "License");
19079  * you may not use this file except in compliance with the License.
19080  * You may obtain a copy of the License at
19081  *
19082  *      http://www.apache.org/licenses/LICENSE-2.0
19083  *
19084  * Unless required by applicable law or agreed to in writing, software
19085  * distributed under the License is distributed on an "AS IS" BASIS,
19086  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19087  * See the License for the specific language governing permissions and
19088  * limitations under the License.
19089  */
19090  /**
19091   * @author Guenther Grau
19092   * @author creatale GmbH ([email protected])
19093   */
19094  /*final*/ class PDF417CodewordDecoder {
19095      /* @note
19096       * this action have to be performed before first use of class
19097       * - static constructor
19098       * working with 32bit float (based from Java logic)
19099      */
19100      static initialize() {
19101          // Pre-computes the symbol ratio table.
19102          for ( /*int*/let i = 0; i < PDF417Common.SYMBOL_TABLE.length; i++) {
19103              let currentSymbol = PDF417Common.SYMBOL_TABLE[i];
19104              let currentBit = currentSymbol & 0x1;
19105              for ( /*int*/let j = 0; j < PDF417Common.BARS_IN_MODULE; j++) {
19106                  let size = 0.0;
19107                  while ((currentSymbol & 0x1) === currentBit) {
19108                      size += 1.0;
19109                      currentSymbol >>= 1;
19110                  }
19111                  currentBit = currentSymbol & 0x1;
19112                  if (!PDF417CodewordDecoder.RATIOS_TABLE[i]) {
19113                      PDF417CodewordDecoder.RATIOS_TABLE[i] = new Array(PDF417Common.BARS_IN_MODULE);
19114                  }
19115                  PDF417CodewordDecoder.RATIOS_TABLE[i][PDF417Common.BARS_IN_MODULE - j - 1] = Math.fround(size / PDF417Common.MODULES_IN_CODEWORD);
19116              }
19117          }
19118          this.bSymbolTableReady = true;
19119      }
19120      static getDecodedValue(moduleBitCount) {
19121          let decodedValue = PDF417CodewordDecoder.getDecodedCodewordValue(PDF417CodewordDecoder.sampleBitCounts(moduleBitCount));
19122          if (decodedValue !== -1) {
19123              return decodedValue;
19124          }
19125          return PDF417CodewordDecoder.getClosestDecodedValue(moduleBitCount);
19126      }
19127      static sampleBitCounts(moduleBitCount) {
19128          let bitCountSum = MathUtils.sum(moduleBitCount);
19129          let result = new Int32Array(PDF417Common.BARS_IN_MODULE);
19130          let bitCountIndex = 0;
19131          let sumPreviousBits = 0;
19132          for ( /*int*/let i = 0; i < PDF417Common.MODULES_IN_CODEWORD; i++) {
19133              let sampleIndex = bitCountSum / (2 * PDF417Common.MODULES_IN_CODEWORD) +
19134                  (i * bitCountSum) / PDF417Common.MODULES_IN_CODEWORD;
19135              if (sumPreviousBits + moduleBitCount[bitCountIndex] <= sampleIndex) {
19136                  sumPreviousBits += moduleBitCount[bitCountIndex];
19137                  bitCountIndex++;
19138              }
19139              result[bitCountIndex]++;
19140          }
19141          return result;
19142      }
19143      static getDecodedCodewordValue(moduleBitCount) {
19144          let decodedValue = PDF417CodewordDecoder.getBitValue(moduleBitCount);
19145          return PDF417Common.getCodeword(decodedValue) === -1 ? -1 : decodedValue;
19146      }
19147      static getBitValue(moduleBitCount) {
19148          let result = /*long*/
vendor: 13,445 bytes, lines 19148-19518
19148 0;
19149          for (let /*int*/ i = 0; i < moduleBitCount.length; i++) {
19150              for ( /*int*/let bit = 0; bit < moduleBitCount[i]; bit++) {
19151                  result = (result << 1) | (i % 2 === 0 ? 1 : 0);
19152              }
19153          }
19154          return Math.trunc(result);
19155      }
19156      // working with 32bit float (as in Java)
19157      static getClosestDecodedValue(moduleBitCount) {
19158          let bitCountSum = MathUtils.sum(moduleBitCount);
19159          let bitCountRatios = new Array(PDF417Common.BARS_IN_MODULE);
19160          if (bitCountSum > 1) {
19161              for (let /*int*/ i = 0; i < bitCountRatios.length; i++) {
19162                  bitCountRatios[i] = Math.fround(moduleBitCount[i] / bitCountSum);
19163              }
19164          }
19165          let bestMatchError = Float.MAX_VALUE;
19166          let bestMatch = -1;
19167          if (!this.bSymbolTableReady) {
19168              PDF417CodewordDecoder.initialize();
19169          }
19170          for ( /*int*/let j = 0; j < PDF417CodewordDecoder.RATIOS_TABLE.length; j++) {
19171              let error = 0.0;
19172              let ratioTableRow = PDF417CodewordDecoder.RATIOS_TABLE[j];
19173              for ( /*int*/let k = 0; k < PDF417Common.BARS_IN_MODULE; k++) {
19174                  let diff = Math.fround(ratioTableRow[k] - bitCountRatios[k]);
19175                  error += Math.fround(diff * diff);
19176                  if (error >= bestMatchError) {
19177                      break;
19178                  }
19179              }
19180              if (error < bestMatchError) {
19181                  bestMatchError = error;
19182                  bestMatch = PDF417Common.SYMBOL_TABLE[j];
19183              }
19184          }
19185          return bestMatch;
19186      }
19187  }
19188  // flag that the table is ready for use
19189  PDF417CodewordDecoder.bSymbolTableReady = false;
19190  PDF417CodewordDecoder.RATIOS_TABLE = new Array(PDF417Common.SYMBOL_TABLE.length).map(x => new Array(PDF417Common.BARS_IN_MODULE));
19191
19192  /*
19193   * Copyright 2013 ZXing authors
19194   *
19195   * Licensed under the Apache License, Version 2.0 (the "License");
19196   * you may not use this file except in compliance with the License.
19197   * You may obtain a copy of the License at
19198   *
19199   *      http://www.apache.org/licenses/LICENSE-2.0
19200   *
19201   * Unless required by applicable law or agreed to in writing, software
19202   * distributed under the License is distributed on an "AS IS" BASIS,
19203   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19204   * See the License for the specific language governing permissions and
19205   * limitations under the License.
19206   */
19207  // package com.google.zxing.pdf417;
19208  /**
19209   * @author Guenther Grau
19210   */
19211  /*public final*/ class PDF417ResultMetadata {
19212      constructor() {
19213          this.segmentCount = -1;
19214          this.fileSize = -1;
19215          this.timestamp = -1;
19216          this.checksum = -1;
19217      }
19218      /**
19219       * The Segment ID represents the segment of the whole file distributed over different symbols.
19220       *
19221       * @return File segment index
19222       */
19223      getSegmentIndex() {
19224          return this.segmentIndex;
19225      }
19226      setSegmentIndex(segmentIndex) {
19227          this.segmentIndex = segmentIndex;
19228      }
19229      /**
19230       * Is the same for each related PDF417 symbol
19231       *
19232       * @return File ID
19233       */
19234      getFileId() {
19235          return this.fileId;
19236      }
19237      setFileId(fileId) {
19238          this.fileId = fileId;
19239      }
19240      /**
19241       * @return always null
19242       * @deprecated use dedicated already parsed fields
19243       */
19244      //   @Deprecated
19245      getOptionalData() {
19246          return this.optionalData;
19247      }
19248      /**
19249       * @param optionalData old optional data format as int array
19250       * @deprecated parse and use new fields
19251       */
19252      //   @Deprecated
19253      setOptionalData(optionalData) {
19254          this.optionalData = optionalData;
19255      }
19256      /**
19257       * @return true if it is the last segment
19258       */
19259      isLastSegment() {
19260          return this.lastSegment;
19261      }
19262      setLastSegment(lastSegment) {
19263          this.lastSegment = lastSegment;
19264      }
19265      /**
19266       * @return count of segments, -1 if not set
19267       */
19268      getSegmentCount() {
19269          return this.segmentCount;
19270      }
19271      setSegmentCount(segmentCount /*int*/) {
19272          this.segmentCount = segmentCount;
19273      }
19274      getSender() {
19275          return this.sender || null;
19276      }
19277      setSender(sender) {
19278          this.sender = sender;
19279      }
19280      getAddressee() {
19281          return this.addressee || null;
19282      }
19283      setAddressee(addressee) {
19284          this.addressee = addressee;
19285      }
19286      /**
19287       * Filename of the encoded file
19288       *
19289       * @return filename
19290       */
19291      getFileName() {
19292          return this.fileName;
19293      }
19294      setFileName(fileName) {
19295          this.fileName = fileName;
19296      }
19297      /**
19298       * filesize in bytes of the encoded file
19299       *
19300       * @return filesize in bytes, -1 if not set
19301       */
19302      getFileSize() {
19303          return this.fileSize;
19304      }
19305      setFileSize(fileSize /*long*/) {
19306          this.fileSize = fileSize;
19307      }
19308      /**
19309       * 16-bit CRC checksum using CCITT-16
19310       *
19311       * @return crc checksum, -1 if not set
19312       */
19313      getChecksum() {
19314          return this.checksum;
19315      }
19316      setChecksum(checksum /*int*/) {
19317          this.checksum = checksum;
19318      }
19319      /**
19320       * unix epock timestamp, elapsed seconds since 1970-01-01
19321       *
19322       * @return elapsed seconds, -1 if not set
19323       */
19324      getTimestamp() {
19325          return this.timestamp;
19326      }
19327      setTimestamp(timestamp /*long*/) {
19328          this.timestamp = timestamp;
19329      }
19330  }
19331
19332  /**
19333   * Ponyfill for Java's Long class.
19334   */
19335  class Long {
19336      /**
19337       * Parses a string to a number, since JS has no really Int64.
19338       *
19339       * @param num Numeric string.
19340       * @param radix Destination radix.
19341       */
19342      static parseLong(num, radix = undefined) {
19343          return parseInt(num, radix);
19344      }
19345  }
19346
19347  /**
19348   * Custom Error class of type Exception.
19349   */
19350  class NullPointerException extends Exception {
19351  }
19352  NullPointerException.kind = 'NullPointerException';
19353
19354  /*
19355   * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
19356   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19357   *
19358   * This code is free software; you can redistribute it and/or modify it
19359   * under the terms of the GNU General Public License version 2 only, as
19360   * published by the Free Software Foundation.  Oracle designates this
19361   * particular file as subject to the "Classpath" exception as provided
19362   * by Oracle in the LICENSE file that accompanied this code.
19363   *
19364   * This code is distributed in the hope that it will be useful, but WITHOUT
19365   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19366   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19367   * version 2 for more details (a copy is included in the LICENSE file that
19368   * accompanied this code).
19369   *
19370   * You should have received a copy of the GNU General Public License version
19371   * 2 along with this work; if not, write to the Free Software Foundation,
19372   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19373   *
19374   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19375   * or visit www.oracle.com if you need additional information or have any
19376   * questions.
19377   */
19378  // package java.io;
19379  /**
19380   * This abstract class is the superclass of all classes representing
19381   * an output stream of bytes. An output stream accepts output bytes
19382   * and sends them to some sink.
19383   * <p>
19384   * Applications that need to define a subclass of
19385   * <code>OutputStream</code> must always provide at least a method
19386   * that writes one byte of output.
19387   *
19388   * @author  Arthur van Hoff
19389   * @see     java.io.BufferedOutputStream
19390   * @see     java.io.ByteArrayOutputStream
19391   * @see     java.io.DataOutputStream
19392   * @see     java.io.FilterOutputStream
19393   * @see     java.io.InputStream
19394   * @see     java.io.OutputStream#write(int)
19395   * @since   JDK1.0
19396   */
19397  /*public*/ class OutputStream /*implements Closeable, Flushable*/ {
19398      /**
19399       * Writes <code>b.length</code> bytes from the specified byte array
19400       * to this output stream. The general contract for <code>write(b)</code>
19401       * is that it should have exactly the same effect as the call
19402       * <code>write(b, 0, b.length)</code>.
19403       *
19404       * @param      b   the data.
19405       * @exception  IOException  if an I/O error occurs.
19406       * @see        java.io.OutputStream#write(byte[], int, int)
19407       */
19408      writeBytes(b) {
19409          this.writeBytesOffset(b, 0, b.length);
19410      }
19411      /**
19412       * Writes <code>len</code> bytes from the specified byte array
19413       * starting at offset <code>off</code> to this output stream.
19414       * The general contract for <code>write(b, off, len)</code> is that
19415       * some of the bytes in the array <code>b</code> are written to the
19416       * output stream in order; element <code>b[off]</code> is the first
19417       * byte written and <code>b[off+len-1]</code> is the last byte written
19418       * by this operation.
19419       * <p>
19420       * The <code>write</code> method of <code>OutputStream</code> calls
19421       * the write method of one argument on each of the bytes to be
19422       * written out. Subclasses are encouraged to override this method and
19423       * provide a more efficient implementation.
19424       * <p>
19425       * If <code>b</code> is <code>null</code>, a
19426       * <code>NullPointerException</code> is thrown.
19427       * <p>
19428       * If <code>off</code> is negative, or <code>len</code> is negative, or
19429       * <code>off+len</code> is greater than the length of the array
19430       * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> is thrown.
19431       *
19432       * @param      b     the data.
19433       * @param      off   the start offset in the data.
19434       * @param      len   the number of bytes to write.
19435       * @exception  IOException  if an I/O error occurs. In particular,
19436       *             an <code>IOException</code> is thrown if the output
19437       *             stream is closed.
19438       */
19439      writeBytesOffset(b, off, len) {
19440          if (b == null) {
19441              throw new NullPointerException();
19442          }
19443          else if ((off < 0) || (off > b.length) || (len < 0) ||
19444              ((off + len) > b.length) || ((off + len) < 0)) {
19445              throw new IndexOutOfBoundsException();
19446          }
19447          else if (len === 0) {
19448              return;
19449          }
19450          for (let i = 0; i < len; i++) {
19451              this.write(b[off + i]);
19452          }
19453      }
19454      /**
19455       * Flushes this output stream and forces any buffered output bytes
19456       * to be written out. The general contract of <code>flush</code> is
19457       * that calling it is an indication that, if any bytes previously
19458       * written have been buffered by the implementation of the output
19459       * stream, such bytes should immediately be written to their
19460       * intended destination.
19461       * <p>
19462       * If the intended destination of this stream is an abstraction provided by
19463       * the underlying operating system, for example a file, then flushing the
19464       * stream guarantees only that bytes previously written to the stream are
19465       * passed to the operating system for writing; it does not guarantee that
19466       * they are actually written to a physical device such as a disk drive.
19467       * <p>
19468       * The <code>flush</code> method of <code>OutputStream</code> does nothing.
19469       *
19470       * @exception  IOException  if an I/O error occurs.
19471       */
19472      flush() {
19473      }
19474      /**
19475       * Closes this output stream and releases any system resources
19476       * associated with this stream. The general contract of <code>close</code>
19477       * is that it closes the output stream. A closed stream cannot perform
19478       * output operations and cannot be reopened.
19479       * <p>
19480       * The <code>close</code> method of <code>OutputStream</code> does nothing.
19481       *
19482       * @exception  IOException  if an I/O error occurs.
19483       */
19484      close() {
19485      }
19486  }
19487
19488  /**
19489   * Custom Error class of type Exception.
19490   */
19491  class OutOfMemoryError extends Exception {
19492  }
19493
19494  /*
19495   * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
19496   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19497   *
19498   * This code is free software; you can redistribute it and/or modify it
19499   * under the terms of the GNU General Public License version 2 only, as
19500   * published by the Free Software Foundation.  Oracle designates this
19501   * particular file as subject to the "Classpath" exception as provided
19502   * by Oracle in the LICENSE file that accompanied this code.
19503   *
19504   * This code is distributed in the hope that it will be useful, but WITHOUT
19505   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19506   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19507   * version 2 for more details (a copy is included in the LICENSE file that
19508   * accompanied this code).
19509   *
19510   * You should have received a copy of the GNU General Public License version
19511   * 2 along with this work; if not, write to the Free Software Foundation,
19512   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19513   *
19514   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19515   * or visit www.oracle.com if you need additional information or have any
19516   * questions.
19517   */
19518  /
19518**
19519   * This class implements an output stream in which the data is
19520   * written into a byte array. The buffer automatically grows as data
19521   * is written to it.
19522   * The data can be retrieved using <code>toByteArray()</code> and
19523   * <code>toString()</code>.
19524   * <p>
19525   * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
19526   * this class can be called after the stream has been closed without
19527   * generating an <tt>IOException</tt>.
19528   *
19529   * @author  Arthur van Hoff
19530   * @since   JDK1.0
19531   */
19532  /*public*/ class ByteArrayOutputStream extends OutputStream {
19533      /**
19534       * Creates a new byte array output stream. The buffer capacity is
19535       * initially 32 bytes, though its size increases if necessary.
19536       */
19537      // public constructor() {
19538      //     this(32);
19539      // }
19540      /**
19541       * Creates a new byte array output stream, with a buffer capacity of
19542       * the specified size, in bytes.
19543       *
19544       * @param   size   the initial size.
19545       * @exception  IllegalArgumentException if size is negative.
19546       */
19547      constructor(size = 32) {
19548          super();
19549          /**
19550           * The number of valid bytes in the buffer.
19551           */
19552          this.count = 0;
19553          if (size < 0) {
19554              throw new IllegalArgumentException('Negative initial size: '
19555                  + size);
19556          }
19557          this.buf = new Uint8Array(size);
19558      }
19559      /**
19560       * Increases the capacity if necessary to ensure that it can hold
19561       * at least the number of elements specified by the minimum
19562       * capacity argument.
19563       *
19564       * @param minCapacity the desired minimum capacity
19565       * @throws OutOfMemoryError if {@code minCapacity < 0}.  This is
19566       * interpreted as a request for the unsatisfiably large capacity
19567       * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
19568       */
19569      ensureCapacity(minCapacity) {
19570          // overflow-conscious code
19571          if (minCapacity - this.buf.length > 0)
19572              this.grow(minCapacity);
19573      }
19574      /**
19575       * Increases the capacity to ensure that it can hold at least the
19576       * number of elements specified by the minimum capacity argument.
19577       *
19578       * @param minCapacity the desired minimum capacity
19579       */
19580      grow(minCapacity) {
19581          // overflow-conscious code
19582          let oldCapacity = this.buf.length;
19583          let newCapacity = oldCapacity << 1;
19584          if (newCapacity - minCapacity < 0)
19585              newCapacity = minCapacity;
19586          if (newCapacity < 0) {
19587              if (minCapacity < 0) // overflow
19588                  throw new OutOfMemoryError();
19589              newCapacity = Integer.MAX_VALUE;
19590          }
19591          this.buf = Arrays.copyOfUint8Array(this.buf, newCapacity);
19592      }
19593      /**
19594       * Writes the specified byte to this byte array output stream.
19595       *
19596       * @param   b   the byte to be written.
19597       */
19598      write(b) {
19599          this.ensureCapacity(this.count + 1);
19600          this.buf[this.count] = /*(byte)*/ b;
19601          this.count += 1;
19602      }
19603      /**
19604       * Writes <code>len</code> bytes from the specified byte array
19605       * starting at offset <code>off</code> to this byte array output stream.
19606       *
19607       * @param   b     the data.
19608       * @param   off   the start offset in the data.
19609       * @param   len   the number of bytes to write.
19610       */
19611      writeBytesOffset(b, off, len) {
19612          if ((off < 0) || (off > b.length) || (len < 0) ||
19613              ((off + len) - b.length > 0)) {
19614              throw new IndexOutOfBoundsException();
19615          }
19616          this.ensureCapacity(this.count + len);
19617          System.arraycopy(b, off, this.buf, this.count, len);
19618          this.count += len;
19619      }
19620      /**
19621       * Writes the complete contents of this byte array output stream to
19622       * the specified output stream argument, as if by calling the output
19623       * stream's write method using <code>out.write(buf, 0, count)</code>.
19624       *
19625       * @param      out   the output stream to which to write the data.
19626       * @exception  IOException  if an I/O error occurs.
19627       */
19628      writeTo(out) {
19629          out.writeBytesOffset(this.buf, 0, this.count);
19630      }
19631      /**
19632       * Resets the <code>count</code> field of this byte array output
19633       * stream to zero, so that all currently accumulated output in the
19634       * output stream is discarded. The output stream can be used again,
19635       * reusing the already allocated buffer space.
19636       *
19637       * @see     java.io.ByteArrayInputStream#count
19638       */
19639      reset() {
19640          this.count = 0;
19641      }
19642      /**
19643       * Creates a newly allocated byte array. Its size is the current
19644       * size of this output stream and the valid contents of the buffer
19645       * have been copied into it.
19646       *
19647       * @return  the current contents of this output stream, as a byte array.
19648       * @see     java.io.ByteArrayOutputStream#size()
19649       */
19650      toByteArray() {
19651          return Arrays.copyOfUint8Array(this.buf, this.count);
19652      }
19653      /**
19654       * Returns the current size of the buffer.
19655       *
19656       * @return  the value of the <code>count</code> field, which is the number
19657       *          of valid bytes in this output stream.
19658       * @see     java.io.ByteArrayOutputStream#count
19659       */
19660      size() {
19661          return this.count;
19662      }
19663      toString(param) {
19664          if (!param) {
19665              return this.toString_void();
19666          }
19667          if (typeof param === 'string') {
19668              return this.toString_string(param);
19669          }
19670          return this.toString_number(param);
19671      }
19672      /**
19673       * Converts the buffer's contents into a string decoding bytes using the
19674       * platform's default character set. The length of the new <tt>String</tt>
19675       * is a function of the character set, and hence may not be equal to the
19676       * size of the buffer.
19677       *
19678       * <p> This method always replaces malformed-input and unmappable-character
19679       * sequences with the default replacement string for the platform's
19680       * default character set. The {@linkplain java.nio.charset.CharsetDecoder}
19681       * class should be used when more control over the decoding process is
19682       * required.
19683       *
19684       * @return String decoded from the buffer's contents.
19685       * @since  JDK1.1
19686       */
19687      toString_void() {
19688          return new String(this.buf /*, 0, this.count*/).toString();
19689      }
19690      /**
19691       * Converts the buffer's contents into a string by decoding the bytes using
19692       * the specified {@link java.nio.charset.Charset charsetName}. The length of
19693       * the new <tt>String</tt> is a function of the charset, and hence may not be
19694       * equal to the length of the byte array.
19695       *
19696       * <p> This method always replaces malformed-input and unmappable-character
19697       * sequences with this charset's default replacement string. The {@link
19698       * java.nio.charset.CharsetDecoder} class should be used when more control
19699       * over the decoding process is required.
19700       *
19701       * @param  charsetName  the name of a supported
19702       *              {@linkplain java.nio.charset.Charset </code>charset<code>}
19703       * @return String decoded from the buffer's contents.
19704       * @exception  UnsupportedEncodingException
19705       *             If the named charset is not supported
19706       * @since   JDK1.1
19707       */
19708      toString_string(charsetName) {
19709          return new String(this.buf /*, 0, this.count, charsetName*/).toString();
19710      }
19711      /**
19712       * Creates a newly allocated string. Its size is the current size of
19713       * the output stream and the valid contents of the buffer have been
19714       * copied into it. Each character <i>c</i> in the resulting string is
19715       * constructed from the corresponding element <i>b</i> in the byte
19716       * array such that:
19717       * <blockquote><pre>
19718       *     c == (char)(((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
19719       * </pre></blockquote>
19720       *
19721       * @deprecated This method does not properly convert bytes into characters.
19722       * As of JDK&nbsp;1.1, the preferred way to do this is via the
19723       * <code>toString(String enc)</code> method, which takes an encoding-name
19724       * argument, or the <code>toString()</code> method, which uses the
19725       * platform's default character encoding.
19726       *
19727       * @param      hibyte    the high byte of each resulting Unicode character.
19728       * @return     the current contents of the output stream, as a string.
19729       * @see        java.io.ByteArrayOutputStream#size()
19730       * @see        java.io.ByteArrayOutputStream#toString(String)
19731       * @see        java.io.ByteArrayOutputStream#toString()
19732       */
19733      // @Deprecated
19734      toString_number(hibyte) {
19735          return new String(this.buf /*, hibyte, 0, this.count*/).toString();
19736      }
19737      /**
19738       * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
19739       * this class can be called after the stream has been closed without
19740       * generating an <tt>IOException</tt>.
19741       * <p>
19742       *
19743       * @throws IOException
19744       */
19745      close() {
19746      }
19747  }
19748
19749  /*
19750   * Copyright 2009 ZXing authors
19751   *
19752   * Licensed under the Apache License, Version 2.0 (the "License");
19753   * you may not use this file except in compliance with the License.
19754   * You may obtain a copy of the License at
19755   *
19756   *      http://www.apache.org/licenses/LICENSE-2.0
19757   *
19758   * Unless required by applicable law or agreed to in writing, software
19759   * distributed under the License is distributed on an "AS IS" BASIS,
19760   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19761   * See the License for the specific language governing permissions and
19762   * limitations under the License.
19763   */
19764  /*private*/ var Mode$1;
19765  (function (Mode) {
19766      Mode[Mode["ALPHA"] = 0] = "ALPHA";
19767      Mode[Mode["LOWER"] = 1] = "LOWER";
19768      Mode[Mode["MIXED"] = 2] = "MIXED";
19769      Mode[Mode["PUNCT"] = 3] = "PUNCT";
19770      Mode[Mode["ALPHA_SHIFT"] = 4] = "ALPHA_SHIFT";
19771      Mode[Mode["PUNCT_SHIFT"] = 5] = "PUNCT_SHIFT";
19772  })(Mode$1 || (Mode$1 = {}));
19773  /**
19774   * Indirectly access the global BigInt constructor, it
19775   * allows browsers that doesn't support BigInt to run
19776   * the library without breaking due to "undefined BigInt"
19777   * errors.
19778   */
19779  function getBigIntConstructor() {
19780      if (typeof window !== 'undefined') {
19781          return window['BigInt'] || null;
19782      }
19783      if (typeof global !== 'undefined') {
19784          return global['BigInt'] || null;
19785      }
19786      if (typeof self !== 'undefined') {
19787          return self['BigInt'] || null;
19788      }
19789      throw new Error('Can\'t search globals for BigInt!');
19790  }
19791  /**
19792   * Used to store the BigInt constructor.
19793   */
19794  let BigInteger;
19795  /**
19796   * This function creates a bigint value. It allows browsers
19797   * that doesn't support BigInt to run the rest of the library
19798   * by not directly accessing the BigInt constructor.
19799   */
19800  function createBigInt(num) {
19801      if (typeof BigInteger === 'undefined') {
19802          BigInteger = getBigIntConstructor();
19803      }
19804      if (BigInteger === null) {
19805          throw new Error('BigInt is not supported!');
19806      }
19807      return BigInteger(num);
19808  }
19809  function getEXP900() {
19810      // in Java - array with length = 16
19811      let EXP900 = [];
19812      EXP900[0] = createBigInt(1);
19813      let nineHundred = createBigInt(900);
19814      EXP900[1] = nineHundred;
19815      // in Java - array with length = 16
19816      for (let i /*int*/ = 2; i < 16; i++) {
19817          EXP900[i] = EXP900[i - 1] * nineHundred;
19818      }
19819      return EXP900;
19820  }
19821  /**
19822   * <p>This class contains the methods for decoding the PDF417 codewords.</p>
19823   *
19824   * @author SITA Lab ([email protected])
19825   * @author Guenther Grau
19826   */
19827  /*final*/
vendor: 14,720 bytes, lines 19827-20086
19827 class DecodedBitStreamParser {
19828      //   private DecodedBitStreamParser() {
19829      // }
19830      /**
19831       *
19832       * @param codewords
19833       * @param ecLevel
19834       *
19835       * @throws FormatException
19836       */
19837      static decode(codewords, ecLevel) {
19838          // pass encoding to result (will be used for decode symbols in byte mode)
19839          let result = new StringBuilder('');
19840          // let encoding: Charset = StandardCharsets.ISO_8859_1;
19841          let encoding = CharacterSetECI.ISO8859_1;
19842          /**
19843           * @note the next command is specific from this TypeScript library
19844           * because TS can't properly cast some values to char and
19845           * convert it to string later correctly due to encoding
19846           * differences from Java version. As reported here:
19847           * https://github.com/zxing-js/library/pull/264/files#r382831593
19848           */
19849          result.enableDecoding(encoding);
19850          // Get compaction mode
19851          let codeIndex = 1;
19852          let code = codewords[codeIndex++];
19853          let resultMetadata = new PDF417ResultMetadata();
19854          while (codeIndex < codewords[0]) {
19855              switch (code) {
19856                  case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
19857                      codeIndex = DecodedBitStreamParser.textCompaction(codewords, codeIndex, result);
19858                      break;
19859                  case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH:
19860                  case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH_6:
19861                      codeIndex = DecodedBitStreamParser.byteCompaction(code, codewords, encoding, codeIndex, result);
19862                      break;
19863                  case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
19864                      result.append(/*(char)*/ codewords[codeIndex++]);
19865                      break;
19866                  case DecodedBitStreamParser.NUMERIC_COMPACTION_MODE_LATCH:
19867                      codeIndex = DecodedBitStreamParser.numericCompaction(codewords, codeIndex, result);
19868                      break;
19869                  case DecodedBitStreamParser.ECI_CHARSET:
19870                      CharacterSetECI.getCharacterSetECIByValue(codewords[codeIndex++]);
19871                      // encoding = Charset.forName(charsetECI.getName());
19872                      break;
19873                  case DecodedBitStreamParser.ECI_GENERAL_PURPOSE:
19874                      // Can't do anything with generic ECI; skip its 2 characters
19875                      codeIndex += 2;
19876                      break;
19877                  case DecodedBitStreamParser.ECI_USER_DEFINED:
19878                      // Can't do anything with user ECI; skip its 1 character
19879                      codeIndex++;
19880                      break;
19881                  case DecodedBitStreamParser.BEGIN_MACRO_PDF417_CONTROL_BLOCK:
19882                      codeIndex = DecodedBitStreamParser.decodeMacroBlock(codewords, codeIndex, resultMetadata);
19883                      break;
19884                  case DecodedBitStreamParser.BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
19885                  case DecodedBitStreamParser.MACRO_PDF417_TERMINATOR:
19886                      // Should not see these outside a macro block
19887                      throw new FormatException();
19888                  default:
19889                      // Default to text compaction. During testing numerous barcodes
19890                      // appeared to be missing the starting mode. In these cases defaulting
19891                      // to text compaction seems to work.
19892                      codeIndex--;
19893                      codeIndex = DecodedBitStreamParser.textCompaction(codewords, codeIndex, result);
19894                      break;
19895              }
19896              if (codeIndex < codewords.length) {
19897                  code = codewords[codeIndex++];
19898              }
19899              else {
19900                  throw FormatException.getFormatInstance();
19901              }
19902          }
19903          if (result.length() === 0) {
19904              throw FormatException.getFormatInstance();
19905          }
19906          let decoderResult = new DecoderResult(null, result.toString(), null, ecLevel);
19907          decoderResult.setOther(resultMetadata);
19908          return decoderResult;
19909      }
19910      /**
19911       *
19912       * @param int
19913       * @param param1
19914       * @param codewords
19915       * @param int
19916       * @param codeIndex
19917       * @param PDF417ResultMetadata
19918       * @param resultMetadata
19919       *
19920       * @throws FormatException
19921       */
19922      // @SuppressWarnings("deprecation")
19923      static decodeMacroBlock(codewords, codeIndex, resultMetadata) {
19924          if (codeIndex + DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) {
19925              // we must have at least two bytes left for the segment index
19926              throw FormatException.getFormatInstance();
19927          }
19928          let segmentIndexArray = new Int32Array(DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS);
19929          for (let i /*int*/ = 0; i < DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
19930              segmentIndexArray[i] = codewords[codeIndex];
19931          }
19932          resultMetadata.setSegmentIndex(Integer.parseInt(DecodedBitStreamParser.decodeBase900toBase10(segmentIndexArray, DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS)));
19933          let fileId = new StringBuilder();
19934          codeIndex = DecodedBitStreamParser.textCompaction(codewords, codeIndex, fileId);
19935          resultMetadata.setFileId(fileId.toString());
19936          let optionalFieldsStart = -1;
19937          if (codewords[codeIndex] === DecodedBitStreamParser.BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
19938              optionalFieldsStart = codeIndex + 1;
19939          }
19940          while (codeIndex < codewords[0]) {
19941              switch (codewords[codeIndex]) {
19942                  case DecodedBitStreamParser.BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
19943                      codeIndex++;
19944                      switch (codewords[codeIndex]) {
19945                          case DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME:
19946                              let fileName = new StringBuilder();
19947                              codeIndex = DecodedBitStreamParser.textCompaction(codewords, codeIndex + 1, fileName);
19948                              resultMetadata.setFileName(fileName.toString());
19949                              break;
19950                          case DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_SENDER:
19951                              let sender = new StringBuilder();
19952                              codeIndex = DecodedBitStreamParser.textCompaction(codewords, codeIndex + 1, sender);
19953                              resultMetadata.setSender(sender.toString());
19954                              break;
19955                          case DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE:
19956                              let addressee = new StringBuilder();
19957                              codeIndex = DecodedBitStreamParser.textCompaction(codewords, codeIndex + 1, addressee);
19958                              resultMetadata.setAddressee(addressee.toString());
19959                              break;
19960                          case DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT:
19961                              let segmentCount = new StringBuilder();
19962                              codeIndex = DecodedBitStreamParser.numericCompaction(codewords, codeIndex + 1, segmentCount);
19963                              resultMetadata.setSegmentCount(Integer.parseInt(segmentCount.toString()));
19964                              break;
19965                          case DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP:
19966                              let timestamp = new StringBuilder();
19967                              codeIndex = DecodedBitStreamParser.numericCompaction(codewords, codeIndex + 1, timestamp);
19968                              resultMetadata.setTimestamp(Long.parseLong(timestamp.toString()));
19969                              break;
19970                          case DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM:
19971                              let checksum = new StringBuilder();
19972                              codeIndex = DecodedBitStreamParser.numericCompaction(codewords, codeIndex + 1, checksum);
19973                              resultMetadata.setChecksum(Integer.parseInt(checksum.toString()));
19974                              break;
19975                          case DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE:
19976                              let fileSize = new StringBuilder();
19977                              codeIndex = DecodedBitStreamParser.numericCompaction(codewords, codeIndex + 1, fileSize);
19978                              resultMetadata.setFileSize(Long.parseLong(fileSize.toString()));
19979                              break;
19980                          default:
19981                              throw FormatException.getFormatInstance();
19982                      }
19983                      break;
19984                  case DecodedBitStreamParser.MACRO_PDF417_TERMINATOR:
19985                      codeIndex++;
19986                      resultMetadata.setLastSegment(true);
19987                      break;
19988                  default:
19989                      throw FormatException.getFormatInstance();
19990              }
19991          }
19992          // copy optional fields to additional options
19993          if (optionalFieldsStart !== -1) {
19994              let optionalFieldsLength = codeIndex - optionalFieldsStart;
19995              if (resultMetadata.isLastSegment()) {
19996                  // do not include terminator
19997                  optionalFieldsLength--;
19998              }
19999              resultMetadata.setOptionalData(Arrays.copyOfRange(codewords, optionalFieldsStart, optionalFieldsStart + optionalFieldsLength));
20000          }
20001          return codeIndex;
20002      }
20003      /**
20004       * Text Compaction mode (see 5.4.1.5) permits all printable ASCII characters to be
20005       * encoded, i.e. values 32 - 126 inclusive in accordance with ISO/IEC 646 (IRV), as
20006       * well as selected control characters.
20007       *
20008       * @param codewords The array of codewords (data + error)
20009       * @param codeIndex The current index into the codeword array.
20010       * @param result    The decoded data is appended to the result.
20011       * @return The next index into the codeword array.
20012       */
20013      static textCompaction(codewords, codeIndex, result) {
20014          // 2 character per codeword
20015          let textCompactionData = new Int32Array((codewords[0] - codeIndex) * 2);
20016          // Used to hold the byte compaction value if there is a mode shift
20017          let byteCompactionData = new Int32Array((codewords[0] - codeIndex) * 2);
20018          let index = 0;
20019          let end = false;
20020          while ((codeIndex < codewords[0]) && !end) {
20021              let code = codewords[codeIndex++];
20022              if (code < DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH) {
20023                  textCompactionData[index] = code / 30;
20024                  textCompactionData[index + 1] = code % 30;
20025                  index += 2;
20026              }
20027              else {
20028                  switch (code) {
20029                      case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20030                          // reinitialize text compaction mode to alpha sub mode
20031                          textCompactionData[index++] = DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH;
20032                          break;
20033                      case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH:
20034                      case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH_6:
20035                      case DecodedBitStreamParser.NUMERIC_COMPACTION_MODE_LATCH:
20036                      case DecodedBitStreamParser.BEGIN_MACRO_PDF417_CONTROL_BLOCK:
20037                      case DecodedBitStreamParser.BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
20038                      case DecodedBitStreamParser.MACRO_PDF417_TERMINATOR:
20039                          codeIndex--;
20040                          end = true;
20041                          break;
20042                      case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
20043                          // The Mode Shift codeword 913 shall cause a temporary
20044                          // switch from Text Compaction mode to Byte Compaction mode.
20045                          // This switch shall be in effect for only the next codeword,
20046                          // after which the mode shall revert to the prevailing sub-mode
20047                          // of the Text Compaction mode. Codeword 913 is only available
20048                          // in Text Compaction mode; its use is described in 5.4.2.4.
20049                          textCompactionData[index] = DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE;
20050                          code = codewords[codeIndex++];
20051                          byteCompactionData[index] = code;
20052                          index++;
20053                          break;
20054                  }
20055              }
20056          }
20057          DecodedBitStreamParser.decodeTextCompaction(textCompactionData, byteCompactionData, index, result);
20058          return codeIndex;
20059      }
20060      /**
20061       * The Text Compaction mode includes all the printable ASCII characters
20062       * (i.e. values from 32 to 126) and three ASCII control characters: HT or tab
20063       * (9: e), LF or line feed (10: e), and CR or carriage
20064       * return (13: e). The Text Compaction mode also includes various latch
20065       * and shift characters which are used exclusively within the mode. The Text
20066       * Compaction mode encodes up to 2 characters per codeword. The compaction rules
20067       * for converting data into PDF417 codewords are defined in 5.4.2.2. The sub-mode
20068       * switches are defined in 5.4.2.3.
20069       *
20070       * @param textCompactionData The text compaction data.
20071       * @param byteCompactionData The byte compaction data if there
20072       *                           was a mode shift.
20073       * @param length             The size of the text compaction and byte compaction data.
20074       * @param result             The decoded data is appended to the result.
20075       */
20076      static decodeTextCompaction(textCompactionData, byteCompactionData, length, result) {
20077          // Beginning from an initial state of the Alpha sub-mode
20078          // The default compaction mode for PDF417 in effect at the start of each symbol shall always be Text
20079          // Compaction mode Alpha sub-mode (alphabetic: uppercase). A latch codeword from another mode to the Text
20080          // Compaction mode shall always switch to the Text Compaction Alpha sub-mode.
20081          let subMode = Mode$1.ALPHA;
20082          let priorToShiftMode = Mode$1.ALPHA;
20083          let i = 0;
20084          while (i < length) {
20085              let subModeCh = textCompactionData[i];
20086              let ch = 
20086/*char*/
vendor: 9,215 bytes, lines 20086-20268
20086 '';
20087              switch (subMode) {
20088                  case Mode$1.ALPHA:
20089                      // Alpha (alphabetic: uppercase)
20090                      if (subModeCh < 26) {
20091                          // Upper case Alpha Character
20092                          // Note: 65 = 'A' ASCII -> there is byte code of symbol
20093                          ch = /*(char)('A' + subModeCh) */ String.fromCharCode(65 + subModeCh);
20094                      }
20095                      else {
20096                          switch (subModeCh) {
20097                              case 26:
20098                                  ch = ' ';
20099                                  break;
20100                              case DecodedBitStreamParser.LL:
20101                                  subMode = Mode$1.LOWER;
20102                                  break;
20103                              case DecodedBitStreamParser.ML:
20104                                  subMode = Mode$1.MIXED;
20105                                  break;
20106                              case DecodedBitStreamParser.PS:
20107                                  // Shift to punctuation
20108                                  priorToShiftMode = subMode;
20109                                  subMode = Mode$1.PUNCT_SHIFT;
20110                                  break;
20111                              case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
20112                                  result.append(/*(char)*/ byteCompactionData[i]);
20113                                  break;
20114                              case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20115                                  subMode = Mode$1.ALPHA;
20116                                  break;
20117                          }
20118                      }
20119                      break;
20120                  case Mode$1.LOWER:
20121                      // Lower (alphabetic: lowercase)
20122                      if (subModeCh < 26) {
20123                          ch = /*(char)('a' + subModeCh)*/ String.fromCharCode(97 + subModeCh);
20124                      }
20125                      else {
20126                          switch (subModeCh) {
20127                              case 26:
20128                                  ch = ' ';
20129                                  break;
20130                              case DecodedBitStreamParser.AS:
20131                                  // Shift to alpha
20132                                  priorToShiftMode = subMode;
20133                                  subMode = Mode$1.ALPHA_SHIFT;
20134                                  break;
20135                              case DecodedBitStreamParser.ML:
20136                                  subMode = Mode$1.MIXED;
20137                                  break;
20138                              case DecodedBitStreamParser.PS:
20139                                  // Shift to punctuation
20140                                  priorToShiftMode = subMode;
20141                                  subMode = Mode$1.PUNCT_SHIFT;
20142                                  break;
20143                              case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
20144                                  // TODO Does this need to use the current character encoding? See other occurrences below
20145                                  result.append(/*(char)*/ byteCompactionData[i]);
20146                                  break;
20147                              case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20148                                  subMode = Mode$1.ALPHA;
20149                                  break;
20150                          }
20151                      }
20152                      break;
20153                  case Mode$1.MIXED:
20154                      // Mixed (punctuation: e)
20155                      if (subModeCh < DecodedBitStreamParser.PL) {
20156                          ch = DecodedBitStreamParser.MIXED_CHARS[subModeCh];
20157                      }
20158                      else {
20159                          switch (subModeCh) {
20160                              case DecodedBitStreamParser.PL:
20161                                  subMode = Mode$1.PUNCT;
20162                                  break;
20163                              case 26:
20164                                  ch = ' ';
20165                                  break;
20166                              case DecodedBitStreamParser.LL:
20167                                  subMode = Mode$1.LOWER;
20168                                  break;
20169                              case DecodedBitStreamParser.AL:
20170                                  subMode = Mode$1.ALPHA;
20171                                  break;
20172                              case DecodedBitStreamParser.PS:
20173                                  // Shift to punctuation
20174                                  priorToShiftMode = subMode;
20175                                  subMode = Mode$1.PUNCT_SHIFT;
20176                                  break;
20177                              case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
20178                                  result.append(/*(char)*/ byteCompactionData[i]);
20179                                  break;
20180                              case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20181                                  subMode = Mode$1.ALPHA;
20182                                  break;
20183                          }
20184                      }
20185                      break;
20186                  case Mode$1.PUNCT:
20187                      // Punctuation
20188                      if (subModeCh < DecodedBitStreamParser.PAL) {
20189                          ch = DecodedBitStreamParser.PUNCT_CHARS[subModeCh];
20190                      }
20191                      else {
20192                          switch (subModeCh) {
20193                              case DecodedBitStreamParser.PAL:
20194                                  subMode = Mode$1.ALPHA;
20195                                  break;
20196                              case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
20197                                  result.append(/*(char)*/ byteCompactionData[i]);
20198                                  break;
20199                              case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20200                                  subMode = Mode$1.ALPHA;
20201                                  break;
20202                          }
20203                      }
20204                      break;
20205                  case Mode$1.ALPHA_SHIFT:
20206                      // Restore sub-mode
20207                      subMode = priorToShiftMode;
20208                      if (subModeCh < 26) {
20209                          ch = /*(char)('A' + subModeCh)*/ String.fromCharCode(65 + subModeCh);
20210                      }
20211                      else {
20212                          switch (subModeCh) {
20213                              case 26:
20214                                  ch = ' ';
20215                                  break;
20216                              case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20217                                  subMode = Mode$1.ALPHA;
20218                                  break;
20219                          }
20220                      }
20221                      break;
20222                  case Mode$1.PUNCT_SHIFT:
20223                      // Restore sub-mode
20224                      subMode = priorToShiftMode;
20225                      if (subModeCh < DecodedBitStreamParser.PAL) {
20226                          ch = DecodedBitStreamParser.PUNCT_CHARS[subModeCh];
20227                      }
20228                      else {
20229                          switch (subModeCh) {
20230                              case DecodedBitStreamParser.PAL:
20231                                  subMode = Mode$1.ALPHA;
20232                                  break;
20233                              case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
20234                                  // PS before Shift-to-Byte is used as a padding character,
20235                                  // see 5.4.2.4 of the specification
20236                                  result.append(/*(char)*/ byteCompactionData[i]);
20237                                  break;
20238                              case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20239                                  subMode = Mode$1.ALPHA;
20240                                  break;
20241                          }
20242                      }
20243                      break;
20244              }
20245              // if (ch !== 0) {
20246              if (ch !== '') {
20247                  // Append decoded character to result
20248                  result.append(ch);
20249              }
20250              i++;
20251          }
20252      }
20253      /**
20254       * Byte Compaction mode (see 5.4.3) permits all 256 possible 8-bit byte values to be encoded.
20255       * This includes all ASCII characters value 0 to 127 inclusive and provides for international
20256       * character set support.
20257       *
20258       * @param mode      The byte compaction mode i.e. 901 or 924
20259       * @param codewords The array of codewords (data + error)
20260       * @param encoding  Currently active character encoding
20261       * @param codeIndex The current index into the codeword array.
20262       * @param result    The decoded data is appended to the result.
20263       * @return The next index into the codeword array.
20264       */
20265      static /*int*/ byteCompaction(mode, codewords, encoding, codeIndex, result) {
20266          let decodedBytes = new ByteArrayOutputStream();
20267          let count = 0;
20268          let value = 
20268/*long*/
vendor: 12,490 bytes, lines 20268-20517
20268 0;
20269          let end = false;
20270          switch (mode) {
20271              case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH:
20272                  // Total number of Byte Compaction characters to be encoded
20273                  // is not a multiple of 6
20274                  let byteCompactedCodewords = new Int32Array(6);
20275                  let nextCode = codewords[codeIndex++];
20276                  while ((codeIndex < codewords[0]) && !end) {
20277                      byteCompactedCodewords[count++] = nextCode;
20278                      // Base 900
20279                      value = 900 * value + nextCode;
20280                      nextCode = codewords[codeIndex++];
20281                      // perhaps it should be ok to check only nextCode >= TEXT_COMPACTION_MODE_LATCH
20282                      switch (nextCode) {
20283                          case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20284                          case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH:
20285                          case DecodedBitStreamParser.NUMERIC_COMPACTION_MODE_LATCH:
20286                          case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH_6:
20287                          case DecodedBitStreamParser.BEGIN_MACRO_PDF417_CONTROL_BLOCK:
20288                          case DecodedBitStreamParser.BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
20289                          case DecodedBitStreamParser.MACRO_PDF417_TERMINATOR:
20290                              codeIndex--;
20291                              end = true;
20292                              break;
20293                          default:
20294                              if ((count % 5 === 0) && (count > 0)) {
20295                                  // Decode every 5 codewords
20296                                  // Convert to Base 256
20297                                  for (let j /*int*/ = 0; j < 6; ++j) {
20298                                      /* @note
20299                                       * JavaScript stores numbers as 64 bits floating point numbers, but all bitwise operations are performed on 32 bits binary numbers.
20300                                       * So the next bitwise operation could not be done with simple numbers
20301                                       */
20302                                      decodedBytes.write(/*(byte)*/ Number(createBigInt(value) >> createBigInt(8 * (5 - j))));
20303                                  }
20304                                  value = 0;
20305                                  count = 0;
20306                              }
20307                              break;
20308                      }
20309                  }
20310                  // if the end of all codewords is reached the last codeword needs to be added
20311                  if (codeIndex === codewords[0] && nextCode < DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH) {
20312                      byteCompactedCodewords[count++] = nextCode;
20313                  }
20314                  // If Byte Compaction mode is invoked with codeword 901,
20315                  // the last group of codewords is interpreted directly
20316                  // as one byte per codeword, without compaction.
20317                  for (let i /*int*/ = 0; i < count; i++) {
20318                      decodedBytes.write(/*(byte)*/ byteCompactedCodewords[i]);
20319                  }
20320                  break;
20321              case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH_6:
20322                  // Total number of Byte Compaction characters to be encoded
20323                  // is an integer multiple of 6
20324                  while (codeIndex < codewords[0] && !end) {
20325                      let code = codewords[codeIndex++];
20326                      if (code < DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH) {
20327                          count++;
20328                          // Base 900
20329                          value = 900 * value + code;
20330                      }
20331                      else {
20332                          switch (code) {
20333                              case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20334                              case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH:
20335                              case DecodedBitStreamParser.NUMERIC_COMPACTION_MODE_LATCH:
20336                              case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH_6:
20337                              case DecodedBitStreamParser.BEGIN_MACRO_PDF417_CONTROL_BLOCK:
20338                              case DecodedBitStreamParser.BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
20339                              case DecodedBitStreamParser.MACRO_PDF417_TERMINATOR:
20340                                  codeIndex--;
20341                                  end = true;
20342                                  break;
20343                          }
20344                      }
20345                      if ((count % 5 === 0) && (count > 0)) {
20346                          // Decode every 5 codewords
20347                          // Convert to Base 256
20348                          /* @note
20349                           * JavaScript stores numbers as 64 bits floating point numbers, but all bitwise operations are performed on 32 bits binary numbers.
20350                           * So the next bitwise operation could not be done with simple numbers
20351                          */
20352                          for (let j /*int*/ = 0; j < 6; ++j) {
20353                              decodedBytes.write(/*(byte)*/ Number(createBigInt(value) >> createBigInt(8 * (5 - j))));
20354                          }
20355                          value = 0;
20356                          count = 0;
20357                      }
20358                  }
20359                  break;
20360          }
20361          result.append(StringEncoding.decode(decodedBytes.toByteArray(), encoding));
20362          return codeIndex;
20363      }
20364      /**
20365       * Numeric Compaction mode (see 5.4.4) permits efficient encoding of numeric data strings.
20366       *
20367       * @param codewords The array of codewords (data + error)
20368       * @param codeIndex The current index into the codeword array.
20369       * @param result    The decoded data is appended to the result.
20370       * @return The next index into the codeword array.
20371       *
20372       * @throws FormatException
20373       */
20374      static numericCompaction(codewords, codeIndex /*int*/, result) {
20375          let count = 0;
20376          let end = false;
20377          let numericCodewords = new Int32Array(DecodedBitStreamParser.MAX_NUMERIC_CODEWORDS);
20378          while (codeIndex < codewords[0] && !end) {
20379              let code = codewords[codeIndex++];
20380              if (codeIndex === codewords[0]) {
20381                  end = true;
20382              }
20383              if (code < DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH) {
20384                  numericCodewords[count] = code;
20385                  count++;
20386              }
20387              else {
20388                  switch (code) {
20389                      case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
20390                      case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH:
20391                      case DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH_6:
20392                      case DecodedBitStreamParser.BEGIN_MACRO_PDF417_CONTROL_BLOCK:
20393                      case DecodedBitStreamParser.BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
20394                      case DecodedBitStreamParser.MACRO_PDF417_TERMINATOR:
20395                          codeIndex--;
20396                          end = true;
20397                          break;
20398                  }
20399              }
20400              if ((count % DecodedBitStreamParser.MAX_NUMERIC_CODEWORDS === 0 || code === DecodedBitStreamParser.NUMERIC_COMPACTION_MODE_LATCH || end) && count > 0) {
20401                  // Re-invoking Numeric Compaction mode (by using codeword 902
20402                  // while in Numeric Compaction mode) serves  to terminate the
20403                  // current Numeric Compaction mode grouping as described in 5.4.4.2,
20404                  // and then to start a new one grouping.
20405                  result.append(DecodedBitStreamParser.decodeBase900toBase10(numericCodewords, count));
20406                  count = 0;
20407              }
20408          }
20409          return codeIndex;
20410      }
20411      /**
20412       * Convert a list of Numeric Compacted codewords from Base 900 to Base 10.
20413       *
20414       * @param codewords The array of codewords
20415       * @param count     The number of codewords
20416       * @return The decoded string representing the Numeric data.
20417       *
20418       * EXAMPLE
20419       * Encode the fifteen digit numeric string 000213298174000
20420       * Prefix the numeric string with a 1 and set the initial value of
20421       * t = 1 000 213 298 174 000
20422       * Calculate codeword 0
20423       * d0 = 1 000 213 298 174 000 mod 900 = 200
20424       *
20425       * t = 1 000 213 298 174 000 div 900 = 1 111 348 109 082
20426       * Calculate codeword 1
20427       * d1 = 1 111 348 109 082 mod 900 = 282
20428       *
20429       * t = 1 111 348 109 082 div 900 = 1 234 831 232
20430       * Calculate codeword 2
20431       * d2 = 1 234 831 232 mod 900 = 632
20432       *
20433       * t = 1 234 831 232 div 900 = 1 372 034
20434       * Calculate codeword 3
20435       * d3 = 1 372 034 mod 900 = 434
20436       *
20437       * t = 1 372 034 div 900 = 1 524
20438       * Calculate codeword 4
20439       * d4 = 1 524 mod 900 = 624
20440       *
20441       * t = 1 524 div 900 = 1
20442       * Calculate codeword 5
20443       * d5 = 1 mod 900 = 1
20444       * t = 1 div 900 = 0
20445       * Codeword sequence is: 1, 624, 434, 632, 282, 200
20446       *
20447       * Decode the above codewords involves
20448       *   1 x 900 power of 5 + 624 x 900 power of 4 + 434 x 900 power of 3 +
20449       * 632 x 900 power of 2 + 282 x 900 power of 1 + 200 x 900 power of 0 = 1000213298174000
20450       *
20451       * Remove leading 1 =>  Result is 000213298174000
20452       *
20453       * @throws FormatException
20454       */
20455      static decodeBase900toBase10(codewords, count) {
20456          let result = createBigInt(0);
20457          for (let i /*int*/ = 0; i < count; i++) {
20458              result += DecodedBitStreamParser.EXP900[count - i - 1] * createBigInt(codewords[i]);
20459          }
20460          let resultString = result.toString();
20461          if (resultString.charAt(0) !== '1') {
20462              throw new FormatException();
20463          }
20464          return resultString.substring(1);
20465      }
20466  }
20467  DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH = 900;
20468  DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH = 901;
20469  DecodedBitStreamParser.NUMERIC_COMPACTION_MODE_LATCH = 902;
20470  DecodedBitStreamParser.BYTE_COMPACTION_MODE_LATCH_6 = 924;
20471  DecodedBitStreamParser.ECI_USER_DEFINED = 925;
20472  DecodedBitStreamParser.ECI_GENERAL_PURPOSE = 926;
20473  DecodedBitStreamParser.ECI_CHARSET = 927;
20474  DecodedBitStreamParser.BEGIN_MACRO_PDF417_CONTROL_BLOCK = 928;
20475  DecodedBitStreamParser.BEGIN_MACRO_PDF417_OPTIONAL_FIELD = 923;
20476  DecodedBitStreamParser.MACRO_PDF417_TERMINATOR = 922;
20477  DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE = 913;
20478  DecodedBitStreamParser.MAX_NUMERIC_CODEWORDS = 15;
20479  DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME = 0;
20480  DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT = 1;
20481  DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP = 2;
20482  DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_SENDER = 3;
20483  DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE = 4;
20484  DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE = 5;
20485  DecodedBitStreamParser.MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM = 6;
20486  DecodedBitStreamParser.PL = 25;
20487  DecodedBitStreamParser.LL = 27;
20488  DecodedBitStreamParser.AS = 27;
20489  DecodedBitStreamParser.ML = 28;
20490  DecodedBitStreamParser.AL = 28;
20491  DecodedBitStreamParser.PS = 29;
20492  DecodedBitStreamParser.PAL = 29;
20493  DecodedBitStreamParser.PUNCT_CHARS = ';<>@[\\]_`~!\r\t,:\n-.$/"|*()?{}\'';
20494  DecodedBitStreamParser.MIXED_CHARS = '0123456789&\r\t,:#-.$/+%*=^';
20495  /**
20496   * Table containing values for the exponent of 900.
20497   * This is used in the numeric compaction decode algorithm.
20498   */
20499  DecodedBitStreamParser.EXP900 = getBigIntConstructor() ? getEXP900() : [];
20500  DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS = 2;
20501
20502  /*
20503  * Copyright 2013 ZXing authors
20504  *
20505  * Licensed under the Apache License, Version 2.0 (the "License");
20506  * you may not use this file except in compliance with the License.
20507  * You may obtain a copy of the License at
20508  *
20509  *      http://www.apache.org/licenses/LICENSE-2.0
20510  *
20511  * Unless required by applicable law or agreed to in writing, software
20512  * distributed under the License is distributed on an "AS IS" BASIS,
20513  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20514  * See the License for the specific language governing permissions and
20515  * limitations under the License.
20516  */
20517  // 
20517import java.util.ArrayList;
20518  // import java.util.Collection;
20519  // import java.util.Formatter;
20520  // import java.util.List;
20521  /**
20522   * @author Guenther Grau
20523   */
20524  /*public final*/
vendor: 11,722 bytes, lines 20524-20760
20524 class PDF417ScanningDecoder {
20525      constructor() { }
20526      /**
20527       * @TODO don't pass in minCodewordWidth and maxCodewordWidth, pass in barcode columns for start and stop pattern
20528       *
20529       * columns. That way width can be deducted from the pattern column.
20530       * This approach also allows to detect more details about the barcode, e.g. if a bar type (white or black) is wider
20531       * than it should be. This can happen if the scanner used a bad blackpoint.
20532       *
20533       * @param BitMatrix
20534       * @param image
20535       * @param ResultPoint
20536       * @param imageTopLeft
20537       * @param ResultPoint
20538       * @param imageBottomLeft
20539       * @param ResultPoint
20540       * @param imageTopRight
20541       * @param ResultPoint
20542       * @param imageBottomRight
20543       * @param int
20544       * @param minCodewordWidth
20545       * @param int
20546       * @param maxCodewordWidth
20547       *
20548       * @throws NotFoundException
20549       * @throws FormatException
20550       * @throws ChecksumException
20551       */
20552      static decode(image, imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight, minCodewordWidth, maxCodewordWidth) {
20553          let boundingBox = new BoundingBox(image, imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight);
20554          let leftRowIndicatorColumn = null;
20555          let rightRowIndicatorColumn = null;
20556          let detectionResult;
20557          for (let firstPass /*boolean*/ = true;; firstPass = false) {
20558              if (imageTopLeft != null) {
20559                  leftRowIndicatorColumn = PDF417ScanningDecoder.getRowIndicatorColumn(image, boundingBox, imageTopLeft, true, minCodewordWidth, maxCodewordWidth);
20560              }
20561              if (imageTopRight != null) {
20562                  rightRowIndicatorColumn = PDF417ScanningDecoder.getRowIndicatorColumn(image, boundingBox, imageTopRight, false, minCodewordWidth, maxCodewordWidth);
20563              }
20564              detectionResult = PDF417ScanningDecoder.merge(leftRowIndicatorColumn, rightRowIndicatorColumn);
20565              if (detectionResult == null) {
20566                  throw NotFoundException.getNotFoundInstance();
20567              }
20568              let resultBox = detectionResult.getBoundingBox();
20569              if (firstPass && resultBox != null &&
20570                  (resultBox.getMinY() < boundingBox.getMinY() || resultBox.getMaxY() > boundingBox.getMaxY())) {
20571                  boundingBox = resultBox;
20572              }
20573              else {
20574                  break;
20575              }
20576          }
20577          detectionResult.setBoundingBox(boundingBox);
20578          let maxBarcodeColumn = detectionResult.getBarcodeColumnCount() + 1;
20579          detectionResult.setDetectionResultColumn(0, leftRowIndicatorColumn);
20580          detectionResult.setDetectionResultColumn(maxBarcodeColumn, rightRowIndicatorColumn);
20581          let leftToRight = leftRowIndicatorColumn != null;
20582          for (let barcodeColumnCount /*int*/ = 1; barcodeColumnCount <= maxBarcodeColumn; barcodeColumnCount++) {
20583              let barcodeColumn = leftToRight ? barcodeColumnCount : maxBarcodeColumn - barcodeColumnCount;
20584              if (detectionResult.getDetectionResultColumn(barcodeColumn) !== /* null */ undefined) {
20585                  // This will be the case for the opposite row indicator column, which doesn't need to be decoded again.
20586                  continue;
20587              }
20588              let detectionResultColumn;
20589              if (barcodeColumn === 0 || barcodeColumn === maxBarcodeColumn) {
20590                  detectionResultColumn = new DetectionResultRowIndicatorColumn(boundingBox, barcodeColumn === 0);
20591              }
20592              else {
20593                  detectionResultColumn = new DetectionResultColumn(boundingBox);
20594              }
20595              detectionResult.setDetectionResultColumn(barcodeColumn, detectionResultColumn);
20596              let startColumn = -1;
20597              let previousStartColumn = startColumn;
20598              // TODO start at a row for which we know the start position, then detect upwards and downwards from there.
20599              for (let imageRow /*int*/ = boundingBox.getMinY(); imageRow <= boundingBox.getMaxY(); imageRow++) {
20600                  startColumn = PDF417ScanningDecoder.getStartColumn(detectionResult, barcodeColumn, imageRow, leftToRight);
20601                  if (startColumn < 0 || startColumn > boundingBox.getMaxX()) {
20602                      if (previousStartColumn === -1) {
20603                          continue;
20604                      }
20605                      startColumn = previousStartColumn;
20606                  }
20607                  let codeword = PDF417ScanningDecoder.detectCodeword(image, boundingBox.getMinX(), boundingBox.getMaxX(), leftToRight, startColumn, imageRow, minCodewordWidth, maxCodewordWidth);
20608                  if (codeword != null) {
20609                      detectionResultColumn.setCodeword(imageRow, codeword);
20610                      previousStartColumn = startColumn;
20611                      minCodewordWidth = Math.min(minCodewordWidth, codeword.getWidth());
20612                      maxCodewordWidth = Math.max(maxCodewordWidth, codeword.getWidth());
20613                  }
20614              }
20615          }
20616          return PDF417ScanningDecoder.createDecoderResult(detectionResult);
20617      }
20618      /**
20619       *
20620       * @param leftRowIndicatorColumn
20621       * @param rightRowIndicatorColumn
20622       *
20623       * @throws NotFoundException
20624       */
20625      static merge(leftRowIndicatorColumn, rightRowIndicatorColumn) {
20626          if (leftRowIndicatorColumn == null && rightRowIndicatorColumn == null) {
20627              return null;
20628          }
20629          let barcodeMetadata = PDF417ScanningDecoder.getBarcodeMetadata(leftRowIndicatorColumn, rightRowIndicatorColumn);
20630          if (barcodeMetadata == null) {
20631              return null;
20632          }
20633          let boundingBox = BoundingBox.merge(PDF417ScanningDecoder.adjustBoundingBox(leftRowIndicatorColumn), PDF417ScanningDecoder.adjustBoundingBox(rightRowIndicatorColumn));
20634          return new DetectionResult(barcodeMetadata, boundingBox);
20635      }
20636      /**
20637       *
20638       * @param rowIndicatorColumn
20639       *
20640       * @throws NotFoundException
20641       */
20642      static adjustBoundingBox(rowIndicatorColumn) {
20643          if (rowIndicatorColumn == null) {
20644              return null;
20645          }
20646          let rowHeights = rowIndicatorColumn.getRowHeights();
20647          if (rowHeights == null) {
20648              return null;
20649          }
20650          let maxRowHeight = PDF417ScanningDecoder.getMax(rowHeights);
20651          let missingStartRows = 0;
20652          for (let rowHeight /*int*/ of rowHeights) {
20653              missingStartRows += maxRowHeight - rowHeight;
20654              if (rowHeight > 0) {
20655                  break;
20656              }
20657          }
20658          let codewords = rowIndicatorColumn.getCodewords();
20659          for (let row /*int*/ = 0; missingStartRows > 0 && codewords[row] == null; row++) {
20660              missingStartRows--;
20661          }
20662          let missingEndRows = 0;
20663          for (let row /*int*/ = rowHeights.length - 1; row >= 0; row--) {
20664              missingEndRows += maxRowHeight - rowHeights[row];
20665              if (rowHeights[row] > 0) {
20666                  break;
20667              }
20668          }
20669          for (let row /*int*/ = codewords.length - 1; missingEndRows > 0 && codewords[row] == null; row--) {
20670              missingEndRows--;
20671          }
20672          return rowIndicatorColumn.getBoundingBox().addMissingRows(missingStartRows, missingEndRows, rowIndicatorColumn.isLeft());
20673      }
20674      static getMax(values) {
20675          let maxValue = -1;
20676          for (let value /*int*/ of values) {
20677              maxValue = Math.max(maxValue, value);
20678          }
20679          return maxValue;
20680      }
20681      static getBarcodeMetadata(leftRowIndicatorColumn, rightRowIndicatorColumn) {
20682          let leftBarcodeMetadata;
20683          if (leftRowIndicatorColumn == null ||
20684              (leftBarcodeMetadata = leftRowIndicatorColumn.getBarcodeMetadata()) == null) {
20685              return rightRowIndicatorColumn == null ? null : rightRowIndicatorColumn.getBarcodeMetadata();
20686          }
20687          let rightBarcodeMetadata;
20688          if (rightRowIndicatorColumn == null ||
20689              (rightBarcodeMetadata = rightRowIndicatorColumn.getBarcodeMetadata()) == null) {
20690              return leftBarcodeMetadata;
20691          }
20692          if (leftBarcodeMetadata.getColumnCount() !== rightBarcodeMetadata.getColumnCount() &&
20693              leftBarcodeMetadata.getErrorCorrectionLevel() !== rightBarcodeMetadata.getErrorCorrectionLevel() &&
20694              leftBarcodeMetadata.getRowCount() !== rightBarcodeMetadata.getRowCount()) {
20695              return null;
20696          }
20697          return leftBarcodeMetadata;
20698      }
20699      static getRowIndicatorColumn(image, boundingBox, startPoint, leftToRight, minCodewordWidth, maxCodewordWidth) {
20700          let rowIndicatorColumn = new DetectionResultRowIndicatorColumn(boundingBox, leftToRight);
20701          for (let i /*int*/ = 0; i < 2; i++) {
20702              let increment = i === 0 ? 1 : -1;
20703              let startColumn = Math.trunc(Math.trunc(startPoint.getX()));
20704              for (let imageRow /*int*/ = Math.trunc(Math.trunc(startPoint.getY())); imageRow <= boundingBox.getMaxY() &&
20705                  imageRow >= boundingBox.getMinY(); imageRow += increment) {
20706                  let codeword = PDF417ScanningDecoder.detectCodeword(image, 0, image.getWidth(), leftToRight, startColumn, imageRow, minCodewordWidth, maxCodewordWidth);
20707                  if (codeword != null) {
20708                      rowIndicatorColumn.setCodeword(imageRow, codeword);
20709                      if (leftToRight) {
20710                          startColumn = codeword.getStartX();
20711                      }
20712                      else {
20713                          startColumn = codeword.getEndX();
20714                      }
20715                  }
20716              }
20717          }
20718          return rowIndicatorColumn;
20719      }
20720      /**
20721       *
20722       * @param detectionResult
20723       * @param BarcodeValue
20724       * @param param2
20725       * @param param3
20726       * @param barcodeMatrix
20727       *
20728       * @throws NotFoundException
20729       */
20730      static adjustCodewordCount(detectionResult, barcodeMatrix) {
20731          let barcodeMatrix01 = barcodeMatrix[0][1];
20732          let numberOfCodewords = barcodeMatrix01.getValue();
20733          let calculatedNumberOfCodewords = detectionResult.getBarcodeColumnCount() *
20734              detectionResult.getBarcodeRowCount() -
20735              PDF417ScanningDecoder.getNumberOfECCodeWords(detectionResult.getBarcodeECLevel());
20736          if (numberOfCodewords.length === 0) {
20737              if (calculatedNumberOfCodewords < 1 || calculatedNumberOfCodewords > PDF417Common.MAX_CODEWORDS_IN_BARCODE) {
20738                  throw NotFoundException.getNotFoundInstance();
20739              }
20740              barcodeMatrix01.setValue(calculatedNumberOfCodewords);
20741          }
20742          else if (numberOfCodewords[0] !== calculatedNumberOfCodewords) {
20743              // The calculated one is more reliable as it is derived from the row indicator columns
20744              barcodeMatrix01.setValue(calculatedNumberOfCodewords);
20745          }
20746      }
20747      /**
20748       *
20749       * @param detectionResult
20750       *
20751       * @throws FormatException
20752       * @throws ChecksumException
20753       * @throws NotFoundException
20754       */
20755      static createDecoderResult(detectionResult) {
20756          let barcodeMatrix = PDF417ScanningDecoder.createBarcodeMatrix(detectionResult);
20757          PDF417ScanningDecoder.adjustCodewordCount(detectionResult, barcodeMatrix);
20758          let erasures /*Collection<Integer>*/ = new Array();
20759          let codewords = new Int32Array(detectionResult.getBarcodeRowCount() * detectionResult.getBarcodeColumnCount());
20760          let ambiguousIndexValuesList = 
20760/*List<int[]>*/ [];
20761          let ambiguousIndexesList = /*Collection<Integer>*/
vendor: 25,385 bytes, lines 20761-21284
20761 new Array();
20762          for (let row /*int*/ = 0; row < detectionResult.getBarcodeRowCount(); row++) {
20763              for (let column /*int*/ = 0; column < detectionResult.getBarcodeColumnCount(); column++) {
20764                  let values = barcodeMatrix[row][column + 1].getValue();
20765                  let codewordIndex = row * detectionResult.getBarcodeColumnCount() + column;
20766                  if (values.length === 0) {
20767                      erasures.push(codewordIndex);
20768                  }
20769                  else if (values.length === 1) {
20770                      codewords[codewordIndex] = values[0];
20771                  }
20772                  else {
20773                      ambiguousIndexesList.push(codewordIndex);
20774                      ambiguousIndexValuesList.push(values);
20775                  }
20776              }
20777          }
20778          let ambiguousIndexValues = new Array(ambiguousIndexValuesList.length);
20779          for (let i /*int*/ = 0; i < ambiguousIndexValues.length; i++) {
20780              ambiguousIndexValues[i] = ambiguousIndexValuesList[i];
20781          }
20782          return PDF417ScanningDecoder.createDecoderResultFromAmbiguousValues(detectionResult.getBarcodeECLevel(), codewords, PDF417Common.toIntArray(erasures), PDF417Common.toIntArray(ambiguousIndexesList), ambiguousIndexValues);
20783      }
20784      /**
20785       * This method deals with the fact, that the decoding process doesn't always yield a single most likely value. The
20786       * current error correction implementation doesn't deal with erasures very well, so it's better to provide a value
20787       * for these ambiguous codewords instead of treating it as an erasure. The problem is that we don't know which of
20788       * the ambiguous values to choose. We try decode using the first value, and if that fails, we use another of the
20789       * ambiguous values and try to decode again. This usually only happens on very hard to read and decode barcodes,
20790       * so decoding the normal barcodes is not affected by this.
20791       *
20792       * @param erasureArray contains the indexes of erasures
20793       * @param ambiguousIndexes array with the indexes that have more than one most likely value
20794       * @param ambiguousIndexValues two dimensional array that contains the ambiguous values. The first dimension must
20795       * be the same length as the ambiguousIndexes array
20796       *
20797       * @throws FormatException
20798       * @throws ChecksumException
20799       */
20800      static createDecoderResultFromAmbiguousValues(ecLevel, codewords, erasureArray, ambiguousIndexes, ambiguousIndexValues) {
20801          let ambiguousIndexCount = new Int32Array(ambiguousIndexes.length);
20802          let tries = 100;
20803          while (tries-- > 0) {
20804              for (let i /*int*/ = 0; i < ambiguousIndexCount.length; i++) {
20805                  codewords[ambiguousIndexes[i]] = ambiguousIndexValues[i][ambiguousIndexCount[i]];
20806              }
20807              try {
20808                  return PDF417ScanningDecoder.decodeCodewords(codewords, ecLevel, erasureArray);
20809              }
20810              catch (err) {
20811                  let ignored = err instanceof ChecksumException;
20812                  if (!ignored) {
20813                      throw err;
20814                  }
20815              }
20816              if (ambiguousIndexCount.length === 0) {
20817                  throw ChecksumException.getChecksumInstance();
20818              }
20819              for (let i /*int*/ = 0; i < ambiguousIndexCount.length; i++) {
20820                  if (ambiguousIndexCount[i] < ambiguousIndexValues[i].length - 1) {
20821                      ambiguousIndexCount[i]++;
20822                      break;
20823                  }
20824                  else {
20825                      ambiguousIndexCount[i] = 0;
20826                      if (i === ambiguousIndexCount.length - 1) {
20827                          throw ChecksumException.getChecksumInstance();
20828                      }
20829                  }
20830              }
20831          }
20832          throw ChecksumException.getChecksumInstance();
20833      }
20834      static createBarcodeMatrix(detectionResult) {
20835          // let barcodeMatrix: BarcodeValue[][] =
20836          // new BarcodeValue[detectionResult.getBarcodeRowCount()][detectionResult.getBarcodeColumnCount() + 2];
20837          let barcodeMatrix = Array.from({ length: detectionResult.getBarcodeRowCount() }, () => new Array(detectionResult.getBarcodeColumnCount() + 2));
20838          for (let row /*int*/ = 0; row < barcodeMatrix.length; row++) {
20839              for (let column /*int*/ = 0; column < barcodeMatrix[row].length; column++) {
20840                  barcodeMatrix[row][column] = new BarcodeValue();
20841              }
20842          }
20843          let column = 0;
20844          for (let detectionResultColumn /*DetectionResultColumn*/ of detectionResult.getDetectionResultColumns()) {
20845              if (detectionResultColumn != null) {
20846                  for (let codeword /*Codeword*/ of detectionResultColumn.getCodewords()) {
20847                      if (codeword != null) {
20848                          let rowNumber = codeword.getRowNumber();
20849                          if (rowNumber >= 0) {
20850                              if (rowNumber >= barcodeMatrix.length) {
20851                                  // We have more rows than the barcode metadata allows for, ignore them.
20852                                  continue;
20853                              }
20854                              barcodeMatrix[rowNumber][column].setValue(codeword.getValue());
20855                          }
20856                      }
20857                  }
20858              }
20859              column++;
20860          }
20861          return barcodeMatrix;
20862      }
20863      static isValidBarcodeColumn(detectionResult, barcodeColumn) {
20864          return barcodeColumn >= 0 && barcodeColumn <= detectionResult.getBarcodeColumnCount() + 1;
20865      }
20866      static getStartColumn(detectionResult, barcodeColumn, imageRow, leftToRight) {
20867          let offset = leftToRight ? 1 : -1;
20868          let codeword = null;
20869          if (PDF417ScanningDecoder.isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
20870              codeword = detectionResult.getDetectionResultColumn(barcodeColumn - offset).getCodeword(imageRow);
20871          }
20872          if (codeword != null) {
20873              return leftToRight ? codeword.getEndX() : codeword.getStartX();
20874          }
20875          codeword = detectionResult.getDetectionResultColumn(barcodeColumn).getCodewordNearby(imageRow);
20876          if (codeword != null) {
20877              return leftToRight ? codeword.getStartX() : codeword.getEndX();
20878          }
20879          if (PDF417ScanningDecoder.isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
20880              codeword = detectionResult.getDetectionResultColumn(barcodeColumn - offset).getCodewordNearby(imageRow);
20881          }
20882          if (codeword != null) {
20883              return leftToRight ? codeword.getEndX() : codeword.getStartX();
20884          }
20885          let skippedColumns = 0;
20886          while (PDF417ScanningDecoder.isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
20887              barcodeColumn -= offset;
20888              for (let previousRowCodeword /*Codeword*/ of detectionResult.getDetectionResultColumn(barcodeColumn).getCodewords()) {
20889                  if (previousRowCodeword != null) {
20890                      return (leftToRight ? previousRowCodeword.getEndX() : previousRowCodeword.getStartX()) +
20891                          offset *
20892                              skippedColumns *
20893                              (previousRowCodeword.getEndX() - previousRowCodeword.getStartX());
20894                  }
20895              }
20896              skippedColumns++;
20897          }
20898          return leftToRight ? detectionResult.getBoundingBox().getMinX() : detectionResult.getBoundingBox().getMaxX();
20899      }
20900      static detectCodeword(image, minColumn, maxColumn, leftToRight, startColumn, imageRow, minCodewordWidth, maxCodewordWidth) {
20901          startColumn = PDF417ScanningDecoder.adjustCodewordStartColumn(image, minColumn, maxColumn, leftToRight, startColumn, imageRow);
20902          // we usually know fairly exact now how long a codeword is. We should provide minimum and maximum expected length
20903          // and try to adjust the read pixels, e.g. remove single pixel errors or try to cut off exceeding pixels.
20904          // min and maxCodewordWidth should not be used as they are calculated for the whole barcode an can be inaccurate
20905          // for the current position
20906          let moduleBitCount = PDF417ScanningDecoder.getModuleBitCount(image, minColumn, maxColumn, leftToRight, startColumn, imageRow);
20907          if (moduleBitCount == null) {
20908              return null;
20909          }
20910          let endColumn;
20911          let codewordBitCount = MathUtils.sum(moduleBitCount);
20912          if (leftToRight) {
20913              endColumn = startColumn + codewordBitCount;
20914          }
20915          else {
20916              for (let i /*int*/ = 0; i < moduleBitCount.length / 2; i++) {
20917                  let tmpCount = moduleBitCount[i];
20918                  moduleBitCount[i] = moduleBitCount[moduleBitCount.length - 1 - i];
20919                  moduleBitCount[moduleBitCount.length - 1 - i] = tmpCount;
20920              }
20921              endColumn = startColumn;
20922              startColumn = endColumn - codewordBitCount;
20923          }
20924          // TODO implement check for width and correction of black and white bars
20925          // use start (and maybe stop pattern) to determine if black bars are wider than white bars. If so, adjust.
20926          // should probably done only for codewords with a lot more than 17 bits.
20927          // The following fixes 10-1.png, which has wide black bars and small white bars
20928          //    for (let i /*int*/ = 0; i < moduleBitCount.length; i++) {
20929          //      if (i % 2 === 0) {
20930          //        moduleBitCount[i]--;
20931          //      } else {
20932          //        moduleBitCount[i]++;
20933          //      }
20934          //    }
20935          // We could also use the width of surrounding codewords for more accurate results, but this seems
20936          // sufficient for now
20937          if (!PDF417ScanningDecoder.checkCodewordSkew(codewordBitCount, minCodewordWidth, maxCodewordWidth)) {
20938              // We could try to use the startX and endX position of the codeword in the same column in the previous row,
20939              // create the bit count from it and normalize it to 8. This would help with single pixel errors.
20940              return null;
20941          }
20942          let decodedValue = PDF417CodewordDecoder.getDecodedValue(moduleBitCount);
20943          let codeword = PDF417Common.getCodeword(decodedValue);
20944          if (codeword === -1) {
20945              return null;
20946          }
20947          return new Codeword(startColumn, endColumn, PDF417ScanningDecoder.getCodewordBucketNumber(decodedValue), codeword);
20948      }
20949      static getModuleBitCount(image, minColumn, maxColumn, leftToRight, startColumn, imageRow) {
20950          let imageColumn = startColumn;
20951          let moduleBitCount = new Int32Array(8);
20952          let moduleNumber = 0;
20953          let increment = leftToRight ? 1 : -1;
20954          let previousPixelValue = leftToRight;
20955          while ((leftToRight ? imageColumn < maxColumn : imageColumn >= minColumn) &&
20956              moduleNumber < moduleBitCount.length) {
20957              if (image.get(imageColumn, imageRow) === previousPixelValue) {
20958                  moduleBitCount[moduleNumber]++;
20959                  imageColumn += increment;
20960              }
20961              else {
20962                  moduleNumber++;
20963                  previousPixelValue = !previousPixelValue;
20964              }
20965          }
20966          if (moduleNumber === moduleBitCount.length ||
20967              ((imageColumn === (leftToRight ? maxColumn : minColumn)) &&
20968                  moduleNumber === moduleBitCount.length - 1)) {
20969              return moduleBitCount;
20970          }
20971          return null;
20972      }
20973      static getNumberOfECCodeWords(barcodeECLevel) {
20974          return 2 << barcodeECLevel;
20975      }
20976      static adjustCodewordStartColumn(image, minColumn, maxColumn, leftToRight, codewordStartColumn, imageRow) {
20977          let correctedStartColumn = codewordStartColumn;
20978          let increment = leftToRight ? -1 : 1;
20979          // there should be no black pixels before the start column. If there are, then we need to start earlier.
20980          for (let i /*int*/ = 0; i < 2; i++) {
20981              while ((leftToRight ? correctedStartColumn >= minColumn : correctedStartColumn < maxColumn) &&
20982                  leftToRight === image.get(correctedStartColumn, imageRow)) {
20983                  if (Math.abs(codewordStartColumn - correctedStartColumn) > PDF417ScanningDecoder.CODEWORD_SKEW_SIZE) {
20984                      return codewordStartColumn;
20985                  }
20986                  correctedStartColumn += increment;
20987              }
20988              increment = -increment;
20989              leftToRight = !leftToRight;
20990          }
20991          return correctedStartColumn;
20992      }
20993      static checkCodewordSkew(codewordSize, minCodewordWidth, maxCodewordWidth) {
20994          return minCodewordWidth - PDF417ScanningDecoder.CODEWORD_SKEW_SIZE <= codewordSize &&
20995              codewordSize <= maxCodewordWidth + PDF417ScanningDecoder.CODEWORD_SKEW_SIZE;
20996      }
20997      /**
20998       * @throws FormatException,
20999       * @throws ChecksumException
21000       */
21001      static decodeCodewords(codewords, ecLevel, erasures) {
21002          if (codewords.length === 0) {
21003              throw FormatException.getFormatInstance();
21004          }
21005          let numECCodewords = 1 << (ecLevel + 1);
21006          let correctedErrorsCount = PDF417ScanningDecoder.correctErrors(codewords, erasures, numECCodewords);
21007          PDF417ScanningDecoder.verifyCodewordCount(codewords, numECCodewords);
21008          // Decode the codewords
21009          let decoderResult = DecodedBitStreamParser.decode(codewords, '' + ecLevel);
21010          decoderResult.setErrorsCorrected(correctedErrorsCount);
21011          decoderResult.setErasures(erasures.length);
21012          return decoderResult;
21013      }
21014      /**
21015       * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
21016       * correct the errors in-place.</p>
21017       *
21018       * @param codewords   data and error correction codewords
21019       * @param erasures positions of any known erasures
21020       * @param numECCodewords number of error correction codewords that are available in codewords
21021       * @throws ChecksumException if error correction fails
21022       */
21023      static correctErrors(codewords, erasures, numECCodewords) {
21024          if (erasures != null &&
21025              erasures.length > numECCodewords / 2 + PDF417ScanningDecoder.MAX_ERRORS ||
21026              numECCodewords < 0 ||
21027              numECCodewords > PDF417ScanningDecoder.MAX_EC_CODEWORDS) {
21028              // Too many errors or EC Codewords is corrupted
21029              throw ChecksumException.getChecksumInstance();
21030          }
21031          return PDF417ScanningDecoder.errorCorrection.decode(codewords, numECCodewords, erasures);
21032      }
21033      /**
21034       * Verify that all is OK with the codeword array.
21035       * @throws FormatException
21036       */
21037      static verifyCodewordCount(codewords, numECCodewords) {
21038          if (codewords.length < 4) {
21039              // Codeword array size should be at least 4 allowing for
21040              // Count CW, At least one Data CW, Error Correction CW, Error Correction CW
21041              throw FormatException.getFormatInstance();
21042          }
21043          // The first codeword, the Symbol Length Descriptor, shall always encode the total number of data
21044          // codewords in the symbol, including the Symbol Length Descriptor itself, data codewords and pad
21045          // codewords, but excluding the number of error correction codewords.
21046          let numberOfCodewords = codewords[0];
21047          if (numberOfCodewords > codewords.length) {
21048              throw FormatException.getFormatInstance();
21049          }
21050          if (numberOfCodewords === 0) {
21051              // Reset to the length of the array - 8 (Allow for at least level 3 Error Correction (8 Error Codewords)
21052              if (numECCodewords < codewords.length) {
21053                  codewords[0] = codewords.length - numECCodewords;
21054              }
21055              else {
21056                  throw FormatException.getFormatInstance();
21057              }
21058          }
21059      }
21060      static getBitCountForCodeword(codeword) {
21061          let result = new Int32Array(8);
21062          let previousValue = 0;
21063          let i = result.length - 1;
21064          while (true) {
21065              if ((codeword & 0x1) !== previousValue) {
21066                  previousValue = codeword & 0x1;
21067                  i--;
21068                  if (i < 0) {
21069                      break;
21070                  }
21071              }
21072              result[i]++;
21073              codeword >>= 1;
21074          }
21075          return result;
21076      }
21077      static getCodewordBucketNumber(codeword) {
21078          if (codeword instanceof Int32Array) {
21079              return this.getCodewordBucketNumber_Int32Array(codeword);
21080          }
21081          return this.getCodewordBucketNumber_number(codeword);
21082      }
21083      static getCodewordBucketNumber_number(codeword) {
21084          return PDF417ScanningDecoder.getCodewordBucketNumber(PDF417ScanningDecoder.getBitCountForCodeword(codeword));
21085      }
21086      static getCodewordBucketNumber_Int32Array(moduleBitCount) {
21087          return (moduleBitCount[0] - moduleBitCount[2] + moduleBitCount[4] - moduleBitCount[6] + 9) % 9;
21088      }
21089      static toString(barcodeMatrix) {
21090          let formatter = new Formatter();
21091          // try (let formatter = new Formatter()) {
21092          for (let row /*int*/ = 0; row < barcodeMatrix.length; row++) {
21093              formatter.format('Row %2d: ', row);
21094              for (let column /*int*/ = 0; column < barcodeMatrix[row].length; column++) {
21095                  let barcodeValue = barcodeMatrix[row][column];
21096                  if (barcodeValue.getValue().length === 0) {
21097                      formatter.format('        ', null);
21098                  }
21099                  else {
21100                      formatter.format('%4d(%2d)', barcodeValue.getValue()[0], barcodeValue.getConfidence(barcodeValue.getValue()[0]));
21101                  }
21102              }
21103              formatter.format('%n');
21104          }
21105          return formatter.toString();
21106          // }
21107      }
21108  }
21109  /*final*/ PDF417ScanningDecoder.CODEWORD_SKEW_SIZE = 2;
21110  /*final*/ PDF417ScanningDecoder.MAX_ERRORS = 3;
21111  /*final*/ PDF417ScanningDecoder.MAX_EC_CODEWORDS = 512;
21112  /*final*/ PDF417ScanningDecoder.errorCorrection = new ErrorCorrection$1();
21113
21114  /*
21115   * Copyright 2009 ZXing authors
21116   *
21117   * Licensed under the Apache License, Version 2.0 (the "License");
21118   * you may not use this file except in compliance with the License.
21119   * You may obtain a copy of the License at
21120   *
21121   *      http://www.apache.org/licenses/LICENSE-2.0
21122   *
21123   * Unless required by applicable law or agreed to in writing, software
21124   * distributed under the License is distributed on an "AS IS" BASIS,
21125   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21126   * See the License for the specific language governing permissions and
21127   * limitations under the License.
21128   */
21129  // import java.util.ArrayList;
21130  // import java.util.List;
21131  // import java.util.Map;
21132  /**
21133   * This implementation can detect and decode PDF417 codes in an image.
21134   *
21135   * @author Guenther Grau
21136   */
21137  /*public final*/ class PDF417Reader {
21138      // private static /*final Result[]*/ EMPTY_RESULT_ARRAY: Result[] = new Result([0]);
21139      /**
21140       * Locates and decodes a PDF417 code in an image.
21141       *
21142       * @return a String representing the content encoded by the PDF417 code
21143       * @throws NotFoundException if a PDF417 code cannot be found,
21144       * @throws FormatException if a PDF417 cannot be decoded
21145       * @throws ChecksumException
21146       */
21147      // @Override
21148      decode(image, hints = null) {
21149          let result = PDF417Reader.decode(image, hints, false);
21150          if (result == null || result.length === 0 || result[0] == null) {
21151              throw NotFoundException.getNotFoundInstance();
21152          }
21153          return result[0];
21154      }
21155      /**
21156       *
21157       * @param BinaryBitmap
21158       * @param image
21159       * @throws NotFoundException
21160       */
21161      //   @Override
21162      decodeMultiple(image, hints = null) {
21163          try {
21164              return PDF417Reader.decode(image, hints, true);
21165          }
21166          catch (ignored) {
21167              if (ignored instanceof FormatException || ignored instanceof ChecksumException) {
21168                  throw NotFoundException.getNotFoundInstance();
21169              }
21170              throw ignored;
21171          }
21172      }
21173      /**
21174       *
21175       * @param image
21176       * @param hints
21177       * @param multiple
21178       *
21179       * @throws NotFoundException
21180       * @throws FormatExceptionß
21181       * @throws ChecksumException
21182       */
21183      static decode(image, hints, multiple) {
21184          const results = new Array();
21185          const detectorResult = Detector.detectMultiple(image, hints, multiple);
21186          for (const points of detectorResult.getPoints()) {
21187              const decoderResult = PDF417ScanningDecoder.decode(detectorResult.getBits(), points[4], points[5], points[6], points[7], PDF417Reader.getMinCodewordWidth(points), PDF417Reader.getMaxCodewordWidth(points));
21188              const result = new Result$1(decoderResult.getText(), decoderResult.getRawBytes(), undefined, points, BarcodeFormat$1.PDF_417);
21189              result.putMetadata(ResultMetadataType$1.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel());
21190              const pdf417ResultMetadata = decoderResult.getOther();
21191              if (pdf417ResultMetadata != null) {
21192                  result.putMetadata(ResultMetadataType$1.PDF417_EXTRA_METADATA, pdf417ResultMetadata);
21193              }
21194              results.push(result);
21195          }
21196          return results.map(x => x);
21197      }
21198      static getMaxWidth(p1, p2) {
21199          if (p1 == null || p2 == null) {
21200              return 0;
21201          }
21202          return Math.trunc(Math.abs(p1.getX() - p2.getX()));
21203      }
21204      static getMinWidth(p1, p2) {
21205          if (p1 == null || p2 == null) {
21206              return Integer.MAX_VALUE;
21207          }
21208          return Math.trunc(Math.abs(p1.getX() - p2.getX()));
21209      }
21210      static getMaxCodewordWidth(p) {
21211          return Math.floor(Math.max(Math.max(PDF417Reader.getMaxWidth(p[0], p[4]), PDF417Reader.getMaxWidth(p[6], p[2]) * PDF417Common.MODULES_IN_CODEWORD /
21212              PDF417Common.MODULES_IN_STOP_PATTERN), Math.max(PDF417Reader.getMaxWidth(p[1], p[5]), PDF417Reader.getMaxWidth(p[7], p[3]) * PDF417Common.MODULES_IN_CODEWORD /
21213              PDF417Common.MODULES_IN_STOP_PATTERN)));
21214      }
21215      static getMinCodewordWidth(p) {
21216          return Math.floor(Math.min(Math.min(PDF417Reader.getMinWidth(p[0], p[4]), PDF417Reader.getMinWidth(p[6], p[2]) * PDF417Common.MODULES_IN_CODEWORD /
21217              PDF417Common.MODULES_IN_STOP_PATTERN), Math.min(PDF417Reader.getMinWidth(p[1], p[5]), PDF417Reader.getMinWidth(p[7], p[3]) * PDF417Common.MODULES_IN_CODEWORD /
21218              PDF417Common.MODULES_IN_STOP_PATTERN)));
21219      }
21220      // @Override
21221      reset() {
21222          // nothing needs to be reset
21223      }
21224  }
21225
21226  /**
21227   * Custom Error class of type Exception.
21228   */
21229  class ReaderException extends Exception {
21230  }
21231  ReaderException.kind = 'ReaderException';
21232
21233  /*
21234   * Copyright 2009 ZXing authors
21235   *
21236   * Licensed under the Apache License, Version 2.0 (the "License");
21237   * you may not use this file except in compliance with the License.
21238   * You may obtain a copy of the License at
21239   *
21240   *      http://www.apache.org/licenses/LICENSE-2.0
21241   *
21242   * Unless required by applicable law or agreed to in writing, software
21243   * distributed under the License is distributed on an "AS IS" BASIS,
21244   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21245   * See the License for the specific language governing permissions and
21246   * limitations under the License.
21247   */
21248  /*namespace com.google.zxing {*/
21249  /**
21250   * MultiFormatReader is a convenience class and the main entry point into the library for most uses.
21251   * By default it attempts to decode all barcode formats that the library supports. Optionally, you
21252   * can provide a hints object to request different behavior, for example only decoding QR codes.
21253   *
21254   * @author Sean Owen
21255   * @author [email protected] (Daniel Switkin)
21256   */
21257  class MultiFormatReader {
21258      /**
21259       * This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it
21260       * passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly.
21261       * Use setHints() followed by decodeWithState() for continuous scan applications.
21262       *
21263       * @param image The pixel data to decode
21264       * @return The contents of the image
21265       *
21266       * @throws NotFoundException Any errors which occurred
21267       */
21268      /*@Override*/
21269      // public decode(image: BinaryBitmap): Result {
21270      //   setHints(null)
21271      //   return decodeInternal(image)
21272      // }
21273      /**
21274       * Decode an image using the hints provided. Does not honor existing state.
21275       *
21276       * @param image The pixel data to decode
21277       * @param hints The hints to use, clearing the previous state.
21278       * @return The contents of the image
21279       *
21280       * @throws NotFoundException Any errors which occurred
21281       */
21282      /*@Override*/
21283      decode(image, hints) {
21284          
vendor: 5,303 bytes, lines 21284-21410
21284this.setHints(hints);
21285          return this.decodeInternal(image);
21286      }
21287      /**
21288       * Decode an image using the state set up by calling setHints() previously. Continuous scan
21289       * clients will get a <b>large</b> speed increase by using this instead of decode().
21290       *
21291       * @param image The pixel data to decode
21292       * @return The contents of the image
21293       *
21294       * @throws NotFoundException Any errors which occurred
21295       */
21296      decodeWithState(image) {
21297          // Make sure to set up the default state so we don't crash
21298          if (this.readers === null || this.readers === undefined) {
21299              this.setHints(null);
21300          }
21301          return this.decodeInternal(image);
21302      }
21303      /**
21304       * This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls
21305       * to decodeWithState(image) can reuse the same set of readers without reallocating memory. This
21306       * is important for performance in continuous scan clients.
21307       *
21308       * @param hints The set of hints to use for subsequent calls to decode(image)
21309       */
21310      setHints(hints) {
21311          this.hints = hints;
21312          const tryHarder = hints !== null && hints !== undefined && undefined !== hints.get(DecodeHintType$1.TRY_HARDER);
21313          /*@SuppressWarnings("unchecked")*/
21314          const formats = hints === null || hints === undefined ? null : hints.get(DecodeHintType$1.POSSIBLE_FORMATS);
21315          const readers = new Array();
21316          if (formats !== null && formats !== undefined) {
21317              const addOneDReader = formats.some(f => f === BarcodeFormat$1.UPC_A ||
21318                  f === BarcodeFormat$1.UPC_E ||
21319                  f === BarcodeFormat$1.EAN_13 ||
21320                  f === BarcodeFormat$1.EAN_8 ||
21321                  f === BarcodeFormat$1.CODABAR ||
21322                  f === BarcodeFormat$1.CODE_39 ||
21323                  f === BarcodeFormat$1.CODE_93 ||
21324                  f === BarcodeFormat$1.CODE_128 ||
21325                  f === BarcodeFormat$1.ITF ||
21326                  f === BarcodeFormat$1.RSS_14 ||
21327                  f === BarcodeFormat$1.RSS_EXPANDED);
21328              // Put 1D readers upfront in "normal" mode
21329              // TYPESCRIPTPORT: TODO: uncomment below as they are ported
21330              if (addOneDReader && !tryHarder) {
21331                  readers.push(new MultiFormatOneDReader(hints));
21332              }
21333              if (formats.includes(BarcodeFormat$1.QR_CODE)) {
21334                  readers.push(new QRCodeReader());
21335              }
21336              if (formats.includes(BarcodeFormat$1.DATA_MATRIX)) {
21337                  readers.push(new DataMatrixReader());
21338              }
21339              if (formats.includes(BarcodeFormat$1.AZTEC)) {
21340                  readers.push(new AztecReader());
21341              }
21342              if (formats.includes(BarcodeFormat$1.PDF_417)) {
21343                  readers.push(new PDF417Reader());
21344              }
21345              // if (formats.includes(BarcodeFormat.MAXICODE)) {
21346              //    readers.push(new MaxiCodeReader())
21347              // }
21348              // At end in "try harder" mode
21349              if (addOneDReader && tryHarder) {
21350                  readers.push(new MultiFormatOneDReader(hints));
21351              }
21352          }
21353          if (readers.length === 0) {
21354              if (!tryHarder) {
21355                  readers.push(new MultiFormatOneDReader(hints));
21356              }
21357              readers.push(new QRCodeReader());
21358              readers.push(new DataMatrixReader());
21359              readers.push(new AztecReader());
21360              readers.push(new PDF417Reader());
21361              // readers.push(new MaxiCodeReader())
21362              if (tryHarder) {
21363                  readers.push(new MultiFormatOneDReader(hints));
21364              }
21365          }
21366          this.readers = readers; // .toArray(new Reader[readers.size()])
21367      }
21368      /*@Override*/
21369      reset() {
21370          if (this.readers !== null) {
21371              for (const reader of this.readers) {
21372                  reader.reset();
21373              }
21374          }
21375      }
21376      /**
21377       * @throws NotFoundException
21378       */
21379      decodeInternal(image) {
21380          if (this.readers === null) {
21381              throw new ReaderException('No readers where selected, nothing can be read.');
21382          }
21383          for (const reader of this.readers) {
21384              // Trying to decode with ${reader} reader.
21385              try {
21386                  return reader.decode(image, this.hints);
21387              }
21388              catch (ex) {
21389                  if (ex instanceof ReaderException) {
21390                      continue;
21391                  }
21392                  // Bad Exception.
21393              }
21394          }
21395          throw new NotFoundException('No MultiFormat Readers were able to detect the code.');
21396      }
21397  }
21398
21399  class BrowserMultiFormatReader extends BrowserCodeReader {
21400      constructor(hints = null, timeBetweenScansMillis = 500) {
21401          const reader = new MultiFormatReader();
21402          reader.setHints(hints);
21403          super(reader, timeBetweenScansMillis);
21404      }
21405      /**
21406       * Overwrite decodeBitmap to call decodeWithState, which will pay
21407       * attention to the hints set in the constructor function
21408       */
21409      decodeBitmap(binaryBitmap) {
21410          return this.reader.decodeWithState(binaryBitmap);
vendor: 13,344 bytes, lines 21410-21692
21410
21411      }
21412  }
21413
21414  /**
21415   * @deprecated Moving to @zxing/browser
21416   *
21417   * QR Code reader to use from browser.
21418   */
21419  class BrowserPDF417Reader extends BrowserCodeReader {
21420      /**
21421       * Creates an instance of BrowserPDF417Reader.
21422       * @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
21423       */
21424      constructor(timeBetweenScansMillis = 500) {
21425          super(new PDF417Reader(), timeBetweenScansMillis);
21426      }
21427  }
21428
21429  /**
21430   * @deprecated Moving to @zxing/browser
21431   *
21432   * QR Code reader to use from browser.
21433   */
21434  class BrowserQRCodeReader extends BrowserCodeReader {
21435      /**
21436       * Creates an instance of BrowserQRCodeReader.
21437       * @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
21438       */
21439      constructor(timeBetweenScansMillis = 500) {
21440          super(new QRCodeReader(), timeBetweenScansMillis);
21441      }
21442  }
21443
21444  /*
21445   * Copyright 2009 ZXing authors
21446   *
21447   * Licensed under the Apache License, Version 2.0 (the "License");
21448   * you may not use this file except in compliance with the License.
21449   * You may obtain a copy of the License at
21450   *
21451   *      http://www.apache.org/licenses/LICENSE-2.0
21452   *
21453   * Unless required by applicable law or agreed to in writing, software
21454   * distributed under the License is distributed on an "AS IS" BASIS,
21455   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21456   * See the License for the specific language governing permissions and
21457   * limitations under the License.
21458   */
21459  /*namespace com.google.zxing {*/
21460  /**
21461   * These are a set of hints that you may pass to Writers to specify their behavior.
21462   *
21463   * @author [email protected] (Daniel Switkin)
21464   */
21465  var EncodeHintType;
21466  (function (EncodeHintType) {
21467      /**
21468       * Specifies what degree of error correction to use, for example in QR Codes.
21469       * Type depends on the encoder. For example for QR codes it's type
21470       * {@link com.google.zxing.qrcode.decoder.ErrorCorrectionLevel ErrorCorrectionLevel}.
21471       * For Aztec it is of type {@link Integer}, representing the minimal percentage of error correction words.
21472       * For PDF417 it is of type {@link Integer}, valid values being 0 to 8.
21473       * In all cases, it can also be a {@link String} representation of the desired value as well.
21474       * Note: an Aztec symbol should have a minimum of 25% EC words.
21475       */
21476      EncodeHintType[EncodeHintType["ERROR_CORRECTION"] = 0] = "ERROR_CORRECTION";
21477      /**
21478       * Specifies what character encoding to use where applicable (type {@link String})
21479       */
21480      EncodeHintType[EncodeHintType["CHARACTER_SET"] = 1] = "CHARACTER_SET";
21481      /**
21482       * Specifies the matrix shape for Data Matrix (type {@link com.google.zxing.datamatrix.encoder.SymbolShapeHint})
21483       */
21484      EncodeHintType[EncodeHintType["DATA_MATRIX_SHAPE"] = 2] = "DATA_MATRIX_SHAPE";
21485      /**
21486       * Specifies whether to use compact mode for Data Matrix (type {@link Boolean}, or "true" or "false"
21487       * {@link String } value).
21488       * The compact encoding mode also supports the encoding of characters that are not in the ISO-8859-1
21489       * character set via ECIs.
21490       * Please note that in that case, the most compact character encoding is chosen for characters in
21491       * the input that are not in the ISO-8859-1 character set. Based on experience, some scanners do not
21492       * support encodings like cp-1256 (Arabic). In such cases the encoding can be forced to UTF-8 by
21493       * means of the {@link #CHARACTER_SET} encoding hint.
21494       * Compact encoding also provides GS1-FNC1 support when {@link #GS1_FORMAT} is selected. In this case
21495       * group-separator character (ASCII 29 decimal) can be used to encode the positions of FNC1 codewords
21496       * for the purpose of delimiting AIs.
21497       * This option and {@link #FORCE_C40} are mutually exclusive.
21498       */
21499      EncodeHintType[EncodeHintType["DATA_MATRIX_COMPACT"] = 3] = "DATA_MATRIX_COMPACT";
21500      /**
21501       * Specifies a minimum barcode size (type {@link Dimension}). Only applicable to Data Matrix now.
21502       *
21503       * @deprecated use width/height params in
21504       * {@link com.google.zxing.datamatrix.DataMatrixWriter#encode(String, BarcodeFormat, int, int)}
21505       */
21506      /*@Deprecated*/
21507      EncodeHintType[EncodeHintType["MIN_SIZE"] = 4] = "MIN_SIZE";
21508      /**
21509       * Specifies a maximum barcode size (type {@link Dimension}). Only applicable to Data Matrix now.
21510       *
21511       * @deprecated without replacement
21512       */
21513      /*@Deprecated*/
21514      EncodeHintType[EncodeHintType["MAX_SIZE"] = 5] = "MAX_SIZE";
21515      /**
21516       * Specifies margin, in pixels, to use when generating the barcode. The meaning can vary
21517       * by format; for example it controls margin before and after the barcode horizontally for
21518       * most 1D formats. (Type {@link Integer}, or {@link String} representation of the integer value).
21519       */
21520      EncodeHintType[EncodeHintType["MARGIN"] = 6] = "MARGIN";
21521      /**
21522       * Specifies whether to use compact mode for PDF417 (type {@link Boolean}, or "true" or "false"
21523       * {@link String} value).
21524       */
21525      EncodeHintType[EncodeHintType["PDF417_COMPACT"] = 7] = "PDF417_COMPACT";
21526      /**
21527       * Specifies what compaction mode to use for PDF417 (type
21528       * {@link com.google.zxing.pdf417.encoder.Compaction Compaction} or {@link String} value of one of its
21529       * enum values).
21530       */
21531      EncodeHintType[EncodeHintType["PDF417_COMPACTION"] = 8] = "PDF417_COMPACTION";
21532      /**
21533       * Specifies the minimum and maximum number of rows and columns for PDF417 (type
21534       * {@link com.google.zxing.pdf417.encoder.Dimensions Dimensions}).
21535       */
21536      EncodeHintType[EncodeHintType["PDF417_DIMENSIONS"] = 9] = "PDF417_DIMENSIONS";
21537      /**
21538       * Specifies the required number of layers for an Aztec code.
21539       * A negative number (-1, -2, -3, -4) specifies a compact Aztec code.
21540       * 0 indicates to use the minimum number of layers (the default).
21541       * A positive number (1, 2, .. 32) specifies a normal (non-compact) Aztec code.
21542       * (Type {@link Integer}, or {@link String} representation of the integer value).
21543       */
21544      EncodeHintType[EncodeHintType["AZTEC_LAYERS"] = 10] = "AZTEC_LAYERS";
21545      /**
21546       * Specifies the exact version of QR code to be encoded.
21547       * (Type {@link Integer}, or {@link String} representation of the integer value).
21548       */
21549      EncodeHintType[EncodeHintType["QR_VERSION"] = 11] = "QR_VERSION";
21550      /**
21551       * Specifies whether the data should be encoded to the GS1 standard (type {@link Boolean}, or "true" or "false"
21552       * {@link String } value).
21553       */
21554      EncodeHintType[EncodeHintType["GS1_FORMAT"] = 12] = "GS1_FORMAT";
21555      /**
21556       * Forces C40 encoding for data-matrix (type {@link Boolean}, or "true" or "false") {@link String } value). This
21557       * option and {@link #DATA_MATRIX_COMPACT} are mutually exclusive.
21558       */
21559      EncodeHintType[EncodeHintType["FORCE_C40"] = 13] = "FORCE_C40";
21560  })(EncodeHintType || (EncodeHintType = {}));
21561  var EncodeHintType$1 = EncodeHintType;
21562
21563  /*
21564   * Copyright 2008 ZXing authors
21565   *
21566   * Licensed under the Apache License, Version 2.0 (the "License");
21567   * you may not use this file except in compliance with the License.
21568   * You may obtain a copy of the License at
21569   *
21570   *      http://www.apache.org/licenses/LICENSE-2.0
21571   *
21572   * Unless required by applicable law or agreed to in writing, software
21573   * distributed under the License is distributed on an "AS IS" BASIS,
21574   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21575   * See the License for the specific language governing permissions and
21576   * limitations under the License.
21577   */
21578  /**
21579   * <p>Implements Reed-Solomon encoding, as the name implies.</p>
21580   *
21581   * @author Sean Owen
21582   * @author William Rucklidge
21583   */
21584  class ReedSolomonEncoder {
21585      /**
21586       * A reed solomon error-correcting encoding constructor is created by
21587       * passing as Galois Field with of size equal to the number of code
21588       * words (symbols) in the alphabet (the number of values in each
21589       * element of arrays that are encoded/decoded).
21590       * @param field A galois field with a number of elements equal to the size
21591       * of the alphabet of symbols to encode.
21592       */
21593      constructor(field) {
21594          this.field = field;
21595          this.cachedGenerators = [];
21596          this.cachedGenerators.push(new GenericGFPoly(field, Int32Array.from([1])));
21597      }
21598      buildGenerator(degree /*int*/) {
21599          const cachedGenerators = this.cachedGenerators;
21600          if (degree >= cachedGenerators.length) {
21601              let lastGenerator = cachedGenerators[cachedGenerators.length - 1];
21602              const field = this.field;
21603              for (let d = cachedGenerators.length; d <= degree; d++) {
21604                  const nextGenerator = lastGenerator.multiply(new GenericGFPoly(field, Int32Array.from([1, field.exp(d - 1 + field.getGeneratorBase())])));
21605                  cachedGenerators.push(nextGenerator);
21606                  lastGenerator = nextGenerator;
21607              }
21608          }
21609          return cachedGenerators[degree];
21610      }
21611      /**
21612       * <p>Encode a sequence of code words (symbols) using Reed-Solomon to allow decoders
21613       * to detect and correct errors that may have been introduced when the resulting
21614       * data is stored or transmitted.</p>
21615       *
21616       * @param toEncode array used for both and output. Caller initializes the array with
21617       * the code words (symbols) to be encoded followed by empty elements allocated to make
21618       * space for error-correction code words in the encoded output. The array contains
21619       * the encdoded output when encode returns. Code words are encoded as numbers from
21620       * 0 to n-1, where n is the number of possible code words (symbols), as determined
21621       * by the size of the Galois Field passed in the constructor of this object.
21622       * @param ecBytes the number of elements reserved in the array (first parameter)
21623       * to store error-correction code words. Thus, the number of code words (symbols)
21624       * to encode in the first parameter is thus toEncode.length - ecBytes.
21625       * Note, the use of "bytes" in the name of this parameter is misleading, as there may
21626       * be more or fewer than 256 symbols being encoded, as determined by the number of
21627       * elements in the Galois Field passed as a constructor to this object.
21628       * @throws IllegalArgumentException thrown in response to validation errros.
21629       */
21630      encode(toEncode, ecBytes /*int*/) {
21631          if (ecBytes === 0) {
21632              throw new IllegalArgumentException('No error correction bytes');
21633          }
21634          const dataBytes = toEncode.length - ecBytes;
21635          if (dataBytes <= 0) {
21636              throw new IllegalArgumentException('No data bytes provided');
21637          }
21638          const generator = this.buildGenerator(ecBytes);
21639          const infoCoefficients = new Int32Array(dataBytes);
21640          System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
21641          let info = new GenericGFPoly(this.field, infoCoefficients);
21642          info = info.multiplyByMonomial(ecBytes, 1);
21643          const remainder = info.divide(generator)[1];
21644          const coefficients = remainder.getCoefficients();
21645          const numZeroCoefficients = ecBytes - coefficients.length;
21646          for (let i = 0; i < numZeroCoefficients; i++) {
21647              toEncode[dataBytes + i] = 0;
21648          }
21649          System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length);
21650      }
21651  }
21652
21653  /*
21654   * Copyright 2008 ZXing authors
21655   *
21656   * Licensed under the Apache License, Version 2.0 (the "License");
21657   * you may not use this file except in compliance with the License.
21658   * You may obtain a copy of the License at
21659   *
21660   *      http://www.apache.org/licenses/LICENSE-2.0
21661   *
21662   * Unless required by applicable law or agreed to in writing, software
21663   * distributed under the License is distributed on an "AS IS" BASIS,
21664   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21665   * See the License for the specific language governing permissions and
21666   * limitations under the License.
21667   */
21668  /**
21669   * @author Satoru Takabayashi
21670   * @author Daniel Switkin
21671   * @author Sean Owen
21672   */
21673  class MaskUtil {
21674      constructor() {
21675          // do nothing
21676      }
21677      /**
21678       * Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and
21679       * give penalty to them. Example: 00000 or 11111.
21680       */
21681      static applyMaskPenaltyRule1(matrix) {
21682          return MaskUtil.applyMaskPenaltyRule1Internal(matrix, true) + MaskUtil.applyMaskPenaltyRule1Internal(matrix, false);
21683      }
21684      /**
21685       * Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give
21686       * penalty to them. This is actually equivalent to the spec's rule, which is to find MxN blocks and give a
21687       * penalty proportional to (M-1)x(N-1), because this is the number of 2x2 blocks inside such a block.
21688       */
21689      static applyMaskPenaltyRule2(matrix) {
21690          let penalty = 0;
21691          const array = matrix.getArray();
21692          const width 
vendor: 6,851 bytes, lines 21692-21866
21692= matrix.getWidth();
21693          const height = matrix.getHeight();
21694          for (let y = 0; y < height - 1; y++) {
21695              const arrayY = array[y];
21696              for (let x = 0; x < width - 1; x++) {
21697                  const value = arrayY[x];
21698                  if (value === arrayY[x + 1] && value === array[y + 1][x] && value === array[y + 1][x + 1]) {
21699                      penalty++;
21700                  }
21701              }
21702          }
21703          return MaskUtil.N2 * penalty;
21704      }
21705      /**
21706       * Apply mask penalty rule 3 and return the penalty. Find consecutive runs of 1:1:3:1:1:4
21707       * starting with black, or 4:1:1:3:1:1 starting with white, and give penalty to them.  If we
21708       * find patterns like 000010111010000, we give penalty once.
21709       */
21710      static applyMaskPenaltyRule3(matrix) {
21711          let numPenalties = 0;
21712          const array = matrix.getArray();
21713          const width = matrix.getWidth();
21714          const height = matrix.getHeight();
21715          for (let y = 0; y < height; y++) {
21716              for (let x = 0; x < width; x++) {
21717                  const arrayY = array[y]; // We can at least optimize this access
21718                  if (x + 6 < width &&
21719                      arrayY[x] === 1 &&
21720                      arrayY[x + 1] === 0 &&
21721                      arrayY[x + 2] === 1 &&
21722                      arrayY[x + 3] === 1 &&
21723                      arrayY[x + 4] === 1 &&
21724                      arrayY[x + 5] === 0 &&
21725                      arrayY[x + 6] === 1 &&
21726                      (MaskUtil.isWhiteHorizontal(arrayY, x - 4, x) || MaskUtil.isWhiteHorizontal(arrayY, x + 7, x + 11))) {
21727                      numPenalties++;
21728                  }
21729                  if (y + 6 < height &&
21730                      array[y][x] === 1 &&
21731                      array[y + 1][x] === 0 &&
21732                      array[y + 2][x] === 1 &&
21733                      array[y + 3][x] === 1 &&
21734                      array[y + 4][x] === 1 &&
21735                      array[y + 5][x] === 0 &&
21736                      array[y + 6][x] === 1 &&
21737                      (MaskUtil.isWhiteVertical(array, x, y - 4, y) || MaskUtil.isWhiteVertical(array, x, y + 7, y + 11))) {
21738                      numPenalties++;
21739                  }
21740              }
21741          }
21742          return numPenalties * MaskUtil.N3;
21743      }
21744      static isWhiteHorizontal(rowArray, from /*int*/, to /*int*/) {
21745          from = Math.max(from, 0);
21746          to = Math.min(to, rowArray.length);
21747          for (let i = from; i < to; i++) {
21748              if (rowArray[i] === 1) {
21749                  return false;
21750              }
21751          }
21752          return true;
21753      }
21754      static isWhiteVertical(array, col /*int*/, from /*int*/, to /*int*/) {
21755          from = Math.max(from, 0);
21756          to = Math.min(to, array.length);
21757          for (let i = from; i < to; i++) {
21758              if (array[i][col] === 1) {
21759                  return false;
21760              }
21761          }
21762          return true;
21763      }
21764      /**
21765       * Apply mask penalty rule 4 and return the penalty. Calculate the ratio of dark cells and give
21766       * penalty if the ratio is far from 50%. It gives 10 penalty for 5% distance.
21767       */
21768      static applyMaskPenaltyRule4(matrix) {
21769          let numDarkCells = 0;
21770          const array = matrix.getArray();
21771          const width = matrix.getWidth();
21772          const height = matrix.getHeight();
21773          for (let y = 0; y < height; y++) {
21774              const arrayY = array[y];
21775              for (let x = 0; x < width; x++) {
21776                  if (arrayY[x] === 1) {
21777                      numDarkCells++;
21778                  }
21779              }
21780          }
21781          const numTotalCells = matrix.getHeight() * matrix.getWidth();
21782          const fivePercentVariances = Math.floor(Math.abs(numDarkCells * 2 - numTotalCells) * 10 / numTotalCells);
21783          return fivePercentVariances * MaskUtil.N4;
21784      }
21785      /**
21786       * Return the mask bit for "getMaskPattern" at "x" and "y". See 8.8 of JISX0510:2004 for mask
21787       * pattern conditions.
21788       */
21789      static getDataMaskBit(maskPattern /*int*/, x /*int*/, y /*int*/) {
21790          let intermediate; /*int*/
21791          let temp; /*int*/
21792          switch (maskPattern) {
21793              case 0:
21794                  intermediate = (y + x) & 0x1;
21795                  break;
21796              case 1:
21797                  intermediate = y & 0x1;
21798                  break;
21799              case 2:
21800                  intermediate = x % 3;
21801                  break;
21802              case 3:
21803                  intermediate = (y + x) % 3;
21804                  break;
21805              case 4:
21806                  intermediate = (Math.floor(y / 2) + Math.floor(x / 3)) & 0x1;
21807                  break;
21808              case 5:
21809                  temp = y * x;
21810                  intermediate = (temp & 0x1) + (temp % 3);
21811                  break;
21812              case 6:
21813                  temp = y * x;
21814                  intermediate = ((temp & 0x1) + (temp % 3)) & 0x1;
21815                  break;
21816              case 7:
21817                  temp = y * x;
21818                  intermediate = ((temp % 3) + ((y + x) & 0x1)) & 0x1;
21819                  break;
21820              default:
21821                  throw new IllegalArgumentException('Invalid mask pattern: ' + maskPattern);
21822          }
21823          return intermediate === 0;
21824      }
21825      /**
21826       * Helper function for applyMaskPenaltyRule1. We need this for doing this calculation in both
21827       * vertical and horizontal orders respectively.
21828       */
21829      static applyMaskPenaltyRule1Internal(matrix, isHorizontal) {
21830          let penalty = 0;
21831          const iLimit = isHorizontal ? matrix.getHeight() : matrix.getWidth();
21832          const jLimit = isHorizontal ? matrix.getWidth() : matrix.getHeight();
21833          const array = matrix.getArray();
21834          for (let i = 0; i < iLimit; i++) {
21835              let numSameBitCells = 0;
21836              let prevBit = -1;
21837              for (let j = 0; j < jLimit; j++) {
21838                  const bit = isHorizontal ? array[i][j] : array[j][i];
21839                  if (bit === prevBit) {
21840                      numSameBitCells++;
21841                  }
21842                  else {
21843                      if (numSameBitCells >= 5) {
21844                          penalty += MaskUtil.N1 + (numSameBitCells - 5);
21845                      }
21846                      numSameBitCells = 1; // Include the cell itself.
21847                      prevBit = bit;
21848                  }
21849              }
21850              if (numSameBitCells >= 5) {
21851                  penalty += MaskUtil.N1 + (numSameBitCells - 5);
21852              }
21853          }
21854          return penalty;
21855      }
21856  }
21857  // Penalty weights from section 6.8.2.1
21858  MaskUtil.N1 = 3;
21859  MaskUtil.N2 = 3;
21860  MaskUtil.N3 = 40;
21861  MaskUtil.N4 = 10;
21862
21863  /*
21864   * Copyright 2008 ZXing authors
21865   *
21866   * Licensed under the Apache License, Version 2.0 (the "License");
21867   * you may not use this file except in compliance with the License.
21868   * You may obtain a copy of the License at
21869   *
21870   *      http://www.apache.org/licenses/LICENSE-2.0
21871   *
21872   * Unless required by applicable law or agreed to in writing, software
21873   * distributed under the License is distributed on an "AS IS" BASIS,
21874   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21875   * See the License for the specific language governing permissions and
21876   * limitations under the License.
21877   */
21878  /**
21879   * JAVAPORT: The original code was a 2D array of ints, but since it only ever gets assigned
21880   * -1, 0, and 1, I'm going to use less memory and go with bytes.
21881   *
21882   * @author [email protected] (Daniel Switkin)
21883   */
21884  class ByteMatrix {
21885      constructor(width /*int*/, height /*int*/) {
21886          this.width = width;
21887          this.height = height;
21888          const bytes = new Array(height); // [height][width]
21889          for (let i = 0; i !== height; i++) {
21890              bytes[i] = new Uint8Array(width);
21891          }
21892          this.bytes = bytes;
21893      }
21894      getHeight() {
21895          return this.height;
21896      }
21897      getWidth() {
21898          return this.width;
21899      }
21900      get(x /*int*/, y /*int*/) {
21901          return this.bytes[y][x];
21902      }
21903      /**
21904       * @return an internal representation as bytes, in row-major order. array[y][x] represents point (x,y)
21905       */
21906      getArray() {
21907          return this.bytes;
21908      }
21909      // TYPESCRIPTPORT: preffer to let two methods instead of override to avoid type comparison inside
21910      setNumber(x /*int*/, y /*int*/, value /*byte|int*/) {
21911          this.bytes[y][x] = value;
21912      }
21913      // public set(x: number /*int*/, y: number /*int*/, value: number /*int*/): void {
21914      //   bytes[y][x] = (byte) value
21915      // }
21916      setBoolean(x /*int*/, y /*int*/, value) {
21917          this.bytes[y][x] = /*(byte) */ (value ? 1 : 0);
21918      }
21919      clear(value /*byte*/) {
21920          for (const aByte of this.bytes) {
21921              Arrays.fill(aByte, value);
21922          }
21923      }
21924      equals(o) {
21925          if (!(o instanceof ByteMatrix)) {
21926              return false;
21927          }
21928          const other = o;
21929          if (this.width !== other.width) {
21930              return false;
21931          }
21932          if (this.height !== other.height) {
21933              return false;
21934          }
21935          for (let y = 0, height = this.height; y < height; ++y) {
21936              const bytesY = this.bytes[y];
21937              const otherBytesY = other.bytes[y];
21938              for (let x = 0, width = this.width; x < width; ++x) {
21939                  if (bytesY[x] !== otherBytesY[x]) {
21940                      return false;
21941                  }
21942              }
21943          }
21944          return true;
21945      }
21946      /*@Override*/
21947      toString() {
21948          const result = new StringBuilder(); // (2 * width * height + 2)
21949          for (let y = 0, height = this.height; y < height; ++y) {
21950              const bytesY = this.bytes[y];
21951              for (let x = 0, width = this.width; x < width; ++x) {
21952                  switch (bytesY[x]) {
21953                      case 0:
21954                          result.append(' 0');
21955                          break;
21956                      case 1:
21957                          result.append(' 1');
21958                          break;
21959                      default:
21960                          result.append('  ');
21961                          break;
21962                  }
21963              }
21964              result.append('\n');
21965          }
21966          return result.toString();
21967      }
21968  }
21969
21970  /*
21971   * Copyright 2008 ZXing authors
21972   *
21973   * Licensed under the Apache License, Version 2.0 (the "License");
21974   * you may not use this file except in compliance with the License.
21975   * You may obtain a copy of the License at
21976   *
21977   *      http://www.apache.org/licenses/LICENSE-2.0
21978   *
21979   * Unless required by applicable law or agreed to in writing, software
21980   * distributed under the License is distributed on an "AS IS" BASIS,
21981   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21982   * See the License for the specific language governing permissions and
21983   * limitations under the License.
21984   */
21985  /**
21986   * @author [email protected] (Satoru Takabayashi) - creator
21987   * @author [email protected] (Daniel Switkin) - ported from C++
21988   */
21989  class QRCode {
21990      constructor() {
21991          this.maskPattern = -1;
21992      }
21993      getMode() {
21994          return this.mode;
21995      }
21996      getECLevel() {
21997          return this.ecLevel;
21998      }
21999      getVersion() {
22000          return this.version;
22001      }
22002      getMaskPattern() {
22003          return this.maskPattern;
22004      }
22005      getMatrix() {
22006          return this.matrix;
22007      }
22008      /*@Override*/
22009      toString() {
22010          const result = new StringBuilder(); // (200)
22011          result.append('<<\n');
22012          result.append(' mode: ');
22013          result.append(this.mode ? this.mode.toString() : 'null');
22014          result.append('\n ecLevel: ');
22015          result.append(this.ecLevel ? this.ecLevel.toString() : 'null');
22016          result.append('\n version: ');
22017          result.append(this.version ? this.version.toString() : 'null');
22018          result.append('\n maskPattern: ');
22019          result.append(this.maskPattern.toString());
22020          if (this.matrix) {
22021              result.append('\n matrix:\n');
22022              result.append(this.matrix.toString());
22023          }
22024          else {
22025              result.append('\n matrix: null\n');
22026          }
22027          result.append('>>\n');
22028          return result.toString();
22029      }
22030      setMode(value) {
22031          this.mode = value;
22032      }
22033      setECLevel(value) {
22034          this.ecLevel = value;
22035      }
22036      setVersion(version) {
22037          this.version = version;
22038      }
22039      setMaskPattern(value /*int*/) {
22040          this.maskPattern = value;
22041      }
22042      setMatrix(value) {
22043          this.matrix = value;
22044      }
22045      // Check if "mask_pattern" is valid.
22046      static isValidMaskPattern(maskPattern /*int*/) {
22047          return maskPattern >= 0 && maskPattern < QRCode.NUM_MASK_PATTERNS;
22048      }
22049  }
22050  QRCode.NUM_MASK_PATTERNS = 8;
22051
22052  /**
22053   * Custom Error class of type Exception.
22054   */
22055  class WriterException extends Exception {
22056  }
22057  WriterException.kind = 'WriterException';
22058
22059  /*
22060   * Copyright 2008 ZXing authors
22061   *
22062   * Licensed under the Apache License, Version 2.0 (the "License");
22063   * you may not use this file except in compliance with the License.
22064   * You may obtain a copy of the License at
22065   *
22066   *      http://www.apache.org/licenses/LICENSE-2.0
22067   *
22068   * Unless required by applicable law or agreed to in writing, software
22069   * distributed under the License is distributed on an "AS IS" BASIS,
22070   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22071   * See the License for the specific language governing permissions and
22072   * limitations under the License.
22073   
vendor: 16,835 bytes, lines 22073-22416
22073*/
22074  /**
22075   * @author [email protected] (Satoru Takabayashi) - creator
22076   * @author [email protected] (Daniel Switkin) - ported from C++
22077   */
22078  class MatrixUtil {
22079      constructor() {
22080          // do nothing
22081      }
22082      // Set all cells to -1 (TYPESCRIPTPORT: 255).  -1 (TYPESCRIPTPORT: 255) means that the cell is empty (not set yet).
22083      //
22084      // JAVAPORT: We shouldn't need to do this at all. The code should be rewritten to begin encoding
22085      // with the ByteMatrix initialized all to zero.
22086      static clearMatrix(matrix) {
22087          // TYPESCRIPTPORT: we use UintArray se changed here from -1 to 255
22088          matrix.clear(/*(byte) */ /*-1*/ 255);
22089      }
22090      // Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On
22091      // success, store the result in "matrix" and return true.
22092      static buildMatrix(dataBits, ecLevel, version, maskPattern /*int*/, matrix) {
22093          MatrixUtil.clearMatrix(matrix);
22094          MatrixUtil.embedBasicPatterns(version, matrix);
22095          // Type information appear with any version.
22096          MatrixUtil.embedTypeInfo(ecLevel, maskPattern, matrix);
22097          // Version info appear if version >= 7.
22098          MatrixUtil.maybeEmbedVersionInfo(version, matrix);
22099          // Data should be embedded at end.
22100          MatrixUtil.embedDataBits(dataBits, maskPattern, matrix);
22101      }
22102      // Embed basic patterns. On success, modify the matrix and return true.
22103      // The basic patterns are:
22104      // - Position detection patterns
22105      // - Timing patterns
22106      // - Dark dot at the left bottom corner
22107      // - Position adjustment patterns, if need be
22108      static embedBasicPatterns(version, matrix) {
22109          // Let's get started with embedding big squares at corners.
22110          MatrixUtil.embedPositionDetectionPatternsAndSeparators(matrix);
22111          // Then, embed the dark dot at the left bottom corner.
22112          MatrixUtil.embedDarkDotAtLeftBottomCorner(matrix);
22113          // Position adjustment patterns appear if version >= 2.
22114          MatrixUtil.maybeEmbedPositionAdjustmentPatterns(version, matrix);
22115          // Timing patterns should be embedded after position adj. patterns.
22116          MatrixUtil.embedTimingPatterns(matrix);
22117      }
22118      // Embed type information. On success, modify the matrix.
22119      static embedTypeInfo(ecLevel, maskPattern /*int*/, matrix) {
22120          const typeInfoBits = new BitArray();
22121          MatrixUtil.makeTypeInfoBits(ecLevel, maskPattern, typeInfoBits);
22122          for (let i = 0, size = typeInfoBits.getSize(); i < size; ++i) {
22123              // Place bits in LSB to MSB order.  LSB (least significant bit) is the last value in
22124              // "typeInfoBits".
22125              const bit = typeInfoBits.get(typeInfoBits.getSize() - 1 - i);
22126              // Type info bits at the left top corner. See 8.9 of JISX0510:2004 (p.46).
22127              const coordinates = MatrixUtil.TYPE_INFO_COORDINATES[i];
22128              const x1 = coordinates[0];
22129              const y1 = coordinates[1];
22130              matrix.setBoolean(x1, y1, bit);
22131              if (i < 8) {
22132                  // Right top corner.
22133                  const x2 = matrix.getWidth() - i - 1;
22134                  const y2 = 8;
22135                  matrix.setBoolean(x2, y2, bit);
22136              }
22137              else {
22138                  // Left bottom corner.
22139                  const x2 = 8;
22140                  const y2 = matrix.getHeight() - 7 + (i - 8);
22141                  matrix.setBoolean(x2, y2, bit);
22142              }
22143          }
22144      }
22145      // Embed version information if need be. On success, modify the matrix and return true.
22146      // See 8.10 of JISX0510:2004 (p.47) for how to embed version information.
22147      static maybeEmbedVersionInfo(version, matrix) {
22148          if (version.getVersionNumber() < 7) { // Version info is necessary if version >= 7.
22149              return; // Don't need version info.
22150          }
22151          const versionInfoBits = new BitArray();
22152          MatrixUtil.makeVersionInfoBits(version, versionInfoBits);
22153          let bitIndex = 6 * 3 - 1; // It will decrease from 17 to 0.
22154          for (let i = 0; i < 6; ++i) {
22155              for (let j = 0; j < 3; ++j) {
22156                  // Place bits in LSB (least significant bit) to MSB order.
22157                  const bit = versionInfoBits.get(bitIndex);
22158                  bitIndex--;
22159                  // Left bottom corner.
22160                  matrix.setBoolean(i, matrix.getHeight() - 11 + j, bit);
22161                  // Right bottom corner.
22162                  matrix.setBoolean(matrix.getHeight() - 11 + j, i, bit);
22163              }
22164          }
22165      }
22166      // Embed "dataBits" using "getMaskPattern". On success, modify the matrix and return true.
22167      // For debugging purposes, it skips masking process if "getMaskPattern" is -1(TYPESCRIPTPORT: 255).
22168      // See 8.7 of JISX0510:2004 (p.38) for how to embed data bits.
22169      static embedDataBits(dataBits, maskPattern /*int*/, matrix) {
22170          let bitIndex = 0;
22171          let direction = -1;
22172          // Start from the right bottom cell.
22173          let x = matrix.getWidth() - 1;
22174          let y = matrix.getHeight() - 1;
22175          while (x > 0) {
22176              // Skip the vertical timing pattern.
22177              if (x === 6) {
22178                  x -= 1;
22179              }
22180              while (y >= 0 && y < matrix.getHeight()) {
22181                  for (let i = 0; i < 2; ++i) {
22182                      const xx = x - i;
22183                      // Skip the cell if it's not empty.
22184                      if (!MatrixUtil.isEmpty(matrix.get(xx, y))) {
22185                          continue;
22186                      }
22187                      let bit;
22188                      if (bitIndex < dataBits.getSize()) {
22189                          bit = dataBits.get(bitIndex);
22190                          ++bitIndex;
22191                      }
22192                      else {
22193                          // Padding bit. If there is no bit left, we'll fill the left cells with 0, as described
22194                          // in 8.4.9 of JISX0510:2004 (p. 24).
22195                          bit = false;
22196                      }
22197                      // Skip masking if mask_pattern is -1 (TYPESCRIPTPORT: 255).
22198                      if (maskPattern !== 255 && MaskUtil.getDataMaskBit(maskPattern, xx, y)) {
22199                          bit = !bit;
22200                      }
22201                      matrix.setBoolean(xx, y, bit);
22202                  }
22203                  y += direction;
22204              }
22205              direction = -direction; // Reverse the direction.
22206              y += direction;
22207              x -= 2; // Move to the left.
22208          }
22209          // All bits should be consumed.
22210          if (bitIndex !== dataBits.getSize()) {
22211              throw new WriterException('Not all bits consumed: ' + bitIndex + '/' + dataBits.getSize());
22212          }
22213      }
22214      // Return the position of the most significant bit set (one: to) in the "value". The most
22215      // significant bit is position 32. If there is no bit set, return 0. Examples:
22216      // - findMSBSet(0) => 0
22217      // - findMSBSet(1) => 1
22218      // - findMSBSet(255) => 8
22219      static findMSBSet(value /*int*/) {
22220          return 32 - Integer.numberOfLeadingZeros(value);
22221      }
22222      // Calculate BCH (Bose-Chaudhuri-Hocquenghem) code for "value" using polynomial "poly". The BCH
22223      // code is used for encoding type information and version information.
22224      // Example: Calculation of version information of 7.
22225      // f(x) is created from 7.
22226      //   - 7 = 000111 in 6 bits
22227      //   - f(x) = x^2 + x^1 + x^0
22228      // g(x) is given by the standard (p. 67)
22229      //   - g(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1
22230      // Multiply f(x) by x^(18 - 6)
22231      //   - f'(x) = f(x) * x^(18 - 6)
22232      //   - f'(x) = x^14 + x^13 + x^12
22233      // Calculate the remainder of f'(x) / g(x)
22234      //         x^2
22235      //         __________________________________________________
22236      //   g(x) )x^14 + x^13 + x^12
22237      //         x^14 + x^13 + x^12 + x^11 + x^10 + x^7 + x^4 + x^2
22238      //         --------------------------------------------------
22239      //                              x^11 + x^10 + x^7 + x^4 + x^2
22240      //
22241      // The remainder is x^11 + x^10 + x^7 + x^4 + x^2
22242      // Encode it in binary: 110010010100
22243      // The return value is 0xc94 (1100 1001 0100)
22244      //
22245      // Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit
22246      // operations. We don't care if coefficients are positive or negative.
22247      static calculateBCHCode(value /*int*/, poly /*int*/) {
22248          if (poly === 0) {
22249              throw new IllegalArgumentException('0 polynomial');
22250          }
22251          // If poly is "1 1111 0010 0101" (version info poly), msbSetInPoly is 13. We'll subtract 1
22252          // from 13 to make it 12.
22253          const msbSetInPoly = MatrixUtil.findMSBSet(poly);
22254          value <<= msbSetInPoly - 1;
22255          // Do the division business using exclusive-or operations.
22256          while (MatrixUtil.findMSBSet(value) >= msbSetInPoly) {
22257              value ^= poly << (MatrixUtil.findMSBSet(value) - msbSetInPoly);
22258          }
22259          // Now the "value" is the remainder (i.e. the BCH code)
22260          return value;
22261      }
22262      // Make bit vector of type information. On success, store the result in "bits" and return true.
22263      // Encode error correction level and mask pattern. See 8.9 of
22264      // JISX0510:2004 (p.45) for details.
22265      static makeTypeInfoBits(ecLevel, maskPattern /*int*/, bits) {
22266          if (!QRCode.isValidMaskPattern(maskPattern)) {
22267              throw new WriterException('Invalid mask pattern');
22268          }
22269          const typeInfo = (ecLevel.getBits() << 3) | maskPattern;
22270          bits.appendBits(typeInfo, 5);
22271          const bchCode = MatrixUtil.calculateBCHCode(typeInfo, MatrixUtil.TYPE_INFO_POLY);
22272          bits.appendBits(bchCode, 10);
22273          const maskBits = new BitArray();
22274          maskBits.appendBits(MatrixUtil.TYPE_INFO_MASK_PATTERN, 15);
22275          bits.xor(maskBits);
22276          if (bits.getSize() !== 15) { // Just in case.
22277              throw new WriterException('should not happen but we got: ' + bits.getSize());
22278          }
22279      }
22280      // Make bit vector of version information. On success, store the result in "bits" and return true.
22281      // See 8.10 of JISX0510:2004 (p.45) for details.
22282      static makeVersionInfoBits(version, bits) {
22283          bits.appendBits(version.getVersionNumber(), 6);
22284          const bchCode = MatrixUtil.calculateBCHCode(version.getVersionNumber(), MatrixUtil.VERSION_INFO_POLY);
22285          bits.appendBits(bchCode, 12);
22286          if (bits.getSize() !== 18) { // Just in case.
22287              throw new WriterException('should not happen but we got: ' + bits.getSize());
22288          }
22289      }
22290      // Check if "value" is empty.
22291      static isEmpty(value /*int*/) {
22292          return value === 255; // -1
22293      }
22294      static embedTimingPatterns(matrix) {
22295          // -8 is for skipping position detection patterns (7: size), and two horizontal/vertical
22296          // separation patterns (1: size). Thus, 8 = 7 + 1.
22297          for (let i = 8; i < matrix.getWidth() - 8; ++i) {
22298              const bit = (i + 1) % 2;
22299              // Horizontal line.
22300              if (MatrixUtil.isEmpty(matrix.get(i, 6))) {
22301                  matrix.setNumber(i, 6, bit);
22302              }
22303              // Vertical line.
22304              if (MatrixUtil.isEmpty(matrix.get(6, i))) {
22305                  matrix.setNumber(6, i, bit);
22306              }
22307          }
22308      }
22309      // Embed the lonely dark dot at left bottom corner. JISX0510:2004 (p.46)
22310      static embedDarkDotAtLeftBottomCorner(matrix) {
22311          if (matrix.get(8, matrix.getHeight() - 8) === 0) {
22312              throw new WriterException();
22313          }
22314          matrix.setNumber(8, matrix.getHeight() - 8, 1);
22315      }
22316      static embedHorizontalSeparationPattern(xStart /*int*/, yStart /*int*/, matrix) {
22317          for (let x = 0; x < 8; ++x) {
22318              if (!MatrixUtil.isEmpty(matrix.get(xStart + x, yStart))) {
22319                  throw new WriterException();
22320              }
22321              matrix.setNumber(xStart + x, yStart, 0);
22322          }
22323      }
22324      static embedVerticalSeparationPattern(xStart /*int*/, yStart /*int*/, matrix) {
22325          for (let y = 0; y < 7; ++y) {
22326              if (!MatrixUtil.isEmpty(matrix.get(xStart, yStart + y))) {
22327                  throw new WriterException();
22328              }
22329              matrix.setNumber(xStart, yStart + y, 0);
22330          }
22331      }
22332      static embedPositionAdjustmentPattern(xStart /*int*/, yStart /*int*/, matrix) {
22333          for (let y = 0; y < 5; ++y) {
22334              const patternY = MatrixUtil.POSITION_ADJUSTMENT_PATTERN[y];
22335              for (let x = 0; x < 5; ++x) {
22336                  matrix.setNumber(xStart + x, yStart + y, patternY[x]);
22337              }
22338          }
22339      }
22340      static embedPositionDetectionPattern(xStart /*int*/, yStart /*int*/, matrix) {
22341          for (let y = 0; y < 7; ++y) {
22342              const patternY = MatrixUtil.POSITION_DETECTION_PATTERN[y];
22343              for (let x = 0; x < 7; ++x) {
22344                  matrix.setNumber(xStart + x, yStart + y, patternY[x]);
22345              }
22346          }
22347      }
22348      // Embed position detection patterns and surrounding vertical/horizontal separators.
22349      static embedPositionDetectionPatternsAndSeparators(matrix) {
22350          // Embed three big squares at corners.
22351          const pdpWidth = MatrixUtil.POSITION_DETECTION_PATTERN[0].length;
22352          // Left top corner.
22353          MatrixUtil.embedPositionDetectionPattern(0, 0, matrix);
22354          // Right top corner.
22355          MatrixUtil.embedPositionDetectionPattern(matrix.getWidth() - pdpWidth, 0, matrix);
22356          // Left bottom corner.
22357          MatrixUtil.embedPositionDetectionPattern(0, matrix.getWidth() - pdpWidth, matrix);
22358          // Embed horizontal separation patterns around the squares.
22359          const hspWidth = 8;
22360          // Left top corner.
22361          MatrixUtil.embedHorizontalSeparationPattern(0, hspWidth - 1, matrix);
22362          // Right top corner.
22363          MatrixUtil.embedHorizontalSeparationPattern(matrix.getWidth() - hspWidth, hspWidth - 1, matrix);
22364          // Left bottom corner.
22365          MatrixUtil.embedHorizontalSeparationPattern(0, matrix.getWidth() - hspWidth, matrix);
22366          // Embed vertical separation patterns around the squares.
22367          const vspSize = 7;
22368          // Left top corner.
22369          MatrixUtil.embedVerticalSeparationPattern(vspSize, 0, matrix);
22370          // Right top corner.
22371          MatrixUtil.embedVerticalSeparationPattern(matrix.getHeight() - vspSize - 1, 0, matrix);
22372          // Left bottom corner.
22373          MatrixUtil.embedVerticalSeparationPattern(vspSize, matrix.getHeight() - vspSize, matrix);
22374      }
22375      // Embed position adjustment patterns if need be.
22376      static maybeEmbedPositionAdjustmentPatterns(version, matrix) {
22377          if (version.getVersionNumber() < 2) { // The patterns appear if version >= 2
22378              return;
22379          }
22380          const index = version.getVersionNumber() - 1;
22381          const coordinates = MatrixUtil.POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index];
22382          for (let i = 0, length = coordinates.length; i !== length; i++) {
22383              const y = coordinates[i];
22384              if (y >= 0) {
22385                  for (let j = 0; j !== length; j++) {
22386                      const x = coordinates[j];
22387                      if (x >= 0 && MatrixUtil.isEmpty(matrix.get(x, y))) {
22388                          // If the cell is unset, we embed the position adjustment pattern here.
22389                          // -2 is necessary since the x/y coordinates point to the center of the pattern, not the
22390                          // left top corner.
22391                          MatrixUtil.embedPositionAdjustmentPattern(x - 2, y - 2, matrix);
22392                      }
22393                  }
22394              }
22395          }
22396      }
22397  }
22398  MatrixUtil.POSITION_DETECTION_PATTERN = Array.from([
22399      Int32Array.from([1, 1, 1, 1, 1, 1, 1]),
22400      Int32Array.from([1, 0, 0, 0, 0, 0, 1]),
22401      Int32Array.from([1, 0, 1, 1, 1, 0, 1]),
22402      Int32Array.from([1, 0, 1, 1, 1, 0, 1]),
22403      Int32Array.from([1, 0, 1, 1, 1, 0, 1]),
22404      Int32Array.from([1, 0, 0, 0, 0, 0, 1]),
22405      Int32Array.from([1, 1, 1, 1, 1, 1, 1]),
22406  ]);
22407  MatrixUtil.POSITION_ADJUSTMENT_PATTERN = Array.from([
22408      Int32Array.from([1, 1, 1, 1, 1]),
22409      Int32Array.from([1, 0, 0, 0, 1]),
22410      Int32Array.from([1, 0, 1, 0, 1]),
22411      Int32Array.from([1, 0, 0, 0, 1]),
22412      Int32Array.from([1, 1, 1, 1, 1]),
22413  ]);
22414  // From Appendix E. Table 1, JIS0510X:2004 (71: p). The table was double-checked by komatsu.
22415  MatrixUtil.POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE = Array.from([
22416      Int32Array.from([-1, -1, -1, -1, -1, -1, -1]),
vendor: 2,987 bytes, lines 22416-22484
22416
22417      Int32Array.from([6, 18, -1, -1, -1, -1, -1]),
22418      Int32Array.from([6, 22, -1, -1, -1, -1, -1]),
22419      Int32Array.from([6, 26, -1, -1, -1, -1, -1]),
22420      Int32Array.from([6, 30, -1, -1, -1, -1, -1]),
22421      Int32Array.from([6, 34, -1, -1, -1, -1, -1]),
22422      Int32Array.from([6, 22, 38, -1, -1, -1, -1]),
22423      Int32Array.from([6, 24, 42, -1, -1, -1, -1]),
22424      Int32Array.from([6, 26, 46, -1, -1, -1, -1]),
22425      Int32Array.from([6, 28, 50, -1, -1, -1, -1]),
22426      Int32Array.from([6, 30, 54, -1, -1, -1, -1]),
22427      Int32Array.from([6, 32, 58, -1, -1, -1, -1]),
22428      Int32Array.from([6, 34, 62, -1, -1, -1, -1]),
22429      Int32Array.from([6, 26, 46, 66, -1, -1, -1]),
22430      Int32Array.from([6, 26, 48, 70, -1, -1, -1]),
22431      Int32Array.from([6, 26, 50, 74, -1, -1, -1]),
22432      Int32Array.from([6, 30, 54, 78, -1, -1, -1]),
22433      Int32Array.from([6, 30, 56, 82, -1, -1, -1]),
22434      Int32Array.from([6, 30, 58, 86, -1, -1, -1]),
22435      Int32Array.from([6, 34, 62, 90, -1, -1, -1]),
22436      Int32Array.from([6, 28, 50, 72, 94, -1, -1]),
22437      Int32Array.from([6, 26, 50, 74, 98, -1, -1]),
22438      Int32Array.from([6, 30, 54, 78, 102, -1, -1]),
22439      Int32Array.from([6, 28, 54, 80, 106, -1, -1]),
22440      Int32Array.from([6, 32, 58, 84, 110, -1, -1]),
22441      Int32Array.from([6, 30, 58, 86, 114, -1, -1]),
22442      Int32Array.from([6, 34, 62, 90, 118, -1, -1]),
22443      Int32Array.from([6, 26, 50, 74, 98, 122, -1]),
22444      Int32Array.from([6, 30, 54, 78, 102, 126, -1]),
22445      Int32Array.from([6, 26, 52, 78, 104, 130, -1]),
22446      Int32Array.from([6, 30, 56, 82, 108, 134, -1]),
22447      Int32Array.from([6, 34, 60, 86, 112, 138, -1]),
22448      Int32Array.from([6, 30, 58, 86, 114, 142, -1]),
22449      Int32Array.from([6, 34, 62, 90, 118, 146, -1]),
22450      Int32Array.from([6, 30, 54, 78, 102, 126, 150]),
22451      Int32Array.from([6, 24, 50, 76, 102, 128, 154]),
22452      Int32Array.from([6, 28, 54, 80, 106, 132, 158]),
22453      Int32Array.from([6, 32, 58, 84, 110, 136, 162]),
22454      Int32Array.from([6, 26, 54, 82, 110, 138, 166]),
22455      Int32Array.from([6, 30, 58, 86, 114, 142, 170]),
22456  ]);
22457  // Type info cells at the left top corner.
22458  MatrixUtil.TYPE_INFO_COORDINATES = Array.from([
22459      Int32Array.from([8, 0]),
22460      Int32Array.from([8, 1]),
22461      Int32Array.from([8, 2]),
22462      Int32Array.from([8, 3]),
22463      Int32Array.from([8, 4]),
22464      Int32Array.from([8, 5]),
22465      Int32Array.from([8, 7]),
22466      Int32Array.from([8, 8]),
22467      Int32Array.from([7, 8]),
22468      Int32Array.from([5, 8]),
22469      Int32Array.from([4, 8]),
22470      Int32Array.from([3, 8]),
22471      Int32Array.from([2, 8]),
22472      Int32Array.from([1, 8]),
22473      Int32Array.from([0, 8]),
22474  ]);
22475  // From Appendix D in JISX0510:2004 (p. 67)
22476  MatrixUtil.VERSION_INFO_POLY = 0x1f25; // 1 1111 0010 0101
22477  // From Appendix C in JISX0510:2004 (p.65).
22478  MatrixUtil.TYPE_INFO_POLY = 0x537;
22479  MatrixUtil.TYPE_INFO_MASK_PATTERN = 0x5412;
22480
22481  /*
22482   * Copyright 2008 ZXing authors
22483   *
22484   * Licensed under the Apache License, Version 2.0 (the "License");
22485   * you may not use this file except in compliance with the License.
22486   * You may obtain a copy of the License at
22487   *
22488   *      http://www.apache.org/licenses/LICENSE-2.0
22489   *
22490   * Unless required by applicable law or agreed to in writing, software
22491   * distributed under the License is distributed on an "AS IS" BASIS,
22492   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22493   * See the License for the specific language governing permissions and
22494   * limitations under the License.
22495   */
22496  /*namespace com.google.zxing.qrcode.encoder {*/
22497  class BlockPair {
22498      constructor(dataBytes, errorCorrectionBytes) {
22499          this.dataBytes = dataBytes;
22500          this.errorCorrectionBytes = errorCorrectionBytes;
22501      }
22502      getDataBytes() {
22503          return this.dataBytes;
22504      }
22505      getErrorCorrectionBytes() {
22506          return this.errorCorrectionBytes;
22507      }
22508  }
22509
22510  /*
22511   * Copyright 2008 ZXing authors
22512   *
22513   * Licensed under the Apache License, Version 2.0 (the "License");
22514   * you may not use this file except in compliance with the License.
22515   * You may obtain a copy of the License at
22516   *
22517   *      http://www.apache.org/licenses/LICENSE-2.0
22518   *
22519   * Unless required by applicable law or agreed to in writing, software
22520   * distributed under the License is distributed on an "AS IS" BASIS,
22521   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22522   * See the License for the specific language governing permissions and
22523   * limitations under the License.
22524   */
22525  /*import java.io.UnsupportedEncodingException;*/
22526  /*import java.util.ArrayList;*/
22527  /*import java.util.Collection;*/
22528  /*import java.util.Map;*/
22529  /**
22530   * @author [email protected] (Satoru Takabayashi) - creator
22531   * @author [email protected] (Daniel Switkin) - ported from C++
22532   */
22533  class Encoder$1 {
22534      // TYPESCRIPTPORT: changed to UTF8, the default for js
22535      constructor() { }
22536      // The mask penalty calculation is complicated.  See Table 21 of JISX0510:2004 (p.45) for details.
22537      // Basically it applies four rules and summate all penalties.
22538      static calculateMaskPenalty(matrix) {
22539          return MaskUtil.applyMaskPenaltyRule1(matrix)
22540              + MaskUtil.applyMaskPenaltyRule2(matrix)
22541              + MaskUtil.applyMaskPenaltyRule3(matrix)
22542              + MaskUtil.applyMaskPenaltyRule4(matrix);
22543      }
22544      /**
22545       * @param content text to encode
22546       * @param ecLevel error correction level to use
22547       * @return {@link QRCode} representing the encoded QR code
22548       * @throws WriterException if encoding can't succeed, because of for example invalid content
22549       *   or configuration
22550       */
22551      // public static encode(content: string, ecLevel: ErrorCorrectionLevel): QRCode /*throws WriterException*/ {
22552      //   return encode(content, ecLevel, null)
22553      // }
22554      static encode(content, ecLevel, hints = null) {
22555          // Determine what character encoding has been specified by the caller, if any
22556          let encoding = Encoder$1.DEFAULT_BYTE_MODE_ENCODING;
22557          const hasEncodingHint = hints !== null && undefined !== hints.get(EncodeHintType$1.CHARACTER_SET);
22558          if (hasEncodingHint) {
22559              encoding = hints.get(EncodeHintType$1.CHARACTER_SET).toString();
22560          }
22561          // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
22562          // multiple modes / segments even if that were more efficient. Twould be nice.
22563          const mode = this.chooseMode(content, encoding);
22564          // This will store the header information, like mode and
22565          // length, as well as "header" segments like an ECI segment.
22566          const headerBits = new BitArray();
22567          // Append ECI segment if applicable
22568          if (mode === Mode$2.BYTE && (hasEncodingHint || Encoder$1.DEFAULT_BYTE_MODE_ENCODING !== encoding)) {
22569              const eci = CharacterSetECI.getCharacterSetECIByName(encoding);
22570              if (eci !== undefined) {
22571                  this.appendECI(eci, headerBits);
22572              }
22573          }
22574          // (With ECI in place,) Write the mode marker
22575          this.appendModeInfo(mode, headerBits);
22576          // Collect data within the main segment, separately, to count its size if needed. Don't add it to
22577          // main payload yet.
22578          const dataBits = new BitArray();
22579          this.appendBytes(content, mode, dataBits, encoding);
22580          let version;
22581          if (hints !== null && undefined !== hints.get(EncodeHintType$1.QR_VERSION)) {
22582              const versionNumber = Number.parseInt(hints.get(EncodeHintType$1.QR_VERSION).toString(), 10);
22583              version = Version.getVersionForNumber(versionNumber);
22584              const bitsNeeded = this.calculateBitsNeeded(mode, headerBits, dataBits, version);
22585              if (!this.willFit(bitsNeeded, version, ecLevel)) {
22586                  throw new WriterException('Data too big for requested version');
22587              }
22588          }
22589          else {
22590              version = this.recommendVersion(ecLevel, mode, headerBits, dataBits);
22591          }
vendor: 20,568 bytes, lines 22592-23039
22592          const headerAndDataBits = new BitArray();
22593          headerAndDataBits.appendBitArray(headerBits);
22594          // Find "length" of main segment and write it
22595          const numLetters = mode === Mode$2.BYTE ? dataBits.getSizeInBytes() : content.length;
22596          this.appendLengthInfo(numLetters, version, mode, headerAndDataBits);
22597          // Put data together into the overall payload
22598          headerAndDataBits.appendBitArray(dataBits);
22599          const ecBlocks = version.getECBlocksForLevel(ecLevel);
22600          const numDataBytes = version.getTotalCodewords() - ecBlocks.getTotalECCodewords();
22601          // Terminate the bits properly.
22602          this.terminateBits(numDataBytes, headerAndDataBits);
22603          // Interleave data bits with error correction code.
22604          const finalBits = this.interleaveWithECBytes(headerAndDataBits, version.getTotalCodewords(), numDataBytes, ecBlocks.getNumBlocks());
22605          const qrCode = new QRCode();
22606          qrCode.setECLevel(ecLevel);
22607          qrCode.setMode(mode);
22608          qrCode.setVersion(version);
22609          //  Choose the mask pattern and set to "qrCode".
22610          const dimension = version.getDimensionForVersion();
22611          const matrix = new ByteMatrix(dimension, dimension);
22612          const maskPattern = this.chooseMaskPattern(finalBits, ecLevel, version, matrix);
22613          qrCode.setMaskPattern(maskPattern);
22614          // Build the matrix and set it to "qrCode".
22615          MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
22616          qrCode.setMatrix(matrix);
22617          return qrCode;
22618      }
22619      /**
22620       * Decides the smallest version of QR code that will contain all of the provided data.
22621       *
22622       * @throws WriterException if the data cannot fit in any version
22623       */
22624      static recommendVersion(ecLevel, mode, headerBits, dataBits) {
22625          // Hard part: need to know version to know how many bits length takes. But need to know how many
22626          // bits it takes to know version. First we take a guess at version by assuming version will be
22627          // the minimum, 1:
22628          const provisionalBitsNeeded = this.calculateBitsNeeded(mode, headerBits, dataBits, Version.getVersionForNumber(1));
22629          const provisionalVersion = this.chooseVersion(provisionalBitsNeeded, ecLevel);
22630          // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
22631          const bitsNeeded = this.calculateBitsNeeded(mode, headerBits, dataBits, provisionalVersion);
22632          return this.chooseVersion(bitsNeeded, ecLevel);
22633      }
22634      static calculateBitsNeeded(mode, headerBits, dataBits, version) {
22635          return headerBits.getSize() + mode.getCharacterCountBits(version) + dataBits.getSize();
22636      }
22637      /**
22638       * @return the code point of the table used in alphanumeric mode or
22639       *  -1 if there is no corresponding code in the table.
22640       */
22641      static getAlphanumericCode(code /*int*/) {
22642          if (code < Encoder$1.ALPHANUMERIC_TABLE.length) {
22643              return Encoder$1.ALPHANUMERIC_TABLE[code];
22644          }
22645          return -1;
22646      }
22647      // public static chooseMode(content: string): Mode {
22648      //   return chooseMode(content, null);
22649      // }
22650      /**
22651       * Choose the best mode by examining the content. Note that 'encoding' is used as a hint;
22652       * if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}.
22653       */
22654      static chooseMode(content, encoding = null) {
22655          if (CharacterSetECI.SJIS.getName() === encoding && this.isOnlyDoubleByteKanji(content)) {
22656              // Choose Kanji mode if all input are double-byte characters
22657              return Mode$2.KANJI;
22658          }
22659          let hasNumeric = false;
22660          let hasAlphanumeric = false;
22661          for (let i = 0, length = content.length; i < length; ++i) {
22662              const c = content.charAt(i);
22663              if (Encoder$1.isDigit(c)) {
22664                  hasNumeric = true;
22665              }
22666              else if (this.getAlphanumericCode(c.charCodeAt(0)) !== -1) {
22667                  hasAlphanumeric = true;
22668              }
22669              else {
22670                  return Mode$2.BYTE;
22671              }
22672          }
22673          if (hasAlphanumeric) {
22674              return Mode$2.ALPHANUMERIC;
22675          }
22676          if (hasNumeric) {
22677              return Mode$2.NUMERIC;
22678          }
22679          return Mode$2.BYTE;
22680      }
22681      static isOnlyDoubleByteKanji(content) {
22682          let bytes;
22683          try {
22684              bytes = StringEncoding.encode(content, CharacterSetECI.SJIS); // content.getBytes("Shift_JIS"))
22685          }
22686          catch (ignored /*: UnsupportedEncodingException*/) {
22687              return false;
22688          }
22689          const length = bytes.length;
22690          if (length % 2 !== 0) {
22691              return false;
22692          }
22693          for (let i = 0; i < length; i += 2) {
22694              const byte1 = bytes[i] & 0xFF;
22695              if ((byte1 < 0x81 || byte1 > 0x9F) && (byte1 < 0xE0 || byte1 > 0xEB)) {
22696                  return false;
22697              }
22698          }
22699          return true;
22700      }
22701      static chooseMaskPattern(bits, ecLevel, version, matrix) {
22702          let minPenalty = Number.MAX_SAFE_INTEGER; // Lower penalty is better.
22703          let bestMaskPattern = -1;
22704          // We try all mask patterns to choose the best one.
22705          for (let maskPattern = 0; maskPattern < QRCode.NUM_MASK_PATTERNS; maskPattern++) {
22706              MatrixUtil.buildMatrix(bits, ecLevel, version, maskPattern, matrix);
22707              let penalty = this.calculateMaskPenalty(matrix);
22708              if (penalty < minPenalty) {
22709                  minPenalty = penalty;
22710                  bestMaskPattern = maskPattern;
22711              }
22712          }
22713          return bestMaskPattern;
22714      }
22715      static chooseVersion(numInputBits /*int*/, ecLevel) {
22716          for (let versionNum = 1; versionNum <= 40; versionNum++) {
22717              const version = Version.getVersionForNumber(versionNum);
22718              if (Encoder$1.willFit(numInputBits, version, ecLevel)) {
22719                  return version;
22720              }
22721          }
22722          throw new WriterException('Data too big');
22723      }
22724      /**
22725       * @return true if the number of input bits will fit in a code with the specified version and
22726       * error correction level.
22727       */
22728      static willFit(numInputBits /*int*/, version, ecLevel) {
22729          // In the following comments, we use numbers of Version 7-H.
22730          // numBytes = 196
22731          const numBytes = version.getTotalCodewords();
22732          // getNumECBytes = 130
22733          const ecBlocks = version.getECBlocksForLevel(ecLevel);
22734          const numEcBytes = ecBlocks.getTotalECCodewords();
22735          // getNumDataBytes = 196 - 130 = 66
22736          const numDataBytes = numBytes - numEcBytes;
22737          const totalInputBytes = (numInputBits + 7) / 8;
22738          return numDataBytes >= totalInputBytes;
22739      }
22740      /**
22741       * Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24).
22742       */
22743      static terminateBits(numDataBytes /*int*/, bits) {
22744          const capacity = numDataBytes * 8;
22745          if (bits.getSize() > capacity) {
22746              throw new WriterException('data bits cannot fit in the QR Code' + bits.getSize() + ' > ' +
22747                  capacity);
22748          }
22749          for (let i = 0; i < 4 && bits.getSize() < capacity; ++i) {
22750              bits.appendBit(false);
22751          }
22752          // Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details.
22753          // If the last byte isn't 8-bit aligned, we'll add padding bits.
22754          const numBitsInLastByte = bits.getSize() & 0x07;
22755          if (numBitsInLastByte > 0) {
22756              for (let i = numBitsInLastByte; i < 8; i++) {
22757                  bits.appendBit(false);
22758              }
22759          }
22760          // If we have more space, we'll fill the space with padding patterns defined in 8.4.9 (p.24).
22761          const numPaddingBytes = numDataBytes - bits.getSizeInBytes();
22762          for (let i = 0; i < numPaddingBytes; ++i) {
22763              bits.appendBits((i & 0x01) === 0 ? 0xEC : 0x11, 8);
22764          }
22765          if (bits.getSize() !== capacity) {
22766              throw new WriterException('Bits size does not equal capacity');
22767          }
22768      }
22769      /**
22770       * Get number of data bytes and number of error correction bytes for block id "blockID". Store
22771       * the result in "numDataBytesInBlock", and "numECBytesInBlock". See table 12 in 8.5.1 of
22772       * JISX0510:2004 (p.30)
22773       */
22774      static getNumDataBytesAndNumECBytesForBlockID(numTotalBytes /*int*/, numDataBytes /*int*/, numRSBlocks /*int*/, blockID /*int*/, numDataBytesInBlock, numECBytesInBlock) {
22775          if (blockID >= numRSBlocks) {
22776              throw new WriterException('Block ID too large');
22777          }
22778          // numRsBlocksInGroup2 = 196 % 5 = 1
22779          const numRsBlocksInGroup2 = numTotalBytes % numRSBlocks;
22780          // numRsBlocksInGroup1 = 5 - 1 = 4
22781          const numRsBlocksInGroup1 = numRSBlocks - numRsBlocksInGroup2;
22782          // numTotalBytesInGroup1 = 196 / 5 = 39
22783          const numTotalBytesInGroup1 = Math.floor(numTotalBytes / numRSBlocks);
22784          // numTotalBytesInGroup2 = 39 + 1 = 40
22785          const numTotalBytesInGroup2 = numTotalBytesInGroup1 + 1;
22786          // numDataBytesInGroup1 = 66 / 5 = 13
22787          const numDataBytesInGroup1 = Math.floor(numDataBytes / numRSBlocks);
22788          // numDataBytesInGroup2 = 13 + 1 = 14
22789          const numDataBytesInGroup2 = numDataBytesInGroup1 + 1;
22790          // numEcBytesInGroup1 = 39 - 13 = 26
22791          const numEcBytesInGroup1 = numTotalBytesInGroup1 - numDataBytesInGroup1;
22792          // numEcBytesInGroup2 = 40 - 14 = 26
22793          const numEcBytesInGroup2 = numTotalBytesInGroup2 - numDataBytesInGroup2;
22794          // Sanity checks.
22795          // 26 = 26
22796          if (numEcBytesInGroup1 !== numEcBytesInGroup2) {
22797              throw new WriterException('EC bytes mismatch');
22798          }
22799          // 5 = 4 + 1.
22800          if (numRSBlocks !== numRsBlocksInGroup1 + numRsBlocksInGroup2) {
22801              throw new WriterException('RS blocks mismatch');
22802          }
22803          // 196 = (13 + 26) * 4 + (14 + 26) * 1
22804          if (numTotalBytes !==
22805              ((numDataBytesInGroup1 + numEcBytesInGroup1) *
22806                  numRsBlocksInGroup1) +
22807                  ((numDataBytesInGroup2 + numEcBytesInGroup2) *
22808                      numRsBlocksInGroup2)) {
22809              throw new WriterException('Total bytes mismatch');
22810          }
22811          if (blockID < numRsBlocksInGroup1) {
22812              numDataBytesInBlock[0] = numDataBytesInGroup1;
22813              numECBytesInBlock[0] = numEcBytesInGroup1;
22814          }
22815          else {
22816              numDataBytesInBlock[0] = numDataBytesInGroup2;
22817              numECBytesInBlock[0] = numEcBytesInGroup2;
22818          }
22819      }
22820      /**
22821       * Interleave "bits" with corresponding error correction bytes. On success, store the result in
22822       * "result". The interleave rule is complicated. See 8.6 of JISX0510:2004 (p.37) for details.
22823       */
22824      static interleaveWithECBytes(bits, numTotalBytes /*int*/, numDataBytes /*int*/, numRSBlocks /*int*/) {
22825          // "bits" must have "getNumDataBytes" bytes of data.
22826          if (bits.getSizeInBytes() !== numDataBytes) {
22827              throw new WriterException('Number of bits and data bytes does not match');
22828          }
22829          // Step 1.  Divide data bytes into blocks and generate error correction bytes for them. We'll
22830          // store the divided data bytes blocks and error correction bytes blocks into "blocks".
22831          let dataBytesOffset = 0;
22832          let maxNumDataBytes = 0;
22833          let maxNumEcBytes = 0;
22834          // Since, we know the number of reedsolmon blocks, we can initialize the vector with the number.
22835          const blocks = new Array(); // new Array<BlockPair>(numRSBlocks)
22836          for (let i = 0; i < numRSBlocks; ++i) {
22837              const numDataBytesInBlock = new Int32Array(1);
22838              const numEcBytesInBlock = new Int32Array(1);
22839              Encoder$1.getNumDataBytesAndNumECBytesForBlockID(numTotalBytes, numDataBytes, numRSBlocks, i, numDataBytesInBlock, numEcBytesInBlock);
22840              const size = numDataBytesInBlock[0];
22841              const dataBytes = new Uint8Array(size);
22842              bits.toBytes(8 * dataBytesOffset, dataBytes, 0, size);
22843              const ecBytes = Encoder$1.generateECBytes(dataBytes, numEcBytesInBlock[0]);
22844              blocks.push(new BlockPair(dataBytes, ecBytes));
22845              maxNumDataBytes = Math.max(maxNumDataBytes, size);
22846              maxNumEcBytes = Math.max(maxNumEcBytes, ecBytes.length);
22847              dataBytesOffset += numDataBytesInBlock[0];
22848          }
22849          if (numDataBytes !== dataBytesOffset) {
22850              throw new WriterException('Data bytes does not match offset');
22851          }
22852          const result = new BitArray();
22853          // First, place data blocks.
22854          for (let i = 0; i < maxNumDataBytes; ++i) {
22855              for (const block of blocks) {
22856                  const dataBytes = block.getDataBytes();
22857                  if (i < dataBytes.length) {
22858                      result.appendBits(dataBytes[i], 8);
22859                  }
22860              }
22861          }
22862          // Then, place error correction blocks.
22863          for (let i = 0; i < maxNumEcBytes; ++i) {
22864              for (const block of blocks) {
22865                  const ecBytes = block.getErrorCorrectionBytes();
22866                  if (i < ecBytes.length) {
22867                      result.appendBits(ecBytes[i], 8);
22868                  }
22869              }
22870          }
22871          if (numTotalBytes !== result.getSizeInBytes()) { // Should be same.
22872              throw new WriterException('Interleaving error: ' + numTotalBytes + ' and ' +
22873                  result.getSizeInBytes() + ' differ.');
22874          }
22875          return result;
22876      }
22877      static generateECBytes(dataBytes, numEcBytesInBlock /*int*/) {
22878          const numDataBytes = dataBytes.length;
22879          const toEncode = new Int32Array(numDataBytes + numEcBytesInBlock); // int[numDataBytes + numEcBytesInBlock]
22880          for (let i = 0; i < numDataBytes; i++) {
22881              toEncode[i] = dataBytes[i] & 0xFF;
22882          }
22883          new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256).encode(toEncode, numEcBytesInBlock);
22884          const ecBytes = new Uint8Array(numEcBytesInBlock);
22885          for (let i = 0; i < numEcBytesInBlock; i++) {
22886              ecBytes[i] = /*(byte) */ toEncode[numDataBytes + i];
22887          }
22888          return ecBytes;
22889      }
22890      /**
22891       * Append mode info. On success, store the result in "bits".
22892       */
22893      static appendModeInfo(mode, bits) {
22894          bits.appendBits(mode.getBits(), 4);
22895      }
22896      /**
22897       * Append length info. On success, store the result in "bits".
22898       */
22899      static appendLengthInfo(numLetters /*int*/, version, mode, bits) {
22900          const numBits = mode.getCharacterCountBits(version);
22901          if (numLetters >= (1 << numBits)) {
22902              throw new WriterException(numLetters + ' is bigger than ' + ((1 << numBits) - 1));
22903          }
22904          bits.appendBits(numLetters, numBits);
22905      }
22906      /**
22907       * Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
22908       */
22909      static appendBytes(content, mode, bits, encoding) {
22910          switch (mode) {
22911              case Mode$2.NUMERIC:
22912                  Encoder$1.appendNumericBytes(content, bits);
22913                  break;
22914              case Mode$2.ALPHANUMERIC:
22915                  Encoder$1.appendAlphanumericBytes(content, bits);
22916                  break;
22917              case Mode$2.BYTE:
22918                  Encoder$1.append8BitBytes(content, bits, encoding);
22919                  break;
22920              case Mode$2.KANJI:
22921                  Encoder$1.appendKanjiBytes(content, bits);
22922                  break;
22923              default:
22924                  throw new WriterException('Invalid mode: ' + mode);
22925          }
22926      }
22927      static getDigit(singleCharacter) {
22928          return singleCharacter.charCodeAt(0) - 48;
22929      }
22930      static isDigit(singleCharacter) {
22931          const cn = Encoder$1.getDigit(singleCharacter);
22932          return cn >= 0 && cn <= 9;
22933      }
22934      static appendNumericBytes(content, bits) {
22935          const length = content.length;
22936          let i = 0;
22937          while (i < length) {
22938              const num1 = Encoder$1.getDigit(content.charAt(i));
22939              if (i + 2 < length) {
22940                  // Encode three numeric letters in ten bits.
22941                  const num2 = Encoder$1.getDigit(content.charAt(i + 1));
22942                  const num3 = Encoder$1.getDigit(content.charAt(i + 2));
22943                  bits.appendBits(num1 * 100 + num2 * 10 + num3, 10);
22944                  i += 3;
22945              }
22946              else if (i + 1 < length) {
22947                  // Encode two numeric letters in seven bits.
22948                  const num2 = Encoder$1.getDigit(content.charAt(i + 1));
22949                  bits.appendBits(num1 * 10 + num2, 7);
22950                  i += 2;
22951              }
22952              else {
22953                  // Encode one numeric letter in four bits.
22954                  bits.appendBits(num1, 4);
22955                  i++;
22956              }
22957          }
22958      }
22959      static appendAlphanumericBytes(content, bits) {
22960          const length = content.length;
22961          let i = 0;
22962          while (i < length) {
22963              const code1 = Encoder$1.getAlphanumericCode(content.charCodeAt(i));
22964              if (code1 === -1) {
22965                  throw new WriterException();
22966              }
22967              if (i + 1 < length) {
22968                  const code2 = Encoder$1.getAlphanumericCode(content.charCodeAt(i + 1));
22969                  if (code2 === -1) {
22970                      throw new WriterException();
22971                  }
22972                  // Encode two alphanumeric letters in 11 bits.
22973                  bits.appendBits(code1 * 45 + code2, 11);
22974                  i += 2;
22975              }
22976              else {
22977                  // Encode one alphanumeric letter in six bits.
22978                  bits.appendBits(code1, 6);
22979                  i++;
22980              }
22981          }
22982      }
22983      static append8BitBytes(content, bits, encoding) {
22984          let bytes;
22985          try {
22986              bytes = StringEncoding.encode(content, encoding);
22987          }
22988          catch (uee /*: UnsupportedEncodingException*/) {
22989              throw new WriterException(uee);
22990          }
22991          for (let i = 0, length = bytes.length; i !== length; i++) {
22992              const b = bytes[i];
22993              bits.appendBits(b, 8);
22994          }
22995      }
22996      /**
22997       * @throws WriterException
22998       */
22999      static appendKanjiBytes(content, bits) {
23000          let bytes;
23001          try {
23002              bytes = StringEncoding.encode(content, CharacterSetECI.SJIS);
23003          }
23004          catch (uee /*: UnsupportedEncodingException*/) {
23005              throw new WriterException(uee);
23006          }
23007          const length = bytes.length;
23008          for (let i = 0; i < length; i += 2) {
23009              const byte1 = bytes[i] & 0xFF;
23010              const byte2 = bytes[i + 1] & 0xFF;
23011              const code = ((byte1 << 8) & 0xFFFFFFFF) | byte2;
23012              let subtracted = -1;
23013              if (code >= 0x8140 && code <= 0x9ffc) {
23014                  subtracted = code - 0x8140;
23015              }
23016              else if (code >= 0xe040 && code <= 0xebbf) {
23017                  subtracted = code - 0xc140;
23018              }
23019              if (subtracted === -1) {
23020                  throw new WriterException('Invalid byte sequence');
23021              }
23022              const encoded = ((subtracted >> 8) * 0xc0) + (subtracted & 0xff);
23023              bits.appendBits(encoded, 13);
23024          }
23025      }
23026      static appendECI(eci, bits) {
23027          bits.appendBits(Mode$2.ECI.getBits(), 4);
23028          // This is correct for values up to 127, which is all we need now.
23029          bits.appendBits(eci.getValue(), 8);
23030      }
23031  }
23032  // The original table is defined in the table 5 of JISX0510:2004 (p.19).
23033  Encoder$1.ALPHANUMERIC_TABLE = Int32Array.from([
23034      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23035      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23036      36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
23037      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
23038      -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
23039      25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
vendor: 6,038 bytes, lines 23039-23174
23039
23040  ]);
23041  Encoder$1.DEFAULT_BYTE_MODE_ENCODING = CharacterSetECI.UTF8.getName(); // "ISO-8859-1"
23042
23043  /**
23044   * @deprecated Moving to @zxing/browser
23045   */
23046  class BrowserQRCodeSvgWriter {
23047      /**
23048       * Writes and renders a QRCode SVG element.
23049       *
23050       * @param contents
23051       * @param width
23052       * @param height
23053       * @param hints
23054       */
23055      write(contents, width, height, hints = null) {
23056          if (contents.length === 0) {
23057              throw new IllegalArgumentException('Found empty contents');
23058          }
23059          // if (format != BarcodeFormat.QR_CODE) {
23060          //   throw new IllegalArgumentException("Can only encode QR_CODE, but got " + format)
23061          // }
23062          if (width < 0 || height < 0) {
23063              throw new IllegalArgumentException('Requested dimensions are too small: ' + width + 'x' + height);
23064          }
23065          let errorCorrectionLevel = ErrorCorrectionLevel.L;
23066          let quietZone = BrowserQRCodeSvgWriter.QUIET_ZONE_SIZE;
23067          if (hints !== null) {
23068              if (undefined !== hints.get(EncodeHintType$1.ERROR_CORRECTION)) {
23069                  errorCorrectionLevel = ErrorCorrectionLevel.fromString(hints.get(EncodeHintType$1.ERROR_CORRECTION).toString());
23070              }
23071              if (undefined !== hints.get(EncodeHintType$1.MARGIN)) {
23072                  quietZone = Number.parseInt(hints.get(EncodeHintType$1.MARGIN).toString(), 10);
23073              }
23074          }
23075          const code = Encoder$1.encode(contents, errorCorrectionLevel, hints);
23076          return this.renderResult(code, width, height, quietZone);
23077      }
23078      /**
23079       * Renders the result and then appends it to the DOM.
23080       */
23081      writeToDom(containerElement, contents, width, height, hints = null) {
23082          if (typeof containerElement === 'string') {
23083              containerElement = document.querySelector(containerElement);
23084          }
23085          const svgElement = this.write(contents, width, height, hints);
23086          if (containerElement)
23087              containerElement.appendChild(svgElement);
23088      }
23089      /**
23090       * Note that the input matrix uses 0 == white, 1 == black.
23091       * The output matrix uses 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
23092       */
23093      renderResult(code, width /*int*/, height /*int*/, quietZone /*int*/) {
23094          const input = code.getMatrix();
23095          if (input === null) {
23096              throw new IllegalStateException();
23097          }
23098          const inputWidth = input.getWidth();
23099          const inputHeight = input.getHeight();
23100          const qrWidth = inputWidth + (quietZone * 2);
23101          const qrHeight = inputHeight + (quietZone * 2);
23102          const outputWidth = Math.max(width, qrWidth);
23103          const outputHeight = Math.max(height, qrHeight);
23104          const multiple = Math.min(Math.floor(outputWidth / qrWidth), Math.floor(outputHeight / qrHeight));
23105          // Padding includes both the quiet zone and the extra white pixels to accommodate the requested
23106          // dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
23107          // If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
23108          // handle all the padding from 100x100 (the actual QR) up to 200x160.
23109          const leftPadding = Math.floor((outputWidth - (inputWidth * multiple)) / 2);
23110          const topPadding = Math.floor((outputHeight - (inputHeight * multiple)) / 2);
23111          const svgElement = this.createSVGElement(outputWidth, outputHeight);
23112          for (let inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
23113              // Write the contents of this row of the barcode
23114              for (let inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
23115                  if (input.get(inputX, inputY) === 1) {
23116                      const svgRectElement = this.createSvgRectElement(outputX, outputY, multiple, multiple);
23117                      svgElement.appendChild(svgRectElement);
23118                  }
23119              }
23120          }
23121          return svgElement;
23122      }
23123      /**
23124       * Creates a SVG element.
23125       *
23126       * @param w SVG's width attribute
23127       * @param h SVG's height attribute
23128       */
23129      createSVGElement(w, h) {
23130          const svgElement = document.createElementNS(BrowserQRCodeSvgWriter.SVG_NS, 'svg');
23131          svgElement.setAttributeNS(null, 'height', w.toString());
23132          svgElement.setAttributeNS(null, 'width', h.toString());
23133          return svgElement;
23134      }
23135      /**
23136       * Creates a SVG rect element.
23137       *
23138       * @param x Element's x coordinate
23139       * @param y Element's y coordinate
23140       * @param w Element's width attribute
23141       * @param h Element's height attribute
23142       */
23143      createSvgRectElement(x, y, w, h) {
23144          const rect = document.createElementNS(BrowserQRCodeSvgWriter.SVG_NS, 'rect');
23145          rect.setAttributeNS(null, 'x', x.toString());
23146          rect.setAttributeNS(null, 'y', y.toString());
23147          rect.setAttributeNS(null, 'height', w.toString());
23148          rect.setAttributeNS(null, 'width', h.toString());
23149          rect.setAttributeNS(null, 'fill', '#000000');
23150          return rect;
23151      }
23152  }
23153  BrowserQRCodeSvgWriter.QUIET_ZONE_SIZE = 4;
23154  /**
23155   * SVG markup NameSpace
23156   */
23157  BrowserQRCodeSvgWriter.SVG_NS = 'http://www.w3.org/2000/svg';
23158
23159  /*
23160   * Copyright 2008 ZXing authors
23161   *
23162   * Licensed under the Apache License, Version 2.0 (the "License");
23163   * you may not use this file except in compliance with the License.
23164   * You may obtain a copy of the License at
23165   *
23166   *      http://www.apache.org/licenses/LICENSE-2.0
23167   *
23168   * Unless required by applicable law or agreed to in writing, software
23169   * distributed under the License is distributed on an "AS IS" BASIS,
23170   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23171   * See the License for the specific language governing permissions and
23172   * limitations under the License.
23173   */
23174  /*
vendor: 3,829 bytes, lines 23174-23247
23174import java.util.Map;*/
23175  /**
23176   * This object renders a QR Code as a BitMatrix 2D array of greyscale values.
23177   *
23178   * @author [email protected] (Daniel Switkin)
23179   */
23180  class QRCodeWriter {
23181      /*@Override*/
23182      // public encode(contents: string, format: BarcodeFormat, width: number /*int*/, height: number /*int*/): BitMatrix
23183      //     /*throws WriterException */ {
23184      //   return encode(contents, format, width, height, null)
23185      // }
23186      /*@Override*/
23187      encode(contents, format, width /*int*/, height /*int*/, hints) {
23188          if (contents.length === 0) {
23189              throw new IllegalArgumentException('Found empty contents');
23190          }
23191          if (format !== BarcodeFormat$1.QR_CODE) {
23192              throw new IllegalArgumentException('Can only encode QR_CODE, but got ' + format);
23193          }
23194          if (width < 0 || height < 0) {
23195              throw new IllegalArgumentException(`Requested dimensions are too small: ${width}x${height}`);
23196          }
23197          let errorCorrectionLevel = ErrorCorrectionLevel.L;
23198          let quietZone = QRCodeWriter.QUIET_ZONE_SIZE;
23199          if (hints !== null) {
23200              if (undefined !== hints.get(EncodeHintType$1.ERROR_CORRECTION)) {
23201                  errorCorrectionLevel = ErrorCorrectionLevel.fromString(hints.get(EncodeHintType$1.ERROR_CORRECTION).toString());
23202              }
23203              if (undefined !== hints.get(EncodeHintType$1.MARGIN)) {
23204                  quietZone = Number.parseInt(hints.get(EncodeHintType$1.MARGIN).toString(), 10);
23205              }
23206          }
23207          const code = Encoder$1.encode(contents, errorCorrectionLevel, hints);
23208          return QRCodeWriter.renderResult(code, width, height, quietZone);
23209      }
23210      // Note that the input matrix uses 0 == white, 1 == black, while the output matrix uses
23211      // 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
23212      static renderResult(code, width /*int*/, height /*int*/, quietZone /*int*/) {
23213          const input = code.getMatrix();
23214          if (input === null) {
23215              throw new IllegalStateException();
23216          }
23217          const inputWidth = input.getWidth();
23218          const inputHeight = input.getHeight();
23219          const qrWidth = inputWidth + (quietZone * 2);
23220          const qrHeight = inputHeight + (quietZone * 2);
23221          const outputWidth = Math.max(width, qrWidth);
23222          const outputHeight = Math.max(height, qrHeight);
23223          const multiple = Math.min(Math.floor(outputWidth / qrWidth), Math.floor(outputHeight / qrHeight));
23224          // Padding includes both the quiet zone and the extra white pixels to accommodate the requested
23225          // dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
23226          // If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
23227          // handle all the padding from 100x100 (the actual QR) up to 200x160.
23228          const leftPadding = Math.floor((outputWidth - (inputWidth * multiple)) / 2);
23229          const topPadding = Math.floor((outputHeight - (inputHeight * multiple)) / 2);
23230          const output = new BitMatrix(outputWidth, outputHeight);
23231          for (let inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
23232              // Write the contents of this row of the barcode
23233              for (let inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
23234                  if (input.get(inputX, inputY) === 1) {
23235                      output.setRegion(outputX, outputY, multiple, multiple);
23236                  }
23237              }
23238          }
23239          return output;
23240      }
23241  }
23242  QRCodeWriter.QUIET_ZONE_SIZE = 4;
23243
23244  /*
23245   * Copyright 2008 ZXing authors
23246   *
23247   * Licensed under the Apache License, Version 2.0 (the "License");
23248   * you may not use this file except in compliance with the License.
23249   * You may obtain a copy of the License at
23250   *
23251   *      http://www.apache.org/licenses/LICENSE-2.0
23252   *
23253   * Unless required by applicable law or agreed to in writing, software
23254   * distributed under the License is distributed on an "AS IS" BASIS,
23255   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23256   * See the License for the specific language governing permissions and
23257   * limitations under the License.
23258   */
23259  /*import java.util.Map;*/
23260  /**
23261   * This is a factory class which finds the appropriate Writer subclass for the BarcodeFormat
23262   * requested and encodes the barcode with the supplied contents.
23263   *
23264   * @author [email protected] (Daniel Switkin)
23265   */
23266  class MultiFormatWriter {
23267      /*@Override*/
23268      // public encode(contents: string,
23269      //                         format: BarcodeFormat,
23270      //                         width: number /*int*/,
23271      //                         height: number /*int*/): BitMatrix /*throws WriterException */ {
23272      //   return encode(contents, format, width, height, null)
23273      // }
23274      /*@Override*/
23275      encode(contents, format, width /*int*/, height /*int*/, hints) {
23276          let writer;
23277          switch (format) {
23278              // case BarcodeFormat.EAN_8:
23279              //   writer = new EAN8Writer()
23280              //   break
23281              // case BarcodeFormat.UPC_E:
23282              //   writer = new UPCEWriter()
23283              //   break
23284              // case BarcodeFormat.EAN_13:
23285              //   writer = new EAN13Writer()
23286              //   break
23287              // case BarcodeFormat.UPC_A:
23288              //   writer = new UPCAWriter()
23289              //   break
23290              case BarcodeFormat$1.QR_CODE:
23291                  writer = new QRCodeWriter();
23292                  break;
23293              // case BarcodeFormat.CODE_39:
23294              //   writer = new Code39Writer()
23295              //   break
23296              // case BarcodeFormat.CODE_93:
23297              //   writer = new Code93Writer()
23298              //   break
23299              // case BarcodeFormat.CODE_128:
23300              //   writer = new Code128Writer()
23301              //   break
23302              // case BarcodeFormat.ITF:
23303              //   writer = new ITFWriter()
23304              //   break
23305              // case BarcodeFormat.PDF_417:
23306              //   writer = new PDF417Writer()
23307              //   break
23308              // case BarcodeFormat.CODABAR:
23309              //   writer = new CodaBarWriter()
23310              //   break
23311              // case BarcodeFormat.DATA_MATRIX:
23312              //   writer = new DataMatrixWriter()
23313              //   break
23314              // case BarcodeFormat.AZTEC:
23315              //   writer = new AztecWriter()
23316              //   break
23317              default:
23318                  throw new IllegalArgumentException('No encoder available for format ' + format);
23319          }
23320          return writer.encode(contents, format, width, height, hints);
23321      }
23322  }
23323
23324  /*
23325   * Copyright 2009 ZXing authors
23326   *
23327   * Licensed under the Apache License, Version 2.0 (the "License");
23328   * you may not use this file except in compliance with the License.
23329   * You may obtain a copy of the License at
23330   *
23331   *      http://www.apache.org/licenses/LICENSE-2.0
23332   *
23333   * Unless required by applicable law or agreed to in writing, software
23334   * distributed under the License is distributed on an "AS IS" BASIS,
23335   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23336   * See the License for the specific language governing permissions and
23337   * limitations under the License.
23338   */
23339  /**
23340   * This object extends LuminanceSource around an array of YUV data returned from the camera driver,
23341   * with the option to crop to a rectangle within the full data. This can be used to exclude
23342   * superfluous pixels around the perimeter and speed up decoding.
23343   *
23344   * It works for any pixel format where the Y channel is planar and appears first, including
23345   * YCbCr_420_SP and YCbCr_422_SP.
23346   *
23347   * @author [email protected] (Daniel Switkin)
23348   */
23349  class PlanarYUVLuminanceSource extends LuminanceSource {
23350      constructor(yuvData, dataWidth /*int*/, dataHeight /*int*/, left /*int*/, top /*int*/, width /*int*/, height /*int*/, reverseHorizontal) {
23351          super(width, height);
23352          this.yuvData = yuvData;
23353          this.dataWidth = dataWidth;
23354          this.dataHeight = dataHeight;
23355          this.left = left;
23356          this.top = top;
23357          if (left + width > dataWidth || top + height > dataHeight) {
23358              throw new IllegalArgumentException('Crop rectangle does not fit within image data.');
23359          }
23360          if (reverseHorizontal) {
23361              this.reverseHorizontal(width, height);
23362          }
23363      }
23364      /*@Override*/
23365      getRow(y /*int*/, row) {
23366          if (y < 0 || y >= this.getHeight()) {
23367              throw new IllegalArgumentException('Requested row is outside the image: ' + y);
23368          }
23369          const width = this.getWidth();
vendor: 4,349 bytes, lines 23370-23469
23370          if (row === null || row === undefined || row.length < width) {
23371              row = new Uint8ClampedArray(width);
23372          }
23373          const offset = (y + this.top) * this.dataWidth + this.left;
23374          System.arraycopy(this.yuvData, offset, row, 0, width);
23375          return row;
23376      }
23377      /*@Override*/
23378      getMatrix() {
23379          const width = this.getWidth();
23380          const height = this.getHeight();
23381          // If the caller asks for the entire underlying image, save the copy and give them the
23382          // original data. The docs specifically warn that result.length must be ignored.
23383          if (width === this.dataWidth && height === this.dataHeight) {
23384              return this.yuvData;
23385          }
23386          const area = width * height;
23387          const matrix = new Uint8ClampedArray(area);
23388          let inputOffset = this.top * this.dataWidth + this.left;
23389          // If the width matches the full width of the underlying data, perform a single copy.
23390          if (width === this.dataWidth) {
23391              System.arraycopy(this.yuvData, inputOffset, matrix, 0, area);
23392              return matrix;
23393          }
23394          // Otherwise copy one cropped row at a time.
23395          for (let y = 0; y < height; y++) {
23396              const outputOffset = y * width;
23397              System.arraycopy(this.yuvData, inputOffset, matrix, outputOffset, width);
23398              inputOffset += this.dataWidth;
23399          }
23400          return matrix;
23401      }
23402      /*@Override*/
23403      isCropSupported() {
23404          return true;
23405      }
23406      /*@Override*/
23407      crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
23408          return new PlanarYUVLuminanceSource(this.yuvData, this.dataWidth, this.dataHeight, this.left + left, this.top + top, width, height, false);
23409      }
23410      renderThumbnail() {
23411          const width = this.getWidth() / PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
23412          const height = this.getHeight() / PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
23413          const pixels = new Int32Array(width * height);
23414          const yuv = this.yuvData;
23415          let inputOffset = this.top * this.dataWidth + this.left;
23416          for (let y = 0; y < height; y++) {
23417              const outputOffset = y * width;
23418              for (let x = 0; x < width; x++) {
23419                  const grey = yuv[inputOffset + x * PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR] & 0xff;
23420                  pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
23421              }
23422              inputOffset += this.dataWidth * PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
23423          }
23424          return pixels;
23425      }
23426      /**
23427       * @return width of image from {@link #renderThumbnail()}
23428       */
23429      getThumbnailWidth() {
23430          return this.getWidth() / PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
23431      }
23432      /**
23433       * @return height of image from {@link #renderThumbnail()}
23434       */
23435      getThumbnailHeight() {
23436          return this.getHeight() / PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
23437      }
23438      reverseHorizontal(width /*int*/, height /*int*/) {
23439          const yuvData = this.yuvData;
23440          for (let y = 0, rowStart = this.top * this.dataWidth + this.left; y < height; y++, rowStart += this.dataWidth) {
23441              const middle = rowStart + width / 2;
23442              for (let x1 = rowStart, x2 = rowStart + width - 1; x1 < middle; x1++, x2--) {
23443                  const temp = yuvData[x1];
23444                  yuvData[x1] = yuvData[x2];
23445                  yuvData[x2] = temp;
23446              }
23447          }
23448      }
23449      invert() {
23450          return new InvertedLuminanceSource(this);
23451      }
23452  }
23453  PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR = 2;
23454
23455  /*
23456   * Copyright 2009 ZXing authors
23457   *
23458   * Licensed under the Apache License, Version 2.0 (the "License");
23459   * you may not use this file except in compliance with the License.
23460   * You may obtain a copy of the License at
23461   *
23462   *      http://www.apache.org/licenses/LICENSE-2.0
23463   *
23464   * Unless required by applicable law or agreed to in writing, software
23465   * distributed under the License is distributed on an "AS IS" BASIS,
23466   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23467   * See the License for the specific language governing permissions and
23468   * limitations under the License.
23469   
vendor: 37,160 bytes, lines 23469-24435
23469*/
23470  /**
23471   * This class is used to help decode images from files which arrive as RGB data from
23472   * an ARGB pixel array. It does not support rotation.
23473   *
23474   * @author [email protected] (Daniel Switkin)
23475   * @author Betaminos
23476   */
23477  class RGBLuminanceSource extends LuminanceSource {
23478      constructor(luminances, width /*int*/, height /*int*/, dataWidth /*int*/, dataHeight /*int*/, left /*int*/, top /*int*/) {
23479          super(width, height);
23480          this.dataWidth = dataWidth;
23481          this.dataHeight = dataHeight;
23482          this.left = left;
23483          this.top = top;
23484          if (luminances.BYTES_PER_ELEMENT === 4) { // Int32Array
23485              const size = width * height;
23486              const luminancesUint8Array = new Uint8ClampedArray(size);
23487              for (let offset = 0; offset < size; offset++) {
23488                  const pixel = luminances[offset];
23489                  const r = (pixel >> 16) & 0xff; // red
23490                  const g2 = (pixel >> 7) & 0x1fe; // 2 * green
23491                  const b = pixel & 0xff; // blue
23492                  // Calculate green-favouring average cheaply
23493                  luminancesUint8Array[offset] = /*(byte) */ ((r + g2 + b) / 4) & 0xFF;
23494              }
23495              this.luminances = luminancesUint8Array;
23496          }
23497          else {
23498              this.luminances = luminances;
23499          }
23500          if (undefined === dataWidth) {
23501              this.dataWidth = width;
23502          }
23503          if (undefined === dataHeight) {
23504              this.dataHeight = height;
23505          }
23506          if (undefined === left) {
23507              this.left = 0;
23508          }
23509          if (undefined === top) {
23510              this.top = 0;
23511          }
23512          if (this.left + width > this.dataWidth || this.top + height > this.dataHeight) {
23513              throw new IllegalArgumentException('Crop rectangle does not fit within image data.');
23514          }
23515      }
23516      /*@Override*/
23517      getRow(y /*int*/, row) {
23518          if (y < 0 || y >= this.getHeight()) {
23519              throw new IllegalArgumentException('Requested row is outside the image: ' + y);
23520          }
23521          const width = this.getWidth();
23522          if (row === null || row === undefined || row.length < width) {
23523              row = new Uint8ClampedArray(width);
23524          }
23525          const offset = (y + this.top) * this.dataWidth + this.left;
23526          System.arraycopy(this.luminances, offset, row, 0, width);
23527          return row;
23528      }
23529      /*@Override*/
23530      getMatrix() {
23531          const width = this.getWidth();
23532          const height = this.getHeight();
23533          // If the caller asks for the entire underlying image, save the copy and give them the
23534          // original data. The docs specifically warn that result.length must be ignored.
23535          if (width === this.dataWidth && height === this.dataHeight) {
23536              return this.luminances;
23537          }
23538          const area = width * height;
23539          const matrix = new Uint8ClampedArray(area);
23540          let inputOffset = this.top * this.dataWidth + this.left;
23541          // If the width matches the full width of the underlying data, perform a single copy.
23542          if (width === this.dataWidth) {
23543              System.arraycopy(this.luminances, inputOffset, matrix, 0, area);
23544              return matrix;
23545          }
23546          // Otherwise copy one cropped row at a time.
23547          for (let y = 0; y < height; y++) {
23548              const outputOffset = y * width;
23549              System.arraycopy(this.luminances, inputOffset, matrix, outputOffset, width);
23550              inputOffset += this.dataWidth;
23551          }
23552          return matrix;
23553      }
23554      /*@Override*/
23555      isCropSupported() {
23556          return true;
23557      }
23558      /*@Override*/
23559      crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
23560          return new RGBLuminanceSource(this.luminances, width, height, this.dataWidth, this.dataHeight, this.left + left, this.top + top);
23561      }
23562      invert() {
23563          return new InvertedLuminanceSource(this);
23564      }
23565  }
23566
23567  /**
23568   * Just to make a shortcut between Java code and TS code.
23569   */
23570  class Charset extends CharacterSetECI {
23571      static forName(name) {
23572          return this.getCharacterSetECIByName(name);
23573      }
23574  }
23575
23576  /**
23577   * Just to make a shortcut between Java code and TS code.
23578   */
23579  class StandardCharsets {
23580  }
23581  StandardCharsets.ISO_8859_1 = CharacterSetECI.ISO8859_1;
23582
23583  /**
23584   * Symbol Character Placement Program. Adapted from Annex M.1 in ISO/IEC 16022:2000(E).
23585   */
23586  class DefaultPlacement {
23587      /**
23588       * Main constructor
23589       *
23590       * @param codewords the codewords to place
23591       * @param numcols   the number of columns
23592       * @param numrows   the number of rows
23593       */
23594      constructor(codewords, numcols, numrows) {
23595          this.codewords = codewords;
23596          this.numcols = numcols;
23597          this.numrows = numrows;
23598          this.bits = new Uint8Array(numcols * numrows);
23599          Arrays.fill(this.bits, 2); // Initialize with "not set" value
23600      }
23601      getNumrows() {
23602          return this.numrows;
23603      }
23604      getNumcols() {
23605          return this.numcols;
23606      }
23607      getBits() {
23608          return this.bits;
23609      }
23610      getBit(col, row) {
23611          return this.bits[row * this.numcols + col] === 1;
23612      }
23613      setBit(col, row, bit) {
23614          this.bits[row * this.numcols + col] = bit ? 1 : 0;
23615      }
23616      noBit(col, row) {
23617          return this.bits[row * this.numcols + col] === 2;
23618      }
23619      place() {
23620          let pos = 0;
23621          let row = 4;
23622          let col = 0;
23623          do {
23624              // repeatedly first check for one of the special corner cases, then...
23625              if (row === this.numrows && col === 0) {
23626                  this.corner1(pos++);
23627              }
23628              if (row === this.numrows - 2 && col === 0 && this.numcols % 4 !== 0) {
23629                  this.corner2(pos++);
23630              }
23631              if (row === this.numrows - 2 && col === 0 && this.numcols % 8 === 4) {
23632                  this.corner3(pos++);
23633              }
23634              if (row === this.numrows + 4 && col === 2 && this.numcols % 8 === 0) {
23635                  this.corner4(pos++);
23636              }
23637              // sweep upward diagonally, inserting successive characters...
23638              do {
23639                  if (row < this.numrows && col >= 0 && this.noBit(col, row)) {
23640                      this.utah(row, col, pos++);
23641                  }
23642                  row -= 2;
23643                  col += 2;
23644              } while (row >= 0 && col < this.numcols);
23645              row++;
23646              col += 3;
23647              // and then sweep downward diagonally, inserting successive characters, ...
23648              do {
23649                  if (row >= 0 && col < this.numcols && this.noBit(col, row)) {
23650                      this.utah(row, col, pos++);
23651                  }
23652                  row += 2;
23653                  col -= 2;
23654              } while (row < this.numrows && col >= 0);
23655              row += 3;
23656              col++;
23657              // ...until the entire array is scanned
23658          } while (row < this.numrows || col < this.numcols);
23659          // Lastly, if the lower right-hand corner is untouched, fill in fixed pattern
23660          if (this.noBit(this.numcols - 1, this.numrows - 1)) {
23661              this.setBit(this.numcols - 1, this.numrows - 1, true);
23662              this.setBit(this.numcols - 2, this.numrows - 2, true);
23663          }
23664      }
23665      module(row, col, pos, bit) {
23666          if (row < 0) {
23667              row += this.numrows;
23668              col += 4 - ((this.numrows + 4) % 8);
23669          }
23670          if (col < 0) {
23671              col += this.numcols;
23672              row += 4 - ((this.numcols + 4) % 8);
23673          }
23674          // Note the conversion:
23675          let v = this.codewords.charCodeAt(pos);
23676          v &= 1 << (8 - bit);
23677          this.setBit(col, row, v !== 0);
23678      }
23679      /**
23680       * Places the 8 bits of a utah-shaped symbol character in ECC200.
23681       *
23682       * @param row the row
23683       * @param col the column
23684       * @param pos character position
23685       */
23686      utah(row, col, pos) {
23687          this.module(row - 2, col - 2, pos, 1);
23688          this.module(row - 2, col - 1, pos, 2);
23689          this.module(row - 1, col - 2, pos, 3);
23690          this.module(row - 1, col - 1, pos, 4);
23691          this.module(row - 1, col, pos, 5);
23692          this.module(row, col - 2, pos, 6);
23693          this.module(row, col - 1, pos, 7);
23694          this.module(row, col, pos, 8);
23695      }
23696      corner1(pos) {
23697          this.module(this.numrows - 1, 0, pos, 1);
23698          this.module(this.numrows - 1, 1, pos, 2);
23699          this.module(this.numrows - 1, 2, pos, 3);
23700          this.module(0, this.numcols - 2, pos, 4);
23701          this.module(0, this.numcols - 1, pos, 5);
23702          this.module(1, this.numcols - 1, pos, 6);
23703          this.module(2, this.numcols - 1, pos, 7);
23704          this.module(3, this.numcols - 1, pos, 8);
23705      }
23706      corner2(pos) {
23707          this.module(this.numrows - 3, 0, pos, 1);
23708          this.module(this.numrows - 2, 0, pos, 2);
23709          this.module(this.numrows - 1, 0, pos, 3);
23710          this.module(0, this.numcols - 4, pos, 4);
23711          this.module(0, this.numcols - 3, pos, 5);
23712          this.module(0, this.numcols - 2, pos, 6);
23713          this.module(0, this.numcols - 1, pos, 7);
23714          this.module(1, this.numcols - 1, pos, 8);
23715      }
23716      corner3(pos) {
23717          this.module(this.numrows - 3, 0, pos, 1);
23718          this.module(this.numrows - 2, 0, pos, 2);
23719          this.module(this.numrows - 1, 0, pos, 3);
23720          this.module(0, this.numcols - 2, pos, 4);
23721          this.module(0, this.numcols - 1, pos, 5);
23722          this.module(1, this.numcols - 1, pos, 6);
23723          this.module(2, this.numcols - 1, pos, 7);
23724          this.module(3, this.numcols - 1, pos, 8);
23725      }
23726      corner4(pos) {
23727          this.module(this.numrows - 1, 0, pos, 1);
23728          this.module(this.numrows - 1, this.numcols - 1, pos, 2);
23729          this.module(0, this.numcols - 3, pos, 3);
23730          this.module(0, this.numcols - 2, pos, 4);
23731          this.module(0, this.numcols - 1, pos, 5);
23732          this.module(1, this.numcols - 3, pos, 6);
23733          this.module(1, this.numcols - 2, pos, 7);
23734          this.module(1, this.numcols - 1, pos, 8);
23735      }
23736  }
23737
23738  /**
23739   * Lookup table which factors to use for which number of error correction codewords.
23740   * See FACTORS.
23741   */
23742  const FACTOR_SETS = [
23743      5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68,
23744  ];
23745  /**
23746   * Precomputed polynomial factors for ECC 200.
23747   */
23748  const FACTORS = [
23749      [228, 48, 15, 111, 62],
23750      [23, 68, 144, 134, 240, 92, 254],
23751      [28, 24, 185, 166, 223, 248, 116, 255, 110, 61],
23752      [175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120],
23753      [41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242],
23754      [156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185],
23755      [
23756          83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48, 90,
23757          188,
23758      ],
23759      [
23760          15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82, 27,
23761          174, 186, 172,
23762      ],
23763      [
23764          52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172,
23765          254, 124, 12, 181, 184, 96, 50, 193,
23766      ],
23767      [
23768          211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121, 17,
23769          138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255,
23770      ],
23771      [
23772          245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80,
23773          182, 229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25,
23774          225, 98, 81, 112,
23775      ],
23776      [
23777          77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8, 175,
23778          95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101, 248, 202,
23779          69, 50, 150, 177, 226, 5, 9, 5,
23780      ],
23781      [
23782          245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87,
23783          191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138,
23784          186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19,
23785      ],
23786      [
23787          175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235,
23788          150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232,
23789          144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28,
23790          155, 43, 203, 107, 233, 53, 143, 46,
23791      ],
23792      [
23793          242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37,
23794          185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, 71,
23795          161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31, 176,
23796          170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204,
23797      ],
23798      [
23799          220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127,
23800          213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, 236,
23801          66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, 223, 239,
23802          181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, 132, 63, 96,
23803          103, 82, 186,
23804      ],
23805  ];
23806  const /*final*/ MODULO_VALUE = 0x12d;
23807  const static_LOG = (LOG, ALOG) => {
23808      let p = 1;
23809      for (let i = 0; i < 255; i++) {
23810          ALOG[i] = p;
23811          LOG[p] = i;
23812          p *= 2;
23813          if (p >= 256) {
23814              p ^= MODULO_VALUE;
23815          }
23816      }
23817      return {
23818          LOG,
23819          ALOG,
23820      };
23821  };
23822  const { LOG, ALOG } = static_LOG([], []);
23823  exports.DataMatrixSymbolShapeHint = void 0;
23824  (function (SymbolShapeHint) {
23825      SymbolShapeHint[SymbolShapeHint["FORCE_NONE"] = 0] = "FORCE_NONE";
23826      SymbolShapeHint[SymbolShapeHint["FORCE_SQUARE"] = 1] = "FORCE_SQUARE";
23827      SymbolShapeHint[SymbolShapeHint["FORCE_RECTANGLE"] = 2] = "FORCE_RECTANGLE";
23828  })(exports.DataMatrixSymbolShapeHint || (exports.DataMatrixSymbolShapeHint = {}));
23829  /**
23830   * Padding character
23831   */
23832  const PAD = 129;
23833  /**
23834   * mode latch to C40 encodation mode
23835   */
23836  const LATCH_TO_C40 = 230;
23837  /**
23838   * mode latch to Base 256 encodation mode
23839   */
23840  const LATCH_TO_BASE256 = 231;
23841  /**
23842   * FNC1 Codeword
23843   */
23844  // private static FNC1 = 232;
23845  /**
23846   * Structured Append Codeword
23847   */
23848  // private static STRUCTURED_APPEND = 233;
23849  /**
23850   * Reader Programming
23851   */
23852  // private static READER_PROGRAMMING = 234;
23853  /**
23854   * Upper Shift
23855   */
23856  const UPPER_SHIFT = 235;
23857  /**
23858   * 05 Macro
23859   */
23860  const MACRO_05 = 236;
23861  /**
23862   * 06 Macro
23863   */
23864  const MACRO_06 = 237;
23865  /**
23866   * mode latch to ANSI X.12 encodation mode
23867   */
23868  const LATCH_TO_ANSIX12 = 238;
23869  /**
23870   * mode latch to Text encodation mode
23871   */
23872  const LATCH_TO_TEXT = 239;
23873  /**
23874   * mode latch to EDIFACT encodation mode
23875   */
23876  const LATCH_TO_EDIFACT = 240;
23877  /**
23878   * ECI character (Extended Channel Interpretation)
23879   */
23880  // private export const ECI = 241;
23881  /**
23882   * Unlatch from C40 encodation
23883   */
23884  const C40_UNLATCH = 254;
23885  /**
23886   * Unlatch from X12 encodation
23887   */
23888  const X12_UNLATCH = 254;
23889  /**
23890   * 05 Macro header
23891   */
23892  const MACRO_05_HEADER = '[)>\u001E05\u001D';
23893  /**
23894   * 06 Macro header
23895   */
23896  const MACRO_06_HEADER = '[)>\u001E06\u001D';
23897  /**
23898   * Macro trailer
23899   */
23900  const MACRO_TRAILER = '\u001E\u0004';
23901  const ASCII_ENCODATION = 0;
23902  const C40_ENCODATION = 1;
23903  const TEXT_ENCODATION = 2;
23904  const X12_ENCODATION = 3;
23905  const EDIFACT_ENCODATION = 4;
23906  const BASE256_ENCODATION = 5;
23907
23908  /**
23909   * Error Correction Code for ECC200.
23910   */
23911  class ErrorCorrection {
23912      /**
23913       * Creates the ECC200 error correction for an encoded message.
23914       *
23915       * @param codewords  the codewords
23916       * @param symbolInfo information about the symbol to be encoded
23917       * @return the codewords with interleaved error correction.
23918       */
23919      static encodeECC200(codewords, symbolInfo) {
23920          if (codewords.length !== symbolInfo.getDataCapacity()) {
23921              throw new Error('The number of codewords does not match the selected symbol');
23922          }
23923          const sb = new StringBuilder();
23924          sb.append(codewords);
23925          const blockCount = symbolInfo.getInterleavedBlockCount();
23926          if (blockCount === 1) {
23927              const ecc = this.createECCBlock(codewords, symbolInfo.getErrorCodewords());
23928              sb.append(ecc);
23929          }
23930          else {
23931              const errorSizes = [];
23932              for (let i = 0; i < blockCount; i++) {
23933                  symbolInfo.getDataLengthForInterleavedBlock(i + 1);
23934                  errorSizes[i] = symbolInfo.getErrorLengthForInterleavedBlock(i + 1);
23935              }
23936              for (let block = 0; block < blockCount; block++) {
23937                  const temp = new StringBuilder();
23938                  for (let d = block; d < symbolInfo.getDataCapacity(); d += blockCount) {
23939                      temp.append(codewords.charAt(d));
23940                  }
23941                  const ecc = this.createECCBlock(temp.toString(), errorSizes[block]);
23942                  let pos = 0;
23943                  for (let e = block; e < errorSizes[block] * blockCount; e += blockCount) {
23944                      sb.setCharAt(symbolInfo.getDataCapacity() + e, ecc.charAt(pos++));
23945                  }
23946              }
23947          }
23948          return sb.toString();
23949      }
23950      static createECCBlock(codewords, numECWords) {
23951          let table = -1;
23952          for (let i = 0; i < FACTOR_SETS.length; i++) {
23953              if (FACTOR_SETS[i] === numECWords) {
23954                  table = i;
23955                  break;
23956              }
23957          }
23958          if (table < 0) {
23959              throw new Error('Illegal number of error correction codewords specified: ' + numECWords);
23960          }
23961          const poly = FACTORS[table];
23962          const ecc = [];
23963          for (let i = 0; i < numECWords; i++) {
23964              ecc[i] = 0;
23965          }
23966          for (let i = 0; i < codewords.length; i++) {
23967              let m = ecc[numECWords - 1] ^ codewords.charAt(i).charCodeAt(0);
23968              for (let k = numECWords - 1; k > 0; k--) {
23969                  if (m !== 0 && poly[k] !== 0) {
23970                      ecc[k] = ecc[k - 1] ^ ALOG[(LOG[m] + LOG[poly[k]]) % 255];
23971                  }
23972                  else {
23973                      ecc[k] = ecc[k - 1];
23974                  }
23975              }
23976              if (m !== 0 && poly[0] !== 0) {
23977                  ecc[0] = ALOG[(LOG[m] + LOG[poly[0]]) % 255];
23978              }
23979              else {
23980                  ecc[0] = 0;
23981              }
23982          }
23983          const eccReversed = [];
23984          for (let i = 0; i < numECWords; i++) {
23985              eccReversed[i] = ecc[numECWords - i - 1];
23986          }
23987          return eccReversed.map(c => String.fromCharCode(c)).join('');
23988      }
23989  }
23990
23991  class ASCIIEncoder {
23992      getEncodingMode() {
23993          return ASCII_ENCODATION;
23994      }
23995      encode(context) {
23996          // step B
23997          const n = HighLevelEncoder$1.determineConsecutiveDigitCount(context.getMessage(), context.pos);
23998          if (n >= 2) {
23999              context.writeCodeword(this.encodeASCIIDigits(context.getMessage().charCodeAt(context.pos), context.getMessage().charCodeAt(context.pos + 1)));
24000              context.pos += 2;
24001          }
24002          else {
24003              const c = context.getCurrentChar();
24004              const newMode = HighLevelEncoder$1.lookAheadTest(context.getMessage(), context.pos, this.getEncodingMode());
24005              if (newMode !== this.getEncodingMode()) {
24006                  switch (newMode) {
24007                      case BASE256_ENCODATION:
24008                          context.writeCodeword(LATCH_TO_BASE256);
24009                          context.signalEncoderChange(BASE256_ENCODATION);
24010                          return;
24011                      case C40_ENCODATION:
24012                          context.writeCodeword(LATCH_TO_C40);
24013                          context.signalEncoderChange(C40_ENCODATION);
24014                          return;
24015                      case X12_ENCODATION:
24016                          context.writeCodeword(LATCH_TO_ANSIX12);
24017                          context.signalEncoderChange(X12_ENCODATION);
24018                          break;
24019                      case TEXT_ENCODATION:
24020                          context.writeCodeword(LATCH_TO_TEXT);
24021                          context.signalEncoderChange(TEXT_ENCODATION);
24022                          break;
24023                      case EDIFACT_ENCODATION:
24024                          context.writeCodeword(LATCH_TO_EDIFACT);
24025                          context.signalEncoderChange(EDIFACT_ENCODATION);
24026                          break;
24027                      default:
24028                          throw new Error('Illegal mode: ' + newMode);
24029                  }
24030              }
24031              else if (HighLevelEncoder$1.isExtendedASCII(c)) {
24032                  context.writeCodeword(UPPER_SHIFT);
24033                  context.writeCodeword(c - 128 + 1);
24034                  context.pos++;
24035              }
24036              else {
24037                  context.writeCodeword(c + 1);
24038                  context.pos++;
24039              }
24040          }
24041      }
24042      encodeASCIIDigits(digit1, digit2) {
24043          if (HighLevelEncoder$1.isDigit(digit1) && HighLevelEncoder$1.isDigit(digit2)) {
24044              const num = (digit1 - 48) * 10 + (digit2 - 48);
24045              return num + 130;
24046          }
24047          throw new Error('not digits: ' + digit1 + digit2);
24048      }
24049  }
24050
24051  class Base256Encoder {
24052      getEncodingMode() {
24053          return BASE256_ENCODATION;
24054      }
24055      encode(context) {
24056          const buffer = new StringBuilder();
24057          buffer.append(0o0); // Initialize length field
24058          while (context.hasMoreCharacters()) {
24059              const c = context.getCurrentChar();
24060              buffer.append(c);
24061              context.pos++;
24062              const newMode = HighLevelEncoder$1.lookAheadTest(context.getMessage(), context.pos, this.getEncodingMode());
24063              if (newMode !== this.getEncodingMode()) {
24064                  // Return to ASCII encodation, which will actually handle latch to new mode
24065                  context.signalEncoderChange(ASCII_ENCODATION);
24066                  break;
24067              }
24068          }
24069          const dataCount = buffer.length() - 1;
24070          const lengthFieldSize = 1;
24071          const currentSize = context.getCodewordCount() + dataCount + lengthFieldSize;
24072          context.updateSymbolInfo(currentSize);
24073          const mustPad = context.getSymbolInfo().getDataCapacity() - currentSize > 0;
24074          if (context.hasMoreCharacters() || mustPad) {
24075              if (dataCount <= 249) {
24076                  buffer.setCharAt(0, StringUtils.getCharAt(dataCount));
24077              }
24078              else if (dataCount <= 1555) {
24079                  buffer.setCharAt(0, StringUtils.getCharAt(Math.floor(dataCount / 250) + 249));
24080                  buffer.insert(1, StringUtils.getCharAt(dataCount % 250));
24081              }
24082              else {
24083                  throw new Error('Message length not in valid ranges: ' + dataCount);
24084              }
24085          }
24086          for (let i = 0, c = buffer.length(); i < c; i++) {
24087              context.writeCodeword(this.randomize255State(buffer.charAt(i).charCodeAt(0), context.getCodewordCount() + 1));
24088          }
24089      }
24090      randomize255State(ch, codewordPosition) {
24091          const pseudoRandom = ((149 * codewordPosition) % 255) + 1;
24092          const tempVariable = ch + pseudoRandom;
24093          if (tempVariable <= 255) {
24094              return tempVariable;
24095          }
24096          else {
24097              return tempVariable - 256;
24098          }
24099      }
24100  }
24101
24102  class C40Encoder {
24103      getEncodingMode() {
24104          return C40_ENCODATION;
24105      }
24106      encodeMaximal(context) {
24107          const buffer = new StringBuilder();
24108          let lastCharSize = 0;
24109          let backtrackStartPosition = context.pos;
24110          let backtrackBufferLength = 0;
24111          while (context.hasMoreCharacters()) {
24112              const c = context.getCurrentChar();
24113              context.pos++;
24114              lastCharSize = this.encodeChar(c, buffer);
24115              if (buffer.length() % 3 === 0) {
24116                  backtrackStartPosition = context.pos;
24117                  backtrackBufferLength = buffer.length();
24118              }
24119          }
24120          if (backtrackBufferLength !== buffer.length()) {
24121              const unwritten = Math.floor((buffer.length() / 3) * 2);
24122              const curCodewordCount = Math.floor(context.getCodewordCount() + unwritten + 1); // +1 for the latch to C40
24123              context.updateSymbolInfo(curCodewordCount);
24124              const available = context.getSymbolInfo().getDataCapacity() - curCodewordCount;
24125              const rest = Math.floor(buffer.length() % 3);
24126              if ((rest === 2 && available !== 2) ||
24127                  (rest === 1 && (lastCharSize > 3 || available !== 1))) {
24128                  // buffer.setLength(backtrackBufferLength);
24129                  context.pos = backtrackStartPosition;
24130              }
24131          }
24132          if (buffer.length() > 0) {
24133              context.writeCodeword(LATCH_TO_C40);
24134          }
24135          this.handleEOD(context, buffer);
24136      }
24137      encode(context) {
24138          // step C
24139          const buffer = new StringBuilder();
24140          while (context.hasMoreCharacters()) {
24141              const c = context.getCurrentChar();
24142              context.pos++;
24143              let lastCharSize = this.encodeChar(c, buffer);
24144              const unwritten = Math.floor(buffer.length() / 3) * 2;
24145              const curCodewordCount = context.getCodewordCount() + unwritten;
24146              context.updateSymbolInfo(curCodewordCount);
24147              const available = context.getSymbolInfo().getDataCapacity() - curCodewordCount;
24148              if (!context.hasMoreCharacters()) {
24149                  // Avoid having a single C40 value in the last triplet
24150                  const removed = new StringBuilder();
24151                  if (buffer.length() % 3 === 2 && available !== 2) {
24152                      lastCharSize = this.backtrackOneCharacter(context, buffer, removed, lastCharSize);
24153                  }
24154                  while (buffer.length() % 3 === 1 &&
24155                      (lastCharSize > 3 || available !== 1)) {
24156                      lastCharSize = this.backtrackOneCharacter(context, buffer, removed, lastCharSize);
24157                  }
24158                  break;
24159              }
24160              const count = buffer.length();
24161              if (count % 3 === 0) {
24162                  const newMode = HighLevelEncoder$1.lookAheadTest(context.getMessage(), context.pos, this.getEncodingMode());
24163                  if (newMode !== this.getEncodingMode()) {
24164                      // Return to ASCII encodation, which will actually handle latch to new mode
24165                      context.signalEncoderChange(ASCII_ENCODATION);
24166                      break;
24167                  }
24168              }
24169          }
24170          this.handleEOD(context, buffer);
24171      }
24172      backtrackOneCharacter(context, buffer, removed, lastCharSize) {
24173          const count = buffer.length();
24174          const test = buffer.toString().substring(0, count - lastCharSize);
24175          buffer.setLengthToZero();
24176          buffer.append(test);
24177          // buffer.delete(count - lastCharSize, count);
24178          /*for (let i = count - lastCharSize; i < count; i++) {
24179            buffer.deleteCharAt(i);
24180          }*/
24181          context.pos--;
24182          const c = context.getCurrentChar();
24183          lastCharSize = this.encodeChar(c, removed);
24184          context.resetSymbolInfo(); // Deal with possible reduction in symbol size
24185          return lastCharSize;
24186      }
24187      writeNextTriplet(context, buffer) {
24188          context.writeCodewords(this.encodeToCodewords(buffer.toString()));
24189          const test = buffer.toString().substring(3);
24190          buffer.setLengthToZero();
24191          buffer.append(test);
24192          // buffer.delete(0, 3);
24193          /*for (let i = 0; i < 3; i++) {
24194            buffer.deleteCharAt(i);
24195          }*/
24196      }
24197      /**
24198       * Handle "end of data" situations
24199       *
24200       * @param context the encoder context
24201       * @param buffer  the buffer with the remaining encoded characters
24202       */
24203      handleEOD(context, buffer) {
24204          const unwritten = Math.floor((buffer.length() / 3) * 2);
24205          const rest = buffer.length() % 3;
24206          const curCodewordCount = context.getCodewordCount() + unwritten;
24207          context.updateSymbolInfo(curCodewordCount);
24208          const available = context.getSymbolInfo().getDataCapacity() - curCodewordCount;
24209          if (rest === 2) {
24210              buffer.append('\0'); // Shift 1
24211              while (buffer.length() >= 3) {
24212                  this.writeNextTriplet(context, buffer);
24213              }
24214              if (context.hasMoreCharacters()) {
24215                  context.writeCodeword(C40_UNLATCH);
24216              }
24217          }
24218          else if (available === 1 && rest === 1) {
24219              while (buffer.length() >= 3) {
24220                  this.writeNextTriplet(context, buffer);
24221              }
24222              if (context.hasMoreCharacters()) {
24223                  context.writeCodeword(C40_UNLATCH);
24224              }
24225              // else no unlatch
24226              context.pos--;
24227          }
24228          else if (rest === 0) {
24229              while (buffer.length() >= 3) {
24230                  this.writeNextTriplet(context, buffer);
24231              }
24232              if (available > 0 || context.hasMoreCharacters()) {
24233                  context.writeCodeword(C40_UNLATCH);
24234              }
24235          }
24236          else {
24237              throw new Error('Unexpected case. Please report!');
24238          }
24239          context.signalEncoderChange(ASCII_ENCODATION);
24240      }
24241      encodeChar(c, sb) {
24242          if (c === ' '.charCodeAt(0)) {
24243              sb.append(0o3);
24244              return 1;
24245          }
24246          if (c >= '0'.charCodeAt(0) && c <= '9'.charCodeAt(0)) {
24247              sb.append(c - 48 + 4);
24248              return 1;
24249          }
24250          if (c >= 'A'.charCodeAt(0) && c <= 'Z'.charCodeAt(0)) {
24251              sb.append(c - 65 + 14);
24252              return 1;
24253          }
24254          if (c < ' '.charCodeAt(0)) {
24255              sb.append(0o0); // Shift 1 Set
24256              sb.append(c);
24257              return 2;
24258          }
24259          if (c <= '/'.charCodeAt(0)) {
24260              sb.append(0o1); // Shift 2 Set
24261              sb.append(c - 33);
24262              return 2;
24263          }
24264          if (c <= '@'.charCodeAt(0)) {
24265              sb.append(0o1); // Shift 2 Set
24266              sb.append(c - 58 + 15);
24267              return 2;
24268          }
24269          if (c <= '_'.charCodeAt(0)) {
24270              sb.append(0o1); // Shift 2 Set
24271              sb.append(c - 91 + 22);
24272              return 2;
24273          }
24274          if (c <= 127) {
24275              sb.append(0o2); // Shift 3 Set
24276              sb.append(c - 96);
24277              return 2;
24278          }
24279          sb.append(`${0o1}\u001e`); // Shift 2, Upper Shift
24280          let len = 2;
24281          len += this.encodeChar(c - 128, sb);
24282          return len;
24283      }
24284      encodeToCodewords(sb) {
24285          const v = 1600 * sb.charCodeAt(0) + 40 * sb.charCodeAt(1) + sb.charCodeAt(2) + 1;
24286          const cw1 = v / 256;
24287          const cw2 = v % 256;
24288          const result = new StringBuilder();
24289          result.append(cw1);
24290          result.append(cw2);
24291          return result.toString();
24292      }
24293  }
24294
24295  class EdifactEncoder {
24296      getEncodingMode() {
24297          return EDIFACT_ENCODATION;
24298      }
24299      encode(context) {
24300          // step F
24301          const buffer = new StringBuilder();
24302          while (context.hasMoreCharacters()) {
24303              const c = context.getCurrentChar();
24304              this.encodeChar(c, buffer);
24305              context.pos++;
24306              const count = buffer.length();
24307              if (count >= 4) {
24308                  context.writeCodewords(this.encodeToCodewords(buffer.toString()));
24309                  const test = buffer.toString().substring(4);
24310                  buffer.setLengthToZero();
24311                  buffer.append(test);
24312                  // buffer.delete(0, 4);
24313                  // for (let i = 0; i < 4; i++) {
24314                  //  buffer.deleteCharAt(i);
24315                  // }
24316                  const newMode = HighLevelEncoder$1.lookAheadTest(context.getMessage(), context.pos, this.getEncodingMode());
24317                  if (newMode !== this.getEncodingMode()) {
24318                      // Return to ASCII encodation, which will actually handle latch to new mode
24319                      context.signalEncoderChange(ASCII_ENCODATION);
24320                      break;
24321                  }
24322              }
24323          }
24324          buffer.append(StringUtils.getCharAt(31)); // Unlatch
24325          this.handleEOD(context, buffer);
24326      }
24327      /**
24328       * Handle "end of data" situations
24329       *
24330       * @param context the encoder context
24331       * @param buffer  the buffer with the remaining encoded characters
24332       */
24333      handleEOD(context, buffer) {
24334          try {
24335              const count = buffer.length();
24336              if (count === 0) {
24337                  return; // Already finished
24338              }
24339              if (count === 1) {
24340                  // Only an unlatch at the end
24341                  context.updateSymbolInfo();
24342                  let available = context.getSymbolInfo().getDataCapacity() -
24343                      context.getCodewordCount();
24344                  const remaining = context.getRemainingCharacters();
24345                  // The following two lines are a hack inspired by the 'fix' from https://sourceforge.net/p/barcode4j/svn/221/
24346                  if (remaining > available) {
24347                      context.updateSymbolInfo(context.getCodewordCount() + 1);
24348                      available =
24349                          context.getSymbolInfo().getDataCapacity() -
24350                              context.getCodewordCount();
24351                  }
24352                  if (remaining <= available && available <= 2) {
24353                      return; // No unlatch
24354                  }
24355              }
24356              if (count > 4) {
24357                  throw new Error('Count must not exceed 4');
24358              }
24359              const restChars = count - 1;
24360              const encoded = this.encodeToCodewords(buffer.toString());
24361              const endOfSymbolReached = !context.hasMoreCharacters();
24362              let restInAscii = endOfSymbolReached && restChars <= 2;
24363              if (restChars <= 2) {
24364                  context.updateSymbolInfo(context.getCodewordCount() + restChars);
24365                  const available = context.getSymbolInfo().getDataCapacity() -
24366                      context.getCodewordCount();
24367                  if (available >= 3) {
24368                      restInAscii = false;
24369                      context.updateSymbolInfo(context.getCodewordCount() + encoded.length);
24370                      // available = context.symbolInfo.dataCapacity - context.getCodewordCount();
24371                  }
24372              }
24373              if (restInAscii) {
24374                  context.resetSymbolInfo();
24375                  context.pos -= restChars;
24376              }
24377              else {
24378                  context.writeCodewords(encoded);
24379              }
24380          }
24381          finally {
24382              context.signalEncoderChange(ASCII_ENCODATION);
24383          }
24384      }
24385      encodeChar(c, sb) {
24386          if (c >= ' '.charCodeAt(0) && c <= '?'.charCodeAt(0)) {
24387              sb.append(c);
24388          }
24389          else if (c >= '@'.charCodeAt(0) && c <= '^'.charCodeAt(0)) {
24390              sb.append(StringUtils.getCharAt(c - 64));
24391          }
24392          else {
24393              HighLevelEncoder$1.illegalCharacter(StringUtils.getCharAt(c));
24394          }
24395      }
24396      encodeToCodewords(sb) {
24397          const len = sb.length;
24398          if (len === 0) {
24399              throw new Error('StringBuilder must not be empty');
24400          }
24401          const c1 = sb.charAt(0).charCodeAt(0);
24402          const c2 = len >= 2 ? sb.charAt(1).charCodeAt(0) : 0;
24403          const c3 = len >= 3 ? sb.charAt(2).charCodeAt(0) : 0;
24404          const c4 = len >= 4 ? sb.charAt(3).charCodeAt(0) : 0;
24405          const v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4;
24406          const cw1 = (v >> 16) & 255;
24407          const cw2 = (v >> 8) & 255;
24408          const cw3 = v & 255;
24409          const res = new StringBuilder();
24410          res.append(cw1);
24411          if (len >= 2) {
24412              res.append(cw2);
24413          }
24414          if (len >= 3) {
24415              res.append(cw3);
24416          }
24417          return res.toString();
24418      }
24419  }
24420
24421  /**
24422   * Symbol info table for DataMatrix.
24423   */
24424  class SymbolInfo {
24425      constructor(rectangular, dataCapacity, errorCodewords, matrixWidth, matrixHeight, dataRegions, rsBlockData = 0, rsBlockError = 0) {
24426          this.rectangular = rectangular;
24427          this.dataCapacity = dataCapacity;
24428          this.errorCodewords = errorCodewords;
24429          this.matrixWidth = matrixWidth;
24430          this.matrixHeight = matrixHeight;
24431          this.dataRegions = dataRegions;
24432          this.rsBlockData = rsBlockData;
24433          this.rsBlockError = rsBlockError;
24434      }
24435      static lookup(dataCodewords, shape = 0 /* 
vendor: 26,262 bytes, lines 24435-25113
24435FORCE_NONE */, minSize = null, maxSize = null, fail = true) {
24436          for (const symbol of PROD_SYMBOLS) {
24437              if (shape === 1 /* FORCE_SQUARE */ && symbol.rectangular) {
24438                  continue;
24439              }
24440              if (shape === 2 /* FORCE_RECTANGLE */ && !symbol.rectangular) {
24441                  continue;
24442              }
24443              if (minSize != null &&
24444                  (symbol.getSymbolWidth() < minSize.getWidth() ||
24445                      symbol.getSymbolHeight() < minSize.getHeight())) {
24446                  continue;
24447              }
24448              if (maxSize != null &&
24449                  (symbol.getSymbolWidth() > maxSize.getWidth() ||
24450                      symbol.getSymbolHeight() > maxSize.getHeight())) {
24451                  continue;
24452              }
24453              if (dataCodewords <= symbol.dataCapacity) {
24454                  return symbol;
24455              }
24456          }
24457          if (fail) {
24458              throw new Error("Can't find a symbol arrangement that matches the message. Data codewords: " +
24459                  dataCodewords);
24460          }
24461          return null;
24462      }
24463      getHorizontalDataRegions() {
24464          switch (this.dataRegions) {
24465              case 1:
24466                  return 1;
24467              case 2:
24468              case 4:
24469                  return 2;
24470              case 16:
24471                  return 4;
24472              case 36:
24473                  return 6;
24474              default:
24475                  throw new Error('Cannot handle this number of data regions');
24476          }
24477      }
24478      getVerticalDataRegions() {
24479          switch (this.dataRegions) {
24480              case 1:
24481              case 2:
24482                  return 1;
24483              case 4:
24484                  return 2;
24485              case 16:
24486                  return 4;
24487              case 36:
24488                  return 6;
24489              default:
24490                  throw new Error('Cannot handle this number of data regions');
24491          }
24492      }
24493      getSymbolDataWidth() {
24494          return this.getHorizontalDataRegions() * this.matrixWidth;
24495      }
24496      getSymbolDataHeight() {
24497          return this.getVerticalDataRegions() * this.matrixHeight;
24498      }
24499      getSymbolWidth() {
24500          return this.getSymbolDataWidth() + this.getHorizontalDataRegions() * 2;
24501      }
24502      getSymbolHeight() {
24503          return this.getSymbolDataHeight() + this.getVerticalDataRegions() * 2;
24504      }
24505      getCodewordCount() {
24506          return this.dataCapacity + this.errorCodewords;
24507      }
24508      getInterleavedBlockCount() {
24509          if (!this.rsBlockData)
24510              return 1;
24511          return this.dataCapacity / this.rsBlockData;
24512      }
24513      getDataCapacity() {
24514          return this.dataCapacity;
24515      }
24516      getErrorCodewords() {
24517          return this.errorCodewords;
24518      }
24519      getDataLengthForInterleavedBlock(index) {
24520          return this.rsBlockData;
24521      }
24522      getErrorLengthForInterleavedBlock(index) {
24523          return this.rsBlockError;
24524      }
24525  }
24526  class DataMatrixSymbolInfo144 extends SymbolInfo {
24527      constructor() {
24528          super(false, 1558, 620, 22, 22, 36, -1, 62);
24529      }
24530      getInterleavedBlockCount() {
24531          return 10;
24532      }
24533      getDataLengthForInterleavedBlock(index) {
24534          return index <= 8 ? 156 : 155;
24535      }
24536  }
24537  const PROD_SYMBOLS = [
24538      new SymbolInfo(false, 3, 5, 8, 8, 1),
24539      new SymbolInfo(false, 5, 7, 10, 10, 1),
24540      /*rect*/ new SymbolInfo(true, 5, 7, 16, 6, 1),
24541      new SymbolInfo(false, 8, 10, 12, 12, 1),
24542      /*rect*/ new SymbolInfo(true, 10, 11, 14, 6, 2),
24543      new SymbolInfo(false, 12, 12, 14, 14, 1),
24544      /*rect*/ new SymbolInfo(true, 16, 14, 24, 10, 1),
24545      new SymbolInfo(false, 18, 14, 16, 16, 1),
24546      new SymbolInfo(false, 22, 18, 18, 18, 1),
24547      /*rect*/ new SymbolInfo(true, 22, 18, 16, 10, 2),
24548      new SymbolInfo(false, 30, 20, 20, 20, 1),
24549      /*rect*/ new SymbolInfo(true, 32, 24, 16, 14, 2),
24550      new SymbolInfo(false, 36, 24, 22, 22, 1),
24551      new SymbolInfo(false, 44, 28, 24, 24, 1),
24552      /*rect*/ new SymbolInfo(true, 49, 28, 22, 14, 2),
24553      new SymbolInfo(false, 62, 36, 14, 14, 4),
24554      new SymbolInfo(false, 86, 42, 16, 16, 4),
24555      new SymbolInfo(false, 114, 48, 18, 18, 4),
24556      new SymbolInfo(false, 144, 56, 20, 20, 4),
24557      new SymbolInfo(false, 174, 68, 22, 22, 4),
24558      new SymbolInfo(false, 204, 84, 24, 24, 4, 102, 42),
24559      new SymbolInfo(false, 280, 112, 14, 14, 16, 140, 56),
24560      new SymbolInfo(false, 368, 144, 16, 16, 16, 92, 36),
24561      new SymbolInfo(false, 456, 192, 18, 18, 16, 114, 48),
24562      new SymbolInfo(false, 576, 224, 20, 20, 16, 144, 56),
24563      new SymbolInfo(false, 696, 272, 22, 22, 16, 174, 68),
24564      new SymbolInfo(false, 816, 336, 24, 24, 16, 136, 56),
24565      new SymbolInfo(false, 1050, 408, 18, 18, 36, 175, 68),
24566      new SymbolInfo(false, 1304, 496, 20, 20, 36, 163, 62),
24567      new DataMatrixSymbolInfo144(),
24568  ];
24569
24570  class EncoderContext {
24571      constructor(msg) {
24572          this.msg = msg;
24573          this.pos = 0;
24574          this.skipAtEnd = 0;
24575          // From this point on Strings are not Unicode anymore!
24576          const msgBinary = msg.split('').map(c => c.charCodeAt(0));
24577          const sb = new StringBuilder();
24578          for (let i = 0, c = msgBinary.length; i < c; i++) {
24579              const ch = String.fromCharCode(msgBinary[i] & 0xff);
24580              if (ch === '?' && msg.charAt(i) !== '?') {
24581                  throw new Error('Message contains characters outside ISO-8859-1 encoding.');
24582              }
24583              sb.append(ch);
24584          }
24585          this.msg = sb.toString(); // Not Unicode here!
24586          this.shape = 0 /* FORCE_NONE */;
24587          this.codewords = new StringBuilder();
24588          this.newEncoding = -1;
24589      }
24590      setSymbolShape(shape) {
24591          this.shape = shape;
24592      }
24593      setSizeConstraints(minSize, maxSize) {
24594          this.minSize = minSize;
24595          this.maxSize = maxSize;
24596      }
24597      getMessage() {
24598          return this.msg;
24599      }
24600      setSkipAtEnd(count) {
24601          this.skipAtEnd = count;
24602      }
24603      getCurrentChar() {
24604          return this.msg.charCodeAt(this.pos);
24605      }
24606      getCurrent() {
24607          return this.msg.charCodeAt(this.pos);
24608      }
24609      getCodewords() {
24610          return this.codewords;
24611      }
24612      writeCodewords(codewords) {
24613          this.codewords.append(codewords);
24614      }
24615      writeCodeword(codeword) {
24616          this.codewords.append(codeword);
24617      }
24618      getCodewordCount() {
24619          return this.codewords.length();
24620      }
24621      getNewEncoding() {
24622          return this.newEncoding;
24623      }
24624      signalEncoderChange(encoding) {
24625          this.newEncoding = encoding;
24626      }
24627      resetEncoderSignal() {
24628          this.newEncoding = -1;
24629      }
24630      hasMoreCharacters() {
24631          return this.pos < this.getTotalMessageCharCount();
24632      }
24633      getTotalMessageCharCount() {
24634          return this.msg.length - this.skipAtEnd;
24635      }
24636      getRemainingCharacters() {
24637          return this.getTotalMessageCharCount() - this.pos;
24638      }
24639      getSymbolInfo() {
24640          return this.symbolInfo;
24641      }
24642      updateSymbolInfo(len = this.getCodewordCount()) {
24643          if (this.symbolInfo == null || len > this.symbolInfo.getDataCapacity()) {
24644              this.symbolInfo = SymbolInfo.lookup(len, this.shape, this.minSize, this.maxSize, true);
24645          }
24646      }
24647      resetSymbolInfo() {
24648          this.symbolInfo = null;
24649      }
24650  }
24651
24652  class X12Encoder extends C40Encoder {
24653      getEncodingMode() {
24654          return X12_ENCODATION;
24655      }
24656      encode(context) {
24657          // step C
24658          const buffer = new StringBuilder();
24659          while (context.hasMoreCharacters()) {
24660              const c = context.getCurrentChar();
24661              context.pos++;
24662              this.encodeChar(c, buffer);
24663              const count = buffer.length();
24664              if (count % 3 === 0) {
24665                  this.writeNextTriplet(context, buffer);
24666                  const newMode = HighLevelEncoder$1.lookAheadTest(context.getMessage(), context.pos, this.getEncodingMode());
24667                  if (newMode !== this.getEncodingMode()) {
24668                      // Return to ASCII encodation, which will actually handle latch to new mode
24669                      context.signalEncoderChange(ASCII_ENCODATION);
24670                      break;
24671                  }
24672              }
24673          }
24674          this.handleEOD(context, buffer);
24675      }
24676      encodeChar(c, sb) {
24677          switch (c) {
24678              case 13: // CR (Carriage return)
24679                  sb.append(0o0);
24680                  break;
24681              case '*'.charCodeAt(0):
24682                  sb.append(0o1);
24683                  break;
24684              case '>'.charCodeAt(0):
24685                  sb.append(0o2);
24686                  break;
24687              case ' '.charCodeAt(0):
24688                  sb.append(0o3);
24689                  break;
24690              default:
24691                  if (c >= '0'.charCodeAt(0) && c <= '9'.charCodeAt(0)) {
24692                      sb.append(c - 48 + 4);
24693                  }
24694                  else if (c >= 'A'.charCodeAt(0) && c <= 'Z'.charCodeAt(0)) {
24695                      sb.append(c - 65 + 14);
24696                  }
24697                  else {
24698                      HighLevelEncoder$1.illegalCharacter(StringUtils.getCharAt(c));
24699                  }
24700                  break;
24701          }
24702          return 1;
24703      }
24704      handleEOD(context, buffer) {
24705          context.updateSymbolInfo();
24706          const available = context.getSymbolInfo().getDataCapacity() - context.getCodewordCount();
24707          const count = buffer.length();
24708          context.pos -= count;
24709          if (context.getRemainingCharacters() > 1 ||
24710              available > 1 ||
24711              context.getRemainingCharacters() !== available) {
24712              context.writeCodeword(X12_UNLATCH);
24713          }
24714          if (context.getNewEncoding() < 0) {
24715              context.signalEncoderChange(ASCII_ENCODATION);
24716          }
24717      }
24718  }
24719
24720  class TextEncoder$1 extends C40Encoder {
24721      getEncodingMode() {
24722          return TEXT_ENCODATION;
24723      }
24724      encodeChar(c, sb) {
24725          if (c === ' '.charCodeAt(0)) {
24726              sb.append(0o3);
24727              return 1;
24728          }
24729          if (c >= '0'.charCodeAt(0) && c <= '9'.charCodeAt(0)) {
24730              sb.append(c - 48 + 4);
24731              return 1;
24732          }
24733          if (c >= 'a'.charCodeAt(0) && c <= 'z'.charCodeAt(0)) {
24734              sb.append(c - 97 + 14);
24735              return 1;
24736          }
24737          if (c < ' '.charCodeAt(0)) {
24738              sb.append(0o0); // Shift 1 Set
24739              sb.append(c);
24740              return 2;
24741          }
24742          if (c <= '/'.charCodeAt(0)) {
24743              sb.append(0o1); // Shift 2 Set
24744              sb.append(c - 33);
24745              return 2;
24746          }
24747          if (c <= '@'.charCodeAt(0)) {
24748              sb.append(0o1); // Shift 2 Set
24749              sb.append(c - 58 + 15);
24750              return 2;
24751          }
24752          if (c >= '['.charCodeAt(0) && c <= '_'.charCodeAt(0)) {
24753              sb.append(0o1); // Shift 2 Set
24754              sb.append(c - 91 + 22);
24755              return 2;
24756          }
24757          if (c === '`'.charCodeAt(0)) {
24758              sb.append(0o2); // Shift 3 Set
24759              sb.append(0); // '`' - 96 == 0
24760              return 2;
24761          }
24762          if (c <= 'Z'.charCodeAt(0)) {
24763              sb.append(0o2); // Shift 3 Set
24764              sb.append(c - 65 + 1);
24765              return 2;
24766          }
24767          if (c <= 127) {
24768              sb.append(0o2); // Shift 3 Set
24769              sb.append(c - 123 + 27);
24770              return 2;
24771          }
24772          sb.append(`${0o1}\u001e`); // Shift 2, Upper Shift
24773          let len = 2;
24774          len += this.encodeChar(c - 128, sb);
24775          return len;
24776      }
24777  }
24778
24779  // tslint:disable-next-line:no-circular-imports
24780  /**
24781   * DataMatrix ECC 200 data encoder following the algorithm described in ISO/IEC 16022:200(E) in
24782   * annex S.
24783   */
24784  class HighLevelEncoder$1 {
24785      static randomize253State(codewordPosition) {
24786          const pseudoRandom = ((149 * codewordPosition) % 253) + 1;
24787          const tempVariable = PAD + pseudoRandom;
24788          return tempVariable <= 254 ? tempVariable : tempVariable - 254;
24789      }
24790      /**
24791       * Performs message encoding of a DataMatrix message using the algorithm described in annex P
24792       * of ISO/IEC 16022:2000(E).
24793       *
24794       * @param msg     the message
24795       * @param shape   requested shape. May be {@code SymbolShapeHint.FORCE_NONE},
24796       *                {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}.
24797       * @param minSize the minimum symbol size constraint or null for no constraint
24798       * @param maxSize the maximum symbol size constraint or null for no constraint
24799       * @param forceC40 enforce C40 encoding
24800       * @return the encoded message (the char values range from 0 to 255)
24801       */
24802      static encodeHighLevel(msg, shape = 0 /* FORCE_NONE */, minSize = null, maxSize = null, forceC40 = false) {
24803          // the codewords 0..255 are encoded as Unicode characters
24804          const c40Encoder = new C40Encoder();
24805          const encoders = [
24806              new ASCIIEncoder(),
24807              c40Encoder,
24808              new TextEncoder$1(),
24809              new X12Encoder(),
24810              new EdifactEncoder(),
24811              new Base256Encoder(),
24812          ];
24813          const context = new EncoderContext(msg);
24814          context.setSymbolShape(shape);
24815          context.setSizeConstraints(minSize, maxSize);
24816          if (msg.startsWith(MACRO_05_HEADER) && msg.endsWith(MACRO_TRAILER)) {
24817              context.writeCodeword(MACRO_05);
24818              context.setSkipAtEnd(2);
24819              context.pos += MACRO_05_HEADER.length;
24820          }
24821          else if (msg.startsWith(MACRO_06_HEADER) && msg.endsWith(MACRO_TRAILER)) {
24822              context.writeCodeword(MACRO_06);
24823              context.setSkipAtEnd(2);
24824              context.pos += MACRO_06_HEADER.length;
24825          }
24826          let encodingMode = ASCII_ENCODATION; // Default mode
24827          if (forceC40) {
24828              c40Encoder.encodeMaximal(context);
24829              encodingMode = context.getNewEncoding();
24830              context.resetEncoderSignal();
24831          }
24832          while (context.hasMoreCharacters()) {
24833              encoders[encodingMode].encode(context);
24834              if (context.getNewEncoding() >= 0) {
24835                  encodingMode = context.getNewEncoding();
24836                  context.resetEncoderSignal();
24837              }
24838          }
24839          const len = context.getCodewordCount();
24840          context.updateSymbolInfo();
24841          const capacity = context.getSymbolInfo().getDataCapacity();
24842          if (len < capacity &&
24843              encodingMode !== ASCII_ENCODATION &&
24844              encodingMode !== BASE256_ENCODATION &&
24845              encodingMode !== EDIFACT_ENCODATION) {
24846              context.writeCodeword('\u00fe'); // Unlatch (254)
24847          }
24848          // Padding
24849          const codewords = context.getCodewords();
24850          if (codewords.length() < capacity) {
24851              codewords.append(PAD);
24852          }
24853          while (codewords.length() < capacity) {
24854              codewords.append(this.randomize253State(codewords.length() + 1));
24855          }
24856          return context.getCodewords().toString();
24857      }
24858      static lookAheadTest(msg, startpos, currentMode) {
24859          const newMode = this.lookAheadTestIntern(msg, startpos, currentMode);
24860          if (currentMode === X12_ENCODATION && newMode === X12_ENCODATION) {
24861              const endpos = Math.min(startpos + 3, msg.length);
24862              for (let i = startpos; i < endpos; i++) {
24863                  if (!this.isNativeX12(msg.charCodeAt(i))) {
24864                      return ASCII_ENCODATION;
24865                  }
24866              }
24867          }
24868          else if (currentMode === EDIFACT_ENCODATION &&
24869              newMode === EDIFACT_ENCODATION) {
24870              const endpos = Math.min(startpos + 4, msg.length);
24871              for (let i = startpos; i < endpos; i++) {
24872                  if (!this.isNativeEDIFACT(msg.charCodeAt(i))) {
24873                      return ASCII_ENCODATION;
24874                  }
24875              }
24876          }
24877          return newMode;
24878      }
24879      static lookAheadTestIntern(msg, startpos, currentMode) {
24880          if (startpos >= msg.length) {
24881              return currentMode;
24882          }
24883          let charCounts;
24884          // step J
24885          if (currentMode === ASCII_ENCODATION) {
24886              charCounts = [0, 1, 1, 1, 1, 1.25];
24887          }
24888          else {
24889              charCounts = [1, 2, 2, 2, 2, 2.25];
24890              charCounts[currentMode] = 0;
24891          }
24892          let charsProcessed = 0;
24893          const mins = new Uint8Array(6);
24894          const intCharCounts = [];
24895          while (true) {
24896              // step K
24897              if (startpos + charsProcessed === msg.length) {
24898                  Arrays.fill(mins, 0);
24899                  Arrays.fill(intCharCounts, 0);
24900                  const min = this.findMinimums(charCounts, intCharCounts, Integer.MAX_VALUE, mins);
24901                  const minCount = this.getMinimumCount(mins);
24902                  if (intCharCounts[ASCII_ENCODATION] === min) {
24903                      return ASCII_ENCODATION;
24904                  }
24905                  if (minCount === 1) {
24906                      if (mins[BASE256_ENCODATION] > 0) {
24907                          return BASE256_ENCODATION;
24908                      }
24909                      if (mins[EDIFACT_ENCODATION] > 0) {
24910                          return EDIFACT_ENCODATION;
24911                      }
24912                      if (mins[TEXT_ENCODATION] > 0) {
24913                          return TEXT_ENCODATION;
24914                      }
24915                      if (mins[X12_ENCODATION] > 0) {
24916                          return X12_ENCODATION;
24917                      }
24918                  }
24919                  return C40_ENCODATION;
24920              }
24921              const c = msg.charCodeAt(startpos + charsProcessed);
24922              charsProcessed++;
24923              // step L
24924              if (this.isDigit(c)) {
24925                  charCounts[ASCII_ENCODATION] += 0.5;
24926              }
24927              else if (this.isExtendedASCII(c)) {
24928                  charCounts[ASCII_ENCODATION] = Math.ceil(charCounts[ASCII_ENCODATION]);
24929                  charCounts[ASCII_ENCODATION] += 2.0;
24930              }
24931              else {
24932                  charCounts[ASCII_ENCODATION] = Math.ceil(charCounts[ASCII_ENCODATION]);
24933                  charCounts[ASCII_ENCODATION]++;
24934              }
24935              // step M
24936              if (this.isNativeC40(c)) {
24937                  charCounts[C40_ENCODATION] += 2.0 / 3.0;
24938              }
24939              else if (this.isExtendedASCII(c)) {
24940                  charCounts[C40_ENCODATION] += 8.0 / 3.0;
24941              }
24942              else {
24943                  charCounts[C40_ENCODATION] += 4.0 / 3.0;
24944              }
24945              // step N
24946              if (this.isNativeText(c)) {
24947                  charCounts[TEXT_ENCODATION] += 2.0 / 3.0;
24948              }
24949              else if (this.isExtendedASCII(c)) {
24950                  charCounts[TEXT_ENCODATION] += 8.0 / 3.0;
24951              }
24952              else {
24953                  charCounts[TEXT_ENCODATION] += 4.0 / 3.0;
24954              }
24955              // step O
24956              if (this.isNativeX12(c)) {
24957                  charCounts[X12_ENCODATION] += 2.0 / 3.0;
24958              }
24959              else if (this.isExtendedASCII(c)) {
24960                  charCounts[X12_ENCODATION] += 13.0 / 3.0;
24961              }
24962              else {
24963                  charCounts[X12_ENCODATION] += 10.0 / 3.0;
24964              }
24965              // step P
24966              if (this.isNativeEDIFACT(c)) {
24967                  charCounts[EDIFACT_ENCODATION] += 3.0 / 4.0;
24968              }
24969              else if (this.isExtendedASCII(c)) {
24970                  charCounts[EDIFACT_ENCODATION] += 17.0 / 4.0;
24971              }
24972              else {
24973                  charCounts[EDIFACT_ENCODATION] += 13.0 / 4.0;
24974              }
24975              // step Q
24976              if (this.isSpecialB256(c)) {
24977                  charCounts[BASE256_ENCODATION] += 4.0;
24978              }
24979              else {
24980                  charCounts[BASE256_ENCODATION]++;
24981              }
24982              // step R
24983              if (charsProcessed >= 4) {
24984                  Arrays.fill(mins, 0);
24985                  Arrays.fill(intCharCounts, 0);
24986                  this.findMinimums(charCounts, intCharCounts, Integer.MAX_VALUE, mins);
24987                  if (intCharCounts[ASCII_ENCODATION] <
24988                      this.min(intCharCounts[BASE256_ENCODATION], intCharCounts[C40_ENCODATION], intCharCounts[TEXT_ENCODATION], intCharCounts[X12_ENCODATION], intCharCounts[EDIFACT_ENCODATION])) {
24989                      return ASCII_ENCODATION;
24990                  }
24991                  if (intCharCounts[BASE256_ENCODATION] < intCharCounts[ASCII_ENCODATION] ||
24992                      intCharCounts[BASE256_ENCODATION] + 1 <
24993                          this.min(intCharCounts[C40_ENCODATION], intCharCounts[TEXT_ENCODATION], intCharCounts[X12_ENCODATION], intCharCounts[EDIFACT_ENCODATION])) {
24994                      return BASE256_ENCODATION;
24995                  }
24996                  if (intCharCounts[EDIFACT_ENCODATION] + 1 <
24997                      this.min(intCharCounts[BASE256_ENCODATION], intCharCounts[C40_ENCODATION], intCharCounts[TEXT_ENCODATION], intCharCounts[X12_ENCODATION], intCharCounts[ASCII_ENCODATION])) {
24998                      return EDIFACT_ENCODATION;
24999                  }
25000                  if (intCharCounts[TEXT_ENCODATION] + 1 <
25001                      this.min(intCharCounts[BASE256_ENCODATION], intCharCounts[C40_ENCODATION], intCharCounts[EDIFACT_ENCODATION], intCharCounts[X12_ENCODATION], intCharCounts[ASCII_ENCODATION])) {
25002                      return TEXT_ENCODATION;
25003                  }
25004                  if (intCharCounts[X12_ENCODATION] + 1 <
25005                      this.min(intCharCounts[BASE256_ENCODATION], intCharCounts[C40_ENCODATION], intCharCounts[EDIFACT_ENCODATION], intCharCounts[TEXT_ENCODATION], intCharCounts[ASCII_ENCODATION])) {
25006                      return X12_ENCODATION;
25007                  }
25008                  if (intCharCounts[C40_ENCODATION] + 1 <
25009                      this.min(intCharCounts[ASCII_ENCODATION], intCharCounts[BASE256_ENCODATION], intCharCounts[EDIFACT_ENCODATION], intCharCounts[TEXT_ENCODATION])) {
25010                      if (intCharCounts[C40_ENCODATION] < intCharCounts[X12_ENCODATION]) {
25011                          return C40_ENCODATION;
25012                      }
25013                      if (intCharCounts[C40_ENCODATION] === intCharCounts[X12_ENCODATION]) {
25014                          let p = startpos + charsProcessed + 1;
25015                          while (p < msg.length) {
25016                              const tc = msg.charCodeAt(p);
25017                              if (this.isX12TermSep(tc)) {
25018                                  return X12_ENCODATION;
25019                              }
25020                              if (!this.isNativeX12(tc)) {
25021                                  break;
25022                              }
25023                              p++;
25024                          }
25025                          return C40_ENCODATION;
25026                      }
25027                  }
25028              }
25029          }
25030      }
25031      static min(f1, f2, f3, f4, f5) {
25032          const val = Math.min(f1, Math.min(f2, Math.min(f3, f4)));
25033          if (f5 === undefined) {
25034              return val;
25035          }
25036          else {
25037              return Math.min(val, f5);
25038          }
25039      }
25040      static findMinimums(charCounts, intCharCounts, min, mins) {
25041          for (let i = 0; i < 6; i++) {
25042              const current = (intCharCounts[i] = Math.ceil(charCounts[i]));
25043              if (min > current) {
25044                  min = current;
25045                  Arrays.fill(mins, 0);
25046              }
25047              if (min === current) {
25048                  mins[i] = mins[i] + 1;
25049              }
25050          }
25051          return min;
25052      }
25053      static getMinimumCount(mins) {
25054          let minCount = 0;
25055          for (let i = 0; i < 6; i++) {
25056              minCount += mins[i];
25057          }
25058          return minCount || 0;
25059      }
25060      static isDigit(ch) {
25061          return ch >= '0'.charCodeAt(0) && ch <= '9'.charCodeAt(0);
25062      }
25063      static isExtendedASCII(ch) {
25064          return ch >= 128 && ch <= 255;
25065      }
25066      static isNativeC40(ch) {
25067          return (ch === ' '.charCodeAt(0) ||
25068              (ch >= '0'.charCodeAt(0) && ch <= '9'.charCodeAt(0)) ||
25069              (ch >= 'A'.charCodeAt(0) && ch <= 'Z'.charCodeAt(0)));
25070      }
25071      static isNativeText(ch) {
25072          return (ch === ' '.charCodeAt(0) ||
25073              (ch >= '0'.charCodeAt(0) && ch <= '9'.charCodeAt(0)) ||
25074              (ch >= 'a'.charCodeAt(0) && ch <= 'z'.charCodeAt(0)));
25075      }
25076      static isNativeX12(ch) {
25077          return (this.isX12TermSep(ch) ||
25078              ch === ' '.charCodeAt(0) ||
25079              (ch >= '0'.charCodeAt(0) && ch <= '9'.charCodeAt(0)) ||
25080              (ch >= 'A'.charCodeAt(0) && ch <= 'Z'.charCodeAt(0)));
25081      }
25082      static isX12TermSep(ch) {
25083          return (ch === 13 || // CR
25084              ch === '*'.charCodeAt(0) ||
25085              ch === '>'.charCodeAt(0));
25086      }
25087      static isNativeEDIFACT(ch) {
25088          return ch >= ' '.charCodeAt(0) && ch <= '^'.charCodeAt(0);
25089      }
25090      static isSpecialB256(ch) {
25091          return false; // TODO NOT IMPLEMENTED YET!!!
25092      }
25093      /**
25094       * Determines the number of consecutive characters that are encodable using numeric compaction.
25095       *
25096       * @param msg      the message
25097       * @param startpos the start position within the message
25098       * @return the requested character count
25099       */
25100      static determineConsecutiveDigitCount(msg, startpos = 0) {
25101          const len = msg.length;
25102          let idx = startpos;
25103          while (idx < len && this.isDigit(msg.charCodeAt(idx))) {
25104              idx++;
25105          }
25106          return idx - startpos;
25107      }
25108      static illegalCharacter(singleCharacter) {
25109          let hex = Integer.toHexString(singleCharacter.charCodeAt(0));
25110          hex = '0000'.substring(0, 4 - hex.length) + hex;
25111          throw new Error('Illegal character: ' + singleCharacter + ' (0x' + hex + ')');
25112      }
25113  }
vendor: 54,800 bytes, lines 25113-26266
25113
25114
25115  /**
25116   * Set of CharsetEncoders for a given input string
25117   *
25118   * Invariants:
25119   * - The list contains only encoders from CharacterSetECI (list is shorter then the list of encoders available on
25120   *   the platform for which ECI values are defined).
25121   * - The list contains encoders at least one encoder for every character in the input.
25122   * - The first encoder in the list is always the ISO-8859-1 encoder even of no character in the input can be encoded
25123   *       by it.
25124   * - If the input contains a character that is not in ISO-8859-1 then the last two entries in the list will be the
25125   *   UTF-8 encoder and the UTF-16BE encoder.
25126   *
25127   * @author Alex Geller
25128   */
25129  class CharsetEncoder {
25130      constructor(charset) {
25131          this.charset = charset;
25132          this.name = charset.name;
25133      }
25134      canEncode(c) {
25135          try {
25136              return StringEncoding.encode(c, this.charset) != null;
25137          }
25138          catch (ex) {
25139              return false;
25140          }
25141      }
25142  }
25143  class ECIEncoderSet {
25144      /**
25145       * Constructs an encoder set
25146       *
25147       * @param stringToEncode the string that needs to be encoded
25148       * @param priorityCharset The preferred {@link Charset} or null.
25149       * @param fnc1 fnc1 denotes the character in the input that represents the FNC1 character or -1 for a non-GS1 bar
25150       * code. When specified, it is considered an error to pass it as argument to the methods canEncode() or encode().
25151       */
25152      constructor(stringToEncode, priorityCharset, fnc1) {
25153          this.ENCODERS = [
25154              'IBM437',
25155              'ISO-8859-2',
25156              'ISO-8859-3',
25157              'ISO-8859-4',
25158              'ISO-8859-5',
25159              'ISO-8859-6',
25160              'ISO-8859-7',
25161              'ISO-8859-8',
25162              'ISO-8859-9',
25163              'ISO-8859-10',
25164              'ISO-8859-11',
25165              'ISO-8859-13',
25166              'ISO-8859-14',
25167              'ISO-8859-15',
25168              'ISO-8859-16',
25169              'windows-1250',
25170              'windows-1251',
25171              'windows-1252',
25172              'windows-1256',
25173              'Shift_JIS',
25174          ].map(name => new CharsetEncoder(Charset.forName(name)));
25175          this.encoders = [];
25176          const neededEncoders = [];
25177          // we always need the ISO-8859-1 encoder. It is the default encoding
25178          neededEncoders.push(new CharsetEncoder(StandardCharsets.ISO_8859_1));
25179          let needUnicodeEncoder = priorityCharset != null && priorityCharset.name.startsWith('UTF');
25180          // Walk over the input string and see if all characters can be encoded with the list of encoders
25181          for (let i = 0; i < stringToEncode.length; i++) {
25182              let canEncode = false;
25183              for (const encoder of neededEncoders) {
25184                  const singleCharacter = stringToEncode.charAt(i);
25185                  const c = singleCharacter.charCodeAt(0);
25186                  if (c === fnc1 || encoder.canEncode(singleCharacter)) {
25187                      canEncode = true;
25188                      break;
25189                  }
25190              }
25191              if (!canEncode) {
25192                  // for the character at position i we don't yet have an encoder in the list
25193                  for (const encoder of this.ENCODERS) {
25194                      if (encoder.canEncode(stringToEncode.charAt(i))) {
25195                          // Good, we found an encoder that can encode the character. We add him to the list and continue scanning
25196                          // the input
25197                          neededEncoders.push(encoder);
25198                          canEncode = true;
25199                          break;
25200                      }
25201                  }
25202              }
25203              if (!canEncode) {
25204                  // The character is not encodeable by any of the single byte encoders so we remember that we will need a
25205                  // Unicode encoder.
25206                  needUnicodeEncoder = true;
25207              }
25208          }
25209          if (neededEncoders.length === 1 && !needUnicodeEncoder) {
25210              // the entire input can be encoded by the ISO-8859-1 encoder
25211              this.encoders = [neededEncoders[0]];
25212          }
25213          else {
25214              // we need more than one single byte encoder or we need a Unicode encoder.
25215              // In this case we append a UTF-8 and UTF-16 encoder to the list
25216              this.encoders = [];
25217              let index = 0;
25218              for (const encoder of neededEncoders) {
25219                  this.encoders[index++] = encoder;
25220              }
25221              // this.encoders[index] = new CharsetEncoder(StandardCharsets.UTF_8);
25222              // this.encoders[index + 1] = new CharsetEncoder(StandardCharsets.UTF_16BE);
25223          }
25224          // Compute priorityEncoderIndex by looking up priorityCharset in encoders
25225          let priorityEncoderIndexValue = -1;
25226          if (priorityCharset != null) {
25227              for (let i = 0; i < this.encoders.length; i++) {
25228                  if (this.encoders[i] != null &&
25229                      priorityCharset.name === this.encoders[i].name) {
25230                      priorityEncoderIndexValue = i;
25231                      break;
25232                  }
25233              }
25234          }
25235          this.priorityEncoderIndex = priorityEncoderIndexValue;
25236          // invariants
25237          // if(this?.encoders?.[0].name !== StandardCharsets.ISO_8859_1)){
25238          // throw new Error("ISO-8859-1 must be the first encoder");
25239          // }
25240      }
25241      length() {
25242          return this.encoders.length;
25243      }
25244      getCharsetName(index) {
25245          if (!(index < this.length())) {
25246              throw new Error('index must be less than length');
25247          }
25248          return this.encoders[index].name;
25249      }
25250      getCharset(index) {
25251          if (!(index < this.length())) {
25252              throw new Error('index must be less than length');
25253          }
25254          return this.encoders[index].charset;
25255      }
25256      getECIValue(encoderIndex) {
25257          return this.encoders[encoderIndex].charset.getValueIdentifier();
25258      }
25259      /*
25260       *  returns -1 if no priority charset was defined
25261       */
25262      getPriorityEncoderIndex() {
25263          return this.priorityEncoderIndex;
25264      }
25265      canEncode(c, encoderIndex) {
25266          if (!(encoderIndex < this.length())) {
25267              throw new Error('index must be less than length');
25268          }
25269          return true;
25270      }
25271      encode(c, encoderIndex) {
25272          if (!(encoderIndex < this.length())) {
25273              throw new Error('index must be less than length');
25274          }
25275          return StringEncoding.encode(StringUtils.getCharAt(c), this.encoders[encoderIndex].name);
25276      }
25277  }
25278
25279  const COST_PER_ECI = 3; // approximated (latch + 2 codewords)
25280  class MinimalECIInput {
25281      /**
25282       * Constructs a minimal input
25283       *
25284       * @param stringToEncode the character string to encode
25285       * @param priorityCharset The preferred {@link Charset}. When the value of the argument is null, the algorithm
25286       *   chooses charsets that leads to a minimal representation. Otherwise the algorithm will use the priority
25287       *   charset to encode any character in the input that can be encoded by it if the charset is among the
25288       *   supported charsets.
25289       * @param fnc1 denotes the character in the input that represents the FNC1 character or -1 if this is not GS1
25290       *   input.
25291       */
25292      constructor(stringToEncode, priorityCharset, fnc1) {
25293          this.fnc1 = fnc1;
25294          const encoderSet = new ECIEncoderSet(stringToEncode, priorityCharset, fnc1);
25295          if (encoderSet.length() === 1) {
25296              // optimization for the case when all can be encoded without ECI in ISO-8859-1
25297              for (let i = 0; i < this.bytes.length; i++) {
25298                  const c = stringToEncode.charAt(i).charCodeAt(0);
25299                  this.bytes[i] = c === fnc1 ? 1000 : c;
25300              }
25301          }
25302          else {
25303              this.bytes = this.encodeMinimally(stringToEncode, encoderSet, fnc1);
25304          }
25305      }
25306      getFNC1Character() {
25307          return this.fnc1;
25308      }
25309      /**
25310       * Returns the length of this input.  The length is the number
25311       * of {@code byte}s, FNC1 characters or ECIs in the sequence.
25312       *
25313       * @return  the number of {@code char}s in this sequence
25314       */
25315      length() {
25316          return this.bytes.length;
25317      }
25318      haveNCharacters(index, n) {
25319          if (index + n - 1 >= this.bytes.length) {
25320              return false;
25321          }
25322          for (let i = 0; i < n; i++) {
25323              if (this.isECI(index + i)) {
25324                  return false;
25325              }
25326          }
25327          return true;
25328      }
25329      /**
25330       * Returns the {@code byte} value at the specified index.  An index ranges from zero
25331       * to {@code length() - 1}.  The first {@code byte} value of the sequence is at
25332       * index zero, the next at index one, and so on, as for array
25333       * indexing.
25334       *
25335       * @param   index the index of the {@code byte} value to be returned
25336       *
25337       * @return  the specified {@code byte} value as character or the FNC1 character
25338       *
25339       * @throws  IndexOutOfBoundsException
25340       *          if the {@code index} argument is negative or not less than
25341       *          {@code length()}
25342       * @throws  IllegalArgumentException
25343       *          if the value at the {@code index} argument is an ECI (@see #isECI)
25344       */
25345      charAt(index) {
25346          if (index < 0 || index >= this.length()) {
25347              throw new Error('' + index);
25348          }
25349          if (this.isECI(index)) {
25350              throw new Error('value at ' + index + ' is not a character but an ECI');
25351          }
25352          return this.isFNC1(index) ? this.fnc1 : this.bytes[index];
25353      }
25354      /**
25355       * Returns a {@code CharSequence} that is a subsequence of this sequence.
25356       * The subsequence starts with the {@code char} value at the specified index and
25357       * ends with the {@code char} value at index {@code end - 1}.  The length
25358       * (in {@code char}s) of the
25359       * returned sequence is {@code end - start}, so if {@code start == end}
25360       * then an empty sequence is returned.
25361       *
25362       * @param   start   the start index, inclusive
25363       * @param   end     the end index, exclusive
25364       *
25365       * @return  the specified subsequence
25366       *
25367       * @throws  IndexOutOfBoundsException
25368       *          if {@code start} or {@code end} are negative,
25369       *          if {@code end} is greater than {@code length()},
25370       *          or if {@code start} is greater than {@code end}
25371       * @throws  IllegalArgumentException
25372       *          if a value in the range {@code start}-{@code end} is an ECI (@see #isECI)
25373       */
25374      subSequence(start, end) {
25375          if (start < 0 || start > end || end > this.length()) {
25376              throw new Error('' + start);
25377          }
25378          const result = new StringBuilder();
25379          for (let i = start; i < end; i++) {
25380              if (this.isECI(i)) {
25381                  throw new Error('value at ' + i + ' is not a character but an ECI');
25382              }
25383              result.append(this.charAt(i));
25384          }
25385          return result.toString();
25386      }
25387      /**
25388       * Determines if a value is an ECI
25389       *
25390       * @param   index the index of the value
25391       *
25392       * @return  true if the value at position {@code index} is an ECI
25393       *
25394       * @throws  IndexOutOfBoundsException
25395       *          if the {@code index} argument is negative or not less than
25396       *          {@code length()}
25397       */
25398      isECI(index) {
25399          if (index < 0 || index >= this.length()) {
25400              throw new Error('' + index);
25401          }
25402          return this.bytes[index] > 255 && this.bytes[index] <= 999;
25403      }
25404      /**
25405       * Determines if a value is the FNC1 character
25406       *
25407       * @param   index the index of the value
25408       *
25409       * @return  true if the value at position {@code index} is the FNC1 character
25410       *
25411       * @throws  IndexOutOfBoundsException
25412       *          if the {@code index} argument is negative or not less than
25413       *          {@code length()}
25414       */
25415      isFNC1(index) {
25416          if (index < 0 || index >= this.length()) {
25417              throw new Error('' + index);
25418          }
25419          return this.bytes[index] === 1000;
25420      }
25421      /**
25422       * Returns the {@code int} ECI value at the specified index.  An index ranges from zero
25423       * to {@code length() - 1}.  The first {@code byte} value of the sequence is at
25424       * index zero, the next at index one, and so on, as for array
25425       * indexing.
25426       *
25427       * @param   index the index of the {@code int} value to be returned
25428       *
25429       * @return  the specified {@code int} ECI value.
25430       *          The ECI specified the encoding of all bytes with a higher index until the
25431       *          next ECI or until the end of the input if no other ECI follows.
25432       *
25433       * @throws  IndexOutOfBoundsException
25434       *          if the {@code index} argument is negative or not less than
25435       *          {@code length()}
25436       * @throws  IllegalArgumentException
25437       *          if the value at the {@code index} argument is not an ECI (@see #isECI)
25438       */
25439      getECIValue(index) {
25440          if (index < 0 || index >= this.length()) {
25441              throw new Error('' + index);
25442          }
25443          if (!this.isECI(index)) {
25444              throw new Error('value at ' + index + ' is not an ECI but a character');
25445          }
25446          return this.bytes[index] - 256;
25447      }
25448      addEdge(edges, to, edge) {
25449          if (edges[to][edge.encoderIndex] == null ||
25450              edges[to][edge.encoderIndex].cachedTotalSize > edge.cachedTotalSize) {
25451              edges[to][edge.encoderIndex] = edge;
25452          }
25453      }
25454      addEdges(stringToEncode, encoderSet, edges, from, previous, fnc1) {
25455          const ch = stringToEncode.charAt(from).charCodeAt(0);
25456          let start = 0;
25457          let end = encoderSet.length();
25458          if (encoderSet.getPriorityEncoderIndex() >= 0 &&
25459              (ch === fnc1 ||
25460                  encoderSet.canEncode(ch, encoderSet.getPriorityEncoderIndex()))) {
25461              start = encoderSet.getPriorityEncoderIndex();
25462              end = start + 1;
25463          }
25464          for (let i = start; i < end; i++) {
25465              if (ch === fnc1 || encoderSet.canEncode(ch, i)) {
25466                  this.addEdge(edges, from + 1, new InputEdge(ch, encoderSet, i, previous, fnc1));
25467              }
25468          }
25469      }
25470      encodeMinimally(stringToEncode, encoderSet, fnc1) {
25471          const inputLength = stringToEncode.length;
25472          // Array that represents vertices. There is a vertex for every character and encoding.
25473          const edges = new InputEdge[inputLength + 1][encoderSet.length()]();
25474          this.addEdges(stringToEncode, encoderSet, edges, 0, null, fnc1);
25475          for (let i = 1; i <= inputLength; i++) {
25476              for (let j = 0; j < encoderSet.length(); j++) {
25477                  if (edges[i][j] != null && i < inputLength) {
25478                      this.addEdges(stringToEncode, encoderSet, edges, i, edges[i][j], fnc1);
25479                  }
25480              }
25481              // optimize memory by removing edges that have been passed.
25482              for (let j = 0; j < encoderSet.length(); j++) {
25483                  edges[i - 1][j] = null;
25484              }
25485          }
25486          let minimalJ = -1;
25487          let minimalSize = Integer.MAX_VALUE;
25488          for (let j = 0; j < encoderSet.length(); j++) {
25489              if (edges[inputLength][j] != null) {
25490                  const edge = edges[inputLength][j];
25491                  if (edge.cachedTotalSize < minimalSize) {
25492                      minimalSize = edge.cachedTotalSize;
25493                      minimalJ = j;
25494                  }
25495              }
25496          }
25497          if (minimalJ < 0) {
25498              throw new Error('Failed to encode "' + stringToEncode + '"');
25499          }
25500          const intsAL = [];
25501          let current = edges[inputLength][minimalJ];
25502          while (current != null) {
25503              if (current.isFNC1()) {
25504                  intsAL.unshift(1000);
25505              }
25506              else {
25507                  const bytes = encoderSet.encode(current.c, current.encoderIndex);
25508                  for (let i = bytes.length - 1; i >= 0; i--) {
25509                      intsAL.unshift(bytes[i] & 0xff);
25510                  }
25511              }
25512              const previousEncoderIndex = current.previous === null ? 0 : current.previous.encoderIndex;
25513              if (previousEncoderIndex !== current.encoderIndex) {
25514                  intsAL.unshift(256 + encoderSet.getECIValue(current.encoderIndex));
25515              }
25516              current = current.previous;
25517          }
25518          const ints = [];
25519          for (let i = 0; i < ints.length; i++) {
25520              ints[i] = intsAL[i];
25521          }
25522          return ints;
25523      }
25524  }
25525  class InputEdge {
25526      constructor(c, encoderSet, encoderIndex, previous, fnc1) {
25527          this.c = c;
25528          this.encoderSet = encoderSet;
25529          this.encoderIndex = encoderIndex;
25530          this.previous = previous;
25531          this.fnc1 = fnc1;
25532          this.c = c === fnc1 ? 1000 : c;
25533          let size = this.isFNC1() ? 1 : encoderSet.encode(c, encoderIndex).length;
25534          const previousEncoderIndex = previous === null ? 0 : previous.encoderIndex;
25535          if (previousEncoderIndex !== encoderIndex) {
25536              size += COST_PER_ECI;
25537          }
25538          if (previous != null) {
25539              size += previous.cachedTotalSize;
25540          }
25541          this.cachedTotalSize = size;
25542      }
25543      isFNC1() {
25544          return this.c === 1000;
25545      }
25546  }
25547
25548  var Mode;
25549  (function (Mode) {
25550      Mode[Mode["ASCII"] = 0] = "ASCII";
25551      Mode[Mode["C40"] = 1] = "C40";
25552      Mode[Mode["TEXT"] = 2] = "TEXT";
25553      Mode[Mode["X12"] = 3] = "X12";
25554      Mode[Mode["EDF"] = 4] = "EDF";
25555      Mode[Mode["B256"] = 5] = "B256";
25556  })(Mode || (Mode = {}));
25557  const C40_SHIFT2_CHARS = [
25558      '!',
25559      '"',
25560      '#',
25561      '$',
25562      '%',
25563      '&',
25564      "'",
25565      '(',
25566      ')',
25567      '*',
25568      '+',
25569      ',',
25570      '-',
25571      '.',
25572      '/',
25573      ':',
25574      ';',
25575      '<',
25576      '=',
25577      '>',
25578      '?',
25579      '@',
25580      '[',
25581      '\\',
25582      ']',
25583      '^',
25584      '_',
25585  ];
25586  class MinimalEncoder {
25587      static isExtendedASCII(ch, fnc1) {
25588          return ch !== fnc1 && ch >= 128 && ch <= 255;
25589      }
25590      static isInC40Shift1Set(ch) {
25591          return ch <= 31;
25592      }
25593      static isInC40Shift2Set(ch, fnc1) {
25594          for (const c40Shift2Char of C40_SHIFT2_CHARS) {
25595              if (c40Shift2Char.charCodeAt(0) === ch) {
25596                  return true;
25597              }
25598          }
25599          return ch === fnc1;
25600      }
25601      static isInTextShift1Set(ch) {
25602          return this.isInC40Shift1Set(ch);
25603      }
25604      static isInTextShift2Set(ch, fnc1) {
25605          return this.isInC40Shift2Set(ch, fnc1);
25606      }
25607      /**
25608       * Performs message encoding of a DataMatrix message
25609       *
25610       * @param msg the message
25611       * @param priorityCharset The preferred {@link Charset}. When the value of the argument is null, the algorithm
25612       *   chooses charsets that leads to a minimal representation. Otherwise the algorithm will use the priority
25613       *   charset to encode any character in the input that can be encoded by it if the charset is among the
25614       *   supported charsets.
25615       * @param fnc1 denotes the character in the input that represents the FNC1 character or -1 if this is not a GS1
25616       *   bar code. If the value is not -1 then a FNC1 is also prepended.
25617       * @param shape requested shape.
25618       * @return the encoded message (the char values range from 0 to 255)
25619       */
25620      static encodeHighLevel(msg, priorityCharset = null, fnc1 = -1, shape = 0 /* FORCE_NONE */) {
25621          let macroId = 0;
25622          if (msg.startsWith(MACRO_05_HEADER) && msg.endsWith(MACRO_TRAILER)) {
25623              macroId = 5;
25624              msg = msg.substring(MACRO_05_HEADER.length, msg.length - 2);
25625          }
25626          else if (msg.startsWith(MACRO_06_HEADER) && msg.endsWith(MACRO_TRAILER)) {
25627              macroId = 6;
25628              msg = msg.substring(MACRO_06_HEADER.length, msg.length - 2);
25629          }
25630          return decodeURIComponent(escape(String.fromCharCode(...this.encode(msg, priorityCharset, fnc1, shape, macroId))));
25631      }
25632      /**
25633       * Encodes input minimally and returns an array of the codewords
25634       *
25635       * @param input The string to encode
25636       * @param priorityCharset The preferred {@link Charset}. When the value of the argument is null, the algorithm
25637       *   chooses charsets that leads to a minimal representation. Otherwise the algorithm will use the priority
25638       *   charset to encode any character in the input that can be encoded by it if the charset is among the
25639       *   supported charsets.
25640       * @param fnc1 denotes the character in the input that represents the FNC1 character or -1 if this is not a GS1
25641       *   bar code. If the value is not -1 then a FNC1 is also prepended.
25642       * @param shape requested shape.
25643       * @param macroId Prepends the specified macro function in case that a value of 5 or 6 is specified.
25644       * @return An array of bytes representing the codewords of a minimal encoding.
25645       */
25646      static encode(input, priorityCharset, fnc1, shape, macroId) {
25647          return this.encodeMinimally(new Input(input, priorityCharset, fnc1, shape, macroId)).getBytes();
25648      }
25649      static addEdge(edges, edge) {
25650          const vertexIndex = edge.fromPosition + edge.characterLength;
25651          if (edges[vertexIndex][edge.getEndMode()] === null ||
25652              edges[vertexIndex][edge.getEndMode()].cachedTotalSize >
25653                  edge.cachedTotalSize) {
25654              edges[vertexIndex][edge.getEndMode()] = edge;
25655          }
25656      }
25657      /** @return the number of words in which the string starting at from can be encoded in c40 or text mode.
25658       *  The number of characters encoded is returned in characterLength.
25659       *  The number of characters encoded is also minimal in the sense that the algorithm stops as soon
25660       *  as a character encoding fills a C40 word competely (three C40 values). An exception is at the
25661       *  end of the string where two C40 values are allowed (according to the spec the third c40 value
25662       *  is filled  with 0 (Shift 1) in this case).
25663       */
25664      static getNumberOfC40Words(input, from, c40, characterLength) {
25665          let thirdsCount = 0;
25666          for (let i = from; i < input.length(); i++) {
25667              if (input.isECI(i)) {
25668                  characterLength[0] = 0;
25669                  return 0;
25670              }
25671              const ci = input.charAt(i);
25672              if ((c40 && HighLevelEncoder$1.isNativeC40(ci)) ||
25673                  (!c40 && HighLevelEncoder$1.isNativeText(ci))) {
25674                  thirdsCount++; // native
25675              }
25676              else if (!MinimalEncoder.isExtendedASCII(ci, input.getFNC1Character())) {
25677                  thirdsCount += 2; // shift
25678              }
25679              else {
25680                  const asciiValue = ci & 0xff;
25681                  if (asciiValue >= 128 &&
25682                      ((c40 && HighLevelEncoder$1.isNativeC40(asciiValue - 128)) ||
25683                          (!c40 && HighLevelEncoder$1.isNativeText(asciiValue - 128)))) {
25684                      thirdsCount += 3; // shift, Upper shift
25685                  }
25686                  else {
25687                      thirdsCount += 4; // shift, Upper shift, shift
25688                  }
25689              }
25690              if (thirdsCount % 3 === 0 ||
25691                  ((thirdsCount - 2) % 3 === 0 && i + 1 === input.length())) {
25692                  characterLength[0] = i - from + 1;
25693                  return Math.ceil(thirdsCount / 3.0);
25694              }
25695          }
25696          characterLength[0] = 0;
25697          return 0;
25698      }
25699      static addEdges(input, edges, from, previous) {
25700          if (input.isECI(from)) {
25701              this.addEdge(edges, new Edge(input, Mode.ASCII, from, 1, previous));
25702              return;
25703          }
25704          const ch = input.charAt(from);
25705          if (previous === null || previous.getEndMode() !== Mode.EDF) {
25706              // not possible to unlatch a full EDF edge to something
25707              // else
25708              if (HighLevelEncoder$1.isDigit(ch) &&
25709                  input.haveNCharacters(from, 2) &&
25710                  HighLevelEncoder$1.isDigit(input.charAt(from + 1))) {
25711                  // two digits ASCII encoded
25712                  this.addEdge(edges, new Edge(input, Mode.ASCII, from, 2, previous));
25713              }
25714              else {
25715                  // one ASCII encoded character or an extended character via Upper Shift
25716                  this.addEdge(edges, new Edge(input, Mode.ASCII, from, 1, previous));
25717              }
25718              const modes = [Mode.C40, Mode.TEXT];
25719              for (const mode of modes) {
25720                  const characterLength = [];
25721                  if (MinimalEncoder.getNumberOfC40Words(input, from, mode === Mode.C40, characterLength) > 0) {
25722                      this.addEdge(edges, new Edge(input, mode, from, characterLength[0], previous));
25723                  }
25724              }
25725              if (input.haveNCharacters(from, 3) &&
25726                  HighLevelEncoder$1.isNativeX12(input.charAt(from)) &&
25727                  HighLevelEncoder$1.isNativeX12(input.charAt(from + 1)) &&
25728                  HighLevelEncoder$1.isNativeX12(input.charAt(from + 2))) {
25729                  this.addEdge(edges, new Edge(input, Mode.X12, from, 3, previous));
25730              }
25731              this.addEdge(edges, new Edge(input, Mode.B256, from, 1, previous));
25732          }
25733          // We create 4 EDF edges,  with 1, 2 3 or 4 characters length. The fourth normally doesn't have a latch to ASCII
25734          // unless it is 2 characters away from the end of the input.
25735          let i;
25736          for (i = 0; i < 3; i++) {
25737              const pos = from + i;
25738              if (input.haveNCharacters(pos, 1) &&
25739                  HighLevelEncoder$1.isNativeEDIFACT(input.charAt(pos))) {
25740                  this.addEdge(edges, new Edge(input, Mode.EDF, from, i + 1, previous));
25741              }
25742              else {
25743                  break;
25744              }
25745          }
25746          if (i === 3 &&
25747              input.haveNCharacters(from, 4) &&
25748              HighLevelEncoder$1.isNativeEDIFACT(input.charAt(from + 3))) {
25749              this.addEdge(edges, new Edge(input, Mode.EDF, from, 4, previous));
25750          }
25751      }
25752      static encodeMinimally(input) {
25753          /* The minimal encoding is computed by Dijkstra. The acyclic graph is modeled as follows:
25754           * A vertex represents a combination of a position in the input and an encoding mode where position 0
25755           * denotes the position left of the first character, 1 the position left of the second character and so on.
25756           * Likewise the end vertices are located after the last character at position input.length().
25757           * For any position there might be up to six vertices, one for each of the encoding types ASCII, C40, TEXT, X12,
25758           * EDF and B256.
25759           *
25760           * As an example consider the input string "ABC123" then at position 0 there is only one vertex with the default
25761           * ASCII encodation. At position 3 there might be vertices for the types ASCII, C40, X12, EDF and B256.
25762           *
25763           * An edge leading to such a vertex encodes one or more of the characters left of the position that the vertex
25764           * represents. It encodes the characters in the encoding mode of the vertex that it ends on. In other words,
25765           * all edges leading to a particular vertex encode the same characters (the length of the suffix can vary) using the same
25766           * encoding mode.
25767           * As an example consider the input string "ABC123" and the vertex (4,EDF). Possible edges leading to this vertex
25768           * are:
25769           *   (0,ASCII)  --EDF(ABC1)--> (4,EDF)
25770           *   (1,ASCII)  --EDF(BC1)-->  (4,EDF)
25771           *   (1,B256)   --EDF(BC1)-->  (4,EDF)
25772           *   (1,EDF)    --EDF(BC1)-->  (4,EDF)
25773           *   (2,ASCII)  --EDF(C1)-->   (4,EDF)
25774           *   (2,B256)   --EDF(C1)-->   (4,EDF)
25775           *   (2,EDF)    --EDF(C1)-->   (4,EDF)
25776           *   (3,ASCII)  --EDF(1)-->    (4,EDF)
25777           *   (3,B256)   --EDF(1)-->    (4,EDF)
25778           *   (3,EDF)    --EDF(1)-->    (4,EDF)
25779           *   (3,C40)    --EDF(1)-->    (4,EDF)
25780           *   (3,X12)    --EDF(1)-->    (4,EDF)
25781           *
25782           * The edges leading to a vertex are stored in such a way that there is a fast way to enumerate the edges ending
25783           * on a particular vertex.
25784           *
25785           * The algorithm processes the vertices in order of their position thereby performing the following:
25786           *
25787           * For every vertex at position i the algorithm enumerates the edges ending on the vertex and removes all but the
25788           * shortest from that list.
25789           * Then it processes the vertices for the position i+1. If i+1 == input.length() then the algorithm ends
25790           * and chooses the the edge with the smallest size from any of the edges leading to vertices at this position.
25791           * Otherwise the algorithm computes all possible outgoing edges for the vertices at the position i+1
25792           *
25793           * Examples:
25794           * The process is illustrated by showing the graph (edges) after each iteration from left to right over the input:
25795           * An edge is drawn as follows "(" + fromVertex + ") -- " + encodingMode + "(" + encodedInput + ") (" +
25796           * accumulatedSize + ") --> (" + toVertex + ")"
25797           *
25798           * Example 1 encoding the string "ABCDEFG":
25799           *
25800           *
25801           * Situation after adding edges to the start vertex (0,ASCII)
25802           * (0,ASCII) ASCII(A) (1) --> (1,ASCII)
25803           * (0,ASCII) B256(A) (3) --> (1,B256)
25804           * (0,ASCII) EDF(AB) (4) --> (2,EDF)
25805           * (0,ASCII) C40(ABC) (3) --> (3,C40)
25806           * (0,ASCII) TEXT(ABC) (5) --> (3,TEXT)
25807           * (0,ASCII) X12(ABC) (3) --> (3,X12)
25808           * (0,ASCII) EDF(ABC) (4) --> (3,EDF)
25809           * (0,ASCII) EDF(ABCD) (4) --> (4,EDF)
25810           *
25811           * Situation after adding edges to vertices at position 1
25812           * (0,ASCII) ASCII(A) (1) --> (1,ASCII)
25813           * (0,ASCII) B256(A) (3) --> (1,B256)
25814           * (0,ASCII) EDF(AB) (4) --> (2,EDF)
25815           * (0,ASCII) C40(ABC) (3) --> (3,C40)
25816           * (0,ASCII) TEXT(ABC) (5) --> (3,TEXT)
25817           * (0,ASCII) X12(ABC) (3) --> (3,X12)
25818           * (0,ASCII) EDF(ABC) (4) --> (3,EDF)
25819           * (0,ASCII) EDF(ABCD) (4) --> (4,EDF)
25820           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII)
25821           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) B256(B) (4) --> (2,B256)
25822           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) EDF(BC) (5) --> (3,EDF)
25823           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) C40(BCD) (4) --> (4,C40)
25824           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) TEXT(BCD) (6) --> (4,TEXT)
25825           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) X12(BCD) (4) --> (4,X12)
25826           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) EDF(BCD) (5) --> (4,EDF)
25827           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) EDF(BCDE) (5) --> (5,EDF)
25828           * (0,ASCII) B256(A) (3) --> (1,B256) ASCII(B) (4) --> (2,ASCII)
25829           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256)
25830           * (0,ASCII) B256(A) (3) --> (1,B256) EDF(BC) (6) --> (3,EDF)
25831           * (0,ASCII) B256(A) (3) --> (1,B256) C40(BCD) (5) --> (4,C40)
25832           * (0,ASCII) B256(A) (3) --> (1,B256) TEXT(BCD) (7) --> (4,TEXT)
25833           * (0,ASCII) B256(A) (3) --> (1,B256) X12(BCD) (5) --> (4,X12)
25834           * (0,ASCII) B256(A) (3) --> (1,B256) EDF(BCD) (6) --> (4,EDF)
25835           * (0,ASCII) B256(A) (3) --> (1,B256) EDF(BCDE) (6) --> (5,EDF)
25836           *
25837           * Edge "(1,ASCII) ASCII(B) (2) --> (2,ASCII)" is minimal for the vertex (2,ASCII) so that edge "(1,B256) ASCII(B) (4) --> (2,ASCII)" is removed.
25838           * Edge "(1,B256) B256(B) (3) --> (2,B256)" is minimal for the vertext (2,B256) so that the edge "(1,ASCII) B256(B) (4) --> (2,B256)" is removed.
25839           *
25840           * Situation after adding edges to vertices at position 2
25841           * (0,ASCII) ASCII(A) (1) --> (1,ASCII)
25842           * (0,ASCII) B256(A) (3) --> (1,B256)
25843           * (0,ASCII) EDF(AB) (4) --> (2,EDF)
25844           * (0,ASCII) C40(ABC) (3) --> (3,C40)
25845           * (0,ASCII) TEXT(ABC) (5) --> (3,TEXT)
25846           * (0,ASCII) X12(ABC) (3) --> (3,X12)
25847           * (0,ASCII) EDF(ABC) (4) --> (3,EDF)
25848           * (0,ASCII) EDF(ABCD) (4) --> (4,EDF)
25849           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII)
25850           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) EDF(BC) (5) --> (3,EDF)
25851           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) C40(BCD) (4) --> (4,C40)
25852           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) TEXT(BCD) (6) --> (4,TEXT)
25853           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) X12(BCD) (4) --> (4,X12)
25854           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) EDF(BCD) (5) --> (4,EDF)
25855           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) EDF(BCDE) (5) --> (5,EDF)
25856           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256)
25857           * (0,ASCII) B256(A) (3) --> (1,B256) EDF(BC) (6) --> (3,EDF)
25858           * (0,ASCII) B256(A) (3) --> (1,B256) C40(BCD) (5) --> (4,C40)
25859           * (0,ASCII) B256(A) (3) --> (1,B256) TEXT(BCD) (7) --> (4,TEXT)
25860           * (0,ASCII) B256(A) (3) --> (1,B256) X12(BCD) (5) --> (4,X12)
25861           * (0,ASCII) B256(A) (3) --> (1,B256) EDF(BCD) (6) --> (4,EDF)
25862           * (0,ASCII) B256(A) (3) --> (1,B256) EDF(BCDE) (6) --> (5,EDF)
25863           * (0,ASCII) EDF(AB) (4) --> (2,EDF) ASCII(C) (5) --> (3,ASCII)
25864           * (0,ASCII) EDF(AB) (4) --> (2,EDF) B256(C) (6) --> (3,B256)
25865           * (0,ASCII) EDF(AB) (4) --> (2,EDF) EDF(CD) (7) --> (4,EDF)
25866           * (0,ASCII) EDF(AB) (4) --> (2,EDF) C40(CDE) (6) --> (5,C40)
25867           * (0,ASCII) EDF(AB) (4) --> (2,EDF) TEXT(CDE) (8) --> (5,TEXT)
25868           * (0,ASCII) EDF(AB) (4) --> (2,EDF) X12(CDE) (6) --> (5,X12)
25869           * (0,ASCII) EDF(AB) (4) --> (2,EDF) EDF(CDE) (7) --> (5,EDF)
25870           * (0,ASCII) EDF(AB) (4) --> (2,EDF) EDF(CDEF) (7) --> (6,EDF)
25871           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII)
25872           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) B256(C) (5) --> (3,B256)
25873           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) EDF(CD) (6) --> (4,EDF)
25874           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) C40(CDE) (5) --> (5,C40)
25875           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) TEXT(CDE) (7) --> (5,TEXT)
25876           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) X12(CDE) (5) --> (5,X12)
25877           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) EDF(CDE) (6) --> (5,EDF)
25878           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) EDF(CDEF) (6) --> (6,EDF)
25879           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) ASCII(C) (4) --> (3,ASCII)
25880           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) B256(C) (4) --> (3,B256)
25881           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) EDF(CD) (6) --> (4,EDF)
25882           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) C40(CDE) (5) --> (5,C40)
25883           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) TEXT(CDE) (7) --> (5,TEXT)
25884           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) X12(CDE) (5) --> (5,X12)
25885           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) EDF(CDE) (6) --> (5,EDF)
25886           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) EDF(CDEF) (6) --> (6,EDF)
25887           *
25888           * Edge "(2,ASCII) ASCII(C) (3) --> (3,ASCII)" is minimal for the vertex (3,ASCII) so that edges "(2,EDF) ASCII(C) (5) --> (3,ASCII)"
25889           * and "(2,B256) ASCII(C) (4) --> (3,ASCII)" can be removed.
25890           * Edge "(0,ASCII) EDF(ABC) (4) --> (3,EDF)" is minimal for the vertex (3,EDF) so that edges "(1,ASCII) EDF(BC) (5) --> (3,EDF)"
25891           * and "(1,B256) EDF(BC) (6) --> (3,EDF)" can be removed.
25892           * Edge "(2,B256) B256(C) (4) --> (3,B256)" is minimal for the vertex (3,B256) so that edges "(2,ASCII) B256(C) (5) --> (3,B256)"
25893           * and "(2,EDF) B256(C) (6) --> (3,B256)" can be removed.
25894           *
25895           * This continues for vertices 3 thru 7
25896           *
25897           * Situation after adding edges to vertices at position 7
25898           * (0,ASCII) ASCII(A) (1) --> (1,ASCII)
25899           * (0,ASCII) B256(A) (3) --> (1,B256)
25900           * (0,ASCII) EDF(AB) (4) --> (2,EDF)
25901           * (0,ASCII) C40(ABC) (3) --> (3,C40)
25902           * (0,ASCII) TEXT(ABC) (5) --> (3,TEXT)
25903           * (0,ASCII) X12(ABC) (3) --> (3,X12)
25904           * (0,ASCII) EDF(ABC) (4) --> (3,EDF)
25905           * (0,ASCII) EDF(ABCD) (4) --> (4,EDF)
25906           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII)
25907           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) C40(BCD) (4) --> (4,C40)
25908           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) TEXT(BCD) (6) --> (4,TEXT)
25909           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) X12(BCD) (4) --> (4,X12)
25910           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) EDF(BCDE) (5) --> (5,EDF)
25911           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256)
25912           * (0,ASCII) C40(ABC) (3) --> (3,C40) C40(DEF) (5) --> (6,C40)
25913           * (0,ASCII) X12(ABC) (3) --> (3,X12) X12(DEF) (5) --> (6,X12)
25914           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII)
25915           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) C40(CDE) (5) --> (5,C40)
25916           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) TEXT(CDE) (7) --> (5,TEXT)
25917           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) X12(CDE) (5) --> (5,X12)
25918           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) EDF(CDEF) (6) --> (6,EDF)
25919           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) C40(BCD) (4) --> (4,C40) C40(EFG) (6) --> (7,C40)    //Solution 1
25920           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) X12(BCD) (4) --> (4,X12) X12(EFG) (6) --> (7,X12)    //Solution 2
25921           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) B256(C) (4) --> (3,B256)
25922           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII) ASCII(D) (4) --> (4,ASCII)
25923           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII) TEXT(DEF) (8) --> (6,TEXT)
25924           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII) EDF(DEFG) (7) --> (7,EDF)
25925           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) B256(C) (4) --> (3,B256) B256(D) (5) --> (4,B256)
25926           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII) ASCII(D) (4) --> (4,ASCII) ASCII(E) (5) --> (5,ASCII)
25927           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII) ASCII(D) (4) --> (4,ASCII) TEXT(EFG) (9) --> (7,TEXT)
25928           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) B256(C) (4) --> (3,B256) B256(D) (5) --> (4,B256) B256(E) (6) --> (5,B256)
25929           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII) ASCII(D) (4) --> (4,ASCII) ASCII(E) (5) --> (5,ASCII) ASCII(F) (6) --> (6,ASCII)
25930           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) B256(C) (4) --> (3,B256) B256(D) (5) --> (4,B256) B256(E) (6) --> (5,B256) B256(F) (7) --> (6,B256)
25931           * (0,ASCII) ASCII(A) (1) --> (1,ASCII) ASCII(B) (2) --> (2,ASCII) ASCII(C) (3) --> (3,ASCII) ASCII(D) (4) --> (4,ASCII) ASCII(E) (5) --> (5,ASCII) ASCII(F) (6) --> (6,ASCII) ASCII(G) (7) --> (7,ASCII)
25932           * (0,ASCII) B256(A) (3) --> (1,B256) B256(B) (3) --> (2,B256) B256(C) (4) --> (3,B256) B256(D) (5) --> (4,B256) B256(E) (6) --> (5,B256) B256(F) (7) --> (6,B256) B256(G) (8) --> (7,B256)
25933           *
25934           * Hence a minimal encoding of "ABCDEFG" is either ASCII(A),C40(BCDEFG) or ASCII(A), X12(BCDEFG) with a size of 5 bytes.
25935           */
25936          const inputLength = input.length();
25937          // Array that represents vertices. There is a vertex for every character and mode.
25938          // The last dimension in the array below encodes the 6 modes ASCII, C40, TEXT, X12, EDF and B256
25939          const edges = Array(inputLength + 1)
25940              .fill(null)
25941              .map(() => Array(6).fill(0));
25942          this.addEdges(input, edges, 0, null);
25943          for (let i = 1; i <= inputLength; i++) {
25944              for (let j = 0; j < 6; j++) {
25945                  if (edges[i][j] !== null && i < inputLength) {
25946                      this.addEdges(input, edges, i, edges[i][j]);
25947                  }
25948              }
25949              // optimize memory by removing edges that have been passed.
25950              for (let j = 0; j < 6; j++) {
25951                  edges[i - 1][j] = null;
25952              }
25953          }
25954          let minimalJ = -1;
25955          let minimalSize = Integer.MAX_VALUE;
25956          for (let j = 0; j < 6; j++) {
25957              if (edges[inputLength][j] !== null) {
25958                  const edge = edges[inputLength][j];
25959                  const size = j >= 1 && j <= 3 ? edge.cachedTotalSize + 1 : edge.cachedTotalSize; // C40, TEXT and X12 need an
25960                  // extra unlatch at the end
25961                  if (size < minimalSize) {
25962                      minimalSize = size;
25963                      minimalJ = j;
25964                  }
25965              }
25966          }
25967          if (minimalJ < 0) {
25968              throw new Error('Failed to encode "' + input + '"');
25969          }
25970          return new Result(edges[inputLength][minimalJ]);
25971      }
25972  }
25973  class Result {
25974      constructor(solution) {
25975          const input = solution.input;
25976          let size = 0;
25977          let bytesAL = [];
25978          const randomizePostfixLength = [];
25979          const randomizeLengths = [];
25980          if ((solution.mode === Mode.C40 ||
25981              solution.mode === Mode.TEXT ||
25982              solution.mode === Mode.X12) &&
25983              solution.getEndMode() !== Mode.ASCII) {
25984              size += this.prepend(Edge.getBytes(254), bytesAL);
25985          }
25986          let current = solution;
25987          while (current !== null) {
25988              size += this.prepend(current.getDataBytes(), bytesAL);
25989              if (current.previous === null ||
25990                  current.getPreviousStartMode() !== current.getMode()) {
25991                  if (current.getMode() === Mode.B256) {
25992                      if (size <= 249) {
25993                          bytesAL.unshift(size);
25994                          size++;
25995                      }
25996                      else {
25997                          bytesAL.unshift(size % 250);
25998                          bytesAL.unshift(size / 250 + 249);
25999                          size += 2;
26000                      }
26001                      randomizePostfixLength.push(bytesAL.length);
26002                      randomizeLengths.push(size);
26003                  }
26004                  this.prepend(current.getLatchBytes(), bytesAL);
26005                  size = 0;
26006              }
26007              current = current.previous;
26008          }
26009          if (input.getMacroId() === 5) {
26010              size += this.prepend(Edge.getBytes(236), bytesAL);
26011          }
26012          else if (input.getMacroId() === 6) {
26013              size += this.prepend(Edge.getBytes(237), bytesAL);
26014          }
26015          if (input.getFNC1Character() > 0) {
26016              size += this.prepend(Edge.getBytes(232), bytesAL);
26017          }
26018          for (let i = 0; i < randomizePostfixLength.length; i++) {
26019              this.applyRandomPattern(bytesAL, bytesAL.length - randomizePostfixLength[i], randomizeLengths[i]);
26020          }
26021          // add padding
26022          const capacity = solution.getMinSymbolSize(bytesAL.length);
26023          if (bytesAL.length < capacity) {
26024              bytesAL.push(129);
26025          }
26026          while (bytesAL.length < capacity) {
26027              bytesAL.push(this.randomize253State(bytesAL.length + 1));
26028          }
26029          this.bytes = new Uint8Array(bytesAL.length);
26030          for (let i = 0; i < this.bytes.length; i++) {
26031              this.bytes[i] = bytesAL[i];
26032          }
26033      }
26034      prepend(bytes, into) {
26035          for (let i = bytes.length - 1; i >= 0; i--) {
26036              into.unshift(bytes[i]);
26037          }
26038          return bytes.length;
26039      }
26040      randomize253State(codewordPosition) {
26041          const pseudoRandom = ((149 * codewordPosition) % 253) + 1;
26042          const tempVariable = 129 + pseudoRandom;
26043          return tempVariable <= 254 ? tempVariable : tempVariable - 254;
26044      }
26045      applyRandomPattern(bytesAL, startPosition, length) {
26046          for (let i = 0; i < length; i++) {
26047              // See "B.1 253-state algorithm
26048              const Pad_codeword_position = startPosition + i;
26049              const Pad_codeword_value = bytesAL[Pad_codeword_position] & 0xff;
26050              const pseudo_random_number = ((149 * (Pad_codeword_position + 1)) % 255) + 1;
26051              const temp_variable = Pad_codeword_value + pseudo_random_number;
26052              bytesAL[Pad_codeword_position] =
26053                  temp_variable <= 255 ? temp_variable : temp_variable - 256;
26054          }
26055      }
26056      getBytes() {
26057          return this.bytes;
26058      }
26059  }
26060  class Edge {
26061      constructor(input, mode, fromPosition, characterLength, previous) {
26062          this.input = input;
26063          this.mode = mode;
26064          this.fromPosition = fromPosition;
26065          this.characterLength = characterLength;
26066          this.previous = previous;
26067          this.allCodewordCapacities = [
26068              3, 5, 8, 10, 12, 16, 18, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, 174, 204,
26069              280, 368, 456, 576, 696, 816, 1050, 1304, 1558,
26070          ];
26071          this.squareCodewordCapacities = [
26072              3, 5, 8, 12, 18, 22, 30, 36, 44, 62, 86, 114, 144, 174, 204, 280, 368, 456,
26073              576, 696, 816, 1050, 1304, 1558,
26074          ];
26075          this.rectangularCodewordCapacities = [5, 10, 16, 33, 32, 49];
26076          if (!(fromPosition + characterLength <= input.length())) {
26077              throw new Error('Invalid edge');
26078          }
26079          let size = previous !== null ? previous.cachedTotalSize : 0;
26080          const previousMode = this.getPreviousMode();
26081          /*
26082           * Switching modes
26083           * ASCII -> C40: latch 230
26084           * ASCII -> TEXT: latch 239
26085           * ASCII -> X12: latch 238
26086           * ASCII -> EDF: latch 240
26087           * ASCII -> B256: latch 231
26088           * C40 -> ASCII: word(c1,c2,c3), 254
26089           * TEXT -> ASCII: word(c1,c2,c3), 254
26090           * X12 -> ASCII: word(c1,c2,c3), 254
26091           * EDIFACT -> ASCII: Unlatch character,0,0,0 or c1,Unlatch character,0,0 or c1,c2,Unlatch character,0 or
26092           * c1,c2,c3,Unlatch character
26093           * B256 -> ASCII: without latch after n bytes
26094           */
26095          switch (mode) {
26096              case Mode.ASCII:
26097                  size++;
26098                  if (input.isECI(fromPosition) ||
26099                      MinimalEncoder.isExtendedASCII(input.charAt(fromPosition), input.getFNC1Character())) {
26100                      size++;
26101                  }
26102                  if (previousMode === Mode.C40 ||
26103                      previousMode === Mode.TEXT ||
26104                      previousMode === Mode.X12) {
26105                      size++; // unlatch 254 to ASCII
26106                  }
26107                  break;
26108              case Mode.B256:
26109                  size++;
26110                  if (previousMode !== Mode.B256) {
26111                      size++; // byte count
26112                  }
26113                  else if (this.getB256Size() === 250) {
26114                      size++; // extra byte count
26115                  }
26116                  if (previousMode === Mode.ASCII) {
26117                      size++; // latch to B256
26118                  }
26119                  else if (previousMode === Mode.C40 ||
26120                      previousMode === Mode.TEXT ||
26121                      previousMode === Mode.X12) {
26122                      size += 2; // unlatch to ASCII, latch to B256
26123                  }
26124                  break;
26125              case Mode.C40:
26126              case Mode.TEXT:
26127              case Mode.X12:
26128                  if (mode === Mode.X12) {
26129                      size += 2;
26130                  }
26131                  else {
26132                      let charLen = [];
26133                      size +=
26134                          MinimalEncoder.getNumberOfC40Words(input, fromPosition, mode === Mode.C40, charLen) * 2;
26135                  }
26136                  if (previousMode === Mode.ASCII || previousMode === Mode.B256) {
26137                      size++; // additional byte for latch from ASCII to this mode
26138                  }
26139                  else if (previousMode !== mode &&
26140                      (previousMode === Mode.C40 ||
26141                          previousMode === Mode.TEXT ||
26142                          previousMode === Mode.X12)) {
26143                      size += 2; // unlatch 254 to ASCII followed by latch to this mode
26144                  }
26145                  break;
26146              case Mode.EDF:
26147                  size += 3;
26148                  if (previousMode === Mode.ASCII || previousMode === Mode.B256) {
26149                      size++; // additional byte for latch from ASCII to this mode
26150                  }
26151                  else if (previousMode === Mode.C40 ||
26152                      previousMode === Mode.TEXT ||
26153                      previousMode === Mode.X12) {
26154                      size += 2; // unlatch 254 to ASCII followed by latch to this mode
26155                  }
26156                  break;
26157          }
26158          this.cachedTotalSize = size;
26159      }
26160      // does not count beyond 250
26161      getB256Size() {
26162          let cnt = 0;
26163          let current = this;
26164          while (current !== null && current.mode === Mode.B256 && cnt <= 250) {
26165              cnt++;
26166              current = current.previous;
26167          }
26168          return cnt;
26169      }
26170      getPreviousStartMode() {
26171          return this.previous === null ? Mode.ASCII : this.previous.mode;
26172      }
26173      getPreviousMode() {
26174          return this.previous === null ? Mode.ASCII : this.previous.getEndMode();
26175      }
26176      /** Returns Mode.ASCII in case that:
26177       *  - Mode is EDIFACT and characterLength is less than 4 or the remaining characters can be encoded in at most 2
26178       *    ASCII bytes.
26179       *  - Mode is C40, TEXT or X12 and the remaining characters can be encoded in at most 1 ASCII byte.
26180       *  Returns mode in all other cases.
26181       * */
26182      getEndMode() {
26183          if (this.mode === Mode.EDF) {
26184              if (this.characterLength < 4) {
26185                  return Mode.ASCII;
26186              }
26187              const lastASCII = this.getLastASCII(); // see 5.2.8.2 EDIFACT encodation Rules
26188              if (lastASCII > 0 &&
26189                  this.getCodewordsRemaining(this.cachedTotalSize + lastASCII) <=
26190                      2 - lastASCII) {
26191                  return Mode.ASCII;
26192              }
26193          }
26194          if (this.mode === Mode.C40 ||
26195              this.mode === Mode.TEXT ||
26196              this.mode === Mode.X12) {
26197              // see 5.2.5.2 C40 encodation rules and 5.2.7.2 ANSI X12 encodation rules
26198              if (this.fromPosition + this.characterLength >= this.input.length() &&
26199                  this.getCodewordsRemaining(this.cachedTotalSize) === 0) {
26200                  return Mode.ASCII;
26201              }
26202              const lastASCII = this.getLastASCII();
26203              if (lastASCII === 1 &&
26204                  this.getCodewordsRemaining(this.cachedTotalSize + 1) === 0) {
26205                  return Mode.ASCII;
26206              }
26207          }
26208          return this.mode;
26209      }
26210      getMode() {
26211          return this.mode;
26212      }
26213      /** Peeks ahead and returns 1 if the postfix consists of exactly two digits, 2 if the postfix consists of exactly
26214       *  two consecutive digits and a non extended character or of 4 digits.
26215       *  Returns 0 in any other case
26216       **/
26217      getLastASCII() {
26218          const length = this.input.length();
26219          const from = this.fromPosition + this.characterLength;
26220          if (length - from > 4 || from >= length) {
26221              return 0;
26222          }
26223          if (length - from === 1) {
26224              if (MinimalEncoder.isExtendedASCII(this.input.charAt(from), this.input.getFNC1Character())) {
26225                  return 0;
26226              }
26227              return 1;
26228          }
26229          if (length - from === 2) {
26230              if (MinimalEncoder.isExtendedASCII(this.input.charAt(from), this.input.getFNC1Character()) ||
26231                  MinimalEncoder.isExtendedASCII(this.input.charAt(from + 1), this.input.getFNC1Character())) {
26232                  return 0;
26233              }
26234              if (HighLevelEncoder$1.isDigit(this.input.charAt(from)) &&
26235                  HighLevelEncoder$1.isDigit(this.input.charAt(from + 1))) {
26236                  return 1;
26237              }
26238              return 2;
26239          }
26240          if (length - from === 3) {
26241              if (HighLevelEncoder$1.isDigit(this.input.charAt(from)) &&
26242                  HighLevelEncoder$1.isDigit(this.input.charAt(from + 1)) &&
26243                  !MinimalEncoder.isExtendedASCII(this.input.charAt(from + 2), this.input.getFNC1Character())) {
26244                  return 2;
26245              }
26246              if (HighLevelEncoder$1.isDigit(this.input.charAt(from + 1)) &&
26247                  HighLevelEncoder$1.isDigit(this.input.charAt(from + 2)) &&
26248                  !MinimalEncoder.isExtendedASCII(this.input.charAt(from), this.input.getFNC1Character())) {
26249                  return 2;
26250              }
26251              return 0;
26252          }
26253          if (HighLevelEncoder$1.isDigit(this.input.charAt(from)) &&
26254              HighLevelEncoder$1.isDigit(this.input.charAt(from + 1)) &&
26255              HighLevelEncoder$1.isDigit(this.input.charAt(from + 2)) &&
26256              HighLevelEncoder$1.isDigit(this.input.charAt(from + 3))) {
26257              return 2;
26258          }
26259          return 0;
26260      }
26261      /** Returns the capacity in codewords of the smallest symbol that has enough capacity to fit the given minimal
26262       * number of codewords.
26263       **/
26264      getMinSymbolSize(minimum) {
26265          switch (this.input.getShapeHint()) {
26266              case 1 /* 
26266FORCE_SQUARE */:
26267                  for (const capacity of this.squareCodewordCapacities) {
26268                      if (capacity >= minimum) {
26269                          return capacity;
26270                      }
26271                  }
26272                  break;
26273              case 2 /* 
vendor: 27,324 bytes, lines 26273-26947
26273FORCE_RECTANGLE */:
26274                  for (const capacity of this.rectangularCodewordCapacities) {
26275                      if (capacity >= minimum) {
26276                          return capacity;
26277                      }
26278                  }
26279                  break;
26280          }
26281          for (const capacity of this.allCodewordCapacities) {
26282              if (capacity >= minimum) {
26283                  return capacity;
26284              }
26285          }
26286          return this.allCodewordCapacities[this.allCodewordCapacities.length - 1];
26287      }
26288      /** Returns the remaining capacity in codewords of the smallest symbol that has enough capacity to fit the given
26289       * minimal number of codewords.
26290       **/
26291      getCodewordsRemaining(minimum) {
26292          return this.getMinSymbolSize(minimum) - minimum;
26293      }
26294      static getBytes(c1, c2) {
26295          const result = new Uint8Array(c2 ? 2 : 1);
26296          result[0] = c1;
26297          if (c2) {
26298              result[1] = c2;
26299          }
26300          return result;
26301      }
26302      setC40Word(bytes, offset, c1, c2, c3) {
26303          const val16 = 1600 * (c1 & 0xff) + 40 * (c2 & 0xff) + (c3 & 0xff) + 1;
26304          bytes[offset] = val16 / 256;
26305          bytes[offset + 1] = val16 % 256;
26306      }
26307      getX12Value(c) {
26308          return c === 13
26309              ? 0
26310              : c === 42
26311                  ? 1
26312                  : c === 62
26313                      ? 2
26314                      : c === 32
26315                          ? 3
26316                          : c >= 48 && c <= 57
26317                              ? c - 44
26318                              : c >= 65 && c <= 90
26319                                  ? c - 51
26320                                  : c;
26321      }
26322      getX12Words() {
26323          if (!(this.characterLength % 3 === 0)) {
26324              throw new Error('X12 words must be a multiple of 3');
26325          }
26326          const result = new Uint8Array((this.characterLength / 3) * 2);
26327          for (let i = 0; i < result.length; i += 2) {
26328              this.setC40Word(result, i, this.getX12Value(this.input.charAt(this.fromPosition + (i / 2) * 3)), this.getX12Value(this.input.charAt(this.fromPosition + (i / 2) * 3 + 1)), this.getX12Value(this.input.charAt(this.fromPosition + (i / 2) * 3 + 2)));
26329          }
26330          return result;
26331      }
26332      getShiftValue(c, c40, fnc1) {
26333          return (c40 && MinimalEncoder.isInC40Shift1Set(c)) ||
26334              (!c40 && MinimalEncoder.isInTextShift1Set(c))
26335              ? 0
26336              : (c40 && MinimalEncoder.isInC40Shift2Set(c, fnc1)) ||
26337                  (!c40 && MinimalEncoder.isInTextShift2Set(c, fnc1))
26338                  ? 1
26339                  : 2;
26340      }
26341      getC40Value(c40, setIndex, c, fnc1) {
26342          if (c === fnc1) {
26343              if (!(setIndex === 2)) {
26344                  throw new Error('FNC1 cannot be used in C40 shift 2');
26345              }
26346              return 27;
26347          }
26348          if (c40) {
26349              return c <= 31
26350                  ? c
26351                  : c === 32
26352                      ? 3
26353                      : c <= 47
26354                          ? c - 33
26355                          : c <= 57
26356                              ? c - 44
26357                              : c <= 64
26358                                  ? c - 43
26359                                  : c <= 90
26360                                      ? c - 51
26361                                      : c <= 95
26362                                          ? c - 69
26363                                          : c <= 127
26364                                              ? c - 96
26365                                              : c;
26366          }
26367          else {
26368              return c === 0
26369                  ? 0
26370                  : setIndex === 0 && c <= 3
26371                      ? c - 1 // is this a bug in the spec?
26372                      : setIndex === 1 && c <= 31
26373                          ? c
26374                          : c === 32
26375                              ? 3
26376                              : c >= 33 && c <= 47
26377                                  ? c - 33
26378                                  : c >= 48 && c <= 57
26379                                      ? c - 44
26380                                      : c >= 58 && c <= 64
26381                                          ? c - 43
26382                                          : c >= 65 && c <= 90
26383                                              ? c - 64
26384                                              : c >= 91 && c <= 95
26385                                                  ? c - 69
26386                                                  : c === 96
26387                                                      ? 0
26388                                                      : c >= 97 && c <= 122
26389                                                          ? c - 83
26390                                                          : c >= 123 && c <= 127
26391                                                              ? c - 96
26392                                                              : c;
26393          }
26394      }
26395      getC40Words(c40, fnc1) {
26396          const c40Values = [];
26397          for (let i = 0; i < this.characterLength; i++) {
26398              const ci = this.input.charAt(this.fromPosition + i);
26399              if ((c40 && HighLevelEncoder$1.isNativeC40(ci)) ||
26400                  (!c40 && HighLevelEncoder$1.isNativeText(ci))) {
26401                  c40Values.push(this.getC40Value(c40, 0, ci, fnc1));
26402              }
26403              else if (!MinimalEncoder.isExtendedASCII(ci, fnc1)) {
26404                  const shiftValue = this.getShiftValue(ci, c40, fnc1);
26405                  c40Values.push(shiftValue); // Shift[123]
26406                  c40Values.push(this.getC40Value(c40, shiftValue, ci, fnc1));
26407              }
26408              else {
26409                  const asciiValue = (ci & 0xff) - 128;
26410                  if ((c40 && HighLevelEncoder$1.isNativeC40(asciiValue)) ||
26411                      (!c40 && HighLevelEncoder$1.isNativeText(asciiValue))) {
26412                      c40Values.push(1); // Shift 2
26413                      c40Values.push(30); // Upper Shift
26414                      c40Values.push(this.getC40Value(c40, 0, asciiValue, fnc1));
26415                  }
26416                  else {
26417                      c40Values.push(1); // Shift 2
26418                      c40Values.push(30); // Upper Shift
26419                      const shiftValue = this.getShiftValue(asciiValue, c40, fnc1);
26420                      c40Values.push(shiftValue); // Shift[123]
26421                      c40Values.push(this.getC40Value(c40, shiftValue, asciiValue, fnc1));
26422                  }
26423              }
26424          }
26425          if (c40Values.length % 3 !== 0) {
26426              if (!((c40Values.length - 2) % 3 === 0 &&
26427                  this.fromPosition + this.characterLength === this.input.length())) {
26428                  throw new Error('C40 words must be a multiple of 3');
26429              }
26430              c40Values.push(0); // pad with 0 (Shift 1)
26431          }
26432          const result = new Uint8Array((c40Values.length / 3) * 2);
26433          let byteIndex = 0;
26434          for (let i = 0; i < c40Values.length; i += 3) {
26435              this.setC40Word(result, byteIndex, c40Values[i] & 0xff, c40Values[i + 1] & 0xff, c40Values[i + 2] & 0xff);
26436              byteIndex += 2;
26437          }
26438          return result;
26439      }
26440      getEDFBytes() {
26441          const numberOfThirds = Math.ceil(this.characterLength / 4.0);
26442          const result = new Uint8Array(numberOfThirds * 3);
26443          let pos = this.fromPosition;
26444          const endPos = Math.min(this.fromPosition + this.characterLength - 1, this.input.length() - 1);
26445          for (let i = 0; i < numberOfThirds; i += 3) {
26446              const edfValues = [];
26447              for (let j = 0; j < 4; j++) {
26448                  if (pos <= endPos) {
26449                      edfValues[j] = this.input.charAt(pos++) & 0x3f;
26450                  }
26451                  else {
26452                      edfValues[j] = pos === endPos + 1 ? 0x1f : 0;
26453                  }
26454              }
26455              let val24 = edfValues[0] << 18;
26456              val24 |= edfValues[1] << 12;
26457              val24 |= edfValues[2] << 6;
26458              val24 |= edfValues[3];
26459              result[i] = (val24 >> 16) & 0xff;
26460              result[i + 1] = (val24 >> 8) & 0xff;
26461              result[i + 2] = val24 & 0xff;
26462          }
26463          return result;
26464      }
26465      getLatchBytes() {
26466          switch (this.getPreviousMode()) {
26467              case Mode.ASCII:
26468              case Mode.B256: // after B256 ends (via length) we are back to ASCII
26469                  switch (this.mode) {
26470                      case Mode.B256:
26471                          return Edge.getBytes(231);
26472                      case Mode.C40:
26473                          return Edge.getBytes(230);
26474                      case Mode.TEXT:
26475                          return Edge.getBytes(239);
26476                      case Mode.X12:
26477                          return Edge.getBytes(238);
26478                      case Mode.EDF:
26479                          return Edge.getBytes(240);
26480                  }
26481                  break;
26482              case Mode.C40:
26483              case Mode.TEXT:
26484              case Mode.X12:
26485                  if (this.mode !== this.getPreviousMode()) {
26486                      switch (this.mode) {
26487                          case Mode.ASCII:
26488                              return Edge.getBytes(254);
26489                          case Mode.B256:
26490                              return Edge.getBytes(254, 231);
26491                          case Mode.C40:
26492                              return Edge.getBytes(254, 230);
26493                          case Mode.TEXT:
26494                              return Edge.getBytes(254, 239);
26495                          case Mode.X12:
26496                              return Edge.getBytes(254, 238);
26497                          case Mode.EDF:
26498                              return Edge.getBytes(254, 240);
26499                      }
26500                  }
26501                  break;
26502              case Mode.EDF:
26503                  // The rightmost EDIFACT edge always contains an unlatch character
26504                  if (this.mode !== Mode.EDF) {
26505                      throw new Error('Cannot switch from EDF to ' + this.mode);
26506                  }
26507                  break;
26508          }
26509          return new Uint8Array(0);
26510      }
26511      // Important: The function does not return the length bytes (one or two) in case of B256 encoding
26512      getDataBytes() {
26513          switch (this.mode) {
26514              case Mode.ASCII:
26515                  if (this.input.isECI(this.fromPosition)) {
26516                      return Edge.getBytes(241, this.input.getECIValue(this.fromPosition) + 1);
26517                  }
26518                  else if (MinimalEncoder.isExtendedASCII(this.input.charAt(this.fromPosition), this.input.getFNC1Character())) {
26519                      return Edge.getBytes(235, this.input.charAt(this.fromPosition) - 127);
26520                  }
26521                  else if (this.characterLength === 2) {
26522                      return Edge.getBytes(this.input.charAt(this.fromPosition) * 10 +
26523                          this.input.charAt(this.fromPosition + 1) +
26524                          130);
26525                  }
26526                  else if (this.input.isFNC1(this.fromPosition)) {
26527                      return Edge.getBytes(232);
26528                  }
26529                  else {
26530                      return Edge.getBytes(this.input.charAt(this.fromPosition) + 1);
26531                  }
26532              case Mode.B256:
26533                  return Edge.getBytes(this.input.charAt(this.fromPosition));
26534              case Mode.C40:
26535                  return this.getC40Words(true, this.input.getFNC1Character());
26536              case Mode.TEXT:
26537                  return this.getC40Words(false, this.input.getFNC1Character());
26538              case Mode.X12:
26539                  return this.getX12Words();
26540              case Mode.EDF:
26541                  return this.getEDFBytes();
26542          }
26543      }
26544  }
26545  class Input extends MinimalECIInput {
26546      constructor(stringToEncode, priorityCharset, fnc1, shape, macroId) {
26547          super(stringToEncode, priorityCharset, fnc1);
26548          this.shape = shape;
26549          this.macroId = macroId;
26550      }
26551      getMacroId() {
26552          return this.macroId;
26553      }
26554      getShapeHint() {
26555          return this.shape;
26556      }
26557  }
26558
26559  class DataMatrixWriter {
26560      encode(contents, format, width, height, hints = null) {
26561          if (contents.trim() === '') {
26562              throw new Error('Found empty contents');
26563          }
26564          if (format !== BarcodeFormat$1.DATA_MATRIX) {
26565              throw new Error('Can only encode DATA_MATRIX, but got ' + format);
26566          }
26567          if (width < 0 || height < 0) {
26568              throw new Error('Requested dimensions can\'t be negative: ' + width + 'x' + height);
26569          }
26570          // Try to get force shape & min / max size
26571          let shape = 0 /* FORCE_NONE */;
26572          let minSize = null;
26573          let maxSize = null;
26574          if (hints != null) {
26575              const requestedShape = hints.get(EncodeHintType$1.DATA_MATRIX_SHAPE);
26576              if (requestedShape != null) {
26577                  shape = requestedShape;
26578              }
26579              const requestedMinSize = hints.get(EncodeHintType$1.MIN_SIZE);
26580              if (requestedMinSize != null) {
26581                  minSize = requestedMinSize;
26582              }
26583              const requestedMaxSize = hints.get(EncodeHintType$1.MAX_SIZE);
26584              if (requestedMaxSize != null) {
26585                  maxSize = requestedMaxSize;
26586              }
26587          }
26588          // 1. step: Data encodation
26589          let encoded;
26590          const hasCompactionHint = hints != null &&
26591              hints.has(EncodeHintType$1.DATA_MATRIX_COMPACT) &&
26592              Boolean(hints.get(EncodeHintType$1.DATA_MATRIX_COMPACT).toString());
26593          if (hasCompactionHint) {
26594              const hasGS1FormatHint = hints.has(EncodeHintType$1.GS1_FORMAT) &&
26595                  Boolean(hints.get(EncodeHintType$1.GS1_FORMAT).toString());
26596              let charset = null;
26597              const hasEncodingHint = hints.has(EncodeHintType$1.CHARACTER_SET);
26598              if (hasEncodingHint) {
26599                  charset = Charset.forName(hints.get(EncodeHintType$1.CHARACTER_SET).toString());
26600              }
26601              encoded = MinimalEncoder.encodeHighLevel(contents, charset, hasGS1FormatHint ? 0x1d : -1, shape);
26602          }
26603          else {
26604              const hasForceC40Hint = hints != null &&
26605                  hints.has(EncodeHintType$1.FORCE_C40) &&
26606                  Boolean(hints.get(EncodeHintType$1.FORCE_C40).toString());
26607              encoded = HighLevelEncoder$1.encodeHighLevel(contents, shape, minSize, maxSize, hasForceC40Hint);
26608          }
26609          const symbolInfo = SymbolInfo.lookup(encoded.length, shape, minSize, maxSize, true);
26610          // 2. step: ECC generation
26611          const codewords = ErrorCorrection.encodeECC200(encoded, symbolInfo);
26612          // 3. step: Module placement in Matrix
26613          const placement = new DefaultPlacement(codewords, symbolInfo.getSymbolDataWidth(), symbolInfo.getSymbolDataHeight());
26614          placement.place();
26615          // 4. step: low-level encoding
26616          return this.encodeLowLevel(placement, symbolInfo, width, height);
26617      }
26618      /**
26619       * Encode the given symbol info to a bit matrix.
26620       *
26621       * @param placement  The DataMatrix placement.
26622       * @param symbolInfo The symbol info to encode.
26623       * @return The bit matrix generated.
26624       */
26625      encodeLowLevel(placement, symbolInfo, width, height) {
26626          const symbolWidth = symbolInfo.getSymbolDataWidth();
26627          const symbolHeight = symbolInfo.getSymbolDataHeight();
26628          const matrix = new ByteMatrix(symbolInfo.getSymbolWidth(), symbolInfo.getSymbolHeight());
26629          let matrixY = 0;
26630          for (let y = 0; y < symbolHeight; y++) {
26631              // Fill the top edge with alternate 0 / 1
26632              let matrixX;
26633              if (y % symbolInfo.matrixHeight === 0) {
26634                  matrixX = 0;
26635                  for (let x = 0; x < symbolInfo.getSymbolWidth(); x++) {
26636                      matrix.setBoolean(matrixX, matrixY, x % 2 === 0);
26637                      matrixX++;
26638                  }
26639                  matrixY++;
26640              }
26641              matrixX = 0;
26642              for (let x = 0; x < symbolWidth; x++) {
26643                  // Fill the right edge with full 1
26644                  if (x % symbolInfo.matrixWidth === 0) {
26645                      matrix.setBoolean(matrixX, matrixY, true);
26646                      matrixX++;
26647                  }
26648                  matrix.setBoolean(matrixX, matrixY, placement.getBit(x, y));
26649                  matrixX++;
26650                  // Fill the right edge with alternate 0 / 1
26651                  if (x % symbolInfo.matrixWidth === symbolInfo.matrixWidth - 1) {
26652                      matrix.setBoolean(matrixX, matrixY, y % 2 === 0);
26653                      matrixX++;
26654                  }
26655              }
26656              matrixY++;
26657              // Fill the bottom edge with full 1
26658              if (y % symbolInfo.matrixHeight === symbolInfo.matrixHeight - 1) {
26659                  matrixX = 0;
26660                  for (let x = 0; x < symbolInfo.getSymbolWidth(); x++) {
26661                      matrix.setBoolean(matrixX, matrixY, true);
26662                      matrixX++;
26663                  }
26664                  matrixY++;
26665              }
26666          }
26667          return this.convertByteMatrixToBitMatrix(matrix, width, height);
26668      }
26669      /**
26670       * Convert the ByteMatrix to BitMatrix.
26671       *
26672       * @param reqHeight The requested height of the image (in pixels) with the Datamatrix code
26673       * @param reqWidth The requested width of the image (in pixels) with the Datamatrix code
26674       * @param matrix The input matrix.
26675       * @return The output matrix.
26676       */
26677      convertByteMatrixToBitMatrix(matrix, reqWidth, reqHeight) {
26678          const matrixWidth = matrix.getWidth();
26679          const matrixHeight = matrix.getHeight();
26680          const outputWidth = Math.max(reqWidth, matrixWidth);
26681          const outputHeight = Math.max(reqHeight, matrixHeight);
26682          const multiple = Math.min(outputWidth / matrixWidth, outputHeight / matrixHeight);
26683          let leftPadding = (outputWidth - matrixWidth * multiple) / 2;
26684          let topPadding = (outputHeight - matrixHeight * multiple) / 2;
26685          let output;
26686          // remove padding if requested width and height are too small
26687          if (reqHeight < matrixHeight || reqWidth < matrixWidth) {
26688              leftPadding = 0;
26689              topPadding = 0;
26690              output = new BitMatrix(matrixWidth, matrixHeight);
26691          }
26692          else {
26693              output = new BitMatrix(reqWidth, reqHeight);
26694          }
26695          output.clear();
26696          for (let inputY = 0, outputY = topPadding; inputY < matrixHeight; inputY++, outputY += multiple) {
26697              // Write the contents of this row of the bytematrix
26698              for (let inputX = 0, outputX = leftPadding; inputX < matrixWidth; inputX++, outputX += multiple) {
26699                  if (matrix.get(inputX, inputY) === 1) {
26700                      output.setRegion(outputX, outputY, multiple, multiple);
26701                  }
26702              }
26703          }
26704          return output;
26705      }
26706  }
26707
26708  /*
26709  * Copyright 2013 ZXing authors
26710  *
26711  * Licensed under the Apache License, Version 2.0 (the "License");
26712  * you may not use this file except in compliance with the License.
26713  * You may obtain a copy of the License at
26714  *
26715  *      http://www.apache.org/licenses/LICENSE-2.0
26716  *
26717  * Unless required by applicable law or agreed to in writing, software
26718  * distributed under the License is distributed on an "AS IS" BASIS,
26719  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26720  * See the License for the specific language governing permissions and
26721  * limitations under the License.
26722  */
26723  /**
26724   * Aztec 2D code representation
26725   *
26726   * @author Rustam Abdullaev
26727   */
26728  /*public final*/ class AztecCode {
26729      /**
26730       * @return {@code true} if compact instead of full mode
26731       */
26732      isCompact() {
26733          return this.compact;
26734      }
26735      setCompact(compact) {
26736          this.compact = compact;
26737      }
26738      /**
26739       * @return size in pixels (width and height)
26740       */
26741      getSize() {
26742          return this.size;
26743      }
26744      setSize(size) {
26745          this.size = size;
26746      }
26747      /**
26748       * @return number of levels
26749       */
26750      getLayers() {
26751          return this.layers;
26752      }
26753      setLayers(layers) {
26754          this.layers = layers;
26755      }
26756      /**
26757       * @return number of data codewords
26758       */
26759      getCodeWords() {
26760          return this.codeWords;
26761      }
26762      setCodeWords(codeWords) {
26763          this.codeWords = codeWords;
26764      }
26765      /**
26766       * @return the symbol image
26767       */
26768      getMatrix() {
26769          return this.matrix;
26770      }
26771      setMatrix(matrix) {
26772          this.matrix = matrix;
26773      }
26774  }
26775
26776  class Collections {
26777      /**
26778       * The singletonList(T) method is used to return an immutable list containing only the specified object.
26779       */
26780      static singletonList(item) {
26781          return [item];
26782      }
26783      /**
26784       * The min(Collection<? extends T>, Comparator<? super T>) method is used to return the minimum element of the given collection, according to the order induced by the specified comparator.
26785       */
26786      static min(collection, comparator) {
26787          return collection.sort(comparator)[0];
26788      }
26789  }
26790
26791  /*
26792  * Copyright 2013 ZXing authors
26793  *
26794  * Licensed under the Apache License, Version 2.0 (the "License");
26795  * you may not use this file except in compliance with the License.
26796  * You may obtain a copy of the License at
26797  *
26798  *      http://www.apache.org/licenses/LICENSE-2.0
26799  *
26800  * Unless required by applicable law or agreed to in writing, software
26801  * distributed under the License is distributed on an "AS IS" BASIS,
26802  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26803  * See the License for the specific language governing permissions and
26804  * limitations under the License.
26805  */
26806  class Token {
26807      constructor(previous) {
26808          this.previous = previous;
26809      }
26810      getPrevious() {
26811          return this.previous;
26812      }
26813  }
26814
26815  /*
26816  * Copyright 2013 ZXing authors
26817  *
26818  * Licensed under the Apache License, Version 2.0 (the "License");
26819  * you may not use this file except in compliance with the License.
26820  * You may obtain a copy of the License at
26821  *
26822  *      http://www.apache.org/licenses/LICENSE-2.0
26823  *
26824  * Unless required by applicable law or agreed to in writing, software
26825  * distributed under the License is distributed on an "AS IS" BASIS,
26826  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26827  * See the License for the specific language governing permissions and
26828  * limitations under the License.
26829  */
26830  /*final*/ class SimpleToken extends Token {
26831      constructor(previous, value, bitCount) {
26832          super(previous);
26833          this.value = value;
26834          this.bitCount = bitCount;
26835      }
26836      /**
26837       * @Override
26838       */
26839      appendTo(bitArray, text) {
26840          bitArray.appendBits(this.value, this.bitCount);
26841      }
26842      add(value, bitCount) {
26843          return new SimpleToken(this, value, bitCount);
26844      }
26845      addBinaryShift(start, byteCount) {
26846          // no-op can't binary shift a simple token
26847          console.warn('addBinaryShift on SimpleToken, this simply returns a copy of this token');
26848          return new SimpleToken(this, start, byteCount);
26849      }
26850      /**
26851       * @Override
26852       */
26853      toString() {
26854          let value = this.value & ((1 << this.bitCount) - 1);
26855          value |= 1 << this.bitCount;
26856          return '<' + Integer.toBinaryString(value | (1 << this.bitCount)).substring(1) + '>';
26857      }
26858  }
26859
26860  /*
26861  * Copyright 2013 ZXing authors
26862  *
26863  * Licensed under the Apache License, Version 2.0 (the "License");
26864  * you may not use this file except in compliance with the License.
26865  * You may obtain a copy of the License at
26866  *
26867  *      http://www.apache.org/licenses/LICENSE-2.0
26868  *
26869  * Unless required by applicable law or agreed to in writing, software
26870  * distributed under the License is distributed on an "AS IS" BASIS,
26871  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26872  * See the License for the specific language governing permissions and
26873  * limitations under the License.
26874  */
26875  /*final*/ class BinaryShiftToken extends SimpleToken {
26876      constructor(previous, binaryShiftStart, binaryShiftByteCount) {
26877          super(previous, 0, 0);
26878          this.binaryShiftStart = binaryShiftStart;
26879          this.binaryShiftByteCount = binaryShiftByteCount;
26880      }
26881      /**
26882       * @Override
26883       */
26884      appendTo(bitArray, text) {
26885          for (let i = 0; i < this.binaryShiftByteCount; i++) {
26886              if (i === 0 || (i === 31 && this.binaryShiftByteCount <= 62)) {
26887                  // We need a header before the first character, and before
26888                  // character 31 when the total byte code is <= 62
26889                  bitArray.appendBits(31, 5); // BINARY_SHIFT
26890                  if (this.binaryShiftByteCount > 62) {
26891                      bitArray.appendBits(this.binaryShiftByteCount - 31, 16);
26892                  }
26893                  else if (i === 0) {
26894                      // 1 <= binaryShiftByteCode <= 62
26895                      bitArray.appendBits(Math.min(this.binaryShiftByteCount, 31), 5);
26896                  }
26897                  else {
26898                      // 32 <= binaryShiftCount <= 62 and i == 31
26899                      bitArray.appendBits(this.binaryShiftByteCount - 31, 5);
26900                  }
26901              }
26902              bitArray.appendBits(text[this.binaryShiftStart + i], 8);
26903          }
26904      }
26905      addBinaryShift(start, byteCount) {
26906          // int bitCount = (byteCount * 8) + (byteCount <= 31 ? 10 : byteCount <= 62 ? 20 : 21);
26907          return new BinaryShiftToken(this, start, byteCount);
26908      }
26909      /**
26910       * @Override
26911       */
26912      toString() {
26913          return '<' + this.binaryShiftStart + '::' + (this.binaryShiftStart + this.binaryShiftByteCount - 1) + '>';
26914      }
26915  }
26916
26917  function addBinaryShift(token, start, byteCount) {
26918      // int bitCount = (byteCount * 8) + (byteCount <= 31 ? 10 : byteCount <= 62 ? 20 : 21);
26919      return new BinaryShiftToken(token, start, byteCount);
26920  }
26921  function add(token, value, bitCount) {
26922      return new SimpleToken(token, value, bitCount);
26923  }
26924
26925  const /*final*/ MODE_NAMES = [
26926      'UPPER',
26927      'LOWER',
26928      'DIGIT',
26929      'MIXED',
26930      'PUNCT'
26931  ];
26932  const /*final*/ MODE_UPPER = 0; // 5 bits
26933  const /*final*/ MODE_LOWER = 1; // 5 bits
26934  const /*final*/ MODE_DIGIT = 2; // 4 bits
26935  const /*final*/ MODE_MIXED = 3; // 5 bits
26936  const /*final*/ MODE_PUNCT = 4; // 5 bits
26937  const EMPTY_TOKEN = new SimpleToken(null, 0, 0);
26938
26939  // The Latch Table shows, for each pair of Modes, the optimal method for
26940  // getting from one mode to another.  In the worst possible case, this can
26941  // be up to 14 bits.  In the best possible case, we are already there!
26942  // The high half-word of each entry gives the number of bits.
26943  // The low half-word of each entry are the actual bits necessary to change
26944  const LATCH_TABLE = [
26945      Int32Array.from([
26946          0,
26947          (5 << 16) + 28,
vendor: 18,945 bytes, lines 26947-27422
26947
26948          (5 << 16) + 30,
26949          (5 << 16) + 29,
26950          (10 << 16) + (29 << 5) + 30 // UPPER -> MIXED -> PUNCT
26951      ]),
26952      Int32Array.from([
26953          (9 << 16) + (30 << 4) + 14,
26954          0,
26955          (5 << 16) + 30,
26956          (5 << 16) + 29,
26957          (10 << 16) + (29 << 5) + 30 // LOWER -> MIXED -> PUNCT
26958      ]),
26959      Int32Array.from([
26960          (4 << 16) + 14,
26961          (9 << 16) + (14 << 5) + 28,
26962          0,
26963          (9 << 16) + (14 << 5) + 29,
26964          (14 << 16) + (14 << 10) + (29 << 5) + 30
26965          // DIGIT -> UPPER -> MIXED -> PUNCT
26966      ]),
26967      Int32Array.from([
26968          (5 << 16) + 29,
26969          (5 << 16) + 28,
26970          (10 << 16) + (29 << 5) + 30,
26971          0,
26972          (5 << 16) + 30 // MIXED -> PUNCT
26973      ]),
26974      Int32Array.from([
26975          (5 << 16) + 31,
26976          (10 << 16) + (31 << 5) + 28,
26977          (10 << 16) + (31 << 5) + 30,
26978          (10 << 16) + (31 << 5) + 29,
26979          0
26980      ])
26981  ];
26982
26983  function static_SHIFT_TABLE(SHIFT_TABLE) {
26984      for (let table /*Int32Array*/ of SHIFT_TABLE) {
26985          Arrays.fill(table, -1);
26986      }
26987      SHIFT_TABLE[MODE_UPPER][MODE_PUNCT] = 0;
26988      SHIFT_TABLE[MODE_LOWER][MODE_PUNCT] = 0;
26989      SHIFT_TABLE[MODE_LOWER][MODE_UPPER] = 28;
26990      SHIFT_TABLE[MODE_MIXED][MODE_PUNCT] = 0;
26991      SHIFT_TABLE[MODE_DIGIT][MODE_PUNCT] = 0;
26992      SHIFT_TABLE[MODE_DIGIT][MODE_UPPER] = 15;
26993      return SHIFT_TABLE;
26994  }
26995  const /*final*/ SHIFT_TABLE = static_SHIFT_TABLE(Arrays.createInt32Array(6, 6)); // mode shift codes, per table
26996
26997  /*
26998   * Copyright 2013 ZXing authors
26999   *
27000   * Licensed under the Apache License, Version 2.0 (the "License");
27001   * you may not use this file except in compliance with the License.
27002   * You may obtain a copy of the License at
27003   *
27004   *      http://www.apache.org/licenses/LICENSE-2.0
27005   *
27006   * Unless required by applicable law or agreed to in writing, software
27007   * distributed under the License is distributed on an "AS IS" BASIS,
27008   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27009   * See the License for the specific language governing permissions and
27010   * limitations under the License.
27011   */
27012  /**
27013   * State represents all information about a sequence necessary to generate the current output.
27014   * Note that a state is immutable.
27015   */
27016  /*final*/ class State {
27017      constructor(token, mode, binaryBytes, bitCount) {
27018          this.token = token;
27019          this.mode = mode;
27020          this.binaryShiftByteCount = binaryBytes;
27021          this.bitCount = bitCount;
27022          // Make sure we match the token
27023          // int binaryShiftBitCount = (binaryShiftByteCount * 8) +
27024          //    (binaryShiftByteCount === 0 ? 0 :
27025          //     binaryShiftByteCount <= 31 ? 10 :
27026          //     binaryShiftByteCount <= 62 ? 20 : 21);
27027          // assert this.bitCount === token.getTotalBitCount() + binaryShiftBitCount;
27028      }
27029      getMode() {
27030          return this.mode;
27031      }
27032      getToken() {
27033          return this.token;
27034      }
27035      getBinaryShiftByteCount() {
27036          return this.binaryShiftByteCount;
27037      }
27038      getBitCount() {
27039          return this.bitCount;
27040      }
27041      // Create a new state representing this state with a latch to a (not
27042      // necessary different) mode, and then a code.
27043      latchAndAppend(mode, value) {
27044          // assert binaryShiftByteCount === 0;
27045          let bitCount = this.bitCount;
27046          let token = this.token;
27047          if (mode !== this.mode) {
27048              let latch = LATCH_TABLE[this.mode][mode];
27049              token = add(token, latch & 0xffff, latch >> 16);
27050              bitCount += latch >> 16;
27051          }
27052          let latchModeBitCount = mode === MODE_DIGIT ? 4 : 5;
27053          token = add(token, value, latchModeBitCount);
27054          return new State(token, mode, 0, bitCount + latchModeBitCount);
27055      }
27056      // Create a new state representing this state, with a temporary shift
27057      // to a different mode to output a single value.
27058      shiftAndAppend(mode, value) {
27059          // assert binaryShiftByteCount === 0 && this.mode !== mode;
27060          let token = this.token;
27061          let thisModeBitCount = this.mode === MODE_DIGIT ? 4 : 5;
27062          // Shifts exist only to UPPER and PUNCT, both with tokens size 5.
27063          token = add(token, SHIFT_TABLE[this.mode][mode], thisModeBitCount);
27064          token = add(token, value, 5);
27065          return new State(token, this.mode, 0, this.bitCount + thisModeBitCount + 5);
27066      }
27067      // Create a new state representing this state, but an additional character
27068      // output in Binary Shift mode.
27069      addBinaryShiftChar(index) {
27070          let token = this.token;
27071          let mode = this.mode;
27072          let bitCount = this.bitCount;
27073          if (this.mode === MODE_PUNCT || this.mode === MODE_DIGIT) {
27074              // assert binaryShiftByteCount === 0;
27075              let latch = LATCH_TABLE[mode][MODE_UPPER];
27076              token = add(token, latch & 0xffff, latch >> 16);
27077              bitCount += latch >> 16;
27078              mode = MODE_UPPER;
27079          }
27080          let deltaBitCount = this.binaryShiftByteCount === 0 || this.binaryShiftByteCount === 31
27081              ? 18
27082              : this.binaryShiftByteCount === 62
27083                  ? 9
27084                  : 8;
27085          let result = new State(token, mode, this.binaryShiftByteCount + 1, bitCount + deltaBitCount);
27086          if (result.binaryShiftByteCount === 2047 + 31) {
27087              // The string is as long as it's allowed to be.  We should end it.
27088              result = result.endBinaryShift(index + 1);
27089          }
27090          return result;
27091      }
27092      // Create the state identical to this one, but we are no longer in
27093      // Binary Shift mode.
27094      endBinaryShift(index) {
27095          if (this.binaryShiftByteCount === 0) {
27096              return this;
27097          }
27098          let token = this.token;
27099          token = addBinaryShift(token, index - this.binaryShiftByteCount, this.binaryShiftByteCount);
27100          // assert token.getTotalBitCount() === this.bitCount;
27101          return new State(token, this.mode, 0, this.bitCount);
27102      }
27103      // Returns true if "this" state is better (equal: or) to be in than "that"
27104      // state under all possible circumstances.
27105      isBetterThanOrEqualTo(other) {
27106          let newModeBitCount = this.bitCount + (LATCH_TABLE[this.mode][other.mode] >> 16);
27107          if (this.binaryShiftByteCount < other.binaryShiftByteCount) {
27108              // add additional B/S encoding cost of other, if any
27109              newModeBitCount +=
27110                  State.calculateBinaryShiftCost(other) -
27111                      State.calculateBinaryShiftCost(this);
27112          }
27113          else if (this.binaryShiftByteCount > other.binaryShiftByteCount &&
27114              other.binaryShiftByteCount > 0) {
27115              // maximum possible additional cost (it: h)
27116              newModeBitCount += 10;
27117          }
27118          return newModeBitCount <= other.bitCount;
27119      }
27120      toBitArray(text) {
27121          // Reverse the tokens, so that they are in the order that they should
27122          // be output
27123          let symbols = [];
27124          for (let token = this.endBinaryShift(text.length).token; token !== null; token = token.getPrevious()) {
27125              symbols.unshift(token);
27126          }
27127          let bitArray = new BitArray();
27128          // Add each token to the result.
27129          for (const symbol of symbols) {
27130              symbol.appendTo(bitArray, text);
27131          }
27132          // assert bitArray.getSize() === this.bitCount;
27133          return bitArray;
27134      }
27135      /**
27136       * @Override
27137       */
27138      toString() {
27139          return StringUtils.format('%s bits=%d bytes=%d', MODE_NAMES[this.mode], this.bitCount, this.binaryShiftByteCount);
27140      }
27141      static calculateBinaryShiftCost(state) {
27142          if (state.binaryShiftByteCount > 62) {
27143              return 21; // B/S with extended length
27144          }
27145          if (state.binaryShiftByteCount > 31) {
27146              return 20; // two B/S
27147          }
27148          if (state.binaryShiftByteCount > 0) {
27149              return 10; // one B/S
27150          }
27151          return 0;
27152      }
27153  }
27154  State.INITIAL_STATE = new State(EMPTY_TOKEN, MODE_UPPER, 0, 0);
27155
27156  function static_CHAR_MAP(CHAR_MAP) {
27157      const spaceCharCode = StringUtils.getCharCode(' ');
27158      const pointCharCode = StringUtils.getCharCode('.');
27159      const commaCharCode = StringUtils.getCharCode(',');
27160      CHAR_MAP[MODE_UPPER][spaceCharCode] = 1;
27161      const zUpperCharCode = StringUtils.getCharCode('Z');
27162      const aUpperCharCode = StringUtils.getCharCode('A');
27163      for (let c = aUpperCharCode; c <= zUpperCharCode; c++) {
27164          CHAR_MAP[MODE_UPPER][c] = c - aUpperCharCode + 2;
27165      }
27166      CHAR_MAP[MODE_LOWER][spaceCharCode] = 1;
27167      const zLowerCharCode = StringUtils.getCharCode('z');
27168      const aLowerCharCode = StringUtils.getCharCode('a');
27169      for (let c = aLowerCharCode; c <= zLowerCharCode; c++) {
27170          CHAR_MAP[MODE_LOWER][c] = c - aLowerCharCode + 2;
27171      }
27172      CHAR_MAP[MODE_DIGIT][spaceCharCode] = 1;
27173      const nineCharCode = StringUtils.getCharCode('9');
27174      const zeroCharCode = StringUtils.getCharCode('0');
27175      for (let c = zeroCharCode; c <= nineCharCode; c++) {
27176          CHAR_MAP[MODE_DIGIT][c] = c - zeroCharCode + 2;
27177      }
27178      CHAR_MAP[MODE_DIGIT][commaCharCode] = 12;
27179      CHAR_MAP[MODE_DIGIT][pointCharCode] = 13;
27180      const mixedTable = [
27181          '\x00',
27182          ' ',
27183          '\x01',
27184          '\x02',
27185          '\x03',
27186          '\x04',
27187          '\x05',
27188          '\x06',
27189          '\x07',
27190          '\b',
27191          '\t',
27192          '\n',
27193          '\x0b',
27194          '\f',
27195          '\r',
27196          '\x1b',
27197          '\x1c',
27198          '\x1d',
27199          '\x1e',
27200          '\x1f',
27201          '@',
27202          '\\',
27203          '^',
27204          '_',
27205          '`',
27206          '|',
27207          '~',
27208          '\x7f'
27209      ];
27210      for (let i = 0; i < mixedTable.length; i++) {
27211          CHAR_MAP[MODE_MIXED][StringUtils.getCharCode(mixedTable[i])] = i;
27212      }
27213      const punctTable = [
27214          '\x00',
27215          '\r',
27216          '\x00',
27217          '\x00',
27218          '\x00',
27219          '\x00',
27220          '!',
27221          '\'',
27222          '#',
27223          '$',
27224          '%',
27225          '&',
27226          '\'',
27227          '(',
27228          ')',
27229          '*',
27230          '+',
27231          ',',
27232          '-',
27233          '.',
27234          '/',
27235          ':',
27236          ';',
27237          '<',
27238          '=',
27239          '>',
27240          '?',
27241          '[',
27242          ']',
27243          '{',
27244          '}'
27245      ];
27246      for (let i = 0; i < punctTable.length; i++) {
27247          if (StringUtils.getCharCode(punctTable[i]) > 0) {
27248              CHAR_MAP[MODE_PUNCT][StringUtils.getCharCode(punctTable[i])] = i;
27249          }
27250      }
27251      return CHAR_MAP;
27252  }
27253  const CHAR_MAP = static_CHAR_MAP(Arrays.createInt32Array(5, 256));
27254
27255  /*
27256   * Copyright 2013 ZXing authors
27257   *
27258   * Licensed under the Apache License, Version 2.0 (the "License");
27259   * you may not use this file except in compliance with the License.
27260   * You may obtain a copy of the License at
27261   *
27262   *      http://www.apache.org/licenses/LICENSE-2.0
27263   *
27264   * Unless required by applicable law or agreed to in writing, software
27265   * distributed under the License is distributed on an "AS IS" BASIS,
27266   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27267   * See the License for the specific language governing permissions and
27268   * limitations under the License.
27269   */
27270  /**
27271   * This produces nearly optimal encodings of text into the first-level of
27272   * encoding used by Aztec code.
27273   *
27274   * It uses a dynamic algorithm.  For each prefix of the string, it determines
27275   * a set of encodings that could lead to this prefix.  We repeatedly add a
27276   * character and generate a new set of optimal encodings until we have read
27277   * through the entire input.
27278   *
27279   * @author Frank Yellin
27280   * @author Rustam Abdullaev
27281   */
27282  /*public final*/ class HighLevelEncoder {
27283      constructor(text) {
27284          this.text = text;
27285      }
27286      /**
27287       * @return text represented by this encoder encoded as a {@link BitArray}
27288       */
27289      encode() {
27290          const spaceCharCode = StringUtils.getCharCode(' ');
27291          const lineBreakCharCode = StringUtils.getCharCode('\n');
27292          let states = Collections.singletonList(State.INITIAL_STATE);
27293          for (let index = 0; index < this.text.length; index++) {
27294              let pairCode;
27295              let nextChar = index + 1 < this.text.length ? this.text[index + 1] : 0;
27296              switch (this.text[index]) {
27297                  case StringUtils.getCharCode('\r'):
27298                      pairCode = nextChar === lineBreakCharCode ? 2 : 0;
27299                      break;
27300                  case StringUtils.getCharCode('.'):
27301                      pairCode = nextChar === spaceCharCode ? 3 : 0;
27302                      break;
27303                  case StringUtils.getCharCode(','):
27304                      pairCode = nextChar === spaceCharCode ? 4 : 0;
27305                      break;
27306                  case StringUtils.getCharCode(':'):
27307                      pairCode = nextChar === spaceCharCode ? 5 : 0;
27308                      break;
27309                  default:
27310                      pairCode = 0;
27311              }
27312              if (pairCode > 0) {
27313                  // We have one of the four special PUNCT pairs.  Treat them specially.
27314                  // Get a new set of states for the two new characters.
27315                  states = HighLevelEncoder.updateStateListForPair(states, index, pairCode);
27316                  index++;
27317              }
27318              else {
27319                  // Get a new set of states for the new character.
27320                  states = this.updateStateListForChar(states, index);
27321              }
27322          }
27323          // We are left with a set of states.  Find the shortest one.
27324          const minState = Collections.min(states, (a, b) => {
27325              return a.getBitCount() - b.getBitCount();
27326          });
27327          // Convert it to a bit array, and return.
27328          return minState.toBitArray(this.text);
27329      }
27330      // We update a set of states for a new character by updating each state
27331      // for the new character, merging the results, and then removing the
27332      // non-optimal states.
27333      updateStateListForChar(states, index) {
27334          const result = [];
27335          for (let state /*State*/ of states) {
27336              this.updateStateForChar(state, index, result);
27337          }
27338          return HighLevelEncoder.simplifyStates(result);
27339      }
27340      // Return a set of states that represent the possible ways of updating this
27341      // state for the next character.  The resulting set of states are added to
27342      // the "result" list.
27343      updateStateForChar(state, index, result) {
27344          let ch = (this.text[index] & 0xff);
27345          let charInCurrentTable = CHAR_MAP[state.getMode()][ch] > 0;
27346          let stateNoBinary = null;
27347          for (let mode /*int*/ = 0; mode <= MODE_PUNCT; mode++) {
27348              let charInMode = CHAR_MAP[mode][ch];
27349              if (charInMode > 0) {
27350                  if (stateNoBinary == null) {
27351                      // Only create stateNoBinary the first time it's required.
27352                      stateNoBinary = state.endBinaryShift(index);
27353                  }
27354                  // Try generating the character by latching to its mode
27355                  if (!charInCurrentTable ||
27356                      mode === state.getMode() ||
27357                      mode === MODE_DIGIT) {
27358                      // If the character is in the current table, we don't want to latch to
27359                      // any other mode except possibly digit (which uses only 4 bits).  Any
27360                      // other latch would be equally successful *after* this character, and
27361                      // so wouldn't save any bits.
27362                      const latchState = stateNoBinary.latchAndAppend(mode, charInMode);
27363                      result.push(latchState);
27364                  }
27365                  // Try generating the character by switching to its mode.
27366                  if (!charInCurrentTable &&
27367                      SHIFT_TABLE[state.getMode()][mode] >= 0) {
27368                      // It never makes sense to temporarily shift to another mode if the
27369                      // character exists in the current mode.  That can never save bits.
27370                      const shiftState = stateNoBinary.shiftAndAppend(mode, charInMode);
27371                      result.push(shiftState);
27372                  }
27373              }
27374          }
27375          if (state.getBinaryShiftByteCount() > 0 ||
27376              CHAR_MAP[state.getMode()][ch] === 0) {
27377              // It's never worthwhile to go into binary shift mode if you're not already
27378              // in binary shift mode, and the character exists in your current mode.
27379              // That can never save bits over just outputting the char in the current mode.
27380              let binaryState = state.addBinaryShiftChar(index);
27381              result.push(binaryState);
27382          }
27383      }
27384      static updateStateListForPair(states, index, pairCode) {
27385          const result = [];
27386          for (let state /*State*/ of states) {
27387              this.updateStateForPair(state, index, pairCode, result);
27388          }
27389          return this.simplifyStates(result);
27390      }
27391      static updateStateForPair(state, index, pairCode, result) {
27392          let stateNoBinary = state.endBinaryShift(index);
27393          // Possibility 1.  Latch to C.MODE_PUNCT, and then append this code
27394          result.push(stateNoBinary.latchAndAppend(MODE_PUNCT, pairCode));
27395          if (state.getMode() !== MODE_PUNCT) {
27396              // Possibility 2.  Shift to C.MODE_PUNCT, and then append this code.
27397              // Every state except C.MODE_PUNCT (handled above) can shift
27398              result.push(stateNoBinary.shiftAndAppend(MODE_PUNCT, pairCode));
27399          }
27400          if (pairCode === 3 || pairCode === 4) {
27401              // both characters are in DIGITS.  Sometimes better to just add two digits
27402              let digitState = stateNoBinary
27403                  .latchAndAppend(MODE_DIGIT, 16 - pairCode) // period or comma in DIGIT
27404                  .latchAndAppend(MODE_DIGIT, 1); // space in DIGIT
27405              result.push(digitState);
27406          }
27407          if (state.getBinaryShiftByteCount() > 0) {
27408              // It only makes sense to do the characters as binary if we're already
27409              // in binary mode.
27410              let binaryState = state
27411                  .addBinaryShiftChar(index)
27412                  .addBinaryShiftChar(index + 1);
27413              result.push(binaryState);
27414          }
27415      }
27416      static simplifyStates(states) {
27417          let result = [];
27418          for (const newState of states) {
27419              let add = true;
27420              for (const oldState of result) {
27421                  if (oldState.isBetterThanOrEqualTo(newState)) {
27422                      add = false;
27423                      break;
27424                  }
27425                  if (newState.isBetterThanOrEqualTo(oldState)) {
27426                      // iterator.remove();
27427                      result = result.filter(x => x !== oldState); // remove old state
27428                  }
27429              }
27430              if (add) {
27431                  result.push(newState);
27432              }
27433          }
27434          return result;
27435      }
27436  }
27437
27438  /*
27439   * Copyright 2013 ZXing authors
27440   *
27441   * Licensed under the Apache License, Version 2.0 (the "License");
27442   * you may not use this file except in compliance with the License.
27443   * You may obtain a copy of the License at
27444   *
27445   *      http://www.apache.org/licenses/LICENSE-2.0
27446   *
27447   * Unless required by applicable law or agreed to in writing, software
27448   * distributed under the License is distributed on an "AS IS" BASIS,
27449   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27450   * See the License for the specific language governing permissions and
27451   * limitations under the License.
27452   */
27453  // package com.google.zxing.aztec.encoder;
27454  // import com.google.zxing.common.BitArray;
27455  // import com.google.zxing.common.BitMatrix;
27456  // import com.google.zxing.common.reedsolomon.GenericGF;
27457  // import com.google.zxing.common.reedsolomon.ReedSolomonEncoder;
27458  /**
27459   * Generates Aztec 2D barcodes.
27460   *
27461   * @author Rustam Abdullaev
27462   */
27463  /*public final*/
vendor: 14,667 bytes, lines 27463-27782
27463 class Encoder {
27464      constructor() {
27465      }
27466      /**
27467       * Encodes the given binary content as an Aztec symbol
27468       *
27469       * @param data input data string
27470       * @return Aztec symbol matrix with metadata
27471       */
27472      static encodeBytes(data) {
27473          return Encoder.encode(data, Encoder.DEFAULT_EC_PERCENT, Encoder.DEFAULT_AZTEC_LAYERS);
27474      }
27475      /**
27476       * Encodes the given binary content as an Aztec symbol
27477       *
27478       * @param data input data string
27479       * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008,
27480       *                      a minimum of 23% + 3 words is recommended)
27481       * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers
27482       * @return Aztec symbol matrix with metadata
27483       */
27484      static encode(data, minECCPercent, userSpecifiedLayers) {
27485          // High-level encode
27486          let bits = new HighLevelEncoder(data).encode();
27487          // stuff bits and choose symbol size
27488          let eccBits = Integer.truncDivision((bits.getSize() * minECCPercent), 100) + 11;
27489          let totalSizeBits = bits.getSize() + eccBits;
27490          let compact;
27491          let layers;
27492          let totalBitsInLayer;
27493          let wordSize;
27494          let stuffedBits;
27495          if (userSpecifiedLayers !== Encoder.DEFAULT_AZTEC_LAYERS) {
27496              compact = userSpecifiedLayers < 0;
27497              layers = Math.abs(userSpecifiedLayers);
27498              if (layers > (compact ? Encoder.MAX_NB_BITS_COMPACT : Encoder.MAX_NB_BITS)) {
27499                  throw new IllegalArgumentException(StringUtils.format('Illegal value %s for layers', userSpecifiedLayers));
27500              }
27501              totalBitsInLayer = Encoder.totalBitsInLayer(layers, compact);
27502              wordSize = Encoder.WORD_SIZE[layers];
27503              let usableBitsInLayers = totalBitsInLayer - (totalBitsInLayer % wordSize);
27504              stuffedBits = Encoder.stuffBits(bits, wordSize);
27505              if (stuffedBits.getSize() + eccBits > usableBitsInLayers) {
27506                  throw new IllegalArgumentException('Data to large for user specified layer');
27507              }
27508              if (compact && stuffedBits.getSize() > wordSize * 64) {
27509                  // Compact format only allows 64 data words, though C4 can hold more words than that
27510                  throw new IllegalArgumentException('Data to large for user specified layer');
27511              }
27512          }
27513          else {
27514              wordSize = 0;
27515              stuffedBits = null;
27516              // We look at the possible table sizes in the order Compact1, Compact2, Compact3,
27517              // Compact4, Normal4,...  Normal(i) for i < 4 isn't typically used since Compact(i+1)
27518              // is the same size, but has more data.
27519              for (let i /*int*/ = 0;; i++) {
27520                  if (i > Encoder.MAX_NB_BITS) {
27521                      throw new IllegalArgumentException('Data too large for an Aztec code');
27522                  }
27523                  compact = i <= 3;
27524                  layers = compact ? i + 1 : i;
27525                  totalBitsInLayer = Encoder.totalBitsInLayer(layers, compact);
27526                  if (totalSizeBits > totalBitsInLayer) {
27527                      continue;
27528                  }
27529                  // [Re]stuff the bits if this is the first opportunity, or if the
27530                  // wordSize has changed
27531                  if (stuffedBits == null || wordSize !== Encoder.WORD_SIZE[layers]) {
27532                      wordSize = Encoder.WORD_SIZE[layers];
27533                      stuffedBits = Encoder.stuffBits(bits, wordSize);
27534                  }
27535                  let usableBitsInLayers = totalBitsInLayer - (totalBitsInLayer % wordSize);
27536                  if (compact && stuffedBits.getSize() > wordSize * 64) {
27537                      // Compact format only allows 64 data words, though C4 can hold more words than that
27538                      continue;
27539                  }
27540                  if (stuffedBits.getSize() + eccBits <= usableBitsInLayers) {
27541                      break;
27542                  }
27543              }
27544          }
27545          let messageBits = Encoder.generateCheckWords(stuffedBits, totalBitsInLayer, wordSize);
27546          // generate mode message
27547          let messageSizeInWords = stuffedBits.getSize() / wordSize;
27548          let modeMessage = Encoder.generateModeMessage(compact, layers, messageSizeInWords);
27549          // allocate symbol
27550          let baseMatrixSize = (compact ? 11 : 14) + layers * 4; // not including alignment lines
27551          let alignmentMap = new Int32Array(baseMatrixSize);
27552          let matrixSize;
27553          if (compact) {
27554              // no alignment marks in compact mode, alignmentMap is a no-op
27555              matrixSize = baseMatrixSize;
27556              for (let i /*int*/ = 0; i < alignmentMap.length; i++) {
27557                  alignmentMap[i] = i;
27558              }
27559          }
27560          else {
27561              matrixSize = baseMatrixSize + 1 + 2 * Integer.truncDivision((Integer.truncDivision(baseMatrixSize, 2) - 1), 15);
27562              let origCenter = Integer.truncDivision(baseMatrixSize, 2);
27563              let center = Integer.truncDivision(matrixSize, 2);
27564              for (let i /*int*/ = 0; i < origCenter; i++) {
27565                  let newOffset = i + Integer.truncDivision(i, 15);
27566                  alignmentMap[origCenter - i - 1] = center - newOffset - 1;
27567                  alignmentMap[origCenter + i] = center + newOffset + 1;
27568              }
27569          }
27570          let matrix = new BitMatrix(matrixSize);
27571          // draw data bits
27572          for (let i /*int*/ = 0, rowOffset = 0; i < layers; i++) {
27573              let rowSize = (layers - i) * 4 + (compact ? 9 : 12);
27574              for (let j /*int*/ = 0; j < rowSize; j++) {
27575                  let columnOffset = j * 2;
27576                  for (let k /*int*/ = 0; k < 2; k++) {
27577                      if (messageBits.get(rowOffset + columnOffset + k)) {
27578                          matrix.set(alignmentMap[i * 2 + k], alignmentMap[i * 2 + j]);
27579                      }
27580                      if (messageBits.get(rowOffset + rowSize * 2 + columnOffset + k)) {
27581                          matrix.set(alignmentMap[i * 2 + j], alignmentMap[baseMatrixSize - 1 - i * 2 - k]);
27582                      }
27583                      if (messageBits.get(rowOffset + rowSize * 4 + columnOffset + k)) {
27584                          matrix.set(alignmentMap[baseMatrixSize - 1 - i * 2 - k], alignmentMap[baseMatrixSize - 1 - i * 2 - j]);
27585                      }
27586                      if (messageBits.get(rowOffset + rowSize * 6 + columnOffset + k)) {
27587                          matrix.set(alignmentMap[baseMatrixSize - 1 - i * 2 - j], alignmentMap[i * 2 + k]);
27588                      }
27589                  }
27590              }
27591              rowOffset += rowSize * 8;
27592          }
27593          // draw mode message
27594          Encoder.drawModeMessage(matrix, compact, matrixSize, modeMessage);
27595          // draw alignment marks
27596          if (compact) {
27597              Encoder.drawBullsEye(matrix, Integer.truncDivision(matrixSize, 2), 5);
27598          }
27599          else {
27600              Encoder.drawBullsEye(matrix, Integer.truncDivision(matrixSize, 2), 7);
27601              for (let i /*int*/ = 0, j = 0; i < Integer.truncDivision(baseMatrixSize, 2) - 1; i += 15, j += 16) {
27602                  for (let k /*int*/ = Integer.truncDivision(matrixSize, 2) & 1; k < matrixSize; k += 2) {
27603                      matrix.set(Integer.truncDivision(matrixSize, 2) - j, k);
27604                      matrix.set(Integer.truncDivision(matrixSize, 2) + j, k);
27605                      matrix.set(k, Integer.truncDivision(matrixSize, 2) - j);
27606                      matrix.set(k, Integer.truncDivision(matrixSize, 2) + j);
27607                  }
27608              }
27609          }
27610          let aztec = new AztecCode();
27611          aztec.setCompact(compact);
27612          aztec.setSize(matrixSize);
27613          aztec.setLayers(layers);
27614          aztec.setCodeWords(messageSizeInWords);
27615          aztec.setMatrix(matrix);
27616          return aztec;
27617      }
27618      static drawBullsEye(matrix, center, size) {
27619          for (let i /*int*/ = 0; i < size; i += 2) {
27620              for (let j /*int*/ = center - i; j <= center + i; j++) {
27621                  matrix.set(j, center - i);
27622                  matrix.set(j, center + i);
27623                  matrix.set(center - i, j);
27624                  matrix.set(center + i, j);
27625              }
27626          }
27627          matrix.set(center - size, center - size);
27628          matrix.set(center - size + 1, center - size);
27629          matrix.set(center - size, center - size + 1);
27630          matrix.set(center + size, center - size);
27631          matrix.set(center + size, center - size + 1);
27632          matrix.set(center + size, center + size - 1);
27633      }
27634      static generateModeMessage(compact, layers, messageSizeInWords) {
27635          let modeMessage = new BitArray();
27636          if (compact) {
27637              modeMessage.appendBits(layers - 1, 2);
27638              modeMessage.appendBits(messageSizeInWords - 1, 6);
27639              modeMessage = Encoder.generateCheckWords(modeMessage, 28, 4);
27640          }
27641          else {
27642              modeMessage.appendBits(layers - 1, 5);
27643              modeMessage.appendBits(messageSizeInWords - 1, 11);
27644              modeMessage = Encoder.generateCheckWords(modeMessage, 40, 4);
27645          }
27646          return modeMessage;
27647      }
27648      static drawModeMessage(matrix, compact, matrixSize, modeMessage) {
27649          let center = Integer.truncDivision(matrixSize, 2);
27650          if (compact) {
27651              for (let i /*int*/ = 0; i < 7; i++) {
27652                  let offset = center - 3 + i;
27653                  if (modeMessage.get(i)) {
27654                      matrix.set(offset, center - 5);
27655                  }
27656                  if (modeMessage.get(i + 7)) {
27657                      matrix.set(center + 5, offset);
27658                  }
27659                  if (modeMessage.get(20 - i)) {
27660                      matrix.set(offset, center + 5);
27661                  }
27662                  if (modeMessage.get(27 - i)) {
27663                      matrix.set(center - 5, offset);
27664                  }
27665              }
27666          }
27667          else {
27668              for (let i /*int*/ = 0; i < 10; i++) {
27669                  let offset = center - 5 + i + Integer.truncDivision(i, 5);
27670                  if (modeMessage.get(i)) {
27671                      matrix.set(offset, center - 7);
27672                  }
27673                  if (modeMessage.get(i + 10)) {
27674                      matrix.set(center + 7, offset);
27675                  }
27676                  if (modeMessage.get(29 - i)) {
27677                      matrix.set(offset, center + 7);
27678                  }
27679                  if (modeMessage.get(39 - i)) {
27680                      matrix.set(center - 7, offset);
27681                  }
27682              }
27683          }
27684      }
27685      static generateCheckWords(bitArray, totalBits, wordSize) {
27686          // bitArray is guaranteed to be a multiple of the wordSize, so no padding needed
27687          let messageSizeInWords = bitArray.getSize() / wordSize;
27688          let rs = new ReedSolomonEncoder(Encoder.getGF(wordSize));
27689          let totalWords = Integer.truncDivision(totalBits, wordSize);
27690          let messageWords = Encoder.bitsToWords(bitArray, wordSize, totalWords);
27691          rs.encode(messageWords, totalWords - messageSizeInWords);
27692          let startPad = totalBits % wordSize;
27693          let messageBits = new BitArray();
27694          messageBits.appendBits(0, startPad);
27695          for (const messageWord /*: int*/ of Array.from(messageWords)) {
27696              messageBits.appendBits(messageWord, wordSize);
27697          }
27698          return messageBits;
27699      }
27700      static bitsToWords(stuffedBits, wordSize, totalWords) {
27701          let message = new Int32Array(totalWords);
27702          let i;
27703          let n;
27704          for (i = 0, n = stuffedBits.getSize() / wordSize; i < n; i++) {
27705              let value = 0;
27706              for (let j /*int*/ = 0; j < wordSize; j++) {
27707                  value |= stuffedBits.get(i * wordSize + j) ? (1 << wordSize - j - 1) : 0;
27708              }
27709              message[i] = value;
27710          }
27711          return message;
27712      }
27713      static getGF(wordSize) {
27714          switch (wordSize) {
27715              case 4:
27716                  return GenericGF.AZTEC_PARAM;
27717              case 6:
27718                  return GenericGF.AZTEC_DATA_6;
27719              case 8:
27720                  return GenericGF.AZTEC_DATA_8;
27721              case 10:
27722                  return GenericGF.AZTEC_DATA_10;
27723              case 12:
27724                  return GenericGF.AZTEC_DATA_12;
27725              default:
27726                  throw new IllegalArgumentException('Unsupported word size ' + wordSize);
27727          }
27728      }
27729      static stuffBits(bits, wordSize) {
27730          let out = new BitArray();
27731          let n = bits.getSize();
27732          let mask = (1 << wordSize) - 2;
27733          for (let i /*int*/ = 0; i < n; i += wordSize) {
27734              let word = 0;
27735              for (let j /*int*/ = 0; j < wordSize; j++) {
27736                  if (i + j >= n || bits.get(i + j)) {
27737                      word |= 1 << (wordSize - 1 - j);
27738                  }
27739              }
27740              if ((word & mask) === mask) {
27741                  out.appendBits(word & mask, wordSize);
27742                  i--;
27743              }
27744              else if ((word & mask) === 0) {
27745                  out.appendBits(word | 1, wordSize);
27746                  i--;
27747              }
27748              else {
27749                  out.appendBits(word, wordSize);
27750              }
27751          }
27752          return out;
27753      }
27754      static totalBitsInLayer(layers, compact) {
27755          return ((compact ? 88 : 112) + 16 * layers) * layers;
27756      }
27757  }
27758  Encoder.DEFAULT_EC_PERCENT = 33; // default minimal percentage of error check words
27759  Encoder.DEFAULT_AZTEC_LAYERS = 0;
27760  Encoder.MAX_NB_BITS = 32;
27761  Encoder.MAX_NB_BITS_COMPACT = 4;
27762  Encoder.WORD_SIZE = Int32Array.from([
27763      4, 6, 6, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
27764      12, 12, 12, 12, 12, 12, 12, 12, 12, 12
27765  ]);
27766
27767  /*
27768  * Copyright 2013 ZXing authors
27769  *
27770  * Licensed under the Apache License, Version 2.0 (the "License");
27771  * you may not use this file except in compliance with the License.
27772  * You may obtain a copy of the License at
27773  *
27774  *      http://www.apache.org/licenses/LICENSE-2.0
27775  *
27776  * Unless required by applicable law or agreed to in writing, software
27777  * distributed under the License is distributed on an "AS IS" BASIS,
27778  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27779  * See the License for the specific language governing permissions and
27780  * limitations under the License.
27781  */
27782  /
vendor: 7,743 bytes, lines 27782-27944
27782**
27783   * Renders an Aztec code as a {@link BitMatrix}.
27784   */
27785  /*public final*/ class AztecWriter {
27786      // @Override
27787      encode(contents, format, width, height) {
27788          return this.encodeWithHints(contents, format, width, height, null);
27789      }
27790      // @Override
27791      encodeWithHints(contents, format, width, height, hints) {
27792          let charset = StandardCharsets.ISO_8859_1;
27793          let eccPercent = Encoder.DEFAULT_EC_PERCENT;
27794          let layers = Encoder.DEFAULT_AZTEC_LAYERS;
27795          if (hints != null) {
27796              if (hints.has(EncodeHintType$1.CHARACTER_SET)) {
27797                  charset = Charset.forName(hints.get(EncodeHintType$1.CHARACTER_SET).toString());
27798              }
27799              if (hints.has(EncodeHintType$1.ERROR_CORRECTION)) {
27800                  eccPercent = Integer.parseInt(hints.get(EncodeHintType$1.ERROR_CORRECTION).toString());
27801              }
27802              if (hints.has(EncodeHintType$1.AZTEC_LAYERS)) {
27803                  layers = Integer.parseInt(hints.get(EncodeHintType$1.AZTEC_LAYERS).toString());
27804              }
27805          }
27806          return AztecWriter.encodeLayers(contents, format, width, height, charset, eccPercent, layers);
27807      }
27808      static encodeLayers(contents, format, width, height, charset, eccPercent, layers) {
27809          if (format !== BarcodeFormat$1.AZTEC) {
27810              throw new IllegalArgumentException('Can only encode AZTEC, but got ' + format);
27811          }
27812          let aztec = Encoder.encode(StringUtils.getBytes(contents, charset), eccPercent, layers);
27813          return AztecWriter.renderResult(aztec, width, height);
27814      }
27815      static renderResult(code, width, height) {
27816          let input = code.getMatrix();
27817          if (input == null) {
27818              throw new IllegalStateException();
27819          }
27820          let inputWidth = input.getWidth();
27821          let inputHeight = input.getHeight();
27822          let outputWidth = Math.max(width, inputWidth);
27823          let outputHeight = Math.max(height, inputHeight);
27824          let multiple = Math.min(outputWidth / inputWidth, outputHeight / inputHeight);
27825          let leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
27826          let topPadding = (outputHeight - (inputHeight * multiple)) / 2;
27827          let output = new BitMatrix(outputWidth, outputHeight);
27828          for (let inputY /*int*/ = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
27829              // Write the contents of this row of the barcode
27830              for (let inputX /*int*/ = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
27831                  if (input.get(inputX, inputY)) {
27832                      output.setRegion(outputX, outputY, multiple, multiple);
27833                  }
27834              }
27835          }
27836          return output;
27837      }
27838  }
27839
27840  exports.AbstractExpandedDecoder = AbstractExpandedDecoder;
27841  exports.ArgumentException = ArgumentException;
27842  exports.ArithmeticException = ArithmeticException;
27843  exports.AztecCode = AztecCode;
27844  exports.AztecCodeReader = AztecReader;
27845  exports.AztecCodeWriter = AztecWriter;
27846  exports.AztecDecoder = Decoder$2;
27847  exports.AztecDetector = Detector$3;
27848  exports.AztecDetectorResult = AztecDetectorResult;
27849  exports.AztecEncoder = Encoder;
27850  exports.AztecHighLevelEncoder = HighLevelEncoder;
27851  exports.AztecPoint = Point;
27852  exports.BarcodeFormat = BarcodeFormat$1;
27853  exports.Binarizer = Binarizer;
27854  exports.BinaryBitmap = BinaryBitmap;
27855  exports.BitArray = BitArray;
27856  exports.BitMatrix = BitMatrix;
27857  exports.BitSource = BitSource;
27858  exports.BrowserAztecCodeReader = BrowserAztecCodeReader;
27859  exports.BrowserBarcodeReader = BrowserBarcodeReader;
27860  exports.BrowserCodeReader = BrowserCodeReader;
27861  exports.BrowserDatamatrixCodeReader = BrowserDatamatrixCodeReader;
27862  exports.BrowserMultiFormatReader = BrowserMultiFormatReader;
27863  exports.BrowserPDF417Reader = BrowserPDF417Reader;
27864  exports.BrowserQRCodeReader = BrowserQRCodeReader;
27865  exports.BrowserQRCodeSvgWriter = BrowserQRCodeSvgWriter;
27866  exports.CharacterSetECI = CharacterSetECI;
27867  exports.ChecksumException = ChecksumException;
27868  exports.CodaBarReader = CodaBarReader;
27869  exports.Code128Reader = Code128Reader;
27870  exports.Code39Reader = Code39Reader;
27871  exports.Code93Reader = Code93Reader;
27872  exports.DataMatrixDecodedBitStreamParser = DecodedBitStreamParser$2;
27873  exports.DataMatrixDefaultPlacement = DefaultPlacement;
27874  exports.DataMatrixErrorCorrection = ErrorCorrection;
27875  exports.DataMatrixHighLevelEncoder = HighLevelEncoder$1;
27876  exports.DataMatrixReader = DataMatrixReader;
27877  exports.DataMatrixSymbolInfo = SymbolInfo;
27878  exports.DataMatrixWriter = DataMatrixWriter;
27879  exports.DecodeHintType = DecodeHintType$1;
27880  exports.DecoderResult = DecoderResult;
27881  exports.DefaultGridSampler = DefaultGridSampler;
27882  exports.DetectorResult = DetectorResult;
27883  exports.EAN13Reader = EAN13Reader;
27884  exports.EncodeHintType = EncodeHintType$1;
27885  exports.Exception = Exception;
27886  exports.FormatException = FormatException;
27887  exports.GenericGF = GenericGF;
27888  exports.GenericGFPoly = GenericGFPoly;
27889  exports.GlobalHistogramBinarizer = GlobalHistogramBinarizer;
27890  exports.GridSampler = GridSampler;
27891  exports.GridSamplerInstance = GridSamplerInstance;
27892  exports.HTMLCanvasElementLuminanceSource = HTMLCanvasElementLuminanceSource;
27893  exports.HybridBinarizer = HybridBinarizer;
27894  exports.ITFReader = ITFReader;
27895  exports.IllegalArgumentException = IllegalArgumentException;
27896  exports.IllegalStateException = IllegalStateException;
27897  exports.InvertedLuminanceSource = InvertedLuminanceSource;
27898  exports.LuminanceSource = LuminanceSource;
27899  exports.MathUtils = MathUtils;
27900  exports.MultiFormatOneDReader = MultiFormatOneDReader;
27901  exports.MultiFormatReader = MultiFormatReader;
27902  exports.MultiFormatWriter = MultiFormatWriter;
27903  exports.NotFoundException = NotFoundException;
27904  exports.OneDReader = OneDReader;
27905  exports.PDF417DecodedBitStreamParser = DecodedBitStreamParser;
27906  exports.PDF417DecoderErrorCorrection = ErrorCorrection$1;
27907  exports.PDF417Reader = PDF417Reader;
27908  exports.PDF417ResultMetadata = PDF417ResultMetadata;
27909  exports.PerspectiveTransform = PerspectiveTransform;
27910  exports.PlanarYUVLuminanceSource = PlanarYUVLuminanceSource;
27911  exports.QRCodeByteMatrix = ByteMatrix;
27912  exports.QRCodeDataMask = DataMask;
27913  exports.QRCodeDecodedBitStreamParser = DecodedBitStreamParser$1;
27914  exports.QRCodeDecoderErrorCorrectionLevel = ErrorCorrectionLevel;
27915  exports.QRCodeDecoderFormatInformation = FormatInformation;
27916  exports.QRCodeEncoder = Encoder$1;
27917  exports.QRCodeEncoderQRCode = QRCode;
27918  exports.QRCodeMaskUtil = MaskUtil;
27919  exports.QRCodeMatrixUtil = MatrixUtil;
27920  exports.QRCodeMode = Mode$2;
27921  exports.QRCodeReader = QRCodeReader;
27922  exports.QRCodeVersion = Version;
27923  exports.QRCodeWriter = QRCodeWriter;
27924  exports.RGBLuminanceSource = RGBLuminanceSource;
27925  exports.RSS14Reader = RSS14Reader;
27926  exports.RSSExpandedReader = RSSExpandedReader;
27927  exports.ReaderException = ReaderException;
27928  exports.ReedSolomonDecoder = ReedSolomonDecoder;
27929  exports.ReedSolomonEncoder = ReedSolomonEncoder;
27930  exports.ReedSolomonException = ReedSolomonException;
27931  exports.Result = Result$1;
27932  exports.ResultMetadataType = ResultMetadataType$1;
27933  exports.ResultPoint = ResultPoint;
27934  exports.StringUtils = StringUtils;
27935  exports.UnsupportedOperationException = UnsupportedOperationException;
27936  exports.VideoInputDevice = VideoInputDevice;
27937  exports.WhiteRectangleDetector = WhiteRectangleDetector;
27938  exports.WriterException = WriterException;
27939  exports.ZXingArrays = Arrays;
27940  exports.ZXingCharset = Charset;
27941  exports.ZXingInteger = Integer;
27942  exports.ZXingStandardCharsets = StandardCharsets;
27943  exports.ZXingStringBuilder = StringBuilder;
27944  exports.ZXingStringEncoding = StringEncoding;
27945  exports.ZXingSystem = System;
27946  exports.createAbstractExpandedDecoder = createDecoder;
27947
27948  Object.defineProperty(exports, '__esModule', { value: true });
27949
27950}));
27951//# sourceMappingURL=index.js.map

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