Version.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. <?php
  2. declare(strict_types = 1);
  3. namespace BaconQrCode\Common;
  4. use BaconQrCode\Exception\InvalidArgumentException;
  5. use SplFixedArray;
  6. /**
  7. * Version representation.
  8. */
  9. final class Version
  10. {
  11. private const VERSION_DECODE_INFO = [
  12. 0x07c94,
  13. 0x085bc,
  14. 0x09a99,
  15. 0x0a4d3,
  16. 0x0bbf6,
  17. 0x0c762,
  18. 0x0d847,
  19. 0x0e60d,
  20. 0x0f928,
  21. 0x10b78,
  22. 0x1145d,
  23. 0x12a17,
  24. 0x13532,
  25. 0x149a6,
  26. 0x15683,
  27. 0x168c9,
  28. 0x177ec,
  29. 0x18ec4,
  30. 0x191e1,
  31. 0x1afab,
  32. 0x1b08e,
  33. 0x1cc1a,
  34. 0x1d33f,
  35. 0x1ed75,
  36. 0x1f250,
  37. 0x209d5,
  38. 0x216f0,
  39. 0x228ba,
  40. 0x2379f,
  41. 0x24b0b,
  42. 0x2542e,
  43. 0x26a64,
  44. 0x27541,
  45. 0x28c69,
  46. ];
  47. /**
  48. * Version number of this version.
  49. *
  50. * @var int
  51. */
  52. private $versionNumber;
  53. /**
  54. * Alignment pattern centers.
  55. *
  56. * @var SplFixedArray
  57. */
  58. private $alignmentPatternCenters;
  59. /**
  60. * Error correction blocks.
  61. *
  62. * @var EcBlocks[]
  63. */
  64. private $ecBlocks;
  65. /**
  66. * Total number of codewords.
  67. *
  68. * @var int
  69. */
  70. private $totalCodewords;
  71. /**
  72. * Cached version instances.
  73. *
  74. * @var array<int, self>|null
  75. */
  76. private static $versions;
  77. /**
  78. * @param int[] $alignmentPatternCenters
  79. */
  80. private function __construct(
  81. int $versionNumber,
  82. array $alignmentPatternCenters,
  83. EcBlocks ...$ecBlocks
  84. ) {
  85. $this->versionNumber = $versionNumber;
  86. $this->alignmentPatternCenters = $alignmentPatternCenters;
  87. $this->ecBlocks = $ecBlocks;
  88. $totalCodewords = 0;
  89. $ecCodewords = $ecBlocks[0]->getEcCodewordsPerBlock();
  90. foreach ($ecBlocks[0]->getEcBlocks() as $ecBlock) {
  91. $totalCodewords += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords);
  92. }
  93. $this->totalCodewords = $totalCodewords;
  94. }
  95. /**
  96. * Returns the version number.
  97. */
  98. public function getVersionNumber() : int
  99. {
  100. return $this->versionNumber;
  101. }
  102. /**
  103. * Returns the alignment pattern centers.
  104. *
  105. * @return int[]
  106. */
  107. public function getAlignmentPatternCenters() : array
  108. {
  109. return $this->alignmentPatternCenters;
  110. }
  111. /**
  112. * Returns the total number of codewords.
  113. */
  114. public function getTotalCodewords() : int
  115. {
  116. return $this->totalCodewords;
  117. }
  118. /**
  119. * Calculates the dimension for the current version.
  120. */
  121. public function getDimensionForVersion() : int
  122. {
  123. return 17 + 4 * $this->versionNumber;
  124. }
  125. /**
  126. * Returns the number of EC blocks for a specific EC level.
  127. */
  128. public function getEcBlocksForLevel(ErrorCorrectionLevel $ecLevel) : EcBlocks
  129. {
  130. return $this->ecBlocks[$ecLevel->ordinal()];
  131. }
  132. /**
  133. * Gets a provisional version number for a specific dimension.
  134. *
  135. * @throws InvalidArgumentException if dimension is not 1 mod 4
  136. */
  137. public static function getProvisionalVersionForDimension(int $dimension) : self
  138. {
  139. if (1 !== $dimension % 4) {
  140. throw new InvalidArgumentException('Dimension is not 1 mod 4');
  141. }
  142. return self::getVersionForNumber(intdiv($dimension - 17, 4));
  143. }
  144. /**
  145. * Gets a version instance for a specific version number.
  146. *
  147. * @throws InvalidArgumentException if version number is out of range
  148. */
  149. public static function getVersionForNumber(int $versionNumber) : self
  150. {
  151. if ($versionNumber < 1 || $versionNumber > 40) {
  152. throw new InvalidArgumentException('Version number must be between 1 and 40');
  153. }
  154. return self::versions()[$versionNumber - 1];
  155. }
  156. /**
  157. * Decodes version information from an integer and returns the version.
  158. */
  159. public static function decodeVersionInformation(int $versionBits) : ?self
  160. {
  161. $bestDifference = PHP_INT_MAX;
  162. $bestVersion = 0;
  163. foreach (self::VERSION_DECODE_INFO as $i => $targetVersion) {
  164. if ($targetVersion === $versionBits) {
  165. return self::getVersionForNumber($i + 7);
  166. }
  167. $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion);
  168. if ($bitsDifference < $bestDifference) {
  169. $bestVersion = $i + 7;
  170. $bestDifference = $bitsDifference;
  171. }
  172. }
  173. if ($bestDifference <= 3) {
  174. return self::getVersionForNumber($bestVersion);
  175. }
  176. return null;
  177. }
  178. /**
  179. * Builds the function pattern for the current version.
  180. */
  181. public function buildFunctionPattern() : BitMatrix
  182. {
  183. $dimension = $this->getDimensionForVersion();
  184. $bitMatrix = new BitMatrix($dimension);
  185. // Top left finder pattern + separator + format
  186. $bitMatrix->setRegion(0, 0, 9, 9);
  187. // Top right finder pattern + separator + format
  188. $bitMatrix->setRegion($dimension - 8, 0, 8, 9);
  189. // Bottom left finder pattern + separator + format
  190. $bitMatrix->setRegion(0, $dimension - 8, 9, 8);
  191. // Alignment patterns
  192. $max = count($this->alignmentPatternCenters);
  193. for ($x = 0; $x < $max; ++$x) {
  194. $i = $this->alignmentPatternCenters[$x] - 2;
  195. for ($y = 0; $y < $max; ++$y) {
  196. if (($x === 0 && ($y === 0 || $y === $max - 1)) || ($x === $max - 1 && $y === 0)) {
  197. // No alignment patterns near the three finder paterns
  198. continue;
  199. }
  200. $bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5);
  201. }
  202. }
  203. // Vertical timing pattern
  204. $bitMatrix->setRegion(6, 9, 1, $dimension - 17);
  205. // Horizontal timing pattern
  206. $bitMatrix->setRegion(9, 6, $dimension - 17, 1);
  207. if ($this->versionNumber > 6) {
  208. // Version info, top right
  209. $bitMatrix->setRegion($dimension - 11, 0, 3, 6);
  210. // Version info, bottom left
  211. $bitMatrix->setRegion(0, $dimension - 11, 6, 3);
  212. }
  213. return $bitMatrix;
  214. }
  215. /**
  216. * Returns a string representation for the version.
  217. */
  218. public function __toString() : string
  219. {
  220. return (string) $this->versionNumber;
  221. }
  222. /**
  223. * Build and cache a specific version.
  224. *
  225. * See ISO 18004:2006 6.5.1 Table 9.
  226. *
  227. * @return array<int, self>
  228. */
  229. private static function versions() : array
  230. {
  231. if (null !== self::$versions) {
  232. return self::$versions;
  233. }
  234. return self::$versions = [
  235. new self(
  236. 1,
  237. [],
  238. new EcBlocks(7, new EcBlock(1, 19)),
  239. new EcBlocks(10, new EcBlock(1, 16)),
  240. new EcBlocks(13, new EcBlock(1, 13)),
  241. new EcBlocks(17, new EcBlock(1, 9))
  242. ),
  243. new self(
  244. 2,
  245. [6, 18],
  246. new EcBlocks(10, new EcBlock(1, 34)),
  247. new EcBlocks(16, new EcBlock(1, 28)),
  248. new EcBlocks(22, new EcBlock(1, 22)),
  249. new EcBlocks(28, new EcBlock(1, 16))
  250. ),
  251. new self(
  252. 3,
  253. [6, 22],
  254. new EcBlocks(15, new EcBlock(1, 55)),
  255. new EcBlocks(26, new EcBlock(1, 44)),
  256. new EcBlocks(18, new EcBlock(2, 17)),
  257. new EcBlocks(22, new EcBlock(2, 13))
  258. ),
  259. new self(
  260. 4,
  261. [6, 26],
  262. new EcBlocks(20, new EcBlock(1, 80)),
  263. new EcBlocks(18, new EcBlock(2, 32)),
  264. new EcBlocks(26, new EcBlock(3, 24)),
  265. new EcBlocks(16, new EcBlock(4, 9))
  266. ),
  267. new self(
  268. 5,
  269. [6, 30],
  270. new EcBlocks(26, new EcBlock(1, 108)),
  271. new EcBlocks(24, new EcBlock(2, 43)),
  272. new EcBlocks(18, new EcBlock(2, 15), new EcBlock(2, 16)),
  273. new EcBlocks(22, new EcBlock(2, 11), new EcBlock(2, 12))
  274. ),
  275. new self(
  276. 6,
  277. [6, 34],
  278. new EcBlocks(18, new EcBlock(2, 68)),
  279. new EcBlocks(16, new EcBlock(4, 27)),
  280. new EcBlocks(24, new EcBlock(4, 19)),
  281. new EcBlocks(28, new EcBlock(4, 15))
  282. ),
  283. new self(
  284. 7,
  285. [6, 22, 38],
  286. new EcBlocks(20, new EcBlock(2, 78)),
  287. new EcBlocks(18, new EcBlock(4, 31)),
  288. new EcBlocks(18, new EcBlock(2, 14), new EcBlock(4, 15)),
  289. new EcBlocks(26, new EcBlock(4, 13), new EcBlock(1, 14))
  290. ),
  291. new self(
  292. 8,
  293. [6, 24, 42],
  294. new EcBlocks(24, new EcBlock(2, 97)),
  295. new EcBlocks(22, new EcBlock(2, 38), new EcBlock(2, 39)),
  296. new EcBlocks(22, new EcBlock(4, 18), new EcBlock(2, 19)),
  297. new EcBlocks(26, new EcBlock(4, 14), new EcBlock(2, 15))
  298. ),
  299. new self(
  300. 9,
  301. [6, 26, 46],
  302. new EcBlocks(30, new EcBlock(2, 116)),
  303. new EcBlocks(22, new EcBlock(3, 36), new EcBlock(2, 37)),
  304. new EcBlocks(20, new EcBlock(4, 16), new EcBlock(4, 17)),
  305. new EcBlocks(24, new EcBlock(4, 12), new EcBlock(4, 13))
  306. ),
  307. new self(
  308. 10,
  309. [6, 28, 50],
  310. new EcBlocks(18, new EcBlock(2, 68), new EcBlock(2, 69)),
  311. new EcBlocks(26, new EcBlock(4, 43), new EcBlock(1, 44)),
  312. new EcBlocks(24, new EcBlock(6, 19), new EcBlock(2, 20)),
  313. new EcBlocks(28, new EcBlock(6, 15), new EcBlock(2, 16))
  314. ),
  315. new self(
  316. 11,
  317. [6, 30, 54],
  318. new EcBlocks(20, new EcBlock(4, 81)),
  319. new EcBlocks(30, new EcBlock(1, 50), new EcBlock(4, 51)),
  320. new EcBlocks(28, new EcBlock(4, 22), new EcBlock(4, 23)),
  321. new EcBlocks(24, new EcBlock(3, 12), new EcBlock(8, 13))
  322. ),
  323. new self(
  324. 12,
  325. [6, 32, 58],
  326. new EcBlocks(24, new EcBlock(2, 92), new EcBlock(2, 93)),
  327. new EcBlocks(22, new EcBlock(6, 36), new EcBlock(2, 37)),
  328. new EcBlocks(26, new EcBlock(4, 20), new EcBlock(6, 21)),
  329. new EcBlocks(28, new EcBlock(7, 14), new EcBlock(4, 15))
  330. ),
  331. new self(
  332. 13,
  333. [6, 34, 62],
  334. new EcBlocks(26, new EcBlock(4, 107)),
  335. new EcBlocks(22, new EcBlock(8, 37), new EcBlock(1, 38)),
  336. new EcBlocks(24, new EcBlock(8, 20), new EcBlock(4, 21)),
  337. new EcBlocks(22, new EcBlock(12, 11), new EcBlock(4, 12))
  338. ),
  339. new self(
  340. 14,
  341. [6, 26, 46, 66],
  342. new EcBlocks(30, new EcBlock(3, 115), new EcBlock(1, 116)),
  343. new EcBlocks(24, new EcBlock(4, 40), new EcBlock(5, 41)),
  344. new EcBlocks(20, new EcBlock(11, 16), new EcBlock(5, 17)),
  345. new EcBlocks(24, new EcBlock(11, 12), new EcBlock(5, 13))
  346. ),
  347. new self(
  348. 15,
  349. [6, 26, 48, 70],
  350. new EcBlocks(22, new EcBlock(5, 87), new EcBlock(1, 88)),
  351. new EcBlocks(24, new EcBlock(5, 41), new EcBlock(5, 42)),
  352. new EcBlocks(30, new EcBlock(5, 24), new EcBlock(7, 25)),
  353. new EcBlocks(24, new EcBlock(11, 12), new EcBlock(7, 13))
  354. ),
  355. new self(
  356. 16,
  357. [6, 26, 50, 74],
  358. new EcBlocks(24, new EcBlock(5, 98), new EcBlock(1, 99)),
  359. new EcBlocks(28, new EcBlock(7, 45), new EcBlock(3, 46)),
  360. new EcBlocks(24, new EcBlock(15, 19), new EcBlock(2, 20)),
  361. new EcBlocks(30, new EcBlock(3, 15), new EcBlock(13, 16))
  362. ),
  363. new self(
  364. 17,
  365. [6, 30, 54, 78],
  366. new EcBlocks(28, new EcBlock(1, 107), new EcBlock(5, 108)),
  367. new EcBlocks(28, new EcBlock(10, 46), new EcBlock(1, 47)),
  368. new EcBlocks(28, new EcBlock(1, 22), new EcBlock(15, 23)),
  369. new EcBlocks(28, new EcBlock(2, 14), new EcBlock(17, 15))
  370. ),
  371. new self(
  372. 18,
  373. [6, 30, 56, 82],
  374. new EcBlocks(30, new EcBlock(5, 120), new EcBlock(1, 121)),
  375. new EcBlocks(26, new EcBlock(9, 43), new EcBlock(4, 44)),
  376. new EcBlocks(28, new EcBlock(17, 22), new EcBlock(1, 23)),
  377. new EcBlocks(28, new EcBlock(2, 14), new EcBlock(19, 15))
  378. ),
  379. new self(
  380. 19,
  381. [6, 30, 58, 86],
  382. new EcBlocks(28, new EcBlock(3, 113), new EcBlock(4, 114)),
  383. new EcBlocks(26, new EcBlock(3, 44), new EcBlock(11, 45)),
  384. new EcBlocks(26, new EcBlock(17, 21), new EcBlock(4, 22)),
  385. new EcBlocks(26, new EcBlock(9, 13), new EcBlock(16, 14))
  386. ),
  387. new self(
  388. 20,
  389. [6, 34, 62, 90],
  390. new EcBlocks(28, new EcBlock(3, 107), new EcBlock(5, 108)),
  391. new EcBlocks(26, new EcBlock(3, 41), new EcBlock(13, 42)),
  392. new EcBlocks(30, new EcBlock(15, 24), new EcBlock(5, 25)),
  393. new EcBlocks(28, new EcBlock(15, 15), new EcBlock(10, 16))
  394. ),
  395. new self(
  396. 21,
  397. [6, 28, 50, 72, 94],
  398. new EcBlocks(28, new EcBlock(4, 116), new EcBlock(4, 117)),
  399. new EcBlocks(26, new EcBlock(17, 42)),
  400. new EcBlocks(28, new EcBlock(17, 22), new EcBlock(6, 23)),
  401. new EcBlocks(30, new EcBlock(19, 16), new EcBlock(6, 17))
  402. ),
  403. new self(
  404. 22,
  405. [6, 26, 50, 74, 98],
  406. new EcBlocks(28, new EcBlock(2, 111), new EcBlock(7, 112)),
  407. new EcBlocks(28, new EcBlock(17, 46)),
  408. new EcBlocks(30, new EcBlock(7, 24), new EcBlock(16, 25)),
  409. new EcBlocks(24, new EcBlock(34, 13))
  410. ),
  411. new self(
  412. 23,
  413. [6, 30, 54, 78, 102],
  414. new EcBlocks(30, new EcBlock(4, 121), new EcBlock(5, 122)),
  415. new EcBlocks(28, new EcBlock(4, 47), new EcBlock(14, 48)),
  416. new EcBlocks(30, new EcBlock(11, 24), new EcBlock(14, 25)),
  417. new EcBlocks(30, new EcBlock(16, 15), new EcBlock(14, 16))
  418. ),
  419. new self(
  420. 24,
  421. [6, 28, 54, 80, 106],
  422. new EcBlocks(30, new EcBlock(6, 117), new EcBlock(4, 118)),
  423. new EcBlocks(28, new EcBlock(6, 45), new EcBlock(14, 46)),
  424. new EcBlocks(30, new EcBlock(11, 24), new EcBlock(16, 25)),
  425. new EcBlocks(30, new EcBlock(30, 16), new EcBlock(2, 17))
  426. ),
  427. new self(
  428. 25,
  429. [6, 32, 58, 84, 110],
  430. new EcBlocks(26, new EcBlock(8, 106), new EcBlock(4, 107)),
  431. new EcBlocks(28, new EcBlock(8, 47), new EcBlock(13, 48)),
  432. new EcBlocks(30, new EcBlock(7, 24), new EcBlock(22, 25)),
  433. new EcBlocks(30, new EcBlock(22, 15), new EcBlock(13, 16))
  434. ),
  435. new self(
  436. 26,
  437. [6, 30, 58, 86, 114],
  438. new EcBlocks(28, new EcBlock(10, 114), new EcBlock(2, 115)),
  439. new EcBlocks(28, new EcBlock(19, 46), new EcBlock(4, 47)),
  440. new EcBlocks(28, new EcBlock(28, 22), new EcBlock(6, 23)),
  441. new EcBlocks(30, new EcBlock(33, 16), new EcBlock(4, 17))
  442. ),
  443. new self(
  444. 27,
  445. [6, 34, 62, 90, 118],
  446. new EcBlocks(30, new EcBlock(8, 122), new EcBlock(4, 123)),
  447. new EcBlocks(28, new EcBlock(22, 45), new EcBlock(3, 46)),
  448. new EcBlocks(30, new EcBlock(8, 23), new EcBlock(26, 24)),
  449. new EcBlocks(30, new EcBlock(12, 15), new EcBlock(28, 16))
  450. ),
  451. new self(
  452. 28,
  453. [6, 26, 50, 74, 98, 122],
  454. new EcBlocks(30, new EcBlock(3, 117), new EcBlock(10, 118)),
  455. new EcBlocks(28, new EcBlock(3, 45), new EcBlock(23, 46)),
  456. new EcBlocks(30, new EcBlock(4, 24), new EcBlock(31, 25)),
  457. new EcBlocks(30, new EcBlock(11, 15), new EcBlock(31, 16))
  458. ),
  459. new self(
  460. 29,
  461. [6, 30, 54, 78, 102, 126],
  462. new EcBlocks(30, new EcBlock(7, 116), new EcBlock(7, 117)),
  463. new EcBlocks(28, new EcBlock(21, 45), new EcBlock(7, 46)),
  464. new EcBlocks(30, new EcBlock(1, 23), new EcBlock(37, 24)),
  465. new EcBlocks(30, new EcBlock(19, 15), new EcBlock(26, 16))
  466. ),
  467. new self(
  468. 30,
  469. [6, 26, 52, 78, 104, 130],
  470. new EcBlocks(30, new EcBlock(5, 115), new EcBlock(10, 116)),
  471. new EcBlocks(28, new EcBlock(19, 47), new EcBlock(10, 48)),
  472. new EcBlocks(30, new EcBlock(15, 24), new EcBlock(25, 25)),
  473. new EcBlocks(30, new EcBlock(23, 15), new EcBlock(25, 16))
  474. ),
  475. new self(
  476. 31,
  477. [6, 30, 56, 82, 108, 134],
  478. new EcBlocks(30, new EcBlock(13, 115), new EcBlock(3, 116)),
  479. new EcBlocks(28, new EcBlock(2, 46), new EcBlock(29, 47)),
  480. new EcBlocks(30, new EcBlock(42, 24), new EcBlock(1, 25)),
  481. new EcBlocks(30, new EcBlock(23, 15), new EcBlock(28, 16))
  482. ),
  483. new self(
  484. 32,
  485. [6, 34, 60, 86, 112, 138],
  486. new EcBlocks(30, new EcBlock(17, 115)),
  487. new EcBlocks(28, new EcBlock(10, 46), new EcBlock(23, 47)),
  488. new EcBlocks(30, new EcBlock(10, 24), new EcBlock(35, 25)),
  489. new EcBlocks(30, new EcBlock(19, 15), new EcBlock(35, 16))
  490. ),
  491. new self(
  492. 33,
  493. [6, 30, 58, 86, 114, 142],
  494. new EcBlocks(30, new EcBlock(17, 115), new EcBlock(1, 116)),
  495. new EcBlocks(28, new EcBlock(14, 46), new EcBlock(21, 47)),
  496. new EcBlocks(30, new EcBlock(29, 24), new EcBlock(19, 25)),
  497. new EcBlocks(30, new EcBlock(11, 15), new EcBlock(46, 16))
  498. ),
  499. new self(
  500. 34,
  501. [6, 34, 62, 90, 118, 146],
  502. new EcBlocks(30, new EcBlock(13, 115), new EcBlock(6, 116)),
  503. new EcBlocks(28, new EcBlock(14, 46), new EcBlock(23, 47)),
  504. new EcBlocks(30, new EcBlock(44, 24), new EcBlock(7, 25)),
  505. new EcBlocks(30, new EcBlock(59, 16), new EcBlock(1, 17))
  506. ),
  507. new self(
  508. 35,
  509. [6, 30, 54, 78, 102, 126, 150],
  510. new EcBlocks(30, new EcBlock(12, 121), new EcBlock(7, 122)),
  511. new EcBlocks(28, new EcBlock(12, 47), new EcBlock(26, 48)),
  512. new EcBlocks(30, new EcBlock(39, 24), new EcBlock(14, 25)),
  513. new EcBlocks(30, new EcBlock(22, 15), new EcBlock(41, 16))
  514. ),
  515. new self(
  516. 36,
  517. [6, 24, 50, 76, 102, 128, 154],
  518. new EcBlocks(30, new EcBlock(6, 121), new EcBlock(14, 122)),
  519. new EcBlocks(28, new EcBlock(6, 47), new EcBlock(34, 48)),
  520. new EcBlocks(30, new EcBlock(46, 24), new EcBlock(10, 25)),
  521. new EcBlocks(30, new EcBlock(2, 15), new EcBlock(64, 16))
  522. ),
  523. new self(
  524. 37,
  525. [6, 28, 54, 80, 106, 132, 158],
  526. new EcBlocks(30, new EcBlock(17, 122), new EcBlock(4, 123)),
  527. new EcBlocks(28, new EcBlock(29, 46), new EcBlock(14, 47)),
  528. new EcBlocks(30, new EcBlock(49, 24), new EcBlock(10, 25)),
  529. new EcBlocks(30, new EcBlock(24, 15), new EcBlock(46, 16))
  530. ),
  531. new self(
  532. 38,
  533. [6, 32, 58, 84, 110, 136, 162],
  534. new EcBlocks(30, new EcBlock(4, 122), new EcBlock(18, 123)),
  535. new EcBlocks(28, new EcBlock(13, 46), new EcBlock(32, 47)),
  536. new EcBlocks(30, new EcBlock(48, 24), new EcBlock(14, 25)),
  537. new EcBlocks(30, new EcBlock(42, 15), new EcBlock(32, 16))
  538. ),
  539. new self(
  540. 39,
  541. [6, 26, 54, 82, 110, 138, 166],
  542. new EcBlocks(30, new EcBlock(20, 117), new EcBlock(4, 118)),
  543. new EcBlocks(28, new EcBlock(40, 47), new EcBlock(7, 48)),
  544. new EcBlocks(30, new EcBlock(43, 24), new EcBlock(22, 25)),
  545. new EcBlocks(30, new EcBlock(10, 15), new EcBlock(67, 16))
  546. ),
  547. new self(
  548. 40,
  549. [6, 30, 58, 86, 114, 142, 170],
  550. new EcBlocks(30, new EcBlock(19, 118), new EcBlock(6, 119)),
  551. new EcBlocks(28, new EcBlock(18, 47), new EcBlock(31, 48)),
  552. new EcBlocks(30, new EcBlock(34, 24), new EcBlock(34, 25)),
  553. new EcBlocks(30, new EcBlock(20, 15), new EcBlock(61, 16))
  554. ),
  555. ];
  556. }
  557. }