// optimisation, mise en cache des $("elem") 
var e = [];
function ce(id) { 
    if ( !e[id] ) {
        e[id] = $(id);
    }
    return e[id];
}

var timer1 = null; //timer utilisé pour le loader
var timer2 = null; //timer utilisé pour "play"

var AppCam = {

    path : 'cam/cam1/daily/',
    pathCam2: 'cam/cam2/daily/',
    delay : 200, //en ms le delay min entre deux affichages d'images 
    stopped : true,
    preload : false, //si true, va faire un accès à toutes les images pour les mettre en cache

    
    init: function() {
        
        Status.start("mainInit");
        Debug.init();        
        MainImg.init();
        //CacheImg.init();
        Controls.init();

        //chargement de la liste des images
        Status.start("AjaxImagesLoading");
        ImgsList.load();
        
        Status.end("mainInit");
    },
     
    imgsListLoaded: function(json) {

        Debug.log("count : " + ImgsList.count);
        Status.end("AjaxImagesLoading");
        //initialisation du slider
        Status.start("init2");
        
        Slider1.init();
        //Position sur l'image actuelle
        Slider1.setVal( MainImg.current );
        
        if( AppCam.preload ) {
            Status.start("preload");
            ImgsList.preload();
        }
        Status.end("init2");
    },
    
    ImagesPreloadEnded: function() {
        Status.end("preload");
    },
  
    slider1Changed: function() {
          
        //Debug.log("Slider1Changed: " + Slider1.getVal() );
        AppCam.displayImg( Slider1.getVal() );

    },

    displayImg: function( id ) {
        //affiche l'image dont l'id est transmit
        Status.end("displayImg");
        Status.start("displayImg");
        Status.end("displayImg2");
        Status.start("displayImg2");
        //Debug.log("DisplayImg: " + id );
        
        //on charge l'image en cache
        //CacheImg.load( id );
        MainImg.load( id );
    },

    displayNextImg: function() {
        //on recherche l'image actuellement dans le cache
        var actuelle = parseInt( MainImg.getId() ) ;
        var next = actuelle + 1;
        //Debug.log( "actuelle: " + actuelle );
        //Si on a pas dépassé la limite, on affiche l'image suivante
        
        
        if( actuelle > ( ImgsList.count - 2 ) ) {
            next = actuelle;
            Debug.log("Limite Haute atteinte");
            AppCam.stop();
        } else {   
            //Debug.log( "next: " + next );
            
            AppCam.displayImg( next );
            Slider1.setVal( next );    
        }

        
    },
    
    stop: function() {
        clearTimeout( timer2 );
        AppCam.stopped = true;
        Controls.displayPlay();
    },
    
    displayPrevImg: function() {
    
        //on recherche l'image actuellement dans le cache
        var actuelle = parseInt( MainImg.getId() ) ;
        var next = actuelle - 1 ;
        //Debug.log( "actuelle: " + actuelle );
        //Si on a pas dépassé la limite, on affiche l'image suivante

        if( actuelle <= 0 ) {
            next = actuelle;   
            Debug.log("Limite Basse atteinte");
        } else {   
            //Debug.log( "next: " + next );
            
            AppCam.displayImg( next );
            Slider1.setVal( next );    
        }        
    },
    
    mainImgLoaded: function() {

        //Debug.log("AppCam.mainImgLoaded");
        Status.end("displayImg");
        if( ImgsList.loaded ) {
            MainImg.displayInfo( "Images prises le " + Tools.extractDateFromId( MainImg.current ) + " vers 12h30.");
        }            


        if( AppCam.stopped ) {
            //rien
        } else {
            timer2 = setTimeout( "AppCam.displayNextImg()" , AppCam.delay ) ;
        }


    },
    
    mainImg2Loaded: function() {
        Status.end("displayImg2");    
    },
  
    btnPlayClicked: function() {
        Debug.log("play");
        AppCam.stopped = false
        AppCam.displayNextImg();
        
        //timer2 = setTimeout("AppCam.btnPlayClicked()", 200);
        
    },
    
    btnStopClicked: function() {
        
        Debug.log("stop");
        
        
        AppCam.stop();
    },
    
    btnNextClicked: function() {
        AppCam.displayNextImg();
        AppCam.stop();
    },
      
    btnPrevClicked: function() {
        AppCam.displayPrevImg();
        AppCam.stop();
    },
  
    end: function() {
        //lancé à la fermeture de l'application
    }

};

