<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>PRISMA EVO X | Modern Pro</title>

    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&family=JetBrains+Mono:wght@400;700&family=swap" rel="stylesheet">

    <style>

        :root {

            --accent: #FFFFFF;

            --bg: #0a0a0c;

            --panel: rgba(20, 20, 25, 0.8);

            --border: rgba(255, 255, 255, 0.08);

            --text: #e0e0e0;

            --subtext: #888;

        }


        body {

            margin: 0;

            height: 100vh;

            display: flex;

            background: var(--bg);

            color: var(--text);

            font-family: 'Inter', sans-serif;

            overflow: hidden;

        }


        /* --- SIDEBAR --- */

        .sidebar {

            width: 600px;

            background: var(--panel);

            backdrop-filter: blur(20px);

            border-right: 1px solid var(--border);

            display: flex;

            flex-direction: column;

            z-index: 100;

            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);

        }


        .header {

            padding: 40px 30px;

            background: linear-gradient(to bottom, rgba(0,0,0,0.2), transparent);

        }


        /* Logo Ayarı */

        .header img {

            max-width: 180px;

            height: auto;

            display: block;

        }


        .header .version {

            font-family: 'JetBrains Mono';

            font-size: 9px;

            color: var(--subtext);

            margin-top: 8px;

            display: block;

            letter-spacing: 2px;

        }


        .scroll {

            flex: 1;

            overflow-y: auto;

            padding: 0 25px 40px;

            mask-image: linear-gradient(to bottom, transparent, black 5%, black 95%, transparent);

        }


        .scroll::-webkit-scrollbar { width: 4px; }

        .scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 10px; }


        /* --- GRID & BUTTONS --- */

        .cat-title {

            font-size: 16px;

            color: var(--subtext);

            margin: 35px 0 15px;

            font-weight: 600;

            text-transform: uppercase;

            letter-spacing: 1.5px;

            display: flex;

            align-items: center;

            gap: 10px;

        }


        .cat-title::after {

            content: '';

            flex: 1;

            height: 1px;

            background: var(--border);

        }


        .grid {

            display: grid;

            grid-template-columns: repeat(2, 1fr);

            gap: 10px;

        }


        .btn {

            background: rgba(255,255,255,0.03);

            border: 1px solid var(--border);

            color: #ccc;

            font-size: 16px;

            padding: 12px 10px;

            cursor: pointer;

            transition: all 0.25s ease;

            border-radius: 8px;

            text-align: center;

            font-family: 'Inter';

        }


        .btn:hover {

            background: rgba(255,255,255,0.08);

            border-color: var(--accent);

            color: #fff;

            transform: translateY(-2px);

        }


        .btn.active {

            background: var(--accent);

            color: #000;

            font-weight: 700;

            border-color: var(--accent);

            box-shadow: 0 8px 20px rgba(0, 2, 4, 0.1);

        }


        /* --- VIEWPORT --- */

        .viewport {

            flex: 1;

            display: flex;

            flex-direction: column;

            padding: 40px;

            position: relative;

            background: radial-gradient(circle at center, #16161a 0%, #0a0a0c 100%);

        }


        .main-controls {

            margin-bottom: 30px;

            display: flex;

            justify-content: flex-end;

            align-items: center;

            gap: 10px;

        }


        /* Mobil Logo Stili */

        .mobile-logo {

            display: none; /* Masaüstünde gizli */

            max-width: 240px;

            height: auto;

            margin-right: auto; /* Sola yaslar */

        }


        canvas {

            max-width: 100%;

            max-height: 65vh;

            border-radius: 16px;

            background: #000;

            box-shadow: 0 30px 60px rgba(0,0,0,0.5);

            transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);

            object-fit: contain;

            margin: auto;

            display: none;

        }


        .file-btn {

            background: transparent;

            border: 1px solid var(--border);

            color: var(--text);

            padding: 12px 28px;

            cursor: pointer;

            font-weight: 600;

            font-size: 13px;

            border-radius: 50px;

            transition: 0.3s;

            display: inline-flex;

            align-items: center;

            gap: 8px;

        }


        .file-btn:hover {

            transform: scale(1.05);

            box-shadow: 0 0 30px rgba(255,255,255,0.2);

            border-color: var(--accent);

        }


        .action-btns {

            display: none;

            gap: 10px;

            flex: 1;

            justify-content: flex-end;

        }


        #up { display: none; }


        .upload-area {

            position: absolute;

            top: 50%;

            left: 50%;

            transform: translate(-50%, -50%);

            width: 80%;

            max-width: 600px;

            height: 300px;

            border: 2px dashed #999;

            border-radius: 20px;

            display: flex;

            flex-direction: column;

            justify-content: center;

            align-items: center;

            color: var(--subtext);

            cursor: pointer;

            transition: 0.3s;

        }


        .upload-area:hover {

            border-color: var(--accent);

            background: rgba(255,255,255,0.2);

            color: #fff;

        }


        .upload-area svg {

            width: 48px;

            height: 48px;

            margin-bottom: 20px;

        }


        #loader {

            position: absolute;

            top: 50%;

            left: 50%;

            transform: translate(-50%,-50%);

            padding: 20px 40px;

            background: rgba(0,0,0,0.8);

            backdrop-filter: blur(10px);

            border-radius: 12px;

            font-family: 'JetBrains Mono';

            letter-spacing: 2px;

            border: 1px solid var(--accent);

            display: none;

            z-index: 200;

        }


        .stats {

            font-family: 'JetBrains Mono';

            font-size: 10px;

            color: var(--subtext);

            margin-top: 10px;

        }


        .mobile-toggle {

            display: none;

            position: fixed;

            bottom: 72px;

            right: 25px;

            background: var(--accent);

            width: 80px;

            height: 80px;

            border-radius: 50%;

            z-index: 1000;

            border: none;

            box-shadow: 0 10px 30px rgba(0, 2, 4, 0.4);

            cursor: pointer;

        }


        @media (max-width: 768px) {

            .sidebar {

                position: fixed;

                bottom: 0;

                left: 0;

                width: 100%;

                height: 80vh;

                transform: translateY(100%);

                border-radius: 30px 30px 0 0;

                border-top: 1px solid var(--border);

            }

            .sidebar.open { transform: translateY(0); }

            .viewport { padding: 20px; }

            .mobile-toggle { display: flex; align-items: center; justify-content: center; }

            canvas { max-height: 40vh; }

            .upload-area { width: 90%; height: 250px; }

            

            /* Mobilde logoyu görünür yap */

            .mobile-logo { display: block; }

            .main-controls { justify-content: space-between; }

        }

    </style>

