﻿$TTFlash avec suivi SCORM 2004
$DS
Modèle de publication pour la communication SCORM 2004. Modifié pour prendre en charge les Interactions de formation.  Comprend un JavaScript pour trouver et initialiser un objet API ADL pour SCORM 2004 et l'action FSCommand 'glue' pour permettre l'appel des fonctions LMS à partir de Flash.

$DF

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
$CS
<script type="text/javascript" language="JavaScript" name="fsIeVbscript">
<!--
// Hook pour Internet Explorer
if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 && navigator.userAgent.indexOf("Windows") != -1 && navigator.userAgent.indexOf("Windows 3.1") == -1) {
	document.write('<script language=\"VBScript\"\>\n');
	document.write('On Error Resume Next\n');
	document.write('Sub $TI_FSCommand(ByVal command, ByVal args)\n');
	document.write('	Call $TI_DoFSCommand(command, args)\n');
	document.write('End Sub\n');
	document.write('</script\>\n');
}
//-->
</script>
<title>$TI</title>
</head>
<script type="text/javascript" language="JavaScript" name="cmifrag">
<!--

// FS SCORM - adaptateur fscommand pour ADL SCORM 2004 et les interactions d'apprentissage de Flash MX 2004
// version 1.0    12/10/04
// Modifié par Andrew Chemey, Macromedia
// Basé sur la version 1.2.4 de l'adaptateur FS SCORM :
// 		Fragments Copyright 2002 Pathlore Software Corporation Tous droits réservés
// 		Fragments Copyright 2002 Macromedia Inc. Tous droits réservés.
// 		Fragments Copyright 2003 Click2learn, Inc. Tous droits réservés.
// 		Développé par Tom King, Macromedia, Leonard Greenberg, Pathlore, et Claude Ostyn, Click2learn, Inc.
// 		Une partie du code a été rédigée par Jeff Burton et Andrew Chemey, Macromedia (09/01/02)
// -----------------------------------------------------------------

// Modifiez ces valeurs prédéfinies selon vos besoins et vos préférences.
// Méthode de recherche d'un objet API (0 - recherche de bas en haut ; 1 - recherche de haut en bas)
var g_intAPIOrder = 1;
var g_bShowApiErrors = false; 	// Définissez la valeur sur true pour afficher les messages d'erreur

var g_bInitializeOnLoad = true; // Définissez la valeur sur false pour désactiver l'initialisation des fonctions LMS lors du chargement de la page HTML

// Traduisez ces chaînes si g_bShowApiErrors est défini sur true et si vous êtes amené à localiser l'application
var g_strAPINotFound = "Management system interface not found.";
var g_strAPITooDeep = "Cannot find API - too deeply nested.";
var g_strAPIInitFailed = "Found API but LMSInitialize failed.";
var g_strAPISetError = "Trying to set value but API not available.";
var g_strFSAPIError = 'LMS API adapter returned error code: "%1"\nWhen FScommand called API.%2\nwith "%3"';
var g_strDisableErrorMsgs = "Select cancel to disable future warnings.";

// Définissez g_bSetCompletedAutomatically sur true si vous souhaitez que l'état indique l'exécution automatique lors de l'appel de la fonction LMSFinish. 
// En principe, cet indicateur conserve la valeur false si l'animation Flash indique elle-même l'état en envoyant une FSCommand pour définir la valeur sur "completed" (terminé), "passed" (réussi) ou "failed" (échec), les deux dernières valeurs impliquant l'état "completed" (terminé). "passed" or "failed" (both of which imply "completed")"
var g_bSetCompletedAutomatically = false;

// Cette valeur est en principe attribuée par la fonction LMS, mais dans le cas contraire voici la valeur par défaut permettant de déterminer l'état passed/failed (réussi/échec).
// Indiquez une valeur nulle si l'actionscript Flash détermine l'état passed/fail (réussi/échec) selon sa propre méthode ou indiquez une valeur comprise entre 0 et 1 inclus (possibilité d'indiquer un nombre à virgule flottante, par exemple 0,75).
var g_SCO_MasteryScore = null; // valeurs possibles : 0,0 ; 1,0 ou nulle

//==================================================================

