SyntaxError: Unexpected token ')'
    at mn (<anonymous>:16:5455)

fix full code

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// Example placeholder for displayMessage function
// You need to implement or adjust this to your UI


// New asynchronous cycleBossAttacks function
async function cycleBossAttacks() {
    if (bossHealth <= 0) {
        if (!bossDefeatedMessageDisplayed) {
            bossDefeatedMessageDisplayed = true;
            displayMessage("Boss Defeated!", 5);
        }
        return;
    }

    // Initialize phaseStartTime and phase for fresh phases if not present
    if (!phaseStartTime) {
        phaseStartTime = Date.now();
        bossAttackPhase = 0;
    }

    // Shield on at beginning of attack cycle
    bossAttacking = true;
    bossShielded = true;
    boss.classList.add('boss-shielded');

    // Number of boss moves for level
    const maxBossMoves = (level === 1) ? 4 : (level === 2) ? 4 : 6;

    // Define async helper to handle pre-attack messaging & shields for phases 4 & 5:
async function preAttackWithMessage(phaseNumber, phaseAttackFunction, messages = []) {
    // Make a unique key for current attack in phase and level
    const key = `L${level}_P${phaseNumber}_A${bossAttackPhase}`;

    // Only show messages if not shown before for this key
    if (!shownPreMessages[key]) {
        for (const msg of messages) {
            displayMessage(msg.text, msg.durationSeconds);
            await sleep(msg.durationSeconds * 1000);
        }
        shownPreMessages[key] = true; // Mark as shown
    }
    
    // Attack now (do it every time)
    await phaseAttackFunction();

    // After attack keep shield on for 5 seconds
    displayMessage(`Shield active for 5 seconds after phase ${phaseNumber} attack`, 5);
    await sleep(5000);
}

    // Because phases 4 and 5 need to wait and show messages with shield ON before attack,
    // make sure your phase functions return Promise for awaiting or wrap if needed.
    // If they don't, I'll wrap them here:

    // Wrappers for your attack functions to make them async
    const wrapAttack = (attackFunc) => {
        return () => new Promise(resolve => {
            attackFunc();
            resolve();
        });
    };

    switch (level) {
        case 1:
            switch (bossAttackPhase) {
                case 0:
                    bossEnemyBarrage();
                    break;
                case 1:
                    bossTargetSlam();
                    break;
                case 2:
                    bossNewPower();
                    break;
                case 3:
                    bossExplosionRain();
                    break;
            }
            // Shield off after 5 seconds for these phases too
            setTimeout(() => {
                bossShielded = false;
                boss.classList.remove('boss-shielded');
                displayMessage("Boss shield is OFF! Attack now!");
            }, 5000);

            bossAttackPhase = (bossAttackPhase + 1) % maxBossMoves;
            break;

        case 2:
            switch (bossAttackPhase) {
                case 0:
                    bossPhaseTwoBarrage();
                    break;
                case 1:
                    bossPhaseTwoTargetSlam();
                    break;
                case 2:
                    bossPhaseTwoNewPower();
                    break;
                case 3:
                    bossPhaseTwoExplosionRain();
                    break;
            }
            setTimeout(() => {
                bossShielded = false;
                boss.classList.remove('boss-shielded');
                displayMessage("Boss shield is OFF! Attack now!");
            }, 5000);

            bossAttackPhase = (bossAttackPhase + 1) % maxBossMoves;
            break;

        case 3:
            if (bossAttackPhase === 0 && (Date.now() - phaseStartTime) < 13000) {
                startPhaseThree();
                return;
            }
            switch (bossAttackPhase) {
                case 0:
                    bossPhaseThree();
                    break;
                case 1:
                    bossPhaseTwoExplosionRain2();
                    break;
                case 2:
                    bossPhaseTwoTargetSlam3();
                    break;
                case 3:
                    bossPhaseTwoNewPower2();
                    break;
                case 4:
                    bossPhaseTwoTargetSlam2();
                    break;
                case 5:
                    bossPhase5();
                    break;
            }
            setTimeout(() => {
                bossShielded = false;
                boss.classList.remove('boss-shielded');
                displayMessage("Boss shield is OFF! Attack now!");
            }, 5000);

            bossAttackPhase = (bossAttackPhase + 1) % maxBossMoves;
            break;

        case 4:
            // Example startup condition before attacks on phase 0
            if (bossAttackPhase === 0 && (Date.now() - phaseStartTime) < 13000) {
                startPhaseFour();
                return;
            }

            // Define messages before each phase 4 attack optionally:
            switch (bossAttackPhase) {
                case 0:
                    // Example: Pre-attack messages before attack
                    await preAttackWithMessage(4, wrapAttack(EnemyBarrage), [{
                        text: "Lets start with something simple!",
                        durationSeconds: 4
                    }]);
                    break;
                case 1:
                    await preAttackWithMessage(4, wrapAttack(laserPhaseMove), [{
                        text: "Incredible, a nice worthy foe.",
                        durationSeconds: 3
                    }]);
                    break;
                case 2:
                    await preAttackWithMessage(5, wrapAttack(bossPhase5), [{
                        text: "Well nobody has got this far before, your doing somehow great...",
                        durationSeconds: 4
                    }]);
                    break;
                case 3:
                    await preAttackWithMessage(4, wrapAttack(bossPhaseTwoExplosionRain2), [{
                        text: "How are you NOT DEAD YET?",
                        durationSeconds: 3
                    }]);
                    break;
                case 4:
                    await preAttackWithMessage(4, wrapAttack(bossPhaseThree), [{
                        text: "Your actully getting annoying now...",
                        durationSeconds: 3
                    }]);
                    break;
                case 5:
                    await preAttackWithMessage(4, wrapAttack(slidingLaserPhase), [{
                        text: "Alright let me stop talking now its game on.",
                        durationSeconds: 4
                    }]);
                    break;
            }

            bossAttackPhase = (bossAttackPhase + 1) % maxBossMoves;
            break;

        case 5:
            // Example start condition if needed
            if (bossAttackPhase === 0 && (Date.now() - phaseStartTime) < 13000) {
                cycleBossAttacks(); // Assuming you have this
                return;
            }

            // Define messages + attacks for phase 5 (you can customize this)
            switch (bossAttackPhase) {
                case 0:
                    await preAttackWithMessage(5, wrapAttack(bossPhaseFiveAttackA), [{
                        text: "Phase 5 begins! Watch closely!",
                        durationSeconds: 4
                    }]);
                    break;
                case 1:
                    await preAttackWithMessage(5, wrapAttack(bossPhaseFiveAttackB), [{
                        text: "Don't blink!",
                        durationSeconds: 3
                    }]);
                    break;
                case 2:
                    await preAttackWithMessage(5, wrapAttack(bossPhase5)), [{
                        text: "Well nobody has got this far before, your doing somehow great...",
                        durationSeconds: 3
                    }]);
                    break;
                case 3:
                    await preAttackWithMessage(5, wrapAttack(bossPhaseFiveAttackD));
                    break;
                case 4:
                    await preAttackWithMessage(5, wrapAttack(bossPhaseFiveAttackE));
                    break;
                case 5:
                    await preAttackWithMessage(5, wrapAttack(bossPhaseFiveAttackF));
                    break;
            }

            bossAttackPhase = (bossAttackPhase + 1) % maxBossMoves;
            break;
    }
}