</head>

<body>


<button class="mobile-toggle" onclick="toggleMenu()">

    <svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">

        <g id="SVGRepo_iconCarrier"> 

            <path d="M3.84453 3.84453C2.71849 4.97056 2.71849 6.79623 3.84453 7.92226L5.43227 9.51C5.44419 9.49622 5.45669 9.48276 5.46978 9.46967L9.46978 5.46967C9.48284 5.45662 9.49625 5.44415 9.50999 5.43226L7.92226 3.84453C6.79623 2.71849 4.97056 2.71849 3.84453 3.84453Z" fill="#121212"></path> 

            <path d="M10.5679 6.49012C10.556 6.50386 10.5435 6.51728 10.5304 6.53033L6.53044 10.5303C6.51735 10.5434 6.5039 10.5559 6.49011 10.5678L16.0777 20.1555C17.2038 21.2815 19.0294 21.2815 20.1555 20.1555C21.2815 19.0294 21.2815 17.2038 20.1555 16.0777L10.5679 6.49012Z" fill="#121212"></path> 

            <path d="M16.1 2.30719C16.261 1.8976 16.8385 1.8976 16.9994 2.30719L17.4298 3.40247C17.479 3.52752 17.5776 3.62651 17.7022 3.67583L18.7934 4.1078C19.2015 4.26934 19.2015 4.849 18.7934 5.01054L17.7022 5.44252C17.5776 5.49184 17.479 5.59082 17.4298 5.71587L16.9995 6.81115C16.8385 7.22074 16.261 7.22074 16.1 6.81116L15.6697 5.71587C15.6205 5.59082 15.5219 5.49184 15.3973 5.44252L14.3061 5.01054C13.898 4.849 13.898 4.26934 14.3061 4.1078L15.3973 3.67583C15.5219 3.62651 15.6205 3.52752 15.6697 3.40247L16.1 2.30719Z" fill="#121212"></path> 

            <path d="M19.9672 9.12945C20.1281 8.71987 20.7057 8.71987 20.8666 9.12945L21.0235 9.5288C21.0727 9.65385 21.1713 9.75284 21.2959 9.80215L21.6937 9.95965C22.1018 10.1212 22.1018 10.7009 21.6937 10.8624L21.2959 11.0199C21.1713 11.0692 21.0727 11.1682 21.0235 11.2932L20.8666 11.6926C20.7057 12.1022 20.1281 12.1022 19.9672 11.6926L19.8103 11.2932C19.7611 11.1682 19.6625 11.0692 19.5379 11.0199L19.14 10.8624C18.732 10.7009 18.732 10.1212 19.14 9.95965L19.5379 9.80215C19.6625 9.75284 19.7611 9.65385 19.8103 9.5288L19.9672 9.12945Z" fill="#121212"></path> 

            <path d="M5.1332 15.3072C5.29414 14.8976 5.87167 14.8976 6.03261 15.3072L6.18953 15.7065C6.23867 15.8316 6.33729 15.9306 6.46188 15.9799L6.85975 16.1374C7.26783 16.2989 7.26783 16.8786 6.85975 17.0401L6.46188 17.1976C6.33729 17.2469 6.23867 17.3459 6.18953 17.471L6.03261 17.8703C5.87167 18.2799 5.29414 18.2799 5.1332 17.8703L4.97628 17.471C4.92714 17.3459 4.82852 17.2469 4.70393 17.1976L4.30606 17.0401C3.89798 16.8786 3.89798 16.2989 4.30606 16.1374L4.70393 15.9799C4.82852 15.9306 4.92714 15.8316 4.97628 15.7065L5.1332 15.3072Z" fill="#121212"></path> 

        </g>

    </svg>

</button>