// AVERTISSEMENT !!!
// Ne modifiez pas la section ci-après, à moins de savoir exactement ce que vous faites !

// En principe, il n'est pas nécessaire de modifier ces deux valeurs : elles servent de référence pour la définition des paramètres du modèle Flash.
var g_nSCO_ScoreMin = 0; 		// doit être un nombre
var g_nSCO_ScoreMax = 100; 		// doit être un nombre > nSCO_Score_Min

// D'après la spécification SCORM, la note de réussite fournie par le système LMS, le cas échéant, remplace le SCO et interprète si la note doit être interprétée lorsque l'état de réussite/d'échec est déterminé.
// Le modèle essaie d'obtenir la note de réussite et le cas échéant de définir l'état de réussite/d'échec en conséquence lorsque le SCO envoie une note.
// Le système LMS ne peut pas déterminer l'état tant que le SCO ne s'est pas arrêté.
// La valeur par défaut de cet indicateur est true. Définissez-le sur false si vous ne souhaitez pas prévoir comment le LMS va définir l'état de réussite/échec en fonction de la note de réussite (le LMS sera gagnant au final de toute façon).
var g_bInterpretMasteryScore = true;

// Ce script implémente de nombreux aspects du comportement logique standard d'un SCO.

/////////// FONCTIONS D'INITIALISATION ET DE CATCHER DE L'INTERFACE API ////////
var g_nFindAPITries = 0;
var g_objAPI = null;
var g_bInitDone = false;
var g_bFinishDone = false;
var	g_bSCOBrowse = false;
var g_dtmInitialized = new Date(); // seront ajustées après l'initialisation
var g_bMasteryScoreInitialized = false;

var g_varInterval = "";			// intervalle global
var g_intIntervalSecs = 3 		// Nombre de secondes d'attente du chargement de l'API SCORM
var g_intPollSecs = 0.25			// Nombre de secondes de recherche de l'API
var g_intCurrentTime = new Date().getTime();
var g_intAPI = 0;				// Type d'API à rechercher ; valeurs autorisées : 0 - SCORM 2004 ; 1 - SCORM 1.2 (ou 1.1)
var g_aryAPI = ["1.0", "0.2"]	// Tableau contenant les versions des API
var g_strAPIVersion = -1;

function AlertUserOfAPIError(strText) {
	if (g_bShowApiErrors) {
		var s = strText + "\n\n" + g_strDisableErrorMsgs;
		if (!confirm(s)){
			g_bShowApiErrors = false
		}
	}
}

function ExpandString(s){
	var re = new RegExp("%","g")
	for (i = arguments.length-1; i > 0; i--){
		s2 = "%" + i;
		if (s.indexOf(s2) > -1){
			re.compile(s2,"g")
			s = s.replace(re, arguments[i]);
		}
	}
	return s
}

function findAPI(win)
{
	// Rechercher dans la hiérarchie de fenêtres un objet nommé "API_1484_11" pour SCORM 2004 ou "API" pour SCORM 1.2 ou antérieur
	// Examiner la fenêtre en cours (win) et effectuer une recherche récursive dans les images enfants
	if(g_intAPI == 0)
	{
		if(win.API_1484_11 != null)
		{
			return win.API_1484_11;
		}
	} else if(g_intAPI == 1 || g_intAPI == "") {
		if (win.API != null)
		{
			g_strAPIVersion = g_aryAPI[g_intAPI];
			return win.API;
		}
	}

	if (win.length > 0)  // vérifier les images
	{
		for (var i=0;i<win.length;i++)
		{
			var objAPI = findAPI(win.frames[i]);
			if (objAPI != null)
			{
				return objAPI;
			}
		}
	}
	return null;
}


