Provides the inverse mixColumns and inverse sboxes tables

@see Crypt_Rijndael:_decryptBlock()
@see Crypt_Rijndael:_setupInlineCrypt()
@see Crypt_Rijndael:_setupKey()
@access private
@return array &$tables
482403
function &_getInvTables()
    {
        static $tables;
        if (empty($tables)) {
            $dt3 = array_map('intval', array(
                0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
                0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
                0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
                0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
                0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
                0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
                0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
                0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
                0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
                0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
                0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
                0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
                0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
                0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
                0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
                0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
                0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
                0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
                0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
                0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
                0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
                0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
                0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
                0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
                0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
                0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
                0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
                0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
                0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
                0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
                0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
                0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
            ));

            foreach ($dt3 as $dt3i) {
                $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >>  8) & 0x00FFFFFF);
                $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
                $dt2[] = (($dt3i <<  8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
            };

            $tables = array(
                // The Precomputed inverse mixColumns tables dt0 - dt3
                $dt0,
                $dt1,
                $dt2,
                $dt3,
                // The inverse SubByte S-Box
                array(
                    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
                    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
                    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
                    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
                    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
                    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
                    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
                    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
                    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
                    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
                    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
                    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
                    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
                    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
                    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
                    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
                )
            );
        }
        return $tables;
    }
1042771
public function columns()
    {
        $orig = $this->origLanguage();
        $opposites = $this->oppositeLanguages();

        $columns = [ $orig ];

        foreach ($opposites as $lang) {
            $columns[] = $lang;
        }

        // Add context.
        $columns[] = 'context';

        return $columns;
    }
770912
private function parseTableRows()
    {
        $table = array();
        while (in_array($predicted = $this->predictTokenType(), array('TableRow', 'Newline', 'Comment'))) {
            if ('Comment' === $predicted || 'Newline' === $predicted) {
                $this->acceptTokenType($predicted);
                continue;
            }

            $token = $this->expectTokenType('TableRow');

            $table[$token['line']] = $token['columns'];
        }

        return $table;
    }
841131
public function getTables()
    {
        $options = $this->getOptions();
        $tables = [];

        foreach ($this->fetchAll(sprintf("select name from sqlite_master where type = 'table'")) as $row) {
            if ($row[0] == 'sqlite_sequence') continue;

            $table = new Table($row[0], [], $this);
            $tables[] = $table;
            $options = [];

            $describes = $this->fetchAll(sprintf('PRAGMA table_info(%s)', $this->quoteTableName($table->getName())));
            $primary_keys = [];
            foreach ($describes as $describe) {
                if ($describe['pk'] === '1') {
                    $primary_keys[] = $describe['name'];
                }
            }

            if (! $primary_keys || (count($primary_keys) === 1 && $primary_keys[0] === 'id')) {
            }

            // $this->table('foo', ['id' => 'foo_id']);
            elseif (count($primary_keys) === 1 && $primary_keys[0] !== 'id') {
                $options = ['id' => $primary_keys[0]];
            } else {
                $options = ['id' => false, 'primary_key' => $primary_keys];
            }

            $table->setOptions($options);
        }

        return $tables;
    }
849614
public function encryptBlock($x)
    {
        $y = ''; // 16-byte string

        // place input x into the initial state matrix in column order
        for ($i = 0; $i < 4 * self::$nb; ++$i) {
            // we want integerger division for the second index
                $this->state[$i % 4][($i - $i % self::$nb) / self::$nb] = ord($x[$i]);
        }

        // add round key
        $this->addRoundKey(0);

        for ($i = 1; $i < $this->rounds; ++$i) {
            // substitute bytes
                $this->subBytes();

                // shift rows
                $this->shiftRows();

                // mix columns
                $this->mixColumns();

                // add round key
                $this->addRoundKey($i);
        }

        // substitute bytes
        $this->subBytes();

        // shift rows
        $this->shiftRows();

        // add round key
        $this->addRoundKey($i);

        // place state matrix s into y in column order
        for ($i = 0; $i < 4 * self::$nb; ++$i) {
            $y .= chr($this->state[$i % 4][($i - $i % self::$nb) / self::$nb]);
        }

        return $y;
    }
471915
private function prepareColumns()
    {
        $columns = [];
        $hasId = false;
        foreach ($this->columns as $column) {
            if ($column['name'] === 'id') {
                $hasId = true;
            }
            if (!$column['label']) {
                continue;
            }
            $columnType = null;
            array_push($columns, [
                'name'  => $column['name'],
                'label' => $column['label'],
            ]);
        }
        if (!$hasId) {
            array_unshift($columns, [
                'name'  => 'id',
                'label' => 'ID'
            ]);
        }
        return $columns;
    }
21215
function GetTables()
    {
        $tables = array();
        $sql = new Sql\Builder($this);
        $tbl = $sql->Table('information_schema.tables', array('TABLE_SCHEMA', 'TABLE_NAME'));
        $cond = $sql->Equals($tbl->Field('TABLE_SCHEMA'), $sql->Value($this->dbName));
        $what = $sql->SelectList($tbl->Field('TABLE_NAME'));

        $select = $sql->Select(true, $what, $tbl, $cond);
        $reader = $this->ExecuteQuery((string) $select);
        while ($reader->Read())
        {
            $tables[] = $reader->ByIndex(0);
        }
        return $tables;
    }