<div class="sidebar" id="sidebar">

    <div class="header">

        <img src="https://armzoyxigtzenavvvtzu.supabase.co/storage/v1/object/public/brands/pilight.png" alt="PRISMA EVO X">

        <span class="version">ULTIMATE PIPELINE ENGINE 2026</span>

        <div class="stats" id="stats">Engines: Loading...</div>

    </div>

    <div class="scroll">

        <div id="menu"></div>

    </div>

</div>


<div class="viewport">

    <div class="main-controls">

        <img class="mobile-logo" src="https://armzoyxigtzenavvvtzu.supabase.co/storage/v1/object/public/brands/pilight.png" alt="PRISMA EVO X">

        

        <input type="file" id="up" accept="image/*">

        

        <div class="action-btns" id="action-btns">

            <label class="file-btn" for="up">

                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 4v6h-6M1 20v-6h6M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>

                NEW IMAGE

            </label>


            <button class="file-btn" onclick="downloadImg()">

                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>

                EXPORT

            </button>

        </div>

    </div>

    

    <label class="upload-area" for="up" id="upload-label">

        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"/></svg>

        <span>UPLOAD IMAGE</span>

    </label>

    

    <div id="loader">PROCESSING...</div>

    <canvas id="cv"></canvas>

</div>


<script>

function toggleMenu() {

    const sb = document.getElementById('sidebar');

    sb.classList.toggle('open');

}


const cv=document.getElementById("cv"), ctx=cv.getContext("2d",{willReadFrequently:true});

let img=null, currentStyle="Normal", origData=null;


