OCKSAİ

Ctrl+Shift+E - Ucretsiz AI asistan + Resim uretimi (OpenRouter + Pollinations)

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

Advertisement:

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

Advertisement:

// ==UserScript==
// @name         OCKSAİ
// @namespace    http://tampermonkey.net/
// @version      4.0
// @description  Ctrl+Shift+E - Ucretsiz AI asistan + Resim uretimi (OpenRouter + Pollinations)
// @author       Mustafa Hakan
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @connect      openrouter.ai
// @connect      image.pollinations.ai
// @connect      text.pollinations.ai
// @run-at       document-end
// ==/UserScript==

(function () {
  'use strict';

  /* =========================================================
     YAPILANDIRMA
  ========================================================= */
  var OR_KEY   = GM_getValue('osiris_or_key', '');   // OpenRouter key
  var OR_MODEL = GM_getValue('osiris_model', 'mistralai/mistral-7b-instruct:free');
  var MAX_TOK  = 2048;

  // OpenRouter ucretsiz modeller
  var FREE_MODELS = [
    { id: 'mistralai/mistral-7b-instruct:free',      label: 'Mistral 7B (Ucretsiz)' },
    { id: 'meta-llama/llama-3.2-3b-instruct:free',   label: 'Llama 3.2 3B (Ucretsiz)' },
    { id: 'meta-llama/llama-3.1-8b-instruct:free',   label: 'Llama 3.1 8B (Ucretsiz)' },
    { id: 'google/gemma-2-9b-it:free',               label: 'Gemma 2 9B (Ucretsiz)' },
    { id: 'qwen/qwen-2.5-7b-instruct:free',          label: 'Qwen 2.5 7B (Ucretsiz)' },
    { id: 'deepseek/deepseek-r1:free',               label: 'DeepSeek R1 (Ucretsiz)' },
    { id: 'anthropic/claude-3.5-haiku',              label: 'Claude Haiku (Ucretli)' },
    { id: 'openai/gpt-4o-mini',                      label: 'GPT-4o Mini (Ucretli)' }
  ];

  var SYS = 'Sen OsirisAI adinda guclu bir yapay zeka asistaninsin. ' +
            'Kullaniciya net, dogrudan ve yararli yanitlar ver. ' +
            'Turkce konusulursa Turkce, Ingilizce konusulursa Ingilizce yanitla. ' +
            'Markdown kullan. Resim istegi alirsan [RESIM_ISTEGI: prompt] formatini kullan.';

  // Pollinations resim boyutlari
  var IMG_SIZES = [
    { w: 512,  h: 512,  label: '512x512 Kare' },
    { w: 768,  h: 512,  label: '768x512 Yatay' },
    { w: 512,  h: 768,  label: '512x768 Dikey' },
    { w: 1024, h: 576,  label: '1024x576 Genis' },
    { w: 1024, h: 1024, label: '1024x1024 Buyuk' }
  ];

  var IMG_MODELS = [
    { id: 'flux',         label: 'FLUX (Kaliteli)' },
    { id: 'flux-realism', label: 'FLUX Realism' },
    { id: 'flux-anime',   label: 'FLUX Anime' },
    { id: 'flux-3d',      label: 'FLUX 3D' },
    { id: 'turbo',        label: 'Turbo (Hizli)' }
  ];

  /* =========================================================
     DURUM
  ========================================================= */
  var isOpen       = false;
  var isThinking   = false;
  var messages     = [];
  var inclCtx      = false;
  var streamBuf    = '';
  var lastPos      = 0;
  var totalTok     = 0;
  var activeBub    = null;
  var curReq       = null;
  var sessionHist  = [];
  var userScrolled = false;
  var imgSize      = IMG_SIZES[0];
  var imgModel     = IMG_MODELS[0];
  var imgMode      = false; // resim modu acik mi

  /* =========================================================
     STİL
  ========================================================= */
  GM_addStyle([
    '@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap");',

    /* OVERLAY */
    '#osiris{position:fixed;inset:0;z-index:2147483647;background:#08080e;',
    'font-family:Inter,sans-serif;display:flex;flex-direction:column;',
    'opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;transform:translateY(8px);}',
    '#osiris.on{opacity:1;pointer-events:all;transform:translateY(0);}',
    '#osiris::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;',
    'background:radial-gradient(ellipse 80% 40% at 50% -10%,rgba(120,60,255,.06),transparent);}',

    /* GRID */
    '#o-grid{position:absolute;inset:0;pointer-events:none;z-index:0;',
    'background-image:linear-gradient(rgba(255,255,255,.025) 1px,transparent 1px),',
    'linear-gradient(90deg,rgba(255,255,255,.025) 1px,transparent 1px);',
    'background-size:44px 44px;}',

    /* HEADER */
    '#o-hdr{display:flex;align-items:center;justify-content:space-between;padding:13px 24px;',
    'border-bottom:1px solid rgba(255,255,255,.07);background:rgba(8,8,14,.94);',
    'backdrop-filter:blur(20px);flex-shrink:0;position:relative;z-index:3;}',

    '#o-logo{display:flex;align-items:center;gap:9px;user-select:none;}',
    '#o-logo-icon{width:26px;height:26px;}',
    '#o-logo-text{font-size:16px;font-weight:700;letter-spacing:-.5px;',
    'background:linear-gradient(120deg,#a78bfa,#60a5fa);-webkit-background-clip:text;-webkit-text-fill-color:transparent;}',
    '#o-logo-ver{font-size:9px;color:rgba(255,255,255,.18);margin-top:2px;letter-spacing:.5px;}',

    '#o-status{display:flex;align-items:center;gap:6px;font-size:10.5px;',
    'color:rgba(255,255,255,.3);letter-spacing:.8px;text-transform:uppercase;}',
    '#o-dot{width:6px;height:6px;border-radius:50%;background:#4ade80;',
    'box-shadow:0 0 7px #4ade80;animation:opls 2.5s infinite;}',
    '#o-dot.busy{background:#a78bfa;box-shadow:0 0 7px #a78bfa;animation:oblnk .5s infinite;}',
    '#o-dot.img{background:#60a5fa;box-shadow:0 0 7px #60a5fa;animation:opls 1s infinite;}',
    '@keyframes opls{0%,100%{opacity:1}50%{opacity:.3}}',
    '@keyframes oblnk{0%,100%{opacity:1}50%{opacity:.1}}',

    '#o-hdr-r{display:flex;align-items:center;gap:8px;}',
    '.o-hbtn{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.08);',
    'color:rgba(255,255,255,.4);padding:5px 12px;border-radius:8px;font-family:Inter,sans-serif;',
    'font-size:11px;cursor:pointer;transition:all .2s;white-space:nowrap;}',
    '.o-hbtn:hover{background:rgba(167,139,250,.1);border-color:rgba(167,139,250,.3);color:#a78bfa;}',
    '#o-close{background:none;border:none;color:rgba(255,255,255,.2);cursor:pointer;',
    'padding:5px;border-radius:6px;line-height:0;transition:color .2s;}',
    '#o-close:hover{color:#f87171;}',
    '#o-tok-info{font-size:10px;color:rgba(255,255,255,.18);font-family:"JetBrains Mono",monospace;padding:0 2px;}',

    /* BODY */
    '#o-body{flex:1;display:flex;overflow:hidden;position:relative;z-index:1;}',

    /* MESAJLAR */
    '#o-msgs{flex:1;overflow-y:auto;padding:24px 28px;display:flex;flex-direction:column;gap:18px;scroll-behavior:smooth;}',
    '#o-msgs::-webkit-scrollbar{width:3px;}',
    '#o-msgs::-webkit-scrollbar-thumb{background:rgba(167,139,250,.2);border-radius:2px;}',

    /* WELCOME */
    '#o-wel{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:40px;}',
    '#o-wel-icon{width:64px;height:64px;opacity:.08;}',
    '#o-wel h2{font-size:24px;font-weight:700;color:rgba(255,255,255,.06);letter-spacing:-1px;margin:0;}',
    '#o-wel p{font-size:13px;color:rgba(255,255,255,.11);margin:0;text-align:center;}',
    '#o-chips{display:flex;gap:7px;flex-wrap:wrap;justify-content:center;margin-top:18px;max-width:640px;}',
    '.o-chip{background:rgba(167,139,250,.06);border:1px solid rgba(167,139,250,.14);color:rgba(255,255,255,.35);',
    'padding:7px 14px;border-radius:100px;font-size:12px;cursor:pointer;transition:all .2s;font-family:Inter,sans-serif;}',
    '.o-chip:hover{background:rgba(167,139,250,.12);border-color:rgba(167,139,250,.35);color:#c4b5fd;transform:translateY(-1px);}',
    '.o-chip.img-chip{background:rgba(96,165,250,.06);border-color:rgba(96,165,250,.14);color:rgba(96,165,250,.7);}',
    '.o-chip.img-chip:hover{background:rgba(96,165,250,.12);border-color:rgba(96,165,250,.35);color:#93c5fd;}',

    /* MESAJ */
    '.o-msg{display:flex;gap:10px;animation:omup .22s ease;max-width:900px;}',
    '@keyframes omup{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:translateY(0)}}',
    '.o-msg.user{align-self:flex-end;flex-direction:row-reverse;}',
    '.o-msg.assistant{align-self:flex-start;}',
    '.o-msg.imgmsg{align-self:flex-start;}',

    '.o-av{width:30px;height:30px;border-radius:8px;flex-shrink:0;display:flex;align-items:center;justify-content:center;}',
    '.o-msg.user .o-av{background:rgba(167,139,250,.12);border:1px solid rgba(167,139,250,.22);}',
    '.o-msg.assistant .o-av,.o-msg.imgmsg .o-av{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);}',

    '.o-bbl{padding:11px 15px;border-radius:13px;font-size:13.5px;line-height:1.75;letter-spacing:.01em;max-width:700px;word-break:break-word;}',
    '.o-msg.user .o-bbl{background:rgba(167,139,250,.1);border:1px solid rgba(167,139,250,.2);',
    'color:rgba(255,255,255,.88);border-bottom-right-radius:3px;}',
    '.o-msg.assistant .o-bbl{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);',
    'color:rgba(255,255,255,.82);border-bottom-left-radius:3px;}',

    /* Markdown */
    '.o-bbl strong{color:#c4b5fd;font-weight:600;}',
    '.o-bbl em{color:rgba(255,255,255,.6);font-style:italic;}',
    '.o-bbl code{font-family:"JetBrains Mono",monospace;font-size:12px;background:rgba(167,139,250,.09);',
    'border:1px solid rgba(167,139,250,.15);padding:1px 5px;border-radius:4px;color:#c4b5fd;}',
    '.o-bbl pre{background:rgba(0,0,0,.55);border:1px solid rgba(167,139,250,.1);border-radius:10px;',
    'padding:13px 15px;overflow-x:auto;margin:10px 0;position:relative;}',
    '.o-bbl pre code{background:none;border:none;padding:0;color:#d4c5b0;font-size:12px;}',
    '.o-cpybtn{position:absolute;top:7px;right:7px;background:rgba(167,139,250,.1);',
    'border:1px solid rgba(167,139,250,.2);color:rgba(255,255,255,.35);padding:2px 8px;',
    'border-radius:5px;font-size:10px;cursor:pointer;font-family:Inter,sans-serif;transition:all .15s;}',
    '.o-cpybtn:hover{color:#a78bfa;border-color:rgba(167,139,250,.5);}',
    '.o-bbl ul,.o-bbl ol{padding-left:18px;margin:5px 0;}',
    '.o-bbl li{margin:3px 0;color:rgba(255,255,255,.75);}',
    '.o-bbl p{margin:4px 0;}',
    '.o-bbl h1,.o-bbl h2,.o-bbl h3{color:#c4b5fd;font-weight:700;margin:11px 0 4px;}',
    '.o-bbl h1{font-size:17px;}.o-bbl h2{font-size:15px;}.o-bbl h3{font-size:13.5px;}',
    '.o-bbl blockquote{border-left:2px solid rgba(167,139,250,.3);padding-left:11px;',
    'color:rgba(255,255,255,.4);font-style:italic;margin:7px 0;}',
    '.o-bbl table{width:100%;border-collapse:collapse;margin:7px 0;font-size:12.5px;}',
    '.o-bbl th{background:rgba(167,139,250,.08);color:#c4b5fd;padding:6px 11px;',
    'text-align:left;border:1px solid rgba(167,139,250,.15);}',
    '.o-bbl td{padding:5px 11px;border:1px solid rgba(255,255,255,.06);color:rgba(255,255,255,.68);}',
    '.o-bbl tr:nth-child(even) td{background:rgba(255,255,255,.02);}',
    '.o-bbl a{color:#93c5fd;text-decoration:underline;text-decoration-color:rgba(147,197,253,.3);}',
    '.o-bbl hr{border:none;border-top:1px solid rgba(255,255,255,.07);margin:10px 0;}',
    '.o-bbl del{color:rgba(255,255,255,.3);}',

    /* Yazıyor */
    '.o-typing{display:flex;gap:4px;align-items:center;padding:3px 0;}',
    '.o-typing span{width:5px;height:5px;background:rgba(167,139,250,.5);border-radius:50%;animation:otyp 1.1s infinite;}',
    '.o-typing span:nth-child(2){animation-delay:.16s;}.o-typing span:nth-child(3){animation-delay:.32s;}',
    '@keyframes otyp{0%,80%,100%{transform:scale(1);opacity:.5}40%{transform:scale(1.4);opacity:1}}',

    /* Resim yuklenme */
    '.o-img-load{display:flex;align-items:center;gap:8px;font-size:12px;color:rgba(96,165,250,.6);padding:8px 0;}',
    '.o-img-spin{width:14px;height:14px;border:2px solid rgba(96,165,250,.2);border-top-color:#60a5fa;',
    'border-radius:50%;animation:ospin .7s linear infinite;}',
    '@keyframes ospin{to{transform:rotate(360deg)}}',

    /* Resim karti */
    '.o-img-card{background:rgba(96,165,250,.05);border:1px solid rgba(96,165,250,.15);',
    'border-radius:14px;overflow:hidden;max-width:520px;}',
    '.o-img-card img{width:100%;display:block;border-radius:0;}',
    '.o-img-card-info{padding:10px 14px;display:flex;justify-content:space-between;align-items:center;}',
    '.o-img-card-prompt{font-size:11px;color:rgba(255,255,255,.3);flex:1;overflow:hidden;',
    'text-overflow:ellipsis;white-space:nowrap;}',
    '.o-img-dl{background:rgba(96,165,250,.1);border:1px solid rgba(96,165,250,.2);',
    'color:#93c5fd;padding:4px 11px;border-radius:6px;font-size:11px;cursor:pointer;',
    'font-family:Inter,sans-serif;transition:all .2s;text-decoration:none;display:inline-block;}',
    '.o-img-dl:hover{background:rgba(96,165,250,.2);}',
    '.o-img-actions{display:flex;gap:6px;margin-top:6px;flex-wrap:wrap;}',
    '.o-img-act-btn{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);',
    'color:rgba(255,255,255,.35);padding:4px 10px;border-radius:6px;font-size:11px;',
    'cursor:pointer;font-family:Inter,sans-serif;transition:all .2s;}',
    '.o-img-act-btn:hover{background:rgba(167,139,250,.1);border-color:rgba(167,139,250,.3);color:#c4b5fd;}',

    /* Hata */
    '.o-err{background:rgba(239,68,68,.07);border:1px solid rgba(239,68,68,.18);',
    'color:rgba(239,68,68,.8);border-radius:10px;padding:9px 13px;font-size:13px;line-height:1.6;}',

    /* Meta */
    '.o-meta{font-size:9.5px;color:rgba(255,255,255,.13);margin-top:3px;padding:0 3px;font-family:"JetBrains Mono",monospace;}',
    '.o-msg.user .o-meta{text-align:right;}',

    /* SIDEBAR */
    '#o-side{width:210px;border-left:1px solid rgba(255,255,255,.05);',
    'padding:20px 16px;display:flex;flex-direction:column;gap:16px;flex-shrink:0;overflow-y:auto;}',
    '#o-side::-webkit-scrollbar{width:2px;}',
    '#o-side::-webkit-scrollbar-thumb{background:rgba(167,139,250,.15);}',
    '.o-sec h4{font-size:9px;font-weight:600;letter-spacing:2px;text-transform:uppercase;',
    'color:rgba(255,255,255,.15);margin-bottom:8px;}',
    '#o-page-info{font-size:11px;color:rgba(255,255,255,.25);line-height:1.5;word-break:break-all;}',

    /* Resim ayarlari */
    '#o-img-settings{display:none;flex-direction:column;gap:8px;}',
    '#o-img-settings.show{display:flex;}',
    '.o-img-sel{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);',
    'color:rgba(255,255,255,.5);padding:5px 8px;border-radius:7px;font-family:Inter,sans-serif;',
    'font-size:11px;cursor:pointer;outline:none;width:100%;transition:border-color .2s;}',
    '.o-img-sel:hover,.o-img-sel:focus{border-color:rgba(96,165,250,.35);color:#93c5fd;}',
    '.o-img-sel option{background:#111118;color:#ccc;}',
    '.o-img-sel-label{font-size:10px;color:rgba(255,255,255,.2);margin-bottom:2px;}',

    '#o-kbs{display:flex;flex-direction:column;gap:6px;}',
    '.o-kb{display:flex;justify-content:space-between;align-items:center;font-size:10.5px;color:rgba(255,255,255,.2);}',
    '.o-key{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);',
    'border-radius:4px;padding:2px 5px;font-family:"JetBrains Mono",monospace;font-size:9px;color:rgba(255,255,255,.28);}',

    '#o-hist-list{display:flex;flex-direction:column;gap:5px;max-height:140px;overflow-y:auto;}',
    '#o-hist-list::-webkit-scrollbar{width:2px;}',
    '.o-hi{font-size:11px;color:rgba(255,255,255,.22);padding:5px 8px;border-radius:7px;',
    'cursor:pointer;border:1px solid transparent;transition:all .18s;',
    'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}',
    '.o-hi:hover{background:rgba(167,139,250,.07);border-color:rgba(167,139,250,.15);color:rgba(255,255,255,.5);}',

    '#o-badge{margin-top:auto;padding-top:12px;border-top:1px solid rgba(255,255,255,.04);',
    'font-size:10px;color:rgba(255,255,255,.12);line-height:1.7;font-family:"JetBrains Mono",monospace;}',

    /* INPUT */
    '#o-inp-area{padding:14px 24px 20px;border-top:1px solid rgba(255,255,255,.06);',
    'background:rgba(8,8,14,.97);backdrop-filter:blur(20px);flex-shrink:0;position:relative;z-index:2;}',

    /* Mod sekmeleri */
    '#o-tabs{display:flex;gap:6px;margin-bottom:10px;}',
    '.o-tab{background:none;border:1px solid rgba(255,255,255,.07);color:rgba(255,255,255,.3);',
    'padding:5px 14px;border-radius:8px;font-family:Inter,sans-serif;font-size:11.5px;cursor:pointer;transition:all .2s;}',
    '.o-tab.active{background:rgba(167,139,250,.12);border-color:rgba(167,139,250,.3);color:#c4b5fd;}',
    '.o-tab.img-tab.active{background:rgba(96,165,250,.12);border-color:rgba(96,165,250,.3);color:#93c5fd;}',

    '#o-inp-wrap{display:flex;align-items:flex-end;gap:9px;',
    'background:rgba(255,255,255,.035);border:1px solid rgba(255,255,255,.08);',
    'border-radius:13px;padding:9px 13px;transition:border-color .2s,box-shadow .2s;}',
    '#o-inp-wrap:focus-within{border-color:rgba(167,139,250,.3);box-shadow:0 0 0 3px rgba(167,139,250,.06);}',
    '#o-inp-wrap.img-mode:focus-within{border-color:rgba(96,165,250,.3);box-shadow:0 0 0 3px rgba(96,165,250,.06);}',

    '#o-ctx-btn{background:none;border:1px solid rgba(255,255,255,.07);color:rgba(255,255,255,.28);',
    'padding:4px 8px;border-radius:6px;font-size:10px;cursor:pointer;font-family:Inter,sans-serif;',
    'transition:all .2s;white-space:nowrap;align-self:flex-end;margin-bottom:2px;}',
    '#o-ctx-btn:hover{border-color:rgba(167,139,250,.3);color:#a78bfa;}',
    '#o-ctx-btn.on{background:rgba(167,139,250,.1);border-color:rgba(167,139,250,.3);color:#a78bfa;}',

    '#o-tx{flex:1;background:none;border:none;outline:none;color:rgba(255,255,255,.88);',
    'font-family:Inter,sans-serif;font-size:13.5px;line-height:1.65;resize:none;',
    'min-height:22px;max-height:180px;overflow-y:auto;}',
    '#o-tx::placeholder{color:rgba(255,255,255,.18);}',
    '#o-tx::-webkit-scrollbar{width:3px;}',
    '#o-tx::-webkit-scrollbar-thumb{background:rgba(167,139,250,.15);}',

    '#o-send{background:linear-gradient(135deg,#7c3aed,#4f46e5);border:none;border-radius:9px;',
    'width:36px;height:36px;cursor:pointer;display:flex;align-items:center;justify-content:center;',
    'flex-shrink:0;transition:all .2s;box-shadow:0 2px 12px rgba(124,58,237,.4);}',
    '#o-send:hover:not(:disabled){transform:scale(1.07);box-shadow:0 4px 20px rgba(124,58,237,.6);}',
    '#o-send:active:not(:disabled){transform:scale(.97);}',
    '#o-send:disabled{opacity:.3;cursor:not-allowed;}',
    '#o-send.img-mode{background:linear-gradient(135deg,#1d4ed8,#0284c7);box-shadow:0 2px 12px rgba(29,78,216,.4);}',
    '#o-send.img-mode:hover:not(:disabled){box-shadow:0 4px 20px rgba(29,78,216,.6);}',

    '#o-stop{background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.22);',
    'color:rgba(239,68,68,.75);padding:4px 12px;border-radius:7px;font-size:11px;',
    'cursor:pointer;font-family:Inter,sans-serif;display:none;transition:all .2s;align-self:flex-end;margin-bottom:2px;}',
    '#o-stop.show{display:block;}',
    '#o-stop:hover{background:rgba(239,68,68,.18);color:#ef4444;}',

    '#o-hint{font-size:10px;color:rgba(255,255,255,.11);margin-top:8px;text-align:center;}',
    '#o-hint kbd{font-family:"JetBrains Mono",monospace;font-size:9px;',
    'background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.09);',
    'border-radius:3px;padding:1px 4px;color:rgba(255,255,255,.22);}',

    /* Model sec */
    '#o-model-sel{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);',
    'color:rgba(255,255,255,.45);padding:4px 9px;border-radius:7px;font-family:Inter,sans-serif;',
    'font-size:10.5px;cursor:pointer;outline:none;transition:border-color .2s;}',
    '#o-model-sel:hover,#o-model-sel:focus{border-color:rgba(167,139,250,.35);color:#a78bfa;}',
    '#o-model-sel option{background:#111118;color:#ccc;}',

    /* Scroll butonu */
    '#o-scrl{position:absolute;bottom:16px;right:24px;background:rgba(167,139,250,.15);',
    'border:1px solid rgba(167,139,250,.25);color:#c4b5fd;width:30px;height:30px;border-radius:50%;',
    'cursor:pointer;display:none;align-items:center;justify-content:center;z-index:5;',
    'font-size:15px;transition:all .2s;}',
    '#o-scrl.show{display:flex;}',
    '#o-scrl:hover{background:rgba(167,139,250,.25);}',

    /* API Key Modal */
    '#o-ak-modal{position:fixed;inset:0;z-index:2147483648;background:rgba(0,0,0,.8);',
    'backdrop-filter:blur(14px);display:flex;align-items:center;justify-content:center;}',
    '#o-ak-box{background:#0c0c14;border:1px solid rgba(167,139,250,.2);border-radius:18px;',
    'padding:34px;width:430px;box-shadow:0 24px 60px rgba(0,0,0,.9);}',
    '#o-ak-box h3{font-size:19px;font-weight:700;color:#fff;margin:0 0 7px;}',
    '#o-ak-box p{font-size:12.5px;color:rgba(255,255,255,.3);margin:0 0 20px;line-height:1.65;}',
    '.o-ak-inp{width:100%;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.09);',
    'border-radius:9px;padding:10px 13px;font-family:"JetBrains Mono",monospace;font-size:12px;',
    'color:rgba(255,255,255,.8);outline:none;margin-bottom:12px;box-sizing:border-box;transition:border-color .2s;}',
    '.o-ak-inp:focus{border-color:rgba(167,139,250,.4);}',
    '#o-ak-save{width:100%;background:linear-gradient(135deg,#7c3aed,#4f46e5);border:none;',
    'border-radius:9px;padding:11px;font-family:Inter,sans-serif;font-size:14px;font-weight:700;',
    'color:#fff;cursor:pointer;transition:box-shadow .2s;}',
    '#o-ak-save:hover{box-shadow:0 4px 20px rgba(124,58,237,.5);}',
    '#o-ak-note{margin-top:11px;font-size:10.5px;color:rgba(255,255,255,.16);text-align:center;}',
    '#o-ak-note a{color:rgba(167,139,250,.55);text-decoration:none;}',
    '#o-ak-note a:hover{color:#a78bfa;}',
    '#o-ak-free-note{background:rgba(74,222,128,.06);border:1px solid rgba(74,222,128,.15);',
    'border-radius:8px;padding:9px 12px;margin-bottom:14px;font-size:11.5px;',
    'color:rgba(74,222,128,.8);line-height:1.6;}',
  ].join(''));

  /* =========================================================
     YARDIMCI
  ========================================================= */
  function esc(s) {
    return String(s)
      .replace(/&/g,'&')
      .replace(/</g,'&lt;')
      .replace(/>/g,'&gt;')
      .replace(/"/g,'&quot;');
  }

  function timeStr() {
    var d = new Date();
    return d.getHours().toString().padStart(2,'0') + ':' + d.getMinutes().toString().padStart(2,'0');
  }

  /* =========================================================
     MARKDOWN
  ========================================================= */
  function md(raw) {
    var s = String(raw);

    // Kod bloglari
    s = s.replace(/```([\w]*)\n?([\s\S]*?)```/g, function(_, lang, code) {
      var id = 'cb' + Math.random().toString(36).slice(2,7);
      var ec = esc(code.trim());
      return '<pre><button class="o-cpybtn" id="' + id + '" onclick="(function(){' +
        'var b=document.getElementById(\'' + id + '\');' +
        'navigator.clipboard.writeText(b.nextSibling.textContent);' +
        'b.textContent=\'Kopyalandi!\';setTimeout(function(){b.textContent=\'Kopyala\'},1500)' +
        '})()">Kopyala</button><code>' + ec + '</code></pre>';
    });

    // Inline kod
    s = s.replace(/`([^`\n]+)`/g, function(_,c){ return '<code>' + esc(c) + '</code>'; });
    // Blockquote (> satirdan once esc yapilacak, bu yuzden &gt; ariyoruz)
    s = s.replace(/^&gt; (.+)$/gm, function(_,t){ return '<blockquote>' + t + '</blockquote>'; });
    // Basliklar
    s = s.replace(/^### (.+)$/gm,'<h3>$1</h3>');
    s = s.replace(/^## (.+)$/gm, '<h2>$1</h2>');
    s = s.replace(/^# (.+)$/gm,  '<h1>$1</h1>');
    // Kalin + italik
    s = s.replace(/\*\*\*(.+?)\*\*\*/g,'<strong><em>$1</em></strong>');
    s = s.replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>');
    s = s.replace(/\*(.+?)\*/g,'<em>$1</em>');
    s = s.replace(/__(.+?)__/g,'<strong>$1</strong>');
    s = s.replace(/_(.+?)_/g,'<em>$1</em>');
    s = s.replace(/~~(.+?)~~/g,'<del>$1</del>');
    // Link
    s = s.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" target="_blank">$1</a>');
    // HR
    s = s.replace(/^[-*_]{3,}$/gm,'<hr>');
    // Tablo
    s = s.replace(/((?:^\|.+\|\n?)+)/gm, function(blk) {
      var rows = blk.trim().split('\n');
      var html = '<table>';
      var head = true;
      for (var i=0;i<rows.length;i++) {
        var row = rows[i].trim();
        if (/^\|[-:| ]+\|$/.test(row)) { head=false; continue; }
        var cells = row.replace(/^\||\|$/g,'').split('|');
        html += '<tr>';
        for (var j=0;j<cells.length;j++) {
          var tag = head ? 'th' : 'td';
          html += '<'+tag+'>'+cells[j].trim()+'</'+tag+'>';
        }
        html += '</tr>';
        if (head) head=false;
      }
      return html + '</table>';
    });
    // Numarali liste
    s = s.replace(/((?:^\d+\. .+\n?)+)/gm, function(blk) {
      var items = blk.trim().split('\n');
      var h = '<ol>';
      for(var i=0;i<items.length;i++) h += '<li>'+items[i].replace(/^\d+\. /,'')+' </li>';
      return h+'</ol>';
    });
    // Sirali liste
    s = s.replace(/((?:^[-*+] .+\n?)+)/gm, function(blk) {
      var items = blk.trim().split('\n');
      var h = '<ul>';
      for(var i=0;i<items.length;i++) h += '<li>'+items[i].replace(/^[-*+] /,'')+' </li>';
      return h+'</ul>';
    });
    // Paragraf
    s = s.replace(/\n{2,}/g,'</p><p>');
    s = s.replace(/\n/g,'<br>');
    return '<p>' + s + '</p>';
  }

  /* =========================================================
     HTML OLUŞTUR
  ========================================================= */
  function buildHTML() {
    var modelOpts = '';
    for (var i=0;i<FREE_MODELS.length;i++) {
      var sel = FREE_MODELS[i].id === OR_MODEL ? ' selected' : '';
      modelOpts += '<option value="'+esc(FREE_MODELS[i].id)+'"'+sel+'>'+esc(FREE_MODELS[i].label)+'</option>';
    }
    var sizeOpts = '';
    for (var j=0;j<IMG_SIZES.length;j++) {
      sizeOpts += '<option value="'+j+'">'+IMG_SIZES[j].label+'</option>';
    }
    var imgModelOpts = '';
    for (var k=0;k<IMG_MODELS.length;k++) {
      imgModelOpts += '<option value="'+k+'">'+IMG_MODELS[k].label+'</option>';
    }

    return [
      '<div id="osiris">',
      '<div id="o-grid"></div>',

      /* HEADER */
      '<div id="o-hdr">',
        '<div id="o-logo">',
          '<svg id="o-logo-icon" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">',
            '<polygon points="13,2 23,23 3,23" fill="none" stroke="url(#og)" stroke-width="1.8"/>',
            '<polygon points="13,7 19,20 7,20" fill="rgba(167,139,250,.15)" stroke="url(#og2)" stroke-width="1"/>',
            '<circle cx="13" cy="13" r="2.2" fill="url(#og)"/>',
            '<defs>',
              '<linearGradient id="og" x1="0" y1="0" x2="1" y2="1">',
                '<stop offset="0%" stop-color="#a78bfa"/>',
                '<stop offset="100%" stop-color="#60a5fa"/>',
              '</linearGradient>',
              '<linearGradient id="og2" x1="0" y1="0" x2="1" y2="1">',
                '<stop offset="0%" stop-color="#a78bfa" stop-opacity=".5"/>',
                '<stop offset="100%" stop-color="#60a5fa" stop-opacity=".5"/>',
              '</linearGradient>',
            '</defs>',
          '</svg>',
          '<div>',
            '<div id="o-logo-text">OSIRIS AI</div>',
            '<div id="o-logo-ver">LIVE v4.0 · UCRETSIZ</div>',
          '</div>',
        '</div>',
        '<div id="o-status"><div id="o-dot"></div><span id="o-stxt">CANLI</span></div>',
        '<div id="o-hdr-r">',
          '<span id="o-tok-info">0 tok</span>',
          '<select id="o-model-sel">'+modelOpts+'</select>',
          '<button class="o-hbtn" id="o-clear-btn">Temizle</button>',
          '<button class="o-hbtn" id="o-ak-btn">🔑 API Anahtari</button>',
          '<button id="o-close">',
            '<svg width="17" height="17" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">',
              '<path d="M18 6L6 18M6 6l12 12"/>',
            '</svg>',
          '</button>',
        '</div>',
      '</div>',

      /* BODY */
      '<div id="o-body">',
        '<div id="o-msgs">',
          '<div id="o-wel">',
            '<svg id="o-wel-icon" viewBox="0 0 64 64" fill="none">',
              '<polygon points="32,3 58,58 6,58" fill="none" stroke="currentColor" stroke-width="2"/>',
              '<circle cx="32" cy="32" r="5" fill="currentColor"/>',
            '</svg>',
            '<h2>OsirisAI Live</h2>',
            '<p>Ucretsiz AI + Resim Uretimi · OpenRouter & Pollinations</p>',
            '<div id="o-chips">',
              '<div class="o-chip" data-p="Bu sayfayi analiz et ve ozetle">📄 Sayfayi ozetle</div>',
              '<div class="o-chip" data-p="Adim adim anlat:">📚 Anlat</div>',
              '<div class="o-chip" data-p="Kod yaz ve acikla:">⚡ Kod yaz</div>',
              '<div class="o-chip" data-p="Fikir uret hakkinda:">💡 Fikir uret</div>',
              '<div class="o-chip img-chip" data-p="__IMG__beautiful fantasy landscape, magical forest, glowing lights" data-img="1">🎨 Fantazi manzara</div>',
              '<div class="o-chip img-chip" data-p="__IMG__futuristic city at night, neon lights, cyberpunk" data-img="1">🌆 Siber sehir</div>',
              '<div class="o-chip img-chip" data-p="__IMG__cute anime character, big eyes, colorful hair" data-img="1">✨ Anime karakter</div>',
              '<div class="o-chip img-chip" data-p="__IMG__realistic portrait of a person, professional photo" data-img="1">📷 Gercekci portre</div>',
            '</div>',
          '</div>',
        '</div>',
        '<button id="o-scrl">↓</button>',

        /* SIDEBAR */
        '<div id="o-side">',
          '<div class="o-sec"><h4>Sayfa</h4><div id="o-page-info"></div></div>',
          '<div class="o-sec" id="o-img-sec">',
            '<h4>Resim Ayarlari</h4>',
            '<div id="o-img-settings">',
              '<div>',
                '<div class="o-img-sel-label">Model</div>',
                '<select class="o-img-sel" id="o-imgmodel-sel">'+imgModelOpts+'</select>',
              '</div>',
              '<div>',
                '<div class="o-img-sel-label">Boyut</div>',
                '<select class="o-img-sel" id="o-imgsize-sel">'+sizeOpts+'</select>',
              '</div>',
            '</div>',
            '<div id="o-img-settings-off" style="font-size:11px;color:rgba(255,255,255,.2)">',
              'Resim modu icin asagidaki <strong style="color:rgba(96,165,250,.5)">🎨 Resim</strong> sekmesini ac.',
            '</div>',
          '</div>',
          '<div class="o-sec">',
            '<h4>Son Sorular</h4>',
            '<div id="o-hist-list"><div style="font-size:11px;color:rgba(255,255,255,.1)">Henuz yok</div></div>',
          '</div>',
          '<div class="o-sec">',
            '<h4>Kisayollar</h4>',
            '<div id="o-kbs">',
              '<div class="o-kb"><span>Ac/Kapat</span><span class="o-key">Ctrl+E</span></div>',
              '<div class="o-kb"><span>Gonder</span><span class="o-key">Enter</span></div>',
              '<div class="o-kb"><span>Yeni satir</span><span class="o-key">Shift+↵</span></div>',
              '<div class="o-kb"><span>Temizle</span><span class="o-key">Ctrl+L</span></div>',
            '</div>',
          '</div>',
          '<div id="o-badge">OpenRouter: Aktif<br>Pollinations: Aktif<br>Streaming: Aktif</div>',
        '</div>',
      '</div>',

      /* INPUT */
      '<div id="o-inp-area">',
        '<div id="o-tabs">',
          '<button class="o-tab active" id="o-tab-chat">💬 Sohbet</button>',
          '<button class="o-tab img-tab" id="o-tab-img">🎨 Resim Uret</button>',
        '</div>',
        '<div id="o-inp-wrap">',
          '<button id="o-ctx-btn">📋 Sayfa</button>',
          '<textarea id="o-tx" rows="1" placeholder="Bir sey sor..."></textarea>',
          '<button id="o-stop">Dur</button>',
          '<button id="o-send">',
            '<svg width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">',
              '<path d="M22 2L11 13M22 2L15 22l-4-9-9-4 20-7z"/>',
            '</svg>',
          '</button>',
        '</div>',
        '<div id="o-hint">',
          '<kbd>Enter</kbd> gonder &nbsp;·&nbsp; <kbd>Shift+Enter</kbd> satir &nbsp;·&nbsp; <kbd>Esc</kbd> kapat',
        '</div>',
      '</div>',

      '</div>'
    ].join('');
  }

  /* =========================================================
     OVERLAY
  ========================================================= */
  function buildOverlay() {
    var c = document.createElement('div');
    c.innerHTML = buildHTML();
    document.body.appendChild(c.firstChild);
    initEvents();
    updatePageInfo();
  }

  /* =========================================================
     SAYFA BİLGİSİ
  ========================================================= */
  function updatePageInfo() {
    var el = document.getElementById('o-page-info');
    if (!el) return;
    var fav = document.querySelector('link[rel~="icon"]');
    var img = fav ? '<img style="width:14px;height:14px;vertical-align:middle;margin-right:4px;border-radius:2px" src="'+esc(fav.href)+'" onerror="this.style.display=\'none\'">' : '';
    var title = document.title.length > 32 ? document.title.slice(0,32)+'…' : document.title;
    el.innerHTML = img + '<strong style="color:rgba(255,255,255,.35)">'+esc(title)+'</strong>' +
                   '<br><span style="color:rgba(255,255,255,.16)">'+esc(window.location.hostname)+'</span>';
  }

  function getCtx() {
    var sel = window.getSelection ? window.getSelection().toString().trim() : '';
    return '\n\n---\n[SAYFA BAGLAMI]\nURL: '+window.location.href+'\nBaslik: '+document.title+'\n' +
      (sel ? 'Secili Metin:\n'+sel : 'Sayfa Icerigi:\n'+(document.body ? document.body.innerText.slice(0,2500) : '')) +
      '\n---\n';
  }

  /* =========================================================
     MESAJ EKLE
  ========================================================= */
  function clearWel() { var w=document.getElementById('o-wel'); if(w) w.parentNode.removeChild(w); }

  function scrollBot() {
    var m = document.getElementById('o-msgs');
    if (m) { m.scrollTop = m.scrollHeight; userScrolled = false; }
  }

  function addMsg(role, content, streaming) {
    clearWel();
    var cont = document.getElementById('o-msgs');
    if (!cont) return null;

    var wrap = document.createElement('div');
    wrap.className = 'o-msg ' + role;

    var av = document.createElement('div');
    av.className = 'o-av';
    av.innerHTML = role === 'user'
      ? '<svg width="13" height="13" fill="none" stroke="#a78bfa" stroke-width="2" viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>'
      : '<svg width="13" height="13" viewBox="0 0 26 26" fill="none"><polygon points="13,2 23,23 3,23" fill="none" stroke="#a78bfa" stroke-width="1.8"/><circle cx="13" cy="13" r="2.2" fill="#a78bfa"/></svg>';

    var bbl = document.createElement('div');
    bbl.className = 'o-bbl';

    if (streaming) {
      bbl.innerHTML = '<span class="o-typing"><span></span><span></span><span></span></span>';
      activeBub = bbl;
    } else {
      bbl.innerHTML = role === 'user' ? esc(content).replace(/\n/g,'<br>') : md(content);
    }

    var meta = document.createElement('div');
    meta.className = 'o-meta';
    meta.textContent = timeStr() + (role === 'user' ? ' · Sen' : ' · Osiris');

    var inner = document.createElement('div');
    inner.appendChild(bbl);
    inner.appendChild(meta);

    wrap.appendChild(av);
    wrap.appendChild(inner);
    cont.appendChild(wrap);
    if (!userScrolled) scrollBot();
    return bbl;
  }

  /* =========================================================
     RESİM EKLE
  ========================================================= */
  function addImgMsg(prompt, url) {
    clearWel();
    var cont = document.getElementById('o-msgs');
    if (!cont) return;

    var wrap = document.createElement('div');
    wrap.className = 'o-msg imgmsg';

    var av = document.createElement('div');
    av.className = 'o-av';
    av.innerHTML = '<svg width="13" height="13" viewBox="0 0 26 26" fill="none"><polygon points="13,2 23,23 3,23" fill="none" stroke="#60a5fa" stroke-width="1.8"/><circle cx="13" cy="13" r="2.2" fill="#60a5fa"/></svg>';

    var inner = document.createElement('div');
    inner.style.maxWidth = '520px';

    var card = document.createElement('div');
    card.className = 'o-img-card';

    var imgEl = document.createElement('img');
    imgEl.src = url;
    imgEl.alt = prompt;
    imgEl.style.cssText = 'width:100%;display:block;cursor:pointer;';
    imgEl.onclick = function() { window.open(url, '_blank'); };
    imgEl.onerror = function() {
      card.innerHTML = '<div class="o-err" style="margin:0;border-radius:0">Resim yuklenemedi. Tekrar dene.</div>';
    };

    var info = document.createElement('div');
    info.className = 'o-img-card-info';

    var pEl = document.createElement('div');
    pEl.className = 'o-img-card-prompt';
    pEl.textContent = prompt;

    var dlA = document.createElement('a');
    dlA.className = 'o-img-dl';
    dlA.href = url;
    dlA.target = '_blank';
    dlA.download = 'osiris-' + Date.now() + '.jpg';
    dlA.textContent = '⬇ İndir';

    info.appendChild(pEl);
    info.appendChild(dlA);

    // Varyasyon ve yeniden uret butonlari
    var actions = document.createElement('div');
    actions.className = 'o-img-actions';

    var regen = document.createElement('button');
    regen.className = 'o-img-act-btn';
    regen.textContent = '🔄 Yeniden Uret';
    regen.onclick = function() { generateImage(prompt); };

    var vary = document.createElement('button');
    vary.className = 'o-img-act-btn';
    vary.textContent = '✨ Varyasyon';
    vary.onclick = function() {
      var vPrompt = prompt + ', variation, different composition, ' + Math.random().toString(36).slice(2,6);
      generateImage(vPrompt);
    };

    var copyUrl = document.createElement('button');
    copyUrl.className = 'o-img-act-btn';
    copyUrl.textContent = '🔗 URL Kopyala';
    copyUrl.onclick = function() {
      navigator.clipboard.writeText(url);
      copyUrl.textContent = 'Kopyalandi!';
      setTimeout(function(){ copyUrl.textContent = '🔗 URL Kopyala'; }, 1500);
    };

    actions.appendChild(regen);
    actions.appendChild(vary);
    actions.appendChild(copyUrl);

    card.appendChild(imgEl);
    card.appendChild(info);

    var meta = document.createElement('div');
    meta.className = 'o-meta';
    meta.textContent = timeStr() + ' · Osiris · ' + imgModel.label + ' · ' + imgSize.w + 'x' + imgSize.h;

    inner.appendChild(card);
    inner.appendChild(actions);
    inner.appendChild(meta);

    wrap.appendChild(av);
    wrap.appendChild(inner);
    cont.appendChild(wrap);
    if (!userScrolled) scrollBot();
  }

  /* =========================================================
     RESİM ÜRET (Pollinations.ai)
  ========================================================= */
  function generateImage(prompt) {
    if (isThinking) return;
    isThinking = true;
    setStatus('img');

    clearWel();
    var cont = document.getElementById('o-msgs');

    // Kullanici mesaji
    var userWrap = document.createElement('div');
    userWrap.className = 'o-msg user';
    var userAv = document.createElement('div');
    userAv.className = 'o-av';
    userAv.innerHTML = '<svg width="13" height="13" fill="none" stroke="#a78bfa" stroke-width="2" viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>';
    var userBbl = document.createElement('div');
    userBbl.className = 'o-bbl';
    userBbl.innerHTML = '🎨 ' + esc(prompt);
    var uMeta = document.createElement('div');
    uMeta.className = 'o-meta';
    uMeta.textContent = timeStr() + ' · Sen · Resim';
    var uInner = document.createElement('div');
    uInner.appendChild(userBbl);
    uInner.appendChild(uMeta);
    userWrap.appendChild(userAv);
    userWrap.appendChild(uInner);
    cont.appendChild(userWrap);

    // Yukleme gostergesi
    var loadWrap = document.createElement('div');
    loadWrap.className = 'o-msg imgmsg';
    var loadAv = document.createElement('div');
    loadAv.className = 'o-av';
    loadAv.innerHTML = '<svg width="13" height="13" viewBox="0 0 26 26" fill="none"><polygon points="13,2 23,23 3,23" fill="none" stroke="#60a5fa" stroke-width="1.8"/><circle cx="13" cy="13" r="2.2" fill="#60a5fa"/></svg>';
    var loadInner = document.createElement('div');
    loadInner.innerHTML = '<div class="o-img-load"><div class="o-img-spin"></div><span>Resim uretiliyor... ('+ imgModel.label +' · '+ imgSize.w+'x'+imgSize.h+')</span></div>';
    loadWrap.appendChild(loadAv);
    loadWrap.appendChild(loadInner);
    cont.appendChild(loadWrap);
    scrollBot();

    addToHist('[Resim] ' + prompt);

    // Pollinations URL
    var encodedPrompt = encodeURIComponent(prompt);
    var seed = Math.floor(Math.random() * 999999);
    var url = 'https://image.pollinations.ai/prompt/' + encodedPrompt +
      '?model=' + imgModel.id +
      '&width=' + imgSize.w +
      '&height=' + imgSize.h +
      '&seed=' + seed +
      '&nologo=true' +
      '&enhance=true';

    // Resmi preload et
    var testImg = new Image();
    testImg.onload = function() {
      cont.removeChild(loadWrap);
      addImgMsg(prompt, url);
      isThinking = false;
      setStatus('live');
    };
    testImg.onerror = function() {
      loadInner.innerHTML = '<div class="o-err">Resim uretimi basarisiz. Farkli bir prompt dene.</div>';
      isThinking = false;
      setStatus('live');
    };
    testImg.src = url;
  }

  /* =========================================================
     TOKEN / STATUS / GEÇMİŞ
  ========================================================= */
  function setStatus(s) {
    var dot = document.getElementById('o-dot');
    var txt = document.getElementById('o-stxt');
    var stop = document.getElementById('o-stop');
    var send = document.getElementById('o-send');
    if (!dot) return;
    dot.className = '';
    if (s === 'busy') {
      dot.classList.add('busy');
      if (txt) txt.textContent = 'DUSUNUYOR';
      if (stop) stop.classList.add('show');
      if (send) send.disabled = true;
    } else if (s === 'img') {
      dot.classList.add('img');
      if (txt) txt.textContent = 'RESIM URETILIYOR';
      if (send) send.disabled = true;
    } else {
      if (txt) txt.textContent = 'CANLI';
      if (stop) stop.classList.remove('show');
      if (send) send.disabled = false;
    }
  }

  function updTok(n) {
    totalTok += n;
    var el = document.getElementById('o-tok-info');
    if (el) el.textContent = totalTok + ' tok';
  }

  function addToHist(txt) {
    var label = txt.length > 42 ? txt.slice(0,42)+'…' : txt;
    sessionHist.unshift(label);
    if (sessionHist.length > 8) sessionHist.pop();
    renderHist();
  }

  function renderHist() {
    var list = document.getElementById('o-hist-list');
    if (!list) return;
    if (!sessionHist.length) {
      list.innerHTML = '<div style="font-size:11px;color:rgba(255,255,255,.1)">Henuz yok</div>';
      return;
    }
    var h = '';
    for (var i=0;i<sessionHist.length;i++) {
      h += '<div class="o-hi" data-i="'+i+'">'+esc(sessionHist[i])+'</div>';
    }
    list.innerHTML = h;
    var items = list.querySelectorAll('.o-hi');
    for (var j=0;j<items.length;j++) {
      (function(item){
        item.onclick = function() {
          var tx = document.getElementById('o-tx');
          var val = sessionHist[parseInt(item.getAttribute('data-i'),10)];
          if (tx && val) { tx.value = val; tx.focus(); }
        };
      })(items[j]);
    }
  }

  /* =========================================================
     API ÇAĞRISI — OpenRouter Streaming
  ========================================================= */
  function sendToAI(userText) {
    if (!OR_KEY) { showApiModal(); return; }
    if (isThinking) return;

    isThinking = true;
    setStatus('busy');
    streamBuf = '';
    lastPos = 0;

    var content = inclCtx ? userText + getCtx() : userText;
    messages.push({ role:'user', content:content });
    addMsg('user', userText, false);
    addToHist(userText);

    var bbl = addMsg('assistant', '', true);

    var payload = JSON.stringify({
      model: OR_MODEL,
      max_tokens: MAX_TOK,
      stream: true,
      messages: [{ role:'system', content:SYS }].concat(messages)
    });

    curReq = GM_xmlhttpRequest({
      method: 'POST',
      url: 'https://openrouter.ai/api/v1/chat/completions',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + OR_KEY,
        'HTTP-Referer': 'https://osirisai.live',
        'X-Title': 'OsirisAI Live'
      },
      data: payload,
      responseType: 'text',

      onprogress: function(res) {
        var chunk = res.responseText.slice(lastPos);
        lastPos = res.responseText.length;
        var lines = chunk.split('\n');
        for (var i=0;i<lines.length;i++) {
          var line = lines[i].trim();
          if (line.indexOf('data: ') !== 0) continue;
          var json = line.slice(6).trim();
          if (json === '[DONE]') continue;
          try {
            var evt = JSON.parse(json);
            var delta = evt.choices && evt.choices[0] && evt.choices[0].delta;
            if (delta && delta.content) {
              streamBuf += delta.content;
              if (bbl) {
                bbl.innerHTML = md(streamBuf);
                if (!userScrolled) scrollBot();
              }
            }
            if (evt.usage && evt.usage.completion_tokens) updTok(evt.usage.completion_tokens);
          } catch(e) {}
        }
      },

      onload: function(res) {
        if (!streamBuf) {
          try {
            var data = JSON.parse(res.responseText);
            if (data.choices && data.choices[0] && data.choices[0].message) {
              streamBuf = data.choices[0].message.content || '';
              if (bbl) bbl.innerHTML = md(streamBuf);
            } else if (data.error) {
              if (bbl) bbl.innerHTML = '<div class="o-err">OpenRouter Hatasi: '+esc(data.error.message||'Bilinmeyen hata')+'</div>';
            }
          } catch(e) {}
        }
        if (streamBuf) messages.push({ role:'assistant', content:streamBuf });
        finishReq();
      },

      onerror: function(err) {
        if (bbl) bbl.innerHTML = '<div class="o-err">Baglanti hatasi. OpenRouter API anahtarini kontrol et.<br>' +
          '<small style="opacity:.5">'+esc((err.statusText||'')+' '+(err.status||''))+'</small></div>';
        finishReq();
      },

      ontimeout: function() {
        if (bbl) bbl.innerHTML = '<div class="o-err">Zaman asimi (timeout). Tekrar dene.</div>';
        finishReq();
      }
    });
  }

  function finishReq() {
    isThinking = false;
    curReq = null;
    activeBub = null;
    setStatus('live');
    var tx = document.getElementById('o-tx');
    if (tx) tx.focus();
  }

  /* =========================================================
     GÖNDER
  ========================================================= */
  function doSend() {
    var tx = document.getElementById('o-tx');
    if (!tx) return;
    var text = tx.value.replace(/^\s+|\s+$/g,'');
    if (!text || isThinking) return;
    tx.value = '';
    tx.style.height = 'auto';

    if (imgMode) {
      generateImage(text);
    } else {
      sendToAI(text);
    }
  }

  /* =========================================================
     API KEY MODAL (OpenRouter)
  ========================================================= */
  function showApiModal() {
    var old = document.getElementById('o-ak-modal');
    if (old) old.parentNode.removeChild(old);

    var modal = document.createElement('div');
    modal.id = 'o-ak-modal';
    modal.innerHTML = [
      '<div id="o-ak-box">',
        '<h3>🔑 OpenRouter API Anahtari</h3>',
        '<div id="o-ak-free-note">',
          '✅ OpenRouter ucretsiz modeller sunuyor!<br>',
          'Kayit ol → Anahtar olustur → Ucretsiz kullan.',
        '</div>',
        '<p>openrouter.ai adresinden ucretsiz anahtar alin. Kredi karti gerekmez.</p>',
        '<input type="password" class="o-ak-inp" id="o-ak-inp" placeholder="sk-or-v1-..." value="'+esc(OR_KEY)+'"/>',
        '<button id="o-ak-save">Kaydet ve Devam Et</button>',
        '<div id="o-ak-note">',
          'Kayit: <a href="https://openrouter.ai/keys" target="_blank">openrouter.ai/keys</a> · ',
          'Ucretsiz modeller: Mistral, Llama, Gemma, Qwen, DeepSeek',
        '</div>',
      '</div>'
    ].join('');

    document.body.appendChild(modal);
    var inp = document.getElementById('o-ak-inp');
    if (inp) inp.focus();
    var saveBtn = document.getElementById('o-ak-save');
    if (saveBtn) {
      saveBtn.onclick = function() {
        var val = inp ? inp.value.replace(/^\s+|\s+$/g,'') : '';
        if (val.length > 5) {
          OR_KEY = val;
          GM_setValue('osiris_or_key', val);
          modal.parentNode.removeChild(modal);
        } else {
          if (inp) inp.style.borderColor = 'rgba(239,68,68,.5)';
        }
      };
    }
    modal.onclick = function(e) { if (e.target===modal) modal.parentNode.removeChild(modal); };
    if (inp) inp.onkeydown = function(e) { if (e.keyCode===13 && saveBtn) saveBtn.click(); };
  }

  /* =========================================================
     MOD DEĞIŞIMI (Sohbet / Resim)
  ========================================================= */
  function setImgMode(on) {
    imgMode = on;
    var chatTab = document.getElementById('o-tab-chat');
    var imgTab  = document.getElementById('o-tab-img');
    var wrap    = document.getElementById('o-inp-wrap');
    var send    = document.getElementById('o-send');
    var tx      = document.getElementById('o-tx');
    var imgSets = document.getElementById('o-img-settings');
    var imgOff  = document.getElementById('o-img-settings-off');
    var dot     = document.getElementById('o-dot');
    var ctxBtn  = document.getElementById('o-ctx-btn');

    if (on) {
      if (chatTab) chatTab.classList.remove('active');
      if (imgTab)  imgTab.classList.add('active');
      if (wrap)    wrap.classList.add('img-mode');
      if (send)    send.classList.add('img-mode');
      if (tx)      tx.placeholder = 'Resim aciklamasi gir... (Ingilizce daha iyi sonuc verir)';
      if (imgSets) imgSets.classList.add('show');
      if (imgOff)  imgOff.style.display = 'none';
      if (ctxBtn)  ctxBtn.style.display = 'none';
    } else {
      if (chatTab) chatTab.classList.add('active');
      if (imgTab)  imgTab.classList.remove('active');
      if (wrap)    wrap.classList.remove('img-mode');
      if (send)    send.classList.remove('img-mode');
      if (tx)      tx.placeholder = 'Bir sey sor...';
      if (imgSets) imgSets.classList.remove('show');
      if (imgOff)  imgOff.style.display = '';
      if (ctxBtn)  ctxBtn.style.display = '';
    }
  }

  /* =========================================================
     CHIP
  ========================================================= */
  function bindChips() {
    var chips = document.querySelectorAll('#o-chips .o-chip');
    for (var i=0;i<chips.length;i++) {
      (function(chip){
        chip.onclick = function() {
          var p = chip.getAttribute('data-p');
          var isImg = chip.getAttribute('data-img') === '1';
          if (isImg) {
            var prompt = p.replace('__IMG__','');
            setImgMode(true);
            generateImage(prompt);
          } else {
            var tx = document.getElementById('o-tx');
            if (tx) { tx.value = p; tx.focus(); }
          }
        };
      })(chip);
    }
  }

  /* =========================================================
     EVENTS
  ========================================================= */
  function initEvents() {
    /* Kapat */
    var cl = document.getElementById('o-close');
    if (cl) cl.onclick = function() { toggle(false); };

    /* Temizle */
    var clrBtn = document.getElementById('o-clear-btn');
    if (clrBtn) {
      clrBtn.onclick = function() {
        messages = []; totalTok = 0;
        var tk = document.getElementById('o-tok-info'); if (tk) tk.textContent='0 tok';
        var cont = document.getElementById('o-msgs'); if (!cont) return;
        cont.innerHTML = [
          '<div id="o-wel">',
            '<svg id="o-wel-icon" viewBox="0 0 64 64" fill="none">',
              '<polygon points="32,3 58,58 6,58" fill="none" stroke="currentColor" stroke-width="2"/>',
              '<circle cx="32" cy="32" r="5" fill="currentColor"/>',
            '</svg>',
            '<h2>OsirisAI Live</h2>',
            '<p>Ucretsiz AI + Resim Uretimi · OpenRouter & Pollinations</p>',
            '<div id="o-chips">',
              '<div class="o-chip" data-p="Bu sayfayi analiz et ve ozetle">📄 Sayfayi ozetle</div>',
              '<div class="o-chip" data-p="Adim adim anlat:">📚 Anlat</div>',
              '<div class="o-chip" data-p="Kod yaz ve acikla:">⚡ Kod yaz</div>',
              '<div class="o-chip" data-p="Fikir uret hakkinda:">💡 Fikir uret</div>',
              '<div class="o-chip img-chip" data-p="__IMG__beautiful fantasy landscape, magical forest, glowing lights" data-img="1">🎨 Fantazi manzara</div>',
              '<div class="o-chip img-chip" data-p="__IMG__futuristic city at night, neon lights, cyberpunk" data-img="1">🌆 Siber sehir</div>',
              '<div class="o-chip img-chip" data-p="__IMG__cute anime character, big eyes, colorful hair" data-img="1">✨ Anime karakter</div>',
              '<div class="o-chip img-chip" data-p="__IMG__realistic portrait of a person, professional photo" data-img="1">📷 Gercekci portre</div>',
            '</div>',
          '</div>'
        ].join('');
        bindChips();
      };
    }

    /* API Key */
    var ak = document.getElementById('o-ak-btn');
    if (ak) ak.onclick = showApiModal;

    /* Model sec */
    var ms = document.getElementById('o-model-sel');
    if (ms) {
      ms.onchange = function() {
        OR_MODEL = ms.value;
        GM_setValue('osiris_model', OR_MODEL);
      };
    }

    /* Resim model */
    var ims = document.getElementById('o-imgmodel-sel');
    if (ims) {
      ims.onchange = function() {
        imgModel = IMG_MODELS[parseInt(ims.value,10)];
      };
    }

    /* Resim boyut */
    var iss = document.getElementById('o-imgsize-sel');
    if (iss) {
      iss.onchange = function() {
        imgSize = IMG_SIZES[parseInt(iss.value,10)];
      };
    }

    /* Mod sekmeleri */
    var tabChat = document.getElementById('o-tab-chat');
    var tabImg  = document.getElementById('o-tab-img');
    if (tabChat) tabChat.onclick = function() { setImgMode(false); };
    if (tabImg)  tabImg.onclick  = function() { setImgMode(true);  };

    /* Context */
    var ctx = document.getElementById('o-ctx-btn');
    if (ctx) {
      ctx.onclick = function() {
        inclCtx = !inclCtx;
        if (inclCtx) ctx.classList.add('on'); else ctx.classList.remove('on');
      };
    }

    /* Durdur */
    var stop = document.getElementById('o-stop');
    if (stop) {
      stop.onclick = function() {
        if (curReq && curReq.abort) curReq.abort();
        if (streamBuf && activeBub) {
          activeBub.innerHTML = md(streamBuf) + '<br><small style="color:rgba(255,255,255,.25)">[Durduruldu]</small>';
          messages.push({ role:'assistant', content:streamBuf+' [Durduruldu]' });
        }
        finishReq();
      };
    }

    /* Textarea */
    var tx = document.getElementById('o-tx');
    if (tx) {
      tx.addEventListener('input', function() {
        tx.style.height = 'auto';
        tx.style.height = Math.min(tx.scrollHeight,180) + 'px';
      });
      tx.addEventListener('keydown', function(e) {
        if (e.keyCode === 13 && !e.shiftKey) { e.preventDefault(); doSend(); }
      });
    }

    /* Gonder */
    var snd = document.getElementById('o-send');
    if (snd) snd.onclick = doSend;

    /* Scroll */
    var msgs = document.getElementById('o-msgs');
    var scrl = document.getElementById('o-scrl');
    if (msgs && scrl) {
      msgs.addEventListener('scroll', function() {
        var fromBot = msgs.scrollHeight - msgs.scrollTop - msgs.clientHeight;
        if (fromBot > 100) {
          userScrolled = true;
          scrl.classList.add('show');
        } else {
          userScrolled = false;
          scrl.classList.remove('show');
        }
      });
      scrl.onclick = function() { scrollBot(); scrl.classList.remove('show'); };
    }

    /* Chips */
    bindChips();
  }

  /* =========================================================
     WELCOME YENİLE
  ========================================================= */

  /* =========================================================
     AÇ / KAPAT
  ========================================================= */
  function toggle(force) {
    var el = document.getElementById('osiris');
    if (!el) return;
    isOpen = force !== undefined ? !!force : !isOpen;
    if (isOpen) {
      el.classList.add('on');
      updatePageInfo();
      setTimeout(function() {
        var tx = document.getElementById('o-tx');
        if (tx) tx.focus();
      }, 200);
      if (!OR_KEY) setTimeout(showApiModal, 350);
    } else {
      el.classList.remove('on');
    }
  }

  /* =========================================================
     KLAVYE
  ========================================================= */
  document.addEventListener('keydown', function(e) {
    // Ctrl+Shift+E
    if (e.ctrlKey && e.shiftKey && (e.keyCode === 69 || e.key === 'E' || e.key === 'e')) {
      e.preventDefault();
      toggle();
    }
    // Esc
    if ((e.keyCode === 27 || e.key === 'Escape') && isOpen) {
      var modal = document.getElementById('o-ak-modal');
      if (modal) modal.parentNode.removeChild(modal);
      else toggle(false);
    }
    // Ctrl+L
    if (e.ctrlKey && (e.keyCode === 76 || e.key === 'l') && isOpen) {
      e.preventDefault();
      var c = document.getElementById('o-clear-btn');
      if (c) c.click();
    }
  });

  /* =========================================================
     BAŞLAT
  ========================================================= */
  buildOverlay();

  console.log(
    '%c▲ OsirisAI Live v4 %c Ctrl+Shift+E · Ucretsiz AI + Resim',
    'color:#a78bfa;font-weight:700;font-size:12px;background:#0d0d18;padding:3px 8px;border-radius:4px',
    'color:rgba(255,255,255,.35);font-size:11px'
  );

})();