var AppCam3 = {

    path : 'cam/cam3/daily/',
    //pathCam2: 'cam/cam2/daily/',
    delay : 200, //en ms le delay min entre deux affichages d'images 
    stopped : true,
    preload : false, //si true, va faire un accès à toutes les images pour les mettre en cache

    
    init: function() {
        
        
        
        Status.start("mainInitCam3");
        Debug.init();        
        MainImgCam3.init();
        //CacheImg.init();
        ControlsCam3.init();

        //chargement de la liste des images
        Status.start("AjaxImagesLoading");
        ImgsListCam3.load();
        
        Status.end("mainInitCam3");

    },
     
    imgsListLoaded: function(json) {

        Debug.log("count : " + ImgsListCam3.count);
        Status.end("AjaxImagesLoading");
        //initialisation du slider
        Status.start("init2");
        
        Slider1Cam3.init();
        //Position sur l'image actuelle
        Slider1Cam3.setVal( MainImgCam3.current );
        
        if( AppCam3.preload ) {
            Status.start("preload");
            ImgsListCam3.preload();
        }
        Status.end("init2");
    },
    
    ImagesPreloadEnded: function() {
        Status.end("preload");
    },
  
    slider1Changed: function() {
          
        //Debug.log("Slider1Changed: " + Slider1.getVal() );
        AppCam3.displayImg( Slider1Cam3.getVal() );

    },

    displayImg: function( id ) {
        //affiche l'image dont l'id est transmit
        Status.end("displayImg3");
        Status.start("displayImg3");
        //Debug.log("DisplayImg: " + id );
        
        //on charge l'image en cache
        //CacheImg.load( id );
        MainImgCam3.load( id );
    },

    displayNextImg: function() {
        //on recherche l'image actuellement dans le cache
        var actuelle = parseInt( MainImgCam3.getId() ) ;
        var next = actuelle + 1;
        //Debug.log( "actuelle: " + actuelle );
        //Si on a pas dépassé la limite, on affiche l'image suivante
        
        
        if( actuelle > ( ImgsListCam3.count - 2 ) ) {
            next = actuelle;
            Debug.log("Limite Haute atteinte");
            AppCam3.stop();
        } else {   
            //Debug.log( "next: " + next );
            
            AppCam3.displayImg( next );
            Slider1Cam3.setVal( next );    
        }
        
    },
    
    stop: function() {
        clearTimeout( timer2 );
        AppCam3.stopped = true;
        ControlsCam3.displayPlay();
    },
    
    displayPrevImg: function() {
    
        //on recherche l'image actuellement dans le cache
        var actuelle = parseInt( MainImgCam3.getId() ) ;
        var next = actuelle - 1 ;
        //Debug.log( "actuelle: " + actuelle );
        //Si on a pas dépassé la limite, on affiche l'image suivante

        if( actuelle <= 0 ) {
            next = actuelle;   
            Debug.log("Limite Basse atteinte");
        } else {   
            //Debug.log( "next: " + next );
            
            AppCam3.displayImg( next );
            Slider1Cam3.setVal( next );    
        }        
    },
    
    mainImgLoaded: function() {

        //Debug.log("AppCam.mainImgLoaded");
        Status.end("displayImg");
        if( ImgsListCam3.loaded ) {
            MainImgCam3.displayInfo( "Image prise le " + ToolsCam3.extractDateFromId( MainImgCam3.current ) + " vers 12h30.");
        }            


        if( AppCam3.stopped ) {
            //rien
        } else {
            timer2 = setTimeout( "AppCam3.displayNextImg()" , AppCam3.delay ) ;
        }

    },
    
    mainImg2Loaded: function() {
        Status.end("displayImg2");    
    },
  
    mainImg3Loaded: function() {
        this.mainImgLoaded();
        Status.end("displayImg3");    
    },
  
    btnPlayClicked: function() {
        Debug.log("play");
        AppCam3.stopped = false
        AppCam3.displayNextImg();
        
        //alert("play");
        
        //timer2 = setTimeout("AppCam.btnPlayClicked()", 200);
        
    },
    
    btnStopClicked: function() {
        
        Debug.log("stop");
        
        
        AppCam3.stop();
    },
    
    btnNextClicked: function() {
        AppCam3.displayNextImg();
        AppCam3.stop();
    },
      
    btnPrevClicked: function() {
        AppCam3.displayPrevImg();
        AppCam3.stop();
    },
  
    end: function() {
        //lancé à la fermeture de l'application
    }

};