673044
public function getColumns()
    {
        $query = Schema::make(trim($this->tableName), function ($table) {
            $table->on($this->database);
            $this->setSchemaInstance($table);

            return $table->setTableSchema()->getSchemaPreparedQuery();
        });

        return $this->query($query)->getAll();
    }
971301
function _encryptBlock($in)
    {
        list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
        $keys = $this->keys;
        $limit = 20;
        $actions = array($limit => 44, 44 => 64);
        $j = 0;

        for (;;) {
            // Mixing round.
            $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
            $r0 |= $r0 >> 16;
            $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
            $r1 |= $r1 >> 16;
            $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
            $r2 |= $r2 >> 16;
            $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
            $r3 |= $r3 >> 16;

            if ($j === $limit) {
                if ($limit === 64) {
                    break;
                }

                // Mashing round.
                $r0 += $keys[$r3 & 0x3F];
                $r1 += $keys[$r0 & 0x3F];
                $r2 += $keys[$r1 & 0x3F];
                $r3 += $keys[$r2 & 0x3F];
                $limit = $actions[$limit];
            }
        }

        return pack('vvvv', $r0, $r1, $r2, $r3);
    }
816733
protected function generateColumns($table)
    {
        $columns = [];
        $needPK = true;
        foreach ($table->columns as $column) {
            if ($column->autoIncrement) {
                $columns[$column->name] = $column->type == Schema::TYPE_BIGINT ? 'Schema::TYPE_BIGPK' : 'Schema::TYPE_PK';
                $needPK = false;
                continue;
            }
            list($type, $extra) = $this->getSchemaType($column);
            $quote = "'";
            if (!$column->allowNull) {
                $extra .= ' NOT NULL';
            }

            if ($column->defaultValue !== null) {
                $extra .= ' DEFAULT ';
                if ($column->defaultValue instanceof Expression || is_numeric($column->defaultValue)) {
                    $extra .= $column->defaultValue;
                } else {
                    $extra .= "'{$column->defaultValue}'";
                    $quote = '"';
                }
            }

            if (!empty($extra)) {
                $type = "$type . {$quote}$extra{$quote}";
            }
            $columns[$column->name] = $type;
        }
        if ($needPK && !empty($table->primaryKey)) {
            $pks = implode(']], [[', $table->primaryKey);
            $columns[0] = "PRIMARY KEY ([[{$pks}]])";
        }

        return $columns;
    }
567158
public static function getFromDB( )
    {
        $result = array();
        $objDB = \Database::getInstance( );

        $tables = $objDB->listTables( null, true );
        if( empty($tables) ) {
            return $result;
        }

        foreach( $tables as $table ) {
            $keys = array();
            $fields = $objDB->listFields($table, true);

            foreach( $fields as $field ) {
                $name = $field['name'];
                $field['name'] = '`' . $field['name'] . '`';

                if( in_array(strtolower($field['type']), array('text', 'tinytext', 'mediumtext', 'longtext')) && isset($fields[$name]) ) {
                    $keys[$name] = 'FULLTEXT ';
                }

                //--- Tabellenspalten definieren ---
                if( $field['type'] != 'index' ) {
                    unset($field['index']);

                    // Field type
                    if( isset($field['length']) && ($field['length'] != '') ) {
                        $field['type'] .= '(' . $field['length'] . ((isset($field['precision']) && $field['precision'] != '') ? ',' . $field['precision'] : '') . ')';

                        unset( $field['length'] );
                        unset( $field['precision'] );
                    }

                    // Variant collation
                    if( ($field['collation'] != '') && ($field['collation'] != $GLOBALS['TL_CONFIG']['dbCollation']) ) {
                        $field['collation'] = 'COLLATE ' . $field['collation'];
                    }
                    else {
                        unset( $field['collation'] );
                    }

                    // Default values
                    if( in_array(strtolower($field['type']), array('text', 'tinytext', 'mediumtext', 'longtext', 'blob', 'tinyblob', 'mediumblob', 'longblob')) || stristr($field['extra'], 'auto_increment') || ($field['default'] === null) || (strtolower($field['null']) == 'null') ) {
                        unset( $field['default'] );
                    }
                    // Date/time constants (see #5089)
                    else if( in_array(strtolower($field['default']), array('current_date', 'current_time', 'current_timestamp')) ) {
                        $field['default'] = "default " . $field['default'];
                    }
                    // Everything else
                    else {
                        $field['default'] = "default '" . $field['default'] . "'";
                    }

                    unset( $field['origtype'] );
                    $result[$table]['TABLE_FIELDS'][$name] = trim( implode( ' ', $field ) );
                }

                //--- Index-Einträge ---
                if( isset($field['index']) && !empty($field['index_fields']) ) {
                    $index_fields = '`' . implode( '`, `', $field['index_fields'] ) . '`';
                    $index_fields = str_replace(array('(', ')`'), array('`(', ')'), $index_fields );

                    switch( $field['index'] ) {
                        case 'UNIQUE':  if( $name == 'PRIMARY' ) {
                                            $result[$table]['TABLE_CREATE_DEFINITIONS'][$name] = 'PRIMARY KEY  ('.$index_fields.')';
                                        }
                                        else {
                                            $result[$table]['TABLE_CREATE_DEFINITIONS'][$name] = 'UNIQUE KEY `'.$name.'` ('.$index_fields.')';
                                        }
                                        break;

                        default:        $result[$table]['TABLE_CREATE_DEFINITIONS'][$name] = (isset($keys[$name]) ? $keys[$name] : '') . 'KEY `'.$name.'` ('.$index_fields.')';
                                        break;
                    }
                    unset( $field['index_fields'] );
                    unset( $field['index'] );
                }
            }
        }

        // Table status
        $objStatus = $objDB->execute( 'SHOW TABLE STATUS' );
        while( $zeile = $objStatus->fetchAssoc() ) {
            $result[$zeile['Name']]['TABLE_OPTIONS'] = ' ENGINE=' . $zeile['Engine'] . ' DEFAULT CHARSET=' . substr($zeile['Collation'], 0, strpos($zeile['Collation'],"_"));

            if( $zeile['Auto_increment'] != '' ) {
                $result[$zeile['Name']]['TABLE_OPTIONS'] .= ' AUTO_INCREMENT=' . $zeile['Auto_increment'];
            }
        }

        return $result;
    }