function getAPI(intAPISearchOrder)
{
	// intAPISearchOrder est égal à 0 - commencer à la fenêtre en cours et remonter ; 1 - commencer à la première fenêtre et descendre.
	var objAPI = null;
	intAPISearchOrder=((typeof(intAPISearchOrder)=='undefined')?0:intAPISearchOrder);
	if(intAPISearchOrder==0)
	{
		// commencer à la fenêtre en cours et parcourir les fenêtres/images parents en remontant
		objAPI = findAPI(window);
		if((objAPI==null) && (window.opener != null) && (typeof(window.opener) != "undefined"))
		{
			objAPI = findAPI(window.opener);
		} else if((objAPI==null) && (window.parent != null) && (typeof(window.parent) != "undefined")) {
			objAPI = findAPI(window.parent);
		}
		if((objAPI==null) && (g_intAPI < (g_aryAPI.length-1)))
		{
			g_intAPI++;
			objAPI = getAPI(intAPISearchOrder);
		}
	} else {
		// commencer à la première fenêtre et parcourir les images enfants en descendant
		objAPI = findAPI(this.top);

		if (objAPI == null)
		{
			// L'API est introuvable dans la hiérarchie de la fenêtre en cours. Si la fenêtre en cours a été lancée par une autre fenêtre, vérifier la hiérarchie de cette dernière.
			objTopWindow=window.top;

			objTopWindow = objTopWindow.opener;

			while (objTopWindow && !objAPI)
			{
				//vérification de la fenêtre de lancement
				objAPI = findAPI(objTopWindow.top);
				if (objAPI==null) objTopWindow = objTopWindow.opener;
			}
			if(objAPI==null && g_intAPI < (g_aryAPI.length-1))
			{
				g_intAPI++;
				objAPI = getAPI(intAPISearchOrder);
			}
		}
	}
	if(objAPI==null)
	{
		// API introuvable
	} else if(objAPI != null && g_strAPIVersion == -1) {
		g_strAPIVersion = objAPI.version;
	}

	return objAPI;
}

function waitForAPI()
{
	if(new Date().getTime() > (g_intCurrentTime + g_intIntervalSecs*1000) || APIOK())
	{
		// délai dépassé ou API trouvée
		clearInterval(g_varInterval);
		if(!APIOK())
		{
			g_objAPI = null;
		} else {
			if (g_bInitializeOnLoad) {
				SCOInitialize()
			}
		}
	} else {
		g_objAPI = getAPI(g_intAPIOrder);
	}
}

function APIOK() {
	return ((typeof(g_objAPI)!= "undefined") && (g_objAPI != null))
}

function SCOInitialize() {
	var err = true;
	if (!g_bInitDone) {
		if (!APIOK()) {
			AlertUserOfAPIError(g_strAPINotFound);
			err = false
		} else {
			err = g_objAPI.Initialize("");
			if (err == "true") {
				g_bSCOBrowse = (g_objAPI.GetValue("cmi.mode") == "browse");
				if (!g_bSCOBrowse) {
					if (g_objAPI.GetValue("cmi.completion_status") == "not attempted") {
						err = g_objAPI.SetValue("cmi.completion_status","incomplete")
					}
				}
			} else {
				AlertUserOfAPIError(g_strAPIInitFailed)
			}
		}
		if (typeof(SCOInitData) != "undefined") {
			// La fonction SCOInitData peut être définie dans un autre script du SCO
			SCOInitData()
		}
		g_dtmInitialized = new Date();
	}
	g_bInitDone = true;
	return (err + "") // Imposer le type chaîne
}

function SCOFinish() {
	if ((APIOK()) && (g_bFinishDone == false)) {
		SCOReportSessionTime()
		if (g_bSetCompletedAutomatically){
			SCOSetStatusCompleted();
		}
		if (typeof(SCOSaveData) != "undefined"){
			// La fonction SCOSaveData peut être définie dans un autre script du SCO
			SCOSaveData();
		}
		g_bFinishDone = (g_objAPI.Terminate("") == "true");
	}
	return (g_bFinishDone + "" ) // Imposer le type chaîne
}

// Appelez ces fonctions au lieu d'essayer d'appeler directement l'adaptateur
function SCOGetValue(nam)			{return ((APIOK())?g_objAPI.GetValue(nam.toString()):"")}
function SCOCommit()					{return ((APIOK())?g_objAPI.Commit(""):"false")}
function SCOGetLastError()		{return ((APIOK())?g_objAPI.GetLastError():"-1")}
function SCOGetErrorString(n)	{return ((APIOK())?g_objAPI.GetErrorString(n):"No API")}
function SCOGetDiagnostic(p)	{return ((APIOK())?g_objAPI.GetDiagnostic(p):"No API")}