var ImgsList = {
    
    data: null,
    data2: null,
    count: null,
    loaded: false,

    init: function() {
    },
    
    load: function() {
    
        $.getJSON("/images/getList.php?p=" + AppCam.path , function(json) {
            ImgsList.data = json;
            ImgsList.count = json.length;
            ImgsList.loaded = true;
            AppCam.imgsListLoaded();
        });

        $.getJSON("/images/getList.php?p=" + AppCam.pathCam2 , function(json2) {
            ImgsList.data2 = json2;
        });


    },
    
    preload: function() {
        //précharge toutes les images
        
        $.preload(ImgsList.data, {
            base: "/images/img.php?w=" + MainImg.width + "&img=" + AppCam.path,
            onComplete: function( data ) {
                //Debug.log(data.image);
            },
            onFinish: function() {
                AppCam.ImagesPreloadEnded();
            },
            onRequest: function() {
                
            }
        });       
    },
    
    getPath: function( id ) {
        return AppCam.path + this.data[ id ];
    },
    
    getCount: function() {
        return this.count;
    }
};

var ImgsListCam3 = {
    
    data: null,
    data2: null,
    count: null,
    loaded: false,

    init: function() {
    },
    
    load: function() {
    
        $.getJSON("/images/getList.php?p=" + AppCam3.path , function(json) {
            ImgsListCam3.data = json;
            ImgsListCam3.count = json.length;
            ImgsListCam3.loaded = true;
            AppCam3.imgsListLoaded();
        });

    },
    
    preload: function() {
        //précharge toutes les images
        
        $.preload(ImgsListCam3.data, {
            base: "/images/img.php?w=" + MainImgCam3.width + "&img=" + AppCam3.path,
            onComplete: function( data ) {
                //Debug.log(data.image);
            },
            onFinish: function() {
                AppCam3.ImagesPreloadEnded();
            },
            onRequest: function() {
                
            }
        });       
    },
    
    getPath: function( id ) {
        return AppCam3.path + this.data[ id ];
    },
    
    getCount: function() {
        return this.count;
    }
};

var Slider1 = {

    obj: null,
    
    init: function() {

        //Debug.log("init Slider");
        
        this.obj = ce("#mainImg .slider");        
        this.obj.slider({
            change: function() {               
                AppCam.slider1Changed();
            },
            slide: function() {
                //Debug.log("slide");
                AppCam.slider1Changed();
            },
            min: 0,
            max: ImgsList.count - 1        
        });
        
        
    },
    
    setVal : function( val ) {
        //Debug.log("Setting slider value : " + val );
        this.obj.slider('option', 'value', val);
    },
      
    getVal : function() {
        return this.obj.slider('option', 'value');
    }
};

var Slider1Cam3 = {

    obj: null,
    
    init: function() {

        //Debug.log("init Slider");
        
        this.obj = ce("#mainImgCam3 .slider");        
        this.obj.slider({
            change: function() {               
                AppCam3.slider1Changed();
            },
            slide: function() {
                //Debug.log("slide");
                AppCam3.slider1Changed();
            },
            min: 0,
            max: ImgsListCam3.count - 1        
        });
        
        
    },
    
    setVal : function( val ) {
        //Debug.log("Setting slider value : " + val );
        this.obj.slider('option', 'value', val);
    },
      
    getVal : function() {
        return this.obj.slider('option', 'value');
    }
};

