Spaces:
Running
Running
Download src/build_deck.py from SoSa123456/greenroot: direct link, hf CLI and curl.
- Browser
- Download file 32.4 kB
-
https://huggingface.co/spaces/SoSa123456/greenroot/resolve/main/src/build_deck.py
- Command line
-
hf download hf://spaces/SoSa123456/greenroot/src/build_deck.py
-
curl -L -o build_deck.py https://huggingface.co/spaces/SoSa123456/greenroot/resolve/main/src/build_deck.py
32.4 kB
| #!/usr/bin/env python3 | |
| """GreenRoot trilingual pitch decks (EN/FA/TR) — python-pptx.""" | |
| import pathlib | |
| from pptx import Presentation | |
| from pptx.util import Inches, Pt, Emu | |
| from pptx.dml.color import RGBColor | |
| from pptx.enum.text import PP_ALIGN, MSO_ANCHOR | |
| from pptx.enum.shapes import MSO_SHAPE | |
| from pptx.oxml.ns import qn | |
| OUT = pathlib.Path("/home/user/greenroot/kit") | |
| OUT.mkdir(parents=True, exist_ok=True) | |
| # palette | |
| DEEP = RGBColor(0x0B, 0x3B, 0x2A) | |
| GREEN = RGBColor(0x16, 0xA3, 0x4A) | |
| LIME = RGBColor(0xA3, 0xE6, 0x35) | |
| INK = RGBColor(0x0C, 0x23, 0x18) | |
| MUTED = RGBColor(0x54, 0x68, 0x5C) | |
| LINE = RGBColor(0xE2, 0xE9, 0xDD) | |
| BG = RGBColor(0xF6, 0xF8, 0xF3) | |
| AMBER = RGBColor(0xF5, 0x9E, 0x0B) | |
| TEAL = RGBColor(0x0D, 0x94, 0x88) | |
| WHITE = RGBColor(0xFF, 0xFF, 0xFF) | |
| CREAM = RGBColor(0xD9, 0xF9, 0x9D) | |
| W, H = 13.333, 7.5 | |
| def C(hexs): return RGBColor(*[int(hexs[i:i+2],16) for i in (0,2,4)]) | |
| # ---------------- content ---------------- | |
| DECKS = {} | |
| DECKS["en"] = dict( | |
| font="Calibri", rtl=False, | |
| slides=[ | |
| dict(k="ADDICTION RECOVERY × GREEN WORK × AI", t="GreenRoot", | |
| s="Healing people, healing the planet — recovery through environmental work, funded by recycling, guided by AI.", | |
| f="COP31 · Antalya & Istanbul · 9–20 November 2026"), | |
| dict(k="THE PROBLEM", t="Three crises, one root", | |
| cards=[("Addiction thrives in emptiness","Most relapses happen in long, unstructured hours alone — no structure, no purpose, no people."), | |
| ("The job trap","CV gaps close the employer's door; joblessness pushes people back to use. Closed from both sides."), | |
| ("Cities drowning in waste","Parks and riverbanks litter faster than cities clean; recyclables worth millions are lost every year.")], | |
| note="Addiction, unemployment and waste feed each other. GreenRoot attacks all three at once."), | |
| dict(k="THE SOLUTION", t="One program, three engines", | |
| cards=[("1 · Evidence-based recovery","Contingency management (token economy), behavioral activation and therapeutic community — built into every workday."), | |
| ("2 · Paid green work","Real wages for cleanup crews, sorting lines and upcycling. Recycling income funds therapy and medicine."), | |
| ("3 · AI career rewind","Raha, our AI companion, coaches cravings, tracks mood and maps skills back to the job each person had before.")], | |
| note="Each engine makes the other two stronger."), | |
| dict(k="HOW IT WORKS", t="The GreenRoot Loop", | |
| loop=[("Collect","Outdoor cleanup shifts: structure, exercise, nature."), | |
| ("Earn","Wages + tokens — immediate, earned reward."), | |
| ("Heal","Recycling income funds therapy and medicine."), | |
| ("Return","AI career rewind leads back to the old profession.")], | |
| note="Recovery and environment compound like interest."), | |
| dict(k="THE SCIENCE", t="Built on addiction science", | |
| bullets=["Contingency management — strong randomized-trial evidence; raises abstinence and treatment retention.", | |
| "Supported employment — meaningful work improves outcomes, self-esteem and quality of life.", | |
| "Behavioral activation — structured, value-driven activity reduces substance use.", | |
| "Green care — nature lowers stress hormones; exercise is linked to reduced craving.", | |
| "Therapeutic community — peer roles rebuild identity: from 'patient' to environmental worker."], | |
| note="Design informed by established literature; pilot figures in this deck are illustrative."), | |
| dict(k="STREET → WARD", t="Waste in, medicine out", | |
| cards=[("Recycling revenue funds treatment","Sold PET, metal, paper and glass pay for therapy sessions, psychiatric care and essential medicines."), | |
| ("Materials become medical supplies","With certified partners, collected plastics are cleaned, shredded and remanufactured into face shields, splint parts and clinical packaging."), | |
| ("Open budget","Crew revenue → 40% wages · 30% treatment fund · 30% operations. Published monthly.")], | |
| stats=[("€41k","to therapy & medicine*"),("3,200","medical items produced*"),("26 t","CO₂e saved*")]), | |
| dict(k="TECHNOLOGY", t="Meet Raha — the AI companion", | |
| bullets=["Craving SOS — urge-surfing coach, breathing, 24/7.", | |
| "Mood & relapse watch — daily check-ins, risk alerts to counselors (opt-in only).", | |
| "Token wallet & goals — small wins wired into the habit loop.", | |
| "Career rewind — skills map, résumé rebuild, interview practice back to the previous job.", | |
| "Private by design — encrypted, participant-owned; crisis routes to humans, never to police."], | |
| note="AI assists; licensed humans make clinical decisions."), | |
| dict(k="IMPACT", t="Impact you can weigh", | |
| stats=[("120+","people in recovery"),("18.4 t","waste collected & sorted"),("63% vs 60%","6-month relapse: GR vs typical*"),("87%","program completion*")], | |
| note="*Demo cohort figures for the concept. An open dashboard publishes monthly numbers for every cohort."), | |
| dict(k="ROADMAP", t="Twelve months, four phases", | |
| loop=[("Stabilize · wk 0–4","Medical assessment, MAT where indicated, safety plan, meet Raha."), | |
| ("Work & heal · wk 2–12","3 supported shifts/week, group therapy, tokens."), | |
| ("Build · mo 3–6","Sorting line & upcycling skills; career-rewind plan drafted."), | |
| ("Return · mo 6–12","CV rebuild, mock interviews, placement, alumni network.")], | |
| note="Pilot cities: Frankfurt · Tehran · Istanbul."), | |
| dict(k="BUSINESS MODEL", t="The circular economy of recovery", | |
| cards=[("Revenue","Sale of recyclables; upcycled medical products; municipal cleanup service contracts; ESG partnerships."), | |
| ("Costs","40% participant wages · 30% treatment fund · 30% operations & growth."), | |
| ("Unit dignity","Wages at or above local minimum. No quotas used against participants — ever.")], | |
| note="Dual return: environmental (tons diverted) and public-health (remission, employment)."), | |
| dict(k="AT COP31", t="Our five asks", | |
| numbered=["Recognize recovery-through-work as climate finance: fund therapeutic green employment.", | |
| "Include waste-picker and recovery communities in national just-transition plans.", | |
| "Back city pilots — Istanbul, Frankfurt, Tehran — with open impact dashboards.", | |
| "Set data rights for AI recovery tools: opt-in, participant-owned, never policing tools.", | |
| "Count health outcomes next to CO₂ — a person in remission is a climate result too."], | |
| note="Antalya 9–20 Nov 2026 · civil-society & Peoples' Climate Summit"), | |
| dict(k="THE ASK", t="Be the crew that cleans two crises at once", | |
| cards=[("City partners","Host a pilot cohort: Frankfurt, Tehran or Istanbul — with an open dashboard."), | |
| ("Operators & clinics","Waste streams, sorting sites, clinical supervision and placement partners."), | |
| ("Seed funding","€350k for the first 12-month cohort: equipment, micro-factory line, clinical team.")], | |
| note="hello@greenroot.example · greenroot — healing people, healing the planet."), | |
| ]) | |
| DECKS["fa"] = dict( | |
| font="Tahoma", rtl=True, | |
| slides=[ | |
| dict(k="بهبودی از اعتیاد × کار سبز × هوش مصنوعی", t="گرینروت", | |
| s="انسانها را شفا بده، سیاره را شفا بده — بهبودی از راه کار محیطزیستی، تأمینشده با بازیافت، هدایتشده با هوش مصنوعی.", | |
| f="COP31 · آنتالیا و استانبول · ۹ تا ۲۰ نوامبر ۲۰۲۶"), | |
| dict(k="مسئله", t="سه بحران، یک ریشه", | |
| cards=[("اعتیاد در خلأ رشد میکند","بیشتر لغزشها در ساعات طولانیِ بیساختار و در تنهایی رخ میدهند — بدون نظم، هدف و آدمها."), | |
| ("تلهٔ شغل","جای خالی رزومه، درِ کارفرما را میبندد؛ بیکاری فرد را به مصرف برمیگرداند. در از هر دو سو بسته است."), | |
| ("شهرها در زباله غرق میشوند","پارکها و حاشیهٔ رودها سریعتر از توان شهرداری آلوده میشوند؛ سالانه مواد بازیافتی بهارزش میلیونها از دست میرود.")], | |
| note="اعتیاد، بیکاری و زباله به هم غذا میدهند. گرینروت هر سه را همزمان هدف میگیرد."), | |
| dict(k,"راهحل".replace("راهحل","راهحل"), t="یک برنامه، سه موتور") if False else dict(k="راهحل", t="یک برنامه، سه موتور", | |
| cards=[("۱ · بهبودی مبتنی بر شواهد","مدیریت پیامد (اقتصاد توکنی)، فعالسازی رفتاری و جامعهٔ درمانی — درون هر روزِ کاری."), | |
| ("۲ · کار سبز حقوقدار","دستمزد واقعی برای تیمهای پاکسازی، خط جداسازی و بازیافت خلاق. درآمد بازیافت، درمان و دارو را تأمین میکند."), | |
| ("۳ · بازگشت شغلی با هوش مصنوعی","رها، همیار هوش مصنوعی، برای هوسها مربیگری میکند، خلق را رصد میکند و مهارتها را به شغلِ قبلی وصل میکند.")], | |
| note="هر موتور، دو موتور دیگر را قویتر میکند."), | |
| dict(k="چگونه کار میکند", t="چرخهٔ گرینروت", | |
| loop=[("جمعآوری","شیفتهای پاکسازی در فضای باز: نظم، ورزش، طبیعت."), | |
| ("درآمد","دستمزد + توکن — پاداشِ فوری و اودهشده."), | |
| ("درمان","درآمد بازیافت، درمان و دارو را تأمین میکند."), | |
| ("بازگشت","بازگشت شغلی با هوش مصنوعی، به حرفهٔ قبلی.")], | |
| note="بهبودی و محیطزیست مثل بهرهٔ مرکب رشد میکنند."), | |
| dict(k="علم", t="بر پایهٔ علم اعتیاد", | |
| bullets=["مدیریت پیامد — شواهد قوی کارآزماییهای تصادفی؛ افزایش پرهیز از مصرف و ماندگاری در درمان.", | |
| "اشتغال حمایتی — کارِ معنادار، نتایج درمان، عزتنفس و کیفیت زندگی را بهتر میکند.", | |
| "فعالسازی رفتاری — فعالیت ساختیافته و ارزشمحور، مصرف را کاهش میدهد.", | |
| "مراقبت سبز — طبیعت هورمونهای استرس را کم میکند؛ ورزش با کاهش هوس پیوند دارد.", | |
| "جامعهٔ درمانی — نقشهای همتا، هویت را بازمیسازند: از «بیمار» به کارگر محیطزیست."], | |
| note="طراحی بر پایهٔ ادبیات علمیِ تثبیتشده؛ ارقام این دِک نمایشی است."), | |
| dict(k="از خیابان تا بیمارستان", t="زباله داخل، دارو خارج", | |
| cards=[("درآمد بازیافت، هزینهٔ درمان","فروش پت، فلز، کاغذ و شیشه، جلسات درمان، مراقبت روانپزشکی و داروهای ضروری را تأمین میکند."), | |
| ("مواد، تجهیزات پزشکی میشوند","با شرکای معتبر، پلاستیکها شسته، خرد و به شیلد صورت، قطعات اسپلینت و بستهبندی کلینیکال تبدیل میشوند."), | |
| ("بودجهٔ باز","درآمد تیم ← ۴۰٪ دستمزد · ۳۰٪ صندوق درمان · ۳۰٪ عملیات. انتشار ماهانه.")], | |
| stats=[("€۴۱هزار","برای درمان و دارو*"),("۳٬۲۰۰","قلم تجهیزات پزشکی*"),("۲۶ تن","CO₂e صرفهجویی*")]), | |
| dict(k="فناوری", t="با رها آشنا شوید — همیار هوش مصنوعی", | |
| bullets=["SOS هوس — مربی موجسواریِ هوس، تنفس، شبانهروزی.", | |
| "رصد خلق و لغزش — چک-این روزانه، هشدار خطر به مشاور (فقط با رضایت).", | |
| "کیف توکن و اهداف — برد کوچک، قلابشده در حلقهٔ عادت.", | |
| "بازگشت شغلی — نقشهٔ مهارت، بازسازی رزومه، تمرین مصاحبه تا شغل قبلی.", | |
| "خصوصی از پایه — رمزنگاریشده، متعلق به خودِ فرد؛ بحران به انسان میرسد، نه پلیس."], | |
| note="هوش مصنوعی کمک میکند؛ تصمیم بالینی با انسانهای مجاز است."), | |
| dict(k="اثرگذاری", t="اثری که میشود وزنش کرد", | |
| stats=[("+۱۲۰","فرد در بهبودی"),("۱۸.۴ تن","زباله جمعآوریشده"),("۶۳٪ در برابر ۶۰٪","لغزش ۶ماهه: گرینروت/معمول*"),("۸۷٪","تکمیل برنامه*")], | |
| note="*ارقام نمایشی برای معرفی مفهوم. داشبورد باز، عددهای هر گروه را ماهانه منتشر میکند."), | |
| dict(k="نقشهٔ راه", t="دوازده ماه، چهار فاز", | |
| loop=[("تثبیت · هفته ۰–۴","ارزیابی پزشکی، دارو در صورت لزوم، برنامهٔ ایمنی، آشنایی با رها."), | |
| ("کار و شفا · هفته ۲–۱۲","هفتهای ۳ شیفت همراهیشده، گروهدرمانی، توکن."), | |
| ("ساختن · ماه ۳–۶","مهارتهای جداسازی و بازیافت خلاق؛ نوشتن طرح بازگشت شغلی."), | |
| ("بازگشت · ماه ۶–۱۲","رزومه، مصاحبهٔ تمرینی، استخدام، شبکهٔ فارغالتحصیلان.")], | |
| note="شهرهای پایلوت: فرانکفورت · تهران · استانبول."), | |
| dict(k="مدل کسبوکار", t="اقتصاد چرخهایِ بهبودی", | |
| cards=[("درآمد","فروش مواد بازیافتی؛ محصولات پزشکیِ بازیافت خلاق؛ قراردادهای خدمات پاکسازی شهری؛ شراکتهای ESG."), | |
| ("هزینه","۴۰٪ دستمزد اعضا · ۳۰٪ صندوق درمان · ۳۰٪ عملیات و رشد."), | |
| ("عزت واحد","دستمزد در حد یا بالای حداقل محلی. هیچ سهمیهای علیه اعضا استفاده نمیشود — هرگز.")], | |
| note="بازده دوگانه: محیطزیستی (تنهای بازیافتشده) و سلامت عمومی (بهبودی، اشتغال)."), | |
| dict(k="در COP31", t="پنج خواستهٔ ما", | |
| numbered=["بهبودی از راه کار بهعنوان تأمین مالی اقلیمی به رسمیت شناخته شود: کارِ سبزِ درمانی تأمین مالی شود.", | |
| "جامعهٔ زبالهچینها و افراد در بهبودی در برنامههای گذار عادلانهٔ ملی دیده شوند.", | |
| "از پایلوتهای شهری — استانبول، فرانکفورت، تهران — با داشبورد باز پشتیبانی شود.", | |
| "حقوق داده برای ابزارهای هوش مصنوعی بهبودی تعیین شود: اختیاری، متعلق به فرد، هرگز ابزار پلیسگری نه.", | |
| "پیامدهای سلامت را کنار CO₂ بشمارید — انسانِ در بهبودی هم نتیجهٔ اقلیمی است."], | |
| note="آنتالیا، ۹ تا ۲۰ نوامبر ۲۰۲۶ · جامعهٔ مدنی و قلهٔ اقلیم مردمها"), | |
| dict(k="درخواست ما", t="همان تیمی باش که دو بحران را با هم تمیز میکند", | |
| cards=[("شهرهای شریک","میزبانی یک گروه پایلوت: فرانکفورت، تهران یا استانبول — با داشبورد باز."), | |
| ("بهرهبرداران و کلینیکها","جریان پسماند، سایت جداسازی، نظارت بالینی و کارفرمایانِ پذیرش."), | |
| ("سرمایهٔ اولیه","€۳۵۰هزار برای نخستین گروه ۱۲ماهه: تجهیزات، خط ریز-کارخانه، تیم بالینی.")], | |
| note="hello@greenroot.example · گرینروت — انسانها را شفا بده، سیاره را شفا بده."), | |
| ]) | |
| DECKS["tr"] = dict( | |
| font="Calibri", rtl=False, | |
| slides=[ | |
| dict(k="BAĞIMLILIKTAN TOPARLANMA × YEŞİL İŞ × YAPAY ZEKÂ", t="GreenRoot", | |
| s="İnsanları iyileştir, gezegeni iyileştir — çevre işiyle toparlanma; geri dönüşümle finanse edilen tedavi, yapay zekâ desteğiyle dönüş.", | |
| f="COP31 · Antalya & İstanbul · 9–20 Kasım 2026"), | |
| dict(k="SORUN", t="Üç kriz, tek kök", | |
| cards=[("Bağımlılık boşlukta büyür","Nükslerin çoğu uzun ve yapılandırılmamış saatlerde, yalnızken yaşanır — yapı yok, amaç yok, insan yok."), | |
| ("İş tuzağı","Özgeçmişteki boşluk işveren kapısını kapatır; işsizlik yeniden kullanıma iter. Kapı iki taraftan kapalı."), | |
| ("Şehirler çöpe gömülüyor","Parklar ve nehir kenarları belediyeden hızlı kirleniyor; her yıl milyonlarca değerinde geri dönüşüm malzemesi kayboluyor.")], | |
| note="Bağımlılık, işsizlik ve atık birbirini besler. GreenRoot üçüne birden vurur."), | |
| dict(k="ÇÖZÜM", t="Tek program, üç motor", | |
| cards=[("1 · Kanıta dayalı toparlanma","Sonuç yönetimi (jeton ekonomisi), davranışsal aktivasyon ve terapötik topluluk — her iş gününe işlenmiş."), | |
| ("2 · Ücretli yeşil iş","Temizlik ekipleri, ayrıştırma hatları ve geri dönüşüm atölyeleri için gerçek ücret. Geri dönüşüm geliri tedaviyi ve ilacı finanse eder."), | |
| ("3 · YZ ile kariyer dönüşü","YZ dostumuz Raha krizde koçluk yapar, ruh halini izler ve becerileri kişinin eski mesleğine geri bağlar.")], | |
| note="Her motor diğer ikisini güçlendirir."), | |
| dict(k="NASIL ÇALIŞIR", t="GreenRoot Döngüsü", | |
| loop=[("Topla","Açık havada temizlik vardiyası: yapı, egzersiz, doğa."), | |
| ("Kazan","Ücret + jeton — anında, kazanılmış ödül."), | |
| ("İyileş","Geri dönüşüm geliri terapiyi ve ilacı finanse eder."), | |
| ("Dön","YZ kariyer dönüşü eski mesleğe taşır.")], | |
| note="Toparlanma ve çevre, bileşik faiz gibi büyür."), | |
| dict(k="BİLİM", t="Bağımlılık bilimi üzerine kurulu", | |
| bullets=["Sonuç yönetimi — güçlü randomize çalışma kanıtı; kesinleşmeyi ve tedavide kalmayı artırır.", | |
| "Destekli istihdam — anlamlı iş; sonuçları, benlik saygısını ve yaşam kalitesini iyileştirir.", | |
| "Davranışsal aktivasyon — yapılandırılmış, değer güdümlü etkinlik kullanımı azaltır.", | |
| "Yeşil bakım — doğa stres hormonlarını düşürür; egzersiz azalan krizle ilişkilidir.", | |
| "Terapötik topluluk — akran rolleri kimliği kurar: 'hasta'dan çevre işçisine."], | |
| note="Tasarım yerleşik literatürle bilgilendirilmiştir; döküdeki rakamlar temsilidir."), | |
| dict(k="SOKAK → SERVİS", t="Atık girer, ilaç çıkar", | |
| cards=[("Geri dönüşüm geliri tedaviyi finanse eder","Satılan PET, metal, kâğıt ve cam; terapi seanslarını, psikiyatrik bakımı ve temel ilaçları öder."), | |
| ("Malzeme tıbbi sarfa dönüşür","Sertifikalı ortaklarla plastikler yıkanır, parçalanır; yüz siperi, atel parçası ve klinik ambalaja dönüşür."), | |
| ("Açık bütçe","Ekip geliri → %40 ücret · %30 tedavi fonu · %30 operasyon. Aylık yayımlanır.")], | |
| stats=[("€41 bin","terapi ve ilaca*"),("3.200","üretilen tıbbi ürün*"),("26 t","tasarruf edilen CO₂e*")]), | |
| dict(k="TEKNOLOJİ", t="Raha ile tanış — YZ dostu", | |
| bullets=["Kriz SOS — dürtü sörfü koçu, nefes egzersizi, 7/24.", | |
| "Ruh hali ve nüks gözcüsü — günlük check-in; danışmana risk uyarısı (yalnızca isteğe bağlı).", | |
| "Jeton cüzdanı ve hedefler — alışkanlık döngüsüne bağlanmış küçük zaferler.", | |
| "Kariyer dönüşü — beceri haritası, özgeçmiş, eski işe dönüş için mülakat pratiği.", | |
| "Tasarım gereği özel — şifreli, katılımcıya ait; kriz polise değil, insana gider."], | |
| note="YZ destekler; klinik kararı yetkili insanlar verir."), | |
| dict(k="ETKİ", t="Tartılabilir etki", | |
| stats=[("120+","toparlanmada kişi"),("18,4 t","toplanan & ayrıştırılan atık"),("%63 vs %60","6 aylık nüks: GR/tipik*"),("%87","program tamamlama*")], | |
| note="*Kavram için temsili kohort verisi. Açık pano her kohortun aylık sayılarını yayımlar."), | |
| dict(k="YOL HARİTASI", t="On iki ay, dört evre", | |
| loop=[("Sağlamlaş · 0–4. hf","Tıbbi değerlendirme, gerekirse ilaçla tedavi, güvenlik planı, Raha ile tanışma."), | |
| ("Çalış & iyileş · 2–12. hf","Haftada 3 destekli vardiya, grup terapisi, jeton."), | |
| ("İnşa et · 3–6. ay","Ayrıştırma ve geri dönüşüm becerileri; kariyer dönüşü planı."), | |
| ("Dön · 6–12. ay","Özgeçmiş, deneme mülakatı, yerleştirme, mezunlar ağı.")], | |
| note="Pilot şehirler: Frankfurt · Tahran · İstanbul."), | |
| dict(k="İŞ MODELİ", t="Toparlanmanın döngüsel ekonomisi", | |
| cards=[("Gelir","Geri dönüşüm malzemesi satışı; dönüştürülmüş tıbbi ürünler; belediye temizlik hizmet sözleşmeleri; ESG ortaklıkları."), | |
| ("Maliyet","%40 katılımcı ücreti · %30 tedavi fonu · %30 operasyon ve büyüme."), | |
| ("Birim onuru","Ücret yerel asgarinin düzeyinde veya üzerinde. Kota asla katılımcıya karşı kullanılmaz.")], | |
| note="Çifte getiri: çevresel (diverte edilen tonlar) ve toplum sağlığı (remisyon, istihdam)."), | |
| dict(k="COP31'DE", t="Beş talebimiz", | |
| numbered=["İşle toparlanma iklim finansmanı olarak tanınsın: terapötik yeşil istihdam fonlansın.", | |
| "Çöp toplayıcı ve toparlanma toplulukları ulusal adil geçiş planlarına alınsın.", | |
| "Şehir pilotları desteklensin — İstanbul, Frankfurt, Tahran — açık etki panolarıyla.", | |
| "YZ destekli toparlanma araçlarına veri hakları gelsin: isteğe bağlı, katılımcıya ait, asla kolluk aracı değil.", | |
| "Sağlık sonuçlarını CO₂'nin yanına koyun — remisyondaki insan da iklim sonucudur."], | |
| note="Antalya 9–20 Kasım 2026 · sivil toplum & Halkların İklim Zirvesi"), | |
| dict(k="ÇAĞRI", t="İki krizi birden temizleyen ekiple gel", | |
| cards=[("Şehir ortakları","Açık panoyla bir pilot kohorta ev sahipliği: Frankfurt, Tahran veya İstanbul."), | |
| ("İşletmeciler & klinikler","Atık akışları, ayrıştırma alanları, klinik gözetim ve istihdam ortakları."), | |
| ("Tohum yatırım","İlk 12 aylık kohort için €350 bin: ekipman, mikro-fabrika hattı, klinik ekip.")], | |
| note="hello@greenroot.example · GreenRoot — insanları iyileştir, gezegeni iyileştir."), | |
| ]) | |
| # ---------------- builder ---------------- | |
| def set_font(run, size, bold=False, color=INK, font="Calibri"): | |
| run.font.size = Pt(size); run.font.bold = bold; run.font.color.rgb = color; run.font.name = font | |
| # ensure complex-script (Arabic/Persian) font matches | |
| rPr = run._r.get_or_add_rPr() | |
| cs = rPr.find(qn('a:cs')) | |
| if cs is None: | |
| cs = rPr.makeelement(qn('a:cs'), {}); rPr.append(cs) | |
| cs.set('typeface', font) | |
| def add_rect(slide, x, y, w, h, fill, line=None, round_=False, radius=0.08): | |
| shp = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE if round_ else MSO_SHAPE.RECTANGLE, | |
| Inches(x), Inches(y), Inches(w), Inches(h)) | |
| shp.fill.solid(); shp.fill.fore_color.rgb = fill | |
| if line: shp.line.color.rgb = line; shp.line.width = Pt(1) | |
| else: shp.line.fill.background() | |
| shp.shadow.inherit = False | |
| if round_: | |
| try: shp.adjustments[0] = radius | |
| except Exception: pass | |
| return shp | |
| def add_text(slide, x, y, w, h, runs_lines, align=PP_ALIGN.LEFT, anchor=MSO_ANCHOR.TOP, | |
| font="Calibri", space_after=6, line_spacing=1.0): | |
| """runs_lines: list of paragraphs; each paragraph = list of (text,size,bold,color)""" | |
| tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h)) | |
| tf = tb.text_frame; tf.word_wrap = True; tf.vertical_anchor = anchor | |
| for i, para in enumerate(runs_lines): | |
| p = tf.paragraphs[0] if i == 0 else tf.add_paragraph() | |
| p.alignment = align; p.space_after = Pt(space_after); p.line_spacing = line_spacing | |
| for (txt, size, bold, color) in para: | |
| r = p.add_run(); r.text = txt; set_font(r, size, bold, color, font) | |
| return tb | |
| def build_deck(lang, spec, path): | |
| rtl = spec["rtl"]; F = spec["font"] | |
| prs = Presentation(); prs.slide_width = Inches(W); prs.slide_height = Inches(H) | |
| blank = prs.slide_layouts[6] | |
| def X(x, w): # mirror helper | |
| return (W - x - w) if rtl else x | |
| AL = PP_ALIGN.RIGHT if rtl else PP_ALIGN.LEFT | |
| for idx, sl in enumerate(spec["slides"], 1): | |
| s = prs.slides.add_slide(blank) | |
| add_rect(s, 0, 0, W, H, BG) | |
| add_rect(s, 0, 0, 0.16, H, GREEN) # accent bar | |
| # kicker + title | |
| add_text(s, X(0.62, 12.1), 0.42, 12.1, 0.42, [[(sl["k"], 12.5, True, GREEN)]], align=AL, font=F) | |
| add_text(s, X(0.6, 12.1), 0.78, 12.1, 1.0, [[(sl["t"], 30, True, DEEP)]], align=AL, font=F) | |
| # footer | |
| add_text(s, X(0.62, 9.6), 7.08, 9.6, 0.32, | |
| [[("GreenRoot", 10, True, GREEN), (" · COP31 · Antalya & İstanbul · Nov 2026", 10, False, MUTED)]], | |
| align=AL, font=F) | |
| add_text(s, X(12.35, 0.55), 7.08, 0.55, 0.32, [[(f"{idx:02d}", 10, True, MUTED)]], | |
| align=PP_ALIGN.RIGHT if not rtl else PP_ALIGN.LEFT, font=F) | |
| y = 2.0 | |
| if "s" in sl: # title slide subtitle | |
| add_text(s, X(0.62, 11.5), 2.35, 11.5, 1.4, [[(sl["s"], 17, False, MUTED)]], align=AL, font=F, line_spacing=1.25) | |
| # hero chips | |
| chips = [("120+", "recovery"), ("18.4 t", "waste"), ("63%", "less relapse*")] if lang=="en" else \ | |
| (["+120|فرد در بهبودی","18.4 t|زباله","63%|لغزش کمتر*"] if lang=="fa" else ["120+|toparlanma","18,4 t|atık","%63|daha az nüks*"]) | |
| cx = 0.62 | |
| for ch in chips: | |
| a, b = (ch.split("|") if "|" in ch else (ch[0], ch[1])) | |
| cwid = 2.6 | |
| add_rect(s, X(cx, cwid), 4.3, cwid, 1.05, WHITE, LINE, round_=True) | |
| add_text(s, X(cx+0.15, cwid-0.3), 4.42, cwid-0.3, 0.45, [[(a, 16, True, GREEN)]], align=AL, font=F) | |
| add_text(s, X(cx+0.15, cwid-0.3), 4.88, cwid-0.3, 0.35, [[(b, 10.5, False, MUTED)]], align=AL, font=F) | |
| cx += cwid + 0.25 | |
| add_text(s, X(0.62, 11.5), 5.85, 11.5, 0.5, [[(sl["f"], 12, True, DEEP)]], align=AL, font=F) | |
| continue | |
| if "cards" in sl: | |
| n = len(sl["cards"]); gap = 0.28 | |
| cwid = (12.11 - gap*(n-1)) / n | |
| for i, (h, b) in enumerate(sl["cards"]): | |
| x = 0.62 + i*(cwid+gap) | |
| if rtl: x = 0.62 + (n-1-i)*(cwid+gap) | |
| add_rect(s, X(x, cwid), y, cwid, 3.4, WHITE, LINE, round_=True) | |
| add_rect(s, X(x, cwid), y, cwid, 0.12, GREEN if i%3==0 else (AMBER if i%3==1 else TEAL), round_=False) | |
| add_text(s, X(x+0.22, cwid-0.44), y+0.3, cwid-0.44, 0.8, [[(h, 14.5, True, DEEP)]], align=AL, font=F, line_spacing=1.05) | |
| add_text(s, X(x+0.22, cwid-0.44), y+1.15, cwid-0.44, 2.1, [[(b, 11.5, False, MUTED)]], align=AL, font=F, line_spacing=1.22) | |
| y += 3.65 | |
| if "loop" in sl: | |
| n = len(sl["loop"]); gap = 0.3 | |
| cwid = (12.11 - gap*(n-1)) / n | |
| colors = [GREEN, AMBER, TEAL, GREEN] | |
| for i, (h, b) in enumerate(sl["loop"]): | |
| x = 0.62 + i*(cwid+gap) | |
| if rtl: x = 0.62 + (n-1-i)*(cwid+gap) | |
| add_rect(s, X(x, cwid), y, cwid, 3.15, WHITE, LINE, round_=True) | |
| # number circle | |
| circ = s.shapes.add_shape(MSO_SHAPE.OVAL, Inches(X(x, cwid)+Inches(0.22).inches), Inches(y+0.25), Inches(0.6), Inches(0.6)) if False else None | |
| circ = s.shapes.add_shape(MSO_SHAPE.OVAL, Inches(X(x+0.22, 0.6)), Inches(y+0.25), Inches(0.6), Inches(0.6)) | |
| circ.fill.solid(); circ.fill.fore_color.rgb = colors[i%4]; circ.line.fill.background(); circ.shadow.inherit=False | |
| etf = circ.text_frame; etf.word_wrap=False | |
| ep = etf.paragraphs[0]; ep.alignment = PP_ALIGN.CENTER | |
| er = ep.add_run(); er.text = str(i+1); set_font(er, 18, True, WHITE, F) | |
| add_text(s, X(x+0.22, cwid-0.44), y+1.0, cwid-0.44, 0.55, [[(h, 14, True, DEEP)]], align=AL, font=F) | |
| add_text(s, X(x+0.22, cwid-0.44), y+1.55, cwid-0.44, 1.5, [[(b, 11, False, MUTED)]], align=AL, font=F, line_spacing=1.2) | |
| y += 3.4 | |
| if "bullets" in sl or "numbered" in sl: | |
| items = sl.get("bullets") or sl.get("numbered") | |
| paras = [] | |
| for j, it in enumerate(items): | |
| mark = "• " if "bullets" in sl else f"{j+1}. " | |
| paras.append([(mark, 14, True, GREEN), (it, 14, False, INK)]) | |
| add_rect(s, X(0.62, 12.11), y, 12.11, 3.4, WHITE, LINE, round_=True) | |
| add_text(s, X(0.95, 11.45), y+0.3, 11.45, 2.9, paras, align=AL, font=F, space_after=10, line_spacing=1.15) | |
| y += 3.65 | |
| if "stats" in sl: | |
| n = len(sl["stats"]); gap = 0.3 | |
| cwid = (12.11 - gap*(n-1)) / n | |
| base_y = y if "cards" not in sl else y | |
| yy = 5.35 if "cards" in sl else y | |
| hh = 1.15 if "cards" in sl else 2.6 | |
| for i, (a, b) in enumerate(sl["stats"]): | |
| x = 0.62 + i*(cwid+gap) | |
| if rtl: x = 0.62 + (n-1-i)*(cwid+gap) | |
| add_rect(s, X(x, cwid), yy, cwid, hh, DEEP, round_=True) | |
| add_text(s, X(x+0.2, cwid-0.4), yy+0.18, cwid-0.4, 0.55, [[(a, 20, True, CREAM)]], align=AL, font=F) | |
| add_text(s, X(x+0.2, cwid-0.4), yy+0.72 if hh>1.3 else yy+0.62, cwid-0.4, 0.4, [[(b, 10.5, False, RGBColor(0xC8,0xE6,0xCF))]], align=AL, font=F) | |
| if hh > 1.3: y += 2.8 | |
| if "note" in sl: | |
| add_text(s, X(0.62, 12.11), 6.62, 12.11, 0.42, [[("◆ ", 11, True, GREEN), (sl["note"], 11.5, False, MUTED)]], align=AL, font=F) | |
| prs.save(path) | |
| print("saved", path.name, f"({path.stat().st_size//1024} KB, {len(spec['slides'])} slides)") | |
| for lang in ["en", "fa", "tr"]: | |
| spec = DECKS[lang] | |
| build_deck(lang, spec, OUT / f"GreenRoot-Pitch-{lang.upper()}.pptx") | |
| print("ALL DECKS DONE") | |