INFO:     10.16.1.165:50536 - "POST /upload HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/user/.local/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "/home/user/.local/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 70, in __call__
    return await self.app(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 187, in __call__
    raise exc
  File "/home/user/.local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 165, in __call__
    await self.app(scope, receive, _send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 93, in __call__
    await self.simple_response(scope, receive, send, request_headers=headers)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 144, in simple_response
    await self.app(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    raise exc
  File "/home/user/.local/lib/python3.9/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    await app(scope, receive, sender)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/routing.py", line 715, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/routing.py", line 735, in app
    await route.handle(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/routing.py", line 288, in handle
    await self.app(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/routing.py", line 76, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    raise exc
  File "/home/user/.local/lib/python3.9/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    await app(scope, receive, sender)
  File "/home/user/.local/lib/python3.9/site-packages/starlette/routing.py", line 73, in app
    response = await f(request)
  File "/home/user/.local/lib/python3.9/site-packages/fastapi/routing.py", line 301, in app
    raw_response = await run_endpoint_function(
  File "/home/user/.local/lib/python3.9/site-packages/fastapi/routing.py", line 212, in run_endpoint_function
    return await dependant.call(**values)
  File "/app/app.py", line 625, in handle_upload
    start_byte, end_byte, total_size = map(int, range_str.replace('bytes', '').split('-')[0].split('/'))
ValueError: not enough values to unpack (expected 3, got 1)

from fastapi import FastAPI, File, UploadFile, Request, HTTPException
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
from fastapi.middleware.cors import CORSMiddleware
import requests
import time
import asyncio
from typing import Dict

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

HTML_CONTENT = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Radd PRO Uploader</title>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Poppins', sans-serif;
            background-color: #121212;
            color: #e0e0e0;
            margin: 0;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
            box-sizing: border-box;
        }

        body::before {
            content: "";
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAQAAACM/9unAAAACXBIWXMAAAsTAAALEwEAmpwYAAABF0lEQVR4nO3YMRLCQBRE0clsYgxZwwq7oLGxAgp2AtbsqQZsYgEG0wEWc/LSZnb9HcMjR8fHvEKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgsK8tJOq9fzs7vlkNlWvf5ELi+20t5k2VSL7p/iHJ5Rz5ynOhU7rQ4pUi+6b4hyeUc+cpzoVO60OkV7rQ4pUi+6b4hxenu+en4rQAOkaks/eJegGaUfOHI+nRvQCND1w2J9yf8C2KZwNjkeUsAKRa7Nz50tQAokVbO/U6AaiWjl5wd6kQAOke8Xpx3JgTQKVq7Heh0ADpFvF6cd0kE0Claux3odAA6RfxenHc+BNCpWrsd6HQAOkX8Xpx3PgTQqVq7Heh0ADpF/F6cdz4E0KlarjdI/cR1FBQUGBgYGBgYGBgYG/AT4AIHph6aQGU7oAAAAASUVORK5CYII=') repeat;
            animation: grain 8s steps(10) infinite;
            opacity: 0.2;
            pointer-events: none;
        }

        @keyframes grain {
            0% { transform: translate(0, 0); }
            10% { transform: translate(-5%, -5%); }
            20% { transform: translate(-10%, 5%); }
            30% { transform: translate(5%, -10%); }
            40% { transform: translate(-5%, 15%); }
            50% { transform: translate(-10%, 5%); }
            60% { transform: translate(15%, 0); }
            70% { transform: translate(0, 10%); }
            80% { transform: translate(-15%, 0); }
            90% { transform: translate(10%, 5%); }
            100% { transform: translate(5%, 0); }
        }

        .container {
            position: relative;
            width: 100%;
            max-width: 450px;
            margin: 0 auto;
            padding: 2rem;
            background: rgba(18, 18, 18, 0.9);
            backdrop-filter: blur(10px);
            border-radius: 15px;
            z-index: 1;
            text-align: center;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
        }

        h1 {
            margin-bottom: 1.5rem;
            font-size: 1.8rem;
            color: #ffffff;
            text-shadow: 0 0 5px rgba(255, 255, 255, 0.2);
        }

        .btn {
            display: inline-block;
            position: relative;
            padding: 12px 24px;
            margin: 0.5rem;
            font-size: 1rem;
            font-weight: 600;
            color: #ffffff;
            background-color: #2a2a2a;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            overflow: hidden;
            z-index: 1;
            transition: color 0.3s ease, box-shadow 0.3s ease;
        }

        .btn:hover {
            color: #ffffff;
            box-shadow: 0 0 15px rgba(200, 200, 200, 0.5);
        }

        .btn:hover::before {
            content: '';
            position: absolute;
            inset: -10px;
            background: radial-gradient(circle at center, rgba(200,200,200,0.2), transparent);
            filter: blur(20px);
            animation: glowAnimation 2s infinite;
            z-index: -1;
            pointer-events: none;
        }

        @keyframes glowAnimation {
            0% { transform: scale(0.8); }
            50% { transform: scale(1.2); }
            100% { transform: scale(0.8); }
        }

        .btn:active {
            transform: scale(0.98);
        }

        .small-btn {
            padding: 6px 12px;
            font-size: 0.8rem;
            font-weight: 500;
            background-color: #2a2a2a;
            color: #ffffff;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: color 0.3s ease, box-shadow 0.3s ease;
            position: relative;
            overflow: hidden;
            z-index: 1;
            margin: 0.25rem;
        }

        .small-btn:hover {
            color: #ffffff;
            box-shadow: 0 0 10px rgba(200, 200, 200, 0.5);
        }

        .small-btn:hover::before {
            content: '';
            position: absolute;
            inset: -10px;
            background: radial-gradient(circle at center, rgba(200,200,200,0.2), transparent);
            filter: blur(15px);
            animation: glowAnimation 2s infinite;
            z-index: -1;
            pointer-events: none;
        }

        .small-btn:active {
            transform: scale(0.98);
        }

        .drop-zone {
            position: relative;
            padding: 20px;
            margin-bottom: 1rem;
            border: 2px dashed #aaa;
            border-radius: 10px;
            cursor: pointer;
            transition: all 0.3s ease;
            background: rgba(255, 255, 255, 0.05);
            overflow: hidden;
        }

        .drop-zone:hover, .drop-zone.drag-over {
            border-color: #ffffff;
            background: rgba(255, 255, 255, 0.1);
            position: relative;
        }

        .drop-zone:hover::before, .drop-zone.drag-over::before {
            content: '';
            position: absolute;
            inset: -10px;
            background: radial-gradient(circle at center, rgba(200,200,200,0.2), transparent);
            filter: blur(30px);
            animation: grainGlow 5s infinite;
            z-index: -1;
            pointer-events: none;
        }

        @keyframes grainGlow {
            0% { opacity: 0.2; }
            50% { opacity: 0.5; }
            100% { opacity: 0.2; }
        }

        .file-input {
            display: none;
        }

        .file-name {
            margin-top: 1rem;
            font-size: 0.9rem;
            color: #aaa;
            word-break: break-all;
        }

        .progress-container {
            display: none;
            margin-top: 1.5rem;
        }

        .progress-bar {
            width: 100%;
            height: 10px;
            background-color: #333;
            border-radius: 5px;
            overflow: hidden;
            margin-bottom: 10px;
        }

        .progress {
            width: 0%;
            height: 100%;
            background-color: #ffffff;
            transition: width 0.3s ease;
        }

        .loading-spinner {
            display: none;
            width: 40px;
            height: 40px;
            border: 4px solid #333;
            border-top: 4px solid #ffffff;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin: 20px auto;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .result-container {
            display: none;
            margin-top: 1.5rem;
        }

        .result-link {
            color: #ffffff;
            text-decoration: none;
            font-weight: 600;
            transition: all 0.3s ease;
            margin-right: 10px;
            word-break: break-all;
        }

        .result-link:hover {
            text-decoration: underline;
        }

        .link-buttons {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            margin-top: 10px;
        }

        /* File Types */
        .file-types {
            margin-top: 2rem;
            font-size: 0.8rem;
            color: #aaa;
        }

        .modal {
            display: none;
            position: fixed;
            z-index: 2;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            overflow: auto;
            background-color: rgba(0,0,0,0.8);
        }

        .modal-content {
            background-color: #1e1e1e;
            margin: 15% auto;
            padding: 20px;
            border: 1px solid #333;
            width: 90%;
            max-width: 600px;
            border-radius: 10px;
            color: #e0e0e0;
            animation: modalFadeIn 0.3s;
            position: relative;
        }

        @keyframes modalFadeIn {
            from {opacity: 0; transform: scale(0.8);}
            to {opacity: 1; transform: scale(1);}
        }

        .close {
            color: #aaa;
            position: absolute;
            top: 10px;
            right: 15px;
            font-size: 28px;
            font-weight: bold;
            transition: color 0.3s ease;
        }

        .close:hover,
        .close:focus {
            color: #fff;
            text-decoration: none;
            cursor: pointer;
        }

        .embed-container {
            display: flex;
            flex-direction: column;
            align-items: stretch;
            margin-top: 15px;
        }

        #embedLink {
            width: 100%;
            padding: 10px;
            background-color: #333;
            border: 1px solid #555;
            color: #e0e0e0;
            border-radius: 5px;
            margin-bottom: 10px;
            font-size: 0.9rem;
        }

        @media (max-width: 480px) {
            .container {
                padding: 1.5rem;
            }

            h1 {
                font-size: 1.5rem;
            }

            .btn, .small-btn {
                font-size: 0.9rem;
                padding: 10px 20px;
            }

            .file-types {
                font-size: 0.7rem;
            }

            .modal-content {
                width: 95%;
                margin: 10% auto;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Radd PRO Uploader</h1>
        <form id="uploadForm">
            <div id="dropZone" class="drop-zone">
                <input type="file" name="file" id="file" class="file-input" accept=".zip,.mp4,.txt,.mp3,image/*,.pdf" required>
                <label for="file" class="btn">Choose File</label>
                <p>or drag and drop file here/paste image</p>
            </div>
            <div class="file-name" id="fileName"></div>
            <button type="submit" id="uploadBtn" class="btn" style="display: none; margin-top: 1rem;">Upload File</button>
            <div class="progress-container" id="progressContainer"></div>
            <div class="loading-spinner" id="loadingSpinner"></div>
        </form>
        <div class="result-container" id="resultContainer"></div>
                <div class="file-types">
            Allowed file types: .zip, .mp4, .txt, .mp3, all image types, .pdf
        </div>
    </div>

    <div id="embedModal" class="modal">
        <div class="modal-content">
            <span class="close">&times;</span>
            <h2>Embed Video Link</h2>
            <p>copy the link to embed it on discord:</p>
            <div class="embed-container">
                <input type="text" id="embedLink" readonly>
                <button onclick="copyEmbedLink()" class="small-btn copy-embed-btn">Copy</button>
            </div>
        </div>
    </div>

    <script>
        const fileInput = document.getElementById('file');
        const fileName = document.getElementById('fileName');
        const uploadForm = document.getElementById('uploadForm');
        const progressContainer = document.getElementById('progressContainer');
        const loadingSpinner = document.getElementById('loadingSpinner');
        const resultContainer = document.getElementById('resultContainer');
                const dropZone = document.getElementById('dropZone');
        const modal = document.getElementById('embedModal');
        const span = document.getElementsByClassName("close")[0];
        const embedLinkInput = document.getElementById('embedLink');
        const uploadBtn = document.getElementById('uploadBtn');

        fileInput.addEventListener('change', handleFileSelect);

        uploadForm.addEventListener('submit', async (e) => {
            e.preventDefault();
            if (fileInput.files.length > 0) {
                await uploadFile(fileInput.files[0]);
            }
        });

        dropZone.addEventListener('dragover', (e) => {
            e.preventDefault();
            dropZone.classList.add('drag-over');
        });

        dropZone.addEventListener('dragleave', () => {
            dropZone.classList.remove('drag-over');
        });

        dropZone.addEventListener('drop', (e) => {
            e.preventDefault();
            dropZone.classList.remove('drag-over');
            handleFileSelect({ target: { files: e.dataTransfer.files } });
        });

        document.addEventListener('paste', (e) => {
            const items = e.clipboardData.items;
            for (let i = 0; i < items.length; i++) {
                if (items[i].kind === 'file') {
                    const file = items[i].getAsFile();
                    handleFileSelect({ target: { files: [file] } });
                    break;
                }
            }
        });

        span.onclick = function() {
            modal.style.display = "none";
        }

        window.onclick = function(event) {
            if (event.target == modal) {
                modal.style.display = "none";
            }
        }

        function handleFileSelect(e) {
            if (e.target.files && e.target.files.length > 0) {
                const file = e.target.files[0];
                fileName.textContent = file.name;
                uploadBtn.style.display = 'inline-block';
                
                const dataTransfer = new DataTransfer();
                dataTransfer.items.add(file);
                fileInput.files = dataTransfer.files;
            }
        }

        async function uploadFile(file) {
            progressContainer.innerHTML = '';
            progressContainer.style.display = 'block';
            loadingSpinner.style.display = 'block';
            uploadBtn.disabled = true;
            resultContainer.innerHTML = '';
            resultContainer.style.display = 'none';

            const progressBar = createProgressBar(file.name);
            progressContainer.appendChild(progressBar);

            const formData = new FormData();
            formData.append('file', file);

            let uploadedBytes = 0;
            const chunkSize = 1024 * 1024; // 1MB chunks
            const totalSize = file.size;

            while (uploadedBytes < totalSize) {
                const chunk = file.slice(uploadedBytes, uploadedBytes + chunkSize);
                formData.set('file', chunk, file.name);

                try {
                    const response = await fetch('/upload', {
                        method: 'POST',
                        body: formData,
                        headers: {
                            'Content-Range': `bytes ${uploadedBytes}-${uploadedBytes + chunk.size - 1}/${totalSize}`
                        }
                    });

                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }

                    const result = await response.json();
                    if (result.url) {
                        addResultLink(result.url, file.name);
                        break;
                    }

                    uploadedBytes += chunk.size;
                    updateProgress(uploadedBytes, totalSize, progressBar.querySelector('.progress'));
                } catch (error) {
                    console.error('Upload error:', error);
                    await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second before retrying
                    // The loop will continue from where it left off
                }
            }

            resetUploadState();
        }

        function createProgressBar(fileName) {
            const progressBarContainer = document.createElement('div');
            progressBarContainer.className = 'progress-bar';
            const progress = document.createElement('div');
            progress.className = 'progress';
            progressBarContainer.appendChild(progress);
            const label = document.createElement('div');
            label.textContent = fileName;
            label.style.fontSize = '0.8rem';
            label.style.marginBottom = '5px';
            const container = document.createElement('div');
            container.appendChild(label);
            container.appendChild(progressBarContainer);
            return container;
        }

        function updateProgress(uploadedBytes, totalBytes, progressBar) {
            const percentComplete = (uploadedBytes / totalBytes) * 100;
            progressBar.style.width = percentComplete + '%';
        }

        function resetUploadState() {
            fileInput.value = '';
            fileName.textContent = '';
            uploadBtn.style.display = 'none';
            uploadBtn.disabled = false;
            loadingSpinner.style.display = 'none';
        }

        function addResultLink(url, fileName) {
            const linkContainer = document.createElement('div');
            linkContainer.style.marginBottom = '10px';

            const link = document.createElement('a');
            link.href = url;
            link.textContent = `View ${fileName}`;
            link.className = 'result-link';
            link.target = '_blank';

            linkContainer.appendChild(link);

            const buttonsContainer = document.createElement('div');
            buttonsContainer.className = 'link-buttons';

            const copyBtn = document.createElement('button');
            copyBtn.textContent = 'Copy Link';
            copyBtn.className = 'small-btn copy-btn';
            copyBtn.onclick = () => {
                navigator.clipboard.writeText(window.location.origin + url).then(() => {
                    alert('Link copied to clipboard!');
                });
            };
            buttonsContainer.appendChild(copyBtn);

            if (fileName.toLowerCase().endsWith('.mp4')) {
                const embedBtn = document.createElement('button');
                embedBtn.textContent = 'Embed Video for Discord';
                embedBtn.className = 'small-btn embed-btn';
                embedBtn.onclick = () => {
                    showEmbedModal(url);
                };
                buttonsContainer.appendChild(embedBtn);
            }

            linkContainer.appendChild(buttonsContainer);

            resultContainer.appendChild(linkContainer);
            resultContainer.style.display = 'block';
        }

        function showEmbedModal(url) {
            const embedUrl = `${window.location.origin}/embed?url=${encodeURIComponent(window.location.origin + url)}&thumbnail=${encodeURIComponent('https://coollsd-fileuploader.hf.space/rbxg/LdnShkhZFgMlMmCwkeX78RqHbiol6r554v5BryQS9upEC1wu/Untitled.png')}`;
            embedLinkInput.value = embedUrl;
            modal.style.display = "block";
        }

        function copyEmbedLink() {
            embedLinkInput.select();
            document.execCommand('copy');
            alert('Embed link copied to clipboard!');
        }
    </script>
</body>
</html>
"""

@app.get("/", response_class=HTMLResponse)
async def index():
    return HTML_CONTENT

@app.post("/upload")
async def handle_upload(request: Request, file: UploadFile = File(...)):
    content_range = request.headers.get('Content-Range')
    if not content_range:
        raise HTTPException(status_code=400, detail="Content-Range header is missing")

    _, range_str = content_range.split(' ')
    start_byte, end_byte, total_size = map(int, range_str.replace('bytes', '').split('-')[0].split('/'))

    if not file:
        raise HTTPException(status_code=400, detail="No file part")
    if file.filename == '':
        raise HTTPException(status_code=400, detail="No selected file")

    cookies = await get_cookies()
    if 'csrftoken' not in cookies or 'sessionid' not in cookies:
        raise HTTPException(status_code=500, detail="Failed to obtain necessary cookies")

    if start_byte == 0:
        upload_result = await initiate_upload(cookies, file.filename, file.content_type)
        if not upload_result or 'upload_url' not in upload_result:
            raise HTTPException(status_code=500, detail="Failed to initiate upload")
    else:
        upload_result = {'upload_url': file.filename}  # Use filename as a key to retrieve the upload URL

    file_content = await file.read()
    upload_success = await upload_chunk(upload_result['upload_url'], file_content, start_byte, end_byte, total_size)
    if not upload_success:
        raise HTTPException(status_code=500, detail="Chunk upload failed")

    if end_byte + 1 >= total_size:
        original_url = upload_result.get('serving_url')
        if original_url:
            mirrored_url = f"/rbxg/{original_url.split('/pbxt/')[1]}"
            return JSONResponse(content={"url": mirrored_url})
    
    return JSONResponse(content={"status": "chunk uploaded"})

@app.get("/rbxg/{path:path}")
async def handle_video_stream(path: str, request: Request):
    original_url = f'https://replicate.delivery/pbxt/{path}'
    range_header = request.headers.get('Range')

    headers = {'Range': range_header} if range_header else {}
    response = requests.get(original_url, headers=headers, stream=True)

    def generate():
        for chunk in response.iter_content(chunk_size=8192):
            yield chunk

    headers = dict(response.headers)
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Content-Disposition'] = 'inline'

    if response.status_code == 206:
        headers['Content-Range'] = response.headers.get('Content-Range')

    return StreamingResponse(generate(), status_code=response.status_code, headers=headers)

@app.get("/embed")
async def embed_video(url: str, thumbnail: str):
    html = f'''
    <html>
    <head>
        <meta property="og:type" content="video.other">
        <meta property="og:video" content="{url}">
        <meta property="og:video:url" content="{url}">
        <meta property="og:video:secure_url" content="{url}">
        <meta property="og:video:type" content="video/mp4">
        <meta property="og:video:width" content="1280">
        <meta property="og:video:height" content="720">
        <meta property="og:image" content="{thumbnail}">
        <meta property="og:image:secure_url" content="{thumbnail}">
        <meta property="og:image:width" content="1280">
        <meta property="og:image:height" content="720">
        <meta property="og:image:type" content="image/png">
        <style>
            body, html {{ margin: 0; padding: 0; height: 100%; background: #000; }}
            #thumbnail {{ width: 100%; height: 100%; object-fit: contain; cursor: pointer; }}
            #video {{ display: none; width: 100%; height: 100%; object-fit: contain; }}
        </style>
    </head>
    <body>
        <img id="thumbnail" src="{thumbnail}" onclick="playVideo()">
        <video id="video" controls autoplay>
            <source src="{url}" type="video/mp4">
            Your browser does not support the video tag.
        </video>
        <script>
            function playVideo() {{
                document.getElementById('thumbnail').style.display = 'none';
                document.getElementById('video').style.display = 'block';
                document.getElementById('video').play();
            }}
        </script>
    </body>
    </html>
    '''
    return HTMLResponse(content=html)

async def get_cookies() -> Dict[str, str]:
    try:
        response = requests.get('https://replicate.com/levelsio/neon-tokyo', headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
        })
        return dict(response.cookies)
    except Exception as e:
        print(f'Error fetching the page: {e}')
        return {}

async def initiate_upload(cookies: Dict[str, str], filename: str, content_type: str) -> Dict:
    url = f'https://replicate.com/api/upload/{filename}?content_type={content_type}'
    try:
        response = requests.post(url, cookies=cookies, headers={
            'X-CSRFToken': cookies.get('csrftoken'),
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
            'Referer': 'https://replicate.com/levelsio/neon-tokyo',
            'Origin': 'https://replicate.com',
            'Accept': '*/*',
            'Accept-Language': 'en-US,en;q=0.5',
            'Accept-Encoding': 'identity',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'Sec-GPC': '1',
            'Priority': 'u=1, i'
        })
        return response.json()
    except Exception as e:
        print(f'Error initiating upload: {e}')
        raise

async def upload_chunk(upload_url: str, chunk_content: bytes, start_byte: int, end_byte: int, total_size: int) -> bool:
    try:
        headers = {
            'Content-Type': 'application/octet-stream',
            'Content-Range': f'bytes {start_byte}-{end_byte}/{total_size}'
        }
        response = requests.put(upload_url, data=chunk_content, headers=headers)
        return response.status_code in [200, 201, 204]
    except Exception as e:
        print(f'Error uploading chunk: {e}')
        return False

async def retry_upload(upload_url: str, file_content: bytes, content_type: str, max_retries: int = 5, delay: int = 1) -> bool:
    retries = 0
    while retries < max_retries:
        try:
            success = await upload_file(upload_url, file_content, content_type)
            if success:
                return True
            print(f"Upload attempt {retries + 1} failed. Retrying...")
        except Exception as e:
            print(f"Error during upload attempt {retries + 1}: {e}")
        
        retries += 1
        await asyncio.sleep(delay)
        delay = min(delay * 2, 60)  # Exponential backoff, capped at 60 seconds
    
    return False

async def upload_file(upload_url: str, file_content: bytes, content_type: str) -> bool:
    try:
        response = requests.put(upload_url, data=file_content, headers={'Content-Type': content_type})
        return response.status_code == 200
    except Exception as e:
        print(f'Error uploading file: {e}')
        return False

Fix this script, meaning i can upload the line moves when uploading and when there is a network error it doesnt restart till the start but it continues going where its at and once its finally done then its done just keep doing that until its finally done, do this and send the entire full script without placehodlers, 0 placeholders at all none.. do this then send entire full script without placeholders