/***********************************************************************************
Attin3
Copyright (C)2003-2007 SATT, Inc. All Rights Reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE..  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

************************************************************************************
日本訳: （英文優先）


Attain3
Copyright (C)2003-2007 SATT, Inc. All Rights Reserved.

このライブラリはフリーソフトウェアです。あなたはこれを、フリーソフトウェ
ア財団によって発行されたGNU 劣等一般公衆利用許諾契約書(バージョン2.1 
か、希望によってはそれ以降のバージョンのうちどれか)の定める条件の下で
再頒布または改変することができます。


このライブラリは有用であることを願って頒布されますが、*全くの無保証* 
です。商業可能性の保証や特定の目的への適合性は、言外に示されたものも含
め全く存在しません。詳しくはGNU 劣等一般公衆利用許諾契約書をご覧くださ

い。


あなたはこのライブラリと共に、GNU 劣等一般公衆利用許諾契約書の複製物を

一部受け取ったはずです。もし受け取っていなければ、フリーソフトウェア財
団まで請求してください(宛先は the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA)。


***********************************************************************************/

// Trueはコード中ではtrue、Falseはfalse、Nilはundefined、n/aは""、Nullは""
// 未定義かどうかはundefinedか、nullかを両方チェック
var ChildWindow;
var API_1484_11=createMyAPI_1484_11();
var termination_request;
var href_hash=new Array(); // from resource ID to href
var current_activity; // カレントアクティビティ
var suspended_activity; // サスペンドされたアクティビティ
var choiced_activity; // Choiceで選ばれたアクティビティ
var manifest; // Manifestファイル全体


var items=new Array(); // 全てのitem(organization含)
var exit_page="exitAll.html";
var suspend_page="suspendAll.html";
var suspend_program = "suspend.cfm"; // JSONテキストを送りつけるためのプログラム
var resume_program = "resume.cfm"; // JSONテキストを取ってくるためのプログラム
var uri_base=""; // このjsファイルで決め打ちにはせず、外部(HTMLファイル)から貰うようにする
var cource_name="hoge"; // コース名称
var toc_win; // 目次ウィンドウ
var err_code=0;  // エラーコード


var xmlhttp;
var sco_log_current;

// アクティビティ(のidentifier)をキーに取る連想配列
var tracked = new Array(); // Tracked SM.11
var activity_is_suspended = new Array(); // Activity is Suspended AM.1.1
var completion_set_by_content = new Array(); // SM.11 完了状態をSCOから設定するか(bool)
var activity_progress_status = new Array(); // TM.1.2.1 アクティビティ進捗情報が意味を持つか(bool)
var attempt_progress_status = new Array(); // TM.1.2.2 試行進捗情報が意味を持つか(bool)
var attempt_completion_status = new Array(); // TM.1.2.2 試行が完了しているか(bool)
var attempt_completion_amount = new Array(); // TM.1.2.2 アクティビティの試行の完了についての度合い(0-1)
var attempt_absolute_duration = new Array(); // TM.1.2.2. アクティビティの試行期間

var attempt_experienced_duration = new Array(); // TM.1.2.2. アクティビティの試行における経験期間


var objective_set_by_content = new Array(); // SM.11 学習目標習得状態をSCOから設定するか(bool)
var activity_is_active = new Array(); // AM.1.1
var activity_attempt_count = new Array(); // TM.1.2.1
var item_primary_objectives = new Array(); // from item's id to primaryObjective(IDではない)
var item_objectives = new Array(); // from item's id to objective's array
var item_interactions = new Array(); // from item's id to interactions' array
var item_from_id = new Array(); // from ID to item

// SM.8 ロールアップ系 → imsss:rollupRules要素のrollupObjectiveSatisfied属性で決まる(親のrollupに影響するか)
var rollup_objective_satisfied = new Array(); 
// SM.8 ロールアップ系 → imsss:rollupRules要素のrollupProgressCompletion属性で決まる(親のrollupに影響するか)
var rollup_progress_completion = new Array(); 
// SM.8 ロールアップ系 → imsss:rollupRules要素のobjectiveMeasureWeight属性で決まる


var rollup_objective_measure_weight = new Array(); 

// SCO(のID)と学習目標(のobjectiveID)をキーに取る2次元連想配列
var objective_contributes_to_rollup = new Array(); // SM.6 → これは即ちprimaryObjectiveであるということ
var objective_progress_status = new Array(); // TM.1.1 学習目標が習得値を持つか(bool)
var objective_satisfied_status = new Array(); // TM.1.1 学習目標が習得されたか(bool)
var objective_measure_status = new Array(); // TM.1.1 学習目標が習得度を持つか(bool) → 習得度はNormalized Measure
var objective_normalized_measure = new Array(); // TM.1.1 → cmi.score.scaledで決まる


var cmi_datamodel = new Array(); // CMIデータモデル用 連想配列

var minNormalizedMeasure = new Array();

// グローバル共有学習目標を扱うための連想配列
objective_progress_status_global = new Array();
objective_satisfied_status_global = new Array();
objective_measure_status_global = new Array();
objective_normalized_measure_global = new Array();

//Attain2004用
var sco_window;
var fromFlashRequest = "";

function createMyAPI_1484_11(){
	if(typeof theAPI=='undefined'){
		theAPI=new defineMyAPI_1484_11();
		return theAPI;
	} else {
		return theAPI;
	}
}

function defineMyAPI_1484_11(){
	this.name="API_1484_11";
	this.Initialize=function Initialize(iParam){
		sco_log_current=current_activity;
		/*murakami20070129始点*/
		//Attain2のDBへ
		var dummy = null;
		//var FlashApi2004Obj = InternetExplorer ? FlashApi2004 : document.FlashApi2004;
		value = -1;
		window.document.FlashApi2004.TCallLabel( "/", "APIInitialize" );
		for(i=0; i<100; i++){
			dummy = window.document.FlashApi2004.GetVariable("isGatewayOpen");
			if (dummy=="true"||dummy=="false"){
				value = dummy;
				break;
			}
		}
		return value;
		/*murakami20070129終点*/
		return "true";
	}
	
	this.Terminate=function Terminate(iParam){
		// 試行進捗情報を送る
		var completion_log;
		
		// (超番外編)ためしに試行終了プロセスを使ってみる

		//End_Attempt_Process(sco_log_current);
		
		// (超番外編)ためしにオーバーオールロールアッププロセスを使ってみる

		//Overall_Rollup_Process(sco_log_current);
		
		if(attempt_progress_status[id(sco_log_current)]==true){
			if(attempt_completion_status[id(sco_log_current)]==true){
				completion_log="completed";
			} else {
				completion_log="incomplete";
			}
		} else {
			completion_log="unknown";
		}
		
		var parameter = iParam = getItemStatusFromFlash("1");//シーケンシング適用後のステータスデータ文字列の取得

		
		window.document.FlashApi2004.SetVariable( "_root.fParam_str", iParam );//Flashに投げる		
		//Attain2のDBへ
		window.document.FlashApi2004.TCallLabel( "/", "APIFinish" );
		return "true";
	}
	
	this.GetValue=function GetValue(iModel){
		//変更20070322
		var get_val=CMI_GetValue(iModel);
		return get_val;
	}
	
	this.SetValue=function SetValue(iModel,iParam){
		var set_val=CMI_SetValue(iModel,iParam);
		
		//Attain2のDBへ
		var command = iModel;
		var parameter = iParam;
		window.document.FlashApi2004.SetVariable( "_root.fCommand_str", command );
		window.document.FlashApi2004.SetVariable( "_root.fParam_str", parameter );
		window.document.FlashApi2004.TCallLabel( "/" , "SetValue" );
		return "true";
	}
	
	this.Commit=function Commit(iParam){
		// 試行進捗情報を送る
		var completion_log;
		
		// (超番外編)ためしに試行終了プロセスを使ってみる

		//End_Attempt_Process(current_activity);
		
		// (超番外編)ためしにオーバーオールロールアッププロセスを使ってみる

		//Overall_Rollup_Process(current_activity);
		
		// (超番外編)ためしに目次も書き換えてみる

		//parent.my_toc_update(id(current_activity));
		
		if(attempt_progress_status[id(sco_log_current)]==true){
			if(attempt_completion_status[id(sco_log_current)]==true){
				completion_log="completed";
			} else {
				completion_log="incomplete";
			}
		} else {
			completion_log="unknown";
		}
		
		window.document.FlashApi2004.TCallLabel( "/", "Commit" );
		return "true";
	}
	
	this.GetLastError=function GetLastError(){
		return 0;
	}
	
	this.GetErrorString=function GetErrorString(iParam){
		return "";
	}
	
	this.GetDiagnostic=function GetDiagnostic(iParam){
		return "";
	}
}

function Overall_Sequencing_Process(navigation_request,item){ // p43-44
	// 1.1. ナビゲーション要求プロセスをナビゲーション要求に適用する
	// 注) ここでの返り値はTrueとFalseに分ける(LTSに戻さず継続する時はTrue)
	var navigation_request_result=Navigation_Request_Process(navigation_request,item);
	var sequencing_request=navigation_request_result.sequencing;
	var target_activity=navigation_request_result.target;
	var delivery_request="";
	
	/****************************
	何がリクエストされているかフラッシュに返すための変数に格納

	*****************************/
	fromFlashRequest = navigation_request;
	
	if(navigation_request_result.navigation=="Not Valid"){ // 1.2.
		// 1.2.1. ナビゲーション要求エラーを処理

		alert("シーケンシングエラーです。");
		return true; // 1.2.2. continue
	}
	
	if(navigation_request_result.termination!=""){ // 1.3. 終了要求がある
		// 1.3.1. 終了要求プロセスを終了要求に適用する
		var termination_process_result = Termination_Request_Process(navigation_request_result.termination);
		
		// 1.3.2. 終了要求プロセスが「終了要求がNot Valid」という結果を返した

		if(termination_process_result.termination=="Not Valid"){
			// 1.3.2.1. ナビゲーション要求エラー処理

			alert("シーケンシングエラーです。");
			return true; // 1.3.2.2. continue
		}
		
		if(termination_process_result.sequencing!=""){ // 1.3.3. 終了要求プロセスがシーケンシング要求を返した

			// 1.3.3.1. 留保中のシーケンシング要求を終了要求プロセスが返したシーケンシング要求で置き換える
			sequencing_request = termination_process_result.sequencing;
		}
	}
	
	if(sequencing_request!=""){ // 1.4. シーケンシング要求がある
		// 1.4.1. シーケンシング要求プロセスをシーケンシング要求に適用する
		var sequencing_process_result=Sequencing_Request_Process(sequencing_request,target_activity);
		
		// 1.4.2. シーケンシング要求プロセスが「シーケンシング要求がNot Valid」という結果を返した

		if(sequencing_process_result.sequencing_demand=="Not Valid"){
			// 1.4.2.1. シーケンシング要求エラーを処理

			alert("シーケンシングエラーです。");
			return true; // 1.4.2.2. continue
		}
		
		// 1.4.3. シーケンシング要求プロセスが「シーケンシングセッションを終える」という要求を返した

		if(sequencing_process_result.sequencing_session=="exit"){
			return false;  // 1.4.3.1. オーバーオールシーケンシングプロセスが終了した; 制御をLTSに戻す

		}
		
		// 1.4.4. シーケンシング要求プロセスが配信アクティビティを特定しなかった

		if(sequencing_process_result.delivery_request==undefined ||
		   sequencing_process_result.delivery_request==null ||
		   sequencing_process_result.delivery_request+"" ==""){
			alert("シーケンシングエラーです。");
			return true; // 1.4.4.1. 
		}
		
		// 1.4.5. 配信要求はシーケンシング要求プロセスが特定したアクティビティである
		delivery_request=sequencing_process_result.delivery_request;
		
		// (番外編)startの時とresumeAllの時は、Current Activityを開始アクティビティに設定

		/*if(navigation_request_result.sequencing=="start"){
			current_activity=delivery_request;
		} else if(navigation_request_result.sequencing=="resumeAll"){
			current_activity=delivery_request;
		}*/
	}
	
	if(delivery_request!=undefined && delivery_request!=null){ // 1.5. 配信要求が存在する
		// 1.5.1. 配信要求プロセスを配信要求に適用する;
		var delivery_request_result=Delivery_Request_Process(delivery_request);
		
		if(delivery_request_result=="Not Valid"){ // 1.5.2. 配信要求プロセスがNot Validという結果を返した

			// 1.5.2.1. 配信要求エラーを処理

			alert("シーケンシングエラーです。");
			return true; // 1.5.2.2. continue
		}
		// 1.5.3. コンテンツ配信環境プロセスを配信要求に適用する
		Contents_Delivery_Environment_Process(delivery_request);
	}
	
	return true; // 2. 次のナビゲーション要求を待つ
}

function Exit_Action_Rule_Sequencing_Subprocess(){ 
	// p56 終了アクションルールシーケンシングサブプロセス
	// Current Activityを変更する場合がある
	// Exit動作の集合とは("exit")のことである
	
	//1. アクティビティツリーのルートからCurrent Activityの親アクティビティまで、両端のアクティビティを含む
	// 順序付き系列のアクティビティパスを作る
	var activity_path_to_current_parent = new Array();
	tmp_item = current_activity.parentNode;
	while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
		activity_path_to_current_parent.push(tmp_item);
		tmp_item = tmp_item.parentNode;
	}
	activity_path_to_current_parent.reverse(); // 「ルートから」なので逆順にする
	var exit_target = ""; // 2. 終了ターゲットをNullとする
	for(var ap=0;ap<activity_path_to_current_parent.length;ap++){ // 3. アクティビティパスの各アクティビティ
		// 3.1. アクティビティとExit動作の集合に対してシーケンシングルールチェックプロセスを適用する
		// 3.2. シーケンシングルールチェックプロセスがNilを返さなければ	
		if(Sequencing_Rule_Check_Process(activity_path_to_current_parent[ap],new Array("exit"))!=undefined){
			// 3.2.1. 終了ターゲットをアクティビティとする
			exit_target=activity_path_to_current_parent[ap];
			break;
		}
	}
	
	if(exit_target != ""){ // 4. 終了ターゲットがNullでなければ
		// 4.1. 終了ターゲットに下位試行終了プロセスを適用する
		Terminate_Descendent_Attempts_Process(exit_target);	
		// 4.2. 終了ターゲットに試行終了プロセスを適用する
		End_Attempt_Process(exit_target);
		// 4.3. Current Activityを終了ターゲットに設定する



		current_activity=exit_target;
	}
	// 5. Exit 
}

function Post_Condition_Rule_Sequencing_Subprocess(){
	// p57-58 事後条件ルールシーケンシングサブプロセス
	// Current Activityに対して終了要求とシーケンシング要求を返す
	// 値を返す時はstruct_post_condition(構造体風の入れ物)を使う



	
	// 1. Current ActivityのActivity is SuspendedがTrue
	if(activity_is_suspended[id(current_activity)]==true){ 
		// 1.1. Exit(仕様書にはシーケンシング要求と終了要求の値が書かれていないので、とりあえず両方空文字列)
		return new struct_post_condition("",""); 
	}
	
	// 2. Current ActivityとPost Condition動作の集合に対してシーケンシングルールチェックプロセスを適用する
	var checked=Sequencing_Rule_Check_Process(current_activity, new Array("exitParent","exitAll","retry","retryAll","continue","previous"));
	// 3. シーケンシングルールチェックプロセスがNilを返さなければ
	if(checked!=undefined){
		// 3.1. シーケンシングルールチェックプロセスがRetry,ContinueないしPreviousを返したら
		if(checked=="retry"||checked=="continue"||checked=="previous"){
			// 3.1.1. シーケンシング要求はシーケンシングルールチェックプロセスの返却値、



			// 終了要求はn/a
			return new struct_post_condition(checked,"");
		}
		
		// 3.2. シーケンシングルールチェックプロセスがExit ParentないしExit Allを返したら
		if(checked=="exitParent"||checked=="exitAll"){
			// 3.2.1. シーケンシング要求はn/a、終了要求はシーケンシングルールチェックプロセスの返却値
			return new struct_post_condition("",checked);
		}
		
		// 3.3. シーケンシングルールチェックプロセスがRetry Allを返したら
		if(checked=="retryAll"){
			// 3.3.1. シーケンシング要求はRetry、終了要求はExit All
			return new struct_post_condition("retry","exitAll");
		}
	}
	return new struct_post_condition("",""); // 4. Exit
}

