# πŸ“ Avalon MediaCard β€” АрхитСктурноС руководство ΠΈ тСхничСский ΠΎΠ±Π·ΠΎΡ€

English β€’ Русский

Π’ Π΄Π°Π½Π½ΠΎΠΌ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описаны Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠ΅ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π½Ρ‹Π΅ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Ρ‹, топология систСмы, ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° Π²ΠΈΠ΄Π΅ΠΎΠΏΠ»Π΅Π΅Ρ€ΠΎΠ² ΠΈ ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ **Avalon MediaCard**. --- ## πŸ›οΈ ВысокоуровнСвая Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° систСмы ΠŸΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° Avalon MediaCard построСна Π½Π° ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°Ρ… **Чистой АрхитСктуры (Clean Architecture)** Π² Ρ€Π°ΠΌΠΊΠ°Ρ… Π΅Π΄ΠΈΠ½ΠΎΠΉ ΠΊΠΎΠ΄ΠΎΠ²ΠΎΠΉ Π±Π°Π·Ρ‹ Π½Π° **Kotlin Multiplatform (KMP)**: ```mermaid graph TD subgraph Clients["Π‘Π»ΠΎΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² (Compose Multiplatform)"] W["Π’Π΅Π±-ΠΊΠ»ΠΈΠ΅Π½Ρ‚
(WasmGC + JS)"] D["ДСсктоп-ΠΊΠ»ΠΈΠ΅Π½Ρ‚
(JVM: Linux / Windows / macOS)"] A["Android TV & Π‘ΠΌΠ°Ρ€Ρ‚Ρ„ΠΎΠ½Ρ‹
(10-Foot D-Pad UI)"] end subgraph Core["Π‘Π΅Ρ€Π²Π΅Ρ€Π½ΠΎΠ΅ ядро Avalon (Ktor 3.x / Netty)"] RPC["Шлюз сигналинга Kotlin-RPC
(WebSockets)"] SDUI["ΠšΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ΠΎΡ€ манифСстов ΠΈ слотов SDUI"] REC["Π’Π΅ΠΊΡ‚ΠΎΡ€Π½Ρ‹ΠΉ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π΄Π²ΠΈΠΆΠΎΠΊ
(Affinity & Decay Math)"] DB[("Π‘Π»ΠΎΠΉ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…
(PostgreSQL 17+ / SQLite via Exposed)")] end subgraph Contract["ΠžΠ±Ρ‰ΠΈΠΉ ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ ΠΈ SDK"] SDK["avalon-media-card-core-contract
(Π•Π΄ΠΈΠ½Ρ‹ΠΉ источник истины)"] end subgraph Plugins["Π˜Π·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½Π°Ρ срСда ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ²"] P1["Π Π΅Π·ΠΎΠ»Π²Π΅Ρ€Ρ‹ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ…"] P2["P2P ΠΈ ΠΊΠ΅ΡˆΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠΎΠ½Π½Π΅ΠΊΡ‚ΠΎΡ€Ρ‹"] P3["ΠŸΡ€ΠΎΠΊΡΠΈ стримов ΠΈ балансСров"] end W <==>|"Двусторонний RPC-сигналинг"| RPC D <==>|"Двусторонний RPC-сигналинг"| RPC A <==>|"Двусторонний RPC-сигналинг"| RPC RPC <--> SDUI RPC <--> REC SDUI <--> DB REC <--> DB Core <-->|"Π˜Π·ΠΎΠ»ΡΡ†ΠΈΡ ClassLoader Π²ΠΎ врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹"| Contract Contract --- P1 Contract --- P2 Contract --- P3 ``` --- ## 🎬 Π£Π½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° Π²ΠΈΠ΄Π΅ΠΎΠΏΠ»Π΅Π΅Ρ€ΠΎΠ² Π’Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹Π΅ мСдиасСрвСры (Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Plex ΠΈΠ»ΠΈ Jellyfin) ΡΠΎΠ·Π΄Π°ΡŽΡ‚ ΠΊΠΎΠ»ΠΎΡΡΠ°Π»ΡŒΠ½ΡƒΡŽ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π½Π° процСссор хоста Π·Π° счСт постоянного транскодирования Π²ΠΈΠ΄Π΅ΠΎ, прСобразования Π°ΡƒΠ΄ΠΈΠΎΠ΄ΠΎΡ€ΠΎΠΆΠ΅ΠΊ ΠΈ «впСкания» слоТных Π²Π΅ΠΊΡ‚ΠΎΡ€Π½Ρ‹Ρ… `.ass/.ssa` субтитров. Π’ Avalon MediaCard Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ ΠΈΠ½ΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ β€” **Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° с Π½ΡƒΠ»Π΅Π²Ρ‹ΠΌ транскодированиСм Π½Π° сСрвСрС**: 100% дСкодирования ΠΈ отобраТСния субтитров выполняСтся Π½Π° ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ устройствС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Ρ‡Π΅Ρ€Π΅Π· Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ Π΄Π²ΠΈΠΆΠΊΠΈ: | ЦСлСвая ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° | Основной Π΄Π²ΠΈΠΆΠΎΠΊ | АппаратноС ускорСниС | ΠžΡ‚Ρ€ΠΈΡΠΎΠ²ΠΊΠ° субтитров | ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ возмоТности | |---|---|---|---|---| | **ПК (Desktop)**
*(Linux / Windows / macOS)* | **LibMPV**
*(Ρ‡Π΅Ρ€Π΅Π· JNA C-Interop)* | VAAPI, NVDEC, D3D11VA, VideoToolbox | Нативный пиксСль-ΠΏΠ΅Ρ€Ρ„Π΅ΠΊΡ‚Π½Ρ‹ΠΉ ASS/SSA | ΠŸΡ€ΡΠΌΠΎΠΉ JNA-мост ΠΊ памяти Π±Π΅Π· ΠΎΠ²Π΅Ρ€Ρ…Π΅Π΄Π°, HDR tone mapping, ΠΌΠ³Π½ΠΎΠ²Π΅Π½Π½ΠΎΠ΅ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π΄ΠΎΡ€ΠΎΠΆΠ΅ΠΊ, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π»ΡŽΠ±Ρ‹Ρ… ΠΊΠΎΠ΄Π΅ΠΊΠΎΠ². | | **Android & Android TV**
*(Π’Π’, ΠΏΠ»Π°Π½ΡˆΠ΅Ρ‚Ρ‹, смартфоны)* | **AndroidX Media3**
*(ExoPlayer + FFmpeg Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ)* | Android MediaCodec API | Media3 Native + Custom Overlay | **100% оптимизация ΠΏΠΎΠ΄ ΠΏΡƒΠ»ΡŒΡ‚Ρ‹ (D-Pad)**, Leanback 10-foot интСрфСйс, встроСнныС Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ FFmpeg для Π°ΡƒΠ΄ΠΈΠΎ/Π²ΠΈΠ΄Π΅ΠΎ. | | **Π’Π΅Π± (Web)**
*(WasmGC ΠΈ соврСмСнныС Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρ‹)* | **PlaysVideo / Mediabunny**
*(HLS, DASH, MPEG-TS, MP4)* | WebGL / Canvas Direct Draw | WebVTT / ASS.js Canvas | **Π’Π½ΡƒΡ‚Ρ€ΠΈΠ±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½Ρ‹ΠΉ Wasm-FFmpeg транскодСр:** ΠšΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Π² Web Worker ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ HEVC/AC3/E-AC3/DTS прямо Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ ΠΏΡ€ΠΈ **Π½ΡƒΠ»Π΅Π²ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ Π½Π° сСрвСр**. | --- ## πŸ–₯️ Π‘Π΅Ρ€Π²Π΅Ρ€Π½Ρ‹ΠΉ слой (Backend) * **Π€Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ ΠΈ транспорт:** **Ktor 3.x** Π½Π° Π΄Π²ΠΈΠΆΠΊΠ΅ Netty с Π΄Π²ΡƒΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΌ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠΌ **Kotlin-RPC (`kotlinx-rpc`)** ΠΏΠΎΠ²Π΅Ρ€Ρ… WebSockets. * **Π‘Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ORM:** SQLite / PostgreSQL 17+ ΠΏΠΎΠ΄ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ **JetBrains Exposed ORM**. ВсС запросы ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… `newSuspendedTransaction(Dispatchers.IO)`. Π’Ρ‹Π·ΠΎΠ²Ρ‹ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½. * **ΠœΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ Π²Π΅ΠΊΡ‚ΠΎΡ€Π½Ρ‹ΠΉ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π΄Π²ΠΈΠΆΠΎΠΊ:** РассчитываСт ΠΌΠ½ΠΎΠ³ΠΎΠΌΠ΅Ρ€Π½Ρ‹Π΅ Π²Π΅ΠΊΡ‚ΠΎΡ€Ρ‹ близости интСрСсов ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΏΠΎ ΠΆΠ°Π½Ρ€Π°ΠΌ, Ρ‚Π΅Π³Π°ΠΌ, рСТиссСрам, актСрскому составу, Π³ΠΎΠ΄Π°ΠΌ выпуска, Ρ‚Π΅ΠΌΠΏΡƒ ΠΈ Π½Π°ΡΡ‚Ρ€ΠΎΠ΅Π½ΠΈΡŽ. ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅Ρ‚ ΡΠΊΡΠΏΠΎΠ½Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ Π·Π°Ρ‚ΡƒΡ…Π°Π½ΠΈΠ΅ для старых просмотров ΠΈ Ρ„Π°ΠΊΡ‚ΠΎΡ€ случайных Π½Π°Ρ…ΠΎΠ΄ΠΎΠΊ (serendipity) для формирования динамичСских ΠΏΠΎΠ»ΠΎΠΊ. * **Π”Π²ΠΈΠΆΠΎΠΊ совмСстного просмотра (Watch Party):** УправляСт ΠΊΠΎΠΌΠ½Π°Ρ‚Π°ΠΌΠΈ совмСстного просмотра с компСнсациСй сСтСвых Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ, синхронизациСй ΠΎΠΏΠΎΡ€Π½Ρ‹Ρ… Ρ‚Π°ΠΉΠΌΠΊΠΎΠ΄ΠΎΠ² (anchor positions) ΠΈ прСдстартовым Π»ΠΎΠ±Π±ΠΈ со статусами участников (*Β«Π‘ΠΌΠΎΡ‚Ρ€ΡŽ ΠΌΠΎΠ»Ρ‡Π°Β»*, *Β«Π“ΠΎΡ‚ΠΎΠ² ΠΎΠ±ΡΡƒΠΆΠ΄Π°Ρ‚ΡŒΒ»*). --- ## 🧩 Π˜Π·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½Π°Ρ срСда выполнСния ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² Π‘Π΅Ρ€Π²Π΅Ρ€ динамичСски ΠΏΠΎΠ΄Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΏΠ»Π°Π³ΠΈΠ½Ρ‹ ΠΈΠ· ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° `plugins/` ΠΏΡ€ΠΈ запускС ΠΈΠ»ΠΈ Β«Π½Π° Π»Π΅Ρ‚ΡƒΒ» (hot-reload) Ρ‡Π΅Ρ€Π΅Π· панСль администратора: 1. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠ»Π°Π³ΠΈΠ½ `.jar` инстанциируСтся Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅ΠΌ экзСмплярС `URLClassLoader`. 2. ΠŸΠ»Π°Π³ΠΈΠ½Ρ‹ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚ с ядром строго Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ [`avalon-media-card-core-contract`](https://github.com/ensodai/avalon-media-card-core-contract) (интСрфСйсы `AvalonPlugin`, `PluginContext`). 3. ΠŸΡ€ΠΈ сбоС ΠΈΠ»ΠΈ Π½Π΅ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‡Π΅Π½Π½ΠΎΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ Π² стороннСм ΠΊΠΎΠ΄Π΅ ΠΏΠ»Π°Π³ΠΈΠ½ изолируСтся, прСдотвращая ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅ всСго сСрвСра. 4. Горячая ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π²Ρ‹Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ClassLoader старой вСрсии, освобоТдая рСсурсы, ΠΈ запускаСт ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π±Π΅Π· ΠΎΠ±Ρ€Ρ‹Π²Π° Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… воспроизвСдСний. --- ## πŸ“± ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠΈΠΉ слой (UI) * **100% ΠΎΠ±Ρ‰ΠΈΠΉ Π³Ρ€Π°Ρ„ Compose Multiplatform:** Единая Π΄ΠΈΠ·Π°ΠΉΠ½-систСма, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈ навигация скомпилированы ΠΈΠ· ΠΎΠ±Ρ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° для Desktop JVM, Web (WasmGC) ΠΈ Android. * **Server-Driven UI (SDUI):** Π­ΠΊΡ€Π°Π½Ρ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‚ΡΡ сСрвСром динамичСски ΠΈΠ· ΡƒΠ·Π»ΠΎΠ²-слотов (`HeroBanner`, `Carousel`, `ExploreGrid`, `DetailsView`). ОбновлСния структуры экрана ΠΈ состояний ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ Π² Π²ΠΈΠ΄Π΅ Ρ€Π΅Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… Flow Ρ‡Π΅Ρ€Π΅Π· WebSocket. * **ΠžΠΏΡ‹Ρ‚ 10-Foot TV:** Наэкранный интСрфСйс Android TV спроСктирован с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ фокусировки ΠΏΡƒΠ»ΡŒΡ‚ΠΎΠΌ (D-Pad ΠΊΠΎΠ»ΡŒΡ†Π° фокуса, анимация ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡Π΅ΠΊ, Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ списки эпизодов). --- ## πŸ› οΈ Π‘Π±ΠΎΡ€ΠΊΠ° всСй экосистСмы ΠΈΠ· исходного ΠΊΠΎΠ΄Π° ### БистСмныС трСбования * JDK 21+ (рСкомСндуСтся OpenJDK ΠΈΠ»ΠΈ Eclipse Temurin) * Android SDK (build-tools 35+, platform 35) для сборки Android * Node.js & Yarn (Gradle устанавливаСт ΠΈ настраиваСт ΠΈΡ… автоматичСски для Ρ‚Π°Ρ€Π³Π΅Ρ‚ΠΎΠ² Wasm/JS) ### ΠšΠΎΠΌΠ°Π½Π΄Ρ‹ сборки ```bash # 1. ΠšΠ»ΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ рСпозитория git clone https://github.com/ensodai/avalon-media-card.git cd avalon-media-card # 2. Настройка ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ окруТСния cp .env.example .env # 3. Запуск сСрвСра Ktor ./gradlew :server:run # 4. Запуск дСсктопного прилоТСния (JVM) ./gradlew :desktopApp:run # 5. Π‘Π±ΠΎΡ€ΠΊΠ° Ρ€Π΅Π»ΠΈΠ·Π½ΠΎΠ³ΠΎ APK для Android ./gradlew :androidApp:assembleRelease # 6. Π‘Π±ΠΎΡ€ΠΊΠ° WebAssembly Π±Π°Π½Π΄Π»Π° для Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° ./gradlew :web:wasmJsBrowserDistribution ``` --- ## πŸ“š Бвязанная докумСнтация * [Основной README](README.ru.md) β€” Быстрый запуск ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. * [SDK ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π° ядра](https://github.com/ensodai/avalon-media-card-core-contract) β€” Полная спСцификация для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ², слотов SDUI ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² RPC.