const Ops = {

    gray: (d) => { for(let i=0;i<d.data.length;i+=4){ let v=d.data[i]*0.3+d.data[i+1]*0.59+d.data[i+2]*0.11; d.data[i]=d.data[i+1]=d.data[i+2]=v; } },

    invert: (d) => { for(let i=0;i<d.data.length;i+=4){ d.data[i]=255-d.data[i]; d.data[i+1]=255-d.data[i+1]; d.data[i+2]=255-d.data[i+2]; } },

    thresh: (d, val=128) => { for(let i=0;i<d.data.length;i+=4){ let v=(d.data[i]+d.data[i+1]+d.data[i+2])/3 > val ? 255 : 0; d.data[i]=d.data[i+1]=d.data[i+2]=v; } },

    posterize: (d, levels=4) => { let step=255/levels; for(let i=0;i<d.data.length;i+=4){ d.data[i]=Math.round(d.data[i]/step)*step; d.data[i+1]=Math.round(d.data[i+1]/step)*step; d.data[i+2]=Math.round(d.data[i+2]/step)*step; } },

    noise: (d, amt=30) => { for(let i=0;i<d.data.length;i+=4){ let n=(Math.random()-0.5)*amt; d.data[i]+=n; d.data[i+1]+=n; d.data[i+2]+=n; } },

    tint: (d, r, g, b, str=1) => { for(let i=0;i<d.data.length;i+=4){ d.data[i]+=(r-d.data[i])*str; d.data[i+1]+=(g-d.data[i+1])*str; d.data[i+2]+=(b-d.data[i+2])*str; } },

    channelSwap: (d, c1, c2, c3) => { 

        const map = {r:0, g:1, b:2};

        let t = new Uint8ClampedArray(d.data);

        for(let i=0;i<d.data.length;i+=4){ d.data[i]=t[i+map[c1]]; d.data[i+1]=t[i+map[c2]]; d.data[i+2]=t[i+map[c3]]; } 

    },

    scanlines: (d, str=0.5, size=2) => { let w=d.width; for(let i=0;i<d.data.length;i+=4){ let y=Math.floor((i/4)/w); if(y%size===0){ d.data[i]*=str; d.data[i+1]*=str; d.data[i+2]*=str; } } },

    vignette: (d, str=1) => { let w=d.width, h=d.height, cx=w/2, cy=h/2, max=Math.sqrt(cx*cx+cy*cy); for(let i=0;i<d.data.length;i+=4){ let x=(i/4)%w, y=Math.floor((i/4)/w), dist=Math.sqrt((x-cx)**2+(y-cy)**2), r=1-(dist/max)*str; d.data[i]*=r; d.data[i+1]*=r; d.data[i+2]*=r; } },

    pixelate: (d, size=5) => { 

        let w=d.width, h=d.height;

        let temp = new Uint8ClampedArray(d.data);

        for(let y=0; y<h; y+=size){

            for(let x=0; x<w; x+=size){

                let i=(y*w+x)*4, r=temp[i], g=temp[i+1], b=temp[i+2];

                for(let dy=0; dy<size && y+dy<h; dy++){

                    for(let dx=0; dx<size && x+dx<w; dx++){

                        let idx = ((y+dy)*w + (x+dx))*4;

                        d.data[idx]=r; d.data[idx+1]=g; d.data[idx+2]=b;

                    }

                }

            }

        }

    },

    chromatic: (d, off=5) => { let t=new Uint8ClampedArray(d.data); for(let i=0;i<d.data.length;i+=4){ d.data[i]=t[i+off*4]||t[i]; d.data[i+2]=t[i-off*4]||t[i+2]; } },

    duotone: (d, dark, light) => { 

        Ops.gray(d);

        for(let i=0;i<d.data.length;i+=4){

            let lum = d.data[i]/255;

            d.data[i] = dark[0] + lum*(light[0]-dark[0]);

            d.data[i+1] = dark[1] + lum*(light[1]-dark[1]);

            d.data[i+2] = dark[2] + lum*(light[2]-dark[2]);

        }

    },

    convolve: (d, m) => {

        let side=Math.round(Math.sqrt(m.length)), half=Math.floor(side/2), src=new Uint8ClampedArray(d.data), sw=d.width, sh=d.height;

        for(let y=0; y<sh; y++){

            for(let x=0; x<sw; x++){

                let r=0,g=0,b=0;

                for(let cy=0; cy<side; cy++){

                    for(let cx=0; cx<side; cx++){

                        let scy=y+cy-half, scx=x+cx-half;

                        if(scy>=0 && scy<sh && scx>=0 && scx<sw){

                            let off=(scy*sw+scx)*4, wt=m[cy*side+cx];

                            r+=src[off]*wt; g+=src[off+1]*wt; b+=src[off+2]*wt;

                        }

                    }

                }

                let i=(y*sw+x)*4;

                d.data[i]=r; d.data[i+1]=g; d.data[i+2]=b;

            }

        }

    },

    sobel: (d) => {

        Ops.gray(d);

        let src=new Uint8ClampedArray(d.data), w=d.width, h=d.height;

        for(let y=1; y<h-1; y++){

            for(let x=1; x<w-1; x++){

                let px = (dx,dy) => src[((y+dy)*w + (x+dx))*4];

                let gx = -px(-1,-1) + px(1,-1) - 2*px(-1,0) + 2*px(1,0) - px(-1,1) + px(1,1);

                let gy = -px(-1,-1) - 2*px(0,-1) - px(1,-1) + px(-1,1) + 2*px(0,1) + px(1,1);

                let val = Math.sqrt(gx*gx + gy*gy);

                let i = (y*w+x)*4;

                d.data[i]=d.data[i+1]=d.data[i+2]=val;

            }

        }

    },

    glitch: (d, block, shift) => {

        let w=d.width, t=new Uint8ClampedArray(d.data);

        for(let i=0;i<d.data.length;i+=4){

            let y = Math.floor((i/4)/w);

            if(y%block < block/2) {

                let s = shift*4;

                d.data[i]=t[i+s]||t[i]; d.data[i+1]=t[i+1+s]||t[i+1]; d.data[i+2]=t[i+2+s]||t[i+2];

            }

        }

    },

    bayer: (d) => {

        Ops.gray(d);

        const matrix = [[0,8,2,10],[12,4,14,6],[3,11,1,9],[15,7,13,5]];

        for(let i=0;i<d.data.length;i+=4){

            let x=(i/4)%d.width, y=Math.floor((i/4)/d.width);

            let thresh = (matrix[x%4][y%4]/16)*255;

            let v = d.data[i] > thresh ? 255 : 0;

            d.data[i]=d.data[i+1]=d.data[i+2]=v;

        }

    },

    colorFilter: (d, m) => { 

        let t=new Uint8ClampedArray(d.data);

        for(let i=0;i<d.data.length;i+=4){

            d.data[i]   = t[i]*m[0] + t[i+1]*m[1] + t[i+2]*m[2];

            d.data[i+1] = t[i]*m[3] + t[i+1]*m[4] + t[i+2]*m[5];

            d.data[i+2] = t[i]*m[6] + t[i+1]*m[7] + t[i+2]*m[8];

        }

    },

    solarize: (d) => { for(let i=0;i<d.data.length;i+=4){ d.data[i]=d.data[i]>127?255-d.data[i]:d.data[i]; d.data[i+1]=d.data[i+1]>127?255-d.data[i+1]:d.data[i+1]; d.data[i+2]=d.data[i+2]>127?255-d.data[i+2]:d.data[i+2]; } },

    distort: (d, amt=10) => {

        let w=d.width, h=d.height, t=new Uint8ClampedArray(d.data);

        for(let y=0; y<h; y++){

            for(let x=0; x<w; x++){

                let nx = x + Math.sin(y/10)*amt;

                if(nx>=0 && nx<w){

                    let i=(y*w+x)*4, ni=(y*w+Math.floor(nx))*4;

                    d.data[i]=t[ni]; d.data[i+1]=t[ni+1]; d.data[i+2]=t[ni+2];

                }

            }

        }

    },

    kaleidoscope: (d, segments=6) => {

        let w=d.width, h=d.height, t=new Uint8ClampedArray(d.data), cx=w/2, cy=h/2;

        for(let y=0; y<h; y++){

            for(let x=0; x<w; x++){

                let dx=x-cx, dy=y-cy, r=Math.sqrt(dx*dx+dy*dy), a=Math.atan2(dy,dx);

                a = Math.abs(((a % (Math.PI*2/segments)) - Math.PI/segments));

                let nx=Math.floor(cx+Math.cos(a)*r), ny=Math.floor(cy+Math.sin(a)*r);

                if(nx>=0 && nx<w && ny>=0 && ny<h){

                    let i=(y*w+x)*4, ni=(ny*w+nx)*4;

                    d.data[i]=t[ni]; d.data[i+1]=t[ni+1]; d.data[i+2]=t[ni+2];

                }

            }

        }

    },

    liquid: (d) => {

        let w=d.width, h=d.height, t=new Uint8ClampedArray(d.data);

        for(let y=0; y<h; y++){

            for(let x=0; x<w; x++){

                let offX = Math.sin(y/20)*15, offY = Math.cos(x/20)*15;

                let nx=Math.floor(x+offX), ny=Math.floor(y+offY);

                if(nx>=0 && nx<w && ny>=0 && ny<h){

                    let i=(y*w+x)*4, ni=(ny*w+nx)*4;

                    d.data[i]=t[ni]; d.data[i+1]=t[ni+1]; d.data[i+2]=t[ni+2];

                }

            }

        }

    },

    rain: (d) => {

        for(let i=0; i<d.data.length; i+=Math.floor(Math.random()*200+100)){

            for(let j=0; j<40; j++) { if(d.data[i+j*d.width*4]) d.data[i+j*d.width*4]+=100; }

        }

    },

    fractalSplit: (d) => {

        let w=d.width, h=d.height, t=new Uint8ClampedArray(d.data);

        let s = Math.floor(w/2);

        for(let i=0; i<d.data.length; i+=4){

            let x=(i/4)%w, y=Math.floor((i/4)/w);

            let ni = ((y%s)*w + (x%s))*4;

            d.data[i]=t[ni]; d.data[i+1]=t[ni+1]; d.data[i+2]=t[ni+2];

        }

    }

};