var Controls = {

    init : function() {
        //Debug.log ("initialisation des boutons");

        ce("#btn-next").click( function() {
            AppCam.btnNextClicked();
            return false;
        });
        
        ce("#btn-prev").click( function() {
            AppCam.btnPrevClicked();
            return false;
        });        
        
        
        ce("#btn-play-stop").click( function() {
            //on regarde si c'est play ou stop
            
            
            if( ce("#btn-play-stop").hasClass('play') ) {
                Controls.displayStop();
                AppCam.btnPlayClicked();
                
            } else {
                Controls.displayPlay();
                AppCam.btnStopClicked();
            }
            
            return false;
        });
        
        ce(".btn").hover(function(){
            $(this).addClass("hover");
        },function(){
            $(this).removeClass("hover");
        });
        
        ce(".btn").mousedown(function() {
            $(this).addClass("down");
        });

        ce(".btn").mouseup(function() {
            $(this).removeClass("down");
        });

    },
    
    displayPlay: function() {
        ce("#btn-play-stop").addClass("play"); 
        ce("#btn-play-stop").html("<span>play</span>");
    },
    
    displayStop: function() {
        ce("#btn-play-stop").removeClass("play");
        ce("#btn-play-stop").html("<span>stop</span>");
    }
};

var ControlsCam3 = {

    init : function() {
        //Debug.log ("initialisation des boutons");

        ce("#btn-next").click( function() {
            AppCam3.btnNextClicked();
            return false;
        });
        
        ce("#btn-prev").click( function() {
            AppCam3.btnPrevClicked();
            return false;
        });        
        
        
        ce("#btn-play-stop").click( function() {
            //on regarde si c'est play ou stop
            
            
            if( ce("#btn-play-stop").hasClass('play') ) {
                ControlsCam3.displayStop();
                AppCam3.btnPlayClicked();
                
            } else {
                ControlsCam3.displayPlay();
                AppCam3.btnStopClicked();
            }
            
            return false;
        });
        
        ce(".btn").hover(function(){
            $(this).addClass("hover");
        },function(){
            $(this).removeClass("hover");
        });
        
        ce(".btn").mousedown(function() {
            $(this).addClass("down");
        });

        ce(".btn").mouseup(function() {
            $(this).removeClass("down");
        });

    },
    
    displayPlay: function() {
        ce("#btn-play-stop").addClass("play"); 
        ce("#btn-play-stop").html("<span>play</span>");
    },
    
    displayStop: function() {
        ce("#btn-play-stop").removeClass("play");
        ce("#btn-play-stop").html("<span>stop</span>");
    }
};

var Status = {
    
    actions: new Array(),
    
    init: function() {
    },
    
    showLoader: function() {
        MainImg.showLoader();
    },
    
    removeLoader: function() {
        MainImg.removeLoaderAfterDelay();
    },
    
    start: function( action ) {

        Debug.log("--start: " + action);
        this.showLoader();

         //on recherche l'action dans la liste pour pouvoir la virer si elle est déjà la 
        var index = jQuery.inArray( action, this.actions );
        if( index != -1 ) {
            this.actions.splice(index,1);
        }
  
        this.actions.push( action );
        
    },
    
    end: function( action ) {
        //on recherche l'action dans la liste
        
        Debug.log("--end: " + action);
        
        var index = jQuery.inArray( action, this.actions );
        if( index != -1 ) {
            this.actions.splice(index,1);
        }
        //Debug.log( action + " stopped");
        this.pendingActions();
    },
    
    pendingActions: function() {

        if(this.actions.length == 0 ) {
            //Debug.log("!! empty");
            this.removeLoader();
        } else {
            //Debug.log("!! " + this.actions );
            this.showLoader();
        }
    }
    
    
    
};