547679
public Collection<String> getEncryptTableNames() {
        Collection<String> result = new LinkedHashSet<>();
        for (ColumnNode each : columns) {
            result.add(each.getTableName());
        }
        return result;
    }
713231
protected function buildColumns() {
		$select = [];
		$params = [];
		if(!$this->columns)
			return ['*', []];
		else {
			foreach($this->columns as $alias=>$column) {
				if($column instanceof static) {
					$sql = $column->buildSQL();
					$params = array_merge($params, $column->getParameters());
					$select[] = '('.$sql.') AS '.$this->identifierQuotes($alias);
				}
				elseif($column instanceof Raw) {
					$sql = $column->getSQL();
					$params = array_merge($params, $column->getParameters());
					$select[] = $sql.' AS '.$this->identifierQuotes($alias);
				}
				elseif((string)$alias !== (string)$column)
					$select[] = $this->identifierQuotes($column).' AS '.$this->identifierQuotes($alias);
				else
					$select[] = $this->identifierQuotes($column);
			}
		}
		return [implode(', ', $select), $params];
	}
194635
private function mixColumns()
    {
        $s0 = $s1 = $s2 = $s3 = '';

        // There are Nb columns
        for ($i = 0; $i < self::$Nb; $i++) {
            $s0 = $this->s[0][$i];
            $s1 = $this->s[1][$i];
            $s2 = $this->s[2][$i];
            $s3 = $this->s[3][$i];

            $this->s[0][$i] = $this->mult(0x02, $s0) ^ $this->mult(0x03, $s1) ^ $this->mult(0x01, $s2) ^ $this->mult(0x01, $s3);
            $this->s[1][$i] = $this->mult(0x01, $s0) ^ $this->mult(0x02, $s1) ^ $this->mult(0x03, $s2) ^ $this->mult(0x01, $s3);
            $this->s[2][$i] = $this->mult(0x01, $s0) ^ $this->mult(0x01, $s1) ^ $this->mult(0x02, $s2) ^ $this->mult(0x03, $s3);
            $this->s[3][$i] = $this->mult(0x03, $s0) ^ $this->mult(0x01, $s1) ^ $this->mult(0x01, $s2) ^ $this->mult(0x02, $s3);
        }
    }
404253
public function getColumns(): array
    {
        $tSelects = isset($this->statements['selects']) === true ? $this->statements['selects'] : [];
        $tColumns = [];
        foreach ($tSelects as $key => $value) {
            if (\is_string($value)) {
                if (\is_int($key)) {
                    $tElements = explode('.', $value);
                    if (!\in_array('*', $tElements, true)) {
                        $tColumns[$tElements[1] ?? $tElements[0]] = $value;
                    }
                } elseif (\is_string($key)) {
                    $tColumns[$value] = $key;
                }
            }
        }
        return $tColumns;
    }
573258
private function parseTable()
    {
        $length = $this->parseUnsignedInt32();
        $stopAt = strlen($this->buffer) - $length;
        $table = [];

        while (strlen($this->buffer) > $stopAt) {
            $table[$this->parseShortString()] = $this->parseField();
        }

        return $table;
    }
269418
private function mapReverse($columns)
    {
        $result = [];
        foreach ($columns as $one) {
            $tableAlias = $one[0];
            $column = $one[1];
            $valueAlias = $one[2];
            $data = new \Praxigento\Core\App\Web\Processor\WithQuery\Alias();
            $data->setAlias($valueAlias);
            $data->setTable($tableAlias);
            $data->setField($column);
            $result[$valueAlias] = $data;
        }
        return $result;
    }