#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["YukariS8"]
#Text["Shikigami 'Chen & Ran Yakumo'. Ran used card name |Superman 'Soaring En no Ozuno'| from StB and Chen used card name |Child Sign 'Dharmapala's Rampage'| from PCB."]
#Player["./Hecatia/Hecatia.txt"]
#System["./system/Default_System.txt"]
#Background["./BG.txt"]
#include"./Functions/Index.txt"
#include"./SetBoss.txt"
#include"./Shot/AllStarShot_Const.dnh"
#include"./system/Default_Effect.Txt"


let objBoss;
let GCSD=GetCurrentScriptDirectory~"";
let enemy;
let bSpell=false;
let stgx=GetStgFrameWidth()/2;
let stgy=GetStgFrameHeight()/2;
let idle = true;
let atk = false;
let fog = 0;
let action = false;
let objScene=GetEnemyBossSceneObjectID();
let color = [276,277,278];
let color2 = [51,53,55];
let dcolor = [308,309,310];
@Initialize
{
SetBoss("Yukari",true);
SetCommonData("Bomb",1);
CreateRan;
CreateChen;
}

@MainLoop
{
	ObjEnemy_SetIntersectionCircleToPlayer(objBoss,ObjMove_GetX(objBoss),ObjMove_GetY(objBoss),18);
	ObjEnemy_SetIntersectionCircleToShot(objBoss,ObjMove_GetX(objBoss),ObjMove_GetY(objBoss),26);
	yield;

}

@Event
{
	alternative(GetEventType())
	case(EV_REQUEST_LIFE)
	{
		SetScriptResult(1500);
	}
	case(EV_REQUEST_TIMER)
	{
		SetScriptResult(150);
	}
		case(EV_REQUEST_SPELL_SCORE)
	{
		SetScriptResult(65000000);
	}
}

//----------------------------------------------------
task mainTask{
	StartCountDown;
	PlaySound("Shot1",100,0);
	YukariCircle(objBoss,1,-1);
	wait( 1 );
	ObjMove_SetPosition(objRan,384/2,-120);
	ObjMove_SetPosition(objChen,384/2,-120);
	wait( 100 );
                	ObjMove_SetDestAtWeight(objChen,stgx + 150,140,10,7);
                	ObjMove_SetDestAtWeight(objRan,stgx - 150,140,10,7);
	ObjMove_SetDestAtWeight(objBoss,stgx,140,10,7);
	wait( 110 );
	maple;
	wait( 80 );
                //ObjPlayer_ClearIntersection(GetPlayerObjectID);
	Cutin("Shikigami 'Chen & Ran Yakumo'",15,"SHINKI");
	ObjEnemyBossScene_StartSpell(objScene);
	Sound(GCSD ~ "Butterfly.mp3");
	wait(120);
	TShot1;
	wait(1200);
	}
//----------------------------------------------------