function Navigation_Request_Process(navigation_request,item){ // ナビゲーション要求プロセス
	// P47-52 ナビゲーション要求と場合により指定されたアクティビティに対して、ナビゲーション要求の有効性を返却する
	// 場合に応じて終了要求、シーケンシング要求、およびターゲットアクティビティを返却する
	// 値を返す時はstruct_navigation(構造体風の入れ物)を使う

	switch(navigation_request){
	case "start": // 1. ナビげーション要求がStart
		if(current_activity==undefined || current_activity==null){ // 1.1. Current Activityが定義されていない



			// 1.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はStart,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			Initialize_Models(); // (番外編)各モデルを初期化
			return new struct_navigation("Valid","start","","");
		} else { // 1.2.
			// 1.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "resumeAll": // 2. ナビげーション要求がResume All
		Initialize_Models(); // (番外編)各モデルを初期化
		if(current_activity==undefined || current_activity==null){ // 2.1. Current Activityが定義されていない

			suspend_resume_data(onload_resume,'&courseID='+resumeCourseID+'&id='+resumeID,'POST', resume_program ,false);
			current_activity = undefined;
			
			if(suspended_activity!=undefined && suspended_activity!=null){ // 2.1.1. Suspended Activityが定義されている
				// 2.1.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はResume All,
				// 終了要求はn/a, ターゲットアクティビティはn/a
				return new struct_navigation("Valid","resumeAll","","");
			} else { // 2.1.2.
				// 2.1.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a, 
				// 終了要求はn/a, ターゲットアクティビティはn/a
				// (番外編) suspended activityがない時は咄嗟にstartナビゲーション要求に切替える
				return new struct_navigation("Valid","start","",""); 
				
				// 本来は(仕様書上は)Not Validを返さないといけない



				//return new struct_navigation("Not Valid","","","");
			}
		} else { // 2.2.
			// 2.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "continue": // 3. ナビげーション要求がContinue
		if(current_activity==undefined || current_activity==null){ // 3.1. Current Activityが定義されていない

			// 3.1.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		
		// 3.2. Current Activityがアクティビティツリーのルートでは無い And 
		// Current Activityの親のシーケンシングコントロールFlowがTrue
		if(current_activity.nodeName!="organization" && My_Control_Mode(current_activity.parentNode,"flow")==true){
			if(activity_is_active[id(current_activity)]==true){ // 3.2.1. Current ActivityのActivity is ActiveがTrue
				// 3.2.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はContinue,
				// 終了要求はExit, ターゲットアクティビティはn/a
				return new struct_navigation("Valid","continue","exit","");
			} else {// 3.2.2.
				// 3.2.2.1. Exit ナビゲーション要求はValid, シーケンシング要求はContinue,
				// 終了要求はn/a, ターゲットアクティビティはn/a
				return new struct_navigation("Valid","continue","","");
			}
		} else { // 3.3.
			// 3.3.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "previous": // 4. ナビげーション要求がPrevious
		if(current_activity==undefined || current_activity==null){ // 4.1. Current Activityが定義されていない



			// 4.1.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		
		if(current_activity.nodeName!="organization"){ // 4.2. Current Activityがアクティビティツリーのルートでは無い



			// 4.2.1. Current Activityの親のシーケンシングコントロールFlowがTrue And 
			// Current Activityの親のアクティビティのシーケンシングコントロールForward OnlyがFalse
			if(My_Control_Mode(current_activity.parentNode,"flow")==true && My_Control_Mode(current_activity.parentNode,"forwardOnly")==false){
				if(activity_is_active[id(current_activity)]==true){ // 4.2.1.1. Current ActivityのActivity is ActiveがTrue
					// 4.2.1.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はPrevious,
					// 終了要求はExit, ターゲットアクティビティはn/a
					return new struct_navigation("Valid","previous","exit","");
				} else { // 4.2.1.2.
					// 4.2.1.2.1. Exit ナビゲーション要求はValid, シーケンシング要求はPrevious,
					// 終了要求はn/a, ターゲットアクティビティはn/a
					return new struct_navigation("Valid","previous","","");
				}
			} else { // 4.2.2. 
				// 4.2.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
				// 終了要求はn/a, ターゲットアクティビティはn/a
				return new struct_navigation("Not Valid","","","");
			}
		} else { // 4.3.
			// 4.3.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "forward": // 5. ナビげーション要求がForward
		// 5.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
		// 終了要求はn/a, ターゲットアクティビティはn/a
		return new struct_navigation("Not Valid","","","");
		break;
	case "backward": // 6. ナビげーション要求がBackward
		// 6.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
		// 終了要求はn/a, ターゲットアクティビティはn/a
		return new struct_navigation("Not Valid","","","");
		break;
	case "choice": // 7. ナビげーション要求がChoice
		// 7.1. Choiceナビゲーション要求が指定したアクティビティがアクティビティツリーに存在する
		if(item!=undefined && item!=null){
			// 7.1.1. Choiceナビゲーション要求が指定したアクティビティがアクティビティツリーのルートである Or 
			// Choiceナビゲーション要求が指定したアクティビティの親のシーケンシングコントロールChoiceがTrue
			if(item.nodeName=="organization" || My_Control_Mode(item.parentNode,"choice")==true){
				// 7.1.1.1. Current ActivityとChoiceナビゲーション要求が指定したアクティビティの共通の祖先を見つける
				var common_ancestor; // 共通の祖先となるアクティビティ
				var found_common=false; // 共通の祖先が見つかったか
				var current_activity_to_root = new Array();
				var tmp_item = current_activity;
				
				while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
					current_activity_to_root.push(tmp_item);
					tmp_item = tmp_item.parentNode;
				}
				
				var item_to_root = new Array();
				tmp_item = item;
				
				while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
					item_to_root.push(tmp_item);
					tmp_item = tmp_item.parentNode;
				}
				
				for(var c=0;c<current_activity_to_root.length;c++){
					for(var i=0;i<item_to_root.length;i++){
						if(current_activity_to_root[c]==item_to_root[i]){
							common_ancestor=current_activity_to_root[c];
							found_common=true;
							break;
						}
					}
					
					if(found_common==true){
						break;
					}
				}
				
				// 7.1.1.2. Current Activityから共通の祖先へ、共通の祖先を除いて、アクティビティの順序付き系列である
				// アクティビティパスを作る
				var activity_path_to_common_ancestor = new Array();
				tmp_item = current_activity;
				
				while(tmp_item != common_ancestor){
					activity_path_to_common_ancestor.push(tmp_item);
					tmp_item = tmp_item.parentNode;
				} // 共通の祖先は含まない(pushしない)
				
				if(activity_path_to_common_ancestor.length>0){ // 7.1.1.3. アクティビティパスが空でない



					// 7.1.1.3.1. アクティビティパスの各アクティビティ
					for(var ap=0;ap<activity_path_to_common_ancestor.length;ap++){
						// 7.1.1.3.1.1. アクティビティのActivity is ActiveがTrue And 
						// アクティビティのシーケンシングコントロールChoiceExitがFalse
						if(activity_is_active[id(activity_path_to_common_ancestor[ap])]==true && My_Control_Mode(activity_path_to_common_ancestor[ap],"choiceExit")==false){
							// 7.1.1.3.1.1.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
							// 終了要求はn/a, ターゲットアクティビティはn/a
							return new struct_navigation("Not Valid","","","");
						}
					}
				} // 7.1.1.4.
				
				if(activity_is_active[id(current_activity)]==true){ // 7.1.1.4.1. Current ActivityのActivity is ActiveがTrue
					// 7.1.1.4.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はChoice,
					// 終了要求はExit, ターゲットアクティビティはChoiceナビゲーション要求で指定されたアクティビティ
					return new struct_navigation("Valid","choice","exit",item);
				} else { // 7.1.1.4.2.
					// 7.1.1.4.2.1. Exit ナビゲーション要求はValid, シーケンシング要求はChoice,
					// 終了要求はn/a, ターゲットアクティビティはChoiceナビゲーション要求で指定されたアクティビティ
					return new struct_navigation("Valid","choice","",item);
				}
			} else { // 7.1.2. 
				// 7.1.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
				// 終了要求はn/a, ターゲットアクティビティはn/a
				return new struct_navigation("Not Valid","","","");
			}
		} else { // 7.2.
			// 7.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "exit": // 8. ナビげーション要求がExit
		if(current_activity!=undefined && current_activity!=null){ // 8.1. Current Activityが定義されている
			if(activity_is_active[id(current_activity)]==true){ // 8.1.1. Current ActivityのActivity is ActiveがTrue
				// 8.1.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はExit,
				// 終了要求はExit, ターゲットアクティビティはn/a
				return new struct_navigation("Valid","exit","exit","");
			} else { // 8.1.2.
				// 8.1.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
				// 終了要求はn/a, ターゲットアクティビティはn/a
				return new struct_navigation("Not Valid","","","");
			}
		} else { // 8.2.
			// 8.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "exitAll": // 9. ナビげーション要求がExit All
		if(current_activity!=undefined && current_activity!=null){ // 9.1. Current Activityが定義されている
			// 9.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はExit,
			// 終了要求はExit All, ターゲットアクティビティはn/a
			return new struct_navigation("Valid","exit","exitAll","");
		} else { // 9.2.
			// 9.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "abandon": // 10. ナビげーション要求がAbandon
		if(current_activity!=undefined && current_activity!=null){ // 10.1. Current Activityが定義されている
			if(activity_is_active[id(current_activity)]==true){ // 10.1.1. Current ActivityのActivity is ActiveがTrue
				// 10.1.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はExit,
				// 終了要求はAbandon, ターゲットアクティビティはn/a
				return new struct_navigation("Valid","exit","abandon","");
			} else { // 10.1.2.
				// 10.1.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
				// 終了要求はn/a, ターゲットアクティビティはn/a
				return new struct_navigation("Not Valid","","","");
			}
		} else { // 10.2.
			// 10.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "abandonAll": // 11. ナビげーション要求がAbandon All
		if(current_activity!=undefined && current_activity!=null){ // 11.1. Current Activityが定義されている
			// 11.1.1. Exit ナビゲーション要求はValid, シーケンシング要求はExit,
			// 終了要求はAbandon All, ターゲットアクティビティはn/a
			return new struct_navigation("Valid","exit","abandonAll","");
		} else { // 11.2.
			// 11.2.1. Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	case "suspendAll": // 12. ナビげーション要求がSuspend All
		if(current_activity!=undefined && current_activity!=null){ // 12.1. Current Activityが定義されている
			// 12.1.1 Exit ナビゲーション要求はValid, シーケンシング要求はExit,
			// 終了要求はSuspend All, ターゲットアクティビティはn/a
			return new struct_navigation("Valid","exit","suspendAll","");
		} else {// 12.2.
			// 12.2.1 Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
			// 終了要求はn/a, ターゲットアクティビティはn/a
			return new struct_navigation("Not Valid","","","");
		}
		break;
	}
	
	// Exit ナビゲーション要求はNot Valid, シーケンシング要求はn/a,
	// 終了要求はn/a, ターゲットアクティビティはn/a
	return new struct_navigation("Not Valid","","","");
}

function Termination_Request_Process(termination_request){ // 終了プロセスはpostConditionで使う

	// p58-61 終了要求に対しCurrent Activityの現在の試行を終了し終了要求の有効性を返却し、

	// 場合によりシーケンシング要求を返却する
	// 値の返却にはstruct_termination(termination,sequencing)を使う

	if(current_activity==undefined || current_activity==null){ // 1. Current Activityが未定義
		return new struct_termination("Not Valid",""); // 1.1. Exit,終了要求はNot Valid,シーケンシング要求はn/a
	}
	
	if(activity_is_active[id(current_activity)]==false){ // 2. Current ActivityのActivity is ActiveがFalse
		return new struct_termination("Not Valid",""); // 2.1. Exit,終了要求はNot Valid,シーケンシング要求はn/a
	}
	
	if(termination_request=="exit"){ // 3. 終了要求がExit
		// 3.1. Current Activityに試行終了プロセスを適用
		End_Attempt_Process(current_activity);
		
		// 3.2. Current Activityにオーバーオールロールアッププロセスを適用
		Overall_Rollup_Process(current_activity);
		
		// 3.3. Current Activityに終了アクションルールシーケンシングサブプロセスを適用
		Exit_Action_Rule_Sequencing_Subprocess(current_activity);
		
		var post="";
		do{ // 3.4. Repeat
			var termination_done=false;// 3.4.1. 終了処理済をFalseに設定

			// 3.4.2. Current Activityがアクティビティツリーのルートでは無い

			if(current_activity.nodeName!="organization"){
				// 3.4.2.1. Current Activityに事後条件ルールシーケンシングサブプロセスを適用する
				post=Post_Condition_Rule_Sequencing_Subprocess();
				// 3.4.2.2. 事後条件ルールシーケンシングサブプロセスがExit All終了要求を返す
				if(post.termination=="exitAll"){
					termination_request="exitAll";// 3.4.2.2.1. 終了要求をExit Allに変更
					break; // 3.4.2.2.2. Break 次のCaseへ
				}
				
				// 3.4.2.3. 事後条件ルールシーケンシングサブプロセスがExit Parent終了要求を返す
				if(post.termination=="exitParent"){
					// 3.4.2.3.1. Current ActivityをCurrent Activityの親に設定

					current_activity=current_activity.parentNode;
					// 3.4.2.3.2. 試行終了プロセスをCurrent Activityに適用
					End_Attempt_Process(current_activity);
					// 3.4.2.3.3. 終了処理済をTrueに設定

					termination_done=true;
				}
			}
		}while(!(termination_done==false)); // 3.5. Until 終了処理済がFalse
		
		if(termination_request!="exitAll"){
			// 3.6. Exit,終了要求はValid,シーケンシング要求はもし存在すれば
			// 事後条件ルールシーケンシングサブプロセスの返却値、さもなければn/a
			if(post.sequencing!=undefined && post.sequencing!=null){
				return new struct_termination("Valid",post.sequencing);
			} else {
				return new struct_termination("Valid","");
			}
		}
	}
	
    // 4. 終了要求がExit All(直前の3.でExit Allに変更される場合があるため、else ifにはしない

	if(termination_request=="exitAll"){
		if(activity_is_active[id(current_activity)]==true){ // 4.1. Current ActivityのActivity is ActiveがTrue
			// 4.1.1. Current Activityに試行終了プロセスを適用
			End_Attempt_Process(current_activity);
			// 4.1.2. Current Activityにオーバーオールロールアッププロセスを適用
			Overall_Rollup_Process(current_activity);
		}
		
		// 4.2. 下位試行終了プロセスをアクティビティツリーのルートに適用
		Terminate_Descendent_Attempts_Process(manifest.getElementsByTagName("organization")[0]);	
		// 4.3. アクティビティツリーのルートに試行終了プロセスを適用
		End_Attempt_Process(manifest.getElementsByTagName("organization")[0]);	
		// 4.4. Current Activityをアクティビティツリーのルートに設定



		current_activity=manifest.getElementsByTagName("organization")[0];
		// 4.5. Exit,終了要求はValid,シーケンシング要求はもし存在すれば
		// 事後条件ルールシーケンシングサブプロセスの返却値、さもなければExitシーケンシング要求



		var post=Post_Condition_Rule_Sequencing_Subprocess();
		
		if(post.sequencing!=""){
			return new struct_termination("Valid",post.sequencing);
		} else {
			return new struct_termination("Valid","exit");
		}
	} else if(termination_request=="suspendAll"){ // 5. 終了要求がSuspend All
		if(activity_is_active[id(current_activity)]==true){ // 5.1. Current ActivityのActivity is ActiveがTrue
			suspended_activity=current_activity; // 5.1.1. Suspended ActivityをCurrent Activityに設定



		} else { // 5.2.
			// 5.2.1. Current ActivityのActivity is SuspendedがFalse
			if(activity_is_suspended[id(current_activity)]==false){
				// 5.2.1.1. Current Activityアクティビティツリーのルートではない



				if(current_activity.nodeName!="organization"){
					// 5.2.1.1.1. Suspended ActivityをCurrent Activityの親に設定



					suspended_activity=current_activity.parentNode;
				} else { // 5.2.1.2.
					// 5.2.1.2.1. Exit,終了要求はNot Valid,シーケンシング要求はn/a
					return new struct_termination("Not Valid","");
				}
			}
		}
		
		// 5.3. Suspended Activityからアクティビティツリーのルートまで、両端のアクティビティを含む
		// 順序付き系列のアクティビティパスを作る
		var activity_path_to_root = new Array();
		tmp_item = suspended_activity;
		
		while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
			activity_path_to_root.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		
		if(activity_path_to_root.length==0){ // 5.4. アクティビティパスが空
			return new struct_termination("Not Valid",""); // 5.4.1. Exit,終了要求はNot Valid,シーケンシング要求はn/a
		}
		
		for(var ap=0;ap<activity_path_to_root.length;ap++){ // 5.5. アクティビティパスの各アクティビティ
			// 5.5.1. アクティビティのActivity is ActiveをFalseに設定



			activity_is_active[id(activity_path_to_root[ap])]=false;
			// 5.5.2. アクティビティのActivity is SuspendedをTrueに設定



			activity_is_suspended[id(activity_path_to_root[ap])]=true;
		}
		
		// 5.6. Current Activityをアクティビティツリーのルートに設定



		current_activity=manifest.getElementsByTagName("organization")[0];	
		
		// JSONデータ送信
		var json_str=makeJSON(make_suspend_vals());
		suspend_resume_data(onload_suspend,'&data='+json_str+'&courseID='+resumeCourseID+'&id='+resumeID,'POST', suspend_program ,true);
		return new struct_termination("Valid","exit"); // 5.7. Exit,終了要求はValid, シーケンシング要求はExit
	} else if(termination_request=="abandon"){ // 6. 終了要求がAbandon
		// 6.1. Current ActivityのActivity is ActiveをFalseに設定



		activity_is_active[id(current_activity)]=false;
		return new struct_termination("Valid",""); // 6.2. Exit,終了要求はValid,シーケンシング要求はn/a
	} else if(termination_request=="abandonAll"){ // 7. 終了要求がAbandon All
		// 7.1. Current Activityからアクティビティツリーのルートまで、両端のアクティビティを含む
		// 順序付き系列のアクティビティパスを作る
		var activity_path_to_root = new Array();
		tmp_item = current_activity;
		
		while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
			activity_path_to_root.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		
		if(activity_path_to_root.length==0){ // 7.2. アクティビティパスが空
			return new struct_termination("Not Valid",""); // 7.2.1. Exit,終了要求はNot Valid,シーケンシング要求はn/a
		}
		
		for(var ap=0;ap<activity_path_to_root.length;ap++){ // 7.3. アクティビティパスの各アクティビティ
			// 7.3.1. アクティビティのActivity is ActiveをFalseに設定



			activity_is_active[id(activity_path_to_root[ap])]=false;
		}
		
		// 7.4. Current Activityをアクティビティツリーのルートに設定



		current_activity=manifest.getElementsByTagName("organization")[0];
		return new struct_termination("Valid","exit"); // 7.5. Exit,終了要求はValid,シーケンシング要求はExit
	}
	return new struct_termination("Not Valid",""); // 8. Exit,終了要求はNot Valid,シーケンシング要求はn/a
}

function Measure_Rollup_Process(item){ // 習得度ロールアッププロセス
	// p63-65 アクティビティに対して、アクティビティのObjective Informationを変更する場合がある
	var weighted_measure_sum=0; // 1. 重み付き習得度総和を0.0に設定



	var measure_for_calculation=0; // 2. 計算対象習得度を0.0に設定



	var target_objective=undefined; // 3. ターゲット学習目標を未定義に設定



	var target_objective=item_primary_objectives[id(item)]; // primaryObjectiveがターゲット学習目標



	
	if(target_objective!=undefined && target_objective!=null){ // 5. ターゲット学習目標が定義されている
		var item_children=Available_Children(item);
		for(var ic=0;ic<item_children.length;ic++){ // 5.1. 各子アクティビティ
			if(tracked[id(item_children[ic])]==true){ // 5.1.1. 子アクティビティのTrackedがTrue
				var rollup_objective=undefined; // 5.1.1.1. ロールアップ学習目標を未定義に設定



				// primaryObjectiveがロールアップ学習目標



				rollup_objective=item_primary_objectives[id(item_children[ic])];
				// 5.1.1.3. ロールアップ学習目標が定義されている
				if(rollup_objective!=undefined && rollup_objective!=null){
					// 5.1.1.3.1. ロールアップ学習目標のObjective Measure StatusがTrue
					if(objective_measure_status[id(item_children[ic])][obj_id(rollup_objective)]==true){
						// 5.1.1.3.1.1. 子アクティビティのRollup Objective Measure Weightが非負
						if(rollup_objective_measure_weight[id(item_children[ic])]>=0){
							// 5.1.1.3.1.1.1. 計算対象習得度を子のRollup Objective Measure Weightだけ増加
							measure_for_calculation += rollup_objective_measure_weight[id(item_children[ic])];
							// 5.1.1.3.1.1.2. ロールアップ学習目標のObjective Normalized Measureと
							// 子アクティビティのRollup Objective Measure Weightの積を重み付き習得度総和に加える
							weighted_measure_sum = 
							objective_normalized_measure[id(item_children[ic])][obj_id(rollup_objective)] // Objective Normalized Measureと
							* rollup_objective_measure_weight[id(item_children[ic])] // Rollup Objective Measure Weightの積を
							+ weighted_measure_sum; // 重み付き習得度総和に加える
						}
					} else { // 5.1.1.3.2. Else
						// 5.1.1.3.2.1. 計算対象習得度を0.0に設定



						// 子に習得度が設定されていない;不完全なトラッキング状態



						measure_for_calculation = 0;
						break; // 5.1.1.3.2.2. Break For
					}
				} else { // 5.1.1.4. Else
					return; // 5.1.1.4.1. ロールアップ学習目標をもたない子アクティビティがある



				}
			}
		}
		
		if(measure_for_calculation == 0 && item_children.length > 0){ // 5.2. 計算対象習得度が0.0
			// 5.2.1. ターゲット学習目標のObjective Measure StatusをFalseに設定



			// トラッキング状態ロールアップが無いか不完全、ロールアップ習得度を決定できない



			// これ↓は必要か? 葉だったら必要ないのでは?
			objective_measure_status[id(item)][obj_id(target_objective)]=false;
			return; // 5.2.2. Exit
		}
		
		if(measure_for_calculation > 0){ // 5.3. 計算対象習得度が0.0より大きい
			// 5.3.1. ターゲット学習目標のObjective Measure StatusをTrueに設定



			objective_measure_status[id(item)][obj_id(target_objective)]=true;
			// 5.3.2. ターゲット学習目標のObjective Normalized Measureを



			// 「重み付き習得度総和を計算対象習得度で割った値」に設定



			objective_normalized_measure[id(item)][obj_id(target_objective)]=weighted_measure_sum/measure_for_calculation;
			return; // 5.3.3. Exit
		}
	}
	return; // 6. Exit
}

function Objective_Measure_Rollup_Process(item){ // 学習目標習得度ロールアッププロセス
	// p66 アクティビティに対して、アクティビティのObjective Informationを変更する場合がある
	
	// 1. ターゲット学習目標を未定義に設定



	var target_objective=item_primary_objectives[id(item)]; // primaryObjectiveがターゲット学習目標



	if(target_objective!=undefined && target_objective!=null){ // 3. ターゲット学習目標が定義されている
		// 3.1. ターゲット学習目標のObjective Satisfied by MeasureがTrue
		if(target_objective.getAttribute("satisfiedByMeasure")=="true"){ // 文字列のtrueであることに注意



			// 3.1.1. ターゲット学習目標のObjective Measure StatusがFalse
			if(objective_measure_status[id(item)][obj_id(target_objective)]==false){
				// 3.1.1.1. ターゲット学習目標のObjective Progress StatusをFalseに設定



				objective_progress_status[id(item)][obj_id(target_objective)] = false;
			} else { // 3.1.2.
				// 3.1.2.1. ターゲット学習目標のObjective Normalized Mesureがターゲット学習目標の
				// Objective Minimum Normalized Measureに等しいか大きい
				var min_nm=My_getElementsByTagName(target_objective,"imsss:minNormalizedMeasure")[0];
				var min_nm_val;
				if(min_nm!=undefined && min_nm !=null){
					min_nm_val=min_nm.childNodes[0].nodeValue-0;
				} else {
					min_nm_val=1;
				}
				
				if(objective_normalized_measure[id(item)][obj_id(target_objective)] >= min_nm_val){
					// 3.1.2.1.1. ターゲット学習目標のObjective Progress StatusをTrueに設定



					objective_progress_status[id(item)][obj_id(target_objective)] = true;
					// 3.1.2.1.2. ターゲット学習目標のObjective Satisfied StatusをTrueに設定


					objective_satisfied_status[id(item)][obj_id(target_objective)] = true;
				} else { // 3.1.2.2. 
					// 3.1.2.2.1. ターゲット学習目標のObjective Progress StatusをTrueに設定



					objective_progress_status[id(item)][obj_id(target_objective)] = true;
					// 3.1.2.2.2. ターゲット学習目標のObjective Satisfied StatusをFalseに設定


					objective_satisfied_status[id(item)][obj_id(target_objective)] = false;
				}
			}
		}
		return; // 3.2. Exit 学習目標習得度ロールアッププロセス
	} else { // 4.
		return; // 4.1. Exit 学習目標習得度ロールアッププロセス
	}
}

function Objective_Default_Rule_Rollup_Process(item){ // デフォルトルールでの学習目標ルールロールアッププロセス
	// 注! オリジナル関数です

	
	var target_objective=item_primary_objectives[id(item)]; // primaryObjectiveがターゲット学習目標

	if(target_objective!=undefined && target_objective!=null){ // ターゲット学習目標が定義されている
		var item_children=Available_Children(item);	
		// Not Satisfiedルールの評価を開始

		var not_satisfied_num=0; // Not Satisfied(又はAttempted)となる子アクティビティの数
		var related_children_num=0; // ロールアップに関与する子アクティビティの数
		for(var ic=0;ic<item_children.length;ic++){ // アクティビティの各子アクティビティ
			if(tracked[id(item_children[ic])]==true){ // 子のTrackedがTrue
				if(Rollup_Child_Check_Subprocess(item_children[ic],"notSatisfied")==true){ 
					related_children_num=related_children_num+1; 
					// primaryObjectiveがターゲット学習目標

					var ic_target_objective=item_primary_objectives[id(item_children[ic])]; 
					// 子アクティビティがattemptedまたは未習得かどうか
					if((objective_progress_status[id(item)][obj_id(ic_target_objective)]==true && objective_satisfied_status[id(item)][obj_id(ic_target_objective)]==false) || (attempt_progress_status[id(item_children[ic])]==true && activity_attempt_count[id(item_children[ic])]>0)){
						not_satisfied_num=not_satisfied_num+1;
					}
				}
			}
		}
		
		if(not_satisfied_num==related_children_num && not_satisfied_num>0){ // If all (attempted or not satisfied)
			// ターゲット学習目標のObjective Satisfied StatusをFalseに設定

			objective_progress_status[id(item)][obj_id(target_objective)] = true;
			objective_satisfied_status[id(item)][obj_id(target_objective)] = false;
		}
		// Not Satisfiedルールの評価終了


		// Satisfiedルールの評価開始

		var satisfied_num=0; // Satisfiedとなる子アクティビティの数
		related_children_num=0; // ロールアップに関与する子アクティビティの数
		for(var ic=0;ic<item_children.length;ic++){ // アクティビティの各子アクティビティ
			if(tracked[id(item_children[ic])]==true){ // 子のTrackedがTrue
				if(Rollup_Child_Check_Subprocess(item_children[ic],"satisfied")==true){
					related_children_num=related_children_num+1; 
					// primaryObjectiveがターゲット学習目標



					var ic_target_objective=item_primary_objectives[id(item_children[ic])]; 
					// 子アクティビティが習得かどうかを見る
					if(objective_progress_status[id(item)][obj_id(ic_target_objective)]==true && objective_satisfied_status[id(item)][obj_id(ic_target_objective)]==true){
						satisfied_num=satisfied_num+1;
					}
				}
			}
		}
		
		if(satisfied_num==related_children_num && satisfied_num>0){ // If all satisfied
			// ターゲット学習目標のObjective Satisfied StatusをTrueに設定

			objective_progress_status[id(item)][obj_id(target_objective)] = true;
			objective_satisfied_status[id(item)][obj_id(target_objective)] = true;
		}
	}
}

function Objective_Rule_Rollup_Process(item){ // 学習目標ルールロールアッププロセス
	// p67 アクティビティに対して、アクティビティのObjective Informationを変更する場合がある
	
	// 1. ターゲット学習目標を未定義に設定



	var children=item.childNodes;
	var seq; // "imsss:sequencing"
	for(var c=0;c<children.length;c++){
		if(children[c].nodeName=="imsss:sequencing"){
			seq=children[c];
			break;
		}
	}
	
	var target_objective=item_primary_objectives[id(item)]; // primaryObjectiveが主学習目標



	if(target_objective!=undefined && target_objective!=null){ // 3. ターゲット学習目標が定義されている
		// 3.1. ロールアップルールチェックサブプロセスをアクティビティの
		// Not Satisfiedロールアップアクションに対して適用
		// 3.2. ロールアップルールチェックサブプロセスがTrueを返す
		if(Rollup_Rule_Check_Subprocess(item,"notSatisfied")==true){
			// 3.2.1. ターゲット学習目標のObjective Progress StatusをTrueに設定



			objective_progress_status[id(item)][obj_id(target_objective)] = true;
			// 3.2.2. ターゲット学習目標のObjective Satisfied StatusをFalseに設定


			objective_satisfied_status[id(item)][obj_id(target_objective)] = false;
		}
		
		// 3.3. ロールアップルールチェックサブプロセスをアクティビティの
		// Satisfiedロールアップアクションに対して適用
		// 3.4. ロールアップルールチェックサブプロセスがTrueを返す
		if(Rollup_Rule_Check_Subprocess(item,"satisfied")==true){
			// 3.4.1. ターゲット学習目標のObjective Progress StatusをTrueに設定



			objective_progress_status[id(item)][obj_id(target_objective)] = true;
			// 3.4.2. ターゲット学習目標のObjective Satisfied StatusをTrueに設定


			objective_satisfied_status[id(item)][obj_id(target_objective)] = true;
		}
		return; // 3.5. Exit
	} else { // 4.
		return; // 4.1. Exit
	}
}

function Activity_Default_Progress_Rollup_Process(item){// デフォルトルールでの進捗状態ロールアッププロセス
	// 注! オリジナル関数です

	var item_children=Available_Children(item);	
	var incomplete_num=0; // Incompleteとなる子アクティビティの数
	var related_children_num=0; // ロールアップに関与する子アクティビティの数
	for(var ic=0;ic<item_children.length;ic++){ // アクティビティの各子アクティビティ
		if(tracked[id(item_children[ic])]==true){ // 子のTrackedがTrue
			if(Rollup_Child_Check_Subprocess(item_children[ic],"incomplete")==true){
				related_children_num=related_children_num+1;
				// attemptedまたは未完了

				if(attempt_progress_status[id(item_children[ic])]==true && (activity_attempt_count[id(item_children[ic])]>0 || attempt_completion_status[id(item_children[ic])]==false)){
					incomplete_num=incomplete_num+1;
				}
			}
		}
	}
	
	if(incomplete_num == related_children_num && incomplete_num > 0 ){ // If all (attempted or incomplete)
		// 親アクティビティは未完了

		attempt_progress_status[id(item)]=true;
		attempt_completion_status[id(item)]=false;	
	}
	// Incompleteルールの評価終了


	// Completeルールの評価開始

	var complete_num=0; // Completeとなる子アクティビティの数
	related_children_num=0; // ロールアップに関与する子アクティビティの数
	for(var ic=0;ic<item_children.length;ic++){ // アクティビティの各子アクティビティ
		if(tracked[id(item_children[ic])]==true){ // 子のTrackedがTrue
			if(Rollup_Child_Check_Subprocess(item_children[ic],"completed")==true){
				related_children_num=related_children_num+1;
				// 完了

				if(attempt_progress_status[id(item_children[ic])]==true && attempt_completion_status[id(item_children[ic])]==true){
					complete_num=complete_num+1;
				}
			}
		}
	}
	
	if(complete_num == related_children_num && complete_num > 0){ // If all (attempted or incomplete)
		// 親アクティビティは未完了

		attempt_progress_status[id(item)]=true;
		attempt_completion_status[id(item)]=true;
	}
	return;
}

function Activity_Progress_Rollup_Process(item){ // アクティビティ進捗ロールアッププロセス
	// p68 アクティビティに対して、アクティビティのAttempt Informationを変更する場合がある
	
	// 1. アクティビティとIncompleteロールアップアクションに対して
	// ロールアップルールチェックサブプロセスを適用
	// 2. ロールアップルールチェックサブプロセスがTrueを返す
	if(Rollup_Rule_Check_Subprocess(item,"incomplete")==true){
		attempt_progress_status[id(item)]=true; // 2.1. アクティビティのAttempt Progress StatusをTrueに設定

		attempt_completion_status[id(item)]=false; // 2.2. アクティビティのAttempt Completion StatusをFalseに設定

	}
	
	// 3. アクティビティとCompletedロールアップアクションに対して
	// ロールアップルールチェックサブプロセスを適用
	// 4. ロールアップルールチェックサブプロセスがTrueを返す
	if(Rollup_Rule_Check_Subprocess(item,"completed")==true){
		attempt_progress_status[id(item)]=true; // 4.1. アクティビティのAttempt Progress StatusをTrueに設定

		attempt_completion_status[id(item)]=true; // 4.2. アクティビティのAttempt Completion StatusをTrueに設定

	}
	return; // 5. Exit
}

function Rollup_Rule_Check_Subprocess(item,action){ // ロールアップルールチェックサブプロセス
	// p69-70 アクティビティとロールアップアクションに対して、アクションが適用される場合Trueを返す
	// アクションはsatisfied, notSatisfied, completed, incompleteのいずれかが入る

	var children=item.childNodes;
	var seq; // "imsss:sequencing"
	for(var c=0;c<children.length;c++){
		if(children[c].nodeName=="imsss:sequencing"){
			seq=children[c];
			break;
		}
	}
	var actions=My_getElementsByTagName(seq,'imsss:rollupAction');
	var ac_num=0; // 指定されたアクションを持つロールアップルールの数
	var rules=new Array(); // 指定されたアクションを持つロールアップルールを入れておく配列
	for(var ac=0;ac<actions.length;ac++){
		if(actions[ac].getAttribute("action")==action){
			ac_num++;
			rules.push(actions[ac].parentNode); // 番外編(0)
		}
	}
	
	if(ac_num>0){ // 1. アクティビティが指定されたロールアップアクションのRollup Rulesを持つ
		// 1.1. 指定されたロールアップアクションを持つアクティビティのRollup Rulesを選び、



		// ルールの順番を保って、ルールリストを初期化



		// → 実は番外編(0)でrules配列として初期化済



		for(var rule=0;rule<rules.length;rule++){ // 1.2. リスト中の各ルール
			var related_children=new Array(); // 1.2.1. 関与する子の集合を空集合に初期化



			var item_children=Available_Children(item);
			for(var ic=0;ic<item_children.length;ic++){ // 1.2.2. アクティビティの各子アクティビティ
				if(tracked[id(item_children[ic])]==true){ // 1.2.2.1. 子のTrackedがTrue
					// 1.2.2.2.1. 子とロールアップアクションに対してロールアップ子チェックサブプロセスを適用
					// 1.2.2.2.2. ロールアップ子チェックサブプロセスがTrueを返す
					if(Rollup_Child_Check_Subprocess(item_children[ic],action)==true){
						// 1.2.2.2.2.1. 子とルールのRollup Conditionsに対して
						// ロールアップ条件評価サブプロセスを適用
						// 1.2.2.2.2.2. ロールアップ条件評価サブプロセスがTrueを返す
						if(Rollup_Condition_Evaluate_Subprocess(item_children[ic],rules[rule])==true){
							// 1.2.2.2.2.2.1. 関与する子の集合にTrueを追加
							related_children.push(true);
						} else { // 1.2.2.2.2.3.
							// 1.2.2.2.2.3.1.関与する子の集合にFalseを追加
							related_children.push(false);
						}
					}
				}
			}
			
			var state_change=false;    // 1.2.3. 状態変更をFalseに変更
			var cas=rules[rule].getAttribute("childActivitySet"); // Rollup Child Activity Setの値を見ておく
			if(cas==undefined||cas==null){
				cas="all";
			}
			
			// 関与する子の集合の中のtrue,falseの数を数えておく
			var rc_true=0; var rc_false=0;
			for(var rc=0;rc<related_children.length;rc++){
				if(related_children[rc]==true){
					rc_true++;
				} else if(related_children[rc]==false){
					rc_false++;
				}
			}
			
			if(cas=="all"){ // 1.2.4. Rollup Child Activity SetがAll
				if(rc_false==0){ // 1.2.4.1. 関与する子の集合がFalseを含まない



					state_change=true; // 状態変更をTrueに変更 1.2.4.1.1.
				}
			} else if(cas=="any"){ // 1.2.5. Rollup Child Activity SetがAny
				if(rc_true>0){ // 1.2.5.1. 関与する子の集合がTrueを含む
					state_change=true; // 状態変更をTrueに変更 1.2.5.1.1.
				}
			} else if(cas=="none"){ // 1.2.6. Rollup Child Activity SetがNone
				if(rc_true==0){ // 1.2.6.1. 関与する子の集合がTrueを含まない



					state_change=true; // 状態変更をTrueに変更 1.2.6.1.1.
				}
			} else if(cas=="atLeastCount"){ // 1.2.7. Rollup Child Activity SetがAt Least Count
				var mmc=rules[rule].getAttribute("minimumCount");
				if(mmc==undefined || mmc==null){
					mmc=0;
				}
				// 1.2.7.1. 関与する子の集合中のTrueの個数がルールのRollup Minimum Countと等しいか大きい
				if(rc_true>=mmc){
					state_change=true; // 状態変更をTrueに変更 1.2.7.1.1.
				}
			} else if(cas=="atLeastPercent"){ // 1.2.8. Rollup Child Activity SetがAt Least Percent
				var mmp=rules[rule].getAttribute("minimumPercent");
				if(mmp==undefined || mmp==null){
					mmp=0;
				}
				
				if(rc_true/related_children.length >= mmp){ // 1.2.8.1. 関与する子の集合中のTrueの個数の(0と1の間に正規化された)割合がルールのRollup Minimum Percentと等しいか大きい
					state_change=true; // 状態変更をTrueに変更 1.2.8.1.1.
				}
			}
			
			if(state_change==true){ // 1.2.9. 状態変更がTrue
				return true; // 1.2.9.1. 真と評価された最初のルールで停止 - 関連するアクションを実行



			}
		}
	}
	return false; // 2. 真と評価されるルールがない - アクションを実行しない



}

function Rollup_Condition_Evaluate_Subprocess(item, rule){ // ロールアップ条件評価サブプロセス
	// p71 アクティビティとロールアップ条件集合に対して、条件が真と評価されればTrueを返す
	// ruleは"rollupRule"
	
	// 1. ロールアップ条件集合を空集合に初期化



	var rollupsArray = new Array();
	var rollupCondition_array = My_getElementsByTagName(rule,'imsss:rollupCondition'); // 1つ以上返る
	for(var i=0;i<rollupCondition_array.length;i++){ // 2. ロールアップ条件集合中の各Rollup Condition
		// 2.1. アクティビティの適切なトラッキング情報をRollup Conditionに適用してロールアップ条件を評価
		// conditionに入りうるのはsatisfied,objectiveStatusKnown,objectiveMeasureKnown,completed,
		// attempted, attemptLimitExceeded, timeLimitExceededのいずれか
		var eval_result=false; // 評価結果
		var condition = rollupCondition_array[i].getAttribute("condition"); // 必須



		var con_target_objective=My_Rollup_Objective(item);
		if(con_target_objective!=undefined){
			if(condition=="satisfied"){
				if(objective_progress_status[id(item)][obj_id(con_target_objective)]==true && objective_satisfied_status[id(item)][obj_id(con_target_objective)]==true){
					eval_result=true;
				}
			} else if(condition=="objectiveStatusKnown"){
				if(objective_progress_status[id(item)][obj_id(con_target_objective)]==true){
					eval_result=true;
				}
			} else if(condition=="objectiveMeasureKnown"){
				if(objective_measure_status[id(item)][obj_id(con_target_objective)]==true){
					eval_result=true;
				}
			} else if(condition=="completed"){
				if(attempt_progress_status[id(item)]==true && attempt_completion_status[id(item)]==true){
					eval_result=true;
				}
			} else if(condition=="activityProgressKnown"){
				if(attempt_progress_status[id(item)]==true && attempt_progress_status[id(item)]==true){
					eval_result=true;
				}
			} else if(condition=="attempted"){
				if(objective_progress_status[id(item)][obj_id(item)]==true && activity_attempt_count[id(item_children[ic])]>0){
					eval_result=true;
				}
			} else if(condition=="attemptLimitExceeded"){
				// 保留
			} else if(condition=="timeLimitExceeded"){
				// 保留
			} else if(condition=="outsideAvailableTimeRange"){
				// 保留
			}
		}
		
		// 2.2. Rollup Condition のRollup Condition OperatorがNot
		if(rollupCondition_array[i].getAttribute("operator")=="not"){
			eval_result=!(eval_result);	// 2.2.1. ロールアップ条件を否定



		}	
		// 2.3. ロールアップ条件の値をロールアップ条件集合に追加
		rollupsArray.push(eval_result);
	}
	
	if(rollupsArray.length==0){ // 3. ロールアップ条件集合が空
		return false; // 3.1.
	}
	
	// 4. Condition Combinationをロールアップ条件集合に適用し単一のルール結合評価を生成



	var rollupConditions = My_getElementsByTagName(rule,'imsss:rollupConditions')[0];
	var conditionCombination = rollupConditions.getAttribute("conditionCombination");
	var rules_true=0; // 条件を満たしたルールの数
	for(var r=0;r<rollupsArray.length;r++){
		rules_true += rollupsArray[r];
	}
	if(conditionCombination == "all"){ // And演算



		if(rules_true == rollupsArray.length){
			return true;
		} else {
			return false;
		}
	} else { // Anyか空の時、Or演算



		if(rules_true > 0){
			return true; // 一つでも満たしていたらtrue
		} else {
			return false;// 全部ダメならfalse
		}
	}
}

function Rollup_Child_Check_Subprocess(item,action){ // ロールアップ子チェックサブプロセス
	// p72 アクティビティとロールアップアクションに対して、アクティビティがロールアップに含まれればTrueを返す
	if(action=="satisfied"||action=="notSatisfied"){ // 1. ロールアップアクションがSatisfiedかNot Satisfied
		// 1.1. Exit, 「子をロールアップに含める」はアクティビティのRollup Objective Satisfiedの値
		return rollup_objective_satisfied[id(item)];
	}
	if(action=="completed"||action=="incomplete"){ // 2. ロールアップアクションがCompleteかIncomplete
		// 2.1. Exit, 「子をロールアップに含める」はアクティビティのRollup Progress Completionの値
		return rollup_progress_completion[id(item)];
	}
	return false; // 3. Exit, 「子をロールアップに含める」はFalse
}

function Overall_Rollup_Process(item){ // オーバーオールロールアッププロセス
	// p73 アクティビティに対して、アクティビティとその祖先のトラッキング情報を変更する場合がある
	// 1. アクティビティツリーのルートからアクティビティまで、両端のアクティビティを含む、

	// 逆順に順序付き系列のアクティビティパスを作る
	var activity_path_to_root = new Array();
	tmp_item = item;
	while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
		activity_path_to_root.push(tmp_item);
		tmp_item = tmp_item.parentNode;
	}
	if(activity_path_to_root.length==0){ // 2. アクティビティパスが空
		return; // 2.1. Exit
	}
	for(var ap=0;ap<activity_path_to_root.length;ap++){ // 3. アクティビティパスの各アクティビティ
		// 3.1. アクティビティに対して習得度ロールアッププロセスを適用
		// アクティビティの習得度をロールアップ
		Measure_Rollup_Process(activity_path_to_root[ap]);
		// 3.2. アクティビティに対して適切な学習目標ロールアッププロセスを適用
		// アクティビティに定義されたシーケンシング情報に応じてRB.1.2に記述された適切な動作を適用
		Objective_Measure_Rollup_Process(activity_path_to_root[ap]);
		// これより番外編(ロールアップアクションを見る)
		var children=activity_path_to_root[ap].childNodes;
		var seq; // "imsss:sequencing"
		for(var c=0;c<children.length;c++){
			if(children[c].nodeName=="imsss:sequencing"){
				seq=children[c];
				break;
			}
		}
		var actions=My_getElementsByTagName(seq,'imsss:rollupAction');    
		var ac_num=0; // 指定されたアクションを持つロールアップルールの数
		if(actions!=undefined && actions!=null){
			for(var ac=0;ac<actions.length;ac++){
				if(actions[ac].getAttribute("action")=="satisfied" || actions[ac].getAttribute("action")=="notSatisfied"){
					ac_num++;
				}
			}
		}
		// 番外編ここまで	
		if(ac_num>0){ // 親アクティビティにSatisfiedかNot Satisfiedのルールが一つでも設定されている
			Objective_Rule_Rollup_Process(activity_path_to_root[ap]); // ロールアップルールによる決定

		} else {
			Objective_Default_Rule_Rollup_Process(activity_path_to_root[ap]); // デフォルトルール
		}
		
		// 3.3. アクティビティに対して適切なアクティビティ進捗ロールアッププロセスを適用
		// アクティビティに定義されたシーケンシング情報に応じてRB.1.3に記述された適切な動作を適用
		// これより番外編
		ac_num=0;
		if(actions!=undefined && actions!=null){
			for(var ac=0;ac<actions.length;ac++){
				if(actions[ac].getAttribute("action")=="completed" || actions[ac].getAttribute("action")=="incomplete"){
					ac_num++;
				}
			}
		}
		// 番外編ここまで
		if(ac_num>0){ // 親アクティビティにCompletedかIncompleteのルールが一つでも設定されている
			Activity_Progress_Rollup_Process(activity_path_to_root[ap]); // 進捗状態ロールアップ
		} else {
			Activity_Default_Progress_Rollup_Process(activity_path_to_root[ap]); // デフォルトルール
		}
		
		// (長い番外編)ロールアップの各ルールを適用したら、グローバル共有学習目標へ書込む
		var children=activity_path_to_root[ap].childNodes;
		var seq; // "imsss:sequencing"
		for(var c=0;c<children.length;c++){
			if(children[c].nodeName=="imsss:sequencing"){
				seq=children[c];
				break;
			}
		}
		var pobj = My_getElementsByTagName(seq,"imsss:primaryObjective");
		if(pobj != undefined && pobj != null){
			if(pobj[0] != undefined && pobj[0] != null){
				// 主学習目標は連想配列から読む
				var maps = My_getElementsByTagName(item_primary_objectives[id(activity_path_to_root[ap])],"imsss:mapInfo");
				if(maps.length==1){
					if(maps[0].getAttribute("writeSatisfiedStatus")=="true"){ // 文字列としての"true"なので注意

						objective_progress_status_global[obj_id(maps[0])]= // mapInfoに書かれた共有学習目標に入れる
						objective_progress_status[id(activity_path_to_root[ap])][obj_id(pobj[0])]; // primaryObjectiveの習得の有意性
						objective_satisfied_status_global[obj_id(maps[0])]= // mapInfoに書かれた共有学習目標に入れる
						objective_satisfied_status[id(activity_path_to_root[ap])][obj_id(pobj[0])]; // primaryObjectiveの習得状態

					}
					if(maps[0].getAttribute("writeNormalizedMeasure")=="true"){ // 文字列としての"true"なので注意

						objective_measure_status_global[obj_id(maps[0])]= // mapInfoに書かれた共有学習目標に入れる
						objective_measure_status[id(activity_path_to_root[ap])][obj_id(pobj[0])]; // primaryObjectiveの習得度の有意性
						objective_normalized_measure_global[obj_id(maps[0])]= // mapInfoに書かれた共有学習目標に入れる
						objective_normalized_measure[id(activity_path_to_root[ap])][obj_id(pobj[0])]; // primaryObjectiveの習得度
					}
				}
			}
		}
		
		// 主でない学習目標も連想配列から読む
		var objs = item_objectives[id(activity_path_to_root[ap])];
		if(objs != undefined && objs != null){
			for(var o=0;o<objs.length;o++){
				var maps = My_getElementsByTagName(objs[o],"imsss:mapInfo");
				if(maps.length==1){
					if(maps[0].getAttribute("writeSatisfiedStatus")=="true"){ // 文字列としての"true"なので注意



						objective_progress_status_global[obj_id(maps[0])]=  // mapInfoに書かれた共有学習目標に入れる
						objective_progress_status[id(activity_path_to_root[ap])][obj_id(objs[o])]; // objectiveの習得の有意性
						objective_satisfied_status_global[obj_id(maps[0])]= // mapInfoに書かれた共有学習目標に入れる
						objective_satisfied_status[id(activity_path_to_root[ap])][obj_id(objs[o])]; // objectiveの習得状態



					}
					if(maps[0].getAttribute("writeNormalizedMeasure")=="true"){ // 文字列としての"true"なので注意



						objective_measure_status_global[obj_id(maps[0])]= // mapInfoに書かれた共有学習目標に入れる
						objective_measure_status[id(activity_path_to_root[ap])][obj_id(objs[o])]; // primaryObjectiveの習得度の有意性
						objective_normalized_measure_global[obj_id(maps[0])]= // mapInfoに書かれた共有学習目標に入れる
						objective_normalized_measure[id(activity_path_to_root[ap])][obj_id(objs[o])]; // primaryObjectiveの習得度
					}
				}
			} 
		}
		// 長い番外編ここまで
	}
	return; // 4. Exit
}

function Flow_Tree_Traversal_Subprocess(item,direction,child_check,prev_direction){ 
	// フローツリートラバーサルサブプロセス
	// p81-83 指定されたアクティビティから前方または後方にツリーを辿り、次のアクティビティを



	// 特定する。最後もしくは最初を越えるトラバーサルは例外である
	
	// 1. アクティビティがアクティビティツリーのルートではないなら



	if(item.nodeName!="organization"){
		var children=item.parentNode.childNodes;
		var cm; // controlMode
		for(var c=0;c<children.length;c++){
			if(children[c].nodeName=="imsss:sequencing"){
				cm=My_getElementsByTagName(children[c],"imsss:controlMode");
				break;
			}
		}
		
		// 1.1. 親のシーケンシングコントロールFlowがFalseなら



		if((cm==undefined || cm==null) || cm.length==0 || cm[0].getAttribute("flow")=="false"){
			return undefined; // 1.1.1. Exit フローツリートラバーサルサブプロセス
		} // End If
	} // End If
	
	// 2. 直前トラバース方向が定義され And
	// 直前トラバース方向が後方 And
	// アクティビティがアクティビティの親のAvailable Childrenのリストの最後のアクティビティ
	if((prev_direction!=undefined&&prev_direction!=null) && prev_direction=="back" && item==Available_Children(item.parentNode).pop()){
		direction = "back"; // 2.1. トラバース方向は後方
		// 2.2. アクティビティはアクティビティの親のAvailable Childrenのリストの最初のアクティビティ
		item=Available_Children(item.parentNode)[0];
	} // End If
	if(direction=="forward"){ // 3. トラバース方向が前方なら



		if(item==items[items.length-1]){ // 3.1. アクティビティがアクティビティツリーの前方順序付ツリートラバーサルの最後のアクティビティ
			return undefined; // 3.1.1. 
		} // End If
		if(item.getElementsByTagName("item").length==0|| child_check==false){ // 3.2. アクティビティが葉 Or 子検討フラグがFalseなら



			// 3.2.1. アクティビティがアクティビティの親のAvailable Childrenリストの
			// 最後のアクティビティなら



			if(item==Available_Children(item.parentNode).pop()){
				// 3.2.1.1. フローツリートラバーサルプロセスをアクティビティの親に対して
				// トラバース方向前方、直前トラバース方向n/a、子検討フラグFalseで適用
				var rec=Flow_Tree_Traversal_Subprocess(item.parentNode,"forward",false,"");
				return rec; // 3.2.1.2. 再帰の結果を返す
			} else { // 3.2.2.
				// 3.2.2.1. アクティビティに対してStopForwardTraversalシーケンシングルールに関してシーケンシングルールチェックプロセスを適用する
				if(Sequencing_Rule_Check_Process(item,new Array("StopForwardTraversal"))!=undefined){ // 3.2.2.2. // シーケンシングルールチェックプロセスがNilを返さない



					return undefined;// 3.2.2.2.1.
				} // End If
				
				// 3.2.2.3. ツリーを前方に、アクティビティの親のAvailable Childrenリスト中を



				// 次アクティビティに一つ辿る



				var parent_child_array=Available_Children(item.parentNode);
				var p;
				for(p=0;p<parent_child_array.length;p++){
					if(item==parent_child_array[p]){
						break;
					}
				}
				var next=parent_child_array[p+1];
				return next; // 3.2.2.4. 次アクティビティはトラバーサルで特定されたアクティビティ
			} // End If
		} else { // 3.3.
			// 3.3.1. 次アクティビティはアクティビティのAvailable Childrenリスト中の
			// 最初のアクティビティ
			return Available_Children(item)[0]; 
		} // End If
	} // End If(トラバース方向が前方)
	if(direction=="back"){ // 4. トラバース方向が後方
		// 4.1. アクティビティがアクティビティツリーのルートなら



		if(item.nodeName=="organization"){
			return undefined; // 4.1.1.
		}
		if(item.getElementsByTagName("item").length==0|| child_check==false){ // 4.2. アクティビティが葉 Or 子検討フラグがFalse
			// 4.2.1. アクティビティがアクティビティの親のAvailable Childrenリストの
			// 最初のアクティビティなら



			if(item==Available_Children(item.parentNode)[0]){
				// 4.2.1.1. フローツリートラバーサルサブプロセスをアクティビティの親に対して
				// トラバース方向後方、直前トラバース方向n/a、子検討フラグFalseで適用
				var rec=Flow_Tree_Traversal_Subprocess(item.parentNode,"back",false,"");
				return rec; // 4.2.1.2. 再帰の結果を返す
			} else { // 4.2.2. 
				var children=item.parentNode.childNodes; // 親の子供たち
				var cm; // controlMode
				for(var c=0;c<children.length;c++){
					if(children[c].nodeName=="imsss:sequencing"){
						cm=My_getElementsByTagName(children[c],"imsss:controlMode");
						break;
					}
				}
				
				// 4.2.2.1. アクティビティの親のシーケンシングコントロールForwardOnlyがTrue
				if(cm!=undefined && cm!=null && cm[0].getAttribute("forwardOnly")=="true"){ 
					return undefined; // 4.2.2.1.1. 次アクティビティはNil
				}
				
				// 4.2.2.2. ツリーを後方に、アクティビティの親のAvailable Childrenリスト中を



				// 前アクティビティに一つ辿る



				var parent_child_array=Available_Children(item.parentNode);
				var p;
				for(p=0;p<parent_child_array.length;p++){
					if(item==parent_child_array[p]){
						break;
					}
				}
				var prev=parent_child_array[p-1];
				return prev; // 4.2.2.3. 次アクティビティはトラバーサルで特定されたアクティビティ
			}
		} else { // 4.3. 
			var children=item.parentNode.childNodes; // 親の子供たち
			var cm; // controlMode
			for(var c=0;c<children.length;c++){
				if(children[c].nodeName=="imsss:sequencing"){
					cm=My_getElementsByTagName(children[c],"imsss:controlMode");
					break;
				}
			}
			
			// 4.3.1. アクティビティの親のシーケンシングコントロールForwardOnlyがTrue または
			// アクティビティがアクティビティツリーのルートなら



			if(cm!=undefined && cm!=null && cm[0].getAttribute("forwardOnly")=="true" || item.nodeName=="organization"){
				// 4.3.1.1. 次アクティビティはアクティビティのAvailable Childrenリスト中の
				// 最初のアクティビティ
				return Available_Children(item)[0];
			} else { // 4.3.2.
				// 4.3.2.1. 次アクティビティはアクティビティのAvailable Childrenリスト中の
				// 最後のアクティビティ
				return Available_Children(item).pop();
			} // End If
		} // End If
	} // End If
	return undefined; // 5. 次アクティビティはNil
}

function struct(return_activity,return_is_deliver){ // 値を返すための構造体風の入れ物
	this.activity=return_activity;
	this.is_deliver=return_is_deliver;
}

// ナビゲーション要求プロセスで値を返すための構造体風の入れ物
function struct_navigation(navigation,sequencing,termination,target){ 
	this.navigation=navigation;
	this.sequencing=sequencing;
	this.termination=termination;
	this.target=target;
}

// 終了要求プロセスで値を返すための構造体風の入れ物
function struct_termination(termination,sequencing){ 
	this.termination=termination; // 終了要求



	this.sequencing=sequencing;   // シーケンシング要求



}

// 事後条件ルールシーケンシングサブプロセスで値を返すための構造体風の入れ物
function struct_post_condition(sequencing,termination){ 
	this.sequencing=sequencing;   // シーケンシング要求



	this.termination=termination; // 終了要求



}

// シーケンシング要求プロセスで値を返すための構造体風の入れ物
function struct_sequencing_request(sequencing_request,delivery_request,sequencing_session){
	this.sequencing_request=sequencing_request;
	this.delivery_request=delivery_request;
	this.sequencing_session=sequencing_session;
}

function Flow_Activity_Traversal_Subprocess(item,direction,prev_direction){ 
	// フローアクティビティトラバーサルサブプロセス
	// p84-85 アクティビティ、トラバース方向、直前トラバース方向に対し、アクティビティツリー中の
	// 指定のトラバース方向の次のアクティビティおよびアクティビティが配信可能な場合にTrueを返す
	// (構造体風の入れ物で)
	var children=item.parentNode.childNodes;  // 親の子供たち
	var cm; // controlMode
	var fat; // フローアクティビティトラバーサルサブプロセス再帰呼出しの値
	for(var c=0;c<children.length;c++){
		if(children[c].nodeName=="imsss:sequencing"){
			cm=My_getElementsByTagName(children[c],"imsss:controlMode");
			break;
		}
	}
	
	// 1. 親のシーケンシングコントロールFlowがFalseなら


	
	//20070816修正後("imsss:controlMode"無指定対応)
	if(cm!=undefined && cm!=null){
		if(cm[0].getAttribute("flow")=="false"){
			return new struct(item,false); // 1.1. 配信可能はFalse
		}
	} // End If
	/*20070816修正前("imsss:controlMode"無指定対応)
	if(cm==undefined || cm==null || cm[0].getAttribute("flow")=="false"){
		return new struct(item,false); // 1.1. 配信可能はFalse
	} // End If
	*/
	
	// 2. skipシーケンシングルールに関してシーケンシングルールチェックプロセスを適用する
	// 3.シーケンシングルールチェックプロセスがNilを返さない    
	if(Sequencing_Rule_Check_Process(item,new Array("skip"))!=undefined){ 
		// 3.1. アクティビティに対してフローツリートラバーサルサブプロセスをトラバース方向および
		// 直前トラバース方向に子検討フラグFalseで適用
		var ft=Flow_Tree_Traversal_Subprocess(item,direction,false,prev_direction);
		
		// 3.2. フローツリートラバーサルサブプロセスがアクティビティを特定しないなら



		if(ft==undefined){
			return new struct(item,false); // 3.2.1. 配信可能はFalse
		} else { // 3.3.
			// 3.3.1. フローツリートラバーサルサブプロセスが特定したアクティビティに対して
			// フローアクティビティトラバーサルサブプロセスをトラバース方向に
			// 直前トラバース方向n/aで適用
			// 3.3.2. 再帰フローアクティビティトラバーサルサブプロセスの結果を返す
			return Flow_Activity_Traversal_Subprocess(ft,direction,"");
		}
	}
	
	// 4. アクティビティにチェックアクティビティプロセスを適用する
	// 5. チェックアクティビティプロセスがTrueを返すなら



	if(Check_Activity_Process(item)){
		return new struct(item,false); // 5.1. 配信可能はFalse
	}
	
	// 6. アクティビティがアクティビティツリーの葉でない



	if(item.getElementsByTagName("item").length>0){
		// 6.1. アクティビティに対してフローツリートラバーサルサブプロセスをトラバース方向に
		// 直前トラバース方向n/a、子検討フラグTrueで適用
		var ft=Flow_Tree_Traversal_Subprocess(item,direction,true,"");
		if(ft==undefined){ // 6.2. フローツリートラバーサルサブプロセスがアクティビティを特定しない



			return new struct(item,false); // 6.2.1. 配信可能はFalse
		} else { // 6.3.
			var ft_parent_children=ft.parentNode.childNodes; // 特定されたアクティビティの親の子供たち
			var cm_parent_children; // controlMode
			for(var c=0;c<ft_parent_children.length;c++){
				if(ft_parent_children[c].nodeName=="imsss:sequencing"){
					cm_parent_children=My_getElementsByTagName(ft_parent_children[c],"imsss:controlMode");
					break;
				}
			}
			
			// 6.3.1. フローツリートラバーサルプロセスで特定されたアクティビティの親アクティビティの
			// シーケンシングコントロールForwardOnlyがTrue And トラバース方向が後方
			if(cm_parent_children!=undefined && cm_parent_children!=null && cm_parent_children[0].getAttribute("forwardOnly")=="true" && direction=="back"){
				// 6.3.1.1. フローツリートラバーサルプロセスで特定されたアクティビティに対し



				// フローアクティビティトラバーサルサブプロセスをトラバース方向前方、



				// 直前トラバース方向後方で適用
				fat = Flow_Activity_Traversal_Subprocess(ft,"forward","back");
				item=fat.activity;
			} else { // 6.3.2.
				// 6.3.2.1. フローツリートラバーサルプロセスで特定されたアクティビティに対し



				// フローアクティビティトラバーサルサブプロセスをトラバース方向に、



				// 直前トラバーサル方向n/aで適用
				fat=Flow_Activity_Traversal_Subprocess(ft,direction,"");
				item=fat.activity;
			}
		}
	}
	return new struct(item,true); // 配信可能はTrue
}

function Flow_Subprocess(item,direction,child_check){ // フローサブプロセス
	// p86-87
	// アクティビティ、トラバース方向、子検討フラグに対し、移動が成功したか否か、



	// および移動が停止したアクティビティを返す
	var candidate=item;     // 1. アクティビティを候補アクティビティとする
	// 2. 候補アクティビティに対してフローツリートラバーサルプロセスをトラバース方向に、



	// 直前トラバース方向n/a、子検討フラグで適用
	var ft=Flow_Tree_Traversal_Subprocess(candidate,direction,child_check,"");
	if(ft==undefined){ // 3. フローツリートラバーサルサブプロセスがアクティビティを特定しない



		// 3.1. 特定されたアクティビティは候補アクティビティ、配信可否はFalse
		return new struct(candidate,false);
	} else { // 4.
		// 4.1. フローツリートラバーサルサブプロセスが特定したアクティビティを候補アクティビティとする
		candidate=ft;
		// 4.2. 候補アクティビティに対してフローアクティビティトラバーサルサブプロセスを



		// トラバーサル方向に、直前トラバース方向n/aで適用
		// 4.3. 特定されたアクティビティはフローアクティビティトラバーサルサブプロセスが特定した



		// アクティビティ、配信可否はフローアクティビティトラバーサルサブプロセスが特定した通り
		return Flow_Activity_Traversal_Subprocess(candidate,direction,"");
	}
}

function Choice_Activity_Traversal_Subprocess(item,direction){ 
	// p87-88 Choiceアクティビティトラバーサルサブプロセス
	// アクティビティにChoiceシーケンシング要求が許されるかどうかを決定



	// 1つのアクティビティを受け取り、真偽値を返す。制限条件かルールに反したらFalse、



	// アクティビティに達することができればTrue
	
	// 1. アクティビティにチェックアクティビティプロセスを適用
	if(Check_Activity_Process(item)){ // 2. チェックアクティビティプロセスがTrueを返す
		return false; // 2.1. 到達可能はFalse
	}
	if(direction=="forward"){ //3. トラバーサル方向が前方
		// 3.1. アクティビティにシーケンシングルールチェックプロセスをStop Forward Traversal
		// シーケンシングルールに関して適用する
		// 3.2. シーケンシングルールチェックプロセスがNilを返さない



		if(Sequencing_Rule_Check_Process(item,new Array("StopForwardTraversal"))!=undefined){	
			return false; // 3.2.1. 到達可能はFalse
		}
		return true; // 3.3. 到達可能はTrue
	}
	if(direction=="back"){ // 4. トラバーサル方向が後方
		if(item.nodeName!="organization"){ // 4.1. アクティビティが親を持つ
			var children=item.parentNode.childNodes;
			var cm; // controlMode
			for(var c=0;c<children.length;c++){
				if(children[c].nodeName=="imsss:sequencing"){
					cm=My_getElementsByTagName(children[c],"imsss:controlMode");
					break;
				}
			}
			
			// 4.1.1. アクティビティの親のシーケンシングコントロールForward OnlyがTrue
			if(cm!=undefined && cm!=null && cm[0].getAttribute("forwardOnly")=="true"){ 
				return false; // 4.1.1.1. 到達可能はFalse
			}
		} else {  // 4.1.2. (実はこれが4.2.では?)
			return false; // 4.1.2.1. 到達可能はFalse (実はこれが4.2.1.では?)
		}
		return true; // 4.2. 到達可能はTrue (実はこれが4.3では?)
	}
}

function Start_Sequencing_Request_Process(){ // startシーケンシング要求プロセス
	// p89
	// 配信する最初のアクティビティを特定する



	
	// 1. Current Activityが定義されている
	if(current_activity!=undefined && current_activity!=null){
		return; // 1.1. 配信するものがない



	}
	
	// 2. アクティビティツリーのルートに対してフローサブプロセスを前方に子検討フラグTrueで適用
	var fs=Flow_Subprocess(manifest.getElementsByTagName("organization")[0],"forward",true);
	if(fs.is_deliver==false){ // 3. フローサブプロセスがFalseを返す
		return; // 3.1. 配信するものがない



	} else { // 4. Else
		return fs.activity; // 4.1. 配信要求はフローサブプロセスが特定したアクティビティ
	}
}

function Resume_All_Sequencing_Request_Process(){
	// p90
	// 前のシーケンシングセッションの再開を試みて、配信する最初のアクティビティを特定する



	// 配信候補アクティビティを返すか、配信アクティビティがないという識別子を返す
	
	// 1. Current Activityが定義されている
	if(current_activity!=undefined && current_activity!=null){
		return; // 1.1. 配信するものがない



	}
	
	// 2. Suspended Activityが定義されていない



	if(suspended_activity==undefined || suspended_activity==null){
		return; // 2.1. 配信するものがない



	}
	return suspended_activity; // 3. 配信要求はSuspended Activityで特定されるアクティビティ
}

function Continue_Sequencing_Request_Process(){ // continueシーケンシング要求プロセス
	// p91
	// 配信する次のアクティビティを特定する(現在のアクティビティからツリーを前方に辿る)
	// カレントアクティビティとフローサブプロセスを使う



	// 配信候補アクティビティを返すか、配信アクティビティがないという識別子を返す
	
	// 1. Current Activityが定義されていない



	if(current_activity==undefined || current_activity==null){
		return; // 1.1. 配信するものがない



	}
	
	// 2. Current Activityに対してフローサブプロセスを前方に子検討フラグFalseで適用
	var fs=Flow_Subprocess(current_activity,"forward",false);
	if(fs.is_deliver==false){ // 3. フローサブプロセスがFalseを返す
		return; // 3.1. 配信するものがない



	} else { // 4. Else
		return fs.activity; // 4.1. 配信要求はフローサブプロセスが特定したアクティビティ
	}
}

function Previous_Sequencing_Request_Process(){ // previousシーケンシング要求プロセス
	// p92
	// 配信する次のアクティビティを特定する(現在のアクティビティからツリーを後方に辿る)
	// カレントアクティビティとフローサブプロセスを使う



	// 配信候補アクティビティを返すか、配信アクティビティがないという識別子を返す
	
	// 1. Current Activityが定義されていない



	if(current_activity==undefined || current_activity==null){
		return; // 1.1. 配信するものがない



	}
	
	// 2. Current Activityに対してフローサブプロセスを後方に子検討フラグFalseで適用
	var fs=Flow_Subprocess(current_activity,"back",false);
	if(fs.is_deliver==false){ // 3. フローサブプロセスがFalseを返す
		return; // 3.1. 配信するものがない



	} else { // 4. Else
		return fs.activity; // 4.1. 配信要求はフローサブプロセスが特定したアクティビティ
	}
}

function Choice_Sequencing_Request_Process(item){ // choiceシーケンシング要求プロセス
	// p96-100(でかい!)
	// 配信候補アクティビティを返すか、配信アクティビティがないという識別子を返す
	if(item==undefined||item==null){// 1. ターゲットアクティビティがない



		return ""; // 1.1. 配信要求はn/a
	}
	if(item.nodeName!="organization"){ // 2. ターゲットアクティビティがアクティビティツリーのルートではない



		var parent_child_array=Available_Children(item.parentNode);
		var has=false; // Available Childrenがターゲットアクティビティを含むか否か



		for(var p=0;p<parent_child_array.length;p++){
			if(item==parent_child_array[p]){
				has=true;
				break;
			}
		}
		if(has==false){ // 2.1. ターゲットアクティビティの親のAvailable Childrenがターゲットアクティビティを含まない



			return ""; // 2.1.1. 配信要求はn/a	
		}
	}
	
	// 3. アクティビティツリーのルートからターゲットアクティビティまで、両端のアクティビティを含む
	// 順序付き系列のアクティビティパスを作る
	var activity_path_to_target_activity = new Array();
	tmp_item = item;
	while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
		activity_path_to_target_activity.push(tmp_item);
		tmp_item = tmp_item.parentNode;
	}
	activity_path_to_target_activity.reverse(); // 「ルートから」なので逆順にする
	for(var ap=0;ap<activity_path_to_target_activity.length;ap++){ // 4. アクティビティパスの各アクティビティ
		// 4.1. アクティビティに対してHide from Choice シーケンシングルールについて
		// シーケンシングルールチェックプロセスを適用する
		// 4.2. シーケンシングルールチェックプロセスがNilを返さない(仕様書に誤植あり!)
		if(Sequencing_Rule_Check_Process(activity_path_to_target_activity[ap], new Array("hiddenFromChoice"))!=undefined){
			return ""; // 4.2.1. 配信要求はn/a	
		}
	}
	if(item.nodeName!="organization"){ // 5. ターゲットアクティビティがアクティビティツリーのルートではない



		// 5.1. ターゲットアクティビティの親のシーケンシングコントロールモードChoiceがFalse
		if(My_Control_Mode(item.parentNode,"choice")==false){
			return ""; // 5.1.1. 配信要求はn/a	
		}
	}
	var common_ancestor; // 共通の祖先となるアクティビティ
	if(current_activity!=undefined && current_activity!=null){ // 6. Current Activityが定義されている
		// 6.1. Current Activityとターゲットアクティビティの共通の祖先を見つける
		var found_common=false; // 共通の祖先が見つかったか
		var current_activity_to_root = new Array();
		var tmp_item = current_activity;
		while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
			current_activity_to_root.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		var item_to_root = new Array();
		tmp_item = item;
		while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
			item_to_root.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		for(var c=0;c<current_activity_to_root.length;c++){
			for(var i=0;i<item_to_root.length;i++){
				if(current_activity_to_root[c]==item_to_root[i]){
					common_ancestor=current_activity_to_root[c];
					found_common=true;
					break;
				}
			}
			if(found_common){
				break;
			}
		}
	} else { // 7. Else
		// 7.1. 共通の祖先はアクティビティツリーのルート



		common_ancestor=manifest.getElementsByTagName("organization")[0];
	}
	var common_ancestor_index_of_all; // 全体アクティビティ一覧における、共通の祖先の位置
	var item_index_of_all; // 全体アクティビティ一覧における、アイテムの位置
	var current_index_of_all; // 全体アクティビティ一覧における、Current Activityの位置
	for(var it=0;it<items.length;it++){
		// item一覧の中での、共通の祖先の位置を覚えておく(12.で使う)
		if(common_ancestor==items[it]){
			common_ancestor_index_of_all=it;
		}
		// item一覧の中での、アクティビティの位置を覚えておく(12.で使う)
		if(item==items[it]){
			item_index_of_all=it;	    
		}
		// item一覧の中での、Current Activityの位置を覚えておく(12.で使う)
		if(current_activity==items[it]){
			current_index_of_all=it;	    
		}
	}
	if(item==current_activity){ // 8. Current Activityとターゲットアクティビティが同一   
		// 8.1. Current Actibityにチェックアクティビティプロセスを適用する
		if(Check_Activity_Process(current_activity)==true){ // 8.2. チェックアクティビティプロセスがTrueを返す
			return ""; // 8.2.1. 配信要求はn/a	
		}
		// 8.3. Break Case
	} else if(current_activity == null || current_activity == undefined) {
		alert("現在のAttain3では、このマニフェストファイルは使用出来ません。");
	} else if(item.parentNode==current_activity.parentNode){ // 9. Current Activityとターゲットアクティビティが兄弟



		// 9.1. Current Activityからターゲットアクティビティまで両端のアクティビティを含む
		// 順序付き系列のアクティビティリストを作る
		var parent_child_array=Available_Children(item.parentNode);
		var activity_path_to_target_activity = new Array();
		var pc;
		var cur_index; // 親のAvailable Childrenにおける、Current Activityの位置
		var item_index;// 親のAvailable Childrenにおける、itemの位置
		var direction; // 移動方向



		for(pc=0;pc<parent_child_array.length;pc++){
			if(parent_child_array[pc]==current_activity){
				cur_index=pc;
			} else if(parent_child_array[pc]==item){
				item_index=pc;
			}
		}
		if(cur_index<item_index){ // 親のAvailable Childrenにおいて、Current Activityよりも後にitemが出てくる
			for(pc=cur_index;pc<=item_index;pc++){
				activity_path_to_target_activity.push(parent_child_array[pc]);	    
			}
		} else {
			for(pc=cur_index;pc>=item_index;pc--){
				activity_path_to_target_activity.push(parent_child_array[pc]);	    
			}
		}
		if(activity_path_to_target_activity.length==0){ // 9.2. アクティビティリストが空
			return ""; // 9.2.1 配信要求はn/a
		}
		// 9.3. ターゲットアクティビティがアクティビティツリーの順序付きトラバーサルに関してCurrent Activityの前方にある
		if(cur_index<item_index){ 
			// 9.3.1. 移動方向は前方
			direction="forward";
		} else { // 9.4. Else
			// 9.4.1. 移動方向は後方
			direction="back";
		}
		for(var ap=0;ap<activity_path_to_target_activity.length;ap++){ // 9.5. アクティビティリストの各アクティビティ
			// 9.5.1. Choiceアクティビティトラバーサルプロセスをアクティビティに移動方向に適用する
			// 9.5.2. ChoiceアクティビティトラバーサルプロセスがFalseを返す
			if(Choice_Activity_Traversal_Subprocess(activity_path_to_target_activity[ap],direction)==false){
				return ""; // 9.5.2.1 配信要求はn/a
			}
		}
		// 9.6. Break Case
	} else if(current_activity==common_ancestor|| current_activity==undefined||current_activity==null){// 10. Current Activityと共通の祖先が同一かCurrent Activityが未定義
		// 10.1. 共通の祖先からターゲットアクティビティまで、両端のアクティビティを含む
		// 順序付き系列のアクティビティリストを作る
		var activity_path_to_target_activity = new Array();
		tmp_item = item;
		while(tmp_item != common_ancestor){
			activity_path_to_target_activity.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		activity_path_to_target_activity.push(common_ancestor);
		activity_path_to_target_activity.reverse(); // 「共通の祖先からターゲットアクティビティ」なので逆順にする
		if(activity_path_to_target_activity.length==0){ // 10.2. アクティビティパスが空
			return ""; // 10.2.1 配信要求はn/a	    
		}
		for(var ap=0;ap<activity_path_to_target_activity.length;ap++){ // 10.3. アクティビティパスの各アクティビティ
			// 10.3.1. Choiceアクティビティトラバーサルプロセスをアクティビティに前方に適用する
			// 10.3.2. ChoiceアクティビティトラバーサルプロセスがFalseを返す
			if(Choice_Activity_Traversal_Subprocess(activity_path_to_target_activity[ap],direction)==false){
				return ""; // 10.3.2.1 配信要求はn/a	    
			}
		}
		// 10.4. Break Case
	} else if(item==common_ancestor){ // 11. ターゲットアクティビティがCurrent Activityの共通の祖先
		// 11.1. Current Activityからターゲットアクティビティまで、両端のアクティビティを含む
		// 順序付き系列のアクティビティリストを作る
		var activity_path_to_target_activity = new Array();
		tmp_item = current_activity;
		while(tmp_item != item){
			activity_path_to_target_activity.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		activity_path_to_target_activity.push(item); // ここは逆順にしないで終了



		if(activity_path_to_target_activity.length==0){ // 11.2. アクティビティパスが空
			return ""; // 11.2.1 配信要求はn/a	    
		}
		for(var ap=0;ap<activity_path_to_target_activity.length;ap++){ // 11.3. アクティビティパスの各アクティビティ
			// 11.3.1. チェックアクティビティプロセスをアクティビティに適用する
			// 11.3.2. チェックアクティビティプロセスがTrueを返す
			if(Check_Activity_Process(activity_path_to_target_activity[ap])){
				return ""; // 11.3.2.1 配信要求はn/a	    
			}		
			// 11.3.3. アクティビティがアクティビティパスの最後のアクティビティでない



			if(ap!=activity_path_to_target_activity.length-1){
				// 11.3.3.1. アクティビティのシーケンシングコントロールモードChoiceExitがFalse
				var children=activity_path_to_target_activity[ap].childNodes;
				var cm; // controlMode
				for(var c=0;c<children.length;c++){
					if(children[c].nodeName=="imsss:sequencing"){
						cm=My_getElementsByTagName(children[c],"imsss:controlMode");
						break;
					}
				}
				// choiceExitのデフォルトがtrueであることに注意



				if(cm!=undefined && cm!=null){
					if(cm[0]!=undefined && cm[0]!=null && cm[0].getAttribute("choiceExit")=="false"){
						return ""; // 11.3.3.1.1 配信要求はn/a
					}
				}
			}
		}
		// 11.4. Break Case
	} else if(item_index_of_all > common_ancestor_index_of_all){ // 12. ターゲットアクティビティが共通の祖先の前方
		// 12.1. Current Activityから共通の祖先まで、両端のアクティビティを含む
		// 順序付き系列のアクティビティリストを作る
		var activity_path_to_common_ancestor = new Array();
		tmp_item = current_activity;
		while(tmp_item != common_ancestor){
			activity_path_to_common_ancestor.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		activity_path_to_common_ancestor.push(common_ancestor); // 共通の祖先を含む
		if(activity_path_to_common_ancestor.length==0){ // 12.2. アクティビティパスが空
			return ""; // 12.2.1 配信要求はn/a	    
		}
		for(var ap=0;ap<activity_path_to_common_ancestor.length;ap++){ // 12.3. アクティビティパスの各アクティビティ
			// 12.3.1. チェックアクティビティプロセスをアクティビティに適用する
			// 12.3.2. チェックアクティビティプロセスがTrueを返す
			if(Check_Activity_Process(activity_path_to_common_ancestor[ap])){
				return ""; // 12.3.2.1 配信要求はn/a	    
			}		
			// 12.3.3. アクティビティがアクティビティパスの最後のアクティビティでない



			if(ap!=activity_path_to_common_ancestor.length-1){ 
				// 12.3.3.1. アクティビティのシーケンシングコントロールモードChoiceExitがFalse
				var children=activity_path_to_common_ancestor[ap].childNodes;
				var cm; // controlMode
				for(var c=0;c<children.length;c++){
					if(children[c].nodeName=="imsss:sequencing"){
						cm=My_getElementsByTagName(children[c],"imsss:controlMode");
						break;
					}
				}
				// choiceExitのデフォルトがtrueであることに注意



				if(cm!=undefined && cm!=null){
					if(cm[0]!=undefined && cm[0]!=null && cm[0].getAttribute("choiceExit")=="false"){
						return ""; // 12.3.3.1.1. 配信要求はn/a
					}
				}
			}
		}
		// 12.4. 共通の祖先からターゲットアクティビティまで、両端のアクティビティを含む
		// 順序付き系列のアクティビティリストを作る
		var activity_path_to_target_activity = new Array();
		tmp_item = item;
		while(tmp_item != common_ancestor){
			activity_path_to_target_activity.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		activity_path_to_target_activity.push(common_ancestor);
		activity_path_to_target_activity.reverse(); // 「共通の祖先からターゲットアクティビティ」なので逆順にする
		if((activity_path_to_target_activity.length)==0){ // 12.5. アクティビティパスが空
			return ""; // 12.5.1. 配信要求はn/a
		}
		// 12.6. ターゲットアクティビティがアクティビティツリーの順序付きトラバーサルに関してCurrent Activityの前方にある
		if(item_index_of_all > current_index_of_all){
			for(var ap=0;ap<activity_path_to_target_activity.length;ap++){ // 12.6.1. アクティビティパスの各アクティビティ
				// 12.6.1.1. Choiceアクティビティトラバーサルプロセスをアクティビティに前方に適用する
				// 12.6.1.2. ChoiceアクティビティトラバーサルプロセスがFalseを返す		
				if(Choice_Activity_Traversal_Subprocess(activity_path_to_target_activity[ap],"forward")==false){
					return ""; // 12.6.1.2.1. 配信要求はn/a
				}
			}
		} else { // 12.7.
			for(var ap=0;ap<activity_path_to_target_activity.length;ap++){ // 12.7.1. アクティビティパスの各アクティビティ
				// 12.7.1.1. チェックアクティビティプロセスをアクティビティに移動方向に適用する(移動方向というのは変)
				// 12.7.1.2. チェックアクティビティプロセスがTrueを返す		
				if(Check_Activity_Process(activity_path_to_target_activity[ap])==true){
					return ""; // 12.7.1.2.1. 配信要求はn/a		    
				}
			}
		}
		// 12.8. Break Case
	}
	if(item.getElementsByTagName("item").length==0){ // 13. ターゲットアクティビティが葉アクティビティ
		return item; // 13.1. 配信要求はターゲットアクティビティ
	}
	// 14. フローサブプロセスをターゲットアクティビティに前方に子検討フラグTrueで適用する
	var fs=Flow_Subprocess(item,"forward",true);
	if(fs.is_deliver==false){ //15. フローサブプロセスがFalseを返す
		// 15.1. 下位試行終了プロセスを共通の祖先に適用
		Terminate_Descendent_Attempts_Process(common_ancestor);
		// 15.2. 試行終了プロセスを共通の祖先に適用
		End_Attempt_Process(common_ancestor);
		// 15.3. Current Activityをターゲットアクティビティに設定



		current_activity=item;
		return ""; // 15.4. 配信要求はn/a	
	} else { // 16. Else
		return fs.activity; // 16.1. 配信要求はフローサブプロセスで特定されたアクティビティ
	}
}

function Retry_Sequencing_Request_Process(){ // retryシーケンシング要求プロセス
	// p101
	// 配信候補アクティビティを返すか、配信アクティビティがないという識別子を返す
	
	// 1. Current Activityが定義されていない



	if(current_activity==undefined || current_activity==null){
		return ""; // 1.1. 配信要求はn/a
	}
	
	// 2. Current ActivityのActivity is ActiveがTrue Or Current ActivityのActivity is SuspendedがTrue
	if(activity_is_active[id(current_activity)]==true || activity_is_suspended[id(current_activity)]==true){
		return ""; // 2.1. 配信要求はn/a
	}
	
	// 3. Current Activityが葉でない



	if(current_activity.getElementsByTagName("item").length>0){
		// 3.1. Current Activityに対してフローサブプロセスを前方に子検討フラグTrueで適用
		var fs=Flow_Subprocess(current_activity,"forward",true);
		if(fs.is_deliver==false){ // 3.2. フローサブプロセスがFalseを返す
			return ""; // 3.2.1. 配信要求はn/a
		} else { // 3.3. 
			return fs.activity; // 3.3.1. 配信要求はフローサブプロセスが特定したアクティビティ
		}
	} else { // 4. 
		return current_activity; // 4.1. 配信要求はCurrent Activity
	}
}

function Exit_Sequencing_Request_Process(){ // exitシーケンシング要求プロセス
	// p102
	// 配信候補アクティビティを「出力しない」!
	// ルートに適用されたらTrueを返してシーケンシング終了



	
	// 1. Current Activityが定義されていない



	if(current_activity==undefined || current_activity==null){
		return false; //  1.1. シーケンシングセッション終了はFalse
	}
	if(activity_is_active[id(current_activity)]==true){ // 2. Current ActivityのActivity is ActiveがTrue
		return false; // 2.1. シーケンシングセッション終了はFalse
	}
	if(current_activity.nodeName=="organization"){ // 3. Current Activityがアクティビティツリーのルート



		return true; // 3.1. シーケンシングセッション終了はTrue
	}
	return false; // 4. シーケンシングセッション終了はFalse
}

function Sequencing_Request_Process(request,target_activity){ // シーケンシング要求プロセス
	// p103-104
	// 全てのシーケンシングの親玉



	// target_activityはChoiceシーケンシング要求プロセスで処理するターゲットアクティビティ
	// 値を返す時は struct_sequencing_request(sequencing_demand,delivery_request,sequencing_session) を使う



	if(request=="start"){ // 1. シーケンシング要求がStart
		// 1.1. シーケンシング要求プロセスを適用
		// 1.2. シーケンシング要求はValid、配信要求はStartシーケンシング要求プロセスの結果、



		// シーケンシングセッション終了はn/a
		return new struct_sequencing_request("Valid",Start_Sequencing_Request_Process(),"");
	} else if(request=="resumeAll"){ // 2. シーケンシング要求がResume All
		// 2.1. シーケンシング要求プロセスを適用
		// 2.2. シーケンシング要求はValid、配信要求はResume Allシーケンシング要求プロセスの結果、



		// シーケンシングセッション終了はn/a
		return new struct_sequencing_request("Valid",Resume_All_Sequencing_Request_Process(),"");
	} else if(request=="exit"){ // 3. シーケンシング要求がExit
		// 3.1. シーケンシング要求プロセスを適用
		Exit_Sequencing_Request_Process();
		// 3.2. シーケンシング要求はValid、配信要求はn/a、



		// シーケンシングセッション終了はExit
		return new struct_sequencing_request("Valid","","exit");
	} else if(request=="retry"){ // 4. シーケンシング要求がRetry
		// 4.1. シーケンシング要求プロセスを適用
		// 4.2. シーケンシング要求はValid、配信要求はRetryシーケンシング要求プロセスの結果、



		// シーケンシングセッション終了はn/a
		return new struct_sequencing_request("Valid",Retry_Sequencing_Request_Process(),"");
	} else if(request=="continue"){ // 5. シーケンシング要求がContinue
		// 5.1. シーケンシング要求プロセスを適用
		// 5.2. シーケンシング要求はValid、配信要求はContinueシーケンシング要求プロセスの結果、



		// シーケンシングセッション終了はn/a
		return new struct_sequencing_request("Valid",Continue_Sequencing_Request_Process(),"");
	} else if(request=="previous"){ // 6. シーケンシング要求がPrevious
		// 6.1. シーケンシング要求プロセスを適用
		// 6.2. シーケンシング要求はValid、配信要求はPreviousシーケンシング要求プロセスの結果、



		// シーケンシングセッション終了はn/a
		return new struct_sequencing_request("Valid",Previous_Sequencing_Request_Process(),"");
	} else if(request=="choice"){ // 7. シーケンシング要求がChoice
		// 7.1. シーケンシング要求プロセスを適用
		// 7.2. シーケンシング要求はValid、配信要求はChoiceシーケンシング要求プロセスの結果、



		// シーケンシングセッション終了はn/a
		return new struct_sequencing_request("Valid",Choice_Sequencing_Request_Process(target_activity),"");
	}
	// 8. シーケンシング要求はNot Valid, 配信要求はn/a, シーケンシングセッション終了はn/a
	return new struct_sequencing_request("Not Valid","","");
}

function Delivery_Request_Process(item){ // 配信要求プロセス
	// p106
	// 配信要求されたitemに対して配信要求の有効性を返却する
	if(item.getElementsByTagName("item").length>0){ // 1. 配信要求で指定されたアクティビティが葉でない



		return "Not Valid"; // 1.1. 配信要求はNot Valid
	}
	
	// 2. アクティビティツリーのルートから配信要求で指定されたアクティビティまで、両端のアクティビティを含む、



	// 順序付き系列のアクティビティパスを作る
	var activity_path_to_item = new Array();
	var tmp_item = item;
	while(tmp_item!=null && tmp_item != manifest.getElementsByTagName("organizations")[0]){
		activity_path_to_item.push(tmp_item);
		tmp_item = tmp_item.parentNode;
	}
	activity_path_to_item.reverse(); // 「ルートから」なので逆順にする
	if(activity_path_to_item.length==0){ // 3. アクティビティパスが空
		return "Not Valid"; // 配信要求はNot Valid(ここは3.1.ではないのか?)
	}
	for(var ap=0;ap<activity_path_to_item.length;ap++){ // 4. アクティビティパスの各アクティビティ
		// 4.1. アクティビティ確認プロセスをアクティビティに適用する
		if(Check_Activity_Process(activity_path_to_item[ap])){ // 4.2. アクティビティ確認プロセスがTrueを返す
			return "Not Valid"; // 4.2.1. 配信要求はNot Valid
		}
	}
	return "Valid"; // 5. 配信要求はValid
}

function Contents_Delivery_Environment_Process(item){ // コンテンツ配信環境プロセス
	// p108-109
	// 配信対象アクティビティを受け取る(item)
	if(activity_is_active[id(current_activity)]==true){ // 1. Current ActivityのActivity is ActiveがTrue
		return;// 1.1. 配信要求は無効
	}
	
	if(item != suspended_activity){ // 2. 配信対象アクティビティがSuspended Activityと異なる

		// 2.1. 中断アクティビティクリアサブプロセスを配信対象アクティビティに適用
		Suspend_Activity_Clear_Subprocess(item);
	}
	
	// 3. 下位ノード試行終結プロセスを配信対象アクティビティに適用
	Terminate_Descendent_Attempts_Process(item);
	
	// 4. アクティビティツリーのルートから配信対象アクティビティまで、両端のアクティビティを含む、

	// 順序付き系列のアクティビティパスを作る
	var activity_path_to_item = new Array();
	var tmp_item = item;
	while(tmp_item!=null && tmp_item != manifest.getElementsByTagName("organizations")[0]){
		activity_path_to_item.push(tmp_item);
		tmp_item = tmp_item.parentNode;
	}
	activity_path_to_item.reverse(); // 「ルートから」なので逆順にする
	
	for(var ap=0;ap<activity_path_to_item.length;ap++){ // 5. アクティビティパスの各アクティビティ
		if(activity_is_active[id(activity_path_to_item[ap])]==false){ // 5.1. アクティビティのActivity is ActiveがFalse
			if(tracked[id(activity_path_to_item[ap])]==true){ // 5.1.1. アクティビティのTrackedがTrue
				// 5.1.1.1. アクティビティのActivity is SuspendedがTrue
				if(activity_is_suspended[id(activity_path_to_item[ap])]==true){
					// 5.1.1.1.1. アクティビティのActivity is SuspendedをFalseにする
					activity_is_suspended[id(activity_path_to_item[ap])]=false;
				} else { // 5.1.1.2.
					// 5.1.1.2.1. アクティビティのActivity Attempt Countを1増やす

					activity_attempt_count[id(activity_path_to_item[ap])]=activity_attempt_count[id(activity_path_to_item[ap])]+1;
					// 5.1.1.2.2. 新しい試行に必要なObjective Progress InformationとAttempt Progress Informationを初期化
					var children=activity_path_to_item[ap].childNodes;
					var seq; // "imsss:sequencing"
					for(var c=0;c<children.length;c++){
						if(children[c].nodeName=="imsss:sequencing"){
							seq=children[c];
							break;
						}
					}
					var item_all_objectives = new Array();
					// 主学習目標は連想配列から取り出す



					item_all_objectives.push(item_primary_objectives[id(activity_path_to_item[ap])]);
					// 主でない学習目標も連想配列から読む
					var objs = item_objectives[id(activity_path_to_item[ap])];
					if(objs!=undefined && objs!=null){
						for(var o=0;o<objs.length;o++){
							item_all_objectives.push(objs[o]);
						}
					}
					for(var ob=0;ob<item_all_objectives.length;ob++){ // そのitemの全ての学習目標

						// オブジェクトが存在しないときだけ初期化するように変更　鈴木 2008/10/8
						// ほんとに正しいかどうかは不明・・・
						if( objective_progress_status[id(activity_path_to_item[ap])][obj_id(item_all_objectives[ob])] == null ){
							objective_progress_status[id(activity_path_to_item[ap])][obj_id(item_all_objectives[ob])] = false;  // 初期化中…
							objective_satisfied_status[id(activity_path_to_item[ap])][obj_id(item_all_objectives[ob])] = false; // 初期化中…
							objective_measure_status[id(activity_path_to_item[ap])][obj_id(item_all_objectives[ob])] = false;   // 初期化中…
							objective_normalized_measure[id(activity_path_to_item[ap])][obj_id(item_all_objectives[ob])] = 0.0; // 初期化中…
						}
					}
					// オブジェクトが存在しないときだけ初期化するように変更　鈴木 2008/10/8
					// ほんとに正しいかどうかは不明・・・
					if( attempt_progress_status[id(activity_path_to_item[ap])] == null ){
						attempt_progress_status[id(activity_path_to_item[ap])]=false; // 初期化中…
						attempt_completion_amount[id(activity_path_to_item[ap])]=0; // 初期化中…
						attempt_completion_status[id(activity_path_to_item[ap])]=false; // 初期化中…
						attempt_absolute_duration[id(activity_path_to_item[ap])]=0; // 初期化中…
						attempt_experienced_duration[id(activity_path_to_item[ap])]=0; // 初期化中…
					}
				}
				// 5.1.1.3. アクティビティのActivity is ActiveをTrueに設定

				activity_is_active[id(activity_path_to_item[ap])]=true; 
			}
		}
	}
	
	// 6. Current Activityを配信対象アクティビティに設定



	current_activity=item;
	parent.current_activity=item;
	
	// 7. アクティビティのコンテンツと補助リソースの配信が始まる



	// manifestからresourceを見て配信。 下フレームに指定URLのページを流し込む
	// IE以外ではナビゲーションがSCOから発行されたか否かでカレントディレクトリの位置が変わるため場合分け



	uri=uri_base+href_hash[idref(item)];
	
	var guiBtnFlag = "";
	//目次の有効無効の文字列
	var tocTreeFlag = flash_toc_tree_recurse();
	//Attain2用に変更後



	//Flashに値を渡す



	/*identiferとリクエストの種類("choice","previous","continue"等)*/	
	FlashApi2004_DoFSCommand("setIdentifierToFlash", id(item) + "#" + fromFlashRequest + "#" + guiBtnFlag + "#" + tocTreeFlag);
	if(tracked[id(item)]==false){ // 7.1. 配信対象アクティビティのTrackedがFalse
		// 7.1.1. アクティビティの学習目標と試行進捗情報は配信中に記録しない



		// 記録しない!
		// 7.1.2. 配信環境はAttempt Absolute DurationとAttempt Experienced Durationの記録を開始する



		// Attempt Absolute Durationはアクティビティの試行期間(開始から終了まで)0.1秒精度
		// Attempt Experienced Durationはアクティビティの試行期間(開始から終了まで、中断期間を除く)0.1秒精度
	}
}

function Suspend_Activity_Clear_Subprocess(item){ // 中断アクティビティクリアサブプロセス
	// p109-110
	// 中断アクティビティ(suspended_activity)を使う



	if(suspended_activity!=undefined && suspended_activity!=null){ // 1. Suspended Activityが定義されている
		// 1.1. 指定されたアクティビティとSuspended Activityの共通の祖先を見つける
		var common_ancestor; // 共通の祖先となるアクティビティ
		var found_common=false; // 共通の祖先が見つかったか
		var suspended_activity_to_root = new Array();
		var tmp_item = suspended_activity;
		while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
			suspended_activity_to_root.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		var item_to_root = new Array();
		tmp_item = item;
		while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
			item_to_root.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		for(var c=0;c<suspended_activity_to_root.length;c++){
			for(var i=0;i<item_to_root.length;i++){
				if(suspended_activity_to_root[c]==item_to_root[i]){
					common_ancestor=suspended_activity_to_root[c];
					found_common=true;
					break;
				}
			}
			if(found_common){
				break;
			}
		}
		
		// 1.2. Suspended Activityの親から共通の祖先まで、両端のアクティビティを含む、順序付き系列のアクティビティパスを作る
		var activity_path_to_common_ancestor = new Array();
		tmp_item = suspended_activity.parentNode;
		while(tmp_item != common_ancestor){
			activity_path_to_common_ancestor.push(tmp_item);
			tmp_item = tmp_item.parentNode;
		}
		activity_path_to_common_ancestor.push(common_ancestor); // 共通の祖先を含む
		if(activity_path_to_common_ancestor.length>0){ // 1.3. アクティビティパスが空でない



			// 1.3.1. アクティビティパスのすべてのアクティビティについて
			for(var ap=0;ap<activity_path_to_common_ancestor.length;ap++){
				// 1.3.1.1. アクティビティが葉(葉ということはないはずだが)
				if(activity_path_to_common_ancestor[ap].getElementsByTagName("item").length==0){
					// 1.3.1.1.1. アクティビティのActivity is SuspendedをFalseに設定



					activity_is_suspended[id(activity_path_to_common_ancestor[ap])]=false;
				} else { // 1.3.1.2. Else
					var child_array=Available_Children(activity_path_to_common_ancestor[ap]); // 直属の子



					var found_suspended_true=false; // 「Activity is SuspendedがTrueの子」が見つかったか
					for(var c=0;c<child_array.length;c++){
						if(activity_is_suspended[id(child_array[c])]==true){
							found_suspended_true = true;			    
						}
					}
					
					// 1.3.1.2.1. アクティビティがActivity is SuspendedがTrueの子を持たない



					if(found_suspended_true==false){
						// 1.3.1.2.1.1. アクティビティのActivity is SuspendedをFalseに設定



						activity_is_suspended[id(activity_path_to_common_ancestor[ap])]=false;
					}
				}
			}
		}
		suspended_activity=undefined; // 1.4. Suspended Activityを未定義に設定



	}
}

function Limit_Condition_Check_Process(item){ // 制限条件チェックプロセス
	// p112-113 アクティビティのいずれかの制限条件が違反されている場合Trueを返す
	return false; // とりあえず常にFalse
}

function Sequencing_Rule_Check_Process(item, ruleActions){ // シーケンシングルールチェックプロセス
	// p114 アクティビティ(item)とルールアクションの集合(ruleActions)を受け取り、



	// Trueと評価された最初のシーケンシングルールのルール動作を帰すか、Nilを返す
	
	// 1.1. アクティビティに対していずれかのルールアクションを有するシーケンシングルールの
	// 集合を、元のルールの順序を保ちながら選択し、ルールリストを初期化



	var ruleList_Array = new Array();
	var sequencingRules = My_getElementsByTagName(item,"imsss:ruleAction");
	for(var a=0;a<ruleActions.length;a++){ // ルールアクションの集合を舐める
		for(var r=0;r<sequencingRules.length;r++){
			if(sequencingRules[r].getAttribute("action")==ruleActions[a] && sequencingRules[r].parentNode.parentNode.parentNode.parentNode==item){
				ruleList_Array.push(sequencingRules[r].parentNode);
			}
		}
	}
	
	if(ruleList_Array.length!=0){
		// 1. アクティビティが指定されたいずれかのルールアクションを持つシーケンシングルールを含むなら



		for(var r=0;r<ruleList_Array.length;r++){ // 1.2. ルールリストの各ルール
			// 1.2.1. アクティビティとルールに対しシーケンシングルールチェックサブプロセスを適用
			if(Sequencing_Rule_Check_Subprocess(item, ruleList_Array[r])==true){
				// 1.2.2. シーケンシングルールチェックサブプロセスがTrueを返すなら



				// Trueと評価される最初のルール(ルール動作)を返す
				return My_getElementsByTagName(ruleList_Array[r],"imsss:ruleAction")[0].getAttribute("action");
			} // End If
		} // End For
	} // End If
	return undefined; // 2. Trueとして評価するルールがない



}

function Sequencing_Rule_Check_Subprocess(item, rule){
	// p115 シーケンシングルールチェックサブプロセス
	// アクティビティ(item)にシーケンシングルール(rule)を適用し、TrueかFalseを返す
	// ルールはpreCondition, postCondition, exitConditionのどれでもよい



	// ルールのオブジェクトさえあればitemは特定できるので、引数itemは実は使っていない



	
	// (番外編)ここでmapInfoを見ておく!
	// targetObjectiveIDで得られる学習目標の値をobjectiveIDの値としてコピー
	var seq=rule.parentNode.parentNode; // "imsss:sequencing"    
	var item_all_objectives = new Array(); // その(ルールがある)アイテムの全ての学習目標



	// 主学習目標は連想配列から取り出す



	item_all_objectives.push(item_primary_objectives[id(item)]);
	// 主でない学習目標も連想配列から読む
	var objs = item_objectives[id(item)];
	if(objs != undefined && objs != null){
		for(var o=0;o<objs.length;o++){
			item_all_objectives.push(objs[o]);
		}
	}
	for(var ob=0;ob<item_all_objectives.length;ob++){ // mapInfoを見に行く
		var maps = My_getElementsByTagName(item_all_objectives[ob],"imsss:mapInfo");
		if(maps!=undefined){  // mapInfoがない場合、My_getElementsByTagNameはundefinedを返してくる
			if(maps.length>0){
				for(var mp=0;mp<maps.length;mp++){
					if(maps[mp].getAttribute("readSatisfiedStatus")=="true"){ // 文字列としての"true"なので注意


						objective_progress_status[id(item)][obj_id(item_all_objectives[ob])]=objective_progress_status_global[obj_id(maps[mp])];
						objective_satisfied_status[id(item)][obj_id(item_all_objectives[ob])]=objective_satisfied_status_global[obj_id(maps[mp])];
					}
					if(maps[mp].getAttribute("readNormalizedMeasure")=="true"){ // 文字列としての"true"なので注意



						objective_measure_status[id(item)][obj_id(item_all_objectives[ob])]=objective_measure_status_global[obj_id(maps[mp])];
						objective_normalized_measure[id(item)][obj_id(item_all_objectives[ob])]=objective_normalized_measure_global[obj_id(maps[mp])];
					}
				}
			}
		}
	}
	var rulesArray = new Array(); // 1. ルール条件集合を空に初期化



	var ruleCondition_array = My_getElementsByTagName(rule,'imsss:ruleCondition');
	for(var i=0;i<ruleCondition_array.length;i++){ // 2. 各Rule Condition
		var eval_result=false; // 評価結果
		// 2.1. ここでトラッキング情報を見て条件を評価する!
		var referencedObjective=ruleCondition_array[i].getAttribute("referencedObjective");
		var condition = ruleCondition_array[i].getAttribute("condition");
		// referencedObjectiveがなかったら主学習目標を使う



		if(referencedObjective==undefined || referencedObjective==null){
			referencedObjective=obj_id(item_primary_objectives[id(item)]);
		}
		if(condition == "satisfied"){
			if(objective_progress_status[id(item)][referencedObjective]==true && objective_satisfied_status[id(item)][referencedObjective]==true){
				eval_result=true;
			}
		} else if(condition == "objectiveStatusKnown"){
			if(objective_progress_status[id(item)][referencedObjective]==true){
				eval_result=true;
			}
		} else if(condition == "objectiveMeasureKnown"){
			if(objective_progress_status[id(item)][referencedObjective]==true && objective_measure_status[id(item)][referencedObjective]==true){
				eval_result=true;
			}
		} else if(condition == "objectiveMeasureGreaterThan"){
		} else if(condition == "objectiveMeasureLessThan"){
		} else if(condition == "completed"){
			if(attempt_progress_status[id(item)]==true && attempt_completion_status[id(item)]==true){
				eval_result=true;
			}
		} else if(condition == "activityProgressKnown"){
			if(activity_progress_status[id(item)]==true && attempt_progress_status[id(item)]==true){
				eval_result=true;
			}	    
		} else if(condition == "attempted"){
			if(activity_progress_status[id(item)]==true && activity_attempt_count[id(item)]>0){
				eval_result=true;
			}	    
		} else if(condition == "attemptLimitExceeded"){
		} else if(condition == "timeLimitExceeded"){
		} else if(condition == "outsideAvailableTimeRange"){
		} else if(condition == "always"){
			eval_result=true;
		}
		if(ruleCondition_array[i].getAttribute("operator")=="not"){ // 2.2. OperatorがNotなら



			eval_result=!(eval_result);   // 2.2.1. Negate ルール条件
		}
		rulesArray.push(eval_result); // 2.3. ルール条件の値をルール条件集合に追加
	} // End For
	
	if(rulesArray.length==0){ // 3. ルール条件集合が空
		return false;         // 3.1. Falseを返して終了



	}
	var ruleConditions = My_getElementsByTagName(rule,'imsss:ruleConditions')[0];
	if(ruleConditions != undefined && ruleConditions != null){
		var conditionCombination = ruleConditions.getAttribute("conditionCombination");
		// 4. Combinationをルール条件集合に適用して、単一のルール評価を得る
		var rules_true=0; // 条件を満たしたルールの数
		for(var r=0;r<rulesArray.length;r++){
			rules_true += rulesArray[r];
		}
		if(conditionCombination == "all"){ // And演算



			if(rules_true == rulesArray.length){
				return true;
			} else {
				return false;
			}
		} else { // Anyか空の時、Or演算



			if(rules_true > 0){
				return true; // 一つでも満たしていたらtrue
			} else {
				return false;// 全部ダメならfalse
			}
		}
	}
	return false; // 万一ruleConditionsがなかったら…(仕様上は、ない場合もありうる)
}

function Terminate_Descendent_Attempts_Process(item){ // 下位試行終了プロセス
	// p116
	// 値を返さない



	// カレントアクティビティと指定されたアクティビティの共通の祖先の下位アクティビティに
	// 試行終了プロセスを適用する
	
	if( current_activity == undefined || current_activity == null || current_activity+"" == "" ){
		return;	
	}
	
	// 1. Current Activityと指定されたアクティビティの共通の祖先を見つける
	var common_ancestor; // 共通の祖先となるアクティビティ
	var found_common=false; // 共通の祖先が見つかったか
	var current_activity_to_root = new Array();
	var tmp_item = current_activity;
	while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
		current_activity_to_root.push(tmp_item);
		tmp_item = tmp_item.parentNode;
	}
	var item_to_root = new Array();
	tmp_item = item;
	while(tmp_item != manifest.getElementsByTagName("organizations")[0]){
		item_to_root.push(tmp_item);
		tmp_item = tmp_item.parentNode;
	}
	for(var c=0;c<current_activity_to_root.length;c++){
		for(var i=0;i<item_to_root.length;i++){
			if(current_activity_to_root[c]==item_to_root[i]){
				common_ancestor=current_activity_to_root[c];
				found_common=true;
				break;
			}
		}
		if(found_common){
			break;
		}
	}
	
	// 2. Current Activityから共通の祖先まで、Current Activityと共通の祖先を除く、順序付き
	// 系列のアクティビティパスを作る
	var activity_path_to_common_ancestor = new Array();
	tmp_item = current_activity;
	while(tmp_item != common_ancestor){
		if(tmp_item != current_activity){
			activity_path_to_common_ancestor.push(tmp_item);
		}
		tmp_item = tmp_item.parentNode;
	}
	if(activity_path_to_common_ancestor.length>0){ // 3. アクティビティパスがNot Emptyなら



		// 3.1. アクティビティパスの各アクティビティに
		for(var ap=0;ap<activity_path_to_common_ancestor.length;ap++){
			// 3.1.1. アクティビティに試行終了プロセスを適用
			End_Attempt_Process(activity_path_to_common_ancestor[ap]);
		}
	}
	
	// 4. 下位試行終了プロセスの終了



	return;
}

function End_Attempt_Process(item){ // 試行終了プロセス
	//p117-118 コンテンツオブジェクトが値を設定しないときに使う値を規定する

	// 値は返さない

	if(item.getElementsByTagName("item").length==0){ // 1. アクティビティが葉なら

		if(tracked[id(item)]==true){ // 1.1. アクティビティのTrackedがTrueなら

			// 1.1.1. アクティビティのActivity is SuspendedがFalseなら

			if(activity_is_suspended[id(item)]==false){
				// 1.1.1.1. アクティビティのCompletion Set by ContentがFalseなら

				if(completion_set_by_content[id(item)]==false){
					// 1.1.1.1.1. アクティビティのAttempt Progress StatusがFalseなら

					if(attempt_progress_status[id(item)]==false){
						// 1.1.1.1.1.1. アクティビティのAttempt Progress StatusをTrueに設定

						attempt_progress_status[id(item)]=true;
						// 1.1.1.1.1.2. アクティビティのAttempt Completion StatusをTrueに設定

						attempt_completion_status[id(item)]=true;
					}
				}
				
				// 1.1.1.2. アクティビティのObjective Set by ContentがFalseなら

				if(objective_set_by_content[id(item)]==false){
					var item_all_objectives = new Array();
					var seq; // "imsss:sequencing"
					var children=item.childNodes;
					for(var c=0;c<children.length;c++){
						if(children[c].nodeName=="imsss:sequencing"){
							seq=children[c];
							break;
						}
					}
					// 主学習目標は連想配列から
					item_all_objectives.push(item_primary_objectives[id(item)]);
					// 主でない学習目標も連想配列から読む
					var objs = item_objectives[id(item)];
					if(objs!=undefined && objs!=null){
						for(var o=0;o<objs.length;o++){
							item_all_objectives.push(objs[o]);
						}
					}
					// 1.1.1.2.1. アクティビティに関する全学習目標について
					for(var ob=0;ob<item_all_objectives.length;ob++){
						// 1.1.1.2.1.1. 学習目標のObjective Contributes to RollupがTrueなら

						if(objective_contributes_to_rollup[id(item)][obj_id(item_all_objectives[ob])]==true){
							// 1.1.1.2.1.1.1. 学習目標のObjective Progress StatusがFalseなら

							if(objective_progress_status[id(item)][obj_id(item_all_objectives[ob])]==false){
								// 1.1.1.2.1.1.1.1. 学習目標のObjective Progress StatusをTrueに設定

								objective_progress_status[id(item)][obj_id(item_all_objectives[ob])]=true;
								// 1.1.1.2.1.1.1.2. 学習目標のObjective Satisfied StatusをTrueに設定

								objective_satisfied_status[id(item)][obj_id(item_all_objectives[ob])]=true;
							}
						}
					}
				}
			}
		}
	} else {
		// 2. Else(アクティビティが葉でない)
		var item_children = Available_Children(item); // 子アクティビティのリスト

		var has_suspended_child = 0; // 「Activity is Suspended属性がTrueの子アクティビティ」の数
		for (var ic=0;ic<item_children.length;ic++){
			if(activity_is_suspended[id(item_children[ic])]==true){
				has_suspended_child++;
			}
		}
		// 2.1. アクティビティが「Activity is Suspended属性がTrueの子アクティビティ」を持つなら

		if(has_suspended_child>0){
			// 2.1.1. アクティビティのActivity is SuspendedをTrueに設定



			activity_is_suspended[id(item)]=true;
		} else { // 2.2. 
			// 2.2.1. アクティビティのActivity is SuspendedをFalseに設定

			activity_is_suspended[id(item)]=false;
		}
	}
	// 3. アクティビティのActivity is ActiveをFalseに設定

	activity_is_active[id(item)]=false;
	
	// 4. 試行終了プロセスの終了

}

function Check_Activity_Process(item){ // チェックアクティビティプロセス
	// p119 アクティビティが無効ないしなんらかの制限条件に反していたらTrueを返す
	// アクティビティが実行できるかどうかを決定する



	
	// 1. アクティビティにDisabledシーケンシングルールでシーケンシングルールチェックプロセスを適用
	// 2. シーケンシングルールチェックプロセスがNilを返さない



	if(Sequencing_Rule_Check_Process(item,new Array("disabled"))!=undefined){
		return true; // 2.1 結果はTrue
	}
	
	// 3. アクティビティに制限条件チェックプロセスを適用
	if(Limit_Condition_Check_Process(item)){// 4. 制限条件チェックプロセスがTrueを返す
		return true; // 4.1. 結果はTrue
	}
	return false;
}

function getFile(URI) {
	uri_base=URI; // この関数がindex.html等から呼ばれる時に、manifestファイルの置場が指定される
	var manifest_uri = uri_base + "imsmanifest.xml?cache="+(new Date()).getTime();
	if(window.XMLHttpRequest){
		xmlhttp = new XMLHttpRequest();
	} else if(window.ActiveXObject){
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	} else {
		xmlhttp = false;
	}
	
	if (xmlhttp) {
		xmlhttp.onreadystatechange = dummy2;
		xmlhttp.open('GET', manifest_uri, true);
		xmlhttp.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
		xmlhttp.send(null);
	}
}

function Available_Children(item){ // Available Childrenリスト(直属の子)を返す
	var children=new Array();
	for(var i=0;i<item.childNodes.length;i++){
		if(item.childNodes.item(i).nodeName=="item"){
			children.push(item.childNodes.item(i));
		}
	}
	return children;
}

function dummy2(){
	if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
		manifest = xmlhttp.responseXML;
		var resources = manifest.getElementsByTagName("resource");
		for(i=0;i<resources.length;i++){
			var resource_id = resources[i].getAttribute("identifier");
			href_hash[resource_id]=resources[i].getAttribute("href");
		}
		items.push(manifest.getElementsByTagName("organization")[0]);
		
		// 2次元配列にするための初期化

		objective_contributes_to_rollup[id(manifest.getElementsByTagName("organization")[0])]=new Array(); 
		objective_progress_status[id(manifest.getElementsByTagName("organization")[0])]=new Array(); 
		objective_satisfied_status[id(manifest.getElementsByTagName("organization")[0])]=new Array(); 
		objective_measure_status[id(manifest.getElementsByTagName("organization")[0])]=new Array(); 
		objective_normalized_measure[id(manifest.getElementsByTagName("organization")[0])]=new Array();
		var tmp_items=manifest.getElementsByTagName('item');
		for(var i=0;i<tmp_items.length;i++){
			items.push(tmp_items[i]); 
			// 2次元配列にするための初期化

			objective_contributes_to_rollup[id(tmp_items[i])]=new Array(); 
			objective_progress_status[id(tmp_items[i])]=new Array(); 
			objective_satisfied_status[id(tmp_items[i])]=new Array();  
			objective_measure_status[id(tmp_items[i])]=new Array(); 
			objective_normalized_measure[id(tmp_items[i])]=new Array(); 
		}
		
		//Flashに読み込み完了を通知する
		FlashApi2004_DoFSCommand("getFileResult","DummyArg");
	}
}

function My_getElementsByTagName(obj,tagname){
	if( obj != undefined && obj != null ){
		var e = obj.getElementsByTagName( tagname );	// Firefox3対応コード

		if( e.length == 0 ){							// Firefox3対応コード

			tagname = tagname.split( ":" )[1];			// Firefox3対応コード

			e = obj.getElementsByTagName( tagname );	// Firefox3対応コード

		}												// Firefox3対応コード

		
		if(e!=undefined && e!=null){
			return e;
		} else {
			return undefined;
		}
	} else {
		return undefined;
	}
}

function My_Join_Attribute(arr,del){
	if(arr.length>0){
		var str=arr[0].getAttribute("identifier");
		for(var a=1;a<arr.length;a++){
			str=str+del+arr[a].getAttribute("identifier");
		}
		return str;
	} else {
		return "";
	}
}

function My_Rollup_Objective(item){ // ロールアップされる学習目標を返す
	var children=item.childNodes;
	var target_objective=item_primary_objectives[id(item)]; // primaryObjectiveが主学習目標



	return target_objective;
}

function My_Control_Mode(item,mode){
	var children=item.childNodes;
	var cm=undefined; // controlMode
	for(var c=0;c<children.length;c++){
		if(children[c].nodeName=="imsss:sequencing"){
			cm=My_getElementsByTagName(children[c],"imsss:controlMode"); // 0〜1回

			break;
		}
	}
	if(cm==undefined||cm==null){ // sequencing要素自体がない場合には
		return undefined;
	}
	var attr=undefined;
	var get_attr;
	var attr_default=true;
	if(cm[0]!=undefined && cm[0]!=null){ // コントロールモード要素が(1回)存在する
		get_attr=cm[0].getAttribute(mode);
		if(get_attr!=undefined && get_attr!=null){ // modeで指定された属性が存在する
			attr_default=false;
		}
	}
	if(attr_default==true){ // デフォルトの属性を使う

		if(mode=="choice"){
			attr=true;
		} else if(mode=="choiceExit"){
			attr=true;
		} else if(mode=="flow"){
			attr=false;
		} else if(mode=="forwardOnly"){
			attr=false;
		} else if(mode=="useCurrentAttemptObjectiveInfo"){
			attr=true;
		} else if(mode=="useCurrentAttemptProgressInfo"){
			attr=true;
		}
	} else {
		if(get_attr=="true"){// 属性はXML中で指定されたもの
			attr=true; 
		} else if(get_attr=="false"){
			attr=false;
		}
	}
	return attr;
}

// itemを受け取りidentifierを返す。identifierをキーに取る連想配列と組み合わせて使う



function id(item){
	if(item!=null && item!=undefined && item+"" !=""){
		return item.getAttribute("identifier");
	} else {
		return;
	}
}

// itemを受け取りidentifierrefを返す。



function idref(item){
	if(item!=null && item!=undefined){
		return item.getAttribute("identifierref");
	} else {
		return;
	}
}

// itemを受け取り直下のtitleを返す。



function title(item){
	if(item!=null && item!=undefined && item+""!=""){
		var children=item.childNodes;
		var title_node=undefined;
		var val;
		for(var c=0;c<children.length;c++){
			if(children[c].nodeName=="title"){
				title_node=children[c];
				break;
			}
		}
		val=title_node.childNodes[0].nodeValue;
		return val;
	} else {
		return "";
	}
}

// 学習目標を受け取りobjectiveIDを返す。mapInfoにも対応。objectiveIDをキーに取る連想配列と組み合わせて使う



function obj_id(obj){
	if(obj!=null && obj!=undefined){
		if(obj.nodeName=="imsss:mapInfo"){ // mapInfoの時



			return obj.getAttribute("targetObjectiveID"); 
		} else {                             // 通常のobjectiveやPrimaryObjectiveの時



			var attr = obj.getAttribute("objectiveID");	    
			if(attr==null || attr==undefined){ // objectiveIDがない場合



				attr = My_generate_id(obj.parentNode.parentNode.parentNode);
			}
			return attr;
		}
	} else {
		return;
	}
}

function Initialize_Models(){ // トラッキング情報モデル、シーケンシング定義モデル初期化

	for(var it=0;it<items.length;it++){
		var children=items[it].childNodes;
		var seq=undefined; // "imsss:sequencing"
		for(var c=0;c<children.length;c++){
			if(children[c].nodeName=="imsss:sequencing"){
				seq=children[c];
				break;
			}
		}
		item_interactions[id(items[it])]=new Array();
		
		// デフォルト値を入れておく
		tracked[id(items[it])]=true;                // SM.11. 
		completion_set_by_content[id(items[it])]=false;  // SM.11
		objective_set_by_content[id(items[it])]=false ;  // SM.11
		rollup_objective_satisfied[id(items[it])]=true ; // SM.8
		rollup_progress_completion[id(items[it])]=true ; // SM.8
		rollup_objective_measure_weight[id(items[it])]=1;// SM.8

		// primaryでないobjectiveがあったらObjective Contributes to Rollupをfalseにして使う

		var obj = My_getElementsByTagName(seq,"imsss:objective");
		if(obj != undefined && obj != null){
			item_objectives[id(items[it])]=new Array();
			for(var o=0;o<obj.length;o++){
				objective_contributes_to_rollup[id(items[it])][obj_id(obj[o])]=false;
				item_objectives[id(items[it])].push(obj[o]);
			}
		}
		
		// primaryObjectiveがあったらObjective Contributes to Rollupをtrueにする
		var pobj = My_getElementsByTagName(seq,"imsss:primaryObjective");
		if(pobj != undefined && pobj != null){
			if(pobj[0] != undefined && pobj[0] != null){
				objective_contributes_to_rollup[id(items[it])][obj_id(pobj[0])]=true;
				item_primary_objectives[id(items[it])]=pobj[0];
				var MyObj = My_getElementsByTagName(seq,"imsss:minNormalizedMeasure")[0];
				if(MyObj != undefined && MyObj != null){
					minNormalizedMeasure[id(items[it])] = MyObj.childNodes[0].nodeValue - 0;
				} else {
					minNormalizedMeasure[id(items[it])] = null;
				}
			} else {
				// primaryObjectiveがなかったら新たに定義し、

				// Objective Contributes to Rollupをtrueにする(SM.6)
				var new_id = My_generate_id(items[it]);
				var o=new My_obj(items[it],new_id);
				item_primary_objectives[id(items[it])]=o;
				objective_contributes_to_rollup[id(items[it])][obj_id(o)]=true;
			}
		}
		
		// manifestファイル中で定義されていたらそれを入れる
		var r_rules=My_getElementsByTagName(seq,"imsss:rollupRules");
		if(r_rules !=undefined && r_rules != null){
			if(r_rules.length==1){
				var rollupObjectiveSatisfied_tmp = r_rules[0].getAttribute("rollupObjectiveSatisfied");
				var rollupProgressCompletion_tmp = r_rules[0].getAttribute("rollupProgressCompletion");
				var objectiveMeasureWeight_tmp = r_rules[0].getAttribute("objectiveMeasureWeight")-0;
				// 値が入っていたらそれらを使う。trueやfalseは文字列であることに注意



				if(rollupObjectiveSatisfied_tmp == "true"){
					rollup_objective_satisfied[id(items[it])]=true ;
				} else if(rollupObjectiveSatisfied_tmp == "false"){
					rollup_objective_satisfied[id(items[it])]=false ;
				}
				if(rollupProgressCompletion_tmp == "true"){
					rollup_progress_completion[id(items[it])]=true;
				} else if(rollupProgressCompletion_tmp == "false"){
					rollup_progress_completion[id(items[it])]=false;
				}
				if(objectiveMeasureWeight_tmp!=undefined && objectiveMeasureWeight_tmp!=null){
					rollup_objective_measure_weight[id(items[it])]=objectiveMeasureWeight_tmp;
				}
			}
		}
		
		var d_controls=My_getElementsByTagName(seq,"imsss:deliveryControls");
		if(d_controls !=undefined && d_controls != null){
			if(d_controls.length==1){
				var tracked_tmp = d_controls[0].getAttribute("tracked");
				var completion_set_by_content_tmp = d_controls[0].getAttribute("completionSetByContent");
				var objective_set_by_content_tmp = d_controls[0].getAttribute("objectiveSetByContent");
				// 値が入っていたらそれらを使う。trueやfalseは文字列であることに注意



				if(tracked_tmp == "true"){
					tracked[id(items[it])]=true;
				} else if(tracked_tmp == "false"){
					tracked[id(items[it])]=false;
				}
				if(completion_set_by_content_tmp == "true"){
					completion_set_by_content[id(items[it])]=true;
				} else if(completion_set_by_content_tmp == "false"){
				completion_set_by_content[id(items[it])]=false;
			}
			if(objective_set_by_content_tmp == "true"){
				objective_set_by_content[id(items[it])]=true;
			} else if(objective_set_by_content_tmp == "false"){
				objective_set_by_content[id(items[it])]=false;
			}
		}
	}
	activity_attempt_count[id(items[it])]=0;    // TM.1.2.1. 
	activity_is_suspended[id(items[it])]=false; // AM.1.1.
	activity_is_active[id(items[it])]=false;    // AM.1.1.
	item_from_id[id(items[it])]=items[it]; // IDからitemそのものを引けるようにしておく
	}
}

function Navigation_Command_From_SCO(param){ // SCOからのナビゲーションコマンドの発行

	FlashApi2004_DoFSCommand("setNavigationRequestToFlash", param);
}

function My_getAttribute(str){ // (manifest中で未定義の時に)新たに定義した学習目標のためのgetAttribute
	if(str=="objectiveID"){
		return this.new_id;
	} else if(str=="satisfiedByMeasure"){
		return false;
	} else if(str=="minNormalizedMeasure"){
		return 1;
	}
}

// primaryObjectiveのIDが省略されている場合、またはprimaryObjective自体がない場合に
// primaryObjectiveのIDを生成する関数
function My_generate_id(item){ 
	var objs = item_objectives[id(item)]; // primaryでないObjectiveの一覧を取る



	var pobj_id = "p_" + id(item);
	var found=0;
	while(true){
		for(var o=0;o<objs.length;o++){
			if(obj_id(objs[o])==pobj_id){
				found=1;
			}
		}
		if(found==1){
			found=0;
			pobj_id = "p_"+pobj_id;
		} else {
			break;
		}
	}
	return pobj_id;
}

function My_obj(item,new_id){ // (manifest中で未定義の時に)新たに定義する学習目標



	this.pobj=item_primary_objectives[id(item)];
	this.new_id=new_id;
	this.getAttribute=My_getAttribute;
	this.getElementsByTagName=function(){ return undefined; };
}

function my_continue(){
	Overall_Sequencing_Process("continue","");
}

function my_continue_or_not(){ // Continue可能かどうかを返す。GUIボタンの表示部分で使う。



	// Continueシーケンシング要求プロセスが返す配信要求がn/aである
	var cs_result=GUI_Continue_Sequencing_Request_Process();
	if(cs_result==undefined){
		return false;
	} else { // hideLMSUIをチェック
		var hide_buttons=My_getElementsByTagName(current_activity,'adlnav:hideLMSUI');
		var hide_found=false;
		if(hide_buttons!=undefined){
			for(var hb=0;hb<hide_buttons.length;hb++){
				if(hide_buttons[hb].childNodes[0].nodeValue=="continue"){
					hide_found=true;
					break;
				}
			}
		}
		if(hide_found==false){
			return true;
		} else {
			return false;
		}
	}
}

function my_previous(){
	Overall_Sequencing_Process("previous","");
}

function my_previous_or_not(){ // Previous可能かどうかを返す。GUIボタンの表示部分で使う。



	// Previousシーケンシング要求プロセスが返す配信要求がn/aである
	var ps_result=GUI_Previous_Sequencing_Request_Process();
	if(ps_result==undefined){
		return false;
	} else { // hideLMSUIをチェック
		var hide_buttons=My_getElementsByTagName(current_activity,'adlnav:hideLMSUI');
		var hide_found=false;
		if(hide_buttons!=undefined){
			for(var hb=0;hb<hide_buttons.length;hb++){
				if(hide_buttons[hb].childNodes[0].nodeValue=="previous"){
					hide_found=true;
					break;
				}
			}
		}
		if(hide_found==false){
			return true;
		} else {
			return false;
		}
	}
}

function my_exit_or_not(){ // exit(とexitAll)ボタンを表示するかどうかを返す
	var hide_buttons=My_getElementsByTagName(parent.current_activity,'adlnav:hideLMSUI');
	var hide_found=false;
	if(hide_buttons!=undefined){
		for(var hb=0;hb<hide_buttons.length;hb++){
			if(hide_buttons[hb].childNodes[0].nodeValue=="exit"){
				hide_found=true;
				break;
			}
		}
	}
	if(hide_found==false){
		return true;
	} else {
		return false;
	}
}

function my_abandon_or_not(){ // abandonボタンを表示するかどうかを返す
	var hide_buttons=My_getElementsByTagName(parent.current_activity,'adlnav:hideLMSUI');
	var hide_found=false;
	if(hide_buttons!=undefined){
		for(var hb=0;hb<hide_buttons.length;hb++){
			if(hide_buttons[hb].childNodes[0].nodeValue=="abandon"){
				hide_found=true;
				break;
			}
		}
	}
	if(hide_found==false){
		return true;
	} else {
		return false;
	}
}

function my_suspendAll(){
	var exit_return = Overall_Sequencing_Process("suspendAll","");
	if(exit_return == false){
		sco_window.close();
	}
}

function make_suspend_vals(){
	var json_data = new Array(); // JSONテキストを作るための連想配列
	json_data["current_activity"]=undefined;
	json_data["suspended_activity"]=id(suspended_activity); // idを取ることに注意

	json_data["err_code"]=err_code;
	json_data["tracked"]=tracked;
	json_data["activity_is_suspended"]=activity_is_suspended;
	json_data["completion_set_by_content"]=completion_set_by_content;
	json_data["activity_progress_status"]=activity_progress_status;
	json_data["attempt_progress_status"]=attempt_progress_status;
	json_data["attempt_completion_status"]=attempt_completion_status;
	json_data["attempt_completion_amount"]=attempt_completion_amount;
	json_data["attempt_absolute_duration"]=attempt_absolute_duration;
	json_data["attempt_experienced_duration"]=attempt_experienced_duration;
	json_data["objective_set_by_content"]=objective_set_by_content;
	json_data["activity_is_active"]=activity_is_active;
	json_data["activity_attempt_count"]=activity_attempt_count;
	json_data["rollup_objective_satisfied"]=rollup_objective_satisfied;
	json_data["rollup_progress_completion"]=rollup_progress_completion;
	json_data["rollup_objective_measure_weight"]=rollup_objective_measure_weight;
	json_data["objective_contributes_to_rollup"]=objective_contributes_to_rollup;
	json_data["objective_progress_status"]=objective_progress_status;
	json_data["objective_satisfied_status"]=objective_satisfied_status;
	json_data["objective_measure_status"]=objective_measure_status;
	json_data["objective_normalized_measure"]=objective_normalized_measure;
	
	// グローバル共有学習目標を扱うための連想配列
	json_data["objective_progress_status_global"]=objective_progress_status_global;
	json_data["objective_satisfied_status_global"]=objective_satisfied_status_global;
	json_data["objective_measure_status_global"]=objective_measure_status_global;
	json_data["objective_normalized_measure_global"]=objective_normalized_measure_global;
	
	//jsonにcomments_from_learnerも追加
	json_data["cmi.comments_from_learner"] = cmi_datamodel["cmi.comments_from_learner"];
	
	return json_data;
}

function makeJSON(hash){
	var init = true;
	var str = '{';
	for(var i in hash){
		if(!init) str += ',';
		str += '"' + i.replace('"', '\\"', 'g') + '":';
		switch(typeof hash[i]){
		case 'object':
			str += makeJSON(hash[i]);
			break;
		case 'function':
			str += hash[i].toString();
			break;
		default:
			if(isString(hash[i])){
				str += '"' + hash[i].toString().replace('"', '\\"', 'g') + '"';
			} else {
				str += hash[i];
			}
		}
		init = false;
	}
	str += '}';
	return str;
}

function suspend_resume_data( callback , data , method , fileURL , async ){
	//送信データをエンコード

	var encdata = encodeURI( data );
	//送信
	requestFile( callback , encdata , method , fileURL , async );
}

function onload_suspend(oj){
	//受信データをデコード

	var decdata = decodeURI( oj.responseText );
}

function onload_resume(oj){
	//受信データをデコード

	var decdata = decodeURI( oj.responseText );
	if(decdata==""){
		decdata='{"current_activity":undefined}';
	}
	//受信データをJavaScriptとして実行(JSON化)
	var json_data=eval('('+decdata+')');
	for (var i in json_data){
		// (内側の)連想配列から一つずつ中身を取り出す

		if( i != "cmi.comments_from_learner" && i != "cmi.score" && i != "cmi.location" ){
			eval(i + "=json_data"+'["' + i + '"]'); // iには元のJavaScriptの変数名が入る

		}
	}
	current_activity = item_from_id[current_activity];
	suspended_activity = item_from_id[suspended_activity];
	choiced_activity = item_from_id[choiced_activity];
	
	//jsonに格納していたcmi.comments_from_learnerを取り出す

	cmi_datamodel["cmi.comments_from_learner"] = json_data["cmi.comments_from_learner"];
}

function createHttpRequest(){
	if(window.ActiveXObject){
		try{
			return new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try{
				return new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e2) {
				return null;
			}
		}
	} else if(window.XMLHttpRequest){
		return new XMLHttpRequest();
	} else {
		return null;
	}
}

function requestFile( callback , data , method , fileURL , async ){
	var oj = createHttpRequest();
	if( oj == null ){
		return null;
	}
	var ua = navigator.userAgent;
	var safari= ua.indexOf("Safari")!=-1;
	var konqueror = ua.indexOf("Konqueror")!=-1;
	var mozes = ((a=navigator.userAgent.split("Gecko/")[1] )?a.split(" ")[0]:0) >= 20011128 ;
	if(window.opera || safari || mozes){
		oj.onload = function (){
			callback(oj)
		}
	} else {
		oj.onreadystatechange =function(){
			if ( oj.readyState == 4 && oj.status==200){
				callback(oj)
			}
		}
	}
	oj.open( method , fileURL , async );
	if(method == 'POST'){
		if(!window.opera){
			oj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
		}
	}
	oj.send(data);
}

function isString(obj){
	if (obj == null){
		return false;
	}
	return (typeof(obj) == "string" || obj instanceof String);
}

function my_exitAll(){
	var exit_return = Overall_Sequencing_Process("exitAll","");
	if(exit_return == false){
		sco_window.contentFrame.location.href=exit_page;
		sco_window.close();
	}
}

function my_exit(){
	var exit_return = Overall_Sequencing_Process("exit","");
	if(exit_return == false){
		sco_window.contentFrame.location.hrer=exit_page;
		sco_window.close();
	}
}

function my_abandonAll(){
	var exit_return = Overall_Sequencing_Process("abandonAll","");
	if(exit_return == false){
		//
	}
}

function my_choice_internal(item_id){
	var item=item_from_id[item_id];
	Overall_Sequencing_Process("choice",item);
}

function my_choice(item_id, manifest_url){
	choiced_activity=item_from_id[item_id];
	my_choice_internal(item_id);
}

function my_choice_or_not(item_id,manifest_url){ // Choice可能かどうかを返す。

	var item=item_from_id[item_id];    
	// Choiceシーケンシング要求プロセスがcurrent_activityを変えることがあるので元の状態を取っておく
	var current_activity_org = current_activity; 
	// Choiceシーケンシング要求プロセスが返す配信要求がn/aである
	if(Choice_Sequencing_Request_Process(item)+""==""){
		current_activity=current_activity_org; // current_activityが変わったかもしれないので元に戻す

		return false;
	} else {
		current_activity=current_activity_org; // current_activityが変わったかもしれないので元に戻す

		return true;
	}
}

function my_toc(){ // 目次ウィンドウを出す

	toc_win=window.open("toc_dummy.html","toc","toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=300,height=300");
	my_toc_update(id(current_activity));
}

function my_toc_update(){ // 目次ページを更新する
	var str=my_toc_tree();
	content.document.open();
	content.document.writeln("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
	content.document.writeln("<script type=\"text/javascript\" src=\"skelton_org.js\"></script>");
	content.document.writeln("<script type=\"text/javascript\"></script><title>Haribote LMS</title></head>");
	content.document.writeln("<body>"+str+"</body></html>");
	content.document.close();
}

function my_toc_tree(){ // 目次ページの表示内容を作る
	var item=manifest.getElementsByTagName("organization")[0];    
	var str=my_toc_tree_recurse(item,id(item));    
	return str;
}

function my_toc_tree_recurse(item){ // 目次ページのために再帰的にツリーを辿る

	var children=item.childNodes;
	var str=title(item);
	var substr=str;
	var item_found=0;
	for(var c=0;c<children.length;c++){
		if(children[c].nodeName=="item"){
			var mark_str=""; // 目次中の現在位置を示す印
			var list_item_str;
			if(item_found==0){
				substr+="<ul>";
			}
			if(id(children[c]) == id(current_activity)){
				mark_str = '&#8658; ';
			}
			
			// Choice可能かどうか
			if(my_choice_or_not(id(children[c]),"")==false){
				list_item_str = "<li>"+mark_str+my_toc_tree_recurse(children[c])+"</li>";
			} else {
				list_item_str = "<li><a href=javascript:my_choice("+'\"'+id(children[c])+'\"'+',\"\"'+")>"+mark_str+my_toc_tree_recurse(children[c])+"</a></li>";
			}
			substr=substr+list_item_str;
			item_found++;
		}
	}
	if(item_found!=0){
		substr+="</ul>";
	}
	if(substr!=str){
		str = substr;
	}
	return str;
}

var cmi_datamodel=new Array();
function CMI_SetValue(iModel,iParam){
	if(iModel=="cmi.version"){ // 4.2.1. ヴァージョン
		err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
		return "";
    } else if(iModel.match(/^cmi\.comments_from_learner/)){ // 4.2.2. 学習者からのコメント

		var splitted = iModel.split(".");
		if(cmi_datamodel["cmi.comments_from_learner"]==undefined){
			cmi_datamodel["cmi.comments_from_learner"]=new Array();
		}
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2]=="_count"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2].match(/^\d+$/)){	
			var num=splitted[2]-0;
			if(cmi_datamodel["cmi.comments_from_learner"][num]==undefined){
				cmi_datamodel["cmi.comments_from_learner"][num]=new Array();
			}
			if(splitted.length >= 4 && splitted[3]=="comment"){
				//改行削除
				iParam = DeleteLineFeed(iParam);								
				cmi_datamodel["cmi.comments_from_learner"][num]["comment"]=iParam;
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="location"){
				cmi_datamodel["cmi.comments_from_learner"][num]["location"]=iParam;
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="timestamp"){
				cmi_datamodel["cmi.comments_from_learner"][num]["timestamp"]=iParam;
				err_code=0;
				return "true";
			} else {
				err_code=401;
				return "false";
			}
		} else {
			err_code=401; // 3.1.7.5.1. Undefined Data Model Element
			return "false";
		}
	} else if(iModel.match(/^cmi\.comments_from_lms/)){ // 4.2.3. LMSからのコメント

		var splitted = iModel.split(".");
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2]=="_count"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2].match(/^\d+$/)){	
			var num=splitted[2]-0;
			if(splitted.length >= 4 && splitted[3]=="comment"){
				err_code=404;
				return "false";
			} else if(splitted.length >= 4 && splitted[3]=="location"){
				err_code=404;
				return "false";
			} else if(splitted.length >= 4 && splitted[3]=="timestamp"){
				err_code=404;
				return "false";
			} else {
				err_code=401;
				return "false";
			}
		} else {
			err_code=401; // 3.1.7.5.1. Undefined Data Model Element
			return "false";
		}
	} else if(iModel=="cmi.completion_status"){ // 4.2.4. 完了状態

		if(iParam == "completed"){
			attempt_progress_status[id(current_activity)]=true;
			attempt_completion_status[id(current_activity)]=true;
			err_code=0;
			return "true";
		} else if(iParam == "incomplete"){
			attempt_progress_status[id(current_activity)]=true;
			attempt_completion_status[id(current_activity)]=false;
			err_code=0;
			return "true";
		} else if(iParam == "not attempted"){
			attempt_progress_status[id(current_activity)]=true;
			attempt_completion_status[id(current_activity)]=false;
			activity_attempt_count[id(current_activity)]=0;
			err_code=0;
			return "true";
		} else if(iParam == "unknown"){
			attempt_progress_status[id(current_activity)]=false;
			attempt_completion_status[id(current_activity)]=false;
			err_code=0;
			return "true";
		} else {
			err_code=406;
			return "false";
		}
	} else if(iModel=="completion_threshold"){ // 4.2.5. 完了状態の閾値
		err_code=404;
		return "false";
	} else if(iModel=="cmi.credit"){ // 4.2.6. 評価
		err_code=404;
		return "false";
	} else if(iModel=="cmi.entry"){ // 4.2.7. エントリ
		err_code=404;
		return "false";
	} else if(iModel=="cmi.exit"){ // 4.2.8. 退出
		if(iParam == "time-out"){
			cmi_datamodel[iModel]=iParam;	    
			err_code=0;
			return "true";
		} else if(iParam == "suspend"){
			cmi_datamodel[iModel]=iParam;	    
			err_code=0;
			return "true";
		} else if(iParam == "logout"){
			cmi_datamodel[iModel]=iParam;	    
			err_code=0;
			return "true";
		} else if(iParam == "normal"){
			cmi_datamodel[iModel]=iParam;
			err_code=0;
			return "true";
		} else if(iParam == ""){
			cmi_datamodel[iModel]=iParam;
			err_code=0;
			return "true";
		} else {
			err_code=406;
			return "false";
		}
	} else if(iModel.match(/^cmi\.interactions/)){ // 4.2.9. インタラクション
		var splitted = iModel.split(".");
		if(cmi_datamodel["cmi.interactions"]==undefined){
			cmi_datamodel["cmi.interactions"]=new Array();
		}
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2]=="_count"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2].match(/^\d+$/)){	
			var num=splitted[2]-0;
			if(cmi_datamodel["cmi.interactions"][num]==undefined){
				cmi_datamodel["cmi.interactions"][num]=new Array();
			}
			if(splitted.length >= 4 && splitted[3]=="id"){
				cmi_datamodel["cmi.interactions"][num]["id"]=iParam;		
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="type"){
				if(iParam == "true-false" || iParam == "choice" || iParam == "fill-in"||
				   iParam == "long-fill-in" ||iParam == "likert"||iParam == "matching"||
				   iParam == "performance" || iParam == "sequencing"||iParam == "numeric"||
				   iParam == "other"){
					err_code=0;
					cmi_datamodel["cmi.interactions"][num]["type"]=iParam;
					return "true";
				} else {
					err_code=406;
					return "false";
				}
			} else if(splitted.length >= 4 && splitted[3]=="objectives"){
				if(splitted.length >= 5 && splitted[4]=="_count"){
					err_code=404;
					return "false";
				} else if(splitted.length >= 5 && splitted[4].match(/^\d+$/)){
					var num2=splitted[4]-0;
					if(cmi_datamodel["cmi.interactions"][num]["objectives"]==undefined){
						cmi_datamodel["cmi.interactions"][num]["objectives"]=new Array();
					}
					if(cmi_datamodel["cmi.interactions"][num]["objectives"][num2]==undefined){
						cmi_datamodel["cmi.interactions"][num]["objectives"][num2]=new Array();
					}
					if(splitted.length >= 6 && splitted[5]=="id"){
						cmi_datamodel["cmi.interactions"][num]["objectives"][num2]["id"]=iParam;
						err_code=0;
						return "true";
					}
				} else {
					err_code=401;
					return "";
				}
			} else if(splitted.length >= 4 && splitted[3]=="timestamp"){
				cmi_datamodel["cmi.interactions"][num]["timestamp"]=iParam;		
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="correct_response"){
				if(splitted[4]=="_count"){
					err_code=404;
					return "false";
				} else if(splitted.length >= 5 && splitted[4].match(/^\d+$/)){
					var num2=splitted[4]-0;
					if(cmi_datamodel["cmi.interactions"][num]["objectives"]==undefined){
						cmi_datamodel["cmi.interactions"][num]["objectives"]=new Array();
					}
					if(cmi_datamodel["cmi.interactions"][num]["objectives"][num2]==undefined){
						cmi_datamodel["cmi.interactions"][num]["objectives"][num2]=new Array();
					}
					if(splitted.length >= 6 && splitted[5]=="pattern"){
						if(cmi_datamodel["cmi.interactions"][num]["id"]==undefined || 
						   cmi_datamodel["cmi.interactions"][num]["type"]==undefined){
							err_code=408;
							return "false";
						}
						cmi_datamodel["cmi.interactions"][num]["objectives"][num2]["pattern"]=iParam;
						err_code=0;
						return "true";
					} else {
						err_code=401;
						return "false";
					}
				}
			} else if(splitted.length >= 4 && splitted[3]=="weighting"){
				cmi_datamodel["cmi.interactions"][num]["weighing"]=iParam;
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="learner_response"){
				cmi_datamodel["cmi.interactions"][num]["learner_response"]=iParam;
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="result"){
				cmi_datamodel["cmi.interactions"][num]["result"]=iParam;
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="latency"){
				cmi_datamodel["cmi.interactions"][num]["result"]=iParam;
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="description"){
				cmi_datamodel["cmi.interactions"][num]["result"]=iParam;
				err_code=0;
				return "true";
			} else {
				err_code=401;
				return "false";
			}
		} else {
			err_code=401; // 3.1.7.5.1. Undefined Data Model Element
			return "";
		}
	} else if(iModel=="cmi.launch_data"){ // 4.2.10. 起動データ
		err_code=404;
		return "false";
	} else if(iModel=="cmi.leaner_id"){ // 4.2.11. 学習者ID
		err_code=404;
		return "false";
	} else if(iModel=="cmi.learner_name"){ // 4.2.12. 学習者名
		err_code=404;
		return "false";
	} else if(iModel.match(/^cmi\.leaner\.preference/)){ // 4.2.13. 学習者のプリファレンス
		var splitted = iModel.split(".");
		if(cmi_datamodel["cmi.learner_preference"]==undefined){
			cmi_datamodel["cmi.learner_preference"]=new Array();
		}
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2]=="audio_level"){
			cmi_datamodel["cmi.learner_preference"]["audio_level"]=iParam;
			err_code=0;
			return "true";
		} else if(splitted.length >= 3 && splitted[2]=="language"){
			cmi_datamodel["cmi.learner_preference"]["language"]=iParam;
			err_code=0;
			return "true";
		} else if(splitted.length >= 3 && splitted[2]=="delivery_speed"){
			cmi_datamodel["cmi.learner_preference"]["delivery_speed"]=iParam;
			err_code=0;
			return "true";
		} else if(splitted.length >= 3 && splitted[2]=="audio_captioning"){
			cmi_datamodel["cmi.learner_preference"]["audio_captioning"]=iParam;
			err_code=0;
			return "true";
		} else {
			err_code=401;
			return "false";
		}
	} else if(iModel=="cmi.location"){ // 4.2.14. ロケーション
		cmi_datamodel["cmi.location"]=iParam;
		err_code=0;
		return "true";
	} else if(iModel=="cmi.max_time_allowed"){ // 4.2.15. 最大許容時間
		err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
		return "false";
	} else if(iModel=="cmi.mode"){ // 4.2.16. 動作モード

		err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
		return "false";
	} else if(iModel.match(/^cmi\.objectives/)){ // 4.2.17. 学習目標

		var splitted = iModel.split(".");
		if(cmi_datamodel["cmi.objectives"]==undefined){
			cmi_datamodel["cmi.objectives"]=new Array();
		}
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2]=="_count"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2].match(/^\d+$/)){
			var num=splitted[2]-0;
			if(cmi_datamodel["cmi.objectives"][num]==undefined){
				cmi_datamodel["cmi.objectives"][num]=new Array();
			}
			if(splitted.length >= 4 && splitted[3]=="id"){
				cmi_datamodel["cmi.objectives"][num]["id"]=iParam;		
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="score"){
				if(cmi_datamodel["cmi.objectives"][num]["score"]==undefined){
					cmi_datamodel["cmi.objectives"][num]["score"]=new Array();
				}
				if(splitted.length >= 5 && splitted[4]=="_children"){
					err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
					return "false";
				} else if(splitted.length >= 5 && splitted[4]=="scaled"){
					cmi_datamodel["cmi.objectives"][num]["score"]["scaled"]=iParam;		
					err_code=0;
					return "true";
				} else if(splitted.length >= 5 && splitted[4]=="raw"){
					cmi_datamodel["cmi.objectives"][num]["score"]["raw"]=iParam;
					err_code=0;
					return "true";
				} else if(splitted.length >= 5 && splitted[4]=="min"){
					cmi_datamodel["cmi.objectives"][num]["score"]["min"]=iParam;		
					err_code=0;
					return "true";
				} else if(splitted.length >= 5 && splitted[4]=="max"){
					cmi_datamodel["cmi.objectives"][num]["score"]["max"]=iParam;
					err_code=0;
					return "true";
				} else {
					err_code=401;
					return "false";
				}
			} else if(splitted.length >= 4 && splitted[3]=="success_status"){
				var pobj = item_primary_objectives[id(current_activity)];
				var objs = item_objectives[id(current_activity)];
				if(num==0){
					if(iParam == "passed"){
						objective_progress_status[id(current_activity)][obj_id(pobj)] = true;
						objective_satisfied_status[id(current_activity)][obj_id(pobj)] = true;
						err_code=0;
						return "true";
					} else if(iParam == "failed"){
						objective_progress_status[id(current_activity)][obj_id(pobj)] = true; 
						objective_satisfied_status[id(current_activity)][obj_id(pobj)] = false; 
						err_code=0;
						return "true";
					} else if(iParam == "unknown"){
						objective_progress_status[id(current_activity)][obj_id(pobj)] = false; 
						objective_satisfied_status[id(current_activity)][obj_id(pobj)] = false; 
						err_code=0;
						return "true";
					} else {
						err_code=406;
						return "false";
					}
				} else {
					if(iParam == "passed"){
						objective_progress_status[id(current_activity)][obj_id(objs[num-1])] = true; 
						objective_satisfied_status[id(current_activity)][obj_id(objs[num-1])] = true; 
						err_code=0;
						return "true";
					} else if(iParam == "failed"){
						objective_progress_status[id(current_activity)][obj_id(objs[num-1])] = true; 
						objective_satisfied_status[id(current_activity)][obj_id(objs[num-1])] = false; 
						err_code=0;
						return "true";
					} else if(iParam == "unknown"){
						objective_progress_status[id(current_activity)][obj_id(objs[num-1])] = false; 
						objective_satisfied_status[id(current_activity)][obj_id(objs[num-1])] = false; 
						err_code=0;
						return "true";
					} else {
						err_code=406;
						return "false";
					}
				}
			} else if(splitted.length >= 4 && splitted[3]=="completion_status"){
				cmi_datamodel["cmi.objectives"][num]["completion_status"]=iParam;		
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="progress_measure"){
				cmi_datamodel["cmi.objectives"][num]["progress_measure"]=iParam;		
				err_code=0;
				return "true";
			} else if(splitted.length >= 4 && splitted[3]=="description"){
				cmi_datamodel["cmi.objectives"][num]["description"]=iParam;	
				err_code=0;
				return "true";
			} else {
				err_code=401;
				return "false";
			}
		} else {
			err_code=401;
			return "false";
		}
	} else if(iModel=="cmi.progress_measure"){ // 4.2.18. 進捗測定

		cmi_datamodel["cmi.progress_measure"]=iParam;
		err_code=0;
		return "true";
	} else if(iModel=="cmi.scaled_passing_score"){ // 4.2.19. 合格点(正規化表現)
		err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
		return "false";
	} else if(iModel.match(/^cmi\.score/)){ // 4.2.20. 得点
		var splitted = iModel.split(".");
		if(cmi_datamodel["cmi.score"]==undefined){
			cmi_datamodel["cmi.score"]=new Array();
			cmi_datamodel["cmi.score"]["raw"] = "";
			cmi_datamodel["cmi.score"]["min"] = "";
			cmi_datamodel["cmi.score"]["max"] = "";
		}
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2]=="scaled"){
			objective_measure_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] = true;
			objective_normalized_measure[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] = iParam;
			err_code=0;
			return "true";
		} else if(splitted.length >= 3 && splitted[2]=="raw"){
			cmi_datamodel["cmi.score"]["raw"]=iParam;
			err_code=0;
			return "true";
		} else if(splitted.length >= 3 && splitted[2]=="min"){
			cmi_datamodel["cmi.score"]["min"]=iParam;
			err_code=0;
			return "true";
		} else if(splitted.length >= 3 && splitted[2]=="max"){
			cmi_datamodel["cmi.score"]["max"]=iParam;
			err_code=0;
			return "true";
		} else {
			err_code=401;
			return "false";
		}
	} else if(iModel=="cmi.session_time"){ // 4.2.21. セッション時間
		cmi_datamodel["cmi.session_time"]=iParam;
		err_code=0;
		return "true";
	} else if(iModel=="cmi.success_status"){ // 4.2.22. 合格状態

		if(iParam == "passed"){
			objective_progress_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] = true; 
			objective_satisfied_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] = true;
			err_code=0;
			return "true";
		} else if(iParam == "failed"){
			objective_progress_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] = true;
			objective_satisfied_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] = false;
			err_code=0;
			return "true";
		} else {
			err_code=406;
			return "false";
		}
	} else if(iModel=="cmi.suspend_data"){ // 4.2.23. 中断データ
		cmi_datamodel["cmi.suspend_data"]=iParam;
		err_code=0;
		return "true";
	} else if(iModel=="cmi.time_limit_action"){ // 4.2.24. タイムリミット超過後の動作




		err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
		return "false";
	} else if(iModel=="cmi.total_time"){ // 4.2.25. 全学習時間




		err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
		return "false";
	} else if(iModel=="adl.nav.request"){ // ナビゲーションコマンド




		Navigation_Command_From_SCO(iParam);
	} else {
		err_code=401;
		return "false";
	}
}