//LMSSetValue est implémenté avec des données plus complexes Logique de gestion ci-dessous

var g_bMinScoreAcquired = false;
var g_bMaxScoreAcquired = false;

// La logique spéciale commence ici
function SCOSetValue(nam,val){
	var err = "";
	if (!APIOK()){
			AlertUserOfAPIError(g_strAPISetError + "\n" + nam + "\n" + val);
			err = "false"
	} else if (nam == "cmi.score.raw") err = privReportRawScore(val)
	if (err == ""){
			err = g_objAPI.SetValue(nam,val.toString() + "");
			if (err != "true") return err
	}
	if (nam == "cmi.score.min"){
		g_bMinScoreAcquired = true;
		g_nSCO_ScoreMin = val
	}
	else if (nam == "cmi.score.max"){
		g_bMaxScoreAcquired = true;
		g_nSCO_ScoreMax = val
	}
	return err
}

function privReportRawScore(nRaw) { // appelée uniquement par SCOSetValue
	if (isNaN(nRaw)) return "false";
	if (!g_bMinScoreAcquired){
		if (g_objAPI.SetValue("cmi.score.min",g_nSCO_ScoreMin+"")!= "true") return "false"
	}
	if (!g_bMaxScoreAcquired){
		if (g_objAPI.SetValue("cmi.score.max",g_nSCO_ScoreMax+"")!= "true") return "false"
	}
	if (g_objAPI.SetValue("cmi.score.raw", nRaw)!= "true") return "false";
	g_bMinScoreAcquired = false;
	g_bMaxScoreAcquired = false;
	if (!g_bMasteryScoreInitialized){
		var nTemp = SCOGetValue("cmi.scaled_passing_score");
		nTemp = (nTemp <= 0?0:nTemp * 100);
		var nMasteryScore = parseInt(nTemp,10);
		if (!isNaN(nMasteryScore)) g_SCO_MasteryScore = nMasteryScore
	}
  	if ((g_bInterpretMasteryScore)&&(!isNaN(g_SCO_MasteryScore))){
    	var stat = (nRaw >= g_SCO_MasteryScore? "passed" : "failed");
    	if (SCOSetValue("cmi.success_status",stat) != "true") return "false";
  	}
  	return "true"
}

function MillisecondsToCMIDuration(n) {
//Convertir les délais exprimés en millisecondes au format 0000:00:00.00
	var hms = "";
	var dtm = new Date();	dtm.setTime(n);
	var h = "000" + Math.floor(n / 3600000);
	var m = "0" + dtm.getMinutes();
	var s = "0" + dtm.getSeconds();
	var cs = "0" + Math.round(dtm.getMilliseconds() / 10);
	hms = "PT" + h.substr(h.length-4)+"H"+m.substr(m.length-2)+"M";
	hms += s.substr(s.length-2)+"S";
	return hms
}

// SCOReportSessionTime est automatiquement appelée par ce script, mais vous pouvez le faire à tout moment depuis le SCO
function SCOReportSessionTime() {
	var dtm = new Date();
	var n = dtm.getTime() - g_dtmInitialized.getTime();
	return SCOSetValue("cmi.session_time",MillisecondsToCMIDuration(n))
}

// Le créateur d'un SCO étant le seul à connaître la signification de l'état completed (terminé), un autre script du SCO peut appeler cette fonction pour définir l'état completed (terminé).
// La fonction vérifie que le SCO n'est pas en mode de navigation et évite d'indiquer l'état "passed" (réussi) ou "failed" (échec), puisqu'ils impliquent l'état "completed" (terminé).
function SCOSetStatusCompleted(){
	var stat = SCOGetValue("cmi.completion_status");
	if (SCOGetValue("cmi.lesson_mode") != "browse"){
		if ((stat!="completed") && (stat != "passed") && (stat != "failed")){
			return SCOSetValue("cmi.completion_status","completed")
		}
	} else return "false"
}

// Logique de gestion objective