task TShot1
{
	attack( 120 );
	let angle = rand( 0, 80 );
	let dir = 0;
	maple;
	wait( 80 );

	DamageRateAtFrame(18,10,0);
	PatternRanSoaring( 1, 2 );
	while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 1000){ yield; }

	PlaySound("Shot1",100,0);
                	DeleteShotAll( TYPE_ALL, TYPE_ITEM );
	DamageRateAtFrame(0,0,0);
                	ObjMove_SetDestAtWeight(objRan,stgx - 150,140,10,4);
	wait( 120 );
	maple;
	wait( 80 );
	
	DamageRateAtFrame(14,5,0);
	PatternChenSoaring;
	while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){ yield; }

	PlaySound("Shot1",100,0);
                	DeleteShotAll( TYPE_ALL, TYPE_ITEM );
	DamageRateAtFrame(0,0,0);
                	ObjMove_SetDestAtWeight(objRan,stgx - 150,stgy,10,4);
                	ObjMove_SetDestAtWeight(objChen,stgx + 150,stgy,10,7);
                	ObjMove_SetDestAtWeight(objBoss,stgx,80,10,7);
	wait( 120 );
	maple;
	wait( 80 );

	DamageRateAtFrame(8,5,0);
	PatternYukariSleeping;
	PatternRanMoving;
	PatternChenMoving;
	PatternYukariIsNotCompletelySleeping;

	}

              task PatternRanSoaring( frequently1, frequently2 ){
              ObjMove_AddPatternA2( objRan, 0, 0, 90, 0.05, 0, 5.5 );
              EdgeSoaringA( objRan,1000000000000000 );
              EdgeSoaringB( objRan,1000000000000000 );
              let c = 0; 
              while( ObjMove_GetY( objRan ) < GetStgFrameHeight + 10 ){ yield; }
              while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 1000){

			let w = [ frequently1, frequently2 ];
			let speed = 1.2;
	                                	let way = 1;
                                                	let shote = [ 294, 296, 297 ];
              			let angle = rand( 0, 360 );
			let delay = 20;
			loop( way ){

			if((ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 1000)){

			let r = rand( 0, 20 );
                      	                	let sx = ObjMove_GetX( objRan ) + r*cos( angle );
                        		let sy = ObjMove_GetY( objRan ) + r*sin( angle );
				
				let sht1 = TShotA2( sx, sy, 0, angle, 0, 0, shote[c%length( shote )], delay );
				ObjMove_AddPatternA2( sht1, 60, 0, NO_CHANGE, 0.03, 0, speed );
				NotifyEventAll( EV_USER + 40, [ sht1, delay ] );

				angle += 360 / way;

			}		
			}
			c++;
			PlaySound("LenenShot1",92,0);
                        		wait( w[c%length( w )] );

	}
   	}

              task PatternChenSoaring{
              while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
              let a = GetAngleToPlayer( objChen );
              if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
              let ang = 140;
              ObjMove_SetAngleAndSpeed( objChen, ang, 0, 0.05, 7 ); //BLUE
	}
              loop( 25 ){

             			let speed = 1;
			let angle = a + rand( -3, 3 );
	                                	let way = 14;
                                                	let shote = 7;
			let delay = 20;
			loop( way ){

			if((ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500)){

                      	                	let sx = ObjMove_GetX( objChen );
                        		let sy = ObjMove_GetY( objChen );
				
				let sht1 = TShotA2( sx, sy, speed, angle, 0, 0, shote, delay );
				NotifyEventAll( EV_USER + 40, [ sht1, delay ] );

				angle += 360 / way;
			}
			}
              			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
			PlaySound("LenenShot1",92,0);
			}
                        		wait( 6 );		
			}

              if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
              let pos = [ 0, GetStgFrameWidth ];
              let ang = [ 45, 135 ];
              let c = round(rand(0,1));
              ObjMove_SetPosition( objChen, pos[c], 0 );
              ObjMove_SetAngleAndSpeed( objChen, ang[c], 7, 0, 7 );  //RED
	}

              loop( 20 ){

             			let speed = 1;
			let angle = a + rand( -3, 3 );
	                                	let way = 20;
                                                	let shote = 3;
			let delay = 20;
			loop( way ){

			if((ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500)){

                      	                	let sx = ObjMove_GetX( objChen );
                        		let sy = ObjMove_GetY( objChen );
				
				let sht1 = TShotA2( sx, sy, speed, angle, 0, 0, shote, delay );
				NotifyEventAll( EV_USER + 40, [ sht1, delay ] );

				angle += 360 / way;
			}
			}
              			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
			PlaySound("LenenShot1",92,0);
			}
                        		wait( 6 );		
			}
   	
              if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
              let pos = [ 90, GetStgFrameWidth - 90 ];
              ObjMove_SetPosition( objChen, pos[round(rand(0, 1))], 0 );
              ObjMove_SetAngleAndSpeed( objChen, 90, 7, 0, 7 );  //YELLOW1
	}
              loop( 18 ){

             			let speed = 1;
			let angle = a + rand( -3, 3 );
	                                	let way = 24;
                                                	let shote = 14;
			let delay = 20;
			loop( way ){

			if((ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500)){

                      	                	let sx = ObjMove_GetX( objChen );
                        		let sy = ObjMove_GetY( objChen );
				
				let sht1 = TShotA2( sx, sy, speed, angle, 0, 0, shote, delay );
				NotifyEventAll( EV_USER + 40, [ sht1, delay ] );

				angle += 360 / way;
			}
			}
              			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
			PlaySound("LenenShot1",92,0);
			}
                        		wait( 6 );		
			}

              if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
              let c = round(rand(0,1));
              let poss = [ -20, GetStgFrameWidth + 20 ];
              ObjMove_SetPosition( objChen, poss[c], stgy - 70 );
              ObjMove_SetDestAtWeight( objChen, stgx, stgy-50, 10, 4 );  //YELLOW2
	}
              loop( 10 ){

             			let speed = 1;
			let angle = a + rand( -3, 3 );
	                                	let way = 20;
                                                	let shote = 14;
			let delay = 20;
			loop( way ){

			if((ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500)){

                      	                	let sx = ObjMove_GetX( objChen );
                        		let sy = ObjMove_GetY( objChen );
				
				let sht1 = TShotA2( sx, sy, speed, angle, 0, 0, shote, delay );
				NotifyEventAll( EV_USER + 40, [ sht1, delay ] );

				angle += 360 / way;
			}
			}
              			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
			PlaySound("LenenShot1",92,0);
			}
                        		wait( 6 );		
			}

	wait( 60 );
                	if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
	maple3( objChen );
	}
	wait( 80 );

             	let speed = 0.4;
	let angle = a;
	let c = [ -2, 2 ];
	let d = round(rand(0,1));
                	loop( 12 ){
	                                	let way = 28;
                                                	let shote = 15;
			let delay = 20;
			loop( way ){

			if((ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500)){

                      	                	let sx = ObjMove_GetX( objChen );
                        		let sy = ObjMove_GetY( objChen );
				
				let sht1 = TShotA2( sx, sy, speed, angle, 0, 0, shote, delay );
				NotifyEventAll( EV_USER + 40, [ sht1, delay ] );

				angle += 360 / way;
			}
			}
			speed += 0.24;
			angle += c[d];
              			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
			PlaySound("LenenShot1",92,0);
			}
                        		wait( 4 );		
			}
                wait( 150 );
                if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 500){
                 let pos = stgx + 150;
                ObjMove_SetDestAtWeight(objChen,pos,140,10,7);
	}
	wait( 80 );
	}
   	}

              task PatternYukariSleeping{ 
              while( !Obj_IsDeleted( objBoss )){

              			let speed = 1.5;
	                                        let way = 5;
                                                            let shote = [ 99, 110 ];
              			let angle1 = rand( -3.5, 3.5 );
              			let angle2 = 180 + rand( -3.5, 3.5 );
			let delay = 20;

			loop( way ){

                      	                    let sx = [ ObjMove_GetX( objChen ), ObjMove_GetX( objRan ) ];
                        		let sy = [ ObjMove_GetY( objChen ), ObjMove_GetY( objRan ) ];
				
				let sht1 = TShotA2( sx[0], sy[0], speed, angle1, 0, speed, shote[0], delay );
				let sht2 = TShotA2( sx[1], sy[1], speed, angle2, 0, speed, shote[1], delay );

				NotifyEventAll( EV_USER + 40, [ sht1, delay ] );

				angle1 += 360 / way;
				angle2 += 360 / way;

			}
			PlaySound("LenenShot1",92,0);
                       		wait( 5 );

	}

   }

              task PatternYukariIsNotCompletelySleeping{ 
              while( !Obj_IsDeleted( objBoss )){

              			let speed = 1.5;
	                                        let way = 24;
                                                            let shote = 100;
              			let angle = GetAngleToPlayer( objBoss );
			let delay = 20;

			loop( way ){

                      	                    let sx = ObjMove_GetX( objBoss );
                        		let sy = ObjMove_GetY( objBoss );
				
				let sht1 = TShotA2( sx, sy, speed, angle, 0, speed, shote, delay );

				NotifyEventAll( EV_USER + 40, [ sht1, delay ] );

				angle += 360 / way;

			}
			PlaySound("LenenShot1",92,0);
                       		wait( 60 );

	}

   }

	task PatternRanMoving{
	while( !Obj_IsDeleted( objBoss )){
                    ObjMove_SetDestAtWeight(objRan,stgx - 150,0,1,4);
	wait( 135 );
                    ObjMove_SetDestAtWeight(objRan,stgx - 150,GetStgFrameHeight + 1,1,4);
	wait( 135 );
	}
	}

	task PatternChenMoving{
	while( !Obj_IsDeleted( objBoss )){
                    ObjMove_SetDestAtWeight(objChen,stgx + 150,GetStgFrameHeight - 1,1,4);
	wait( 135 );
                    ObjMove_SetDestAtWeight(objChen,stgx + 150,0,1,4);
	wait( 135 );
	}
	}