function CMI_GetValue(iModel){
	if(iModel=="cmi.version"){ // 4.2.1. ヴァージョン
		return "1.0";
	}else if(iModel.match(/^cmi\.comments_from_learner/)){ // 4.2.2. 学習者からのコメント

		var splitted = iModel.split(".");
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=0;
			return GetValue( "cmi.comments_from_learner._children" );
		} else if(splitted.length >= 3 && splitted[2]=="_count"){
			err_code=0;
			return GetValue( "cmi.comments_from_learner._count" );
		} else if(splitted.length >= 3 && splitted[2].match(/^\d+$/)){
			var num=splitted[2];
			if(splitted.length >= 4 && ( splitted[3]=="comment" || splitted[3]=="location" || splitted[3]=="timestamp" ) ){
				err_code=0;
				return GetValue( iModel );
			} else {
				err_code=401;
				return "false";
			}
		} else {
			err_code=401; // 3.1.7.5.1. Undefined Data Model Element
			return "false";
		}
	} else if(iModel.match(/^cmi\.comments_from_lms/)){ // 4.2.3. LMSからのコメント

		var splitted = iModel.split(".");
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=0;
			return GetValue( "cmi.comments_from_lms._children" );
		} else if(splitted.length >= 3 && splitted[2]=="_count"){
			err_code=0;
			return GetValue( "cmi.comments_from_lms._count" );
		} else if(splitted.length >= 3 && splitted[2].match(/^\d+$/)){
			var num=splitted[2];
			if(splitted.length >= 4 && ( splitted[3]=="comment" || splitted[3]=="location" || splitted[3]=="timestamp" ) ){
				err_code=0;
				return GetValue( iModel );
			} else {
				err_code=401;
				return "false";
			}
		} else {
			err_code=401; // 3.1.7.5.1. Undefined Data Model Element
			return "false";
		}
	} else if(iModel=="cmi.completion_status"){ // 4.2.4. 完了状態

		/*if(attempt_progress_status[id(current_activity)]==true){
			var at=attempt_completion_status[id(current_activity)];
			if(at!=undefined && at!=null){
				return at;
			} else {
				return "unknown";
			}
		} else {
			return "unknown";
		}
		
		if(objective_progress_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] == true &&
			objective_satisfied_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] == true){
			err_code=0;
			return "completed";
		} else if(objective_progress_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] == true &&
			objective_satisfied_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] == false){
			err_code=0;
			return "incomplete";
		} else {
			err_code=0;
			return "unknown";
		}*/
		
		err_code=0;
		return GetValue( iModel );
	} else if(iModel=="completion_threshold"){ // 4.2.5. 完了状態の閾値
		err_code=0;
		return GetValue( iModel );
	} else if(iModel=="cmi.credit"){ // 4.2.6. 評価
		err_code=0;
		return GetValue( iModel );
	} else if(iModel=="cmi.entry"){ // 4.2.7. エントリ
		err_code=0;
		return GetValue( iModel );
	} else if(iModel=="cmi.exit"){ // 4.2.8. 退出
		err_code=404;
		return "";
	} else if(iModel.match(/^cmi\.interactions/)){ // 4.2.9. インタラクション
		var splitted = iModel.split(".");
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=404; // 3.1.7.5.4. Data Model Elements Is Read Only
			return "false";
		} else if(splitted.length >= 3 && splitted[2]=="_count"){
			err_code=0;
			var _count=0;
			if(cmi_datamodel["cmi.interactions"]!=undefined && cmi_datamodel["cmi.interactions"]!=null){
				while(cmi_datamodel["cmi.interactions"][_count]!=undefined){
					_count++;
				}
			}
			return _count;
		} else if(splitted.length >= 3 && splitted[2].match(/^\d+$/)){
			var num=splitted[2]-0;
			if(splitted.length >= 4 && splitted[3]=="id"){
				err_code=0;
				return cmi_datamodel["cmi.interactions"][num]["id"];
			} else if(splitted.length >= 4 && splitted[3]=="type"){
				err_code=0;
				return cmi_datamodel["cmi.interactions"][num]["type"];
			} else if(splitted.length >= 4 && splitted[3]=="objectives"){
				if(splitted.length >= 5 && splitted[4]=="_count"){
					err_code=0;
					var _count=0;
					if(cmi_datamodel["cmi.interactions"][num]!=undefined && 
					   cmi_datamodel["cmi.interactions"][num]!=null &&
					   cmi_datamodel["cmi.interactions"][num]["objectives"]!=undefined && 
					   cmi_datamodel["cmi.interactions"][num]["objectives"]!=null ){
						while(cmi_datamodel["cmi.interactions"][num]["objectives"][_count]!=undefined){
							_count++;
						}
					}
					return _count;
				} else if(splitted.length >= 5 && splitted[4].match(/^\d+$/)){
					var num2=splitted[4]-0;
					if(splitted.length >= 6 && splitted[5]=="id"){
						err_code=0;
						return cmi_datamodel["cmi.interactions"][num]["objectives"][num2]["id"];
					}
				} else {
					err_code=401;
					return "";
				}
			} else if(splitted.length >= 4 && splitted[3]=="timestamp"){
				err_code=0;
				return cmi_datamodel["cmi.interactions"][num]["timestamp"];
			} else if(splitted.length >= 4 && splitted[3]=="correct_response"){
				if(splitted.length >= 5 && splitted[4]=="_count"){
					err_code=0;
					var _count=0;
					if(cmi_datamodel["cmi.interactions"][num]!=undefined &&
					   cmi_datamodel["cmi.interactions"][num]!=null &&
					   cmi_datamodel["cmi.interactions"][num]["correct_response"]!=undefined &&
					   cmi_datamodel["cmi.interactions"][num]["correct_response"]!=null ){
						while(cmi_datamodel["cmi.interactions"][num]["correct_response"][_count]!=undefined){
							_count++;
						}
					}
					return _count;
				} else if(splitted.length >= 5 && splitted[4].match(/^\d+$/)){
					var num2=splitted[4]-0;
					if(splitted.length >= 6 && splitted[5]=="pattern"){
						err_code=0;
						return cmi_datamodel["cmi.interactions"][num]["objectives"][num2]["pattern"];
					} else {
						err_code=401;
						return "";
					}
				}
			} else if(splitted.length >= 4 && splitted[3]=="weighting"){
				err_code=0;
				return cmi_datamodel["cmi.interactions"][num]["weighing"];
			} else if(splitted.length >= 4 && splitted[3]=="learner_response"){
				err_code=0;
				return cmi_datamodel["cmi.interactions"][num]["learner_response"];
			} else if(splitted.length >= 4 && splitted[3]=="result"){
				err_code=0;
				return cmi_datamodel["cmi.interactions"][num]["result"];
			} else if(splitted.length >= 4 && splitted[3]=="latency"){
				err_code=0;
				return cmi_datamodel["cmi.interactions"][num]["result"];
			} else if(splitted.length >= 4 && splitted[3]=="description"){
				err_code=0;
				cmi_datamodel["cmi.interactions"][num]["result"];
			} else {
				err_code=401;
				return "";
			}
		} else {
			err_code=401; // 3.1.7.5.1. Undefined Data Model Element
			return "";
		}
	} else if(iModel=="cmi.launch_data"){ // 4.2.10. 起動データ
		err_code=0;
		return GetValue( iModel );
	} else if(iModel=="cmi.leaner_id"){ // 4.2.11. 学習者ID
		err_code=0;
		return GetValue( iModel );
	} else if(iModel=="cmi.learner_name"){ // 4.2.12. 学習者名
		err_code=0;
		return GetValue( iModel );
	} else if(iModel.match(/^cmi\.learner_preference/)){ // 4.2.13. 学習者のプリファレンス
		var splitted = iModel.split(".");
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=0;
			return GetValue( "cmi.learner_preference._children" );
		} else if( splitted[2]=="audio_level" || splitted[2]=="language" || splitted[2]=="delivery_speed" || splitted[2]=="audio_captioning" ){
			err_code=0;
			return GetValue( iModel );
		} else {
			err_code=401; // 3.1.7.5.1. Undefined Data Model Element
			return "false";
		}
	} else if(iModel=="cmi.location"){ // 4.2.14. ロケーション
		err_code=0;
		//レジュームの場合は"undefined"が返っている。

		cmi_datamodel["cmi.location"] = GetValue( "cmi.location" );
		return cmi_datamodel["cmi.location"];
	} else if(iModel=="cmi.max_time_allowed"){ // 4.2.15. 最大許容時間
		err_code=0;
		return "";
	} else if(iModel=="cmi.mode"){ // 4.2.16. 動作モード

		err_code=0;
		return "normal";
	} else if(iModel.match(/^cmi\.objectives/)){ // 4.2.17. 学習目標

		var splitted = iModel.split(".");
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=0;
			return "";
		} else if(splitted.length >= 3 && splitted[2]=="_count"){
			err_code=0;
			var _count=0;
			var pobj = item_primary_objectives[id(current_activity)];
			var objs = item_objectives[id(current_activity)];
			if(pobj!=undefined && pobj!=null){_count++;}
			if(objs!=undefined && objs!=null){
				_count+=objs.length;
			}
			return _count;
		} else if(splitted.length >= 3 && splitted[2].match(/^\d+$/)){
			var num=splitted[2];
			if(splitted.length >= 4 && splitted[3]=="id"){
				err_code=0;
				var pobj = item_primary_objectives[id(current_activity)];
				var objs = item_objectives[id(current_activity)];
				if(num==0){
					return obj_id(pobj);
				} else {
					return obj_id(objs[num-1]);
				}
			} else if(splitted.length >= 4 && splitted[3]=="score"){
				if(splitted.length >= 5 && splitted[4]=="_children"){
					err_code=0;
					return "";
				} else if(splitted.length >= 5 && splitted[4]=="scaled"){
					err_code=0;
					return cmi_datamodel["cmi.objectives"][num]["score"]["scaled"];
				} else if(splitted.length >= 5 && splitted[4]=="raw"){
					err_code=0;
					return cmi_datamodel["cmi.objectives"][num]["score"]["raw"];
				} else if(splitted.length >= 5 && splitted[4]=="min"){
					err_code=0;
					return cmi_datamodel["cmi.objectives"][num]["score"]["min"];
				} else if(splitted.length >= 5 && splitted[4]=="max"){
					err_code=0;
					return cmi_datamodel["cmi.objectives"][num]["score"]["max"];
				} else {
					err_code=401;
					return "false";
				}
			} else if(splitted.length >= 4 && splitted[3]=="success_status"){
				var pobj = item_primary_objectives[id(current_activity)];
				var objs = item_objectives[id(current_activity)];
				if(num==0){
					if(objective_progress_status[id(current_activity)][obj_id(pobj)] == true &&
					   objective_satisfied_status[id(current_activity)][obj_id(pobj)] == true){
						err_code=0;
						return "passed";
					} else {
						if(objective_progress_status[id(current_activity)][obj_id(pobj)] == true &&
						   objective_satisfied_status[id(current_activity)][obj_id(pobj)] == false){
							err_code=0;
							return "failed";
						} else {
							err_code=0;
							return "unknown";
						}
					}
				} else {
					if(objective_progress_status[id(current_activity)][obj_id(objs[num-1])] == true &&
					   objective_satisfied_status[id(current_activity)][obj_id(objs[num-1])] == true){
						err_code=0;
						return "passed";
					} else {
						if(objective_progress_status[id(current_activity)][obj_id(objs[num-1])] == true &&
						   objective_satisfied_status[id(current_activity)][obj_id(objs[num-1])] == false){
							err_code=0;
							return "failed";
						} else {
							err_code=0;
							return "unknown";
						}
					}
				}
			} else if(splitted.length >= 4 && splitted[3]=="completion_status"){
				err_code=0;
				return cmi_datamodel["cmi.objectives"][num]["completion_status"];
			} else if(splitted.length >= 4 && splitted[3]=="progress_measure"){
				err_code=0;
				return cmi_datamodel["cmi.objectives"][num]["progress_measure"];
			} else if(splitted.length >= 4 && splitted[3]=="description"){
				err_code=0;
				return cmi_datamodel["cmi.objectives"][num]["description"];
			} else {
				err_code=401;
				return "false";
			}
		} else {
			err_code=401;
			return "false";
		}
	} else if(iModel=="cmi.progress_measure"){ // 4.2.18. 進捗状態の測定値
		//
	} else if(iModel=="cmi.scaled_passing_score"){ // 4.2.19. 合格点(正規化表現)
		if( minNormalizedMeasure[id(current_activity)] != null ){
			err_code=0;
			return minNormalizedMeasure[id(current_activity)];
		} else {
			err_code=403;
			return "";
		}
    } else if(iModel.match(/^cmi\.score/)){ // 4.2.20. 得点
		var splitted = iModel.split(".");
		if(cmi_datamodel["cmi.score"] == null) {
			cmi_datamodel["cmi.score"]=new Array();
		}
		if( GetValue( "cmi.score.raw" ) == "0" ){
			cmi_datamodel["cmi.score"]["raw"] = "";
		} else {
			cmi_datamodel["cmi.score"]["raw"] = GetValue( "cmi.score.raw" );
		}
		cmi_datamodel["cmi.score"]["min"] = GetValue( "cmi.score.min" );
		cmi_datamodel["cmi.score"]["max"] = GetValue( "cmi.score.max" );
		
		if(splitted.length >= 3 && splitted[2]=="_children"){
			err_code=0;
			return GetValue( "cmi.score._children" );
		} else if(splitted.length >= 3 && splitted[2]=="scaled"){
			if(objective_measure_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])]==true){
				err_code=0;
				return objective_normalized_measure[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])];
			} else {
				err_code=0;
			}
		} else {
			if(splitted.length >= 3 && splitted[2]=="raw"){
				err_code=0;
				return cmi_datamodel["cmi.score"]["raw"];
			} else if(splitted.length >= 3 && splitted[2]=="min"){
				err_code=0;
				return cmi_datamodel["cmi.score"]["min"];
			} else if(splitted.length >= 3 && splitted[2]=="max"){
				err_code=0;
				return cmi_datamodel["cmi.score"]["max"];
			} else {
				err_code=401;
				return "false";
			}
		}
	} else if(iModel=="cmi.session_time"){ // 4.2.21. セッション時間
		err_code=404;
		return "";
	} else if(iModel=="cmi.success_status"){ // 4.2.22. 合格状態

		/*if(objective_progress_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] == true &&
		   objective_satisfied_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] == true){
			err_code=0;
			return "passed";
		} else {
			if(objective_progress_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] == true &&
			   objective_satisfied_status[id(current_activity)][obj_id(item_primary_objectives[id(current_activity)])] == false){
				err_code=0;
				return "failed";
			} else {
				err_code=0;
				return "unknown";
			}
		}*/
		err_code=0;
		return GetValue( iModel );
	} else if(iModel=="cmi.suspend_data"){ // 4.2.23. 中断データ
		err_code=0;
		cmi_datamodel["cmi.suspend_data"] = GetValue( "cmi.suspend_data" );
		return cmi_datamodel["cmi.suspend_data"];
	} else if(iModel=="cmi.time_limit_action"){ // 4.2.24. タイムリミット超過後の動作

		//
	} else if(iModel=="cmi.total_time"){ // 4.2.25. 全学習時間

		err_code=0;
		return GetValue( iModel );
	} else {
		err_code=451;
		return "";
	}
}


