/**
  * 一つのお題を表す配列から解答行に直列化します。
  * @param (string|string[]|float)[][] $word
  * @return string 末尾に改行 (CRLF) を含みます。
  */
 protected function serializeAnswerLine(array $word) : string
 {
     $line = ['A'];
     $specifics = new URLSearchParams($word['specifics'][0] ?? '');
     if (isset($word['option'][0])) {
         if (isset($word['type'][0]) && $word['type'][0] === 'selection' && empty($word['answer'])) {
             $line[] = 2;
         } elseif ($specifics->has('require-all-right')) {
             $line[] = 3;
         } else {
             $line[] = 1;
         }
         $answers = isset($word['answer'][0]) ? $word['answer'] : $word['text'];
         foreach ($word['option'] as $i => $option) {
             $line[] = $this->serializeQuizField($option);
             if ($line[1] === 2) {
                 $line[] = $i + 1;
             } elseif (in_array($option, $answers)) {
                 $line[] = '\\seikai';
             }
         }
         if ($specifics->has('no-random')) {
             $line[] = '\\norandom';
         }
     } else {
         $line[] = 0;
         $answers = $this->getAnswers($word, [$this, 'convertToShiftJISableInAnswerWithKatakana']);
         if (!$answers) {
             $this->logUnserializableError('Inteligenceω クイズ', $word);
             return '';
         }
         $bonuses = $specifics->getAll('bonus');
         foreach ($answers as $i => $answer) {
             $line[] = $answer;
             if (!empty($bonuses[$i])) {
                 $line[] = "\\bonus={$bonuses[$i]}";
             }
         }
     }
     $explain[] = $word['text'][0];
     if (isset($word['description'][0])) {
         $explain[] = $word['description'][0]['lml'];
     }
     $line[] = '\\explain=' . $this->serializeQuizField(implode("\n\n", $explain));
     return implode(',', $line) . "\r\n";
 }
 public function correct(string $input) : string
 {
     $nameValues = $this->parse($input);
     if ($nameValues) {
         $params = new URLSearchParams();
         foreach ($nameValues as $name => $values) {
             foreach ($values as $value) {
                 switch ($name) {
                     // 空文字列
                     case 'pixelization':
                     case 'require-all-right':
                     case 'no-random':
                         $params->append($name, '');
                         break;
                         // 0より大きい実数
                     // 0より大きい実数
                     case 'magnification':
                     case 'last-magnification':
                     case 'length':
                     case 'speed':
                     case 'volume':
                         $validator = new NumberValidator(true);
                         $validator->setLogger($this->logger);
                         $number = $validator->correct($value);
                         if ($number !== '' && $number > 0) {
                             $params->append($name, $number);
                         } else {
                             $this->logger->error(sprintf(_('「%s」は0より大きい実数として扱えません。'), $value));
                         }
                         break;
                         // 0以上の実数
                     // 0以上の実数
                     case 'start':
                         $validator = new NumberValidator(true);
                         $validator->setLogger($this->logger);
                         $number = $validator->correct($value);
                         if ($number !== '' && $number >= 0) {
                             $params->append($name, $number);
                         } else {
                             $this->logger->error(sprintf(_('「%s」は0以上の実数として扱えません。'), $value));
                         }
                         break;
                         // 1以上の整数
                     // 1以上の整数
                     case 'repeat':
                     case 'score':
                     case 'last-score':
                         $validator = new NumberValidator();
                         $validator->setLogger($this->logger);
                         $number = $validator->correct($value);
                         if ($number !== '' && $number >= 1) {
                             $params->append($name, $number);
                         } else {
                             $this->logger->error(sprintf(_('「%s」は1以上の整数として扱えません。'), $value));
                         }
                         break;
                         // 整数
                     // 整数
                     case 'bonus':
                         $validator = new NumberValidator();
                         $validator->setLogger($this->logger);
                         $number = $validator->correct($value);
                         if ($number !== '') {
                             $params->append($name, $number);
                         } else {
                             $this->logger->error(sprintf(_('「%s」は整数として扱えません。'), $value));
                         }
                         break;
                     default:
                         $params->append($name, $value);
                 }
             }
         }
         foreach (self::DEPENDENCES as $source => $destination) {
             if ($params->has($source) && !$params->has($destination)) {
                 $params->delete($source);
                 // TRANRATORS: %1$s、%2$s はapplication/x-www-form-urlencoded形式の名前部分
                 $this->logger->error(sprintf(_('「%1$s」を指定するときは、「%2$s」も指定しておく必要があります。'), $source, $destination));
             }
         }
         $output = (string) $params;
     } else {
         $this->logger->error(_('解析した結果空文字列になりました。'));
     }
     return $output ?? '';
 }