task ObjMove_SetAngleAndSpeed( obj, an, u, a, v ){
ObjMove_SetAngle( obj, an );
ObjMove_SetSpeed( obj, u );
ObjMove_SetAcceleration( obj, a );
ObjMove_SetMaxSpeed( obj, v );
}


task EdgeSoaringA( obj,time )
{
        let count = 0;
        while( !Obj_IsDeleted( obj ) )
        {
            if( count==time ){ break; }
            
            if( ObjMove_GetX( obj ) < -20 ){
		ObjMove_SetY( obj, -10 );
		ObjMove_SetX( obj, rand( 0, GetStgFrameWidth ) ); 
		ObjMove_SetAngle( obj, GetAngleToPlayer( obj ) );	
        		PlaySound("WarpNormal",100,0);
		yield;
		count++;
			}
            if(ObjMove_GetX( obj ) > GetStgFrameWidth + 20 ){
		ObjMove_SetY( obj, -10 );
		ObjMove_SetX( obj, rand( 0, GetStgFrameWidth ) ); 
		ObjMove_SetAngle( obj, GetAngleToPlayer( obj ) );
        		PlaySound("WarpNormal",100,0);
		yield;
		count++;
			}
            		yield;
        }
}
task EdgeSoaringB( obj,time )
{
        let count = 0;
        while( !Obj_IsDeleted( obj ) )
        {
            if( count == time ){ break; }
            
            if( ObjMove_GetY( obj ) > GetStgFrameHeight + 20 ){
		ObjMove_SetY( obj, -10 );
		ObjMove_SetX(obj,rand( 0, GetStgFrameWidth ) ); 
		ObjMove_SetAngle( obj, GetAngleToPlayer( obj ) );
        		PlaySound("WarpNormal",100,0);
		yield;
		count++;
			}
            		yield;
        }
}

	task StartCountDown
	{
		wait((150*60) - (10*60));
		loop(5)
		{
			PlaySound("time1",100,0);
			wait(60);
		}
		loop(5)
		{
			PlaySound("time2",100,0);
			wait(60);
		}
	}