/********************
以下murakami追加
********************/

/*
シーケンシングが適用されたそれぞれのscoのステータスを返す
返すテキストは以下のフォーマット(それぞれのプロパティを","で区切り、各データを";"で区切った形式)

	id1,cmi.completion_status1,cmi.success_status1;id2,cmi.completion_status2,cmi.success_status2; .....
	
*/

function getItemStatusFromFlash(arg) {
	var cmiStatus_txt = "";
	
	for(var it=0;it<items.length;it++){
	 	
	 	var tempId = id(items[it]);
	 	//cmi.completion_status
	 	var tempProgressStatus = attempt_progress_status[tempId];
	 	var tempCompletionStatus = attempt_completion_status[tempId];
	 	var tempActivityAttemptCount = activity_attempt_count[tempId];
	 	//返すテキストに追加
	 	cmiStatus_txt += tempId;
	 	cmiStatus_txt += ",";
	 	cmiStatus_txt += getCompletionStatusFromFlash(tempProgressStatus, tempCompletionStatus, tempActivityAttemptCount);
	 	cmiStatus_txt += ",";
	 	
		//var objectiveProgressStatus = objective_progress_status[obj_id(item_primary_objectives[tempId])];
	  	var objectiveProgressStatus = objective_progress_status[tempId][obj_id(item_primary_objectives[tempId])];
	  	
	 	//var objectiveSatisfiedStatus = objective_satisfied_status[obj_id(item_primary_objectives[tempId])];
	 	var objectiveSatisfiedStatus = objective_satisfied_status[tempId][obj_id(item_primary_objectives[tempId])];
	 	
	 	//返すテキストに追加
	  	cmiStatus_txt += getSuccessStatusFromFlash(objectiveProgressStatus, objectiveSatisfiedStatus);
	 	cmiStatus_txt += ";";
	 	//cmiStatus_txt += "\n";
 	}
 	return cmiStatus_txt;
}