function SCOSetObjectiveData(id, elem, v) {
	var result = "false";
	var i = SCOGetObjectiveIndex(id);
	if (isNaN(i)) {
		i = parseInt(SCOGetValue("cmi.objectives._count"));
		if (isNaN(i)) i = 0;
		if (SCOSetValue("cmi.objectives." + i + ".id", id) == "true"){
			result = SCOSetValue("cmi.objectives." + i + "." + elem, v)
		}
	} else {
		result = SCOSetValue("cmi.objectives." + i + "." + elem, v);
		if (result != "true") {
			// Ce système LMS accepte peut-être uniquement les entrées de journalisation
			i = parseInt(SCOGetValue("cmi.objectives._count"));
			if (!isNaN(i)) {
				if (SCOSetValue("cmi.objectives." + i + ".id", id) == "true"){
					result = SCOSetValue("cmi.objectives." + i + "." + elem, v)
				}
			}
		}
	}
	return result
}

function SCOGetObjectiveData(id, elem) {
	var i = SCOGetObjectiveIndex(id);
	if (!isNaN(i)) {
		return SCOGetValue("cmi.objectives." + i + "."+elem)
	}
	return ""
}

function SCOGetObjectiveIndex(id){
	var i = -1;
	var nCount = parseInt(SCOGetValue("cmi.objectives._count"));
	if (!isNaN(nCount)) {
		for (i = nCount-1; i >= 0; i--){ //retourner en arrière si le LMS procède à de la journalisation
			if (SCOGetValue("cmi.objectives." + i + ".id") == id) {
				return i
			}
		}
	}
	return NaN
}

// Fonctions permettant de convertir des jetons ou des abréviations compatibles AICC en jetons SCORM
function AICCTokenToSCORMToken(strList,strTest){
	var a = strList.split(",");
	var c = strTest.substr(0,1).toLowerCase();
	for (i=0;i<a.length;i++){
			if (c == a[i].substr(0,1)) return a[i]
	}
	return strTest
}

function normalizeStatus(status){
	return AICCTokenToSCORMToken("completed,incomplete,not attempted,failed,passed", status)
}

function normalizeInteractionType(theType){
	return AICCTokenToSCORMToken("true-false,choice,fill-in,matching,performance,sequencing,likert,numeric", theType)
}

function normalizeInteractionResult(result){
	var strInteractionResult = AICCTokenToSCORMToken("correct,wrong,unanticipated,neutral", result)
	strInteractionResult = (strInteractionResult=="wrong"?"incorrect":strInteractionResult);
	return strInteractionResult;
}

function checkInteractionResponse(response_str)
{
	var result_str = "";
	for(var char_int=0;char_int<response_str.length;char_int++)
	{
		if(response_str.substr(char_int,1) == "." || response_str.substr(char_int,1) == ",")
		{
			if(response_str.substr(char_int - 1,1) != "[" && response_str.substr(char_int + 1,1) != "]")
			{
				result_str += "[" + response_str.substr(char_int,1) + "]";
			} else {
				result_str += response_str.substr(char_int,1);
			}
		} else {
			result_str += response_str.substr(char_int,1);
		}
	}
	result_str = (result_str==""?"0":result_str);
	return result_str;
}

function formatTimestamp(time_var)
{
	return formatDate() + "T" + formatTime(time_var, undefined, undefined, 2);
}


// ******************************************************************
// *
// *     Méthode :           formatTime
// *     Description :      Formate les secondes (transmises en tant que paramètre) en PTxHyMzS
// *     Renvoie :          Chaîne (heure formatée en HHHH:MM:SS)
// *
// ******************************************************************
function formatTime(time_var, minutes_str, seconds_str, typeFormat_int)
{
	var days_str, hours_str, formattedTime_str;
	days_str = "0";
	if(time_var == undefined)
	{
		// créer l'heure en fonction de l'heure actuelle du jour
		var time_obj = new Date();
		hours_str = time_obj.getHours();
		minutes_str = time_obj.getMinutes();
		seconds_str = time_obj.getSeconds();
	} else if(typeof(time_var) == "string" && time_var.indexOf(":") > -1) {
		var time_obj = time_var.split(":");
		hours_str = time_obj[0];
		minutes_str = time_obj[1];
		seconds_str = time_obj[2];
	} else {
		days_str    = "0";
		seconds_str = "0";
		minutes_str = "0";
		hours_str     = "0";

		seconds_str = Math.round(time_var);
		if(seconds_str > 59)
		{
			minutes_str = Math.round(seconds_str / 60);
			seconds_str = seconds_str - (minutes_str * 60);
		}
		if(minutes_str > 59)
		{
			hours_str = Math.round(minutes_str / 60);
			minutes_str = minutes_str - (hours_str * 60);
		}
		if(hours_str > 23)
		{
			days_str = Math.round(hours_str / 24);
			hours_str = hours_str - (days_str * 24);
		}
	}

	if(typeFormat_int == undefined || typeFormat_int == 1)
	{
		formattedTime_str = "P";

		if(days_str != "0")
		{
			formattedTime_str += days_str + "D";
		}
		formattedTime_str += "T" + hours_str + "H" + minutes_str + "M" + seconds_str + "S";
	} else {
		formattedTime_str = formatNum(hours_str, 2) + ":" + formatNum(minutes_str, 2) + ":" + formatNum(seconds_str, 2);
	}
	return formattedTime_str;
}