//----------------------------------------------------

task TEnd{
	while(ObjEnemy_GetInfo(objBoss,INFO_LIFE)>0){yield;}
		EndBoss(1);
		yield;
		CloseScript(GetOwnScriptID());
	}

let imgChen = GCSD~"./img/boss12.png"; //Path to image for Chen
let imgRan = GCSD~"./img/boss16.png"; //Path to image for Ran
//----------------------------------------------------------
 
 
task SetRanGraphic(objBoss,row,column,ang){
ObjSprite2D_SetSourceRect(objBoss,64*(column-1), 81*(row-1)-1, 64*column, 81*row);
 
}
 
 
let objRan = ID_INVALID;
let objChen = ID_INVALID;
 
function CreateRan{
let ang = 0;
let idle = true;
let atk = false;
let tran = false;
 
objRan=ObjEnemy_Create(OBJ_ENEMY);
ObjEnemy_Regist(objRan);
ObjEnemy_SetLife(objRan,9990);
ObjEnemy_SetDamageRate(objRan,0,0);
let Rancoor = GetCommonData("Rancoor",[0,0]);
ObjMove_SetPosition(objRan,Rancoor[0],Rancoor[1]);
DrawBoss;
AddCollision;
deletion;
 
task DrawBoss{
   
    let f = 0;
    let t = 0;
    let c = 0;
    ObjPrim_SetTexture(objRan, imgRan);
    ObjRender_SetScaleXYZ(objRan,1,1,1);
    while(!Obj_IsDeleted(objRan))
    {
        let angle = ObjMove_GetAngle(objRan);
        let speed = ObjMove_GetSpeed(objRan);
        if(speed>0 && idle == true){
       
        let name = 0;
        MarisaTail(objRan,name,0,0,64,96,ang);
        }
        if(speed <= 0 && idle == true && atk == false && tran == false){
        ObjRender_SetAngleY(objRan,0);
        if(f<8){SetRanGraphic(objRan,1,1,ang);}
        if(f>=8 && f<16){SetRanGraphic(objRan,1,2,ang);}
        if(f>=16 && f<24){SetRanGraphic(objRan,1,3,ang);}
        if(f>=24 && f<32){SetRanGraphic(objRan,1,4,ang);}
        if(f>=32){f=0;}
        f++;
        c++;
        ObjRender_SetY(objRan,ObjMove_GetY(objRan)+0.1*sin(c*5));
        t = 0;
        }
        else if(cos(angle) > 0 || cos(angle) < 0 && t == 0){
        idle = false;
        if(cos(angle)>0){ang=180;}
        else{ang=0;}
        manageSprite(ang);
        t = 1;
        }
        ObjSprite2D_SetDestCenter(objRan);
        yield;
    }
}
 
task manageSprite(ang){ // Manage movement sprite
        let f = 0;
        let px = 64;
        idle = false;
        ObjRender_SetAngleY(objRan,0);
        let i = 0;
       
        while(f<=16 && idle == false  && atk == false && tran == false){
        if(f<8){SetRanGraphic(objRan,2,2,ang);}
        if(f>8&&f<16){SetRanGraphic(objRan,3,1,ang);}
 
        f+=1;
        yield;
        }
        while(ObjMove_GetSpeed(objRan)>0.5 && tran == false){
        if(ang>=180){
        i+=20;
        }else{
        i-=20;
        }
        ObjRender_SetAngleZ(objRan,i);
        SetRanGraphic(objRan,3,2,ang);
        yield;
        }
        ObjRender_SetAngleZ(objRan,0);
        while(f>=0 && idle == false  && atk == false && tran == false){
        if(f<8){SetRanGraphic(objRan,2,2,ang);}
        if(f>8&&f<16){SetRanGraphic(objRan,3,1,ang);}
        f-=1;
        yield;
        }
        idle = true;
       
       
    }
task AddCollision{
        while(!Obj_IsDeleted(objRan)){
        ObjEnemy_SetIntersectionCircleToShot(objRan,ObjMove_GetX(objRan),ObjMove_GetY(objRan),24);
        ObjEnemy_SetIntersectionCircleToPlayer(objRan,ObjMove_GetX(objRan),ObjMove_GetY(objRan),24);
       
        yield;
        }
    }
task deletion{
while(!Obj_IsDeleted(objBoss)) { yield; }
Obj_Delete(objRan);
}
    }
 