var MainImg = {

    width: 310,
    obj: null,
    obj2: null,
    current: null,
    currentPath: null,

    init: function() {
    
        this.obj = ce("#cam1");
        this.obj2 = ce("#cam2");
        //on récupére l'image actuelle dans le code...
        this.current = 0;
        //this.current = this.obj.attr('name');
        this.obj.load( function() {
            MainImg.cam1loaded();    
        });
        
        this.obj2.load( function() {
            MainImg.cam2loaded();    
        });

        
        
    },
    
    showLoader: function() {
        //Debug.log("showLoader");
        clearTimeout( timer1 );
        ce("#mainImg .info").addClass("loader");
        ce("#mainImgCam3 .info").addClass("loader");
    },
    
    removeLoaderAfterDelay: function( delay ) {
        var delay = ( delay == null ) ? 200 : delay;
        clearTimeout( timer1 );
        timer1 = setTimeout( "MainImg.removeLoader()", delay);
    },
    
    removeLoader: function() {
        //Debug.log("removeLoader");
        ce("#mainImg .info").removeClass("loader");
        ce("#mainImgCam3 .info").removeClass("loader");
    },
    
    cam1loaded: function() {
        AppCam.mainImgLoaded();
    },
    
    cam2loaded: function() {
        AppCam.mainImg2Loaded();
    },
    
    
    load: function( id ) {
        //Debug.log("load: " + "/images/img.php?w=" + this.width + "&img=" + AppCam.path + ImgsList.data[id]);
        //Debug.log( "loading img: " + id );
        this.current = id;
        this.obj.attr( "src", "/images/img.php?w=" + this.width + "&img=" + AppCam.path + ImgsList.data[id] );
        //this.obj.attr( "src", AppCam.path + ImgsList.data[id] );
        
        //on recherche si on a une image pour la cam 2 qui a la même date
        this.loadCam2( id );

    },
    
    loadCam2: function( id ) {
        //alert("/images/img.php?w=" + this.width + "&img=" + AppCam.pathCam2 + ImgsList.data2[id]);
        this.obj2.attr( "src", "/images/img.php?w=" + this.width + "&img=" + AppCam.pathCam2 + ImgsList.data2[id] );    
    },
    
    
    getCurrent: function() {
        return this.current;
    },
    
    getId: function() {
        return this.current;
    },
        
    copyFromCache: function() {
        //charge dans l'image principale celle qui est dans le cache
        Debug.log("CopyFromCache");
        this.currentPath = CacheImg.currentPath;
        this.obj.attr("src", this.currentPath );
    },
    
    displayInfo: function( info ) {
        ce("#mainImg .info p").html( info );
    }
    
};

var MainImgCam3 = {

    width: 630,
    obj: null,
    current: null,
    currentPath: null,

    init: function() {
    
        this.obj = ce("#cam3");
        //on récupére l'image actuelle dans le code...
        this.current = 0;
        //this.current = this.obj.attr('name');
        this.obj.load( function() {
            MainImgCam3.cam3loaded();    
        });
          
    },
    
    showLoader: function() {
        //Debug.log("showLoader");
        clearTimeout( timer1 );
        ce("#mainImgCam3 .info").addClass("loader");
    },
    
    removeLoaderAfterDelay: function( delay ) {
        var delay = ( delay == null ) ? 200 : delay;
        clearTimeout( timer1 );
        timer1 = setTimeout( "MainImgCam3.removeLoader()", delay);
    },
    
    removeLoader: function() {
        //Debug.log("removeLoader");
        ce("#mainImgCam3 .info").removeClass("loader");
    },
    
    cam3loaded: function() {
        AppCam3.mainImg3Loaded();
    },
       
    load: function( id ) {

        this.current = id;
        this.obj.attr( "src", "/images/img.php?w=" + this.width + "&img=" + AppCam3.path + ImgsListCam3.data[id] );

    },
        
    getCurrent: function() {
        return this.current;
    },
    
    getId: function() {
        return this.current;
    },
        
    copyFromCache: function() {
        //charge dans l'image principale celle qui est dans le cache
        Debug.log("CopyFromCache");
        this.currentPath = CacheImg.currentPath;
        this.obj.attr("src", this.currentPath );
    },
    
    displayInfo: function( info ) {
        ce("#mainImgCam3 .info p").html( info );
    }
    
};

var Tools = {

    extractDateFromId: function( id ) {
        var string = ImgsList.getPath(id);
        //Debug.log("extract date from: " + string );
        return Tools.extractDateFromSrc( string ) ;
    },
    
    extractDateFromSrc: function( string ) {
        //on supprime le path du début
        
        //Debug.log("extract date from: " + string );
        
        //on laisse tomber... on retourne string
        //return string;
        
        if( string ) {            
            string = string.substring(AppCam.path.length + 5);
            year = string.substring(0,2);
            mounth = string.substring(3,5);
            day = string.substring(6,8);
            return day + " " + mounth + " " + year;
        } else {
            return "error" ;
        }
    }
    
};