// ******************************************************************
// *
// *     Méthode :           formatDate
// *     Description :      Formate les secondes ou "MM/JJ/AAAA"
// *     Renvoie :          Chaîne (date formatée en "AAAA:MM:JJ")
// *
// ******************************************************************
function formatDate(date_var, day_str, year_str)
{
	if (date_var == undefined) {
		// créer la date en fonction de la date du jour
		var date_obj = new Date();
		date_var = formatNum((date_obj.getMonth()+1), 2);
		day_str  = formatNum((date_obj.getDate()), 2);
		year_str = (date_obj.getFullYear());
	} else if(typeof(date_var) == "string" && date_var.indexOf("/") > -1) {
		// Convertir à partir de MM/JJ/AAAA
		var date_obj = date_var.split("/");
		date_var = formatNum(date_obj[0], 2);
		day_str  = formatNum(date_obj[1], 2);
		year_str = formatNum(date_obj[2], 4);
	}
	var formattedDate_str = (year_str + "-" + date_var + "-" + day_str);
	return formattedDate_str;
}

// ******************************************************************
// *
// *    Méthode :         formatNum
// *    Description :     Convertit le nombre transmis à cette fonction en une valeur à deux ou quatre chiffres (ex. : 2 devient 02 ou 0002)
// *    Renvoie :        Chaîne (avec nombre de 0 transmis
// *
// ******************************************************************
function formatNum (initialValue_var, numToPad_int)
{
	var paddedValue_str = "";                         // Chaîne ; contient la valeur avec des 0 à gauche
	var i = 0;                                     // Entier ; variable utilisée pour les boucles
	var initialValue_str = initialValue_var.toString();    // Chaîne ; convertit le paramètre "initializeValue_var" explicitement en chaîne

	if (initialValue_str.length > numToPad_int)
	{
		// erreur - la longueur de la valeur initiale dépasse déjà le nombre auquel ajouter des zéros à gauche. Renvoie la valeur initiale de la variable sans zéros supplémentaires à gauche
	} else {
		for (var i = 1; i <= (numToPad_int - initialValue_str.length); i++)
		{
			paddedValue_str = paddedValue_str + "0";
		}
	}
	paddedValue_str = paddedValue_str + initialValue_var;
	return paddedValue_str;
}

// Détecter Internet Explorer
var g_bIsInternetExplorer = navigator.appName.indexOf("Microsoft") != -1;