task SetChenGraphic(objBoss,row,column,ang){
ObjSprite2D_SetSourceRect(objBoss,48*(column-1), 64*(row-1)-1, 48*column, 64*row);
 
}
 
 
function CreateChen{
let ang = 0;
let idle = true;
let atk = false;
let tChen = false;
 
objChen=ObjEnemy_Create(OBJ_ENEMY);
ObjEnemy_Regist(objChen);
ObjEnemy_SetLife(objChen,999);
ObjEnemy_SetDamageRate(objChen,0,0);
let Chencoor = GetCommonData("Chencoor",[0,0]);
ObjMove_SetPosition(objChen,Chencoor[0],Chencoor[1]);
DrawBoss;
AddCollision;
deletion;
 
task DrawBoss{
   
    let f = 0;
    let t = 0;
    let c = 0;
    ObjPrim_SetTexture(objChen, imgChen);
    ObjRender_SetScaleXYZ(objChen,1,1,1);
    while(!Obj_IsDeleted(objChen))
    {
        let angle = ObjMove_GetAngle(objChen);
        let speed = ObjMove_GetSpeed(objChen);
        if(speed>0 && idle == true){
       
        //MarisaTail(objChen,0,0,64,96,ang);
        }
        if(speed <= 0 && idle == true && atk == false && tChen == false){
        ObjRender_SetAngleY(objChen,0);
        if(f<8){SetChenGraphic(objChen,1,1,ang);}
        if(f>=8 && f<16){SetChenGraphic(objChen,1,2,ang);}
        if(f>=16 && f<24){SetChenGraphic(objChen,1,3,ang);}
        if(f>=24 && f<32){SetChenGraphic(objChen,1,4,ang);}
        if(f>=32){f=0;}
        f++;
        c++;
        ObjRender_SetY(objChen,ObjMove_GetY(objChen)+0.1*sin(c*5));
        t = 0;
        }
        else if(cos(angle) > 0 || cos(angle) < 0 && t == 0){
        idle = false;
        if(cos(angle)>0){ang=180;}
        else{ang=0;}
        manageSprite(ang);
        t = 1;
        }
        ObjSprite2D_SetDestCenter(objChen);
        yield;
    }
}
 
task manageSprite(ang){ // Manage movement sprite
        let f = 0;
        let px = 64;
        idle = false;
        ObjRender_SetAngleY(objChen,0);
        let i = 0;
       
        while(f<=16 && idle == false  && atk == false && tChen == false){
        if(f<8){SetChenGraphic(objChen,3,1,ang);}
        if(f>8&&f<16){SetChenGraphic(objChen,3,2,ang);}
 
        f+=1;
        yield;
        }
        while(ObjMove_GetSpeed(objChen)>0.5 && tChen == false){
        if(ang>=180){
        i+=20;
        }else{
        i-=20;
        }
        ObjRender_SetAngleZ(objChen,i);
        SetChenGraphic(objChen,3,3,ang);
        yield;
        }
        ObjRender_SetAngleZ(objChen,0);
        while(f>=0 && idle == false  && atk == false && tChen == false){
        if(f<8){SetChenGraphic(objChen,3,1,ang);}
        if(f>8&&f<16){SetChenGraphic(objChen,3,2,ang);}
        f-=1;
        yield;
        }
        idle = true;
       
       
    }
task AddCollision{
        while(!Obj_IsDeleted(objChen)){
        ObjEnemy_SetIntersectionCircleToShot(objChen,ObjMove_GetX(objChen),ObjMove_GetY(objChen),24);
        ObjEnemy_SetIntersectionCircleToPlayer(objChen,ObjMove_GetX(objChen),ObjMove_GetY(objChen),24);
       
        yield;
        }
    }
task deletion{
while(!Obj_IsDeleted(objBoss)) { yield; }
Obj_Delete(objChen);
}
    }
   
task TChenAttack1(time){
        atk = true;
        idle = false;
        loop(8){SetChenGraphic(objChen,2,1,ang);yield;}
        loop(8){SetChenGraphic(objChen,2,2,ang);yield;}
        loop(time){SetChenGraphic(objChen,2,3,ang);yield;}
        loop(8){SetChenGraphic(objChen,2,4,ang);yield;}
        idle = true;
        atk  = false;
    }
   
task TChenAttack2(time){
        atk = true;
        idle = false;
        loop(8){SetChenGraphic(objChen,4,1,ang);yield;}
        loop(8){SetChenGraphic(objChen,4,2,ang);yield;}
        loop(time){SetChenGraphic(objChen,4,3,ang);yield;}
        idle = true;
        atk  = false;
    }