"""Wertykały: treść, która żyje w osobnej sekcji apki, nie w głównym feedzie. Wertykał to zbiór originów, których treść **nie miesza się** z zachodnim katalogiem: osobny namespace tytułów, osobne słownictwo tagów, brak dedupu między wertykałem a resztą. Dlatego nie chcemy ich w jednym strumieniu, tak samo jak nie chcemy mieszać JAV z zachodnimi scenami. **Dlaczego brama po originie jest pewna, a nie heurystyczna.** Scena z wertykału ma WYŁĄCZNIE originy tego wertykału, bo nie ma się z czym zdeduplikować. Zmierzone 2026-08-13: 9507 scen animowanych, **zero** z originem spoza listy. To znaczy, że `EXISTS(origin IN ...)` dzieli katalog dokładnie, bez fałszywych trafień w obie strony. **Dlaczego nie osobna baza.** Rozważane i odrzucone 2026-08-13: skoro rozdzielenie po originie jest dokładne, osobna baza kosztowałaby rozjazd migracji, backupów i wspólnych tabel performerów/tagów/dedupu, nie dając nic ponad to, co daje ta lista. **Tagi to samodzielny powód rozdzielenia.** Z 3116 tagów występujących przy scenach animowanych tylko 452 pojawiają się też poza animacją, czyli **85% to słownictwo wyłącznie animacyjne** (nazwy postaci, serie, gatunki rysunkowe). Bez rozdzielenia lista tagów w głównym feedzie ciągnie 2664 pozycje, których nie da się tam użyć. """ from __future__ import annotations #: JAV: kody typu BKD-368, tytuły po japońsku. Osobna zakładka od 2026-07. JAV_ORIGINS = ( "tube:javflix", "tube:javguru", "tube:vjav", "tube:supjav", ) #: Hentai i 3D. Dla animacji nie istnieje kanon (TPDB/StashDB nie mają rysowanych #: postaci), więc te sceny nie mają obsady i nigdy nie zmatchują się z zachodnimi. ANIMATION_ORIGINS = ( "tube:hentaimama", "tube:xanimeporn", "tube:hentaigasm", "tube:hentaiplay", "tube:rule34video", "tube:naughtymachinima", ) #: Nazwa wertykału → originy. Klucze są częścią kontraktu API (`?vertical=`). VERTICALS: dict[str, tuple[str, ...]] = { "jav": JAV_ORIGINS, "animation": ANIMATION_ORIGINS, } #: Wszystko, co ma NIE wchodzić do głównego feedu. ALL_VERTICAL_ORIGINS: tuple[str, ...] = JAV_ORIGINS + ANIMATION_ORIGINS def origins_for(vertical: str | None) -> tuple[str, ...]: """Originy wertykału. `None` → wszystkie originy wertykałowe (do wykluczania).""" if vertical is None: return ALL_VERTICAL_ORIGINS return VERTICALS.get(vertical, ())