# Changelog

## W12-W16 — Karakter Stüdyosu Modernizasyonu (5-Sprint)

### Sprint 1 (W12) — InstantID + IPAdapter v2 Entegrasyonu

**Added**
- `nodes/character.py` → `_try_apply_instantid()`, `_try_apply_ipadapter_v2()`, `_apply_identity()` dispatcher
- `nodes/common.py` → `hf_download()` stub + `get_models_dir()`/`get_custom_nodes_dir()` utilities
- `nodes/endpoints.py` → `/check_instantid`, `/install_instantid` (+ status), `/check_ipadapter_v2`, `/install_ipadapter_v2` (+ status), `/check_identity` (tüm yöntemler özet)
- Karakter `meta.json` → `identity_method` alanı: `"auto" | "pulid" | "instantid" | "ipadapter_v2" | "none"` (default `"auto"`)
- Karakter modal UI → "🧬 Kimlik Yöntemi" dropdown + 3-yöntem readiness badge
- `_uploadCharacterPose`, `_refreshCharacterPoses`, `_refreshIdentityBadge`, `_installIdentityMethod`, `_generatePreviewLightning`, `_generateVariantsBatch` panel metodları

**Changed**
- `ImageGen._get_patched_model` → PuLID hardcode yerine `_apply_identity` dispatcher kullanır (karakter `identity_method`'una göre yönlendirir)
- `_save_character` → `identity_method` defaults to `"auto"` (additive, geriye dönük uyumlu)
- `/character/{cid}/meta` whitelist'e `identity_method` eklendi

**External**
- InstantID: `cubiq/ComfyUI_InstantID` + InstantX HF models (~1.7GB)
- IPAdapter v2: `cubiq/ComfyUI_IPAdapter_plus` + h94 FaceID-Plus-v2 (~150MB SDXL)

### Sprint 2 (W13) — ControlNet Union + DWPose Pipeline

**Added**
- `nodes/visual.py` → `_try_apply_controlnet_union()` helper (pose+canny+depth+softedge tek slotta)
- Yeni node: `FikoYT_MVD_PoseExtractor` (DWPose öncelikli, fallback OpenPose)
- Yeni node: `FikoYT_MVD_ControlNetUnion` (4 mod toggle + per-mode weight)
- `nodes/endpoints.py` → `/check_dwpose`, `/install_dwpose`, `/check_cn_union`, `/install_cn_union` (Flux Pro / Flux InstantX / SDXL variant'lar)
- Pose library: `meta.pose_library[]` + `/character/{cid}/poses` (GET/POST/DELETE) + auto DWPose extract
- Karakter modal UI → "🦴 POZ KÜTÜPHANESİ" bölümü (yükle → otomatik iskelet → sil)

**External**
- `Fannovel16/comfyui_controlnet_aux` (DWPose) + onnxruntime
- ControlNet Union: `Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro` veya `InstantX/FLUX.1-dev-Controlnet-Union` veya `xinsir/controlnet-union-sdxl-1.0`

### Sprint 3 (W14) — Regional Prompting 3-4 Char + Mask Editör

**Added**
- `workflow/flux_regional_3char.json` (3 mask + 3 prompt + base)
- `workflow/flux_regional_4char.json` (4 mask + 4 prompt + base)
- Yeni node: `FikoYT_MVD_RegionalMultiChar` (2/3/4 char tek code path)
- `/fikoyt_mvd/regional_multichar_generate` endpoint (polygon mask + per-char prompt/lora/identity_method)
- `web/js/mvd/components/mask-editor.js` → Polygon mask editör (HTML5 canvas, vertex drag, bezier handles, grid snap, rect/hex presets, PNG export)
- `openMaskEditorModal({width, height, initial})` modal helper

### Sprint 4 (W15) — Karakter Stüdyosu Derinleştirme

**Added**
- `nodes/character.py` → `_try_apply_reactor()` face swap helper (opt-in, graceful fallback)
- LoRA versiyonlama: `_lora_versions/<UTC-timestamp>/` snapshot + `meta.lora_versions[]`
- Endpoint'ler: `/character/{cid}/lora_versions` (GET), `.../snapshot` (POST), `.../{ts}/activate` (POST)
- Outfit referans görseli: `/character/{cid}/outfits/{oid}/reference` (multipart upload)
- Expression library: `meta.expressions[]` + `/character/{cid}/expressions` (GET/POST/DELETE)
- Character style transfer: `meta.style_transfer{source_id, strength, enabled}` + `/character/{cid}/style_transfer` endpoint
- ReActor durum: `/check_reactor` (lisans uyarısıyla)

### Sprint 5 (W16) — Performans + UX (Hafif)

**Added**
- `nodes/common.py` → `_should_use_schnell(vram_threshold, user_speed_mode)` dispatcher
- Yeni node: `FikoYT_MVD_LightningPreview` (SDXL Lightning 4-step LoRA enjeksiyonu)
- Endpoint'ler: `/sys/vram_info`, `/preview_lightning`, `/generate_variants`, `/project/{name}/gallery`, `/project/{name}/gallery/favorite`
- HuggingFace download utility temelleri (`hf_download` Sprint 5'te tam doluyor — şimdi stub + endpoints'te kullanılıyor)

**Cross-Sprint Refactor**
- `nodes/__init__.py` → visual.py'dan ek node mapping'leri merge eder (NODE_CLASS_MAPPINGS_VISUAL_EXTRA + display)
- Yeni kod kuralı: `_legacy.py`'a yeni kod eklenmez — yeni helper'lar character/visual/common/endpoints'e yazılır
- `_legacy.py` PuLID install pattern'i Sprint 1'in `_generic_hf_install` generic'inde tekrar kullanılır (Sprint 5'te tam refaktör)

**Tests**
- `tests/smoke/sprint_1.py` — character helpers + dispatcher + common utilities
- `tests/smoke/sprint_2_5.py` — visual node'ları + workflow templates + regional validation + mask-editor varlık kontrolü

**Documentation**
- `CHANGELOG.md` (bu dosya)
- README'ye karakter studio yeni özellik bölümleri eklendi (aşağıda)

---

## Sprint 6 — Music Video Production Pipeline

**Hedef:** Klibi gerçek bir müzik klibi yapan profesyonel + verimli production halkaları.

**Added — Yeni Node'lar**
- `FikoYT_MVD_ProfessionalGrade` — 7 LUT preset (cinematic/vintage/vibrant/teal_orange/noir/warm/cool) + vignette (intensity+falloff) + chromatic aberration + letterbox (2.35/2.39/2.76)
- `FikoYT_MVD_AspectPreset` — TikTok/Reels/Insta/YouTube/4K/Cinematic preset → width/height/ratio
- `FikoYT_MVD_MasterRender` — FFmpeg ile tüm segment video + audio + fade in/out + chapter markers → master MP4 (CRF/preset opsiyonu)

**Added — Helper'lar (`nodes/visual.py`)**
- `_apply_lut_3d(image, lut_name, strength)` — kanal-tabanlı 3D LUT yaklaşımı (shadow/midtone/highlight × R/G/B + saturation + contrast + lift)
- `_apply_vignette(image, intensity, falloff)` — radial mask
- `_apply_chromatic_aberration(image, intensity)` — R/B kanal kaydırma
- `_apply_letterbox(image, target_ratio)` — sinematik aspect bar
- `MUSIC_VIDEO_ASPECT_PRESETS` — 7 platform preset dict

**Added — Endpoint'ler**
- `GET /fikoyt_mvd/aspect_presets` — platform preset listesi
- `POST /fikoyt_mvd/project/{name}/aspect_preset` — proje meta'sına aspect kaydı (contain/cover/stretch strategy)
- `POST /fikoyt_mvd/project/{name}/style_lora` — proje-wide style consistency LoRA (filename, strength, trigger)
- `DELETE /fikoyt_mvd/project/{name}/style_lora` — style LoRA kaldır
- `POST /fikoyt_mvd/project/{name}/segment/{idx}/camera` — kamera hareketi metadata (static/pan_*/zoom_*/orbit_*/dolly_*/handheld/crane_*)
- `GET /fikoyt_mvd/project/{name}/beat_grid` — librosa ile tempo + beats[] + onsets[]
- `POST /fikoyt_mvd/project/{name}/snap_segments_to_beats` — segment.start_sec'leri beat'lere snap (tolerance_sec)
- `POST /fikoyt_mvd/project/{name}/render_all_images` (+status) — batch render state tracking
- `POST /fikoyt_mvd/project/{name}/master_render` (+status) — FFmpeg orchestration (audio + fade + scale/pad)
- `POST /fikoyt_mvd/segment/{idx}/lipsync_score` — MediaPipe Face Mesh mouth keypoint + librosa RMS envelope korelasyon (0-100 skor)

**Added — UI helper'lar (`character-actions.js`)**
- `_loadAspectPresets`, `_setProjectAspect`
- `_setProjectStyleLora`
- `_setSegmentCamera`
- `_loadBeatGrid`, `_snapSegmentsToBeats`
- `_masterRender`, `_pollMasterRenderStatus`
- `_lipsyncScore`

**External (opsiyonel)**
- `mediapipe` (lip-sync scoring için, pip install mediapipe)
- `librosa` zaten requirements.txt'te (beat grid)
- FFmpeg sistemde olmalı (path veya imageio_ffmpeg fallback — zaten var)

**Müzik Klibi İş Akışı (önerilen sıra)**
1. **Aspect seç**: `POST /aspect_preset` (örn: `tiktok_reels`) — proje boyutu kilitlenir
2. **Beat-sync**: `POST /snap_segments_to_beats` — segment'ler beat'e otomatik hizalanır
3. **Style LoRA**: `POST /style_lora` (proje-wide) — tüm sahnelerde ortak stil
4. **Karakter render**: identity_method + pose_library + outfit (Sprint 1/2/4)
5. **Segment kamera**: `POST /segment/{idx}/camera` (her segment için movement)
6. **Görsel render**: Variants grid (Sprint 5) → favorile → ProfessionalGrade
7. **Video render**: HuMo/LTX (her segment) → Lip-sync score (Sprint 6)
8. **Master render**: `POST /master_render` → final MP4 (FFmpeg + audio + fade)

---

## Sprint 7 — Character Test Lab & Pose Studio

**Hedef:** Kullanıcının karakteri sürekli iteratif test edebileceği + onayladığı görselleri tek tıkla kütüphaneye geri ekleyebileceği kapsamlı stüdyo.

**Added — Yeni Window'lar (ayrı UI)**
- **🧪 Character Test Lab** (`web/js/mvd/character-lab.js`):
  - Sol panel (380px): 8 preset prompt + custom textarea + identity override + identity weight + 4 aspect preset + steps/guidance + Lightning toggle + pose/outfit seçici + workflow loader inspector
  - Sağ panel: session-bazlı geçmiş, her session'da 4-16 variant grid (auto 2×2 / 3×3 / 4×4), her variant'a tıkla → lightbox
  - Her variant altında 4 onay butonu: 📚 **Referans** (refs/'e ekle), 🦴 **Pose** (pose_library + auto DWPose extract), ⭐ **Ana** (image_path override), 👗 **Outfit→** (outfits[oid].reference_image)
  - Session sil + variant sil + auto-poll (yeni session başladıysa 5sn'de bir refresh)
- **🦴 Pose Studio** (`web/js/mvd/character-lab.js`):
  - Drag-drop zone (birden fazla dosya batch upload + DWPose auto extract)
  - DWPose readiness banner + tek-tık install link
  - Mevcut pozlar grid: Pose/Source tab toggle + lightbox + label edit + Lab'da Kullan + Sil

**Added — Backend Endpoint'leri**
- `GET /fikoyt_mvd/test_lab/presets` — 8 prompt preset + 4 aspect preset listesi
- `POST /character/{cid}/test_lab/render` — N variant kuyruğa ekle (her seed farklı), `_build_test_workflow()` ile dinamik workflow JSON: CharacterRefsBatch + Flux loaders + identity dispatcher (PuLID/InstantID/IPAv2) + opsiyonel LoRA stack + opsiyonel Lightning LoRA + opsiyonel pose ControlNet Union + KSampler + SaveImage
- `GET /character/{cid}/test_lab/sessions` — session listesi + variant dosya tarama + approval state
- `DELETE /character/{cid}/test_lab/sessions/{ts}` — tüm session sil (manifest + render dosyaları)
- `DELETE /character/{cid}/test_lab/variants` — seçili variantları toplu sil
- `POST /character/{cid}/test_lab/approve` — variant'ı reference / pose / main / outfit referansı olarak kütüphaneye taşı; approval manifest'e kaydedilir

**Added — Helper'lar**
- `nodes/endpoints.py`: `TEST_PROMPT_PRESETS` (8 sahne: portrait_studio, full_body_standing, outdoor_natural, action_dynamic, stage_concert, side_profile, cinematic_dark, smile_casual), `TEST_ASPECT_DIMS` (portrait/landscape/square/tiktok)
- `_build_test_workflow()` — Identity method'a göre dinamik PuLID/IPAdapter zinciri, opsiyonel pose ControlNet Union, opsiyonel Lightning LoRA stack
- `_test_lab_dir(cid)` — `output/fikoyt_mvd/_characters/<cid>/test_lab/session_<ts>/`

**Added — UI Launcher**
- Karakter modal'ında eski "🧪 DENEME GÖRSELİ ÜRET" yerine yeni **🧪 KARAKTER LABORATUVARI** kutusu: 2 büyük launcher buton (🧪 Test Lab Aç + 🦴 Pose Studio Aç) + eski hızlı tek-shot test "Hızlı tek-shot test (collapsed)" altında saklı (backward-compat)

**İş Akışı**
1. Karakter Stüdyosu → karakter seç → 🧪 Test Lab Aç
2. Preset seç (örn: stage_concert) → variant=4 → 🎯 PuLID → 🚀 Test Üret
3. 30-60sn sonra sağda 4 variant grid'i belirir
4. Beğendiklerine 📚 Referans → ref'lere eklenir (LoRA training datasetine girer)
5. İyi pose'lara 🦴 Pose → pose_library + DWPose iskelet otomatik
6. En iyiye ⭐ Ana → karakterin yeni ana referansı olur
7. Bu döngüyü tekrarla → karakter sürekli zenginleşir, identity tutarlılığı artar

**Dosyalar**
- Yeni: `web/js/mvd/character-lab.js` (~620 satır)
- Genişletildi: `nodes/endpoints.py` (+~430 satır Test Lab), `web/js/mvd/actions/character-actions.js` (launcher + import)

---

## Sprint 8 — Mouse-Driven OpenPose Stick Figure Editor

**Hedef:** Pose Studio'da mouse'la keypoint'leri sürükleyerek poz çizebilme — OpenPose Editor benzeri.

**Added — Yeni Component**
- `web/js/mvd/components/pose-editor.js` (~470 satır)
  - `PoseEditor` class: HTML5 canvas, **18 keypoint COCO** format (OpenPose standardı)
  - **6 hazır şablon**: standing, sitting, arms_up, arms_crossed, dancing, t_pose
  - **OpenPose renkleri** (RGB) — ControlNet'e direkt uyumlu siyah arka plan + renkli stick figure
  - **Toolbar**: Şablon dropdown, ⇆ Flip H, ⤿ ±10° rotate, ➕/➖ büyüt/küçült, L↔R simetri toggle, Grid snap
  - **Mouse interaction**: Sürükle = pozisyon, **Shift+Click** = gizle/göster (occlusion), Sağ tık = keypoint ismi
  - **Symmetry lock**: Bir tarafı taşırken karşı kol/bacak otomatik simetrik hareket eder
  - PNG export — tam çözünürlükte (1024×1024 default) — ControlNet input formatında
  - `openPoseEditorModal({width, height, initial, label})` modal launcher (önizleme + kaydet butonları)

**Added — Pose Studio Entegrasyonu** (`character-lab.js`)
- Üst kısma 2-kolon grid: **drag-drop zone** (mevcut) + **✏ Sıfırdan Çiz** (yeni, mor gradient, büyük buton)
- Her pose card'a 3. buton: **✏ Düzenle** (mor) — mevcut pozun keypoints'lerini yükle, editör'de değiştir, yeni veya replace olarak kaydet
- `_uploadPoseFromEditor()` — Editor PNG blob'unu `/poses POST` endpoint'ine `auto_extract=false` + `keypoints_json` ile yollar
- `_editExistingPose()` — Mevcut pozun keypoints metadata'sını parse edip editör'e yükler (yoksa default standing)

**Changed — Backend (`endpoints.py`)**
- `/character/{cid}/poses` POST endpoint'i yeni `keypoints_json` multipart field'ı kabul eder
- `auto_extract=false` durumunda image zaten iskelet sayılır, `pose_path = source_path` set edilir (eskiden None'du)
- `source_label` alanı eklendi: `raw` | `drawn` | `dwpose_extract` | `raw_skeleton`
- Editor çıktıları manifest'e `keypoints_json` olarak yazılır → ileride tekrar düzenlenebilir

**Kullanım**
1. Karakter Stüdyosu → karakter → 🦴 Pose Studio Aç
2. **✏ Sıfırdan Çiz** → editör açılır, standing şablonu yüklü
3. Şablon değiştir (örn: dancing) veya keypoint'leri sürükle
4. Etiket yaz (örn: "sahne-dans-poz-1") → ✓ Kaydet
5. Pose kütüphaneye eklenir → Test Lab'da "Poz Seç" dropdown'undan kullan
6. Mevcut pose üzerine **✏ Düzenle** → keypoints yüklenir, değiştir, replace/yeni olarak kaydet

**ControlNet Uyumu**
- Çıkış PNG'si OpenPose standardında (siyah BG + renkli stick figure)
- `FikoYT_MVD_ControlNetUnion` node'unda `enable_pose=True` ile doğrudan kullanılır
- Test Lab'da `pose_ref_id` parametresi ile her render bu pose'a snap eder

---

## Sprint 9 — Window/Modal Z-Index Sistemi Düzeltmesi

**Bug:** Pose editör (z-index 10.000) ve mask editör window'ların (2 milyar+) ALTINDA kalıyordu. Bazı pencereler tıklanınca öne gelmiyordu. Sihirbaz paneli (2.147.483.500) açıkken floating window'lar arkada kalıyordu.

**Fix — 3-Katmanlı Z-Index Sistemi (`windows.js`)**
- **Window katmanı**: `2.000.000.000 - 2.146.999.999` (~146M slot, bringToFront her tıklamada artırır) — sihirbaz panelinden üstte
- **Detail modal katmanı**: `2.147.000.000 - 2.147.299.999` (~300K slot) — karakter detay vb.
- **Editor modal katmanı**: `2.147.300.000 - 2.147.483.630` (~183K slot) — pose/mask editor (EN ÜST)
- Counter sınıra yaklaşırsa otomatik rebalance/reset

**Yeni API**
- `nextWindowZ()`, `nextDetailModalZ()`, `nextEditorModalZ()` — katmanlı z-index dağıtımı
- `registerModal(overlay, layer)` — modal'ı kayıt et + z-index ata (layer: "detail" | "editor")
- `unregisterModal(overlay)` — kayıttan çıkar
- `bringModalToFront(overlay)` — modal'ı aynı katmanda öne getir
- `bringToFront(id)` — window'a "fmvd-win-active" CSS class ekler (görsel vurgu için)

**Click-to-Front İyileştirmesi**
- Document-level capture phase'de **3 event** dinleniyor: `pointerdown`, `mousedown`, `focusin` (input focus dahil)
- Window root'una **4 event** capture listener: `mousedown`, `pointerdown`, `touchstart`, `focusin`
- Modal overlay tıklamasında otomatik `bringModalToFront`
- Editor modal backdrop tıklamasında (ESC dahil) onay isteyip kapatır

**Component Entegrasyonu**
- `pose-editor.js`: `registerModal(overlay, "editor")` + ESC tuşu + backdrop click + box `stopPropagation`
- `mask-editor.js`: aynı entegrasyon
- `character-actions.js`: karakter detail modal `registerModal(bg, "detail")` + ESC + backdrop click
- Eski hardcoded `z-index: 10000` ve `z-index: 2147483800` değerleri kaldırıldı

**Sonuç**
- ✓ Pose editor her zaman tüm window'ların üstünde açılır
- ✓ Window'lar birbirine tıklanınca güvenilir öne gelir (touch + pointer + focus)
- ✓ Sihirbaz paneli açıkken floating window'lar arkada kalmaz
- ✓ Birden fazla modal aynı anda açıksa son tıklanan en üstte
- ✓ ESC tuşu tüm editor modal'larını kapatır

---

## Sprint 10 — Pose/Mask Editor Canvas Hit-Test Fix

**Bug:** Pose editör'de keypoint'lere tıklayıp sürükleyemiyor, **boş yerlerde yuvarlaklar aktif oluyordu**.

**Kök Neden:** Modal box `display:flex; flex-direction:column` ile birlikte default `align-items:stretch` davranışı canvas'ı CSS olarak ENİNE GERİYORDU. Sonuç:
- Canvas drawing buffer: 560×560 (sabit)
- Canvas CSS display: 800×560 (stretched — modal genişliğine göre)
- `getBoundingClientRect()` 800px genişlik döner
- `_toImageSpace()` sadece `this.scale` ile bölüyordu → mouse koordinatları yanlış image-space'e map ediliyordu
- Görsel olarak yuvarlak X konumunda, hit-test X+offset konumunda → "boş yere tıklayınca aktif olur"

**Fix #1 — Canvas Explicit Boyut + Wrapper (`pose-editor.js`, `mask-editor.js`)**
- Canvas'a explicit CSS `width:Npx; height:Npx; flex-shrink:0; align-self:center; max-width:100%`
- Canvas'ı `display:flex; justify-content:center` wrapper div'e sar → her boyutta merkezde

**Fix #2 — Defansif Hit-Test (her iki editor)**
- `_toImageSpace()` artık `rect.width / canvas.width` oranını hesaplar (CSS → buffer scale)
- `_hitVertex()` tolerance'ı `rect.width / this.width` ile dinamik (gerçek display scale)
- Canvas stretch/zoom/transform olsa bile hit-test doğru

**Fix #3 — Document-Level Drag (her iki editor)**
- Drag başladığında `document.addEventListener("mousemove" + "mouseup")` bind
- Drag bitince listener'lar remove
- Mouse canvas dışına çıkarsa drag iptal olmuyor (klasik UX)
- Drag sırasında cursor: `grabbing`, hover: `grab`

**Fix #4 — En Yakın Vertex Seçimi**
- Eski hit-test ilk eşleşeni dönerdi → üst üste binmiş keypoint'lerde yanlış seçim
- Yeni: tüm vertex'leri tara, **en yakın olanı** seç

**Sonuç**
- ✓ Keypoint'lere doğrudan tıklayıp sürüklenebilir
- ✓ Mouse canvas dışına çıksa bile drag bozulmaz
- ✓ Modal boyutu değişse bile hit-test sapma yapmaz
- ✓ Üst üste keypoint'ler için en yakını seçilir
- ✓ Aynı düzeltme regional 3-4 char mask editörü için de geçerli

---

## Sprint 11 — Pose/Mask Editor Modal Titreşim Fix

**Bug:** Mouse editör üzerinde hareket ettikçe modal pencere genişleyip ufalıyordu — gözde rahatsız edici titreşim.

**Kök Neden:**
- `statusEl` (toolbar sağındaki koordinat göstergesi) her mouse move'da metin güncelliyor: `(12,34)` → `(123,456)` → `nose (512,200)` → ...
- Metin uzunluğu değiştikçe **toolbar genişliği değişiyor** (flex-wrap aktifti)
- Toolbar boyut değişimi parent modal box'a propagate oluyor (`max-width:92vw; overflow:auto`)
- Modal "fit-content" davranışıyla içeriğe göre nefes alıyordu → titreşim

**Fix — 4 katmanlı (her iki editor)**
1. **Status sabit boyut**: `width:240px; flex-shrink:0; font-family:monospace; white-space:nowrap; overflow:hidden; text-overflow:ellipsis`
2. **Toolbar nowrap**: `flex-wrap:nowrap; overflow:hidden; min-height:38px` — buton ya da status uzasa wrap olmaz
3. **Modal box sabit width**: `width:${boxW}px` (canvas boyutuna göre hesaplanır, max-width fallback olarak kalır)
4. **CSS containment**: `contain:layout style` — child layout değişikliği parent'a sızmaz (browser hint)

**Sonuç**
- ✓ Modal mouse hareketinde sabit kalır
- ✓ Status koordinatı monospace ile güzel hizalı görünür
- ✓ Aynı düzeltme regional mask editör için de geçerli (3-4 char workflow)

---

## Sprint 12 — Wan 2.2-S2V (Audio→Video) Entegrasyonu

**Hedef:** Müzik klibi için resmi ses-tahrik video gen. Alibaba Wan 2.2-S2V, MoE arch, FID 15.66 / CSIM 0.677 (HuMo'dan üstün). Mevcut HuMo pipeline'ı paralel olarak **bozulmadan** kalır.

**Donanım Optimizasyonu (RTX 4090 24GB + 64GB RAM)**
- Default config: **fp16 ağırlıkları** (fp8 yerine, kalite önce)
- Default resolution: **1080×1920** (TikTok/Reels FullHD 9:16)
- Default frames: **121** (~5s @ 24fps)
- Steps: 25 (MoE 20 yeterli ama kalite için +5)
- `block_swap: 0` (offload yok, tüm model VRAM'de)
- `recommend_models_for_vram()` — VRAM'a göre fp16/fp8 otomatik öner

**Added — Yeni Modül `/wan/`**
- `wan/__init__.py` — defansif çoklu-yol import (ltx/ pattern'i)
- `wan/s2v_helpers.py` — config, preset'ler, model detection, HF download URL'leri (fp16 + fp8 alternatifleri)
- `wan/s2v_node.py` — `FikoYT_MVD_WanS2V` node sınıfı (ComfyUI core + Kijai feature-detect)
- `wan/endpoints.py` — 6 endpoint:
  - `GET /wan/s2v/status` — node/model durumu + VRAM detect + öneri
  - `GET /wan/s2v/presets` — 8 aspect preset (FullHD ilk önerilen)
  - `POST /wan/s2v/install` — VRAM'a göre otomatik model download (4090=fp16, <16GB=fp8)
  - `GET /wan/s2v/install_status` — progress
  - `POST /wan/s2v/install_node` — Kijai WanVideoWrapper git clone
  - `POST /character/{cid}/wan_s2v_render` — karakter ref + ses → workflow JSON build + queue
- `workflow/wan_s2v_segment.json` — Wan 2.2-S2V template (umT5 + Wan VAE + Wav2Vec2 + KSampler uni_pc/simple)

**Aspect Presetleri (4090 odaklı)**
- 🎯 `1080x1920_portrait_fullhd` — TikTok/Reels FullHD (default)
- `832x1280_portrait_tiktok` — hızlı iterasyon
- `1920x1080_landscape_fullhd` — YouTube/Vimeo
- `1080x1080_square` — Instagram HD
- `832x832_square_fast` — test (~2.7s)
- `832x1280_portrait_long` — uzun (~6.7s, intro/outro)

**Added — UI (`web/js/mvd/wan-s2v-studio.js`)**
- Karakter Stüdyosu'na **3. büyük launcher buton** (Test Lab + Pose Studio + 🎤 Wan 2.2-S2V YENİ rozetli)
- Ayrı window: 1180×780, mor gradient header
- **Auto-detect sistem durumu** — modeller eksikse "📦 Kijai Wrapper Kur" + "📥 Modelleri İndir" tek-tık butonları
- VRAM tespit + preset öneri (24GB → fp16 + FullHD)
- Form: audio path + preset + prompt + negative + steps/cfg/seed
- Render kuyruğu sağ panelde — her render kartı timestamp + boyut + süre

**Defansif Özellikler**
- ComfyUI core 0.3.40+ native node yoksa Kijai fallback feature-detect
- Hiçbir model yoksa empty image tensor + install hint döner
- HuMo node'larıyla **çakışma yok** — paralel pipeline'lar
- nodes/__init__.py'a wan subsystem defansif import (paket yoksa silent skip)
- __init__.py'da `wan.setup_endpoints()` try/except içinde

**Kullanım**
1. Karakter Stüdyosu → karakter → **🎤 Wan 2.2-S2V** butonu
2. İlk kez açılışta: "📥 Modelleri İndir" (4090 için fp16, ~46GB)
3. Restart sonrası: audio path + FullHD preset + prompt → 🎤 Üret
4. ComfyUI queue'ya gider, render bitince `output/fikoyt_mvd/_characters/<cid>/wan_s2v/`'a düşer
5. Master Render (Sprint 6) ile tüm segmentleri birleştir → final MP4

---

## Sprint 13 — InfiniteTalk (Sınırsız Uzunluk Lipsync)

**Hedef:** MultiTalk'un halefi InfiniteTalk ile tam şarkı boyunca lipsync. Wan 2.2 üstünde chunk'lı render — Wan 2.2-S2V'nin 5s sınırını aşar.

**Two Modes**
- **I2V**: karakter image + audio → sınırsız uzun lipsync video (tam şarkı boyunca)
- **V2V**: mevcut video + yeni audio → o videonun karakterinin dudakları yeni sese senkron

**Added — Backend**
- `wan/infinitetalk_helpers.py` — model detection, config, `estimate_chunks()` (audio süresinden chunk + 4090 render tahmini)
- `workflow/wan_infinitetalk_i2v.json` — I2V template (Kijai WanVideoSampler, chunk'lı, audio_scale)
- `workflow/wan_infinitetalk_v2v.json` — V2V template (VHS_LoadVideo + denoise)
- `wan/endpoints.py`'a 4 yeni endpoint:
  - `GET /wan/infinitetalk/status` — model durumu
  - `POST /wan/infinitetalk/install` — VRAM'a göre fp16 (~25GB) / fp8 (~12GB)
  - `GET /wan/infinitetalk/estimate?duration_sec=180` — chunk + render süresi tahmini (4090)
  - `POST /character/{cid}/infinitetalk_render` — I2V veya V2V mode
- Wan 2.2-S2V ile **paylaşılan** umT5/VAE/Wav2Vec2 (ekstra indirme yok)

**Added — UI (`infinitetalk-studio.js`)**
- Ayrı window: 1180×800, mor gradient header
- **Tab switcher**: 🖼→🎬 I2V vs 🎬→🎬 V2V
- Audio path girilince **otomatik estimate** (chunk sayısı + 4090 render dakikası)
- V2V için ek alanlar: kaynak video + denoise slider
- Render kuyruğu — her job için chunk + tahmini dk gösterimi
- Karakter Stüdyosu'na **4. büyük launcher buton** (2×2 grid):
  - 🧪 Test Lab · 🦴 Pose Studio · 🎤 Wan 2.2-S2V · 💬 InfiniteTalk

**4090 Render Süre Tahminleri**
| Şarkı Süresi | Chunk Sayısı | Tahmini Render |
|---|---|---|
| 30s | 9 | ~3 dk |
| 60s (1 dk) | 17 | ~5 dk |
| 180s (3 dk) | 53 | ~16 dk |
| 240s (4 dk) | 70 | ~21 dk |

---

## Sprint 14 — TeaCache + WaveSpeed Hızlandırma

**Hedef:** Flux/Wan/LTX/Hunyuan modelleri için 1.5-3x hızlandırma, kalite kaybı yok/minimal.

**Added — Helper'lar (`nodes/common.py`)**
- `_try_apply_teacache(model, model_type, rel_l1_thresh, ...)` — ComfyUI-TeaCache wrapper (feature-detect)
- `_try_apply_wavespeed(model, residual_diff_threshold, ...)` — Comfy-WaveSpeed FBCache wrapper
- `apply_acceleration(model, accelerator="auto", intensity="balanced")` — Dispatcher
  - `accelerator`: auto / teacache / wavespeed / none
  - `intensity`: conservative (1.5x) / balanced (2x) / aggressive (2.5-3x)

**Added — Endpoint'ler**
- `GET /acceleration/status` — TeaCache + WaveSpeed kurulu mu, hangi node'lar
- `POST /acceleration/install_teacache` — welltop-cn/ComfyUI-TeaCache git clone + pip
- `POST /acceleration/install_wavespeed` — chengzeyi/Comfy-WaveSpeed git clone + pip
- `/install_*_status` endpoint'leri

**Etki (4090 24GB)**
- Test Lab 4 variant: ~60s → ~25-30s (TeaCache balanced)
- Wan 2.2-S2V 5s segment: ~90s → ~45s
- InfiniteTalk 3dk şarkı: ~16dk → ~9-10dk (WaveSpeed aggressive)

---

## Sprint 15 — Auto Mode (Tek-Tık Müzik Klibi Pipeline)

**Hedef:** Beat snap → aspect → görsel batch → video batch → master render — hepsi tek tıkla.

**Added — Backend (`nodes/endpoints.py`)**
- `GET /auto_mode/plan/{name}` — proje için pipeline planı + her adımın tahmini süresi
- `POST /auto_mode/run/{name}` — body: `{steps: [...], confirm: true}` — arka planda orkestrasyon
- `GET /auto_mode/status` — current_step / step_index / log[] / errors[] / done
- 6 adımlı default plan:
  1. 🎵 Beat grid (librosa)
  2. 🎯 Segment'leri beat'lere snap
  3. 📐 Aspect preset uygula
  4. 🖼 Görsel batch render hint
  5. 🎬 Video batch (Wan 2.2-S2V) hint
  6. 🎼 Master render (FFmpeg + audio + fade)

**Added — UI (`auto-mode.js`)**
- Yeni window: 720×700
- Plan özeti (audio + segment + karakter + aspect + toplam tahmini dk)
- Step checklist (uncheck ile atla, önkoşulu olmayan adımlar grilleştirilir)
- 🚀 Auto Mode'u Başlat butonu — confirm modal
- Status polling (1.5s tick) — her log satırı canlı akar
- Karakter Stüdyosu detail'in en üstüne **🚀 AUTO MODE** kutusu (turuncu gradient)
- `window.fikoytOpenAutoMode` global expose (console'dan da açılabilir)

---

## Sprint 16 — Flux Kontext (Multi-Image Segmentler Arası Süreklilik)

**Hedef:** Önceki segment görselini "kontext" olarak verip yeni sahneyi aynı karakter/kıyafet/stille üretmek. Black Forest Labs Flux.1 Kontext Dev (12B DiT).

**Added — Node (`nodes/visual.py`)**
- `FikoYT_MVD_FluxKontextChain` — multi-image referans + edit prompt → tutarlı sonraki segment
- Optional `second_reference` input (pose veya outfit ek referansı)
- Feature-detect: `ReferenceLatent` + `FluxKontextImageRescale` + `VAEEncode`
- Defansif fallback: node yoksa hint döner

**Added — Workflow (`workflow/flux_kontext_segment.json`)**
- UNETLoader (Kontext fp16) + DualCLIPLoader (Flux ile aynı T5/CLIP-L) + Flux VAE
- Kontext image → Rescale → VAEEncode → ReferenceLatent ile cond'a bağla
- FluxGuidance 2.5 (Kontext default, Flux Dev 3.5'den düşük)
- KSampler euler/beta, denoise 1.0

**Added — Endpoint'ler**
- `GET /flux_kontext/status` — Kontext node + model kurulum durumu + download hint
- `POST /character/{cid}/kontext_chain_render` — body: source_image_path + edit_prompt + model dosyaları → workflow queue

**Use Case (Müzik Klibi)**
- Segment 1: Karakter LoRA + PuLID ile sahneyi üret (mevcut)
- Segment 2-N: Segment 1 görselini Kontext olarak ver → yeni sahne aynı karakter, aynı kıyafet, aynı stil → **garanti tutarlılık**
- Segment'ler arası "kim bu" sorusu olmaz

**Kurulum**
- Model: `https://huggingface.co/black-forest-labs/FLUX.1-Kontext-dev` → `models/diffusion_models/`
- 4090 24GB: fp16 (~24GB) önerilen; fp8 (~12GB) düşük VRAM
- T5/CLIP-L/VAE: Flux Dev ile aynı (zaten varsa ekstra yok)

---

## 📊 Sprint 12-16 Özet Tablo (RTX 4090 24GB için)

| Sprint | Ne Ekledi | Backend | UI | Donanım Etkisi |
|---|---|---|---|---|
| 12 Wan 2.2-S2V | 5s ses-tahrik video | 1 node + 6 endpoint + workflow | Wan S2V Studio window (mor) | fp16 + 1080×1920 |
| 13 InfiniteTalk | Sınırsız uzunluk lipsync | helpers + 4 endpoint + 2 workflow | InfiniteTalk Studio (I2V+V2V tab) | fp16, 3dk şarkı ~16dk |
| 14 TeaCache | 2x hızlandırma | 3 helper + 4 endpoint | (UI sonra) | Test Lab 4 variant 60→30sn |
| 15 Auto Mode | Tek-tık pipeline | 3 endpoint + state machine | Auto Mode window (turuncu) | Karakter Stüdyosu üst bar |
| 16 Flux Kontext | Segment sürekliliği | 1 node + 2 endpoint + workflow | (node-level kullanım) | fp16 (~24GB) önerilen |

**Toplam Sprint 12-16:**
- 3 yeni paralel modül: `wan/`, sonradan `auto_mode`, `flux_kontext`
- 4 yeni node (Wan S2V, InfiniteTalk indirect, FluxKontextChain + helper'lar)
- 5 yeni workflow JSON template
- ~20 yeni endpoint
- 3 yeni UI window + 1 launcher bar
- **Mevcut sistem garanti bozulmadı** — tüm yeni modüller defansif paralel

---

# 🎬 SEZON 3 — Sprint 17-21 (Tamamlayıcı + Quick Wins)

## Sprint 17 — Auto Mode Tam Orkestrasyon

**Bug:** Sprint 15 Auto Mode'da "videos" step "hint" döndürüyordu, gerçek render yapmıyordu.

**Added — Backend**
- `POST /project/{name}/batch_videos` — body: `{backend, preset, prompt_template, accel_method, segment_indices}`. Her segment için audio kesimi (ffmpeg) + Wan 2.2-S2V workflow build + queue
- `GET /project/{name}/batch_videos_status` — current_segment + completed/total + failed[]
- `_slice_audio()` helper — ffmpeg ile segment.start_sec → start+duration kesimi (audio_segments/ altına)
- Auto Mode "videos" step artık `_batch_videos_state` initialize ediyor, frontend batch_videos endpoint'ini gerçek tetikliyor

**Added — UI**
- `auto-mode.js` Sprint 17 güncelleme: Auto Mode tamamlanınca "videos" step seçildiyse otomatik `/batch_videos` POST → `_pollBatchVideos()` ayrı polling — her segment için canlı progress
- Run button label: `⏳ batch_videos: seg N (X/Y)`

---

## Sprint 18 — TeaCache UI Toggle

**Hedef:** Sprint 14'te helper'lar eklenmişti ama UI'da kullanılamıyordu. Reusable component.

**Added**
- `web/js/mvd/components/acceleration-toggle.js` — `mountAccelerationToggle(parent, opts)` reusable
  - **Status badge**: TeaCache ✓/✗ · WaveSpeed ✓/✗ (5sn'de bir refresh)
  - **Method dropdown**: 🚫 Kapalı / 🤖 Auto / 🍵 TeaCache / 🌊 WaveSpeed
  - **Intensity dropdown**: 🐢 Konservatif (~1.5x) / ⚖ Dengeli (~2x) / 🚀 Agresif (~2.5-3x)
  - **Install butonları** (kurulu değilse görünür): 📦 TeaCache Kur / 📦 WaveSpeed Kur
  - `getMethod()`, `getIntensity()`, `refresh()` API
- Entegrasyon: **Test Lab, Wan S2V Studio, InfiniteTalk Studio** — hepsinin sol panelinde ⚡ kutucuk
- Tüm render body'lerine `accel_method` + `accel_intensity` parametreleri eklendi (backend Sprint 18+'da workflow'a inject edebilir)

---

## Sprint 19 — Wan S2V Batch Render UI

**Hedef:** Sprint 17 backend endpoint'ini Wan S2V Studio'dan tek tıkla tetikle.

**Added**
- Wan S2V Studio'ya **🎬 Aktif Projenin TÜM Segmentlerini Batch Render** butonu (turuncu gradient, full-width)
- `localStorage.fmvd_last_project`'tan aktif proje al
- Confirm modal: "Her segment ~30-90sn (4090). Devam?"
- `_pollBatchVideosStatus()` — yan etkili polling, current_segment ve completed/total canlı
- accel_method + accel_intensity batch_videos endpoint'ine de iletilir

---

## Sprint 20 — PuLID v2 (Flux II) Upgrade

**Hedef:** Mevcut PuLID v0.9.1 yanında yeni nesil PuLID Flux II paralel — model pollution çözüldü, TeaCache/WaveSpeed uyumlu.

**Added — Backend**
- `nodes/character.py` → `_try_apply_pulid_v2(model, image, weight=0.85, end_at=0.85, pulid_file="pulid_flux_v0.9.2.safetensors")` helper
  - Mevcut PuLID node sınıflarını kullanır (PulidFluxModelLoader, ApplyPulidFlux), sadece model dosyası farklı
  - v2 dosyası yoksa v1 fallback (graceful)
  - `end_at=0.85` default (v1'de 0.8'di — kimlik daha geç bırakılır)
- `_apply_identity` dispatcher'a `pulid_v2` eklendi → **auto sıra**: `pulid_v2 → pulid → instantid → ipadapter_v2`
- Yeni endpoint'ler:
  - `GET /check_pulid_v2` — dosya tespiti + v1 fallback durumu
  - `POST /install_pulid_v2` — 3 URL adayı sırayla dener (v0.9.2 / v0.9.II / v1.0)
  - `GET /install_pulid_v2_status`

**Added — UI**
- Karakter modal "🧬 Kimlik Yöntemi" dropdown'a `🎯 PuLID v2 (Flux II) — yeni nesil` seçeneği (en üstte, v1'in üzerinde)

---

## Sprint 21 — Quick Wins Paketi

**3 kullanıcı isteği tek pakette:**

### 📋 Karakter Klonla
- `POST /character/{cid}/clone` — body: `{new_id?, new_name?}`
  - `shutil.copytree()` ile tüm klasör (refs, poses, outfits, _lora_versions) kopyalanır
  - Meta'da `cloned_from` + `cloned_at` alanları
  - Path'ler yeni klasöre düzeltilir (image_path, outfits[].reference_image, pose_library[].source_path)
- Karakter detail modal'da **📋 Klonla** butonu (yeşil) — sil butonunun yanı

### 💾 Karakter Kütüphanesi Auto Backup
- `POST /characters/backup` — `_characters/` klasörünü zip'le `_backups/characters_<UTC>.zip`'e
- `GET /characters/backups` — mevcut backup'ları listele (filename + size_mb + mtime)
- Karakter Stüdyosu üst bar'daki Auto Mode'un yanında **💾 Yedek** butonu (mavi tonu)

### ↶ Pose Editor Ctrl+Z Undo
- `PoseEditor.history` array (max 50 step) — her aksiyon öncesi `_snapshot()`
- Snapshot tetikleyiciler: keypoint sürükle başlangıcı, shift+click visible toggle, template değiştir, flip H, rotate, scale ±
- `undo()` metodu — son snapshot'tan kp + visible restore
- **Ctrl+Z** / Cmd+Z keyboard shortcut (modal-level document listener)
- Toolbar'a **↶ Undo** butonu (manuel)
- Modal kapanırken `keydown` listener cleanup
- Info bar güncellendi: `Ctrl+Z = ↶ undo` ipucu

---

## 📊 SEZON 3 ÖZET (Sprint 17-21)

| Sprint | Ne | Etki |
|---|---|---|
| 17 Auto Mode orkestrasyon | batch_videos endpoint + Auto Mode'a entegrasyon | Tek tık tüm pipeline gerçek çalışır |
| 18 TeaCache UI | acceleration-toggle reusable component | 3 studio'da ⚡ hızlandırma toggle |
| 19 Batch render UI | Wan S2V Studio'ya tüm-segment batch buton | Manuel tek tek render bitti |
| 20 PuLID v2 | Flux II yeni nesil + dispatcher | Auto'da öncelikli, model pollution çözüldü |
| 21 Quick wins | 📋 klonla + 💾 backup + ↶ undo | Karakter iterasyonu çok daha hızlı + güvenli |

**Toplam Sprint 17-21:**
- ~1500 satır yeni kod
- 1 yeni reusable JS component
- 6 yeni endpoint
- 5 yeni UI element (3 buton + 1 dropdown + 1 keyboard shortcut)
- **Mevcut sistem bozulmadı** — tüm değişiklikler additive

---

# 🎬 TOPLAM PROJE DURUMU (Sezon 1 + 2 + 3 = 21 Sprint)

- **~7500+ satır** yeni kod
- **15 yeni node** sınıfı (14 + Sprint 20 PuLID v2 helper)
- **70+ HTTP endpoint**
- **9 workflow JSON** template
- **5 floating window** + 2 reusable component (acceleration-toggle + pose-editor + mask-editor)
- **2 paralel modül** (`wan/`, `auto_mode`)
- **3 sezon** sistematik geliştirme

**Hangi şey nerede?**
- Karakter Stüdyosu (Window) → karakter listesi + detail
- Detail bar 1: 🚀 Auto Mode · 💾 Yedek (Sprint 15+21)
- Detail bar 2: 🧪 Test Lab · 🦴 Pose Studio · 🎤 Wan S2V · 💬 InfiniteTalk (Sprint 7+12+13)
- Pose Studio → ✏ Sıfırdan Çiz (Pose Editor + Ctrl+Z undo)
- Test Lab + Wan + InfiniteTalk → her birinde ⚡ Hızlandırma toggle