const effectCategories = {

    "Art & Sketch": [

        { id:"Pencil_Sketch", p: [ (d)=>Ops.sobel(d), (d)=>Ops.invert(d), (d)=>Ops.tint(d,240,240,240,0.2) ] },

        { id:"Chalkboard", p: [ (d)=>Ops.sobel(d), (d)=>Ops.noise(d,50), (d)=>Ops.tint(d,30,50,40,0.5) ] },

        { id:"Pop_Art_Andy", p: [ (d)=>Ops.posterize(d,3), (d)=>Ops.channelSwap(d,'g','b','r'), (d)=>Ops.tint(d,255,200,0,0.2) ] },

        { id:"Comic_Book", p: [ (d)=>Ops.posterize(d,4), (d)=>Ops.convolve(d, [0,-1,0,-1,5,-1,0,-1,0]), (d)=>Ops.noise(d,15) ] },

        { id:"Pointillism_Dither", p: [ (d)=>Ops.bayer(d), (d)=>Ops.tint(d,50,30,10,0.5) ] },

        { id:"Manga_Studio", p: [ (d)=>Ops.gray(d), (d)=>Ops.thresh(d,100), (d)=>Ops.noise(d,80), (d)=>Ops.scanlines(d,0.8,4) ] },

        { id:"Oil_Paint_Sim", p: [ (d)=>Ops.posterize(d,5), (d)=>Ops.convolve(d, [1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9]), (d)=>Ops.convolve(d, [0,-1,0,-1,5,-1,0,-1,0]) ] },

        { id:"Stain_Art", p: [ (d)=>Ops.thresh(d,128), (d)=>Ops.invert(d), (d)=>Ops.pixelate(d,3) ] },

        { id:"Color_Print", p: [ (d)=>Ops.channelSwap(d,'b','r','g'), (d)=>Ops.posterize(d,3), (d)=>Ops.bayer(d) ] },

        { id:"Pastel_Dream", p: [ (d)=>Ops.posterize(d,6), (d)=>Ops.tint(d,255,200,200,0.3) ] },

        { id:"Gravure_Print", p: [ (d)=>Ops.gray(d), (d)=>Ops.sobel(d), (d)=>Ops.thresh(d,50), (d)=>Ops.invert(d) ] },

        { id:"Mosaic_Glass", p: [ (d)=>Ops.pixelate(d,8), (d)=>Ops.convolve(d, [0,-1,0,-1,5,-1,0,-1,0]) ] },

        { id:"Street_Wall", p: [ (d)=>Ops.posterize(d,2), (d)=>Ops.noise(d,60), (d)=>Ops.tint(d,100,100,100,0.5) ] }

    ],

    "Retro Tech": [

        { id:"Gameboy_Classic", p: [ (d)=>Ops.pixelate(d,4), (d)=>Ops.duotone(d, [15,56,15], [155,188,15]) ] },

        { id:"Virtual_Boy", p: [ (d)=>Ops.pixelate(d,3), (d)=>Ops.duotone(d, [20,0,0], [255,0,0]), (d)=>Ops.scanlines(d,0.5,2) ] },

        { id:"Commodore_64", p: [ (d)=>Ops.pixelate(d,5), (d)=>Ops.posterize(d,2), (d)=>Ops.tint(d,100,100,200,0.4) ] },

        { id:"Old_CRT_TV", p: [ (d)=>Ops.chromatic(d,3), (d)=>Ops.scanlines(d,0.6,3), (d)=>Ops.vignette(d,1.5), (d)=>Ops.noise(d,20) ] },

        { id:"VHS_Tape", p: [ (d)=>Ops.glitch(d,10,5), (d)=>Ops.channelSwap(d,'r','b','g'), (d)=>Ops.noise(d,30) ] },

        { id:"Apple_II_Monitor", p: [ (d)=>Ops.duotone(d, [0,0,0], [51,255,51]), (d)=>Ops.scanlines(d,0.7,2) ] },

        { id:"CGA_Graphics", p: [ (d)=>Ops.posterize(d,2), (d)=>Ops.channelSwap(d,'r','g','b'), (d)=>Ops.tint(d,255,85,255,0.5) ] },

        { id:"Time_Out_Disk", p: [ (d)=>Ops.pixelate(d,2), (d)=>Ops.glitch(d,50,-10), (d)=>Ops.gray(d) ] },

        { id:"Teletext", p: [ (d)=>Ops.pixelate(d,6), (d)=>Ops.posterize(d,2), (d)=>Ops.thresh(d,100) ] },

        { id:"Old_Camera", p: [ (d)=>Ops.sepia=Ops.colorFilter(d,[0.39,0.76,0.18, 0.34,0.68,0.16, 0.27,0.53,0.13]), (d)=>Ops.noise(d,40), (d)=>Ops.vignette(d,1.8) ] },

        { id:"Daguerreotype", p: [ (d)=>Ops.gray(d), (d)=>Ops.noise(d,60), (d)=>Ops.vignette(d,2), (d)=>Ops.convolve(d, [0,-1,0,-1,5,-1,0,-1,0]) ] },

        { id:"Pinhole", p: [ (d)=>Ops.vignette(d,2.5), (d)=>Ops.tint(d,50,30,10,0.3), (d)=>Ops.convolve(d, [1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9]) ] }

    ],

    "Sci-Fi": [

        { id:"Thermal_Vision", p: [ (d)=>Ops.gray(d), (d)=>Ops.colorFilter(d, [2,0,0, 0,1.5,0, 0,0,0.5]) ] },

        { id:"Night_Vision", p: [ (d)=>Ops.gray(d), (d)=>Ops.duotone(d,[0,20,0],[50,255,50]), (d)=>Ops.noise(d,40), (d)=>Ops.vignette(d,1) ] },

        { id:"X_Ray_Machine", p: [ (d)=>Ops.invert(d), (d)=>Ops.duotone(d,[0,10,30],[200,255,255]), (d)=>Ops.sobel(d) ] },

        { id:"Predator_Vision", p: [ (d)=>Ops.solarize(d), (d)=>Ops.posterize(d,4), (d)=>Ops.tint(d,255,0,0,0.4) ] },

        { id:"Matrix_System", p: [ (d)=>Ops.sobel(d), (d)=>Ops.duotone(d,[0,0,0],[0,255,0]), (d)=>Ops.scanlines(d,0.5,2) ] },

        { id:"Sonar_Radar", p: [ (d)=>Ops.gray(d), (d)=>Ops.thresh(d,150), (d)=>Ops.duotone(d,[0,0,0],[0,150,255]), (d)=>Ops.vignette(d,2) ] },

        { id:"Cyborg_Eye", p: [ (d)=>Ops.chromatic(d,10), (d)=>Ops.tint(d,255,0,0,0.6), (d)=>Ops.scanlines(d,0.8,4) ] },

        { id:"Hacker_Terminal", p: [ (d)=>Ops.pixelate(d,2), (d)=>Ops.duotone(d,[0,0,0],[0,255,0]) ] },

        { id:"Infrared_IR", p: [ (d)=>Ops.invert(d), (d)=>Ops.channelSwap(d,'b','r','g') ] },

        { id:"Space_Scanner", p: [ (d)=>Ops.sobel(d), (d)=>Ops.invert(d), (d)=>Ops.colorFilter(d,[0,1,0, 0,0,1, 1,0,0]) ] },

        { id:"Radioactive", p: [ (d)=>Ops.solarize(d), (d)=>Ops.tint(d,100,255,50,0.5), (d)=>Ops.noise(d,50) ] },

        { id:"Biometric_Scan", p: [ (d)=>Ops.bayer(d), (d)=>Ops.duotone(d,[0,0,50],[0,255,255]) ] }

    ],

    "Glitch & Distortion": [

        { id:"Data_Bend", p: [ (d)=>Ops.glitch(d,20,15), (d)=>Ops.chromatic(d,8) ] },

        { id:"Signal_Loss", p: [ (d)=>Ops.glitch(d,2,-20), (d)=>Ops.noise(d,50), (d)=>Ops.scanlines(d,0.2,2) ] },

        { id:"Chromatic_Aberration", p: [ (d)=>Ops.chromatic(d,15), (d)=>Ops.glitch(d,100,-10), (d)=>Ops.pixelate(d,2) ] },

        { id:"Ghost_Frequency", p: [ (d)=>Ops.solarize(d), (d)=>Ops.glitch(d,5,5), (d)=>Ops.tint(d,200,200,255,0.4) ] },

        { id:"Acid_Trip", p: [ (d)=>Ops.channelSwap(d,'g','b','r'), (d)=>Ops.solarize(d), (d)=>Ops.glitch(d,30,10) ] },

        { id:"Memory_Leak", p: [ (d)=>Ops.pixelate(d,10), (d)=>Ops.glitch(d,50,20), (d)=>Ops.posterize(d,3) ] },

        { id:"Corrupted_Tape", p: [ (d)=>Ops.noise(d,100), (d)=>Ops.scanlines(d,0.1,5), (d)=>Ops.chromatic(d,5) ] },

        { id:"Cyber_Wreck", p: [ (d)=>Ops.sobel(d), (d)=>Ops.glitch(d,15,30), (d)=>Ops.tint(d,255,0,255,0.5) ] },

        { id:"Broken_Screen", p: [ (d)=>Ops.glitch(d,200,-50), (d)=>Ops.glitch(d,10,20) ] }

    ],

    "Atmospheric": [

        { id:"Extreme_Infrared", p: [ (d)=>Ops.invert(d), (d)=>Ops.channelSwap(d,'b','r','g'), (d)=>Ops.tint(d,255,0,50,0.4) ] },

        { id:"Anamorphic_Flare", p: [ (d)=>Ops.distort(d,5), (d)=>Ops.chromatic(d,12), (d)=>Ops.scanlines(d,0.8,4) ] },

        { id:"Vaporwave_Pink", p: [ (d)=>Ops.duotone(d,[0,255,255],[255,0,255]), (d)=>Ops.noise(d,20), (d)=>Ops.vignette(d,1.2) ] },

        { id:"Synthwave_Grid", p: [ (d)=>Ops.duotone(d,[20,0,40],[255,0,150]), (d)=>Ops.scanlines(d,0.4,3), (d)=>Ops.convolve(d,[0,-1,0,-1,5,-1,0,-1,0]) ] },

        { id:"ASCII_Matrix", p: [ (d)=>Ops.pixelate(d,6), (d)=>Ops.gray(d), (d)=>Ops.duotone(d,[0,0,0],[0,255,0]), (d)=>Ops.bayer(d) ] },

        { id:"Datamoshing_V1", p: [ (d)=>Ops.glitch(d,5,40), (d)=>Ops.pixelate(d,3), (d)=>Ops.chromatic(d,10) ] },

        { id:"Cyber_Rain", p: [ (d)=>Ops.rain(d), (d)=>Ops.tint(0,100,255,0.2), (d)=>Ops.scanlines(d,0.7,2) ] },

        { id:"Cyber_Fog", p: [ (d)=>Ops.convolve(d,[1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9]), (d)=>Ops.tint(d,200,200,220,0.3), (d)=>Ops.noise(d,10) ] },

        { id:"Broken_Glass", p: [ (d)=>Ops.glitch(d,50,10), (d)=>Ops.sobel(d), (d)=>Ops.invert(d), (d)=>Ops.chromatic(d,4) ] }

    ],

    "Math Twist": [

        { id:"Kaleidoscope", p: [ (d)=>Ops.kaleidoscope(d,8), (d)=>Ops.posterize(d,5) ] },

        { id:"Liquid_Pixel", p: [ (d)=>Ops.liquid(d), (d)=>Ops.chromatic(d,5) ] },

        { id:"Fractal_Split", p: [ (d)=>Ops.fractalSplit(d), (d)=>Ops.convolve(d,[0,-1,0,-1,5,-1,0,-1,0]) ] },

        { id:"Swirl_Effect", p: [ (d)=>Ops.distort(d,30), (d)=>Ops.liquid(d) ] },

        { id:"Mirror_Maze", p: [ (d)=>Ops.kaleidoscope(d,4), (d)=>Ops.glitch(d,20,5) ] }

    ],

    "Optical": [

        { id:"Extreme_Sharpen", p: [ (d)=>Ops.convolve(d, [0,-2,0,-2,9,-2,0,-2,0]) ] },

        { id:"Emboss", p: [ (d)=>Ops.gray(d), (d)=>Ops.convolve(d, [-2,-1,0,-1,1,1,0,1,2]) ] },

        { id:"Laplacian_Edge", p: [ (d)=>Ops.convolve(d, [-1,-1,-1,-1,8,-1,-1,-1,-1]) ] },

        { id:"Light_Blur", p: [ (d)=>Ops.convolve(d, [1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9]) ] },

        { id:"Lomography", p: [ (d)=>Ops.vignette(d,2), (d)=>Ops.tint(d,255,150,0,0.2), (d)=>Ops.posterize(d,6) ] },

        { id:"Dark_Room", p: [ (d)=>Ops.vignette(d,3), (d)=>Ops.tint(d,255,0,0,0.1) ] },

        { id:"Overexposure", p: [ (d)=>Ops.tint(d,255,255,255,0.4), (d)=>Ops.convolve(d, [0,-1,0,-1,5,-1,0,-1,0]) ] },

        { id:"Cinematic_Teal_Orange", p: [ (d)=>Ops.colorFilter(d, [1.2,0,0, 0,1,0.2, 0,0,1.5]), (d)=>Ops.vignette(d,1) ] },

        { id:"Gothic_Haze", p: [ (d)=>Ops.gray(d), (d)=>Ops.tint(d,0,0,0,0.5), (d)=>Ops.noise(d,20) ] },

        { id:"Polaroid_Faded", p: [ (d)=>Ops.tint(d,250,240,200,0.2), (d)=>Ops.vignette(d,1.5) ] },

        { id:"Invert_Negative", p: [ (d)=>Ops.invert(d) ] },

        { id:"High_Contrast_BW", p: [ (d)=>Ops.gray(d), (d)=>Ops.thresh(d,128) ] }

    ]

};