// Traiter les messages fscommand depuis une animation Flash, en mappant si nécessaire les commandes de modèle Flash AICC sur SCORM
function $TI_DoFSCommand(command, args){

	var $TIObj = g_bIsInternetExplorer ? $TI : document.$TI;

	// instruction ineffective si aucun API SCORM n'est disponible

	var myArgs = new String(args);
	var cmd = new String(command);
	var v = "";
	var err = "true";
	var arg1, arg2, n, s, i;
	var sep = myArgs.indexOf(",");
	if (sep > -1){
		arg1 = myArgs.substr(0, sep); // Nom de l'élément de donnée à acquérir depuis l'API
		arg2 = myArgs.substr(sep+1) 	// Nom de la variable d'animation Flash à définir
	} else {
		arg1 = myArgs
	}
	if (!APIOK()) return;

	if (cmd.substring(0,3) == "LMS"){
		// Traiter les FScommands "LMSxxx" (compatibles avec le modèle HTML fsSCORM)
		if ( cmd == "LMSInitialize" ){
			err = (APIOK() + "")
			// La fonction LMSInitialize effective est automatiquement appelée par le modèle
		}	else if ( cmd == "LMSSetValue" ){
			alert('LMSSetValue: \r\rArg1: ' + arg1 + '\rArg2: ' + arg2);
			err = SCOSetValue(arg1,arg2)
		} else if ( cmd == "LMSFinish" ){
			err = SCOFinish()
			// Traitée automatiquement par le modèle, mais l'animation peut l'appeler avant. instruction ineffective
		}	else if ( cmd == "LMSCommit" ){
			err = SCOCommit()
		}	else if ( cmd == "LMSFlush" ){
			// no-op
			// LMSFlush n'est pas définie dans SCORM ; si vous l'appelez, une erreur de test se produit
		}	else if ((arg2) && (arg2.length > 0)){
			if ( cmd == "LMSGetValue") {
				alert('LMSSetValue: \r\rArg1: ' + arg1 + '\rArg2: ' + arg2);
				$TIObj.SetVariable(arg2, SCOGetValue(arg1));
			}	else if ( cmd == "LMSGetLastError") {
				$TIObj.SetVariable(arg2, SCOGetLastError(arg1));
			}	else if ( cmd == "LMSGetErrorString") {
				$TIObj.SetVariable(arg2, SCOGetLastError(arg1));
			}	else if ( cmd == "LMSGetDiagnostic") {
				$TIObj.SetVariable(arg2, SCOGetDiagnostic(arg1));
			}	else {
				// pour une extension LMSGetxxxx inconnue
				v = eval('g_objAPI.' + cmd + '(\"' + arg1 + '\")');
				$TIObj.SetVariable(arg2,v);
			}
		} else if (cmd.substring(0,3) == "LMSGet") {
			err = "-2: No Flash variable specified"
		}
		// fin du traitement des commandes "LMSxxx"
	} else if ((cmd.substring(0,6) == "MM_cmi")||(cmd.substring(0,6) == "CMISet")) {
		// Traiter des FScommands de composants d'apprentissage Macromedia.
		// Ces commandes utilisent des conventions de modèle de données HACP AICC. Vous devrez mapper les données vers SCORM le cas échéant.
		var F_intData = myArgs.split(";");
		if (cmd == "MM_cmiSendInteractionInfo") {
			n = SCOGetValue("cmi.interactions._count");
			s = "cmi.interactions." + n + ".";
			// Repérez les erreurs majeures pour éviter l'échec au test de conformité SCORM
			// Si aucun ID d'interaction n'est spécifié, il est impossible de l'enregistrer
			v = F_intData[2]
			if ((v == null) || (v == "")) err = 201; // Sans ID, il ne sert à rien d'enregistrer
			if (err =="true"){
				err = SCOSetValue(s + "id", v)
			}
			if (err =="true"){
				var re = new RegExp("[{}]","g")
				for (i=1; (i<9) && (err=="true"); i++){
					v = F_intData[i];
					if ((v == null) || (v == "")) continue
					if (i == 1){
						err = SCOSetValue(s + "timestamp", formatTimestamp(v))
					} else if (i == 3){
						err = SCOSetValue(s + "objectives.0.id", v)
					} else if (i == 4){
						err = SCOSetValue(s + "type", normalizeInteractionType(v))
					} else if (i == 5){
						// strip out "{" and "}" from response
						v = v.replace(re, "");
						err = SCOSetValue(s + "correct_responses.0.pattern", checkInteractionResponse(v))
					} else if (i == 6){
						// strip out "{" and "}" from response
						v = v.replace(re, "");
						err = SCOSetValue(s + "learner_response", checkInteractionResponse(v))
					} else if (i == 7){
						err = SCOSetValue(s + "result", normalizeInteractionResult(v))
					} else if (i == 8){
						err = SCOSetValue(s + "weighting", v)
					} else if (i == 9){
						err = SCOSetValue(s + "latency", v)
					}
				}
			}
		} else if (cmd == "MM_cmiSendObjectiveInfo"){
			err = SCOSetObjectiveData(F_intData[1], ".score.raw", F_intData[2])
			if (err=="true"){
				SCOSetObjectiveData(F_intData[1], ".status", normalizeStatus(F_intData[3]))
			}
		} else if ((cmd=="CMISetScore") ||(cmd=="MM_cmiSendScore")){
			err = SCOSetValue("cmi.score.raw", F_intData[0]);
		} else if ((cmd=="CMISetStatus") || (cmd=="MM_cmiSetLessonStatus")){
			var strTempStatus = normalizeStatus(F_intData[0]);
			if (strTempStatus == "passed" || strTempStatus == "failed")
			{
				err = SCOSetValue("cmi.success_status", normalizeStatus(F_intData[0]))
			} else {
				err = SCOSetValue("cmi.completion_status", normalizeStatus(F_intData[0]))
			}
		} else if (cmd=="CMISetTime"){
			err = SCOSetValue("cmi.session_time", formatTime(F_intData[0]))
		} else if (cmd=="CMISetCompleted"){
			err = SCOSetStatusCompleted()
		} else if (cmd=="CMISetStarted"){
			err = SCOSetValue("cmi.completion_status", "incomplete")
		} else if (cmd=="CMISetPassed"){
			SCOSetValue("cmi.completion_status", "completed");
			err = SCOSetValue("cmi.success_status", "passed")
		} else if (cmd=="CMISetFailed"){
			SCOSetValue("cmi.completion_status", "completed");
			err = SCOSetValue("cmi.success_status", "failed")
		} else if (cmd=="CMISetData"){
			err = SCOSetValue("cmi.suspend_data", F_intData[0])
		} else if (cmd=="CMISetLocation"){
			err = SCOSetValue("cmi.location", F_intData[0])
		} else if (cmd=="CMISetTimedOut"){
			err = SCOSetValue("cmi.exit", "time-out")
		} // D'autres FScommands de composant d'apprentissage sont des instructions ineffectives dans ce contexte
	} else {
		if (cmd=="CMIFinish" || cmd=="CMIExitAU"){
			err = SCOFinish()
		} else if (cmd=="CMIInitialize" || cmd=="MM_StartSession"){
			err = SCOInitialize()
		} else {
			// Commande inconnue ; invoque peut-être une extension API
			// Si les commandes possèdent un 2ème argument, indiquez une valeur. Il peut également s'agir d'une cmd
			if (eval('g_objAPI.' + cmd)) {
				v = eval('g_objAPI.' + cmd + '(\"' + arg1 + '\")');
				if ((arg2) && (arg2.length > 0)){
					$TIObj.SetVariable(arg2,v)
				} else {
					err = v
				}
			} else {
				err = "false"
			}
		}
	}
	// Fin de traduction et de traitement de la commande
	// traiter les erreurs détectées, les renvois d'erreur LMS par exemple
	if ((g_bShowApiErrors) && (err != "true")) {
		AlertUserOfAPIError(ExpandString(g_strFSAPIError, err, cmd, args))
	}
	return err
}
//-->
</script>
<body bgcolor="$BG" onunload="SCOFinish()" onbeforeunload="SCOFinish()">
<script type="text/javascript" language="JavaScript" name="earlyInit">
<!--
// Déterminer si l'initialisation de l'API doit être effectuée avant le chargement de l'animation au cas où du code ActionScript se déclenche avant le chargement complet de la page HTML. 
// Vous pouvez configurer cette opération en définissant le booléen global (g_bInitializeOnLoad) au début de ce fichier. La valeur par défaut est TRUE.

// Rechercher l'API SCORM
g_varInterval = setInterval('waitForAPI()', (g_intPollSecs * 1000));

//-->
</script>
<!-- URL utilisées dans l'animation-->
$MU
<!-- texte utilisé dans l'animation-->
$MT
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=$FV,$JR,$NR,0" id="$TI" width="$WI" height="$HE" align="$HA">
<param name="allowScriptAccess" value="sameDomain" />
$PO
<embed $PEwidth="$WI" height="$HE" name="$TI" align="$HA" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer_fr" />
</object>
</body>
</html>
