fb57156ee9
listCalendars теперь забирает и cs:getctag (тот же PROPFIND — ноль лишних запросов; DavCalendar.ctag). Новый CalendarEventsCache — дисковый кэш СЫРЫХ REPORT-ответов per (аккаунт, календарь, диапазон), ключ — CTag: не менялся → события парсятся с диска (боевым парсером CalDavClient), REPORT-запросы в сеть не идут. Изменился → сеть + обновление кэша. Хранение сырого XML вместо сериализации моделей — без хрупкого JSON-маппинга ~20 полей события; чистка записей старше 30 дней. CalDavClient.queryEventsInRange разделён на queryEventsRawXml + parseEventsXml (поведение прежнее). Эффект: переключение месяцев, периодический рефреш и возврат в календарь при неизменных календарях — 1 PROPFIND вместо 1+N REPORT. +5 unit-тестов кэша (JVM, TemporaryFolder).