const generateProceduralEffects = () => {

    let proceduralCat = [];

    let duotones = [

        ["Blood_Moon",[50,0,0],[255,100,100]], ["Ocean_Floor",[0,10,50],[0,200,255]], ["Toxic_Jungle",[0,50,10],[100,255,0]],

        ["Gold_Dust",[30,20,0],[255,200,50]], ["Ice_Age",[200,200,255],[255,255,255]], ["Ashes",[20,20,20],[150,150,150]],

        ["Neon_Pink",[50,0,50],[255,50,200]], ["Dark_Matter",[0,0,0],[100,0,255]], ["Sandstorm",[50,30,0],[255,200,150]]

    ];

    let blends = [

        {n:"_Classic", o:[]}, {n:"_Striped", o:[(d)=>Ops.scanlines(d,0.5,3)]}, {n:"_Broken", o:[(d)=>Ops.glitch(d,15,10)]},

        {n:"_Pixel", o:[(d)=>Ops.pixelate(d,4)]}, {n:"_Edge", o:[(d)=>Ops.sobel(d)]}, {n:"_Dither", o:[(d)=>Ops.bayer(d)]}

    ];

    duotones.forEach(dt => {

        blends.forEach(bl => {

            let ops = [ (d)=>Ops.duotone(d, dt[1], dt[2]) ];

            ops.push(...bl.o);

            proceduralCat.push({ id: dt[0]+bl.n, p: ops });

        });

    });

    let swaps = [['g','b','r'], ['b','r','g'], ['r','r','b'], ['g','g','g']];

    swaps.forEach((sw, i) => {

        proceduralCat.push({ id: `Dimension_Gate_v${i+1}`, p: [ (d)=>Ops.channelSwap(d, sw[0], sw[1], sw[2]), (d)=>Ops.solarize(d), (d)=>Ops.chromatic(d,10) ] });

        proceduralCat.push({ id: `Alien_World_v${i+1}`, p: [ (d)=>Ops.channelSwap(d, sw[0], sw[1], sw[2]), (d)=>Ops.posterize(d,3), (d)=>Ops.invert(d) ] });

        proceduralCat.push({ id: `Synthetic_Dream_v${i+1}`, p: [ (d)=>Ops.channelSwap(d, sw[0], sw[1], sw[2]), (d)=>Ops.noise(d,50), (d)=>Ops.vignette(d,2) ] });

    });

    effectCategories["Procedural Engine"] = proceduralCat;

};


