xref: /webtrees/app/Date/JewishDate.php (revision fcfa147e10aaa6c7ff580c29bd6e5b88666befc1)
1a25f0a04SGreg Roach<?php
23976b470SGreg Roach
3a25f0a04SGreg Roach/**
4a25f0a04SGreg Roach * webtrees: online genealogy
58fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team
6a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify
7a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by
8a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or
9a25f0a04SGreg Roach * (at your option) any later version.
10a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful,
11a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13a25f0a04SGreg Roach * GNU General Public License for more details.
14a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License
15a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
16a25f0a04SGreg Roach */
17*fcfa147eSGreg Roach
18e7f56f2aSGreg Roachdeclare(strict_types=1);
19e7f56f2aSGreg Roach
2076692c8bSGreg Roachnamespace Fisharebest\Webtrees\Date;
21a25f0a04SGreg Roach
22a25f0a04SGreg Roachuse Fisharebest\ExtCalendar\JewishCalendar;
23e364afe4SGreg Roachuse Fisharebest\Localization\Locale\LocaleInterface;
240e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
25a25f0a04SGreg Roach
26a25f0a04SGreg Roach/**
2776692c8bSGreg Roach * Definitions for the Jewish calendar
28a25f0a04SGreg Roach */
294a83f5d7SGreg Roachclass JewishDate extends AbstractCalendarDate
30c1010edaSGreg Roach{
314a83f5d7SGreg Roach    // GEDCOM calendar escape
3216d6367aSGreg Roach    public const ESCAPE = '@#DHEBREW@';
334a83f5d7SGreg Roach
3452348eb8SGreg Roach    // Convert GEDCOM month names to month numbers
3516d6367aSGreg Roach    protected const MONTH_ABBREVIATIONS = [
36c1010edaSGreg Roach        ''    => 0,
37c1010edaSGreg Roach        'TSH' => 1,
38c1010edaSGreg Roach        'CSH' => 2,
39c1010edaSGreg Roach        'KSL' => 3,
40c1010edaSGreg Roach        'TVT' => 4,
41c1010edaSGreg Roach        'SHV' => 5,
42c1010edaSGreg Roach        'ADR' => 6,
43c1010edaSGreg Roach        'ADS' => 7,
44c1010edaSGreg Roach        'NSN' => 8,
45c1010edaSGreg Roach        'IYR' => 9,
46c1010edaSGreg Roach        'SVN' => 10,
47c1010edaSGreg Roach        'TMZ' => 11,
48c1010edaSGreg Roach        'AAV' => 12,
49c1010edaSGreg Roach        'ELL' => 13,
50c1010edaSGreg Roach    ];
51a25f0a04SGreg Roach
5276692c8bSGreg Roach    /**
5376692c8bSGreg Roach     * Create a date from either:
5476692c8bSGreg Roach     * a Julian day number
5576692c8bSGreg Roach     * day/month/year strings from a GEDCOM date
5676692c8bSGreg Roach     * another CalendarDate object
5776692c8bSGreg Roach     *
584a83f5d7SGreg Roach     * @param array|int|AbstractCalendarDate $date
5976692c8bSGreg Roach     */
60c1010edaSGreg Roach    public function __construct($date)
61c1010edaSGreg Roach    {
6259f2f229SGreg Roach        $this->calendar = new JewishCalendar();
63a25f0a04SGreg Roach        parent::__construct($date);
64a25f0a04SGreg Roach    }
65a25f0a04SGreg Roach
6676692c8bSGreg Roach    /**
6776692c8bSGreg Roach     * Generate the %j format for a date.
6876692c8bSGreg Roach     *
6976692c8bSGreg Roach     * @return string
7076692c8bSGreg Roach     */
71fe11e66dSGreg Roach    protected function formatDay(): string
72c1010edaSGreg Roach    {
73e364afe4SGreg Roach        $locale = app(LocaleInterface::class)->language()->code();
74e364afe4SGreg Roach
75e364afe4SGreg Roach        if ($locale === 'he' || $locale === 'yi') {
764a83f5d7SGreg Roach            return (new JewishCalendar())->numberToHebrewNumerals($this->day, true);
77a25f0a04SGreg Roach        }
78b2ce94c6SRico Sonntag
79b2ce94c6SRico Sonntag        return parent::formatDay();
80a25f0a04SGreg Roach    }
81a25f0a04SGreg Roach
8276692c8bSGreg Roach    /**
8376692c8bSGreg Roach     * Generate the %y format for a date.
8476692c8bSGreg Roach     *
8576692c8bSGreg Roach     * NOTE Short year is NOT a 2-digit year. It is for calendars such as hebrew
8676692c8bSGreg Roach     * which have a 3-digit form of 4-digit years.
8776692c8bSGreg Roach     *
8876692c8bSGreg Roach     * @return string
8976692c8bSGreg Roach     */
90fe11e66dSGreg Roach    protected function formatShortYear(): string
91c1010edaSGreg Roach    {
92e364afe4SGreg Roach        $locale = app(LocaleInterface::class)->language()->code();
93e364afe4SGreg Roach
94e364afe4SGreg Roach        if ($locale === 'he' || $locale === 'yi') {
954a83f5d7SGreg Roach            return (new JewishCalendar())->numberToHebrewNumerals($this->year, false);
96a25f0a04SGreg Roach        }
97b2ce94c6SRico Sonntag
98b2ce94c6SRico Sonntag        return parent::formatLongYear();
99a25f0a04SGreg Roach    }
100a25f0a04SGreg Roach
10176692c8bSGreg Roach    /**
10276692c8bSGreg Roach     * Generate the %Y format for a date.
10376692c8bSGreg Roach     *
10476692c8bSGreg Roach     * @return string
10576692c8bSGreg Roach     */
106fe11e66dSGreg Roach    protected function formatLongYear(): string
107c1010edaSGreg Roach    {
108e364afe4SGreg Roach        $locale = app(LocaleInterface::class)->language()->code();
109e364afe4SGreg Roach
110e364afe4SGreg Roach        if ($locale === 'he' || $locale === 'yi') {
1114a83f5d7SGreg Roach            return (new JewishCalendar())->numberToHebrewNumerals($this->year, true);
112a25f0a04SGreg Roach        }
113b2ce94c6SRico Sonntag
114b2ce94c6SRico Sonntag        return parent::formatLongYear();
115a25f0a04SGreg Roach    }
116a25f0a04SGreg Roach
11776692c8bSGreg Roach    /**
11876692c8bSGreg Roach     * Full month name in nominative case.
11976692c8bSGreg Roach     *
1207bb2eb25SGreg Roach     * @param int  $month
12176692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
12276692c8bSGreg Roach     *
12376692c8bSGreg Roach     * @return string
12476692c8bSGreg Roach     */
1257bb2eb25SGreg Roach    protected function monthNameNominativeCase(int $month, bool $leap_year): string
126c1010edaSGreg Roach    {
127a25f0a04SGreg Roach        static $translated_month_names;
128a25f0a04SGreg Roach
129a25f0a04SGreg Roach        if ($translated_month_names === null) {
13013abd6f3SGreg Roach            $translated_month_names = [
131a25f0a04SGreg Roach                0  => '',
132bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
133bbb76c12SGreg Roach                1  => I18N::translateContext('NOMINATIVE', 'Tishrei'),
134bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
135bbb76c12SGreg Roach                2  => I18N::translateContext('NOMINATIVE', 'Heshvan'),
136bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
137bbb76c12SGreg Roach                3  => I18N::translateContext('NOMINATIVE', 'Kislev'),
138bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
139bbb76c12SGreg Roach                4  => I18N::translateContext('NOMINATIVE', 'Tevet'),
140bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
141bbb76c12SGreg Roach                5  => I18N::translateContext('NOMINATIVE', 'Shevat'),
142bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
143bbb76c12SGreg Roach                6  => I18N::translateContext('NOMINATIVE', 'Adar I'),
144bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
145bbb76c12SGreg Roach                7  => I18N::translateContext('NOMINATIVE', 'Adar'),
146bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
147bbb76c12SGreg Roach                -7 => I18N::translateContext('NOMINATIVE', 'Adar II'),
148bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
149bbb76c12SGreg Roach                8  => I18N::translateContext('NOMINATIVE', 'Nissan'),
150bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
151bbb76c12SGreg Roach                9  => I18N::translateContext('NOMINATIVE', 'Iyar'),
152bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
153bbb76c12SGreg Roach                10 => I18N::translateContext('NOMINATIVE', 'Sivan'),
154bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
155bbb76c12SGreg Roach                11 => I18N::translateContext('NOMINATIVE', 'Tamuz'),
156bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
157bbb76c12SGreg Roach                12 => I18N::translateContext('NOMINATIVE', 'Av'),
158bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
159bbb76c12SGreg Roach                13 => I18N::translateContext('NOMINATIVE', 'Elul'),
16013abd6f3SGreg Roach            ];
161a25f0a04SGreg Roach        }
162a25f0a04SGreg Roach
1637bb2eb25SGreg Roach        if ($month === 7 && $leap_year) {
164a25f0a04SGreg Roach            return $translated_month_names[-7];
165a25f0a04SGreg Roach        }
166b2ce94c6SRico Sonntag
1677bb2eb25SGreg Roach        return $translated_month_names[$month];
168a25f0a04SGreg Roach    }
169a25f0a04SGreg Roach
17076692c8bSGreg Roach    /**
17176692c8bSGreg Roach     * Full month name in genitive case.
17276692c8bSGreg Roach     *
1737bb2eb25SGreg Roach     * @param int  $month
17476692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
17576692c8bSGreg Roach     *
17676692c8bSGreg Roach     * @return string
17776692c8bSGreg Roach     */
1787bb2eb25SGreg Roach    protected function monthNameGenitiveCase(int $month, bool $leap_year): string
179c1010edaSGreg Roach    {
180a25f0a04SGreg Roach        static $translated_month_names;
181a25f0a04SGreg Roach
182a25f0a04SGreg Roach        if ($translated_month_names === null) {
18313abd6f3SGreg Roach            $translated_month_names = [
184a25f0a04SGreg Roach                0  => '',
185bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
186bbb76c12SGreg Roach                1  => I18N::translateContext('GENITIVE', 'Tishrei'),
187bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
188bbb76c12SGreg Roach                2  => I18N::translateContext('GENITIVE', 'Heshvan'),
189bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
190bbb76c12SGreg Roach                3  => I18N::translateContext('GENITIVE', 'Kislev'),
191bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
192bbb76c12SGreg Roach                4  => I18N::translateContext('GENITIVE', 'Tevet'),
193bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
194bbb76c12SGreg Roach                5  => I18N::translateContext('GENITIVE', 'Shevat'),
195bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
196bbb76c12SGreg Roach                6  => I18N::translateContext('GENITIVE', 'Adar I'),
197bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
198bbb76c12SGreg Roach                7  => I18N::translateContext('GENITIVE', 'Adar'),
199bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
200bbb76c12SGreg Roach                -7 => I18N::translateContext('GENITIVE', 'Adar II'),
201bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
202bbb76c12SGreg Roach                8  => I18N::translateContext('GENITIVE', 'Nissan'),
203bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
204bbb76c12SGreg Roach                9  => I18N::translateContext('GENITIVE', 'Iyar'),
205bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
206bbb76c12SGreg Roach                10 => I18N::translateContext('GENITIVE', 'Sivan'),
207bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
208bbb76c12SGreg Roach                11 => I18N::translateContext('GENITIVE', 'Tamuz'),
209bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
210bbb76c12SGreg Roach                12 => I18N::translateContext('GENITIVE', 'Av'),
211bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
212bbb76c12SGreg Roach                13 => I18N::translateContext('GENITIVE', 'Elul'),
21313abd6f3SGreg Roach            ];
214a25f0a04SGreg Roach        }
215a25f0a04SGreg Roach
2167bb2eb25SGreg Roach        if ($month === 7 && $leap_year) {
217a25f0a04SGreg Roach            return $translated_month_names[-7];
218a25f0a04SGreg Roach        }
219b2ce94c6SRico Sonntag
2207bb2eb25SGreg Roach        return $translated_month_names[$month];
221a25f0a04SGreg Roach    }
222a25f0a04SGreg Roach
22376692c8bSGreg Roach    /**
22476692c8bSGreg Roach     * Full month name in locative case.
22576692c8bSGreg Roach     *
2267bb2eb25SGreg Roach     * @param int  $month
22776692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
22876692c8bSGreg Roach     *
22976692c8bSGreg Roach     * @return string
23076692c8bSGreg Roach     */
2317bb2eb25SGreg Roach    protected function monthNameLocativeCase(int $month, bool $leap_year): string
232c1010edaSGreg Roach    {
233a25f0a04SGreg Roach        static $translated_month_names;
234a25f0a04SGreg Roach
235a25f0a04SGreg Roach        if ($translated_month_names === null) {
23613abd6f3SGreg Roach            $translated_month_names = [
237a25f0a04SGreg Roach                0  => '',
238bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
239bbb76c12SGreg Roach                1  => I18N::translateContext('LOCATIVE', 'Tishrei'),
240bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
241bbb76c12SGreg Roach                2  => I18N::translateContext('LOCATIVE', 'Heshvan'),
242bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
243bbb76c12SGreg Roach                3  => I18N::translateContext('LOCATIVE', 'Kislev'),
244bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
245bbb76c12SGreg Roach                4  => I18N::translateContext('LOCATIVE', 'Tevet'),
246bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
247bbb76c12SGreg Roach                5  => I18N::translateContext('LOCATIVE', 'Shevat'),
248bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
249bbb76c12SGreg Roach                6  => I18N::translateContext('LOCATIVE', 'Adar I'),
250bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
251bbb76c12SGreg Roach                7  => I18N::translateContext('LOCATIVE', 'Adar'),
252bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
253bbb76c12SGreg Roach                -7 => I18N::translateContext('LOCATIVE', 'Adar II'),
254bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
255bbb76c12SGreg Roach                8  => I18N::translateContext('LOCATIVE', 'Nissan'),
256bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
257bbb76c12SGreg Roach                9  => I18N::translateContext('LOCATIVE', 'Iyar'),
258bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
259bbb76c12SGreg Roach                10 => I18N::translateContext('LOCATIVE', 'Sivan'),
260bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
261bbb76c12SGreg Roach                11 => I18N::translateContext('LOCATIVE', 'Tamuz'),
262bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
263bbb76c12SGreg Roach                12 => I18N::translateContext('LOCATIVE', 'Av'),
264bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
265bbb76c12SGreg Roach                13 => I18N::translateContext('LOCATIVE', 'Elul'),
26613abd6f3SGreg Roach            ];
267a25f0a04SGreg Roach        }
268a25f0a04SGreg Roach
2697bb2eb25SGreg Roach        if ($month === 7 && $leap_year) {
270a25f0a04SGreg Roach            return $translated_month_names[-7];
271a25f0a04SGreg Roach        }
272b2ce94c6SRico Sonntag
2737bb2eb25SGreg Roach        return $translated_month_names[$month];
274a25f0a04SGreg Roach    }
275a25f0a04SGreg Roach
27676692c8bSGreg Roach    /**
27776692c8bSGreg Roach     * Full month name in instrumental case.
27876692c8bSGreg Roach     *
2797bb2eb25SGreg Roach     * @param int  $month
28076692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
28176692c8bSGreg Roach     *
28276692c8bSGreg Roach     * @return string
28376692c8bSGreg Roach     */
2847bb2eb25SGreg Roach    protected function monthNameInstrumentalCase(int $month, bool $leap_year): string
285c1010edaSGreg Roach    {
286a25f0a04SGreg Roach        static $translated_month_names;
287a25f0a04SGreg Roach
288a25f0a04SGreg Roach        if ($translated_month_names === null) {
28913abd6f3SGreg Roach            $translated_month_names = [
290a25f0a04SGreg Roach                0  => '',
291bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
292bbb76c12SGreg Roach                1  => I18N::translateContext('INSTRUMENTAL', 'Tishrei'),
293bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
294bbb76c12SGreg Roach                2  => I18N::translateContext('INSTRUMENTAL', 'Heshvan'),
295bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
296bbb76c12SGreg Roach                3  => I18N::translateContext('INSTRUMENTAL', 'Kislev'),
297bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
298bbb76c12SGreg Roach                4  => I18N::translateContext('INSTRUMENTAL', 'Tevet'),
299bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
300bbb76c12SGreg Roach                5  => I18N::translateContext('INSTRUMENTAL', 'Shevat'),
301bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
302bbb76c12SGreg Roach                6  => I18N::translateContext('INSTRUMENTAL', 'Adar I'),
303bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
304bbb76c12SGreg Roach                7  => I18N::translateContext('INSTRUMENTAL', 'Adar'),
305bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
306bbb76c12SGreg Roach                -7 => I18N::translateContext('INSTRUMENTAL', 'Adar II'),
307bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
308bbb76c12SGreg Roach                8  => I18N::translateContext('INSTRUMENTAL', 'Nissan'),
309bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
310bbb76c12SGreg Roach                9  => I18N::translateContext('INSTRUMENTAL', 'Iyar'),
311bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
312bbb76c12SGreg Roach                10 => I18N::translateContext('INSTRUMENTAL', 'Sivan'),
313bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
314bbb76c12SGreg Roach                11 => I18N::translateContext('INSTRUMENTAL', 'Tamuz'),
315bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
316bbb76c12SGreg Roach                12 => I18N::translateContext('INSTRUMENTAL', 'Av'),
317bbb76c12SGreg Roach                /* I18N: a month in the Jewish calendar */
318bbb76c12SGreg Roach                13 => I18N::translateContext('INSTRUMENTAL', 'Elul'),
31913abd6f3SGreg Roach            ];
320a25f0a04SGreg Roach        }
321a25f0a04SGreg Roach
3227bb2eb25SGreg Roach        if ($month === 7 && $leap_year) {
323a25f0a04SGreg Roach            return $translated_month_names[-7];
324a25f0a04SGreg Roach        }
325b2ce94c6SRico Sonntag
3267bb2eb25SGreg Roach        return $translated_month_names[$month];
327a25f0a04SGreg Roach    }
328a25f0a04SGreg Roach
32976692c8bSGreg Roach    /**
33076692c8bSGreg Roach     * Abbreviated month name
33176692c8bSGreg Roach     *
3327bb2eb25SGreg Roach     * @param int  $month
33376692c8bSGreg Roach     * @param bool $leap_year Some calendars use leap months
33476692c8bSGreg Roach     *
33576692c8bSGreg Roach     * @return string
33676692c8bSGreg Roach     */
3377bb2eb25SGreg Roach    protected function monthNameAbbreviated(int $month, bool $leap_year): string
338c1010edaSGreg Roach    {
3397bb2eb25SGreg Roach        return $this->monthNameNominativeCase($month, $leap_year);
340a25f0a04SGreg Roach    }
341a25f0a04SGreg Roach
34276692c8bSGreg Roach    /**
34376692c8bSGreg Roach     * Which months follows this one? Calendars with leap-months should provide their own implementation.
34476692c8bSGreg Roach     *
345e2052359SGreg Roach     * @return int[]
34676692c8bSGreg Roach     */
347fe11e66dSGreg Roach    protected function nextMonth(): array
348c1010edaSGreg Roach    {
349e364afe4SGreg Roach        if ($this->month === 6 && !$this->isLeapYear()) {
350c1010edaSGreg Roach            return [
3514a83f5d7SGreg Roach                $this->year,
352c1010edaSGreg Roach                8,
353c1010edaSGreg Roach            ];
354b2ce94c6SRico Sonntag        }
355b2ce94c6SRico Sonntag
356c1010edaSGreg Roach        return [
357e364afe4SGreg Roach            $this->year + ($this->month === 13 ? 1 : 0),
3584a83f5d7SGreg Roach            ($this->month % 13) + 1,
359c1010edaSGreg Roach        ];
360a25f0a04SGreg Roach    }
361a25f0a04SGreg Roach}
362