var ToolsCam3 = {

    extractDateFromId: function( id ) {
        var string = ImgsListCam3.getPath(id);
        //Debug.log("extract date from: " + string );
        return ToolsCam3.extractDateFromSrc( string ) ;
    },
    
    extractDateFromSrc: function( string ) {
        //on supprime le path du début
        
        //Debug.log("extract date from: " + string );
        
        //on laisse tomber... on retourne string
        //return string;
        
        if( string ) {            
            string = string.substring(AppCam3.path.length + 5);
            year = string.substring(0,2);
            mounth = string.substring(3,5);
            day = string.substring(6,8);
            return day + " " + mounth + " " + year;
        } else {
            return "error" ;
        }
    }
    
};

var Debug = {
    
    init: function() {
    },
    
    log: function( msg ) {
        //alert( msg);
        //ce('#log').prepend("<br>" + msg);       
    },
    
    refresh: function() {
        ce('#security').html( AppCam.security );
    }
};

var App = {
    init: function() {
    
        
        $('a.lightbox').lightBox();      
        
        //fonctions des boutons afficher le texte complet sur la page d'accueil
        var show = "Afficher le texte complet.";
        var hide = "Masquer le texte complet.";
        
        $(".texte-complet").hide();
        
        //ajout du lien afficher le texte complet à la fin de chaque paragraphes résumé
        $('.texte-resume').append(' <a href="#" class="show-complet">' + show + '</a>');
        $('.texte-complet').append(' <a href="#" class="show-complet">' + hide + '</a>');
        
        
        $(".show-complet").click( function() {
            var c = $("#c" + $(this).parent().attr("id").substr(1) ); //complet
            var r = $("#r" + $(this).parent().attr("id").substr(1) ); //resumé
            if ( c.hasClass("open") ) {
                c.removeClass("open");
                c.hide();
                r.show();
                //$(this).html(show);
            } else {
                /*$(".texte-complet").hide();
                $(".texte-complet").removeClass("open");
                $(".show-complet").html(show);*/
                c.addClass("open");
                c.show();
                r.hide();
                //$(this).html(hide);
            }
            return false;
        });
        
        //si on est sur une page qui contient une cam...
        if( $("#mainImg").length > 0 ) {
            AppCam.init();
        }
 
        if( $("#mainImgCam3").length > 0 ) {
            AppCam3.init();
        }
        
        
        
        //chargement de la vidéo
        
        // Flowplayer installation with Flashembed parameters
		if( $("#player").length > 0) {
			flowplayer("player", {  
			// our Flash component
			src: "flash/flowplayer-3.1.5.swf",
	 
			// we need at least this version
			version: [9, 115],
	 
			// older versions will see a custom message
			onFail: function()  {
				document.getElementById("info").innerHTML =
					"Votre version de Flash est trop ancienne, veuillez mettre à jour. " +
					"Votre version : " + this.getVersion()
				;
			}
	 
			// here is our third argument which is the Flowplayer configuration
			}, {
				clip: {
					url : "/documents/flash/FF_ASSEMBLE_1_CLIP_512x288px.flv",
					autoPlay: false,
					autoBuffering: true,
					scaling: "orig"
				}
			});
			
		}
        
        
        

        
        
    },
    
    end: function() {
        //updateNewsPosCookie(); 
    }
};

function removeNews(divNum) {

  var d = document.getElementById("wrapper");
	
  var olddiv = document.getElementById(divNum);
  d.removeChild(olddiv);
  
  document.cookie = 'b4_news_aff=no';
}

function updateNewsPosCookie() {

    div_news  = document.getElementById("news");
    
    if (div_news) {
        div_news.style.position = "absolute";
    
        c_x = "b4_news_y=" + div_news.style.top;
        c_y = "b4_news_x=" + div_news.style.left;
        document.cookie = c_x;
        document.cookie = c_y;
    
    } else {
    
        document.cookie = "b4_news_y=130px";
        document.cookie = "b4_news_x=20px";
    
    }
}

function getNewsPosCookie() {

    div_news  = document.getElementById("news");
    x = readCookie("b4_news_x");
    y = readCookie("b4_news_y");

    if (div_news) {
        div_news.style.position = "absolute";
    
        div_news.style.left = x;
        div_news.style.top = y;
	
	}
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}



/////////
// INIT
////////
$(document).ready(App.init);
$(window).unload(App.end);