//cmi.completion_statusを返す
function getCompletionStatusFromFlash(argProgress, argCompletion, argAttemptCount) {	
	var returnStatus = "";	
	if(argProgress == true && argCompletion == true) {
		returnStatus = "completed";
	} else if(argProgress == true && argCompletion == false) {
		returnStatus = "incomplete";
	} else if(argProgress == true && argCompletion == false && argAttemptCount == 0) {
		returnStatus = "not attempted";
	} else if(argProgress == false && argCompletion == false) {
		returnStatus = "unknown";
	} else {
		returnStatus = "unknown";
	}	
	return returnStatus;
}

//cmi.success_statusを返す
function getSuccessStatusFromFlash(argProgress, argSatisfied) {	
	var returnStatus = "";
	if(argProgress == true && argSatisfied == true) {
		returnStatus = "passed";
	} else if(argProgress == true && argSatisfied == false) {
		returnStatus = "failed";
	} else {
		returnStatus = "unknown";
	}
	
	return returnStatus;
}

//GUIボタンの可否(表示非表示)をまとめて返す
function getGuiBtnVisible() {
	/*
	my_continue_or_not()
	my_previous_or_not()
	my_exit_or_not()
	my_abandon_or_not()
	*/
	var returnStr = "";
	
	returnStr = my_previous_or_not() + ";";
	returnStr += my_continue_or_not() + ";";
	returnStr += my_exit_or_not() + ";";
	returnStr += my_abandon_or_not();
	
	return returnStr;
}

/*
Flashの目次の有効無効
*/
function flash_toc_tree_recurse(){ // 目次ページのために再帰的にツリーを辿る

	var returnStr = "";
    for(var it=0;it<items.length;it++){
	 	var tempId = id(items[it]);
	 	returnStr += tempId + "," + my_choice_or_not(tempId,"") + ";";
 	}
	
 	return returnStr;
}

/**
*改行削除
*/
function DeleteLineFeed(myLen) {
     var newLen = '';
     for(var i=0; i<myLen.length; i++){
         text = escape(myLen.substring(i, i+1));
         if(text != "%0D" && text != "%0A"){
             newLen += myLen.substring(i, i+1);
         }
     }
     return(newLen);
}