generateProceduralEffects();


const menu=document.getElementById("menu");

let activePipeline = [];

let totalEffects = 0;


Object.entries(effectCategories).forEach(([title, list])=>{

    let t=document.createElement("div"); t.className="cat-title"; 

    t.innerHTML = `${title}`;

    menu.appendChild(t);

    let g=document.createElement("div"); g.className="grid";

    list.forEach(effect => {

        totalEffects++;

        let b=document.createElement("button"); b.className="btn"; 

        b.textContent=effect.id.replace(/_/g,' ');

        b.onclick=() => { 

            document.querySelectorAll(".btn").forEach(x=>x.classList.remove("active")); 

            b.classList.add("active"); 

            activePipeline = effect.p; 

            applyCurrent(); 

            if(window.innerWidth <= 768) toggleMenu();

        };

        g.appendChild(b);

    });

    menu.appendChild(g);

});

document.getElementById("stats").textContent = `PIPELINES LOADED: ${totalEffects}`;


document.getElementById("up").onchange=e=>{

    if(!e.target.files[0]) return;

    let r=new FileReader();

    r.onload=f=>{

        img=new Image();

        img.onload=()=>{

            let sc=Math.min(1200/img.width, 1200/img.height, 1);

            cv.width=img.width*sc; cv.height=img.height*sc;

            ctx.drawImage(img,0,0,cv.width,cv.height);

            origData = ctx.getImageData(0,0,cv.width,cv.height);

            activePipeline = [];

            document.querySelectorAll(".btn").forEach(x=>x.classList.remove("active"));

            

            // UI GÜNCELLEME

            document.getElementById("upload-label").style.display = "none";

            document.getElementById("action-btns").style.display = "flex";

            cv.style.display = "block";

        };

        img.src=f.target.result;

    };

    r.readAsDataURL(e.target.files[0]);

    e.target.value = "";

};


function applyCurrent(){

    if(!origData || activePipeline.length === 0) return;

    const loader = document.getElementById("loader");

    loader.style.display = "block";

    cv.style.filter = "blur(10px) brightness(0.5)";


    setTimeout(() => {

        let d = new ImageData(new Uint8ClampedArray(origData.data), origData.width, origData.height);

        activePipeline.forEach(step => step(d));

        ctx.putImageData(d,0,0);

        loader.style.display = "none";

        cv.style.filter = "none";

    }, 50);

}


function downloadImg() {

    if(!origData) return;

    const link = document.createElement('a');

    link.download = 'prisma_evo_x.png';

    link.href = cv.toDataURL("image/png");

    link.click();

}

</script>

</body>

</html>