// Learn cc.Class:
//  - https://docs.cocos.com/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

// import { getSprNode } from "./util";
import { getDefalutData } from "../script/JJ21_defaultData";
import { getSprNode, playAudioByUrl, showBtnAnima, getScaleRateBy2Node, localPosTolocalPos, randomSortByArr, loadDragonBones, playAudio, showTrebleFirework, getSprNodeByUrl, setSprNodeMaxLen, delayCall, asyncDelay, RandomInt, exchangeNodePos, onHomeworkFinish, roundNum, getAngleByPos, getPosByAngle, jellyShake, setSRRecord, addSRAudioDuration, showSRResultByRecord} from "../script/JJ21_util";

cc.Class({
	extends: cc.Component,

	properties: {
		baseWidth: {
			default: 1920,
			type: cc.Integer
		},
		baseHeight: {
			default: 1080,
			type: cc.Integer
		}
	},

	onLoad() {
		cc.debug.setDisplayStats(false);
		this.initSceneData();
		this.initSize();
	},

	initSceneData() {
		this._imageResList = [];
		this._audioResList = [];
		this._animaResList = [];
	},


	_designSize: null,
	_frameSize: null,
	_mapScaleMin: null,
	_mapScaleMax: null,
	_cocosScale: null,
	canvas: null,
	curTestText: null,

	initSize() {


		// 注意cc.winSize只有在适配后(修改fitHeight/fitWidth后)才能获取到正确的值,因此使用cc.getFrameSize()来获取初始的屏幕大小
		let screen_size = cc.view.getFrameSize().width / cc.view.getFrameSize().height
		let design_size = cc.Canvas.instance.designResolution.width / cc.Canvas.instance.designResolution.height
		let f = screen_size >= design_size
		cc.Canvas.instance.fitHeight = f
		cc.Canvas.instance.fitWidth = !f

		const frameSize = cc.view.getFrameSize();
		this._frameSize = frameSize;

		this._designSize = cc.view.getDesignResolutionSize();

		let sx = cc.winSize.width / frameSize.width;
		let sy = cc.winSize.height / frameSize.height;
		this._cocosScale = Math.min(sx, sy);

		sx = frameSize.width / this._designSize.width;
		sy = frameSize.height / this._designSize.height;
		this._mapScaleMin = Math.min(sx, sy) * this._cocosScale;
		this._mapScaleMax = Math.max(sx, sy) * this._cocosScale;

		this.canvas = cc.find('Canvas');


		// cc.log('cc.Canvas: ', cc.Canvas);
	},

	start() {

		console.log(' in start 1 ');

		let getData = this.getData.bind(this);
		if (window && window.courseware) {
			getData = window.courseware.getData;

			console.log(' in start 2 ');

		}
		getData((_data) => {

			let data;
			if (_data) {
				const dataStr = JSON.stringify(_data);
				const newDataStr = this.changeHttpsUrl(dataStr);
				data = JSON.parse(newDataStr);
				// console.log('newDataStr~:', newDataStr);
				// console.log('data~:', data);
			}
			

			this.data = data || this.getDefaultData();

			const isDebug = cc.sys.localStorage.getItem('isDebug');
			this.data.isDebug = this.data.isDebug || isDebug;

			this.preloadItem()
		})
	},

	changeHttpsUrl(dataStr) {

		return dataStr.replace(/^https:/, 'http:');
    },

	_imageResList: null,
	_audioResList: null,
	_animaResList: null,
	preloadItem() {
		this.addPreloadImage();
		this.addPreloadAudio();
		this.addPreloadAnima();
		this.preload();
	},


	getData(func) {
		if (window && window.courseware) {
			window.courseware.getData(func, 'dfzx_cocos_dqq');
			return;
		}
		
		const middleLayer = cc.find('middleLayer');
		if (middleLayer) {
			const middleLayerComponent = middleLayer.getComponent('middleLayer');
			middleLayerComponent.getData(func);
			return;
		}
		
		func(this.getDefaultData());
	},

	getDefaultData() {

		return getDefalutData();

	},

	preload() {
		const preloadArr = this._imageResList.concat(this._audioResList).concat(this._animaResList);
		console.log(' in preload preloadArr: ', preloadArr);
		cc.assetManager.loadAny(preloadArr, null, null, (err, data) => {
			console.log(' preload data, ', data);


			this.addServerListener();
			// if (window && window["air"]) {
			// 	window["air"].hideAirClassLoading();
			// }
		});
	},

	addServerListener() {
		
		if (window && window["air"]) {
			// cc.find('Canvas').opacity = 0;
			// window.air.onCourseInScreen = (next) => {
			// 	//  cc.find('Canvas').opacity = 255;
			// 	this.loadEnd();
			// 	next();
			// }
			this.loadEnd();
			window.air.hideAirClassLoading();
		} else {
			this.loadEnd();
		}


		if (window.air) {

			window.air.osmoHandwritingCallback = (data) => {

				if (!data) {
					console.log('data is not exist!!!');
					return;
				}

				console.log('osmoHandwritingCallback data: ', data);


				if (typeof (data) == 'string') {
					console.log('data is string ');
					const dataObj = JSON.parse(data);

					this.photoEnd(dataObj);
					return;
				}


				// 哲学逻辑
				this.photoEnd(data);

			}

			
		}

	},

	loopLog(data) {

		console.log("in loopLog");

		let dataStr = data;
		if (typeof (data) == 'object') {
			dataStr = JSON.stringify(data);
		}

		const maxCount = 1000;
		let count = 0;
		while(count < dataStr.length) {
			console.log(dataStr.substr(count, maxCount));
			count += maxCount;
		}
	},

	addPreloadImage() {


		const exercises = this.data.exercises || [];
		exercises.forEach((item) => {
			if (item.picUrl) {
				this._imageResList.push({ url: item.picUrl || ''});
			}
		})
	
		if (this.data.bg_pic_url) {
			this._imageResList.push({ url: this.data.bg_pic_url || ''});
		}

		if (this.data.bgItem) {
			this._imageResList.push({ url: this.data.bgItem.url || ''});
		}

		if (this.data.bgItem2) {
			this._imageResList.push({ url: this.data.bgItem2.url || ''});
		}

		if (!this.data.hotZoneItemArr) {
			return;
		}
		this.data.hotZoneItemArr.forEach((item) => {
			if (item.pic_url) {
				this._imageResList.push({ url: item.pic_url || ''});
			}
		})
	},

	addPreloadAudio() {


		const exercises = this.data.exercises || [];
		exercises.forEach((item) => {
			if (item.audioUrl) {
				this._imageResList.push({ url: item.audioUrl || ''});
			}
		})


		if (this.data.questionArr) {
			const arr = this.data.questionArr;
			for (let i=0 ;i<arr.length; i++) {
				this._audioResList.push({url: arr[i].audio_url || ''});
				this._audioResList.push({url: arr[i].video_url || ''});
			}
		}

	},

	addPreloadAnima() {
		if (!this.data.hotZoneItemArr) {
			return;
		}
		this.data.hotZoneItemArr.forEach((item) => {
			if (item.skeJsonData) {
				this._animaResList.push({ url: item.skeJsonData.url || '' });
				this._animaResList.push({ url: item.texJsonData.url || ''});
				this._animaResList.push({ url: item.texPngData.url || ''});
			}
		})
	},

	loadEnd() {
		console.log(' in loadEnd');

		// this.data.isDebug = true;

		this.initData();
		this.initView();

		// this.initMusic();

		// this.startTesting();

		// cc.debug.setDisplayStats(true);

	},



	initMusic() {
		cc.assetManager.loadRemote(this.data.bg_audio_url, (err, clip) => {
			cc.audioEngine.setMusicVolume(0.3);
			const audioID = cc.audioEngine.playMusic(clip, true);
		});
	},

	curGroupIndex: null,
	curQuestionIndex: null,
	curQuestionData: null,

	picNodeArr: null,


	firstItemData: null,
	bottomItemData: null,
	animaNodeArr: null,
	circleAnimaNodeArr: null,
	signAnimaNodeArr: null,

	initData() {
		console.log(' in initData');

		console.log('this.data: ', this.data);

		this.customTypeGroupArr = this.data.customTypeGroupArr || [];

		

		this.initQuesArr();
		this.initCurQues();

		this.initAudioEffect();


		return;

		// this.curGroupIndex = 0;
		// this.curQuestionIndex = 0;
		// this.setCurGroupAndQuestion()

		// console.log('this.curQuestionData', this.curQuestionData)

		this.CHECK_TYPE_LINE = 'LINE';
		this.CHECK_TYPE_WRITE = 'WRITE';
		this.CHECK_TYPE_CIRCLE = 'CIRCLE';
		this.CHECK_TYPE_SIGN = 'SIGN';
		this.CHECK_TYPE_COLOR = 'COLOR';

		this.isHelp = true;

		this.colorUnit = 0.004;
		this.serverUnitX =  0.00333334;
		this.serverUnitY = 0.00257734;
		this.colorSprPoolArr = [];

		this.totalLineArr = [];
		this.rectNodeArr = [];

		this.picAnimNodeArr = []
		this.colorPicNodeArr = [];

		this.animaNodeArr = [];

		this.circleAnimaNodeArr = [];
		this.signAnimaNodeArr = [];

		this.picNodeArr = [];
		this.initAudioEffect();

		this.linkRectGroup = [];

		this.centerItemArr = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '1');
		this.benchmark1Data = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '3')[0];
		this.benchmark2Data = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '4')[0];
		this.firstItemData = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '5')[0];

		this.lineRectArr = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '0');
		this.newRectArr = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '6');
		this.circleRectArr = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '7');
		this.signRectArr = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '8');
		this.colorRectArr = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '9');
		this.numRectArr = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, '10');
		this.newRectArr = this.newRectArr.concat(this.numRectArr);

		if (this.benchmark1Data) {
			this.initCheckBase();
		} 



		this.initTypeArr();
		
	},

	initQuesArr() {
		this.quesArr = this.data.tempItem.quesArr;

		// this.quesArr.forEach((itemArr, i) => {
		// 	itemArr = itemArr.filter(it => {
		// 		return it.labelArr && it.labelArr[0] && it.labelArr[0].type && it.labelArr[0].type.indexOf('input') != -1;
		// 	})
		// 	this.quesArr[i] = itemArr;
		// });

		// console.log('this.quesArr: ', this.quesArr);

		this.curQuesIndex = 0;
	},

	initCurQues() {
		// const quesData = this.quesArr[this.curQuesIndex];
		// this.curQues = {}
		// quesData.forEach(it => {
		// 	if (it.labelArr[0].type == 'inputText') {
		// 		this.curQues.inputTextData = it;
		// 	}
		// 	if (it.labelArr[0].type == 'inputPic') {
		// 		this.curQues.inputPicData = it;
		// 	}
		// 	if (it.labelArr[0].type == 'inputAudio') {
		// 		this.curQues.inputAudioData = it;
		// 	}
		// })

		// console.log('this.curQues:', this.curQues);

		this.curQues = this.quesArr[this.curQuesIndex];
		
	},


	initTypeArr() {
		const typeArr = this.data.typeArr;
		
		console.log('this.data.typeArr: ', this.data);

		if (!this.data.firstGIdx) {
			this.data.firstGIdx = typeArr[0].gIdx;
		} else {

			const findItem = typeArr.find(it => {
				return it.gIdx == this.data.firstGIdx
			})

			console.log('findItem: ', findItem);

			if (!findItem) {
				this.data.firstGIdx = typeArr[0].gIdx;
			}

		}

		console.log('this.data.typeArr.length: ', this.data.typeArr.length);

		console.log('arr: ', JSON.stringify(this.data.typeArr));

		console.log('this.data.firstGIdx: ', this.data.firstGIdx);
		this.typeArr = [];
		const firstType = typeArr.find((t) => {
			console.log('t.gIdx: ', t.gIdx);
			return t.gIdx == this.data.firstGIdx;
		})

		const index = typeArr.indexOf(firstType);
		console.log('firstType: ', firstType);
		typeArr.splice(index, 1);

		this.typeArr = [firstType];
		this.typeArr = this.typeArr.concat(typeArr)
		this.typeArrIndex = 0;

		console.log("this.typeArr: ", this.typeArr);
	},

	initCheckBase() {


		console.log('benchmark1Data: ', this.benchmark1Data);
		console.log('benchmark2Data: ', this.benchmark2Data);
		console.log('centerItemArr: ', this.centerItemArr);

		const benchmark1Rect = this.benchmark1Data.rect;
		const benchmark2Rect = this.benchmark2Data.rect;
		
		const benchmark1CenterY = (benchmark1Rect.y + benchmark1Rect.height / 2);
		const benchmark2CenterY = (benchmark2Rect.y + benchmark2Rect.height / 2);
		
		let unitH = benchmark2CenterY - benchmark1CenterY;
		let unitW = benchmark2Rect.x + benchmark2Rect.width - benchmark1Rect.x;
		let baseX = benchmark1Rect.x;
		let baseY = benchmark1CenterY;


		if (this.firstItemData) {
			const firstItemRect = this.firstItemData.rect;
			baseX = firstItemRect.x + firstItemRect.width / 2;
			baseY = firstItemRect.y + firstItemRect.height / 2;
			unitW = benchmark1Rect.x + benchmark1Rect.width - (firstItemRect.x + firstItemRect.width / 2);
			unitH = (firstItemRect.y + firstItemRect.height / 2) - benchmark1CenterY;
		}


		for(let i=0; i<this.centerItemArr.length; i++) {

			const itemRect = this.centerItemArr[i].rect;
			const x = itemRect.x + itemRect.width / 2;
			const y = itemRect.y + itemRect.height / 2;

			const unitX = (x - baseX) / unitW;
			const unitY = (y - baseY) / unitH;
			const unitW2 = itemRect.width / unitW;
			const unitH2 = itemRect.height / unitH;


			this.centerItemArr[i].unitX = unitX;
			this.centerItemArr[i].unitY = unitY;
			this.centerItemArr[i].unitW = unitW2;
			this.centerItemArr[i].unitH = unitH2;

			// console.log('unitX: ', unitX)
			// console.log('unitY: ', unitY)
		}

		console.log('unitH: ', unitH)
		console.log('unitW: ', unitW)
		console.log('baseX: ', baseX)
		console.log('baseY: ', baseY)

	
		const centerX = this.data.bgItem2.rect.width / 2;
		this.centerUnitW = (centerX - baseX) / unitW;



	},

	getGroupArrByGIdx(arr, gIdx) {
		const groupArr = [];
		for (let i=0; i<arr.length; i++) {
			if (arr[i].gIdx == gIdx) {

				const data = JSON.parse(JSON.stringify(arr[i]));
				groupArr.push(data);
			}
		}

		return groupArr;
	},

	curGroup: null,
	setCurGroupAndQuestion() {
		this.curGroup = this.data.groupArr[this.curGroupIndex];

		if (!this.curGroup) {
			this.gameEnd();
		} else {
			this.curQuestionIndex = 0;
			this.setCurQuestionData();
		}
	},

	setCurQuestionData() {
		this.curQuestionData = this.curGroup.questionArr[this.curQuestionIndex];

		if (!this.curQuestionData) {

			this.hideVideo();
			this.showBigStar();
		}
	},

	hideVideo() {
		this.videoNode.active = false;

		this.videoNode.player.pause();
		this.videoNode.pauseBtn.active = false;
		this.videoNode.playBtn.active = true;
	},


	rightClip: null,
	wrongClip: null,
	bigStarClip: null,
	btnClip: null,
	finishClip: null,
	selectClip: null,
	starCountClip: null,
	helpClip: null,
	initAudioEffect() {
	
		// this.puchibangClip = cc.find('Canvas/res/audio/puchibang').getComponent(cc.AudioSource).clip;
		// this.kaiSanClip = cc.find('Canvas/res/audio/kai_san').getComponent(cc.AudioSource).clip;
		// this.dropClip = cc.find('Canvas/res/audio/drop').getComponent(cc.AudioSource).clip;
		// this.popClip = cc.find('Canvas/res/audio/pop').getComponent(cc.AudioSource).clip;
		// this.flyClip = cc.find('Canvas/res/audio/fly').getComponent(cc.AudioSource).clip;
		// this.rightClip = cc.find('Canvas/res/audio/right').getComponent(cc.AudioSource).clip;
		// this.wrongClip = cc.find('Canvas/res/audio/wrong').getComponent(cc.AudioSource).clip;
		// this.btnClip = cc.find('Canvas/res/audio/btn').getComponent(cc.AudioSource).clip;
		// this.btn_1Clip = cc.find('Canvas/res/audio/btn_1').getComponent(cc.AudioSource).clip;

		this.excellentClip = cc.find('Canvas/res/audio/excellent').getComponent(cc.AudioSource).clip;
		this.goodClip = cc.find('Canvas/res/audio/good').getComponent(cc.AudioSource).clip;
		this.tryagainClip = cc.find('Canvas/res/audio/tryagain').getComponent(cc.AudioSource).clip;


		
		// this.helpClip = cc.find('Canvas/res/audio/help').getComponent(cc.AudioSource).clip;
	},



	initView() {

		console.log(' in initView');

		this.initHotZone();
		this.initArrow();
		this.initMask();

		this.initListener();

		this.showBackBtn();




		// this.initBg();
		// this.initPanel();
		// this.initScore();
		// this.initBottomPlayer();
		// this.initMask();

		// this.refreshCurPanel();

		// this.initChick();
		// this.showChickStart();

		// this.initRole();
		
		

		// this.showMask();
		return;

		this.initHotZone();
		this.initDebugLayer();

	},


	showBackBtn() {
		const backBtn = cc.find('Canvas/back_btn');
		backBtn.active = true;
		backBtn.zIndex = 30;
		
		backBtn.on('touchstart', () => {
			const middleLayer = global["middleLayer"];
			if (middleLayer) {
				// 有些模板需要在返回时上报数据，直接把数据作为参数传入就可以了
				middleLayer.exitGame({});
			} else {
				console.log("==触发返回事件==");
			}
		})
	},


	initArrow() {
		if (!this.data.isTurnPage) {
			return;
		}

		const arrowL = cc.find("Canvas/arrow_l");
		const arrowR = cc.find("Canvas/arrow_r");

		arrowL.active = arrowR.active = true;

		arrowL.zIndex = 20;
		arrowR.zIndex = 20;

		arrowL.on('click', () => {
			if (this.curQuesIndex == 0) {
				return;
			}
			if (arrowL.opacity < 254) {
				return;
			}
			if (this.isRecord) {
				return;
			}

			this.curQuesIndex--;
			this.initCurQues();
			this.refreshPage();
			this.clickTopAudio(this.topAudioRectNode);
		})

		arrowR.on('click', () => {
			if (this.curQuesIndex >= this.quesArr.length - 1) {
				return;
			}
			if (arrowR.opacity < 254) {
				return;
			}
			if (this.isRecord) {
				return;
			}

			this.curQuesIndex++;
			this.initCurQues();
			this.refreshPage();
			this.clickTopAudio(this.topAudioRectNode);
		})


		this.leftBtn = arrowL;
		this.rightBtn = arrowR;
		this.refreshArrowBtn();
	},





	initChick() {
		const chickNode = new cc.Node();
		chickNode.parent = this.canvas;

		const chick_start_1 = getSprNode("chick_1_1");
		chickNode.start_1 = chick_start_1;
		chick_start_1.parent = chickNode;

		const chick_start_2 = this.getAnimNode("chick_fly");
		chickNode.start_2 = chick_start_2;
		chick_start_2.parent = chickNode;

		const chick_start_3 = this.getAnimNode("chick_drop");
		chickNode.start_3 = chick_start_3;
		chick_start_3.parent = chickNode;

		const chick_up = this.getAnimNode("chick_up");
		chickNode.chick_up = chick_up;
		chick_up.parent = chickNode;

		const chick_right = getSprNode("chick_right");
		chickNode.chick_right = chick_right;
		chick_right.parent = chickNode;

		const chick_wrong = getSprNode("chick_wrong");
		chickNode.chick_wrong = chick_wrong;
		chick_wrong.parent = chickNode;


		chickNode.scale = this._mapScaleMin;
		this.chickNode = chickNode;

		this.hideChickNodeSpr();

	},


	hideChickNodeSpr() {
		this.chickNode.children.forEach(it => {
			it.active = false;
		})	
	},

	showChickStart() {
		this.chickNode.x = -this.canvas.width / 2 + 120;
		this.chickNode.y = this.canvas.height / 2 + 100;

		this.chickNode.start_1.active = true;

		const bottomY = -this.canvas.height - 300 * this._mapScaleMin;
		this.chickNode.bottomY = bottomY;

		let audioId;
		cc.tween(this.chickNode)
			.to(1, {y: 100}, {easing: "cubicIn"})
			.call(() => {
				this.chickNode.start_1.active = false;
				this.chickNode.start_2.active = true;
				this.chickNode.start_2.anim.timeScale = 1;
				playAudio(this.kaiSanClip);
			})
			.to(1, {y: 0})
			.call(() => {
				this.chickNode.start_2.active = false;
				this.chickNode.start_3.active = true;
				this.chickNode.start_3.anim.timeScale = 3;
				audioId = playAudio(this.puchibangClip, ()=>{}, true);
				const dropId = playAudio(this.dropClip);
				cc.audioEngine.setVolume(dropId, 0.2);
			})
			.to(0.7, {y: bottomY}, {easing: "quadIn"})
			.call(() => {
				cc.audioEngine.stopEffect(audioId);

				
				if (this.data.startAudioUrl) {				
					this.showRole();
				} else {
					this.hideMask();
				}
				// this.showChickRight();
				// this.showChickWrong();
			})
			.start();
	},
	
	showChickRight() {

		this.isShowChick = true;
		this.hideChickNodeSpr();

		this.chickNode.chick_up.active = true;
		this.chickNode.chick_up.anim.timeScale = 2;
		const topY = -this.canvas.height / 2 + 200 * this._mapScaleMin;

		let flyId = playAudio(this.puchibangClip, ()=>{}, true);
		

		cc.tween(this.chickNode)
			.to(1, {y: topY}, {easing: "cubicOut"})
			.call(() => {
				this.hideChickNodeSpr();
				this.chickNode.chick_right.active = true;
				this.showScoreItem(this.chickNode, 100, 100);
				cc.audioEngine.stopEffect(flyId);

				playAudio(this.rightClip);
			})
			.delay(0.15)
			.to(1, {y: this.chickNode.bottomY}, {easing: "cubicIn"})
			.call(() => {
				
			})
			.start();

	},

	showChickWrong() {

		this.isShowChick = true;
		this.hideChickNodeSpr();

		this.chickNode.chick_up.active = true;
		this.chickNode.chick_up.anim.timeScale = 2;
		const topY = -this.canvas.height / 2 + 200 * this._mapScaleMin;

		let flyId = playAudio(this.puchibangClip, ()=>{}, true);
		

		cc.tween(this.chickNode)
			.to(1, {y: topY}, {easing: "cubicOut"})
			.call(() => {
				this.hideChickNodeSpr();
				this.chickNode.chick_wrong.active = true;
				this.showScoreItem(this.chickNode, 100, 100);
				cc.audioEngine.stopEffect(flyId);

				const wrongId = playAudio(this.wrongClip);
				cc.audioEngine.setVolume(wrongId, 0.5);
			})
			.delay(0.15)
			.to(1, {y: this.chickNode.bottomY}, {easing: "cubicIn"})
			.call(() => {
				
			})
			.start();
	},

	showScoreItem(baseItem, offX, offY) {
		console.log(' in showScoreItem ')
		const scoreItem = getSprNode("score_item");
		// scoreItem.parent = baseItem;
		// scoreItem.x = offX;
		// scoreItem.y = offY;

		scoreItem.parent = baseItem.parent;
		scoreItem.x = baseItem.x + offX;
		scoreItem.y = baseItem.y + offY;


		const targetScoreBg = this.scoreBgArr[this.curQuesIndex];
		if (targetScoreBg.scoreItem) {
			targetScoreBg.scoreItem.removeFromParent();
		}
		targetScoreBg.scoreItem = scoreItem;


		// const targetScoreBg2 = this.scoreBgArr[this.scoreBgArr.length - 1 - this.curQuesIndex];
		// console.log("targetScoreBg2.x: ", targetScoreBg2.x);

		const targetPos1 = exchangeNodePos(scoreItem.parent, targetScoreBg);


		// const wordPos1 = targetScoreBg.parent.parent.convertToWorldSpaceAR(cc.v2(targetScoreBg.parent.x + targetScoreBg.x, targetScoreBg.parent.y + targetScoreBg.y))
		// const targetPos1 = scoreItem.parent.convertToNodeSpaceAR(wordPos1);
		// targetPos1.x /= -2;
		// console.log('wordPos1: ', wordPos1);
		console.log('targetPos1: ', targetPos1);


		// const localPos = exchangeNodePos(targetScoreBg.parent, scoreItem);
		// scoreItem.parent = targetScoreBg.parent;

		// scoreItem.x = localPos.x;
		// scoreItem.y = localPos.y;


		const flyTime = 1.1;
		const bezier = [cc.v2(scoreItem.x, scoreItem.y), cc.v2(targetPos1.x + 150, targetPos1.y - 150),  cc.v2(targetPos1.x, targetPos1.y)]
		const bezierTo = cc.bezierTo(flyTime, bezier).easing(cc.easeSineInOut());

		scoreItem.runAction(bezierTo)

		scoreItem.scale = 0.3;
		cc.tween(scoreItem)
			.to(flyTime, {angle: 720, scale: 1}, {easing: "sineInOut"})
			// .to(flyTime, {angle: 360, scale: 1})
			.call(() => {
				// playAudio(this.popClip);

				const localPos = exchangeNodePos(targetScoreBg, scoreItem);
				scoreItem.parent = targetScoreBg;

				scoreItem.x = localPos.x;
				scoreItem.y = localPos.y;
			})
			.start();

		cc.tween(scoreItem)
			.delay(flyTime + 0.05)
			.call(() => {

				
				this.showScorePop(scoreItem);
			})
			.start();

		cc.tween({})
			.delay(0.05)
			.call(() => {
				playAudio(this.flyClip);
			})
			.start();
	},

	showScorePop(scoreItem) {

		this.showPopParticle(scoreItem);

		const labelNode = this.getLabel(this.curQues.score + "分", 40);
		labelNode.color = cc.Color.WHITE;
		labelNode.parent = scoreItem;


		this.isShowChick = false;
		this.refreshBottomBtns();
		this.checkIsEnd();

	},

	checkIsEnd() {
		for (let i=0; i<this.quesArr.length; i++) {
			if (this.quesArr[i].score == null) {
				return;
			}
		}

		this.gameEnd();
	},


	showPopParticle(scoreItem) {
		playAudio(this.popClip);

			
		const pNode = new cc.Node();
		const localPos = exchangeNodePos(this.canvas, scoreItem);
		pNode.parent = this.canvas;
		pNode.x = localPos.x;
		pNode.y = localPos.y;


		const popCount = 20;
		for (let i=0; i<popCount; i++) {

			const particle = this.getOneParticle();
			pNode.addChild(particle, 2);
			particle.angle = Math.random() * 360;
			
			const targetScale = Math.random() * 0.5 + 0.5;
			particle.scale = targetScale * 0.3;

			const startMaxLen = 50;
			const endMaxLen = 150;
			const dir = Math.random() * 360;
			
			const startPos = getPosByAngle(dir, Math.random() * startMaxLen);
			const endPos = getPosByAngle(dir, Math.random() * (endMaxLen - startMaxLen) + startMaxLen);

			particle.x = startPos.x;
			particle.y = startPos.y;
			particle.opacity = 0;

			const popTime = 0.7;
			const randomA = 270;

			cc.tween(particle)
				.by(popTime, {angle: Math.random() * randomA*2 - randomA}, {easing: "cubicOut"})
				.call(() => {
					pNode.removeFromParent();
				})
				.start();

			cc.tween(particle)
				.to(popTime - 0.3, {opacity: 255})
				.delay(0.1)
				.to(0.3, {opacity: 0})
				.start();

			cc.tween(particle)
				.to(popTime, {x: endPos.x, y: endPos.y, scale: targetScale}, {easing: "cubicOut"})
				.start();
		}

	},
	getOneParticle() {
		const id = Math.ceil( Math.random() * 6 );
		const p = getSprNode("p_" + id);
		return p;
	},


	exchangeNodePos(targetNode, baseNode, basePos) {
        return targetNode.convertToNodeSpaceAR(baseNode.convertToWorldSpaceAR(cc.v2(basePos.x, basePos.y)));
    },



	getAnimNode(resName) {

		const animNodeBase = cc.find("Canvas/res/anim/" + resName);
		const animNode = cc.instantiate( animNodeBase );
		animNode.anim = animNode.getComponent(dragonBones.ArmatureDisplay);
		animNode.anim.timeScale = 0;
		return animNode
	},
	



	showNextBtn() {
		const nextBtn = cc.find("next_btn", this.roleNode);

		const label = cc.find("label", nextBtn).getComponent(cc.Label);
		label.string = this.data.endTips || '';

		nextBtn.active = true;
		nextBtn.opacity = 0;
		this.btnToOpacity(nextBtn, 255);

		nextBtn.on('touchstart', () => {
			const middleLayer = cc.find('middleLayer');
			if (middleLayer) {
				middleLayer.getComponent('middleLayer').goNextPage();
			}
		})

		if (!this.data.endTips) {
			nextBtn.active = false;
		}
	},

	initRole() {
		this.roleNode = cc.find("Canvas/xiaodi");
		this.roleNode.scale = this._mapScaleMin * 0.6;
		this.roleNode.x = -this.canvas.width;
		this.roleNode.y = -this.canvas.height / 2 + 350 * this._mapScaleMin;

		this.roleNode.anim = this.roleNode.getComponent(dragonBones.ArmatureDisplay);

		this.roleNode.targetX = this.canvas.width * 0.3;
		this.roleNode.baseX = this.roleNode.x;
	},

	async showRole() {
		this.roleNode.active = true;
		cc.tween(this.roleNode)
			.to(1.5, {x: this.roleNode.targetX})
			.call(() => {
				if (this.isGameEnd) {
					this.showEndTip();
				} else {
					this.showEnterTip();
				}
			})
			.start();

		this.roleNode.anim.playAnimation("run", -1);
		this.roleNode.scaleX = -Math.abs(this.roleNode.scaleX);


		await asyncDelay(0.2);
		if (this.isDestroy) {
			return;
		}

		// const dragonDisplay = this.grassNode.getComponent(dragonBones.ArmatureDisplay);
		// dragonDisplay.playAnimation("2left", 1);
		// dragonDisplay.timeScale = 1;

	},

	hideRole() {
		cc.tween(this.roleNode)
		.to(1.5, {x: this.roleNode.baseX})
		.call(() => {
			this.hideMask();
		})
		.start();

		this.roleNode.anim.playAnimation("run", -1);
		this.roleNode.scaleX = Math.abs(this.roleNode.scaleX);

	},

	showEnterTip() {

		playAudioByUrl(this.data.startAudioUrl, () => {
			this.roleNode.anim.playAnimation("normal", -1);
			this.hideRole()
			
		})
		this.roleNode.anim.playAnimation("talk", -1);
		this.roleNode.scaleX = Math.abs(this.roleNode.scaleX);
	},

	showEndTip() {

		playAudioByUrl(this.data.endAudioUrl, () => {
			this.roleNode.anim.playAnimation("normal", -1);
		
			this.showNextBtn();
			
		})
		this.roleNode.anim.playAnimation("talk", -1);
		this.roleNode.scaleX = Math.abs(this.roleNode.scaleX);
	},

	async initScore() {
		
		const count = this.quesArr.length;
		const scoreBgParent = cc.find("Canvas/bg/panel")
		const disX = 190;
		const baseX = -(count - 1) / 2 * disX;
		this.scoreBgArr = [];

		const scoreBg = cc.find("Canvas/bg/scrollView/view/content");

		for (let i=0; i<this.quesArr.length; i++) {

			const scoreItemBg = this.getScoreItemBg();
			scoreItemBg.parent = scoreBg //scoreBgParent;
			// scoreItemBg.x = baseX + i * disX;
			// scoreItemBg.y = 230;

			this.scoreBgArr[i] = scoreItemBg;

			await asyncDelay(0.1 * i);
		}
	},

	getScoreItemBg() {
		const scoreItemBg = getSprNode("score_bg");
		return scoreItemBg;
	},

	initBottomPlayer() {
		this.playBtn = cc.find("Canvas/bottom_player/play_btn_bg");
		this.playBtn.playIcon = cc.find("play_btn", this.playBtn);
		this.playBtn.stopIcon = cc.find("stop_btn", this.playBtn);

		this.soundBtn = cc.find("Canvas/bottom_player/sound_btn_bg");
		this.soundBtn.icon = cc.find("icon", this.soundBtn)
		this.soundBtn.anim = cc.find("anim", this.soundBtn).getComponent(cc.Animation);

		this.speakBtn = cc.find("Canvas/bottom_player/speak_btn_bg");
		this.speakBtn.pb = this.speakBtn.getComponent(cc.ProgressBar);
		this.speakBtn.icon_0 = cc.find("icon_0", this.speakBtn);
		this.speakBtn.icon_1 = cc.find("icon_1", this.speakBtn);

		this.leftBtn = cc.find("Canvas/bottom_player/arrow_left");
		this.rightBtn = cc.find("Canvas/bottom_player/arrow_right");

		this.playBtn.top = cc.find("top", this.playBtn);
		this.soundBtn.top = cc.find("top", this.soundBtn);
		this.speakBtn.top = cc.find("top", this.speakBtn);


		this.leftBtn.on("touchstart", () => {
			if (this.leftBtn.opacity < 254) {
				return;
			}
			this.lastBtnClick();
			this.moveScrollView();

		})

		this.rightBtn.on("touchstart", () => {
			if (this.rightBtn.opacity < 254) {
				return;
			}
			this.nextBtnClick();

			this.moveScrollView();

		})
		

		this.soundBtn.on("touchstart", ()=> {
			if (this.soundBtn.opacity < 254) {
				return;
			}
			// playAudio(this.btn_1Clip);
			this.playSoundAnim();
		})

		this.speakBtn.on("touchstart", () => {
			if (this.speakBtn.opacity < 254) {
				return;
			}

			playAudio(this.btn_1Clip);
			if (this.isRecord) {
				this.recordStop();
			} else {
				this.recordStart();
			}
		})

		this.playBtn.on("touchstart", () => {
			if (this.playBtn.opacity < 254) {
				return;
			}
			playAudio(this.btn_1Clip);
			this.showUserAudio();
		})
	},

	showUserAudio() {
		const {userAudioUrl} = this.curQues;
		if (!userAudioUrl) {
			return;
		}

		this.isPlayUserAudio = true;
		this.refreshBottomBtns();

		playAudioByUrl(userAudioUrl, () => {

			this.isPlayUserAudio = false;

			this.refreshBottomBtns();
		})
	},

	playSoundAnim() {

		if (!this.curQues.audioUrl) {
			return;
		}

		const anim = this.soundBtn.anim;
		const icon = this.soundBtn.icon;

		if (anim.node.active) {
			return;
		}

		icon.active = false;
		anim.node.active = true;
		anim.play("sound");
		this.isSoundPlay = true;

		this.refreshBottomBtns();


		playAudioByUrl(this.curQues.audioUrl, () => {
			this.isSoundPlay = false;

			anim.stop();
			anim.node.active = false;
			icon.active = true;

			this.refreshBottomBtns();

		});
	},

	nextBtnClick() {
		
		
		playAudio(this.btnClip);

		this.curQuesIndex ++;
		this.initCurQues();

		this.refreshCurPanel(true);
	},

	lastBtnClick() {

		playAudio(this.btnClip);

		this.curQuesIndex --;
		this.initCurQues();

		this.refreshCurPanel(true);
	},





    recordStart() {
		
		this.speakBtn.icon_0.active = true;
		this.speakBtn.icon_1.active = false;


		this.isRecord = true;
        this.showRecordProgress();

		this.refreshBottomBtns();

		this.serverStartTest(this.curQues.val);

		return;

        if (this.recordIntervalId) clearInterval(this.recordIntervalId);

		this.voiceNode.progressBarNode.active = true;
		this.voiceNode.voiceIcon.active = false;

        // this.showRecordProgress();

		const courseware = window.courseware;
		if (!courseware) {
			return;
		}
        courseware && courseware.startRecord(1); //开始录音
    },

	recordStop() {

		if (!this.isRecord) {
			return;
		}

		this.speakBtn.icon_0.active = false;
		this.speakBtn.icon_1.active = true;

		this.isRecord = false;

		this.serverStopTest();


		return;

        let testData = {
            "text": "oh no",
            "audio": "https://staging-teach.cdn.ireadabc.com/6ee3ccaa831a884f02c6a75c6f647cb5.wav"
        }

		const courseware = window.courseware;
        if (!courseware) return this.recordEnd(testData)

		this.canTouch = false;
        courseware && courseware.stopRecord(0, (data) => {
			this.canTouch = true;
            data = JSON.parse(data);
            console.log("data: " + JSON.stringify(data));
            this.recordEnd(data);
        }); //结束录音
	},


	serverStartTest(text) {

		console.log(' in serverStartTest: ', text);
		const cw = window?.courseware
		if (cw) {
			this.curTestText = text;
			cw.startTest(text);
		}

	},

	serverStopTest(cb=null) {

		console.log(' in serverStopTest');
		this.showMask();

		// const tmpData = {
		// 	refText: 'ant apple alligator ax.',
		// 	audioUrl: 'https://staging-teach.cdn.ireadabc.com/f01f0d63c0c4c0dd1203a6202ecaf34b.wav',
		// 	result:{
		// 		overall: Math.random() * 40 + 60,
		// 	}
		// }

		// this.setRecordItemAudio(tmpData, this.curQues);
		// cb && cb(tmpData);

		// return;

		const overtime = 7;
		const cw = window?.courseware
		if (cw) {

			let isStopTest = false;
			let overtimeId = setTimeout(() => {
				if (isStopTest) {
					return;
				}
				isStopTest = true;
			
				cb && cb();
				this.hideMask();
			}, overtime * 1000);


			cw.stopTest(data => {
				if (isStopTest) {
					return;
				}
				isStopTest = true;
				clearTimeout(overtimeId);

				console.log('stopTest data: ', data);

				if (data && typeof (data) == 'string') {
					console.log(JSON.parse(data));
					data = JSON.parse(data)
				}

				this.setRecordItemAudio(data, this.curQues);
				cb && cb();

			});
		}


		// if (this.curQuesIndex >= this.quesArr.length - 1) {

		// 	onHomeworkFinish();
		// 	console.log(' in serverStopTest onHomeworkFinish');
		// }
	},

	setRecordItemAudio(data, ques) {
		
		this.hideMask();

		if (data.errCode) {
			this.hideMask();
			return;
		}

		const audioUrl = data.audioUrl;

		// 只做预加载用一下
		if (!audioUrl) {
			this.hideMask();
			return;
		}

		
		const overall = data.result?.overall;
		const integrity = data.result?.integrity;
		let score = overall //integrity * 0.4 + overall * 0.6; //data.result?.overall;

		setSRRecord(this.curTestText, score);

		if (this.rightWord) {
		
			score = this.getScoreByRightWord(data, score);
		
		}



		ques.userAudioUrl = audioUrl;
		ques.score = score;

		console.log('overall is : ', overall);
		console.log('integrity is : ', integrity);
		console.log('score is : ', score);


		this.showScoreNode(score, true);

		this.refreshPageDotArea();

		this.checkIsEnd();


		return;


		if (score >= 60) {
			this.showChickRight();
		} else {
			this.showChickWrong();
		}

		this.moveScrollView();

		// this.isStarShowEnd = false;
		// this.isUserAudioDownLoad = false;

		// let count = 0;
		// if (score >= 85) {
		// 	count = 3;
		// } else if (score >= 75) {
		// 	count = 2;
		// } else if (score >= 60) {
		// 	count = 1;
		// }

		
		// item.starCount = count;
		// this.showStar(item, count);
		// this.showListenBtn(item);



		this.refreshBottomBtns();

	
		this.getAudioClipByUrl(audioUrl, (clip) => {
			// console.log(' in getAudioClipByUrl audioUrl:', audioUrl);

			// this.audioObj[audioUrl] = clip;

			// this.isUserAudioDownLoad = true;
			// this.checkCanCompose();
			// // this.showListenBtn(item);

			// this.hideMask();
		})
	},

	getScoreByRightWord(data, baseScore) {
		console.log(" in getScoreByRightWord");
		let newScore = baseScore;
		const sentences = data?.result?.sentences;
		if (sentences) {
			sentences.forEach(it => {
				const details = it.details;

				if (details) {
					console.log('details: ' + JSON.stringify(details));
					const wordData = details.find(it => {
						return it.word == this.rightWord.trim();
					});
					if (wordData) {
						console.log('wordData: ', JSON.stringify(wordData));
						if (wordData.overall < 60) {
							newScore = 0;
						}	
					}
				}

			});
		}


		// const details = data?.result?.sentences[0].details;
		// if (details) {
		// 	console.log('details: ' + JSON.stringify(details));
		// 	const wordData = details.find(it => {
		// 		it.word == this.rightWord.trim();
		// 	});
		// 	if (wordData) {
		// 		console.log('wordData: ', JSON.stringify(wordData));
		// 		if (wordData.overall < 60) {
		// 			return 0;
		// 		}	
		// 	}
		// }

		return newScore;
	},

	showScoreNode(score, isAnim=false) {
	
		if (!this.recordNode.scoreNode) {
			const scoreNodeBase = cc.find("Canvas/scoreNode");
			const scoreNode = cc.instantiate(scoreNodeBase);
			scoreNode.parent = this.recordNode;
			// scoreNode.x = this.recordNode.width / 2;
			scoreNode.y = 10;
			this.recordNode.scoreNode = scoreNode;
			scoreNode.scale = 0.8;
			scoreNode.zIndex = 10;
		}

		let scoreNode = this.recordNode.scoreNode;
		scoreNode.active = true;


		let icon2 = cc.find("icon_2", scoreNode);
		let icon1 = cc.find("icon_1", scoreNode);
		let icon0 = cc.find("icon_0", scoreNode);
		
		icon2.active = false;
		icon1.active = false;
		icon0.active = false;

		let audioClip;
		if (score > 80) {
			icon2.active = true;
			audioClip = this.excellentClip;
		} else if (score > 60) {
			icon1.active = true;
			audioClip = this.goodClip;
		} else {
			icon0.active = true;
			audioClip = this.tryagainClip;
		}

		if (isAnim) {

			scoreNode.opacity = 0;
			scoreNode.scale = 1.3;
			cc.tween(scoreNode)
			.to(0.7, {opacity: 255, scale: 0.6}, {easing:"expoIn"})
			.start();
			this.curQues.score = score;

			playAudio(audioClip);
		}

	},

	hideScoreNode() {
		if (!this.recordNode.scoreNode) {
			return;
		}

		let scoreNode = this.recordNode.scoreNode;
		scoreNode.active = false;
	},

	moveScrollView() {


		const scrollView = cc.find("Canvas/bg/scrollView").getComponent(cc.ScrollView);

		let maxScrollOffset = this.getMaxScrollOffset();
		console.log('maxScrollOffset: ', maxScrollOffset);
		console.log('scrollView: ', scrollView);
		scrollView.scrollToOffset(cc.v2(maxScrollOffset, 0), 0.9);
	},

	scoreItemW: null,
	getMaxScrollOffset() {
		if (!this.scoreItemW) {
			this.scoreItemW = getSprNode("score_bg").width;
		}

		const scoreItemDis = 30;
		const offX = (this.curQuesIndex - 3) * (this.scoreItemW + scoreItemDis);
		return offX;
	},


	getAudioClipByUrl(audioUrl, cb) {

		if (audioUrl) {
			cc.assetManager.loadRemote(audioUrl, (err, audioClip) => {
				cb && cb(audioClip);
				// playAudio(audioClip, cb);
			});
		}

	},



	showRightTip() {
		this.canTouch = false;
		playAudioByUrl(this.tipAudioRight, () => {
			this.canTouch = true;
			this.roleNode.anim.playAnimation("normal", -1);
		})
		this.roleNode.anim.playAnimation("talk", -1);
	},

	showWrongTip() {
		this.canTouch = false;
		playAudioByUrl(this.tipAudioWrong, () => {
			this.canTouch = true;
			this.roleNode.anim.playAnimation("normal", -1);
		})
		this.roleNode.anim.playAnimation("talk", -1);
	},


	showRecordProgress() {
		const progressBar = this.speakBtn.pb//this.voiceNode.progressBarNode.progressBarComp;
		let percent;

		const startTime = new Date().getTime();
		let totalTime = 0;
		let targetTime = 10;
		this.recordIntervalId = setInterval(() => {
			
			if (this.isDestroy || !this.isRecord) {
				clearInterval(this.recordIntervalId);
				progressBar.progress = 0;
				return
			}
			totalTime = (new Date().getTime() - startTime) / 1000;
			if (totalTime >= targetTime) {
				clearInterval(this.recordIntervalId);
				progressBar.progress = 0;
				this.recordStop()
				return;
			}

			percent = totalTime / targetTime;
			progressBar.progress = percent

		}, 10);

	},






	


	initTestPointArr() {
		
		const linkeItemArr = this.data.hotZoneItemArr.filter(hzItem => {
			return hzItem.gIdx == '0';
		})

		const bgRect = this.data.bgItem2.rect;

		const setDebugCenterPos = (hzItem) => {

			const debugItemIndex = (Number(hzItem.pointItem) - 1) 
			const debugItem = this.data.hotZoneItemArr2[debugItemIndex];
			const {rect} = debugItem

			const left = Math.round( (rect.x ) / bgRect.width  * 1000 ) / 1000;
			const right =  Math.round( (rect.x + rect.width) / bgRect.width * 1000 ) / 1000;
			const top =  Math.round( (rect.y ) / bgRect.height * 1000 ) / 1000;
			const bottom =  Math.round( (rect.y + rect.height) / bgRect.height * 1000 ) / 1000;
	
			
			const x = left + (right - left) / 2;
			const y = bottom - (bottom - top) / 2;

			hzItem.debugCenterPos = [x, y];
		}

		console.log('linkeItemArr: ', linkeItemArr);

		linkeItemArr.forEach(hzItem => {
			return setDebugCenterPos(hzItem);
		})

		const startPosObj = {};
		const endPosObj = {};

		for (let i=0; i<linkeItemArr.length; i++) {
			const index = this.data.hotZoneItemArr.indexOf(linkeItemArr[i]);
			const key = (index + 1).toString();
			if (!startPosObj[key] && !endPosObj[key]) {
				startPosObj[key] = linkeItemArr[i];


				const endKey = linkeItemArr[i].linkItem.toString();
				const endIndex = Number(endKey) - 1;
				const endItem = this.data.hotZoneItemArr[endIndex];
				endPosObj[endKey] = endItem;
			}
		}

		console.log('startPosObj: ', startPosObj);
		console.log('endPosObj: ', endPosObj);

		
		console.log('this.end_points: ', this.end_points);

	
	},

	resetHotZoneBg() {

		this.hotZoneBg.opacity = 0;	
		const panel = this.hotZoneBg.parent;
		const w = panel.width * 0.95;
		const h = panel.height * 0.9;
		

		const region = this.getRegionsByGidx('2')[0];
		const partW = region.right - region.left;
		const partH = region.bottom - region.top;
		const scaleX = w / partW;
		const scaleY = h / partH;
		const scale = Math.min(scaleX, scaleY);
		const bgW = partW * scale;
		const bgH = partH * scale;

		const node = new cc.Node();
		node.parent = panel;
		node.width = bgW / partW;
		node.height = bgH / partH;

		const rectX = (-0.5 + region.left) * node.width;
		const rectY = (0.5 - region.bottom) * node.height;
		const rectW = partW * node.width;
		const rectH = partH * node.height;
		const ctx = node.addComponent(cc.Graphics);
		ctx.rect(rectX, rectY, rectW, rectH);
		ctx.fillColor = cc.Color.WHITE;
		ctx.fill();

		node.y = 3 - (rectY + rectH / 2);

		this.colorDrawLayer = new cc.Node();
		node.addChild(this.colorDrawLayer);
		
		this.colorBg = node;
	},


	checkStart() {

		console.log(' in checkStart')
		if (this.debugBgImg && this.hzLoadEnd && this.catBeginEnd) {
			this.startTesting();

		}

	},

	getSendCirclePoints(tempCirclePointArr) {

		console.log('tempCirclePointArr: ' , tempCirclePointArr);
		
		const sendCirclePointArr = [];

		for (let i=0; i<tempCirclePointArr.length; i++) {
			const {left, top, right, bottom, isMultRect} = tempCirclePointArr[i];

			let data;
			if (isMultRect) {
				console.log("in isMultRect")
				data = {
					left,
					right,
					top,
					bottom
				}
			} else {
				let newLeft = left + (right - left) / 2;
				let newTop = top + (bottom - top) / 2;
				newLeft = roundNum(newLeft, 10000);
				newTop = roundNum(newTop, 10000);
				data = {
					left: newLeft,
					right: newLeft,
					top: newTop,
					bottom: newTop
				}
			}

			console.log("data~:", data);
			sendCirclePointArr.push(data);
			// const tempLink1 = tempCirclePointArr[i];
			// const key2 = tempLink1.linkItem;
			// const tempLink2 = tempCirclePointArr[Number(key2)-1];

			// if (!tempLink1.isGetLinked && !tempLink2.isGetLinked) {
			// 	tempLink1.isGetLinked = true;
			// 	tempLink2.isGetLinked = true;

			// 	const pKey1 = tempLink1.pointItem;
			// 	const pKey2 = tempLink2.pointItem;

			// 	const pointItem1 = this.data.hotZoneItemArr2[Number(pKey1) - 1];
			// 	const pointItem2 = this.data.hotZoneItemArr2[Number(pKey2) - 1];

			// 	const region1 = this.getRegionByRect(pointItem1.rect, bgRect);
			// 	const region2 = this.getRegionByRect(pointItem2.rect, bgRect);

			// 	let x1 = region1.left + (region1.right - region1.left) / 2;
			// 	let y1 = region1.top + (region1.bottom - region1.top) / 2;

			// 	let x2 = region2.left + (region2.right - region2.left) / 2;
			// 	let y2 = region2.top + (region2.bottom - region2.top) / 2;

			// 	x1 = Math.floor(x1 * 1000) / 1000;
			// 	y1 = Math.floor(y1 * 1000) / 1000;
			// 	x2 = Math.floor(x2 * 1000) / 1000;
			// 	y2 = Math.floor(y2 * 1000) / 1000;

			// 	sendCirclePointArr.push( {left:x1, top: y1, right:x2, bottom: y2} )
			// }
		}

		console.log("sendCirclePointArr: ", sendCirclePointArr);
		return sendCirclePointArr;
	},


	getSendLinePoints() {

		const hotZoneItemArr = JSON.parse( JSON.stringify(this.data.hotZoneItemArr) );

		const tempLinkArr = this.getGroupArrByGIdx(hotZoneItemArr, '0');

		console.log('tempLinkArr: ' , tempLinkArr);

		const bgRect = this.data.bgItem2.rect;
		
		const sendLinkPointArr = [];


		for (let i=0; i<tempLinkArr.length; i++) {
			const tempLink1 = tempLinkArr[i];
			const key2 = tempLink1.linkItem;
			const tempLink2 = hotZoneItemArr[Number(key2)-1];

			if (!tempLink1.isGetLinked && !tempLink2.isGetLinked) {
				tempLink1.isGetLinked = true;
				tempLink2.isGetLinked = true;

				const pKey1 = tempLink1.pointItem;
				const pKey2 = tempLink2.pointItem;

				const pointItem1 = this.data.hotZoneItemArr2[Number(pKey1) - 1];
				const pointItem2 = this.data.hotZoneItemArr2[Number(pKey2) - 1];

				const region1 = this.getRegionByRect(pointItem1.rect, bgRect);
				const region2 = this.getRegionByRect(pointItem2.rect, bgRect);

				let x1 = region1.left + (region1.right - region1.left) / 2;
				let y1 = region1.top + (region1.bottom - region1.top) / 2;

				let x2 = region2.left + (region2.right - region2.left) / 2;
				let y2 = region2.top + (region2.bottom - region2.top) / 2;

				x1 = Math.floor(x1 * 1000) / 1000;
				y1 = Math.floor(y1 * 1000) / 1000;
				x2 = Math.floor(x2 * 1000) / 1000;
				y2 = Math.floor(y2 * 1000) / 1000;

				sendLinkPointArr.push( {left:x1, top: y1, right:x2, bottom: y2} )
			}
		}

		console.log("sendLinkPointArr: ", sendLinkPointArr);
		return sendLinkPointArr;

		// for (let i=0; i<regions.length; i++) {
		// 	const oneRegion = regions[i];
		// 	console.log('oneRegion: ', oneRegion);
		// 	const x = oneRegion.left + (oneRegion.right - oneRegion.left) / 2;
		// 	const y = oneRegion.top + (oneRegion.bottom - oneRegion.top) / 2;
		// }
	},


	resetHelperTime() {

		this.helperTime = new Date().getTime();

	},

	showHelper() {

		if (!this.isHelp) {
			return;
		}

		if (this.itemCombineGroup && this.itemCombineGroup.length > 0) {
			return;
		}

		console.log("in showHelper");

		this.helpAudioId = playAudio(this.helpClip, () => {

			this.helpAudioId = null;

			switch(this.curCheckGroup) {
				case this.CHECK_TYPE_LINE:
					this.showHelperLink();
					// 连线
					break;
	
				case this.CHECK_TYPE_WRITE:
					this.showHelperWrite();
					// 手写
					break;
	
				case this.CHECK_TYPE_CIRCLE:
					this.showHelperCircle();
					// 画圈
					break;
	
				case this.CHECK_TYPE_SIGN:
					this.showHelperSign();
					// 符号
					break;
			}

		})
		
	},

	showHelperSign() {

		for (let i = 0; i < this.signAnimaNodeArr.length; i++) {

			const animaNode = this.signAnimaNodeArr[i];

			if (!animaNode.isShowEnd) {
		
				this.showSign(animaNode);
				break;
			}
			
		}
	},
	

	showHelperCircle() {
		
		for (let i = 0; i < this.circleAnimaNodeArr.length; i++) {

			const animaNode = this.circleAnimaNodeArr[i];

			if (!animaNode.isShowEnd) {

				this.showCircle(animaNode);
				break;				
			}
			
		}

	},

	showHelperWrite() {

		let arr = this.animaNodeArr;
		if (this.picAnimNodeArr.length > 0) {
			arr = this.picAnimNodeArr;
		}

		for (let i = 0; i < arr.length; i++) {

			const animaNode = arr[i];
			if (!animaNode.isShowEnd) {

				if (this.picAnimNodeArr.length > 0) {
					this.showLetterPic(animaNode);
				} else {
					this.showLetter(animaNode);
				}
				break;
			}
		}
	},

	
	showHelperLink() {

		console.log(' in showHelperLink..');
		
		let item;
		for (let i=0; i<this.linkRectGroup.length; i++) {

			const {hzItemId} = this.linkRectGroup[i].linkData;

			const rectNode = this.getItemById(hzItemId);
			
			if (!rectNode.isShowEnd && this.linkRectGroup[i].isRightPoint) {
				item = this.linkRectGroup[i];
				break;
			}
		}

		if (item) {
			const {hzItemId, linkHzItemId} = item.linkData
			this.showSuccess(hzItemId, linkHzItemId);
		}
	},


	startHelper() {

		this.resetHelperTime();
		this.isHelpCountDown = true;

		const checkTime = () => {

			if (!this.isHelpCountDown) {
				return;
			}

			let disTime = 10;
			if (this.data.helpTime) {

				if (this.data.helpTime <= 0) {
					return;
				}
				disTime = this.data.helpTime;
			}

			const curTime = new Date().getTime();
			if (curTime - this.helperTime > disTime * 1000) {
				this.showHelper();
				this.resetHelperTime();
			} 
			// else {
	
			// 	delayCall(0.1, () => {
			// 		checkTime();
			// 	})
			// }

			delayCall(0.05, () => {
				checkTime();
			})
		}

		checkTime();
		
	},

	pauseHelper() {
		if (this.helpAudioId) {
			cc.audioEngine.stopEffect(this.helpAudioId);
			this.helpAudioId = null;
		}
	},

	stopHelper() {
		this.isHelpCountDown = false;
	},


	//调起检测
	startTesting() {


		this.isGameEnd = false;

		this.startHelper();


		const writeRegions = this.getRegionsByGidx('6')
		const circleRegions = this.getRegionsByGidx('7')
		const signRegions = this.getRegionsByGidx('8')
		const colorRegions = this.getRegionsByGidx('9')
		const partRegions = this.getRegionsByGidx('2')
		const numberRegions = this.getRegionsByGidx('10')

		// this.changeRegionTo4Pos(signRegions);


		// let lineRegions = this.getRegionsByGidx('0')

		const newPoints = this.getSendLinePoints();
		const newCirclePoints = this.getSendCirclePoints(circleRegions);

		console.log('writeRegions: ', writeRegions);
		console.log('circleRegions: ', circleRegions);
		console.log('newPoints: ', newPoints);
		console.log('signRegions: ', JSON.stringify(signRegions));
		console.log('newCirclePoints: ', newCirclePoints);
		console.log('partRegions: ', partRegions);
		console.log('numberRegions: ', numberRegions);

		

	 

		// const tempType = this.typeArr[this.typeArrIndex];
		// this.curCheckType = '';
		// switch(tempType.gIdx) {
		// 	case "0":
		// 		// 连线
		// 		this.curCheckGroup = this.CHECK_TYPE_LINE;
		// 		break;

		// 	case "1":
		// 		// 手写
		// 		if (partRegions && partRegions.length > 0) {
		// 			this.partRegions = partRegions;
		// 		} else {
		// 			// para.write_regions = writeRegions;
		// 		}
		// 		this.curCheckGroup = this.CHECK_TYPE_WRITE;
		// 		break;

		// 	case "2":
		// 		// 画圈
		// 		this.curCheckGroup = this.CHECK_TYPE_CIRCLE;
		// 		break;

		// 	case "4":
		// 		// 符号
		// 		this.curCheckGroup = this.CHECK_TYPE_SIGN;
		// 		this.signRegions = signRegions ;
		// 		this.initItemCombineGroup();
		// 		break;

		// 	case "5":
		// 		// 涂色
		// 		this.curCheckGroup = this.CHECK_TYPE_COLOR;
		// 		break;

							
		// 	case "6":
		// 		// 手写图片

		// 		if (partRegions && partRegions.length > 0) {
		// 			this.partRegions = partRegions;
		// 		} else {

		// 		}

		// 		this.curCheckGroup = this.CHECK_TYPE_WRITE;
		// 		break;
		// 	}

			

		// 	setInterval(() => {
		// 		this.getPhotoData((data) => { 
		// 			this.photoEnd(data);
		// 		});    
		// 	}, 3000);

		// 	console.log('curCheckGroup: ', JSON.stringify( this.curCheckGroup ));

		// return;





		// write_regions : []

		let lineType = 1;
		let circleSize = 1;

		if (this.data.lineType == '0') {
			lineType = 0;
		}
		if (this.data.circleSize == '0') {
			circleSize = 0;
		}
		
		

		const para = {
			"library_id": "iplayabc",
			"page_id": this.data.page_id, //27,
			"book_id": this.data.book_id,//"opw1",
			"part_name": this.data.part_name, //"d",
		
			"write_regions": [],
			"circle_regions": [],//circleRegions,
			"line_regions": [],
			'sign_regions': [],
			'color_regions': [],
			lineType,
			circleSize
		}


	

		const curCheckGroup = this.typeArr[this.typeArrIndex];
		this.curCheckType = '';

		console.log('curCheckGroup.gIdx: ', curCheckGroup.gIdx);
		switch(curCheckGroup.gIdx) {
			case "0":
				// 连线
				para.line_regions = newPoints;
				this.curCheckGroup = this.CHECK_TYPE_LINE;
				break;

			case "1":
				// 手写

				if (partRegions && partRegions.length > 0) {
					para.write_regions = partRegions;
					this.partRegions = partRegions;
				} else {
					para.write_regions = writeRegions;
				}
				this.curCheckGroup = this.CHECK_TYPE_WRITE;
				break;

			case "2":
				// 画圈
				para.circle_regions = newCirclePoints;
				this.curCheckGroup = this.CHECK_TYPE_CIRCLE;
				break;

			case "4":
				// 符号
				para.sign_regions = signRegions;
				this.signRegions = signRegions;
				this.curCheckGroup = this.CHECK_TYPE_SIGN;
				this.initItemCombineGroup();
				break;

			case "5":
				// 涂色
				// para.color_regions = colorRegions;
				para.color_regions = partRegions;
				this.curCheckGroup = this.CHECK_TYPE_COLOR;
				this.preloadColorSpr();
				break;
				
			case "6":
				// 手写图片

				if (partRegions && partRegions.length > 0) {
					para.write_regions = partRegions;
					this.partRegions = partRegions;
				} else {
					para.write_regions = writeRegions;
				}
				para.number_regions = numberRegions;
				this.curCheckGroup = this.CHECK_TYPE_WRITE;
				break;
		}


		console.log('curCheckGroup: ', JSON.stringify( this.curCheckGroup ));
		console.log('para: ', JSON.stringify( para ));


		const cw = window.courseware;
		if (!cw || !cw.openOsmoHandwriting) {

			console.log('cw.openOsmoHandwriting not exist');
			return;
		}

		cw.openOsmoHandwriting(para);

	},

	//结束检测
	endTesting() {
		
		this.stopHelper();

		const cw = window.courseware;
		if (!cw || !cw.closeOsmoHandwriting) {

			return;
		}
		cw.closeOsmoHandwriting();

		// const cw = window.courseware;
		// if (!cw || !cw.closeOsmoHandwritingMlkit) {

		// 	return;
		// }
		// cw.closeOsmoHandwritingMlkit();
		// // this.isTesting = false;
	},

	changeRegionTo4Pos(regions) {

		for (let i=0; i<regions.length; i++) {
			const {left, top, right, bottom} = regions[i];
			regions[i] = [

					left, top,
					right, top,
					right, bottom,
					left, bottom

			]
		}
		
	},

	initItemCombineGroup() {
		this.itemCombineGroup = this.data?.itemCombineGroup;
	},

	preloadColorSpr() {
		this.isHelp = false;
		for (let i=0; i<20000; i++) {
			const colorNode = this.getColorBgColorDot(0, 0, this.colorUnit, this.colorUnit);
		}
	},

	getRegionsByGidx(gIdx) {

		const arr = this.getGroupArrByGIdx(this.data.hotZoneItemArr2, gIdx);
		const bgRect = this.data.bgItem2.rect;
		
		console.log("arr:", arr);
		const newLocationArr = [];
		for (let i=0; i<arr.length; i++) {

			const hzItem = arr[i];
			const regionRect = hzItem.rect;

			let region = this.getRegionByRect(regionRect, bgRect);

			if (hzItem.multRect) {

				if (gIdx == "7") {
					region = this.getCircleRegionByMultRect(hzItem.multRect);
					console.log('region: ', region);
				}
			}

			newLocationArr.push(region)
		}

		return newLocationArr;

	},

	getRegionByRect(regionRect, bgRect) {

		const left = Math.round( (regionRect.x ) / bgRect.width  * 1000 ) / 1000;
		const right =  Math.round( (regionRect.x + regionRect.width) / bgRect.width * 1000 ) / 1000;
		const top =  Math.round( (regionRect.y ) / bgRect.height * 1000 ) / 1000;
		const bottom =  Math.round( (regionRect.y + regionRect.height) / bgRect.height * 1000 ) / 1000;

		return {left, top, right, bottom};
	},

	getCircleRegionByMultRect(multRect) {

		const bgRect = this.data.bgItem2.rect;
		const data1 = multRect[0];
		const data2 = multRect[1];
	
		const region1 = this.getRegionByRect(data1.rect, bgRect);
		const region2 = this.getRegionByRect(data2.rect, bgRect);

		let x1 = region1.left + (region1.right - region1.left) / 2;
		let y1 = region1.top + (region1.bottom - region1.top) / 2;
		let x2 = region2.left + (region2.right - region2.left) / 2;
		let y2 = region2.top + (region2.bottom - region2.top) / 2;

		x1 = roundNum(x1, 10000);
		y1 = roundNum(y1, 10000);
		x2 = roundNum(x2, 10000);
		y2 = roundNum(y2, 10000);

		return {left:x1, top:y1, right:x2, bottom:y2, isMultRect: true};
	},



	changeWriteData(result) {
		const curTextArr = result.text;
		const bboxTextArr = [];
		for (let i=0; i<curTextArr.length; i++) {

			const score = curTextArr[i].score;

			const {left, right, top, bottom} = curTextArr[i];
			const text = curTextArr[i].content;

			console.log('text..', JSON.stringify( curTextArr[i] ));
			console.log('text..', text);
			const disW = (right - left) / text.length;
			const disH = (bottom - top);
			for (let j=0; j<text.length; j++) {

				const x1 = left + j * disW;
				const y1 = top;

				const x2 = x1 + disW;
				const y2 = y1;

				const x3 = x2;
				const y3 = y2 + disH;

				const x4 = x1;
				const y4 = y3;

				// const bbox = [{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}]
				const bbox = {left: x1, right: x2, top: y1, bottom: y3}


				// this.changeBboxPos(bbox);

				const content = text[j];
				bboxTextArr.push({bbox, content, score});
			}

		}

		result.text = bboxTextArr;

	},


	locate(x1, y1, x2, y2, x3, y3) {
			var a, b;
			a = (y2 - y1) / (x2 - x1);
			b = y1 - a * x1;

			var xMiddle = (x1 + x2) / 2;
			var yMiddle = (y1 + y2) / 2;
			var c, lastX, lastY;
			if (a != 0) {
					c = yMiddle - (-1 / a) * xMiddle;
					lastX = (Math.pow(x1, 2) + Math.pow(y1, 2) - Math.pow(x3, 2) - Math.pow(y3, 2) - 2 * c * y1 + 2 * c * y3) / (2 * ((x1 - x3) - (1 / a) * (y1 - y3)));
					lastY = (-1 / a) * lastX + c;
			} else {
					lastX = c = xMiddle;
					lastY = (Math.pow(x1, 2) + Math.pow(y1, 2) - Math.pow(x3, 2) - Math.pow(y3, 2) + 2 * lastX * (x3 - x1)) / (2 * (y1 - y3));
			}
			console.log("定位点X坐标: " + lastX);
			console.log("定位点Y坐标: " + lastY);

			return {x: lastX, y: lastY};
	},

	

	setOneAnswerDataCircle(colorRect, answerData) {
		const rect = colorRect.ccRect;
		const dotV2 = new cc.Vec2(rect.x + rect.width/2, rect.y + rect.height / 2);


		// const targetLabelText = colorRect.labelText;

		// const newRectCheckArr = this.newRectCheckArr;
		const checkArr = this.circleRectCheckArr;

		for (let i=0; i<checkArr.length; i++) {

			const checkRect = checkArr[i].ccRect;
			const key = checkArr[i].data.index + 1;

			// if (labelText.toLowerCase().indexOf(targetLabelText.toLowerCase()) != -1 && rect.intersects(dotRect)) {
			if (checkRect.contains(dotV2)) {

				answerData[key] = {isFinish: true};

			}

		}

	},


	setOneAnswerDataLink(firstPos, lastPos, answerData) {


		const w = this.debugLayer.width;
    const h = this.debugLayer.height;
    const checkP1 = cc.v2(firstPos.x * w, -firstPos.y * h);
    const checkP2 = cc.v2(lastPos.x * w, -lastPos.y * h);



		let firstPosRectId = -1;
		let lastPosRectId = -1;

		const worldPos1 = this.debugLayer.convertToWorldSpaceAR(cc.v2(checkP1.x, checkP1.y));
		const worldPos2 = this.debugLayer.convertToWorldSpaceAR(cc.v2(checkP2.x, checkP2.y));


		// console.log('worldPos1: ', JSON.stringify(worldPos1));
		// console.log('worldPos2: ', JSON.stringify(worldPos2));

		for (let i=0; i<this.linkRectGroup.length; i++) {
			const rect = this.linkRectGroup[i].ccRect;

			// console.log('rect: ', JSON.stringify(rect));


      if (rect.contains(worldPos1)) {
        firstPosRectId = i;
        // break;
			} 
      if (rect.contains(worldPos2)) {
        lastPosRectId = i;
        // break;
			} 
		}

		console.log('firstPosRectId: ', firstPosRectId);
		console.log('lastPosRectId: ', lastPosRectId);

		if (firstPosRectId != -1 && lastPosRectId != -1 && firstPosRectId != lastPosRectId) {

      answerData[firstPosRectId.toString()] = [firstPosRectId, lastPosRectId];
      this.addDebugLayerDot(checkP1.x, checkP1.y, 10, cc.Color.GREEN);
      this.addDebugLayerDot(checkP2.x, checkP2.y, 10, cc.Color.GREEN);
    }

	},

	addDebugLayerDot(x, y, r=10, color = null) {
    const dotNode = new cc.Node();

    const ctx = dotNode.addComponent(cc.Graphics);
    ctx.fillColor = color || cc.Color.BLUE;
    ctx.circle(x, y, r);
    ctx.fill();

    this.debugDrawLayer.addChild(dotNode);

    const w = this.debugLayer.width;
    const h = this.debugLayer.height;
    const rateX = x / w;
    const rateY = y / h;
    
    console.log('ratePos: {x: ' + rateX + ', y: ' + rateY + '}')
  },

	photoEndLineRect(data) {
		const textArr = data?.result?.text;
		if (!textArr) {
			return;
		}



		const answerData = {};

		for (let i=0; i<textArr.length; i++) {
			const oneTextData = textArr[i];
			const points = oneTextData.points;

			const point1_x = points[0];
			const point1_y = points[1];
			const point2_x = points[2];
			const point2_y = points[3];

			// const rect1 = {
			// 	x:point1_x,
			// 	y: -point1_y,
			// 	width: 0.01,
			// 	height: 0.01
			// }

			// const colorRect1 = this.getColorDot(rect1.x, rect1.y, rect1.width, rect1.height, "purple");
			// this.debugDrawLayer.addChild(colorRect1, 1);
		

			// const rect2 = {
			// 	x:point2_x,
			// 	y: -point2_y,
			// 	width: 0.01,
			// 	height: 0.01
			// }

			// const colorRect2 = this.getColorDot(rect2.x, rect2.y, rect1.width, rect1.height, "purple");
			// this.debugDrawLayer.addChild(colorRect2, 1);

			this.drawUserLine([{x:point1_x, y: point1_y}, {x: point2_x, y: point2_y}]);

			this.setOneAnswerDataLink({x:point1_x, y: point1_y}, {x: point2_x, y: point2_y}, answerData);
		}


		this.showLinkAnswer(answerData);
	},

	drawUserLine(path) {
		this.drawOnePath(path);
	},

	drawOnePath(path) {
    const lineNode = new cc.Node();
    this.debugDrawLayer.addChild(lineNode);

    const w = this.debugLayer.width;
    const h = this.debugLayer.height;



    const subY = 0; //-canvas.height / 2;
    const ctx = lineNode.addComponent(cc.Graphics);
    ctx.lineWidth = 10;
    ctx.strokeColor = cc.Color.RED;
    ctx.fillColor = cc.Color.BLACK;
    

    ctx.moveTo(path[0].x * w, -path[0].y * h + subY);

    for (let i = 1; i < path.length; i++) {
      const x = path[i].x * w;
      const y = -path[i].y * h + subY;

      ctx.lineTo(x, y);
    }
    ctx.stroke();
  },

	showLinkAnswer(answerData) {

    for (let key in answerData) {

      const tempArr = answerData[key];

      const firstItemIndex = tempArr[0];
      const lastItemIndex = tempArr[1];

			const debugFirstItem = this.linkRectGroup[firstItemIndex];
			const debugLastItem = this.linkRectGroup[lastItemIndex];

			console.log('linkdebugId: ', debugFirstItem.linkData.linkDebugItemId);
			console.log('debugLastItem.linkData.debugItemId: ', debugLastItem.linkData.debugItemId)
			console.log('debugFirstItem.isRightPoint: ', debugFirstItem.isRightPoint)

			const hzItemIdFirst = debugFirstItem.linkData.hzItemId
			const hzItemIdLast = debugLastItem.linkData.hzItemId
			const startItem = this.getItemById(hzItemIdFirst);
			const endItem = this.getItemById(hzItemIdLast);
			if (startItem.isShowEnd || endItem.isShowEnd) {
				return;
			}

			if ((startItem.isRightPoint && endItem.isRightPoint) && debugFirstItem.linkData.linkDebugItemId == debugLastItem.linkData.debugItemId) {
				
				const {hzItemId, linkHzItemId} = debugFirstItem.linkData
				this.showSuccess(hzItemId, linkHzItemId);

			} else {			

			}

    }


		// for (let key in answerData) {

    //   const tempArr = answerData[key];

    //   const firstItemIndex = tempArr[0];
    //   const lastItemIndex = tempArr[1];

		// 	const debugFirstItem = this.linkRectGroup[firstItemIndex];
		// 	const debugLastItem = this.linkRectGroup[lastItemIndex];

		// 	console.log('linkdebugId: ', debugFirstItem.linkData.linkDebugItemId);
		// 	console.log('debugLastItem.linkData.debugItemId: ', debugLastItem.linkData.debugItemId)
		// 	console.log('debugFirstItem.isRightPoint: ', debugFirstItem.isRightPoint)

		// 	const hzItemIdFirst = debugFirstItem.linkData.hzItemId
		// 	const hzItemIdLast = debugLastItem.linkData.hzItemId
		// 	const startItem = this.getItemById(hzItemIdFirst);
		// 	const endItem = this.getItemById(hzItemIdLast);
		// 	if (startItem.isShowEnd || endItem.isShowEnd) {
		// 		return;
		// 	}

		// 	if (debugFirstItem.isRightPoint && debugFirstItem.linkData.linkDebugItemId == debugLastItem.linkData.debugItemId) {
				
		// 		// const {hzItemId, linkHzItemId} = debugFirstItem.linkData
		// 		// this.showSuccess(hzItemId, linkHzItemId);

		// 	} else {			

				
		// 		this.showFail(hzItemIdFirst, hzItemIdLast);
		// 		this.playCatAudio(this.data.error_link_audio_url);

		// 	}

    // }


  },

	showSuccess(startItemId, endItemId) {

		console.log( ' in showSuccess');

		const startItem = this.getItemById(startItemId);
		const endItem = this.getItemById(endItemId);

		if (startItem.isShowEnd || endItem.isShowEnd) {
			return;
		}
		startItem.isShowEnd = true;
		endItem.isShowEnd = true;

		const isLinked = this.checkIsLinked(startItem, endItem);
		if (isLinked) {
			return;
		}

		this.addLinkItem(startItem, endItem);
		this.addLinkItem(endItem, startItem);


		const pos1 = startItem.getPosition();
		pos1.x += startItem.width / 2;
		pos1.y += startItem.height / 2;
		const pos2 = endItem.getPosition();
		pos2.x += endItem.width / 2;
		pos2.y += endItem.height / 2;

		const greenColor = new cc.Color();
		greenColor.fromHEX("#519F00"); 
		const line = this.getLine(pos1, pos2, greenColor);
		this.addLinkLine(startItem, endItem, line);
		line.isRight = true;

		const maskNode = new cc.Node();
		maskNode.width = 0;
		maskNode.height = 0;
		maskNode.x = pos1.x;
		maskNode.y = pos1.y;
		this.hotZoneBg.addChild(maskNode);


		const mask = maskNode.addComponent(cc.Mask);
		mask.type = cc.Mask.Type.ELLIPSE;
		mask.segments = 32;

		maskNode.addChild(line);
		// line.mask = mask;

		this.isCurLinked = true;

		cc.tween(maskNode)
			.to(1.5, {width: this.canvas.width * 2, height: this.canvas.height * 2}, {easing: 'sineOut'})
			.call(() => {
				maskNode.removeComponent(cc.Mask);
			})
			.start();
		
		playAudio(this.rightClip, () => {
			
		})
		
		if (!this.isGameEnd) {
			const arr = this.rectNodeArr.filter((r) => {
				return r.isRightPoint == true;
			})
			this.checkGameEnd(arr);
		}
	},

	addLinkLine(item1, item2, line) {
		if ( !item1.lineArr ) {
			item1.lineArr = [];
		}

		if (!item2.lineArr) {
			item2.lineArr = [];
		}
		
		item1.lineArr.push(line);
		item2.lineArr.push(line);
		line.itemArr = [item1, item2];
		this.totalLineArr.push(line);
	},

	checkIsLinked(startItem, endItem) {
		const linkItemArr1 = startItem.linkItemArr || [];
		const linkItemArr2 = endItem.linkItemArr || [];

		return (linkItemArr1.indexOf(endItem) != -1 && linkItemArr2.indexOf(startItem) != -1);
	},

	addLinkItem(item, linkItem) {
		if (!item.linkItemArr) {
			item.linkItemArr = [];
		}

		if (item.linkItemArr.indexOf(linkItem) == -1) {
			item.linkItemArr.push(linkItem);
		}
	},

	getLine(item1, item2, color=cc.Color.BLACK) {
		const lineNode = new cc.Node();


		const ctx = lineNode.addComponent(cc.Graphics);
		ctx.lineWidth = 5;
    ctx.strokeColor = color;
    ctx.fillColor = color;

    ctx.moveTo(0, 0);
		ctx.lineTo(item2.x - item1.x, item2.y - item1.y);
		ctx.stroke();

		const dot1 = this.getDot(0, 0, ctx.lineWidth/2, ctx.strokeColor);
		dot1.parent = lineNode;

		const dot2 = this.getDot(item2.x - item1.x, item2.y - item1.y, ctx.lineWidth/2, ctx.strokeColor);
		dot2.parent = lineNode;

		return lineNode;
	},

	getDot(x, y, r, color) {

		const dotNode = new cc.Node();

    const ctx = dotNode.addComponent(cc.Graphics);
    ctx.fillColor = color || cc.Color.BLUE;
    ctx.circle(x, y, r);
    ctx.fill();

		return dotNode;
	},


	getItemById(id) {

		console.log('getItemById id:', id);
		console.log('this.rectNodeArr: ', this.rectNodeArr);

		const targetItem = this.rectNodeArr.find( node => {

			const data = node.data;

			console.log('data~~: ', JSON.stringify(data));


			if (data && (data.index + 1 == id)) {
				return true;
			}
		})
		return targetItem;
	},


	cleanColorDrawLayer() {
		const layer = this.colorDrawLayer;
		const children = layer.children;
		for (let i=0; i<children.length; i++) {
			this.pushColorPoolSpr(children[i]);
		}
	},

	pushColorPoolSpr(spr) {
		spr.opacity = 0

		this.colorSprPoolArr.push(spr);
	},

	getColorPoolSpr() {
		let spr;
		if (this.colorSprPoolArr.length > 0) {
			spr = this.colorSprPoolArr.pop();
			spr.opacity = 255;
		} else {
			spr = getSprNode('white_dot');
			this.colorDrawLayer.addChild(spr);
		}

		return spr;
	},

	photoEndColorRect(data) {
		const textArr = data?.result?.text;
		if (!textArr) {
			console.log(' photoEndColorRect 1')
			return;
		}

		const {colors, points} = textArr[0]
		if (!colors || !points) {
			console.log(' photoEndColorRect 2')
			return;
		}

		this.cleanColorDrawLayer();


		for (let i=0; i<this.colorRectCheckArr.length; i++) {
			const leftEdgeX = this.colorRectCheckArr[i].x / this.debugBgImg.width;
			const rightEdgeX = (this.colorRectCheckArr[i].x + this.colorRectCheckArr[i].width * this.colorRectCheckArr[i].scaleX) / this.debugBgImg.width;
			// const topEdgeY = (this.debugBgImg.height + this.colorRectCheckArr[i].y - this.colorRectCheckArr[i].height)  / this.debugBgImg.height;
			const topEdgeY = -(this.colorRectCheckArr[i].y + this.colorRectCheckArr[i].height * this.colorRectCheckArr[i].scaleY)  / this.debugBgImg.height;
			// const bottomEdgeY = (this.debugBgImg.height + this.colorRectCheckArr[i].y)  / this.debugBgImg.height;
			const bottomEdgeY = -(this.colorRectCheckArr[i].y)  / this.debugBgImg.height;
			

			console.log("leftEdgeX: ", leftEdgeX);
			console.log("rightEdgeX: ", rightEdgeX);
			console.log("topEdgeY: ", topEdgeY);
			console.log("bottomEdgeY: ", bottomEdgeY);

			this.colorRectCheckArr[i].leftEdgeX = leftEdgeX
			this.colorRectCheckArr[i].rightEdgeX = rightEdgeX
			this.colorRectCheckArr[i].topEdgeY = topEdgeY
			this.colorRectCheckArr[i].bottomEdgeY = bottomEdgeY
			this.colorRectCheckArr[i].colorPoints = [];
		}
		
		for (let i=0; i<points.length; i+=2) {


			const pointX = points[i];

			if (!pointX) {
				break;
			}
			const pointY = points[i+1];
			const color = colors[i/2];


			for (let j=0; j<this.colorRectCheckArr.length; j++) {
			
				const {leftEdgeX,rightEdgeX, topEdgeY, bottomEdgeY} = this.colorRectCheckArr[j];

				if (pointX < leftEdgeX) {
					// console.log(' return ~ 1');
					continue;
				}
				if (pointX > rightEdgeX) {
					// console.log(' return ~ 2');
					continue;
				}
				if (pointY < topEdgeY) {
					// console.log(' return ~ 3');
					continue;
				}
				if (pointY > bottomEdgeY) {
					// console.log(' return ~ 4');
					continue;
				}
		
				const r = color[0];
				const g = color[1];
				const b = color[2];

				if (!(r > 230 && g > 230 && b > 230)) {
					// this.colorRectCheckArr[j].colorPoints.push({pointX, pointY, color});
					this.colorRectCheckArr[j].colorPoints.push({});
				}


			}


				const colorNode = this.getColorBgColorDot(pointX, -pointY, this.colorUnit, this.colorUnit);

				colorNode.x -= this.colorBg.width / 2;
				colorNode.y += this.colorBg.height / 2;

				const pointColor = new cc.Color();

	
				pointColor.r = color[0] * 1.1
				pointColor.g = color[1] * 1.1
				pointColor.b = color[2] * 1.1
				colorNode.color = pointColor;


	
			// }

		}



		const answerData = {};


		for (let i=0; i<this.colorRectCheckArr.length; i++) {
			const colorPoints = this.colorRectCheckArr[i].colorPoints;
			const pointsMax = this.colorRectCheckArr[i].pointsMax;

			console.log('point rate : ', (colorPoints.length / pointsMax));

			if (colorPoints.length / pointsMax >= 0.8) {

				const key = (this.colorRectCheckArr[i].data.index + 1).toString();
				answerData[key] = {colorRectCheckItem: this.colorRectCheckArr[i], isFinish: true}; 
			}
		}


		// for (let i=0; i<this.colorRectCheckArr.length; i++) {

		// 	const colorPoints = this.colorRectCheckArr[i].colorPoints;

		// 	if (colorPoints.length == 0) {
		// 		continue;
		// 	}
		// 	console.log('colorPoints: ', colorPoints);

		// 	let r = 0;
		// 	let g = 0;
		// 	let b = 0;

		// 	for (let j=0; j<colorPoints.length; j++) {
		// 		const {color} = colorPoints[j];
		// 		r += color[0];
		// 		g += color[1];
		// 		b += color[2];
		// 	}

		// 	r /= colorPoints.length;
		// 	g /= colorPoints.length;
		// 	b /= colorPoints.length;
			
		// 	r = Math.round(r);
		// 	g = Math.round(g);
		// 	b = Math.round(b);

		// 	console.log('r~:', r);
		// 	console.log('g~:', g);
		// 	console.log('b~:', b);

		// 	const key = this.colorRectCheckArr[i].data.index + 1;

		// 	if (!(r > 220 && g > 220 && b > 220)) {
		// 		answerData[key] = {r, g, b, isFinish:true};
		// 	}
		// }
		

		console.log('answerData: ', answerData);

		this.showColorAnswer(answerData);

	},


	showColorAnim(oneAnswer) {
		
		console.log(" in showColorAnim 1");

		const colorRectCheckItem = oneAnswer.colorRectCheckItem;
		if (colorRectCheckItem.isShowEnd) {
			return;
		}

		colorRectCheckItem.hitCount++;
		if (colorRectCheckItem.hitCount < 3) {

			console.log("colorRectCheckItem.hitCount: " + colorRectCheckItem.hitCount);

			return;
		}

		colorRectCheckItem.isShowEnd = true;
		console.log(" in showColorAnim 2");


		const animaNodeBase = this.colorPicNodeArr[0];

		console.log('animaNodeBase: ' , animaNodeBase);

		const animaNode = cc.instantiate(animaNodeBase);

		console.log('animaNode: ' , animaNode);

		const {leftEdgeX, rightEdgeX, topEdgeY, bottomEdgeY} = colorRectCheckItem;
		const animX = -this.colorBg.width / 2 + (leftEdgeX + (rightEdgeX - leftEdgeX) / 2) * this.colorBg.width;
		const animY = this.colorBg.height / 2 - (topEdgeY + (bottomEdgeY - topEdgeY) / 2) * this.colorBg.height;


		animaNode.x = animX //colorRectCheckItem.x + colorRectCheckItem.width / 2 * colorRectCheckItem.scaleX;
		animaNode.y = animY //colorRectCheckItem.y + colorRectCheckItem.height / 2 * colorRectCheckItem.scaleY;
		// animaNode.parent = this.colorBg
		this.colorBg.addChild(animaNode, 5);

		animaNode.active = true;
		animaNode.opacity = 255;
		
		const dragonDisplay = animaNode.getComponent(dragonBones.ArmatureDisplay);

		console.log('dragonDisplay: ' , dragonDisplay);
		console.log('animaNode: ' , animaNode);


		delayCall(0.01, () => {
			const animationNames = animaNodeBase.animationNames;
			dragonDisplay.playAnimation(animationNames[0], 0);
		})

		playAudio(this.rightClip, () => {
		
		})

		if (!this.isGameEnd) {
			this.checkGameEnd(this.colorRectCheckArr);
		}

	},


	showColorAnswer(answerData) {
		
		console.log('in showColorAnswer 1');
		if (Object.keys(answerData).length == 0) {
			return;
		}

		console.log('in showColorAnswer 2');



		for (let i=0; i<this.colorRectCheckArr.length; i++) {

			const key = (this.colorRectCheckArr[i].data.index + 1).toString();

			if (!this.colorRectCheckArr[i].hitCount) {
				this.colorRectCheckArr[i].hitCount = 0;
			}

			console.log('hitCount i: ' + i);

			if (answerData[key]) {
				this.showColorAnim(answerData[key]);
			} else {
				console.log('i: ' + i + " hitCount = 0");
				this.colorRectCheckArr[i].hitCount = 0;
			}
		}



		// for (key in answerData) {

		// 	console.log('in showColorAnswer 3: ' + key);
		// 	this.showColorAnim(answerData[key]);

		// }

		// for (let i = 0; i < this.colorPicNodeArr.length; i++) {

		// 	const picNode = this.colorPicNodeArr[i];

		// 	const key = picNode.data.drawItem // i.toString();


		// 	console.log('~picNode.data: ', picNode.data)
		// 	console.log('~key: ', key)

		// 	if (!picNode.hitCount) {
		// 		picNode.hitCount = 0;
		// 	}

		// 	if (answerData[key] && answerData[key].isFinish) {
		// 		console.log('~show Color')
		// 		this.showColorPic(picNode, answerData[key]);

		// 	} else {

		// 		picNode.hitCount = 0;
		// 	}
		// }

	},


	photoEndSignRect(data) {

		const textArr = data?.result?.text;
		if (!textArr) {
			return;
		}

		let symbol = textArr[0]?.symbol
		if (!symbol) {
			return;
		}
		const poly = textArr[0]?.poly
		if (poly) {
			symbol = this.resetSymbolData(symbol, poly);
		}


		if (symbol.length != this.signRegions.length) {
			// 正常经过处理不会出现这种情况  没poly可能会出现这种情况
			return;
		}

		// return 
		const answerData = {};


		for (let i=0; i<this.signRectCheckArr.length; i++) {
			
			const signDebugItem = this.signRectCheckArr[i];
			const dropDownItem = signDebugItem.data.dropDownItem;

			if (symbol[i] == -1) {
				continue;
			}
			const curSignKey = symbol[i].toString();
			
			if (dropDownItem.key == curSignKey) {


				const label = this.getLabel(dropDownItem.label, signDebugItem.ccRect.width);
				label.x = signDebugItem.x;
				label.y = signDebugItem.y;
				label.color = cc.Color.BLACK;
	
				this.debugDrawLayer.addChild(label, 2);


				const key = signDebugItem.data.index + 1;
				answerData[key] = {isFinish: true};

			}
		}

		this.showSignAnswer(answerData);

		return ;

		for (let i=0; i<textArr.length; i++) {
			const oneTextData = textArr[i];

			const signId = '2'

			// const points = oneTextData.points;

			// const tempDisNum = Math.floor(points.length / 2);
			// const point1_x = points[0];
			// const point1_y = points[1];
			// const point2_x = points[tempDisNum];
			// const point2_y = points[tempDisNum + 1];

			// let centerPX = Number(point1_x) + (point2_x - point1_x) / 2;
			// let centerPY = Number(point1_y) + (point2_y - point1_y) / 2;

			// console.log('centerPX: ' ,centerPX);
			// console.log('centerPY: ' ,centerPY);

			// const colorRect = this.getColorDot(centerPX, -centerPY, 0.02, 0.02, "purple");
			// this.debugDrawLayer.addChild(colorRect, 1);


			// this.setOneAnswerDataCircle(colorRect, answerData);

		}

		console.log('answerData: ' , answerData);


		// this.showCircleAnswer(answerData);

	},

	resetSymbolData(symbol, poly) {

		if (symbol.length == this.signRegions.length) {
			return symbol;
		}


		if (!this.signRegionRectArr) {

			this.signRegionRectArr = [];
			for (let i=0; i<this.signRegions.length; i++) {
				const oneRegin = this.signRegions[i];
				const reginRect = new cc.Rect();
				reginRect.x = oneRegin.left;
				reginRect.y = -oneRegin.bottom;
				reginRect.width = oneRegin.right - oneRegin.left;
				reginRect.height = oneRegin.bottom - oneRegin.top;

				const centerP = new cc.Vec2((reginRect.x + reginRect.width / 2) , (reginRect.y + reginRect.height / 2) );
				reginRect.centerP = centerP;

				this.signRegionRectArr.push(reginRect);
			}
		}

		let signRegionRectArr = this.signRegionRectArr



		const newSymbol = [];
		for (let j=0; j<signRegionRectArr.length; j++) {
			newSymbol[j] = -1;			
		}

		for(let i=0; i<poly.length; i++) {
			
			const oneSymbol = symbol[i];
			const onePoly = poly[i];

			const polyRect = new cc.Rect();
			polyRect.x = onePoly.left;
			polyRect.y = -onePoly.bottom;
			polyRect.width = onePoly.right - onePoly.left;
			polyRect.height = onePoly.bottom - onePoly.top;


			const polyCenterP = new cc.Vec2( (polyRect.x + polyRect.width / 2)  , (polyRect.y + polyRect.height / 2) );
			let minDisRectIndex;
			let minLen;
	
			for (let j=0; j<signRegionRectArr.length; j++) {
				const reginRect = signRegionRectArr[j];
				const reginRectCenterP = reginRect.centerP;

				const distance = cc.Vec2.distance(polyCenterP, reginRectCenterP);
				console.log('~polyCenterP: ', polyCenterP);
				console.log('~reginRectCenterP: ', reginRectCenterP);
				console.log('~distance: ', distance);

				if (minLen == null || minLen > distance) {
					minLen = distance;
					minDisRectIndex = j;
					// minDisRect = reginRect;
				}

				
			}

			newSymbol[minDisRectIndex] = oneSymbol


			const colorRect = this.getColorRect(polyRect, "red");
			this.debugDrawLayer.addChild(colorRect, 1);
		}

		console.log('newSymbol: ' + JSON.stringify(newSymbol));

		return newSymbol;

			

	},

	showSignAnswer(answerData) {

		console.log('answerData: ', answerData);
		if (Object.keys(answerData).length == 0) {
			return;
		}

		console.log("signAnimaNodeArr: ", this.signAnimaNodeArr);

		for (let i = 0; i < this.signAnimaNodeArr.length; i++) {

			const animaNode = this.signAnimaNodeArr[i];

			const key = animaNode.data.signItem // i.toString();


			console.log('~animaNode.data: ', animaNode.data)
			console.log('~key: ', key)

			if (!animaNode.hitCount) {
				animaNode.hitCount = 0;
			}

			if (answerData[key] && answerData[key].isFinish) {
				console.log('~showSign')
				this.showSign(animaNode);

			} else {

				animaNode.hitCount = 0;
			}
		}

	},
	

	showSign(node, isRight = true) {

		console.log('in showCircle 1');


		node.hitCount++;
		if (node.hitCount < 1) {
			return;
		}


		console.log('in showCircle 2');


		if (node.isShowEnd) {
			return;
		}

		if (this.itemCombineGroup && this.itemCombineGroup.length > 0) {
			const gourpIsShowEnd = this.checkOneCombineGroupEnd(node);
			if (gourpIsShowEnd) {
				return;
			}
		}


		console.log('in showCircle 3');

		node.isShowEnd = true;
		node.isRight = isRight;


		// node.playRightAnim();
		this.playRightAnim(node);

		if (!this.isGameEnd) {

			if (this.itemCombineGroup && this.itemCombineGroup.length > 0) {
				this.checkGameEndCombineGroup();
			} else {
				this.checkGameEnd(this.signAnimaNodeArr);
			}
		}

		return;

	},

	photoEndCircleRect(data) {
		const textArr = data?.result?.text;
		if (!textArr) {
			return;
		}

		const answerData = {};

		for (let i=0; i<textArr.length; i++) {
			const oneTextData = textArr[i];
			const points = oneTextData.points;

			const tempDisNum = Math.floor(points.length / 2);
			const point1_x = points[0];
			const point1_y = points[1];
			const point2_x = points[tempDisNum];
			const point2_y = points[tempDisNum + 1];
			// const point3_x = points[tempDisNum*2];
			// const point3_y = points[tempDisNum*2 + 1];

			// let centerP = this.locate(point1_x, point1_y, point2_x, point2_y, point3_x, point3_y);
			let centerPX = Number(point1_x) + (point2_x - point1_x) / 2;
			let centerPY = Number(point1_y) + (point2_y - point1_y) / 2;

			console.log('centerPX: ' ,centerPX);
			console.log('centerPY: ' ,centerPY);


			const colorRect = this.getColorDot(centerPX, -centerPY, 0.02, 0.02, "purple");
			this.debugDrawLayer.addChild(colorRect, 1);


			this.setOneAnswerDataCircle(colorRect, answerData);
		}

		console.log('answerData: ' , answerData);


		this.showCircleAnswer(answerData);

		// this.showUserRightNew(answerData);
	},

	showCircleAnswer(answerData) {

		if (Object.keys(answerData).length == 0) {
			return;
		}


		for (let i = 0; i < this.circleAnimaNodeArr.length; i++) {

			const animaNode = this.circleAnimaNodeArr[i];

			const key = animaNode.data.circleItem // i.toString();

			console.log('~animaNode.data: ', animaNode.data)
			console.log('~key: ', key)

			console.log('~key: ', key)

			if (!animaNode.hitCount) {
				animaNode.hitCount = 0;
			}

			if (answerData[key] && answerData[key].isFinish) {
				console.log('~showLetter')
				this.showCircle(animaNode);
				// this.showCircle2(animaNode);

			} else {

				animaNode.hitCount = 0;
			}
		}

	},

	showCircle(node, isRight = true) {

		console.log('in showCircle 1');


		node.hitCount++;
		if (node.hitCount < 1) {
			return;
		}


		console.log('in showCircle 2');


		if (node.isShowEnd) {
			return;
		}

		console.log('in showCircle 3');

		node.isShowEnd = true;
		node.isRight = isRight;



		// this.playRightAnim(node);

		
		this.showCircle2(node);

		if (!this.isGameEnd) {
			this.checkGameEnd(this.circleAnimaNodeArr);
		}

		return;

	},
	

	photoEndNewRect(data) {

		let textArr = data?.result?.text;
		if (!textArr) {
			return;
		}

		const answerData = {};




		const checkOneByData = (oneData) => {

			const oneTextData = oneData
			const x = oneTextData.left//oneTextData.left + (oneTextData.right - oneTextData.left) / 2;
			const y = -oneTextData.bottom//-oneTextData.top - (oneTextData.bottom - oneTextData.top) / 2;
			const w = oneTextData.right - oneTextData.left;
			const h = oneTextData.bottom - oneTextData.top;

			const rect = {
				x, y,
				width: w,
				height: h
			}

			console.log('oneTextData: ', oneTextData);

			const content = oneTextData.content;
			const colorRect = this.getColorRect(rect, "red");
			colorRect.labelText = content;
			this.debugDrawLayer.addChild(colorRect, 1);

			const label = this.getLabel(content, colorRect.scaleX *  colorRect.width);
			label.x = colorRect.x + colorRect.width / 2 * colorRect.scaleX;
			label.y = colorRect.y + colorRect.height / 2 * colorRect.scaleY;
			label.color = cc.Color.BLACK;

			this.debugDrawLayer.addChild(label, 2);

			this.setOneAnswerDataNew(colorRect, answerData);


		}

		for (let i=0; i<textArr.length; i++) {

			const oneTextData = textArr[i];
			if (this.partRegions && oneTextData.characters) {
				console.log('~~ oneTextData: ', oneTextData);
				const tempArr = this.getArrByCharacters(oneTextData);
				console.log('tempArr~: ', tempArr);
				for (let j=0; j<tempArr.length; j++) {
					checkOneByData(tempArr[j]);
				}
			} else {
				checkOneByData(oneTextData);
			}

			// const x = oneTextData.left//oneTextData.left + (oneTextData.right - oneTextData.left) / 2;
			// const y = -oneTextData.bottom//-oneTextData.top - (oneTextData.bottom - oneTextData.top) / 2;
			// const w = oneTextData.right - oneTextData.left;
			// const h = oneTextData.bottom - oneTextData.top;

			// const rect = {
			// 	x, y,
			// 	width: w,
			// 	height: h
			// }

			// console.log('oneTextData: ', oneTextData);

			// const content = oneTextData.content;
			// const colorRect = this.getColorRect(rect, "red");
			// colorRect.labelText = content;
			// this.debugDrawLayer.addChild(colorRect, 1);

			// const label = this.getLabel(content, colorRect.scaleX *  colorRect.width);
			// label.x = colorRect.x + colorRect.width / 2 * colorRect.scaleX;
			// label.y = colorRect.y + colorRect.height / 2 * colorRect.scaleY;
			// label.color = cc.Color.BLACK;

			// this.debugDrawLayer.addChild(label, 2);

			// this.setOneAnswerDataNew(colorRect, answerData);

		}

		console.log('answerData:' , answerData);
		this.showUserRightNew(answerData);
	},

	showUserRightNew(answerData) {

		if (Object.keys(answerData).length == 0) {
			return;
		}

		let arr = this.animaNodeArr;
		if (this.picAnimNodeArr.length > 0) {
			arr = this.picAnimNodeArr;
		}

		for (let i = 0; i < arr.length; i++) {

			const animaNode = arr[i];

			let key = animaNode.data.rectNew // i.toString();
			if (!key && animaNode.data.rectNum) {
				key = animaNode.data.rectNum;
			}

			console.log('~animaNode.data: ', animaNode.data)
			console.log('~key: ', key)

			if (!animaNode.hitCount) {
				animaNode.hitCount = 0;
			}

			if (answerData[key] && answerData[key].isFinish) {
				console.log('~showLetter')

				if (this.picAnimNodeArr.length > 0) {
					this.showLetterPic(animaNode);
				} else {
					this.showLetter(animaNode);
				}
			} else {

				animaNode.hitCount = 0;
			}
		}
	},

	photoEnd(data) {
		
		console.log(' this.photo end ', data);

		this.loopLog(data);

		// if (this.newRectArr && this.newRectArr.length > 0) {
		if (this.curCheckGroup == this.CHECK_TYPE_WRITE) {
			this.photoEndNewRect(data);
			return;
		}


		// if (this.circleRectArr && this.circleRectArr.length > 0) {
		if (this.curCheckGroup == this.CHECK_TYPE_CIRCLE) {
			this.photoEndCircleRect(data);
			return;
		}

		// if (this.lineRectArr && this.lineRectArr.length > 0) {
		if (this.curCheckGroup == this.CHECK_TYPE_LINE) {
			this.photoEndLineRect(data);
			return;
		}

		// if (this.signRectArr && this.signRectArr.length > 0) {
		if (this.curCheckGroup == this.CHECK_TYPE_SIGN) {
			this.photoEndSignRect(data);
			return;
		}

		if (this.curCheckGroup == this.CHECK_TYPE_COLOR) {
			this.photoEndColorRect(data);
			return;
		}

		


		// this.changeBboxPos(data);

		const isRightArea = this.checkIsRightArea(data);
		if (!isRightArea) {
			console.log('没有检测到区域')
			return;
		}



		if (this.isCanDraw) {
			return;
		}
		this.isCanDraw = true;


		delayCall(0.01, () => {
			this.isCanDraw = false;
		})



		this.debugDrawLayer.removeAllChildren();

		// const benchmark1Text = this.benchmark1Data.labelText
		// const benchmark1TextArr = benchmark1Text.split(' ');
		// const benchmark1LabelData = this.getPhotoLabelData(benchmark1TextArr, data?.result?.text);

		// const benchmark2Text = this.benchmark2Data.labelText
		// const benchmark2TextArr = benchmark2Text.split(' ');
		// const benchmark2LabelData = this.getPhotoLabelData(benchmark2TextArr,  data?.result?.text);




		const answerData = this.getAnswerData(data);

		this.showUserRight(answerData, data);

		return;


		const answerWrongData = this.getAnswerWrongData(data);
		let isShowWrong = false;
		if (this.oldAnswerWrongData) {
		
			for (let key in answerWrongData) {
				const wrongData = answerWrongData[key];
				const oldWrongData = this.oldAnswerWrongData[key];
				if (oldWrongData && oldWrongData.sentence == wrongData.sentence) {
					wrongData.count += oldWrongData.count;

					if (wrongData.count >= 3) {
						isShowWrong = true;
					}
				}
			}
		}

		if (isShowWrong) {
			this.showUserWrong(answerWrongData);
		}

		this.oldAnswerWrongData = answerWrongData;


		console.log('answerWrongData: ', JSON.stringify( answerWrongData) );
	},







	checkIsRightArea(data) {

		const text = data?.result?.text
		if (!text) {
			return false;
		}

		const benchmark1Text = this.benchmark1Data.labelText
		const benchmark1TextArr = benchmark1Text.split(' ');
		console.log('benchmark1TextArr: ', benchmark1TextArr);
		// const letter = this.data.letter || 'Aa';

		const benchmark1LabelData = this.getPhotoLabelData(benchmark1TextArr, text, false);
		if (!benchmark1LabelData) {
			console.log('!benchmark1LabelData')
			return false;
		}
		this.benchmark1LabelData = benchmark1LabelData;
		console.log('benchmark1LabelData: ', benchmark1LabelData);

		

		if ( this.firstItemData ) {

			const firstText = this.firstItemData.labelText
			const firstTextArr = firstText.split(' ');

			const firstItemLabelData = this.getTopLeftLetter2(firstText, text, this.benchmark1LabelData);

			if (!firstItemLabelData) {
				return false;
			}
			this.firstItemLabelData = firstItemLabelData;

			console.log('firstItemLabelData: ', firstItemLabelData);
			return true

		} else if (this.benchmark2Data) {
		
			const benchmark2Text = this.benchmark2Data.labelText
			const benchmark2TextArr = benchmark2Text.split(' ');
			const benchmark2LabelData = this.getPhotoLabelData(benchmark2TextArr, text, false);
			if (!benchmark2LabelData) {
				return false;
			}
			this.benchmark2LabelData = benchmark2LabelData;
			return true;
		}



		return false;

	


		// const block = data?.block
		// if (!block) {
		// 	return false;
		// }

		// const topText = this.topItemData.labelText
		// const topTextArr = topText.split(' ');
		// console.log('topTextArr: ', topTextArr);
		// // const letter = this.data.letter || 'Aa';

		// const topLabelData = this.getPhotoLabelData(topTextArr, block);
		// if (!topLabelData) {
		// 	console.log('!topLabelData')
		// 	return false;
		// }
		// this.topLabelData = topLabelData;
		// console.log('topLabelData: ', topLabelData);

		

		// if (this.bottomItemData) {
			
		// 	const bottomText = this.bottomItemData.labelText
		// 	const bottomTextArr = bottomText.split(' ');
		// 	const bottomLabelData = this.getPhotoLabelData(bottomTextArr, block);
		// 	if (!bottomLabelData) {
		// 		return false;
		// 	}
		// 	this.bottomLabelData = bottomLabelData;
		// 	return true

		// } else if (this.firstItemData) {

		// 	const firstText = this.firstItemData.labelText
		// 	const firstTextArr = firstText.split(' ');
		// 	const topLeftLetter = this.getPhotoLabelData(firstTextArr, block);


		// 	// const topLeftLetter = this.getTopLeftLetter(this.firstItemData.labelText, block, topLabelData);
		// 	if (!topLeftLetter) {
		// 		return false;
		// 	}
		// 	this.topLeftLetter = topLeftLetter;

		// 	console.log('topLeftLetter: ', topLeftLetter);
		// 	return true;
		// }



		// return false;

	
	},

	changeBboxPos(data) {

		const text = data?.result?.text;
		if (!text) {
			return;
		}


		for (let i=0; i<text.length; i++) {

			let {left, top, right, bottom} = text[i];

			const q_left = this.ques_region[0];
			const q_top = this.ques_region[1];
			const q_right = this.ques_region[2];
			const q_bottom = this.ques_region[7];

			const rect = {x: q_left, y: q_top, width: q_right - q_left, height: q_bottom - q_top};

			text[i].left = q_left + left * rect.width;
			text[i].top = q_top + top * rect.height;
			text[i].right = q_left + right * rect.width;
			text[i].bottom = q_top + bottom * rect.height;

		}

		// console.log('bbox: ', bbox);
		// const x1 = bbox[0].x1;
		// const y1 = bbox[0].y1;
		// const x2 = bbox[1].x2;
		// const y2 = bbox[1].y2;
		// const x3 = bbox[2].x3;
		// const y3 = bbox[2].y3;
		// const x4 = bbox[3].x4;
		// const y4 = bbox[3].y4;

		// const left = this.ques_region[0];
		// const top = this.ques_region[1];
		// const right = this.ques_region[2];
		// const bottom = this.ques_region[7];

		// const rect = {x: left, y:top, width: right - left, height: bottom - top};

		// const y1_new = top + y1 * rect.height;
		// const y2_new = y1_new;
		// const y3_new = top + y3 * rect.height;
		// const y4_new = y3_new;

		// const x1_new = left + x1 * rect.width;
		// const x2_new = left + x2 * rect.width;
		// const x3_new = x2_new;
		// const x4_new = x1_new;

		// bbox[0].x1 = x1_new;
		// bbox[0].y1 = y1_new;
		// bbox[1].x2 = x2_new;
		// bbox[1].y2 = y2_new;
		// bbox[2].x3 = x3_new;
		// bbox[2].y3 = y3_new;
		// bbox[3].x4 = x4_new;
		// bbox[3].y4 = y4_new;

		// console.log('~~rect: ', rect);

	
	},



	getTopLeftLetter2(text, block, topLabelData) {

		const benchmark1Rect = this.benchmark1Data.rect;

		const rect = {
			x: topLabelData.left, 
			y: -topLabelData.bottom, 
			width: Math.abs( topLabelData.right - topLabelData.left ), 
			height: Math.abs( topLabelData.bottom - topLabelData.top ), 
		}                        
		const colorRect = this.getColorRect(rect, "green");
		this.debugDrawLayer.addChild(colorRect);
		


		const tempUnitW = benchmark1Rect.x + benchmark1Rect.width;
		const tempUnitH = benchmark1Rect.y + benchmark1Rect.height;
		const tempBaseX = benchmark1Rect.x + benchmark1Rect.width / 2;
		const tempBaseY = benchmark1Rect.y + benchmark1Rect.height / 2;


		const firstItemData = this.firstItemData;		
		const firstItemRect = this.firstItemData.rect;

	
		const firstItemX = firstItemRect.x + firstItemRect.width / 2;
		const firstItemY = firstItemRect.y + firstItemRect.height / 2;

		const unitX = (firstItemX - tempBaseX) / tempUnitW;
		const unitY = (firstItemY - tempBaseY) / tempUnitH;
		const unitW2 = firstItemRect.width / tempUnitW;
		const unitH2 = firstItemRect.height / tempUnitH;



		console.log('tempUnitW: ', tempUnitW);
		console.log('tempUnitH: ', tempUnitH);
		console.log('tempBaseX: ', tempBaseX);
		console.log('tempBaseY: ', tempBaseY);

		console.log('firstItemY: ', firstItemY);
		console.log('tempBaseY: ', tempBaseY);
		console.log('tempUnitH: ', tempUnitH);

		firstItemData.unitX = unitX;
		firstItemData.unitY = unitY;
		firstItemData.unitW = unitW2;
		firstItemData.unitH = unitH2;



		const topLocationLeft = topLabelData.left;
		const topLocationTop = topLabelData.top;
		const topLocationRight = topLabelData.right;
		const topLocationBottom = topLabelData.bottom;

		const baseX = topLocationLeft + (topLocationRight - topLocationLeft) / 2;
		const baseY =	topLocationTop + (topLocationBottom - topLocationTop) / 2;
		const unitW = topLocationRight;
		const unitH = topLocationTop + (topLocationBottom - topLocationTop);
		

		const checkLetter = firstItemData;

		console.log('baseY: ', baseY);
		console.log('checkLetter.unitY: ', checkLetter.unitY);
		console.log('unitH: ', unitH);


		let x = baseX + checkLetter.unitX * unitW;
		const y = baseY + checkLetter.unitY * unitH;
		const w = checkLetter.unitW * unitW;
		const h = checkLetter.unitH * unitH;
		const r = Math.min(w, h) / 2;


		console.log(' baseX:  ', baseX);
		console.log(' checkLetter.unitX:  ', checkLetter.unitX);
		console.log(' unitW:  ', unitW);
		console.log(' x:  ', x);
		console.log(' y:  ', y);
		console.log(' r:  ', r);
		console.log(' checkLetter:  ', checkLetter);

		const dot = this.getColorDot(x, -y, r, r, 'blue');
		this.debugDrawLayer.addChild(dot, 5);

		dot.labelText = checkLetter.labelText;


		const wordDataArr =  this.getPhotoWordArr(text, block, topLabelData);
		let topLeftLetterData;


		const {dotRect, labelText} = dot
		


		for (let i=0; i<wordDataArr.length; i++) {

			// const tempWordArr = wordDataArr[i].word;
			const tempWordArr = this.getTempWordArr(wordDataArr[i],['']);



			for (let k=0; k<tempWordArr.length; k++) {
					
				const {location , content} = tempWordArr[k];

				const rect = {
					x: location.left, 
					y: -location.bottom, 
					width: Math.abs( location.right - location.left ), 
					height: Math.abs( location.bottom - location.top ), 
				}                        
				const colorRect = this.getColorRect(rect, "purple");
				colorRect.labelText = content;
				this.debugDrawLayer.addChild(colorRect);

				// console.log('colorRect: ', colorRect);

				const label = this.getLabel(content);
				label.x = colorRect.x + colorRect.width / 2 * colorRect.scaleX;
				label.y = colorRect.y - colorRect.height / 2 //* colorRect.scaleY;
				label.color = cc.Color.GREEN;
				this.debugDrawLayer.addChild(label);




				///------

				const checkRect = colorRect.ccRect;
				const targetLabelText = colorRect.labelText;

				const {dotRect, labelText, key} = dot;

				if (labelText.toLowerCase().indexOf(targetLabelText.toLowerCase()) != -1 && checkRect.intersects(dotRect)) {
					return tempWordArr[k];
				}

				///------
				

			}





			// const lineRect = this.getLineRect( wordDataArr[i] );
			// const isInLineRect = lineRect.intersects(dotRect)
			// if (!isInLineRect) {
			// 	continue;
			// }

			// for (let k=0; k<tempWordArr.length; k++) {
			// 	const {location , content} = tempWordArr[k];

			// 	const tempRect = {
			// 		x: location.left, 
			// 		y: -location.bottom, 
			// 		width: Math.abs( location.right - location.left ), 
			// 		height: Math.abs( location.bottom - location.top ), 
			// 	}
			// 	const colorRect = this.getColorRect(tempRect);
			// 	colorRect.labelText = content;
			// 	// this.debugDrawLayer.addChild(colorRect);

			// 	const label = this.getLabel(content);
			// 	label.x = colorRect.x + colorRect.width / 2 * colorRect.scaleX;
			// 	label.y = colorRect.y - colorRect.height / 2 //* colorRect.scaleY;
			// 	label.color = cc.Color.GREEN;
			// 	// this.debugDrawLayer.addChild(label);
				


						
			// 	const rect = colorRect.ccRect;
			// 	const targetLabelText = colorRect.labelText;



			

			// 	// console.log('targetLabelText.toLowerCase() : ', targetLabelText.toLowerCase() );
			// 	// console.log('labelText.toLowerCase()  : ', labelText.toLowerCase()  );


			// 	const isInLineText = this.checkWordIsInLine(wordDataArr[i], labelText);

			// 	if (isInLineText) {
			// 	// if (targetLabelText.toLowerCase().indexOf(labelText.toLowerCase()) != -1  && rect.intersects(dotRect)) {
			// 		topLeftLetterData = wordDataArr[i];
			// 		// answerData[i.toString()] = colorRect;
			// 		// return;
			// 	}

			// }
			
		}

			
		return null;


	},


	getTopLeftLetter(text, block, topLabelData) {

		// const topItemRect = this.topItemData.rect;

		// const tempUnitW = topItemRect.width;
		// const tempUnitH = topItemRect.height;
		// const tempBaseX = topItemRect.x;
		// const tempBaseY = topItemRect.y + topItemRect.height / 2;


		// const firstItemData = this.firstItemData;
		// console.log('firstItemData: ', firstItemData);
		
		// const firstItemRect = this.firstItemData.rect;


	
		// const firstItemX = firstItemRect.x + firstItemRect.width / 2;
		// const firstItemY = firstItemRect.y + firstItemRect.height / 2;

		// const unitX = (firstItemX - tempBaseX) / tempUnitW;
		// const unitY = (firstItemY - tempBaseY) / tempUnitH;
		// const unitW2 = firstItemRect.width / tempUnitW;
		// const unitH2 = firstItemRect.height / tempUnitH;


		// console.log('firstItemY: ', firstItemY);
		// console.log('tempBaseY: ', tempBaseY);
		// console.log('tempUnitH: ', tempUnitH);

		// firstItemData.unitX = unitX;
		// firstItemData.unitY = unitY;
		// firstItemData.unitW = unitW2;
		// firstItemData.unitH = unitH2;



		// // const topLabelData = this.topLabelData;

		// const firstTopWordLocation = topLabelData.word[0].location;
		// const lastTopWordLocation = topLabelData.word[topLabelData.word.length - 1].location
		// const topLocationLeft = firstTopWordLocation.left;
		// const topLocationTop = firstTopWordLocation.top;
		// const topLocationRight = lastTopWordLocation.right;
		// const topLocationBottom = lastTopWordLocation.bottom;

		// const baseX = topLocationLeft;
		// const baseY =	topLocationTop + (topLocationBottom - topLocationTop) / 2;
		// const unitW = topLocationRight - topLocationLeft;
		// const unitH = topLocationBottom - topLocationTop;
		

		// const checkLetter = firstItemData;

		// console.log('baseY: ', baseY);
		// console.log('checkLetter.unitY: ', checkLetter.unitY);
		// console.log('unitH: ', unitH);


		// let x = baseX + checkLetter.unitX * unitW;
		// const y = baseY + checkLetter.unitY * unitH;
		// const w = checkLetter.unitW * unitW;
		// const h = checkLetter.unitH * unitH;
		// const r = Math.min(w, h) / 2;

		// 	// const centerX = baseX + this.centerUnitW * unitW;
		// 	// x += (centerX - x) * 0.005  * (y * 0.05);

		// console.log(' x:  ', x);
		// console.log(' y:  ', y);
		// console.log(' r:  ', r);

		// const dot = this.getColorDot(x, -y, r, r, 'purple');
		// this.debugDrawLayer.addChild(dot, 5);

		// dot.labelText = checkLetter.labelText;


		// const wordDataArr =  this.getPhotoWordArr(text, block, topLabelData);
		// let topLeftLetterData;


		// const {dotRect, labelText} = dot
		


		// for (let i=0; i<wordDataArr.length; i++) {

		// 	const tempWordArr = wordDataArr[i].word;

		// 	const lineRect = this.getLineRect( wordDataArr[i] );
		// 	const isInLineRect = lineRect.intersects(dotRect)
		// 	if (!isInLineRect) {
		// 		continue;
		// 	}

		// 	for (let k=0; k<tempWordArr.length; k++) {
		// 		const {location , content} = tempWordArr[k];

		// 		const tempRect = {
		// 			x: location.left, 
		// 			y: -location.bottom, 
		// 			width: Math.abs( location.right - location.left ), 
		// 			height: Math.abs( location.bottom - location.top ), 
		// 		}
		// 		const colorRect = this.getColorRect(tempRect);
		// 		colorRect.labelText = content;
		// 		// this.debugDrawLayer.addChild(colorRect);

		// 		const label = this.getLabel(content);
		// 		label.x = colorRect.x + colorRect.width / 2 * colorRect.scaleX;
		// 		label.y = colorRect.y - colorRect.height / 2 //* colorRect.scaleY;
		// 		label.color = cc.Color.GREEN;
		// 		// this.debugDrawLayer.addChild(label);
				


						
		// 		const rect = colorRect.ccRect;
		// 		const targetLabelText = colorRect.labelText;



			

		// 		// console.log('targetLabelText.toLowerCase() : ', targetLabelText.toLowerCase() );
		// 		// console.log('labelText.toLowerCase()  : ', labelText.toLowerCase()  );


		// 		const isInLineText = this.checkWordIsInLine(wordDataArr[i], labelText);

		// 		if (isInLineText) {
		// 		// if (targetLabelText.toLowerCase().indexOf(labelText.toLowerCase()) != -1  && rect.intersects(dotRect)) {
		// 			topLeftLetterData = wordDataArr[i];
		// 			// answerData[i.toString()] = colorRect;
		// 			// return;
		// 		}

		// 	}
			
		// }

			
		// return topLeftLetterData;









		// // const topRect = this.topItemData.rect;

		// // const topCenterY = (topRect.y + topRect.height / 2);
		// // const bottomCenterY = (bottomRect.y + bottomRect.height / 2);
		
		// // const unitH = bottomCenterY - topCenterY;
		// // const unitW = topRect.width;
		// // const baseX = topRect.x;
		// // const baseY = topRect.y + topRect.height;


		

		// // const titleBottom = this.getTitleBottom();
		// // console.log("titleBottom: ", titleBottom);

		// // let topLeftLetter;
		// // const wordDataArr =  this.getPhotoWordArr(text, block, topLabelData);
		// // for (let i=0; i<wordDataArr.length; i++) {

		// // 	const tempWordArr = wordDataArr[i].word;
		// // 	for (let k=0; k<tempWordArr.length; k++) {
		// // 		const {location , content} = tempWordArr[k];


		// // 		// console.log('location: ~~ ', location);

		// // 		// if (location.top <= titleBottom) {
		// // 		// 	continue;
		// // 		// }

		// // 		wordDataArr[i].tmpLen = this.getToZeroLen(location)

					



		// // 		if (!topLeftLetter) {
		// // 			topLeftLetter = wordDataArr[i];
		// // 		} else {
		// // 			if (topLeftLetter.tmpLen > wordDataArr[i].tmpLen) {
		// // 				topLeftLetter = wordDataArr[i];
		// // 			}
		// // 		}
		// // 	}
			
		// // }

		// // return topLeftLetter;


	},

	getLineRect(line) {

		const tempWordArr = line.word;

		let sentenceRect;
		let left;
		let right;
		for (let k=0; k<tempWordArr.length; k++) {
			const {location , content} = tempWordArr[k];

			const tempRect = {
				x: location.left, 
				y: -location.bottom, 
				width: Math.abs( location.right - location.left ), 
				height: Math.abs( location.bottom - location.top ), 
			}
			const colorRect = this.getColorRect(tempRect);
			colorRect.labelText = content;
			// this.debugDrawLayer.addChild(colorRect);

					
			const rect = colorRect.ccRect;
			if (!sentenceRect) {
				sentenceRect = rect;
				left = rect.x;
				right = rect.x + rect.width;
			} else {
				if (rect.x + rect.width > right) {
					right = rect.x + rect.width;
				}
			}



		


		}

		if (sentenceRect) {
			sentenceRect.width = right - left;
		}

		return sentenceRect;



	},

	checkWordIsInLine(line, text) {

		console.log(" in checkWordIsInLine ");
		console.log(" line:  ", line);
		console.log(" word:  ", text);

		const textArr = text.trim().toLowerCase().split('');

		const word = line.word;
		let sentence = ''
		word.forEach(item => {
			sentence += item.content + ' ';
		});

		sentence.trim();
		sentence = sentence.toLowerCase();

		line.sentence = sentence;

		console.log(" sentence:  ", sentence);
		

		if (this.checkIsInsert(textArr, sentence)) {
			return true;
		}

		
		return false;

	},


	getTitleBottom() {
		let maxBottom = 0;
		const word = this.topLabelData.word;
		for (let i=0; i<word.length; i++) {
			if (word[i].location.bottom > maxBottom) {
				maxBottom = word[i].location.bottom;
			}
		}

		return maxBottom;
	},

	getToZeroLen(location) {
		const {top, left} = location;
		const len = Math.sqrt( Math.pow(left, 2) + Math.pow(top, 2) );
		return len;
	},



	getPhotoLabelData(textArr, block, isShow=true) {


		for(let j=0; j<block.length; j++) {

			const line = block[j];
			if (!line) {
				continue;
			}

			const sentence = line.content;


			if (isShow) {
				const label = this.getLabel(sentence, 150);
				label.x = line.left * this.debugBgImg.width;
				label.y = -(line.top + (line.bottom - line.top) / 2) * this.debugBgImg.height;
				label.parent = this.debugDrawLayer;
				label.zIndex = 200;
				// label.color = cc.Color.RED;
				const l = label.getComponent(cc.Label);
				label.anchorX = 0;
				console.log(' sentence~:  ', sentence);
			}




			if (this.checkIsInsert(textArr, sentence)) {
				return line;
			}

		}

		return false;

		// for(let j=0; j<block.length; j++) {

		// 	const line = block[j].line;
		// 	if (!line) {
		// 		continue;
		// 	}

		// 	for (let i=0; i<line.length; i++) {

		// 		const word = line[i].word;
		// 		let sentence = ''
		// 		word.forEach(item => {
		// 			sentence += item.content + ' ';
		// 		});
	
		// 		sentence.trim();
		// 		sentence = sentence.toLowerCase();
	
		// 		line[i].sentence = sentence;

		// 		if (this.checkIsInsert(textArr, sentence)) {
		// 			return line[i];
		// 		}
		// 	}
		// }

		// return false;
	},

	checkIsInsert(textArr, sentence) {
		// console.log('textArr: ', textArr);
		// console.log('sentence: ', sentence);

		sentence = sentence.toLowerCase();

		let index = -1;
		for (let i=0; i<textArr.length; i++) {
			index = sentence.indexOf(textArr[i].toLowerCase(), index);
			// console.log('index: ', index);
			if (index == -1) {
				return false;
			}
		}

		return true;
	},


	showUserRight(answerData, data) {

		const text = data?.result?.text
		if (!text) {
			return false;
		}


		console.log('answerData: ', answerData);
		// console.log('this.picNodeArr: ', this.picNodeArr);

		if (Object.keys(answerData).length == 0) {
			return;
		}



		for (let i = 0; i < this.animaNodeArr.length; i++) {

			const animaNode = this.animaNodeArr[i];

			const key = animaNode.data.rectItem // i.toString();

			console.log('key: ', key)

			console.log('~key: ', key)

			if (!animaNode.hitCount) {
				animaNode.hitCount = 0;
			}

			if (answerData[key] && answerData[key].isFinish) {
				this.showLetter(animaNode);
				// this.removeLine(answerData[key].line, block);
			} else {

				animaNode.hitCount = 0;
			}
		}


		// for (let i = 0; i < this.picNodeArr.length; i++) {

		// 	const picNode = this.picNodeArr[i];

		// 	const key = picNode.data.rectItem // i.toString();

		// 	console.log('key: ', key)

		// 	if (answerData[key] && answerData[key].isFinish) {
		// 		this.showLetter(picNode);
		// 		this.removeLine(answerData[key].line, block);
		// 	} else {

		// 		picNode.hitCount = 0;
		// 	}
		// }


	},

	removeLine(line, block) {

		console.log('block: ', JSON.stringify(block));
		for (let i=0; i<block.length; i++) {
			const lineArr = block[i].line;
	
			const index = lineArr.indexOf(line);
			if (index != -1) {
				lineArr.splice(index, 1);
				console.log(' ```splice lineArr.length: ' , lineArr.length);
			}
		}
	},

	showUserWrong(answerData) {

		console.log('answerData: ', answerData);
		console.log('this.picNodeArr: ', this.picNodeArr);

		if (Object.keys(answerData).length == 0) {
			return;
		}


		for (let i = 0; i < this.picNodeArr.length; i++) {

			const picNode = this.picNodeArr[i];

			const key = picNode.data.rectItem // i.toString();

			console.log('key: ', key)

			if (answerData[key] && answerData[key].count >= 3) {
				this.showLetter(picNode, false);
			}
		}


	},



	showColorPic(picNode, data, isRight = true) {

		console.log('in showLetterPic 1');

		picNode.hitCount++;
		if (picNode.hitCount < 1) {
			return;
		}

		console.log('in showLetterPic 2');

		if (picNode.isShowEnd) {
			return;
		}

		console.log('in showLetterPic 3');

		picNode.isShowEnd = true;
		picNode.isRight = isRight;


		// picNode.opacity = 0;
		picNode.active = true

		const picColor = new cc.Color();
		picColor.r = data.r;
		picColor.g = data.g;
		picColor.b = data.b;
		picNode.sprNode.color = picColor;




		// cc.tween(picNode)
		// 	.to(2, {opacity: 255}, {easing:"cubicOut"})
		// 	.start();

		playAudio(this.rightClip, () => {
		
		})
		
		if (!this.isGameEnd) {
			this.checkGameEnd(this.colorPicNodeArr);
		}

	},

	
	showLetterPic(picNode, isRight = true) {

		console.log('in showLetterPic 1');


		picNode.hitCount++;
		if (picNode.hitCount < 1) {
			return;
		}


		console.log('in showLetterPic 2');


		if (picNode.isShowEnd) {
			return;
		}

		console.log('in showLetterPic 3');

		picNode.isShowEnd = true;
		picNode.isRight = isRight;


		// picNode.playRightAnim();
		// this.playRightAnim(picNode);

		picNode.opacity = 0;
		picNode.active = true
		cc.tween(picNode)
			.to(2, {opacity: 255}, {easing:"cubicOut"})
			.start();

		playAudio(this.rightClip, () => {
		
		})
		
		if (!this.isGameEnd) {
			this.checkGameEnd(this.picAnimNodeArr);
		}

	},


	showLetter(picNode, isRight = true) {

		// let writeRect = this.writeNodeArr[Number(index)];

		console.log('in showLetter 1');


		picNode.hitCount++;
		if (picNode.hitCount < 1) {
			return;
		}


		console.log('in showLetter 2');


		if (picNode.isShowEnd) {
			return;
		}

		console.log('in showLetter 3');

		picNode.isShowEnd = true;
		picNode.isRight = isRight;


		// picNode.playRightAnim();
		this.playRightAnim(picNode);

		if (!this.isGameEnd) {
			this.checkGameEnd(this.animaNodeArr);
		}

		return;


		picNode.answerPic.active = true;



		if (!isRight) {
			console.log(' ~ !isRight');
			picNode.answerPic.color = cc.Color.fromHEX(new cc.Color(), '#ef7961')
			playAudio(this.wrongClip);

			if (!this.isGameEnd) {
				this.checkGameEnd();
			}
			return;
		} else {
			picNode.answerPic.color = cc.Color.fromHEX(new cc.Color(), '#548fd4')
			playAudio(this.rightClip);

		}

		this.showAnimaStar(picNode, ()=> {
			
			if (!this.isGameEnd) {
				this.checkGameEnd();
			}

		});

	
	},

	showAnimaStar(node, cb) {

		const resDragonBone = cc.find("Canvas/res/anim/right")
		const dNode = cc.instantiate(resDragonBone)
		node.addChild(dNode, 20);

		const dragonDisplay = dNode.getComponent(dragonBones.ArmatureDisplay);

		dragonDisplay.playAnimation('newAnimation', 1);

		dragonDisplay.on(dragonBones.EventObject.COMPLETE, ()=> {
			console.log('play end');
			cb && cb();
		})
		

	},


	getAnswerData(data) {
		
		const text = data?.result?.text
		if (!text) {
			return false;
		}


		console.log(' in getAnswerData: ', text);


		const benchmark1LabelData = this.benchmark1LabelData;
		let benchmark2LabelData ;

		const centerItemArr = this.centerItemArr;

		const benchmark1Left = benchmark1LabelData.left;
		const benchmark1Top = benchmark1LabelData.top;
		const benchmark1Right = benchmark1LabelData.right;
		const benchmark1Bottom = benchmark1LabelData.bottom;

		let baseX;
		let baseY;
		let unitW;
		let unitH;

		if (this.benchmark2LabelData) {
			benchmark2LabelData = this.benchmark2LabelData;


			const benchmark2Left = benchmark2LabelData.left;
			const benchmark2Top = benchmark2LabelData.top;
			const benchmark2Right = benchmark2LabelData.right;
			const benchmark2Bottom = benchmark2LabelData.bottom;


			const bottomLocation = benchmark2LabelData;

			baseX = benchmark1Left;
			baseY =	benchmark1Top + (benchmark1Bottom - benchmark1Top) / 2;
			unitW = benchmark2Right - benchmark1Left;
			unitH = bottomLocation.top + (bottomLocation.bottom - bottomLocation.top) / 2 - baseY;


			const benchmark2Rect = {
				x: benchmark2Left, 
				y: -benchmark2Bottom,
				width: Math.abs( benchmark2Left - benchmark2Right ), 
				height: Math.abs( benchmark2Top - benchmark2Bottom ), 
			}
			
			const colorbenchmark2Rect = this.getColorRect(benchmark2Rect, 'green');
			this.debugDrawLayer.addChild(colorbenchmark2Rect);
		} 

	



		if (this.firstItemLabelData) {
			const {location} = this.firstItemLabelData;
			const firstItemLeft = location.left;
			const firstItemRight = location.right;
			const firstItemTop = location.top;
			const firstItemBottom = location.bottom;

			console.log(' location: ', location);
			console.log(' firstItemLeft: ', firstItemLeft);
			console.log(' firstItemRight: ', firstItemRight);
			console.log(' firstItemTop: ', firstItemTop);
			console.log(' firstItemBottom: ', firstItemBottom);

			baseX = firstItemLeft + (firstItemRight - firstItemLeft) / 2;
			baseY =	firstItemTop + (firstItemBottom - firstItemTop) / 2;
			unitW = benchmark1Left + (benchmark1Right -  benchmark1Left) - ( firstItemLeft + (firstItemRight - firstItemLeft) / 2 );
			unitH = ( firstItemTop + (firstItemBottom - firstItemTop) / 2 ) - (benchmark1Top + (benchmark1Bottom -  benchmark1Top) / 2);
		}


		console.log(' baseX ~~~ ', baseX);
		console.log(' baseY ~~~ ', baseY);
		console.log(' unitW ~~~ ', unitW);
		console.log(' unitH ~~~ ', unitH);


		const scaleRate = 1 //this.data.scaleOffY || 0.055;
		let postionRate = 1 //this.data.positionOffY || 0.4;

		// if (cc.sys.isNative && cc.sys.os == cc.sys.OS_IOS) {
		// 	postionRate *= 1.7;
    // }


		const dotArr = [];
		for (let i=0; i<this.centerItemArr.length; i++) {
			const checkLetter = this.centerItemArr[i];

			let x = baseX + checkLetter.unitX * unitW;
			const y = baseY + checkLetter.unitY * unitH;
			const w = checkLetter.unitW * unitW;
			const h = checkLetter.unitH * unitH;
			const r = Math.min(w, h)

			// console.log('w: ', w);
			// console.log('h: ', h);
			// console.log('y: ', y);

			// const centerX = baseX + this.centerUnitW * unitW;

			// const tempR = scaleRate * (checkLetter.unitY * unitH);
			// const newR = r - tempR; 

			// let newW = w - tempR; 
			// let newH = h - tempR;


			// const rate = newR / r;

			// const tempY = ( y - (baseY) ) * postionRate;
			// y = y - tempY * (1 - rate);


			// const tempX = (centerX - x) * postionRate;
			// x = x + tempX * (1-rate);


			// const newScale = 1.4;
			// const edgeOff = (newScale - 1) / 2;
			// x -= edgeOff * newW;
			// y += edgeOff * newH;
			// newW *= newScale;
			// newH *= newScale;

			// const dot = this.getColorDot(x, -y, newW, newH);

			const dot = this.getColorDot(x, -y, w / 2, h / 2);



			this.debugDrawLayer.addChild(dot, 5);

			dot.key = centerItemArr[i].index + 1;

			dot.labelText = checkLetter.labelText;
			dotArr.push(dot);


		}



		// console.log('dotArr: ', dotArr);
		console.log('benchmark1LabelData: ', benchmark1LabelData);

		const answerData = {};

		for (let j=0; j<this.centerItemArr.length; j++) {
			const checkLetter = this.centerItemArr[j];

			const wordDataArr = this.getPhotoWordArr(checkLetter.labelText, text, benchmark1LabelData);

			console.log('~~~wordDataArr: ', wordDataArr);


			for (let i=0; i<wordDataArr.length; i++) {

				const tempWordArr = this.getTempWordArr(wordDataArr[i],['']); // wordDataArr[i].word;

				for (let k=0; k<tempWordArr.length; k++) {
					
					const {location , content} = tempWordArr[k];

					const rect = {
						x: location.left, 
						y: -location.bottom, 
						width: Math.abs( location.right - location.left ), 
						height: Math.abs( location.bottom - location.top ), 
					}                        
					const colorRect = this.getColorRect(rect, "purple");
					colorRect.labelText = content;
					this.debugDrawLayer.addChild(colorRect);

					// console.log('colorRect: ', colorRect);

					const label = this.getLabel(content, colorRect.scaleX *  colorRect.width);
					label.x = colorRect.x + colorRect.width / 2 * colorRect.scaleX;
					label.y = colorRect.y + colorRect.height / 2 * colorRect.scaleY;
					label.color = cc.Color.BLACK;

					this.debugDrawLayer.addChild(label);
					
	
					this.setOneAnswerData(colorRect, dotArr, answerData, wordDataArr[i]);
	
				}
				
			}

		
		}



		const benchmark1Rect = {
			x: benchmark1Left, 
			y: -benchmark1Bottom,
			width: Math.abs( benchmark1Left - benchmark1Right ), 
			height: Math.abs( benchmark1Top - benchmark1Bottom ), 
		}

		console.log('benchmark1Rect: ', benchmark1Rect);
		
		const colorbenchmark1Rect = this.getColorRect(benchmark1Rect, 'green');
		this.debugDrawLayer.addChild(colorbenchmark1Rect);





		// const rectTop = {
		// 	x: topLocationLeft, 
		// 	y: -topLocationBottom,
		// 	width: Math.abs( topLocationLeft - topLocationRight ), 
		// 	height: Math.abs( topLocationTop - topLocationBottom ), 
		// }
		
		// const colorRectTop = this.getColorRect(rectTop, 'green');
		// this.debugDrawLayer.addChild(colorRectTop);



		// const rectBottom = {
		// 	x: bottomLocation.left, 
		// 	y: -bottomLocation.bottom,
		// 	width: Math.abs( bottomLocation.left - bottomLocation.right ), 
		// 	height: Math.abs( bottomLocation.top - bottomLocation.bottom ), 
		// }
		
		// const colorRectBottom = this.getColorRect(rectBottom, 'green');
		// this.debugDrawLayer.addChild(colorRectBottom);






		return answerData;


	},


	getArrByCharacters(line) {
		const wordArr = [];
		const arr = line.characters;
		for (let i=0; i<arr.length; i++) {

			const {character, poly, centerLoc} = arr[i];

			if (character == 0) {
				arr[i].character = 'o'
			}

			let content = character;

		

			const location = {}
			location.left = poly[0];
			location.top = poly[1];
			location.right = poly[2];
			location.bottom = poly[7];

			const left = poly[0];
			const top = poly[1];
			const right = poly[2];
			let bottom = poly[7];

			if (poly.length < 8) {
				location.bottom = poly[3];
				bottom = poly[3];

			}
			
			wordArr.push({content, location, centerLoc, left, top, right, bottom});
		}

		return wordArr;
	},

	getTempWordArr(line, splitText) {

		
		if (line.characters) {
			return this.getArrByCharacters(line);
		}

		const lineBox = {left: line.left, top: line.top, right: line.right, bottom: line.bottom};
		const baseX = lineBox.left;

		let textIndex = 0;
		const oneDisW = (lineBox.right - lineBox.left) / line.content.length;

		const arr = line.content.split(splitText);
		const wordArr = [];
		for (let i=0; i<arr.length; i++) {
			const content = arr[i];
			const location = {}
			location.left = baseX + textIndex * oneDisW;
			location.right = location.left + oneDisW * content.length;
			location.top = lineBox.top;
			location.bottom = lineBox.bottom;
			
			wordArr.push({content, location});

			textIndex += content.length;
		}

		return wordArr;
	},




	getAnswerWrongData(data) {
		
		const block = data?.block
		if (!block) {
			return false;
		}


		console.log(' in getAnswerWrongData: ', block);

		const endKeyObj = {};
		for (let j = 0; j < this.picNodeArr.length; j++) {

			const picNode = this.picNodeArr[j];

			const key = picNode.data.rectItem // i.toString();

			if (picNode.isShowEnd) {
				endKeyObj[key] = true;
			}
		}


		const topLabelData = this.topLabelData;
		let bottomLabelData ;
		if (this.bottomLabelData) {
			bottomLabelData = this.bottomLabelData;
		} else {
			bottomLabelData = this.topLeftLetter;
		}
		// const bottomLabelData = this.bottomLabelData;
		const centerItemArr = this.centerItemArr;

		// console.log('topLabelData: ', topLabelData);

		const firstTopWordLocation = topLabelData.word[0].location;
		const lastTopWordLocation = topLabelData.word[topLabelData.word.length - 1].location
		const topLocationLeft = firstTopWordLocation.left;
		const topLocationTop = firstTopWordLocation.top;
		const topLocationRight = lastTopWordLocation.right;
		const topLocationBottom = lastTopWordLocation.bottom;


		const bottomLocation = bottomLabelData.word[0].location;

		const baseX = topLocationLeft;
		const baseY =	topLocationTop + (topLocationBottom - topLocationTop) / 2;
		const unitW = topLocationRight - topLocationLeft;
		const unitH = bottomLocation.top + (bottomLocation.bottom - bottomLocation.top) / 2 - baseY;

		console.log(' unitW ~~~ ', unitW);
		console.log(' unitH ~~~ ', unitH);


		const scaleRate = this.data.scaleOffY || 0.055;
		let postionRate = this.data.positionOffY || 0.4;

		if (cc.sys.isNative && cc.sys.os == cc.sys.OS_IOS) {
			postionRate *= 1.7;
    }


		const dotArr = [];
		for (let i=0; i<this.centerItemArr.length; i++) {
			const checkLetter = this.centerItemArr[i];

			const key = centerItemArr[i].index + 1;
			if (endKeyObj[key]) {
				continue;
			}

			let x = baseX + checkLetter.unitX * unitW;
			const y = baseY + checkLetter.unitY * unitH;
			const w = checkLetter.unitW * unitW;
			const h = checkLetter.unitH * unitH;
			const r = Math.min(w, h)

			// console.log('w: ', w);
			// console.log('h: ', h);
			// console.log('y: ', y);

			const centerX = baseX + this.centerUnitW * unitW;
	
			
		
			// y -= ( y - (baseY + unitH) ) * 0.35;



			const tempR = scaleRate * (checkLetter.unitY * unitH);
			const newR = r - tempR; 

			let newW = w - tempR; 
			let newH = h - tempR;


			const rate = newR / r;

			const tempY = ( y - (baseY) ) * postionRate;
			y = y - tempY * (1 - rate);


			const tempX = (centerX - x) * postionRate;
			x = x + tempX * (1-rate);




			const newScale = 1.4;
			const edgeOff = (newScale - 1) / 2;
			x -= edgeOff * newW;
			y += edgeOff * newH;
			newW *= newScale;
			newH *= newScale;

			const dot = this.getColorDot(x, -y, newW, newH);
			// const dot = this.getColorDot(x, -y, newR, newR);

			this.debugDrawLayer.addChild(dot, 5);

			dot.key = centerItemArr[i].index + 1;
			dot.centerPos = cc.v2(dot.x+ dot.width / 2, dot.y + dot.height / 2);

			dot.labelText = checkLetter.labelText;
			dotArr.push(dot);


		}


		console.log('topLabelData: ', topLabelData);

		const answerData = {};


		for (let i=0; i<block.length; i++) {
			const lineArr = block[i].line;
			if (!lineArr) {
				continue;
			}

			for (let m=0; m<lineArr.length; m++) {
				const line = lineArr[m];
				
				
				console.log('line: ', JSON.stringify(line));
				const lineRect = this.getLineRect( line );
				console.log('lineRect: ~  ', JSON.stringify(lineRect));
				const lineCenterPos = cc.v2(lineRect.x + lineRect.width / 2, lineRect.y + lineRect.height / 2);

	
				const tempDotArr = [];
				for (let j=0; j<dotArr.length; j++) {
					const isInLineRect = lineRect.intersects(dotArr[j].dotRect)
					if (isInLineRect) {
						tempDotArr.push(dotArr[j]);
					}
				}
				if (tempDotArr.length > 0) {
					const colorRect = this.getColorRect(lineRect, 'purple');
					this.debugDrawLayer.addChild(colorRect);

					console.log('tempDotArr.length > 0')
					let minDistance;
					let curDot;
					for (let j=0; j<tempDotArr.length; j++) {
						const curDistance = cc.Vec2.distance(lineCenterPos, tempDotArr[j].centerPos);
						if (minDistance == null || minDistance > curDistance) {
							minDistance = curDistance;
							curDot = tempDotArr[j];
						}
					}
	
					const tempWordArr = line.word;
					let sentence = ''
					tempWordArr.forEach(item => {
						sentence += item.content.trim();
					});
	
					console.log('sentence: ', sentence);
					console.log('curDot.labelText: ', curDot.labelText);
					if (sentence.length >= curDot.labelText.length) {
						if (!answerData[curDot.key]) {
							answerData[curDot.key] = {sentence, lineCenterPos, minDistance, count: 1}
						} else {                                        
							const oldData = answerData[curDot.key];
							if (oldData.minDistance > minDistance) {
								answerData[curDot.key] = {sentence, lineCenterPos, minDistance, count: 1}
							}
						}
					}
				} else {

					const colorRect = this.getColorRect(lineRect, 'red');
					this.debugDrawLayer.addChild(colorRect);
				}
			}

	
		}


		return answerData;


	},


	setCirclePosInRectArr(colorRect) {


		const rect = colorRect.ccRect;
		const dotV2 = new cc.Vec2(rect.x + rect.width/2, rect.y + rect.height / 2);

		const circleRectCheckArr = this.circleRectCheckArr;

		for (let i=0; i<circleRectCheckArr.length; i++) {

			const checkRect = circleRectCheckArr[i].ccRect;
			const key = circleRectCheckArr[i].data.index + 1;

			// console.log("labelText: ", labelText);
			// console.log("key: ", key);

			// if (labelText.toLowerCase().indexOf(targetLabelText.toLowerCase()) != -1 && rect.intersects(dotRect)) {
			if (checkRect.contains(dotV2)) {
				if (!colorRect.inRectArr) {
					colorRect.inRectArr = []
				}
				colorRect.inRectArr.push(key);
			}

		}
	},



	setOneAnswerDataNew(colorRect, answerData) {
		const rect = colorRect.ccRect;
		const dotV2 = new cc.Vec2(rect.x + rect.width/2, rect.y + rect.height / 2);


		let targetLabelText = colorRect.labelText;
		targetLabelText = targetLabelText.replace(/(^\s+)|(\s+)|(\s+$)/g,"");


		const newRectCheckArr = this.newRectCheckArr;

		for (let i=0; i<newRectCheckArr.length; i++) {

			const labelText = newRectCheckArr[i].data.labelText;
			const checkRect = newRectCheckArr[i].ccRect;
			const key = newRectCheckArr[i].data.index + 1;


			// console.log("labelText: ", labelText);
			// console.log("key: ", key);

			// if (labelText.toLowerCase().indexOf(targetLabelText.toLowerCase()) != -1 && rect.intersects(dotRect)) {
			// if (labelText == targetLabelText && checkRect.contains(dotV2)) {
			if (checkRect.contains(dotV2)) {
				// const len = targetLabelText.trim().length;

				// console.log('len: ', len);

				// if (newRectCheckArr[i].data.isFuzzy) {

				const index = labelText.indexOf("||");
				if (index != -1) {
					const keyArr = labelText.split("||");

					for (let j=0; j<keyArr.length; j++) {

						if (targetLabelText.indexOf(keyArr[j]) != -1 ) {
							answerData[key] = {isFinish: true};
							break;
						}

					}
				} else {

					if (targetLabelText.indexOf(labelText) != -1 ) {
						answerData[key] = {isFinish: true};
					}
				}


					// if (targetLabelText.indexOf(labelText) != -1 ) {
					// 	answerData[key] = {isFinish: true};
					// }

				// } else {
				// 	if (labelText == targetLabelText) {
				// 		answerData[key] = {isFinish: true};
				// 	}
				// }


			}

		}
	},

	setOneAnswerData(colorRect, dotArr, answerData, line) {

		console.log(' in setOneAnswerData')
		console.log('colorRect: ', colorRect)
		console.log('dotArr: ', dotArr)
		console.log('answerData: ', answerData)

		
		const rect = colorRect.ccRect;
		const targetLabelText = colorRect.labelText;

		for (let i=0; i<dotArr.length; i++) {

			const {dotRect, labelText, key} = dotArr[i];

				console.log('targetLabelText.toLowerCase() : ', targetLabelText.toLowerCase() );
				console.log('labelText.toLowerCase()  : ', labelText.toLowerCase()  );
				console.log('rect.intersects(dotRect) : ', rect.intersects(dotRect) );

			if (labelText.toLowerCase().indexOf(targetLabelText.toLowerCase()) != -1 && rect.intersects(dotRect)) {
				const len = targetLabelText.trim().length;

				console.log('len: ', len);

				if (!answerData[key]) {
					answerData[key] = {colorRect, count: len};
				} else {
					answerData[key].count += len;

					// console.log('len: ', len);
					// console.log('	answerData[key].count: ', 	answerData[key].count);

				}

				if ( labelText.length <= 1) {
					answerData[key].isFinish = true;
					answerData[key].line = line;

				} else {
					if (answerData[key].count >= labelText.length) {
						answerData[key].isFinish = true;
						answerData[key].line = line;
					}
				}
				

			
				// return;
			}

		}

	},

	getColorRect(rect, color=null) {

		if (!color) {
			color = 'red'
		}


		rect.x *= this.debugBgImg.width;
		rect.y *= this.debugBgImg.height;
		rect.width *= this.debugBgImg.width;
		rect.height *= this.debugBgImg.height;

		const node = getSprNode(color);
		node.anchorX = 0;
		node.anchorY = 0;
		node.x = rect.x;
		node.y = rect.y;
		node.scaleX = rect.width / node.width;
		node.scaleY = rect.height / node.height;

		node.ccRect = new cc.Rect(rect.x, rect.y, rect.width, rect.height);



		return node;
	},



	getColorDot(x, y, w=100, h=100, color='red') {
		const node = new cc.Node();

		if (!h) {
			h = w;
		}

		x *= this.debugBgImg.width;
		y *= this.debugBgImg.height;
		w *= this.debugBgImg.width;
		h *= this.debugBgImg.height;

		if (this.debugLayer.parent && this.debugLayer.active) {

			const rect = {
				x:- w/2,
				y: - h/ 2, 
				width:w, 
				height:h
			}
			// const colorDot = this.getColorRect(rect,'blue');
			// colorDot.fillColor = cc.Color.BLUE;
			// colorDot.fillRect( - r/2, - r/ 2, r, r);

			const colorDot = getSprNode(color);

			
			// colorDot.anchorX = 0;
			// colorDot.anchorY = 0;
			// colorDot.x = rect.x;
			// colorDot.y = rect.y;
			colorDot.scaleX = rect.width / colorDot.width;
			colorDot.scaleY = rect.height / colorDot.height;
			node.addChild(colorDot);



			// const rect1 = new cc.Rect(node.x -r/2, node.y -r/2, r, r);
			// const colorDot = this.getColorRect(rect1, 'green');

			// colorDot.dotRect = rect1;
			// return colorDot;
		}

		node.x = x;
		node.y = y;


		// node.opacity = 0.5;

		const rect = new cc.Rect(node.x -w/2, node.y -h/2, w, h);
		node.dotRect = rect;
		node.ccRect = rect;
		return node;
	},


	getColorBgColorDot(x, y, w=100, h=100) {
		
		// const node = new cc.Node();

		if (!h) {
			h = w;
		}

		x *= this.colorBg.width;
		y *= this.colorBg.height;
		w *= this.colorBg.width;
		h *= this.colorBg.height;

		x = Math.round(x * 100) / 100;
		y = Math.round(y * 100) / 100;
		w = Math.round(w * 100) / 100;
		h = Math.round(h * 100) / 100;

		const rect = {
			x:- w/2,
			y: - h/ 2, 
			width:w, 
			height:h
		}
	
		const colorDot = this.getColorPoolSpr();



		const sx = rect.width / colorDot.width;;
		const sy = rect.height / colorDot.height;
		colorDot.scale = Math.max(sx, sy);
		// colorDot.scaleX = rect.width / colorDot.width;
		// colorDot.scaleY = rect.height / colorDot.height;

		colorDot.x = x;
		colorDot.y = y;

		return colorDot;


		// node.addChild(colorDot);
		// node.colorDot = colorDot;



		
		// node.x = x;
		// node.y = y;

		// return node;
	},
	



	checkHasAnswer(data, text) {

		text = text.toLowerCase();
		text = text.replace(/(^\s+)|(\s+$)/g,"");



		// -----
		let sentence = data.allText.replace('/\n/g', "");

		sentence = sentence.trim();
		sentence = sentence.toLowerCase();
		 


		if (sentence.indexOf(text) != -1) {

			// this.setTestLabel(line[i])

			return true;
		}
		// -----



		const block = data.block;
		for (let j = 0; j < block.length; j++) {

			const line = block[j].line;
			if (!line) {
				continue;
			}


			for (let i = 0; i < line.length; i++) {

				const word = line[i].word;
				const location = line[i].word[0].location;
		
				// console.log(' center line: ', line[i]);


				let sentence = ''
				word.forEach(item => {
					sentence += item.content.trim();
				});

				sentence = sentence.trim();
				sentence = sentence.toLowerCase();

				line[i].sentence = sentence;
				console.log('sentence: ' + sentence + ', text: ' + text);


				if (sentence.indexOf(text) != -1) {


					if (sentence) {
						this.setTestLabel(line[i])
					}

					// line[i].tmpLen = this.getToZeroLen(location)
					// if (!topLeftLetter) {
					// 	topLeftLetter = line[i];
					// } else {
					// 	if (topLeftLetter.tmpLen > line[i].tmpLen) {
					// 		topLeftLetter = line[i];
					// 	}
					// }

					return true;
				}
			}
		}

	},

	


	setTestLabel(labelData) {

		if (!this.debugLayer.parent || !this.debugLayer.active) {
			return;
		}
		// console.log('labelData: ', labelData)
		const location = labelData.word[0].location;
		const label = this.getLabel(labelData.sentence);
		label.anchorX = 0;
		// label.anchorY = 1;
		label.x = location.left;
		label.y = -location.top
		label.zIndex = 50;


		const rect = {};
		rect.width = location.right - location.left;
		rect.height = location.bottom - location.top;
		rect.x = location.left;
		rect.y = -location.top;
		// const colorRect = this.getColorRect(rect, cc.Color.YELLOW);
		// this.debugLayer.addChild(colorRect);

		this.debugLayer.addChild(label);
	},

	getLabel(text, fontSize = 20, fontColor=cc.Color.BLACK, fontName=null) {
		const labelNode = new cc.Node();
		const label = labelNode.addComponent(cc.Label);
		label.string = text;
		labelNode.color = fontColor;
		label.fontSize = fontSize;
		label.lineHeight = fontSize;
		label.cacheMode = cc.Label.CacheMode.CHAR;

		if (!fontName) {
			fontName = 'default';
		}

		if (fontName) {
			const baseLabel = cc.find("Canvas/res/font/" + fontName).getComponent(cc.Label);
			label.font = baseLabel.font;
		}

		return labelNode;
	},



	debugLayer: null,
	initDebugLayer() {


		console.log(' in initDebugLayer');
		const layer = new cc.Node();

		if (this.data.isDebug) {
			layer.parent = cc.find('Canvas');
		}


		layer.width = this.canvas.width / 2;
		layer.height = this.canvas.height / 2;

		layer.zIndex = 100;
		layer.anchorX = 0;
		layer.anchorY = 1;


		if (!this.data.bgItem2) {
			return;
		}


		cc.loader.load({url: this.data.bgItem2.url}, (err, img) => {

			this.debugBgImg = img;
			this.checkBg = img;
			layer.width = img.width;
			layer.height = img.height;

			layer.data = this.data.bgItem2;

			const sprNode = layer;
	
			var sf = new cc.SpriteFrame(img);

			const spr = sprNode.addComponent(cc.Sprite);
			spr.spriteFrame = sf			

			const sx = this.canvas.width / 2 / layer.width;
			const sy = (this.canvas.height) / 2 / layer.height;
			const s = Math.min(sx, sy);
			layer.scale = s;

			this.addNewRect();
			this.addCircleItem();
			this.addSignItem();
			this.addColorItem();

			this.initDebugRect();

			this.checkStart();
	
		});

		layer.x = -this.canvas.width / 2 + 10;
		layer.y = this.canvas.height / 2 - this.canvas.height / 3;
		layer.opacity = 150;

		// layer.scale = 2;
		this.debugLayer = layer;

		// const bgRectNode = new cc.Node();
		// const ctx = bgRectNode.addComponent(cc.Graphics);
		// ctx.fillRect(0, -layer.height, layer.width, layer.height);
		// ctx.fillColor = cc.Color.YELLOW.setA(100);
		// ctx.fill();
		// layer.addChild(bgRectNode);


		const drawLayer = new cc.Node();
    this.debugLayer.addChild(drawLayer, 2);

    this.debugDrawLayer = drawLayer;



	},

	initDebugRect() {

		console.log(' in initDebugRect');

		
		this.linkRectGroup = [];
		this.data.hotZoneItemArr2.forEach((item) => {
			switch (item.gIdx) {
				case "0":
					this.setOneDebugLinkRect(item);
					break;

		
				// case "1":
				// 	this.setOneDebugWriteRect(item);
				// 	break;

				default:
					break;
			}

		});
	

		console.log("this.linkRectGroup: ", this.linkRectGroup);
	},

	setOneMultRect(data) {
		const rate = (this.debugLayer.scale * this.debugLayer.width) / this.data.bgItem2.rect.width;
	
		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		this.debugLayer.addChild(rectNode);

		let ctx = rectNode.addComponent(cc.Graphics);

		ctx.lineWidth = 4;

		const color = new cc.Color();
		cc.Color.fromHEX(color, data.color );

		ctx.strokeColor = color// cc.Color.RED;
		ctx.fillColor = color.setA(100);//cc.Color.WHITE.setA(100);

		const scale = rate / this.debugLayer.scaleY;

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = data.rect.x * scale;
		rectNode.y =  - data.rect.height * scale - data.rect.y * scale;
	

		rectNode.anchorX = 0;
		rectNode.anchorY = 0;

		if (this.data.isDebug) {
			ctx.rect(0, 0, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();


		rectNode['data'] = data;
		// rectNode.opacity = 100;

		rectNode['ccRect'] = rectNode.getBoundingBoxToWorld()


		// rectNode.isRightPoint = data.checkbox.list[0].value == true;

		// this.linkRectGroup.push(rectNode);

	},

	setOneDebugLinkRect(data) {
		const rate = (this.debugLayer.scale * this.debugLayer.width) / this.data.bgItem2.rect.width;
	
		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		this.debugLayer.addChild(rectNode);

		let ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / this.debugLayer.scaleY;

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = data.rect.x * scale;
		rectNode.y =  - data.rect.height * scale - data.rect.y * scale;
	

		rectNode.anchorX = 0;
		rectNode.anchorY = 0;

		if (this.data.isDebug) {
			ctx.rect(0, 0, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();


		rectNode['data'] = data;
		rectNode.opacity = 100;

		rectNode['ccRect'] = rectNode.getBoundingBoxToWorld()


		rectNode.isRightPoint = data.checkbox.list[0].value == true;

		this.linkRectGroup.push(rectNode);

		this.setLinkDataByDebugItem(rectNode, data.index);

	},

	setLinkDataByDebugItem(item, index) {

		let hzItemId;
		let debugItemId;
		let linkHzItemId;
		let linkDebugItemId;


		debugItemId = index + 1;

		const hzItem = this.getHzItemByPoint(debugItemId)

		hzItemId = this.data.hotZoneItemArr.indexOf(hzItem) + 1;

		console.log(' hzItem: ', hzItem);
		console.log(' debugItemId: ', debugItemId);

		linkHzItemId = hzItem.linkItem;

		const linkHzItem = this.data.hotZoneItemArr[linkHzItemId-1]

		linkDebugItemId = linkHzItem.pointItem;


		const linkData = {hzItemId, debugItemId, linkHzItemId, linkDebugItemId};
		item.linkData = linkData;

	},

	getHzItemByPoint(pointId, gIdx = '0') {
		
		const hzItem = this.data.hotZoneItemArr.find((item) => {

			if (item.gIdx == gIdx) {
				return item.pointItem == pointId
			}
		});

		return hzItem;
	},


	addColorItem() {
		console.log('addColorItem 1');
		if (!this.colorRectArr) {
			return;
		}

		console.log('addColorItem 2');

		this.colorRectCheckArr = [];
		const bg = this.debugLayer;
		for (let i=0; i<this.colorRectArr.length; i++) {
			const oneData = this.colorRectArr[i];
			const rect = this.setDebugRectDot(oneData, bg);
			this.colorRectCheckArr.push(rect);
			this.setColorRectPointsMax(rect);

			console.log('oneData: ', oneData);
		}
	},

	setColorRectPointsMax(rect) {

		const data = rect.data;

		const bgRect = this.data.bgItem2.rect;
		const regionRect = data.rect;
		const region = this.getRegionByRect(regionRect, bgRect);

		const regionW = region.right - region.left;
		const regionH = region.bottom - region.top;


		const pointNumX = regionW / this.serverUnitX;
		const pointNumY = regionH / this.serverUnitY;
		const pointsMax = pointNumX * pointNumY;
		
		rect.pointsMax = Math.round( pointsMax );
		console.log('rect.pointsMax : ', rect.pointsMax );
	},

	addSignItem() {
		if (!this.signRectArr) {
			return;
		}

		this.signRectCheckArr = [];
		const bg = this.debugLayer;
		for (let i=0; i<this.signRectArr.length; i++) {
			const oneData = this.signRectArr[i];
			const rect = this.setDebugRectDot(oneData, bg);
			this.signRectCheckArr.push(rect);
			console.log('oneData: ', oneData);
		}
	},

	addCircleItem() {

		if (!this.circleRectArr) {
			return;
		}

		this.circleRectCheckArr = [];
		const bg = this.debugLayer;
		for (let i=0; i<this.circleRectArr.length; i++) {
			const oneData = this.circleRectArr[i];
			const rect = this.setDebugRectDot(oneData, bg);
			this.circleRectCheckArr.push(rect);

			if (oneData.multRect) {
				this.setMultRect(oneData);
			}
			console.log('oneData: ', oneData);
		}
	},

	setMultRect(data) {
		const multRect = data.multRect;
		for(let i=0; i<multRect.length; i++) {
			this.setOneMultRect(multRect[i]);
		}
		console.log("multRect: " , multRect);
	},

	setDebugRectDot(data, bg) {
		const bgData = bg.data;
		const rate = (bg.scale * bg.width) / bgData.rect.width;

		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		bg.addChild(rectNode);


		const ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / bg.scaleY;

		console.log('scale: ', scale);

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = data.rect.x * scale;
		rectNode.y =  - data.rect.y * scale - data.rect.height * scale;


		rectNode.anchorX = rectNode.anchorY = 0;


		rectNode.x /= bg.width;
		rectNode.y /= bg.height;
		rectNode.width /= bg.width;
		rectNode.height /= bg.height;
		const colorRect = this.getColorRect(rectNode, 'blue');
		colorRect.opacity = 180;
		colorRect.data = data;

		colorRect.rectNode = rectNode;

		bg.addChild(colorRect, 20);

		return colorRect;
	},

	addNewRect() {
		
		if (!this.newRectArr) {
			return;
		}

		this.newRectCheckArr = [];
		const bg = this.debugLayer;
		for (let i=0; i<this.newRectArr.length; i++) {
			const oneData = this.newRectArr[i];
			this.setNewRectDot(oneData, bg);
			console.log('oneData: ', oneData);
		}

	},


	setNewRectDot(data, bg) {
		const bgData = bg.data;
		const rate = (bg.scale * bg.width) / bgData.rect.width;

		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		bg.addChild(rectNode);


		const ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / bg.scaleY;

		console.log('scale: ', scale);

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = data.rect.x * scale;
		rectNode.y =  - data.rect.y * scale - data.rect.height * scale;


		rectNode.anchorX = rectNode.anchorY = 0;


		rectNode.x /= bg.width;
		rectNode.y /= bg.height;
		rectNode.width /= bg.width;
		rectNode.height /= bg.height;
		const colorRect = this.getColorRect(rectNode, 'green');
		colorRect.opacity = 180;
		colorRect.data = data;
		bg.addChild(colorRect, 20);

		this.newRectCheckArr.push(colorRect);                                                                                                                                                                                        


		// if (this.data.bgItem.isShowDebugLine || true) {
		// 	ctx.rect(0, 0, rectNode.width, rectNode.height);
		// }
		// ctx.stroke();
		// ctx.fill();

	},
	 


	getPhotoWordArr(text, block, benchmark1Data) {


		const wordArr = [];
		// const maxLen = 10;

		text = text.trim();

		const topY = -benchmark1Data.top;

		for(let j=0; j<block.length; j++) {

			const line = block[j];
			if (!line) {
				continue;
			}


			const sentence = line.content;
			if (sentence.indexOf(text) != -1 ) {
				wordArr.push( line );
			}

			// for (let i=0; i<line.length; i++) {


			// 	const location = line[i].word[0].location;

			// 	const curTop = -location.top;
			// 	if (curTop >= topY ) {
			// 		continue;
			// 	}


			// 	let word = line[i].word;
			// 	let sentence = ''

			// 	// if (word.length > maxLen) {
			// 	// 	console.log('continue ', word.length);
			// 	// 	continue;
			// 	// }

			// 	line[i].word = word = this.checkCutWordData(word);
			// 	// console.log('word1~ ', word);


			// 	word.forEach(item => {
			// 		sentence += item.content + '';
			// 	});

			// 	sentence = sentence.trim().toLowerCase();

			// 	text = text.toLowerCase();

			// 	line[i].sentence = sentence;
			// 	console.log('sentence: ', sentence);
			// 	console.log('text: ', text);

			// 	console.log('index: ', sentence.indexOf(text));
			// 	if (sentence.indexOf(text) != -1 ) {
			// 		wordArr.push( line[i] );
			// 	}
			// }
		}

		return wordArr;
	},


	checkCutWordData(wordArr) {


		// console.log('wordArr: ', wordArr);

		let newWordArr = [];
		for(let i=0; i<wordArr.length; i++) {

			let wordObj = wordArr[i];

			wordObj.content = wordObj.content.trim();

			if (wordObj.content.length > 1) {

				const tmpArr = [];
				const w = wordObj.location.right - wordObj.location.left
				const subW = w / wordObj.content.length;
				for (let j=0; j<wordObj.content.length; j++) {

					const subWordObj = {};
					subWordObj.content = wordObj.content[j];
					subWordObj.location = {
						top: wordObj.location.top,
						bottom: wordObj.location.bottom,
						left: wordObj.location.left + subW * j,
						right: wordObj.location.left + subW * (j + 1)
					}

					tmpArr.push(subWordObj);
				}
				newWordArr = newWordArr.concat(tmpArr)


			} else {
				newWordArr.push(wordObj)
			}

		}

		// console.log('newWordArr: ', newWordArr);
		return newWordArr;
	},

	getPhotoData(cb) {

		cb ({"result":{"text":[{"symbol":[4,4,2,2,4],"poly":[{"left":0.20399999618530273,"right":0.26999998092651367,"top":0.2774343192577362,"bottom":0.3369397222995758},{"left":0.7649999856948853,"right":0.8330000042915344,"top":0.2774343192577362,"bottom":0.33771252632141113},{"left":0.2070000022649765,"right":0.27300000190734863,"top":0.442812979221344,"bottom":0.5061823725700378},{"left":0.48399999737739563,"right":0.5529999732971191,"top":0.44435858726501465,"bottom":0.5092735886573792},{"left":0.7620000243186951,"right":0.8330000042915344,"top":0.43894898891448975,"bottom":0.5046367645263672}]}]}})

		return;

	
	},


	checkOneCombineGroupEnd(node) {

		const signItem = node.data.signItem;

		for (let i=0; i<this.itemCombineGroup.length; i++) {
			const key1 = this.itemCombineGroup[i][0] + 1;
			const key2 = this.itemCombineGroup[i][1] + 1;

			if (key1 == signItem || key2 == signItem) {

				let item1, item2;
				for (let j=0; j<this.signAnimaNodeArr.length; j++) {
					const data = this.signAnimaNodeArr[j].data;
					if (data.signItem == key1) {
						item1 = this.signAnimaNodeArr[j];
					} else if (data.signItem == key2) {
						item2 =  this.signAnimaNodeArr[j];
					}
				}

				if (item1?.isShowEnd || item2?.isShowEnd) {
					return true;
				}
				return false;
			}
			
		}
	},

	checkGameEndCombineGroup() {
		// const arr = this.signAnimaNodeArr;
		console.log(' in checkGameEndCombineGroup');

		for (let i=0; i<this.itemCombineGroup.length; i++) {
			const key1 = this.itemCombineGroup[i][0] + 1;
			const key2 = this.itemCombineGroup[i][1] + 1;

			let item1, item2;

			for (let j=0; j<this.signAnimaNodeArr.length; j++) {
				const data = this.signAnimaNodeArr[j].data;
				if (data.signItem == key1) {
					item1 = this.signAnimaNodeArr[j];
				} else if (data.signItem == key2) {
					item2 =  this.signAnimaNodeArr[j];
				}
			}

			if (!item1.isShowEnd && !item2.isShowEnd) {
				this.resetHelperTime();
				return;
			}
			
		}

		this.gameEnd();
	},


	checkGameEnd_Old( arr ) {

		this.pauseHelper()

		console.log(' in checkGameEnd arr.length: ', arr.length);
		if (!arr) {
			arr = this.animaNodeArr;
		}
		const isEnd = arr.every(node => {
			return node.isShowEnd;
		})

		if (isEnd) {
			this.gameEnd();
		} else {

			this.resetHelperTime();

			// this.endTesting();

			// setTimeout(() => {
			// 	this.startTesting();
			// }, 8000);

		}
	},














	bigStarArr: null,
	initStar() {
		const gArr = this.data.groupArr;
		if (gArr.length <= 1) {
			return;
		}

		this.cleanStar();

		this.bigStarArr = [];

		let baseX = this.canvas.width / 2 - 80 * this._mapScaleMin;
		let baseY = this.canvas.height / 2 - 80 * this._mapScaleMin;
		let disH = 80 * this._mapScaleMin;
		let disScale = 1;
		if (gArr.length > 5) {
			disH = (400 / gArr.length) * this._mapScaleMin;
			disScale = 5 / gArr.length;
		}
		for (let i = 0; i < gArr.length; i++) {
			const starBg = getSprNode('star_bg');
			this.canvas.addChild(starBg, 10);
			starBg.x = baseX;
			starBg.y = baseY - i * disH;
			starBg.scale = disScale;

			const starTop = getSprNode('star');
			starBg.addChild(starTop);
			starTop.active = false;
			starBg.star = starTop;

			const starBig = getSprNode('icon_bigstar');
			starTop.addChild(starBig);
			starBig.angle = -90;
			starBg.starBig = starBig;

			this.bigStarArr.push(starBg);
		}

		console.log("bigStarArr: ", this.bigStarArr);
	},

	cleanStar() {
		if (this.bigStarArr && this.bigStarArr.length > 0) {
			for (let i=0; i<this.bigStarArr.length; i++) {
				this.bigStarArr[i].removeFromParent();
			}
		}
	},


	showBigStar() {
		if (!this.bigStarArr || this.bigStarArr.length <= 0) {
			this.checkGameEnd();
			return;
		}
		const bigStarBg = this.bigStarArr[this.curGroupIndex];

		const starBig = bigStarBg.starBig;
		starBig.scale = 1;
		const star = bigStarBg.star;
		star.active = true;
		star.scaleX = 0.7 / bigStarBg.scale;
		star.scaleY = 1 / bigStarBg.scale;
		star.angle = 90;
		const canvas = cc.find('Canvas');
		const startPos = exchangeNodePos(star.parent, canvas, cc.v2(0, -canvas.height / 2));
		const middlePos = exchangeNodePos(star.parent, canvas, cc.v2(0, -canvas.height / 4));
		star.x = startPos.x;
		star.y = startPos.y - starBig.height;

		console.log('middlePos = ' + JSON.stringify(middlePos));
		const time = 1;
		cc.tween(star)
			.to(0.3, { y: middlePos.y + 80 }, { easing: 'quadOut' })
			.to(0.1, { y: middlePos.y + 40, scaleX: 1.2 / bigStarBg.scale, scaleY: 0.8 / bigStarBg.scale }, { easing: 'quadOut' })
			.to(0.1, { y: middlePos.y, scaleX: 1 / bigStarBg.scale, scaleY: 1 / bigStarBg.scale }, { easing: 'quadOut' })
			.delay(0.1)
			.to(0.8, { angle: -720, scale: 1 })
			.start();

		cc.tween(star)
			.delay(0.6)
			.to(0.8, { x: 0 }, { easing: 'quadIn' })
			.start();
		cc.tween(star)
			.delay(0.6)
			.to(0.8, { y: 0 }, { easing: 'quadOut' })
			.start();

		cc.tween(starBig)
			.delay(0.6)
			.to(0.8, { scale: 0 }, { easing: 'quadOut' })
			.call(() => {
				this.checkGameEnd();
				playAudio(this.starCountClip);
			})
			.start();

		playAudio(this.bigStarClip);
	},

	// checkGameEnd() {
	
	// 	this.curGroupIndex ++;
	// 	this.setCurGroupAndQuestion();



	// 	if (!this.curQuestionData) {
	// 		// this.gameEnd();
	// 		return;
	// 	}

	// 	this.showChangeQuesAnim();
	// },

	


	checkBtn: null,
	initBtn() {
		const checkBtn = getSprNode("btn_check");
		checkBtn.scale = this._mapScaleMin;
		this.canvas.addChild(checkBtn);
		checkBtn.x = -500 * this._mapScaleMin;
		checkBtn.y = -35 * this._mapScaleMin;
		checkBtn.baseX = checkBtn.x;
		checkBtn.baseY = checkBtn.y;
		checkBtn.opacity = 0;
		this.checkBtn = checkBtn;

		checkBtn.on(cc.Node.EventType.TOUCH_START, () => {
			if (checkBtn.opacity == 0) {
				return;
			}
			showBtnAnima(checkBtn);
			this.checkBtnClick();
		})

	},

	refreshCheckBtn() {

		this.checkBtn.opacity = 0;

		const arr = this.curOptionArr;
		for (let i=0; i<arr.length; i++) {
			if (arr[i].light.opacity > 254) {
				this.checkBtn.opacity = 255;
				return;
			}
		}
	},

	tryagain: null,
	initIcon() {
		const icon = getSprNode("try_again");
		icon.opacity = 0;
		icon.scale = this._mapScaleMin;
		this.canvas.addChild(icon);

		this.tryagain = icon;
	},

	showTryAgain() {
		const time = 0.3;
		cc.tween(this.tryagain)
			.to(time, {opacity: 255}, {easing: "cubicOut"})
			.delay(0.3)
			.to(time, {opacity: 0}, {easing: "cubicIn"})
			.start();
	},


	initQuestion() {
		this.initPicQuestion();
		this.initTextQuestion();
		this.initVideoQuestion();
		this.initAudioQuestion();
	},

	quesPicBg: null,
	initPicQuestion() {
		const picBg = getSprNode("ques_pic_bg");
		this.canvas.addChild(picBg);
		picBg.scale = this._mapScaleMin;
		picBg.y = 130 * this._mapScaleMin
		this.quesPicBg = picBg;
		picBg.active = false;

		this.addQuesAudio(picBg)
	},

	quesTextBg: null,
	initTextQuestion() {
		const picBg = getSprNode("ques_pic_bg");
		this.canvas.addChild(picBg);
		picBg.scale = this._mapScaleMin;
		picBg.y = 130 * this._mapScaleMin
		this.quesTextBg = picBg;


		const labelNode = new cc.Node();
		labelNode.parent = picBg;
		const label = labelNode.addComponent(cc.RichText);
		const size = 80
		label.font = cc.find('Canvas/res/font/Berlin-Sans-FB').getComponent(cc.Label).font;
		// label.string = `<outline color=#a83c13 width=2><size=${size}><color=#ffffff>${this.data.title || " " }</color></size></outline>`
		// label.string = `<size=${size}><color=#751e00>${this.curGroup.title }</color></size>`
		label.lineHeight = size;
		label.horizontalAlign = cc.macro.TextAlignment.CENTER

		label.maxWidth = 648;
	
		picBg.label = label;

		picBg.active = false;
		this.addQuesAudio(picBg)
	},

	quesVideoBg: null,
	videoNode: null,
	initVideoQuestion() {
		const picBg = getSprNode("ques_pic_bg");
		this.canvas.addChild(picBg);
		picBg.scale = this._mapScaleMin;
		picBg.y = 130 * this._mapScaleMin
		this.quesVideoBg = picBg;

		const videoNode = new cc.Node();
		const vPlayer = videoNode.addComponent(cc.VideoPlayer);
		picBg.addChild(videoNode);

		videoNode.width = 678;
		videoNode.height = 396;
		this.videoNode = videoNode;

		picBg.video = vPlayer;


		const btnNode = new cc.Node();
		picBg.addChild(btnNode);
		btnNode.x = picBg.width / 2 + 50;

		const playBtn = getSprNode("video_play");
		btnNode.addChild(playBtn);

		const pauseBtn = getSprNode("video_pause");
		btnNode.addChild(pauseBtn);
		pauseBtn.active = false;


		videoNode.player = vPlayer;
		videoNode.playBtn = playBtn;
		videoNode.pauseBtn = pauseBtn;

		playBtn.on(cc.Node.EventType.TOUCH_START, () => {
			vPlayer.play();
			playBtn.active = false;
			pauseBtn.active = true;
		})

		pauseBtn.on(cc.Node.EventType.TOUCH_START, () => {
			vPlayer.pause();
			pauseBtn.active = false;
			playBtn.active = true;
		})

		videoNode.on('completed', () => {
			pauseBtn.active = false;
			playBtn.active = true;
		})


		picBg.active = false;
	},

	quesAudioBg: null,
	initAudioQuestion() {

		
		const audioNode = new cc.Node();
		audioNode.active = false;

		this.canvas.addChild(audioNode);
		audioNode.x = 440 * this._mapScaleMin;
		audioNode.y = -60 * this._mapScaleMin;
		this.quesAudioBg = audioNode;
		
		const audioAnimNode = cc.instantiate(cc.find("Canvas/res/anim/audio_big"));
		audioNode.addChild(audioAnimNode);

		const iconTop = getSprNode('audio_big')
		audioNode.addChild(iconTop);
		iconTop.opacity = 255;

		iconTop.addComponent(cc.BlockInputEvents);
		iconTop.on(cc.Node.EventType.TOUCH_START, () => {

			if (iconTop.opacity == 0) {
				return;
			}

			if (!audioNode.audioClip) {
				return;
			}
			const anim = audioAnimNode.getComponent(cc.Animation);
			anim.play('audio_big');
			iconTop.opacity = 0;
			audioAnimNode.opacity = 255;

			if (audioNode.audioClip) {
				playAudio(audioNode.audioClip, () => {
					iconTop.opacity = 255;
					audioAnimNode.opacity = 0;
					anim.stop();
				});
			}
		})

	},


	addQuesAudio(bg) {
		const audioNode = new cc.Node();
		bg.addChild(audioNode);
		audioNode.x = bg.width / 2 + 50;


		const audioAnimNode = cc.instantiate(cc.find("Canvas/res/anim/ques_audio"));
		audioNode.addChild(audioAnimNode);

		const iconTop = getSprNode('ques_audio')
		audioNode.addChild(iconTop);
		iconTop.opacity = 255;

		iconTop.addComponent(cc.BlockInputEvents);
		iconTop.on(cc.Node.EventType.TOUCH_START, () => {

			if (iconTop.opacity == 0) {
				return;
			}
			const anim = audioAnimNode.getComponent(cc.Animation);
			anim.play('ques_audio');
			iconTop.opacity = 0;
			audioAnimNode.opacity = 255;

			if (audioNode.audioClip) {
				playAudio(audioNode.audioClip, () => {
					iconTop.opacity = 255;
					audioAnimNode.opacity = 0;
					anim.stop();
				});
			}
		})

		bg.audioNode = audioNode;
	},

	initOption() {
		this.initPicOption();
		this.initAudioOption();
		this.initTextOption();

		this.initPicOptionBig();
		this.initAudioOptionBig();
		this.initTextOptionBig();
	},

	optionPicBgArr: null,
	initPicOption() {
		// console.log('this.data: ', this.data);
		this.optionPicBgArr = [];
		for (let i=0; i<4; i++) {
		
			const pic = this.getOnePicOption();
			this.canvas.addChild(pic);
			pic.scale = this._mapScaleMin;
			pic.y = -235 * this._mapScaleMin;
			this.optionPicBgArr.push(pic);

		} 
	},

	optionPicBgBigArr: null,
	initPicOptionBig() {
		this.optionPicBgBigArr = [];

		const baseX = -380 * this._mapScaleMin;
		const disW = 440 * this._mapScaleMin;
		let baseY = 170 * this._mapScaleMin;
		const disH = 350 * this._mapScaleMin;
		let count = 0;


		for (let i=0; i<4; i++) {
		
			if (i==2) {
				count = 0;
				baseY -= disH;
			}
			const pic = this.getOnePicOption(true);
			this.canvas.addChild(pic);
			pic.scale = this._mapScaleMin;
			pic.x = baseX + count * disW;
			pic.y = baseY;
			this.optionPicBgBigArr.push(pic);

			count ++;
		} 
	},

	getOnePicOption(isBig = false) {
		const picBgParent = new cc.Node();

		let lightResName = "option_pic_bg_l";
		let bgResName = "option_pic_bg";
		if (isBig) {
			lightResName = "op_pic_bg_big_l";
			bgResName = "op_pic_bg_big";
		}

		const light = getSprNode(lightResName);
		picBgParent.addChild(light);
		light.opacity = 0;
		picBgParent.light = light;

		const picBg = getSprNode(bgResName);
		picBgParent.addChild(picBg);
		picBgParent.picBg = picBg;

		picBgParent.width = picBg.width;
		picBgParent.height = picBg.height;


		const soundNode = new cc.Node();
		picBgParent.addChild(soundNode);
		picBgParent.soundIcon = soundNode;

		const soundIconAnim = cc.instantiate(cc.find("Canvas/res/anim/laba"))
		soundNode.addChild(soundIconAnim);
		soundIconAnim.opacity = 0;

		const soundIconTop = getSprNode('btn_laba')
		soundNode.addChild(soundIconTop);
		soundIconTop.opacity = 255;

		soundNode.x = picBgParent.width / 2 - soundIconTop.width / 2;
		soundNode.y = picBgParent.height / 2 //- soundIconTop.height / 2;
		soundNode.active = false;


		picBgParent.active = false;


		picBgParent.on(cc.Node.EventType.TOUCH_START, () => {
			if( light.opacity == 0 ) {
				light.opacity = 255;
				playAudio(this.selectClip);
			} else {
				light.opacity = 0;
			}

			this.refreshCheckBtn();
		})


		soundIconTop.addComponent(cc.BlockInputEvents);
		soundIconTop.on(cc.Node.EventType.TOUCH_START, () => {
			const anim = soundIconAnim.getComponent(cc.Animation);
			anim.play('laba');
			soundIconTop.opacity = 0;
			soundIconAnim.opacity = 255;

			if (soundNode.audioClip) {
				playAudio(soundNode.audioClip, () => {
					soundIconTop.opacity = 255;
					soundIconAnim.opacity = 0;
					anim.stop();
				});
			}
		})

		return picBgParent;
	},

	addIconRight(bg) {

		const px = bg.width / 2;
		const py = -bg.height / 2 ;
		const worldPos = bg.convertToWorldSpaceAR(cc.v2(px, py));
		const localPos = this.canvas.convertToNodeSpaceAR(worldPos);


		const iconRight = getSprNode('icon_right');
		iconRight.scale = this._mapScaleMin;
		this.canvas.addChild(iconRight, 1);
		iconRight.x = localPos.x;
		iconRight.y = localPos.y + 50 * this._mapScaleMin;

		bg.iconRight = iconRight;


		this.showOneFirework(cc.v2(0, -bg.height / 3), bg, cc.find('paperBase').children, 200, 300, 20, 1);
	},


	optionAudioBgArr: null,
	initAudioOption() {
		this.optionAudioBgArr = [];
		for (let i=0; i<4; i++) {
		
			const audio = this.getOneAudioOption();
			this.canvas.addChild(audio);
			audio.scale = this._mapScaleMin;
			audio.y = -235 * this._mapScaleMin;
			this.optionAudioBgArr.push(audio);
		} 
	},

	optionAudioBgBigArr: null,
	initAudioOptionBig() {

		this.optionAudioBgBigArr = [];

		const baseX = -380 * this._mapScaleMin;
		const disW = 440 * this._mapScaleMin;
		let baseY = 170 * this._mapScaleMin;
		const disH = 350 * this._mapScaleMin;
		let count = 0;

		for (let i=0; i<4; i++) {
		
			if (i==2) {
				count = 0;
				baseY -= disH;
			}

			const audio = this.getOneAudioOption(true);
			this.canvas.addChild(audio);
			audio.scale = this._mapScaleMin;
			audio.x = baseX + count * disW;
			audio.y = baseY;
			this.optionAudioBgBigArr.push(audio);

			count ++;
		} 
	},


	optionTextBgArr: null,
	initTextOption() {
		this.optionTextBgArr = [];
		for (let i=0; i<4; i++) {
		
			const textOption = this.getOneTextOption();
			this.canvas.addChild(textOption);
			textOption.scale = this._mapScaleMin;
			// textOption.y = -235 * this._mapScaleMin;
			this.optionTextBgArr.push(textOption);
		} 
	},

	optionTextBgBigArr: null,
	initTextOptionBig() {

		const baseX = -180 * this._mapScaleMin;
		const disW = 100 * this._mapScaleMin;
		let baseY = 220 * this._mapScaleMin;
		const disH = 150 * this._mapScaleMin;

		this.optionTextBgBigArr = [];
		for (let i=0; i<4; i++) {
		
			const textOption = this.getOneTextOption(true);
			this.canvas.addChild(textOption);
			textOption.scale = this._mapScaleMin;
			textOption.x = baseX;
			textOption.y = baseY - i * disH;
			this.optionTextBgBigArr.push(textOption);
		}
	},

	getOneAudioOption(isBig=false) {

		let lightResName = "option_pic_bg_l";
		let bgResName = "option_pic_bg";
		if (isBig) {
			lightResName = "op_pic_bg_big_l";
			bgResName = "op_pic_bg_big";
		}

		const audioBgNode = new cc.Node();

		const light = getSprNode(lightResName);
		audioBgNode.addChild(light);
		light.opacity = 0;
		audioBgNode.light = light;

		const picBg = getSprNode(bgResName);
		audioBgNode.addChild(picBg);
		audioBgNode.picBg = picBg;

		audioBgNode.width = picBg.width;
		audioBgNode.height = picBg.height;

		const animNode = cc.instantiate(cc.find("Canvas/res/anim/op_audio"))
		audioBgNode.addChild(animNode);
		animNode.anchorX = 0.6;


		const animTop = getSprNode('op_audio');
		audioBgNode.addChild(animTop);
		animTop.anchorX = 0.6;

		const anim = animNode.getComponent(cc.Animation);
		animNode.opacity = 0;

		audioBgNode.anim = anim;
		audioBgNode.animNode = animNode;
		audioBgNode.animTop = animTop;
		
		audioBgNode.showAnim = () => {
			this.playItemAnim(audioBgNode);
			cc.audioEngine.stop(audioBgNode.audioId);
		}
		audioBgNode.stopAnim = () => {
			cc.audioEngine.stop(audioBgNode.audioId);
			this.stopItemAnim(audioBgNode);
		}

		audioBgNode.on(cc.Node.EventType.TOUCH_START, () => {
			if( light.opacity == 0 ) {
				light.opacity = 255;
				playAudio(this.selectClip);
				
				audioBgNode.showAnim();
				if (audioBgNode.audioClip) {
					audioBgNode.audioId = playAudio(audioBgNode.audioClip, () => {
						this.stopItemAnim(audioBgNode);
					});
				}

			} else {
				light.opacity = 0;
				audioBgNode.stopAnim();
			}

			this.refreshCheckBtn();

		});

		audioBgNode.active = false;

		return audioBgNode;
	},

	getOneTextOption(isBig=false) {

		let lightResName = "option_text_bg_l";
		let bgResName = "option_text_bg";
		if (isBig) {
			lightResName = "op_text_bg_big_l";
			bgResName = "op_text_bg_big";
		}

		const textBgParent = new cc.Node();
		textBgParent.active = false;

		const light = getSprNode(lightResName);
		textBgParent.addChild(light);
		light.opacity = 0;
		textBgParent.light = light;

		const textBg = getSprNode(bgResName);
		textBgParent.addChild(textBg);
		textBgParent.textBg = textBg;

		textBgParent.width = textBg.width;
		textBgParent.height = textBg.height;

		const labelNode = new cc.Node();
		labelNode.parent = textBgParent;
		const label = labelNode.addComponent(cc.Label);

		label.fontSize = 56;
		label.lineHeight = 56;
		if (isBig) {
			label.fontSize = 64;
			label.lineHeight = 64;
		}

		label.font = cc.find('Canvas/res/font/Berlin-Sans-FB').getComponent(cc.Label).font;
		textBgParent.label = label;

		const color = new cc.Color();
		cc.Color.fromHEX(color, '#023659' );
		labelNode.color = color;


		const soundNode = new cc.Node();
		textBgParent.addChild(soundNode);
		textBgParent.soundIcon = soundNode;

		const soundIconAnim = cc.instantiate(cc.find("Canvas/res/anim/laba"))
		soundNode.addChild(soundIconAnim);
		soundIconAnim.opacity = 0;

		const soundIconTop = getSprNode('btn_laba')
		soundNode.addChild(soundIconTop);
		soundIconTop.opacity = 255;

		soundNode.x = textBgParent.width / 2 - 15; // - soundIconTop.width / 2;
		soundNode.y = textBgParent.height / 2 - 15; //- soundIconTop.height / 2;
		soundNode.active = false;


		textBgParent.on(cc.Node.EventType.TOUCH_START, () => {
			if( light.opacity == 0 ) {
				light.opacity = 255;
				playAudio(this.selectClip);
			} else {
				light.opacity = 0;
			}
			this.refreshCheckBtn();
		})


		soundIconTop.addComponent(cc.BlockInputEvents);
		soundIconTop.on(cc.Node.EventType.TOUCH_START, () => {
			const anim = soundIconAnim.getComponent(cc.Animation);
			anim.play('laba');
			soundIconTop.opacity = 0;
			soundIconAnim.opacity = 255;

			if (soundNode.audioClip) {
				playAudio(soundNode.audioClip, () => {
					soundIconTop.opacity = 255;
					soundIconAnim.opacity = 0;
					anim.stop();
				});
			}
		})

		return textBgParent;
	},

	playItemAnim(item) {
		item.anim.play();
		item.animNode.opacity = 255;
		item.animTop.opacity = 0;
	},

	stopItemAnim(item) {
		item.animNode.opacity = 0;
		item.animTop.opacity = 255;
	},

	setCurQuestion() {
		
		switch(this.curQuestionData.questionType) {
			case "pic":
				this.setQuestionPic();
				break;
			case "text":
				this.setQuestionText();
				break;
			case "video":
				this.setQuestionVideo();
				break;
			case "audio":
				this.setQuestionAudio();
				break;
		}

		this.refreshCheckBtnPos();
	},

	refreshCheckBtnPos() {
		if (this.curQuestionData.questionType == 'audio') {
			this.checkBtn.x = 440 * this._mapScaleMin;
			this.checkBtn.y = -240 * this._mapScaleMin;
		} else {
			this.checkBtn.x = this.checkBtn.baseX;
			this.checkBtn.y = this.checkBtn.baseY;
		}
	},

	curQuesBg: null,
	setQuestionPic() {

		this.curQuesBg = this.quesPicBg;
		this.curQuesBg.active = true;


		if (this.quesPicBg.pic) {
			this.quesPicBg.pic.removeFromParent();
			this.quesPicBg.pic = null;
		}
		if (this.curQuestionData.pic_url) {
			getSprNodeByUrl(this.curQuestionData.pic_url, (spr) => {
				const sprNode = spr.node;
				setSprNodeMaxLen(sprNode, 678, 396);
				this.quesPicBg.addChild(sprNode)
				this.quesPicBg.pic = sprNode;
			})
		}
	
		const audioNode = this.quesPicBg.audioNode;
		audioNode.active = false;
		audioNode.audioClip = null;
		if (this.curQuestionData.audio_url) {
			cc.assetManager.loadRemote(this.curQuestionData.audio_url, (err, audioClip) => {
				audioNode.audioClip = audioClip;
			});	
			audioNode.active = true;
		}
	},

	setQuestionText() {
		this.curQuesBg = this.quesTextBg;
		this.curQuesBg.active = true;

		
		const label = this.curQuesBg.label;
		const size = 80; 
		label.string = `<size=${size}><color=#fff4b6>${this.curQuestionData.text}</color></size>`

		const maxH = this.curQuesBg.height * 0.98;

		if (label.node.height > maxH) {
			label.node.scale = maxH / label.node.height
		} else {
			label.node.scale = 1;
		}


		const audioNode = this.curQuesBg.audioNode;
		audioNode.active = false;
		audioNode.audioClip = null;
		if (this.curQuestionData.audio_url) {
			cc.assetManager.loadRemote(this.curQuestionData.audio_url, (err, audioClip) => {
				audioNode.audioClip = audioClip;
			});	
			audioNode.active = true;
		}
	},

	setQuestionVideo() {
		this.curQuesBg = this.quesVideoBg;
		this.curQuesBg.active = true;
		this.videoNode.active = true;

		if (this.curQuestionData.video_url) {
			this.curQuesBg.video.remoteURL = this.curQuestionData.video_url;
		}
	},

	setQuestionAudio() {
		this.curQuesBg = this.quesAudioBg;
		this.curQuesBg.active = true;


		this.curQuesBg.audioClip = null;
		if (this.curQuestionData.audio_url) {
			cc.assetManager.loadRemote(this.curQuestionData.audio_url, (err, audioClip) => {
				this.curQuesBg.audioClip = audioClip;
			});
		}
	},



	setCurOption() {
		const arr = this.curQuestionData.answerArr;

		const isBig = this.curQuestionData.questionType == 'audio';

		switch(this.curQuestionData.answerType) {
			case "pic":
				this.setOptionPic(arr, isBig);
				break;
			case "audio":
				this.setOptionAudio(arr, isBig);
				break;
			case "text":
				this.setOptionText(arr, isBig);
				break;
		}
		
	},



	curOptionArr: null,
	setOptionPic(arr, isBig=false) {

		let opItemArr = this.optionPicBgArr;
		if (isBig) {
			opItemArr = this.optionPicBgBigArr;
		}
		this.curOptionArr = [];
		const disW = 158 * this._mapScaleMin;
		const baseX = -(arr.length - 1) * disW;
		for (let i=0; i<arr.length; i++) {
			
			opItemArr[i].active = true;
			if (!isBig) {
				opItemArr[i].x = baseX + i * disW * 2;
			}

			const picBg = opItemArr[i].picBg;
			picBg.removeAllChildren();
			
			const data = arr[i];
			if (data.pic_url) {
				getSprNodeByUrl(data.pic_url, (spr) => {
					let maxW = 280;
					let maxH = 190;
					if (isBig) {
						maxW = 366;
						maxH = 248;
					}

					setSprNodeMaxLen(spr.node, maxW, maxH);
					console.log('spr: ', spr);
					picBg.addChild(spr.node);
				})
			}

			const soundIcon = opItemArr[i].soundIcon;
			soundIcon.active = false;
			soundIcon.audioClip = null;
			opItemArr[i].audioClip = null;
			if (data.audio_url) {
				cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
					soundIcon.audioClip = audioClip;
					opItemArr[i].audioClip = audioClip;
				});
				
				soundIcon.active = true;
			}

			opItemArr[i].data = data;
			this.curOptionArr.push(opItemArr[i]);
		}
	},


	setOptionAudio(arr, isBig=false) {

		let opItemArr = this.optionAudioBgArr;
		if (isBig) {
			opItemArr = this.optionAudioBgBigArr;
		}

		this.curOptionArr = [];
		const disW = 158 * this._mapScaleMin;
		const baseX = -(arr.length - 1) * disW;
		for (let i=0; i<arr.length; i++) {
			
			opItemArr[i].active = true;
			if(!isBig) {
				opItemArr[i].x = baseX + i * disW * 2;
			}

			const data = arr[i];

			opItemArr[i].audioClip = null;
			if (data.audio_url) {
				cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
					opItemArr[i].audioClip = audioClip;
				});
			}

			opItemArr[i].data = data;
			this.curOptionArr.push(opItemArr[i]);
		}
	},

	setOptionAudioBig(arr) {
		this.curOptionArr = [];
		for (let i=0; i<arr.length; i++) {
			
			this.optionAudioBgArr[i].active = true;

			const data = arr[i];

			this.optionAudioBgArr[i].audioClip = null;
			if (data.audio_url) {
				cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
					this.optionAudioBgArr[i].audioClip = audioClip;
				});
			}

			this.optionAudioBgArr[i].data = data;
			this.curOptionArr.push(this.optionAudioBgArr[i]);
		}
	},


	setOptionText(options, isBig=false) {

		console.log(' in setOptionText, isBig: ', isBig);

		let opItemArr = this.optionTextBgArr;
		if (isBig) {
			opItemArr = this.optionTextBgBigArr
		}

		this.curOptionArr = [];
		const disW = 315 * this._mapScaleMin;
		const disH = 120 * this._mapScaleMin;
		const baseX = - disW ;
		let baseY = -235 * this._mapScaleMin;
		if (options.length > 2) {
			baseY = -170 * this._mapScaleMin;
		}
		let count = 0;
		for (let i=0; i<options.length; i++) {

			if ( i == 2 ) {
				baseY -= disH;
				count = 0;
			}
			
			opItemArr[i].active = true;
			if (!isBig) {
				opItemArr[i].x = baseX + count * disW * 2;
				opItemArr[i].y = baseY;
			}
		
			const data = options[i];

			opItemArr[i].label.string = data.text;
			opItemArr[i].label["_forceUpdateRenderData"](true);
			if (opItemArr[i].label.node.width > opItemArr[i].width * 0.9) {
				opItemArr[i].label.node.scale = opItemArr[i].width * 0.9 / opItemArr[i].label.node.width;
			} else {
				opItemArr[i].label.node.scale = 1;
			}
			

			const soundIcon = opItemArr[i].soundIcon;
			soundIcon.active = false;
			soundIcon.audioClip = null;
			opItemArr[i].audioClip = null;
			if (data.audio_url) {
				cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
					soundIcon.audioClip = audioClip;
					opItemArr[i].audioClip = audioClip;
				});
				
				soundIcon.active = true;
			}

			opItemArr[i].data = data;
			this.curOptionArr.push(opItemArr[i]);

			count++;
		}
	},



	shakeArr: null,
	wrongArr: null,
	checkBtnClick() {

		this.shakeArr = [];
		this.wrongArr = [];
		this.checkItemWrong();

		if (this.wrongArr.length > 0) {
			//有选错的
			this.itemShake();
			this.hideLight();
			playAudio(this.wrongClip);
			return;
		}

		const isRightAll = this.checkItemRightCount();
		if (!isRightAll) {
			// 有漏选的
			this.itemShake();
			this.hideLight();
			playAudio(this.wrongClip);
			return;
		}

		this.showAllRight();
		this.showMask();

		playAudio(this.rightClip, () => {
			this.playAnswerAudio(0);
		})
		
	},

	playAnswerAudio(index) {
		const arr = this.curOptionArr;
		if (!arr[index]) {

			// delayCall(0.5, () => {
				this.changeNextQuestion();
			// })

		} else {
			if ( arr[index].light.opacity > 254 && arr[index].audioClip ) {
				playAudio(arr[index].audioClip, () => {
					this.playAnswerAudio(index + 1);
				})
			} else {
				this.playAnswerAudio(index + 1);
			}
		}
	},


	checkItemWrong() {
		const arr = this.curOptionArr;
		console.log('arr: ', arr);
		for (let i=0; i<arr.length; i++) {
			const itemBg = arr[i];
			if (itemBg.light.opacity >= 254) {
				this.shakeArr.push(itemBg);
				console.log('aaa', itemBg.data);;
				if (itemBg.data.answerRight == '0') {
					this.wrongArr.push(itemBg);
				}
			}
		}
	},

	checkItemRightCount() {
		let rightTotalCount = 0;
		const answerArr = this.curQuestionData.answerArr;
		for (let i=0; i<answerArr.length; i++) {
			if (answerArr[i].answerRight == '1') {
				rightTotalCount ++;
			}
		}

		let curRightCount = 0;
		const curOptionArr = this.curOptionArr;
		for (let i=0; i<curOptionArr.length; i++) {
			if (curOptionArr[i].light.opacity > 254) {
				curRightCount ++;
			}
		}

		return rightTotalCount == curRightCount;
	},

	itemShake() {
		let rate = 1;
		if (this.curQuestionData.answerType == 'text') {
			rate = 0.5;
		}

		const arr = this.shakeArr;
		for (let i=0; i<arr.length; i++) {
			this.rotateShake(arr[i], rate);
			if (arr[i].stopAnim) {
				arr[i].stopAnim();
			}
		}

		this.showTryAgain();
	},

	hideLight() {
		const arr = this.curOptionArr;
		for (let i=0; i<arr.length; i++) {
			arr[i].light.opacity = 0;
		}
		this.checkBtn.opacity = 0;
	},

	rotateShake(item, rate = 1) {

		const time = 0.9;
		cc.tween(item)
			.to(time / 6 / 2, {angle: -20 * rate}, {easing: 'sineInOut'})
			.to(time / 6, {angle: 12 * rate}, {easing: 'sineInOut'})
			.to(time / 6, {angle: -7 * rate}, {easing: 'sineInOut'})
			.to(time / 6, {angle: 4 * rate}, {easing: 'sineInOut'})
			.to(time / 6, {angle: -2 * rate}, {easing: 'sineInOut'})
			.to(time / 6, {angle: 1 * rate}, {easing: 'sineInOut'})
			.to(time / 6, {angle: 0 * rate}, {easing: 'sineInOut'})
			.start();

	},

	showAllRight() {
		const curOptionArr = this.curOptionArr;
		for (let i=0; i<curOptionArr.length; i++) {
			if (curOptionArr[i].light.opacity > 254) {
				this.addIconRight(curOptionArr[i]);
			}
		}
	},

	changeNextQuestion() {
		console.log(' in changeNextQuestion')

		this.curQuestionIndex ++ ;
		this.setCurQuestionData();

		if (!this.curQuestionData) {
			// this.gameEnd();
			return;
		}

		this.showChangeQuesAnim();
	
	},

	showChangeQuesAnim() {
		this.hideLight();

		this.hideCurOptionAnim(() => {
			this.setCurOption();
			this.showCurOptionAnim();
			this.hideMask();
		});

		this.hideCurQuestion(() => {
			this.setCurQuestion();
			this.showCurQuestionAnim();
		});
	},


	maskLayer: null,
	initMask() {
		this.maskLayer = cc.find("Canvas/maskLayer");
		this.maskLayer.active = false;
		this.maskLayer.zIndex = 50;
	},

	showMask() {
		
		this.maskLayer.active = true;
	},

	hideMask() {
		
		this.maskLayer.active = false;
	},

	hideCurOptionAnim(cb) {
		const arr = this.curOptionArr;
		const time = 0.5;
		for (let i=0; i<arr.length; i++) {
			if (arr[i].iconRight) {
				arr[i].iconRight.removeFromParent();
				arr[i].iconRight = null;
			}
			cc.tween(arr[i])
				.to(time, {opacity: 0}, {easing: "cubicOut"})
				.call(() => {
					arr[i].active = false;
				})
				.start();
		}
		delayCall(time, () => {
			cb();
		})
	},

	showCurOptionAnim(cb=null) {
		const arr = this.curOptionArr;
		const time = 0.5;
		for (let i=0; i<arr.length; i++) {
			arr[i].opacity = 0;
			cc.tween(arr[i])
				.to(time, {opacity: 255}, {easing: "cubicIn"})
				.start();
		}

		if (cb) {
			delayCall(time, () => {
				cb();
			})
		}
	
	},

	hideCurQuestion(cb) {
		const time = 0.5;
		cc.tween(this.curQuesBg)
			.to(time, {opacity: 0}, {easing: "cubicOut"})
			.call(() => {
				this.curQuesBg.active = false;
				cb();
			})
			.start();
	},

	showCurQuestionAnim() {

		this.curQuesBg.active = true;
		this.curQuesBg.opacity = 0;

		const time = 0.5;
		cc.tween(this.curQuesBg)
			.to(time, {opacity: 255}, {easing: "cubicIn"})
			.start();
	},


	changeStep() {

		this.typeArrIndex ++;
		this.curCatAudioUrl = this.data.idle_2_audio_url;
		
		if (!this.data.change_step_audio_url) {
			this.startTesting();
			return;
		}
		playAudioByUrl(this.data.change_step_audio_url, () => {
			this.startTesting();
		})

	},

	gameEnd() {
		console.log('game end !')

		this.isGameEnd = true;

		onHomeworkFinish();
		showSRResultByRecord();


		// this.showMask();
		// this.showRole()

		return;




		this.endTesting();


		if (this.typeArrIndex < this.typeArr.length - 1) {

			this.changeStep();

			return;
		}





		// this.showRestart();
		// this.showGoodjob();
		// this.showOneFirework(cc.v2(0, -this.canvas.height / 2), this.canvas, cc.find('paperBase').children, this.canvas.width / 2.5, this.canvas.height * 2, 100, 1);
		playAudio(this.finishClip);

		if (!this.data.finish_right_audio_url) {
			const endData = this.getEndData();
			onHomeworkFinish(endData);
		}
		
		playAudioByUrl(this.data.finish_right_audio_url, () => {
			const endData = this.getEndData();
			onHomeworkFinish(endData);
		})

	

		const camera = cc.find('Canvas/Main Camera');
		camera.zIndex = 100;

		showTrebleFirework(camera, cc.find('RibbonNodeBase').children);


	

	},

	getEndData() {

		return {};

		const arr = this.picNodeArr;
		const customData = [];
		let stone = 0;
		const oneQuesStone = 10 / arr.length;
		arr.forEach(node => {
			customData.push({isRight: node.isRight})
			if (node.isRight) {
				stone += oneQuesStone;
			}
		})
		stone = Math.round(stone * 10) / 10;
		return {customData, stone};
	},

	showGoodjob() {

		const icon = getSprNode("goodjob");
		icon.scale = this._mapScaleMin;
		icon.baseS = icon.scale;
		this.canvas.addChild(icon, 20);


		const time = 1;
		icon.scale = 0;
		cc.tween(icon)
			.to(0.8,  {scale: icon.baseS}, {easing: "elasticOut"})
			.delay(1)
			.to(0.5, {scale: 0} , {easing: "cubicIn"})

			.start();



	},

	showRestart() {

		const btn = getSprNode("btn_restart");
		btn.scale = this._mapScaleMin;
		btn.baseS = btn.scale;
		this.canvas.addChild(btn, 21);

		btn.on(cc.Node.EventType.TOUCH_START, () => {
			// btn.removeFromParent();
			// this.initData();
			// this.initStar();
			// this.showChangeQuesAnim();
			// playAudio(this.btnClip);

			const middleLayer = cc.find('middleLayer');
			if (middleLayer) {
				middleLayer.getComponent('middleLayer').reloadBundle();
			}
		})

		const time = 0.9;
		btn.scale = 0;
		cc.tween(btn)
			.delay(2.5)
			.to(time,  {scale: btn.baseS}, {easing: "elasticOut"})
			.start();

	},



	async showOneFirework(pos, parentNode, nodeList, w, h, n, timeRate=1) {

		for (let i = 0; i < 3; i++) {
				this.showFirework(pos, parentNode, nodeList, w, h, n, timeRate);
				await asyncDelay(0.1);
		}
	},

	showFirework(pos, parentNode, nodeList, width = 200, height = 500, number = 30, timeRate=1) {
			const subTime = 1;
			for (let i = 0; i < number; i++) {
					const quad = this.createQuads(pos, parentNode, nodeList);
					const targetX = RandomInt(width / 2, -width / 2);
					const targetY = RandomInt(height);

					cc.tween(quad)
							.by(0.5 * timeRate, { x: targetX })
							.by((2 + subTime *  Math.random()) * timeRate, { x: targetX * 2 })
							.start();

					cc.tween(quad)
							.by(0.5 * timeRate, { y: targetY }, { easing: 'quadOut' })
							.to((3 + subTime * Math.random()) * timeRate, { y: -parentNode.height * 2 }, { easing: 'quadIn' })
							.removeSelf()
							.start();

					cc.tween(quad)
							.delay(1  * timeRate)
							.to((0.5 + subTime * Math.random()) * timeRate , { opacity: 0 })
							.start();
			}
	},

	createQuads(pos, parentNode, nodeList) {
			const quadBase = cc.instantiate(nodeList[RandomInt(nodeList.length)]);

			quadBase.x = pos.x;
			quadBase.y = pos.y;
			quadBase.z = pos.z;
			quadBase.angle = RandomInt(180);
			quadBase.parent = parentNode;

			const quad = quadBase.getChildByName('quad');
			quad.x = 0;
			quad.y = 0;
			quad.angle = RandomInt(180);

			const paper = quad.getChildByName('paper');
			paper.scaleX = Math.random() * 0.8 + 0.2;
			paper.scaleY = Math.random() * 0.8 + 0.2;

			quadBase.scaleX = Math.random();
			cc.tween(quadBase)
					.to((1 - quadBase.scaleX) * 0.3, { scaleX: 1 })
					.call(() => {
							const time = Math.random() * 0.2;
							cc.tween(quadBase)
									.to(0.1 + time, { scaleX: -1 })
									.to(0.1 + time, { scaleX: 1 })
									.union()
									.repeatForever()
									.start();
					})
					.start();


			return quadBase;
	},


















	restart() {
		
	},


	initTitle() {

		const offX = 96;
		const offY = 11;
		const title = getSprNode('title_bg');
		title.parent = this.canvas;
		title.scale = this._mapScaleMin;
		title.zIndex = 10;

		title.x = -this.canvas.width / 2 + title.width / 2 * title.scale + offX;
		title.y = this.canvas.height / 2 - title.height / 2 * title.scale - offY;

		// console.log('this.data: ', this.data);

		title.addComponent(cc.Button)
		title.on('click', () => {
			if (this.data.title_audio_url) {
				playAudioByUrl(this.data.title_audio_url);
			}
		})

		const labelNode = new cc.Node();
		labelNode.parent = title;
		const label = labelNode.addComponent(cc.RichText);
		const size = 42
		label.font = cc.find('Canvas/res/font/aharoni').getComponent(cc.Label).font;
		label.string = `<outline color=#a83c13 width=2><size=${size}><color=#ffffff>${this.data.title || " " }</color></size></outline>`
		// label.string = `<size=${size}><color=#751e00>${this.curGroup.title }</color></size>`
		label.lineHeight = size;
		label.horizontalAlign = cc.macro.TextAlignment.LEFT
		labelNode.anchorX = 0;
		labelNode.anchorY = 1
		labelNode.x = -title.width / 2 + 90;

		const maxLen = 305;
		if (labelNode.width > maxLen) {
			labelNode.scale = maxLen / labelNode.width;
		}

		labelNode.y = labelNode.height / 2 * labelNode.scale + 15;

	},


	async initBg() {
		

		// this.initCloud();
		// this.initGrass();
		// this.initPanel();
		// this.initVoice();
		
	},

	initVoice() {

		
		this.voiceNode = cc.find("voice_node", this.panel);
		this.voiceNode.progressBarNode = cc.find("progressBar", this.voiceNode);
		this.voiceNode.progressBarNode.progressBarComp = this.voiceNode.progressBarNode.getComponent(cc.ProgressBar);
		this.voiceNode.voiceIcon = cc.find("icon_voice", this.voiceNode);
		this.voiceNode.opacity = 0;
		this.voiceNode.baseS = this.voiceNode.scale;

		this.voiceNode.voiceIcon.on('touchstart', () => {
			if (!this.canTouch) {
				return;
			}
		})

		this.voiceNode.progressBarNode.on('touchstart', () => {
			this.recordStop();
		})

		// this.showVoiceNode();
	},

	async initPanel() {
		const panel = cc.find("Canvas/bg/panel");
		panel.scale = this._mapScaleMin;

		const picBg = cc.find("pic_bg", panel);		
		this.panelBg = picBg;
	},

	async refreshCurPanel(isAnim = false) {

		if (isAnim) {
			this.isChangePage = true;

			this.refreshBottomBtns();

			const panelBg = this.panelBg;
			cc.tween(panelBg)
				.to(0.15, {opacity: 0}, {easing: "sineIn"})
				.call(() => {
					this.setPanel();
				})
				.to(0.15, {opacity: 255}, {easing: "sineOut"})
				.call(() => {
					this.isChangePage = false;
					this.refreshBottomBtns();
				})
				.start()

		} else {

			this.setPanel();
			this.refreshBottomBtns();
		}

	},

	refreshBottomBtns() {
		this.refreshSoundBtn();
		this.refreshSpeakBtn();
		this.refreshPlayBtn();
		this.refreshArrowBtn();
	},


	setPanel() {

		const panelBg = this.panelBg;
		panelBg.removeAllChildren();

		const pic_url = this.curQues.picUrl;
		const text = this.curQues.val;
		const ch_text = this.curQues.chnVal

		let labelNode;
		let chLabelNode;
		let maxW = panelBg.width / 2;



		if (pic_url && text) {

			getSprNodeByUrl(pic_url, (spr) => {
				panelBg.addChild(spr.node);
				spr.node.x = - panelBg.width / 4;
				setSprNodeMaxLen(spr.node, panelBg.width / 2, panelBg.height);
			}) 

			labelNode = this.getLabel(text, 100);
			labelNode.color = cc.Color.BLACK;
			panelBg.addChild(labelNode);
			labelNode.x = panelBg.width / 4;

		if (labelNode.width > maxW) {
			labelNode.scale = maxW / labelNode.width;
		}
		
			if (ch_text) {
				chLabelNode = this.getLabel(ch_text, 50);
				chLabelNode.color = cc.Color.fromHEX(new cc.Color(), "#cccccc");
				panelBg.addChild(chLabelNode);
				chLabelNode.x = panelBg.width / 4;
				chLabelNode.y = -110;

				labelNode.y = 20;
			}
			
		}

		if (pic_url && !text) {
			getSprNodeByUrl(pic_url, (spr) => {
				panelBg.addChild(spr.node);
				// spr.node.x = - panelBg.width / 4;
				setSprNodeMaxLen(spr.node, panelBg.width, panelBg.height);
			}) 
		}
		
		if (!pic_url && text) {
			labelNode = this.getLabel(text, 100);
			labelNode.color = cc.Color.BLACK;
			panelBg.addChild(labelNode);

			maxW = panelBg.width;
			
			if (labelNode.width > maxW) {
				// await asyncDelay(0.01)
				labelNode.scale = maxW / labelNode.width;
			}

			if (ch_text) {
				chLabelNode = this.getLabel(ch_text, 50);
				chLabelNode.color = cc.Color.fromHEX(new cc.Color(), "#cccccc");
				panelBg.addChild(chLabelNode);
				chLabelNode.y = -110;
				labelNode.y = 20;
			}
		}
	},

	refreshPlayBtn() {

		if (!this.curQues.userAudioUrl || this.isSoundPlay || this.isRecord || this.isPlayUserAudio || this.isChangePage || this.isShowChick) {
			// this.playBtn.opacity = 100;
			// this.btnToOpacity(this.playBtn, 100);
			this.playBtn.top.active = true;

		} else {
			// this.playBtn.opacity = 255;
			// this.btnToOpacity(this.playBtn, 255);
			this.playBtn.top.active = false;
		}
	},

	refreshSoundBtn() {

		console.log(" refreshSoundBtn  this.isRecord): ", this.isRecord);
		if (this.isRecord || this.isPlayUserAudio || this.isChangePage || this.isShowChick) {
			// this.soundBtn.opacity = 100;
			this.soundBtn.top.active = true;
			// this.btnToOpacity(this.soundBtn, 100);
		} else {
			this.soundBtn.top.active = false;
			this.btnToOpacity(this.soundBtn, 255);
			// this.soundBtn.opacity = 255;
		}
	},


	refreshSpeakBtn() {
		
		if (this.isSoundPlay || this.isPlayUserAudio || this.isChangePage || this.isShowChick) {
			// this.speakBtn.opacity = 100;
			// this.btnToOpacity(this.speakBtn, 100);
			this.speakBtn.top.active = true;

		} else {
			// this.speakBtn.opacity = 255;
			// this.btnToOpacity(this.speakBtn, 255);
			this.speakBtn.top.active = false;

		}
	},

	refreshArrowBtn() {
		if (this.isSoundPlay || this.isRecord || this.isPlayUserAudio || this.isChangePage || this.isShowChick) {
			// this.leftBtn.opacity = 100;
			// this.rightBtn.opacity = 100;
			this.btnToOpacity(this.leftBtn, 100);
			this.btnToOpacity(this.rightBtn, 100);

		} else {
			// this.leftBtn.opacity = 255;
			// this.rightBtn.opacity = 255;
			this.btnToOpacity(this.leftBtn, 255);
			this.btnToOpacity(this.rightBtn, 255);
		}

		if (this.curQuesIndex == 0) {
			// this.leftBtn.opacity = 100;
			this.btnToOpacity(this.leftBtn, 100);
		}

		if (this.curQuesIndex >= this.quesArr.length - 1) {
			// this.rightBtn.opacity = 100;
			this.btnToOpacity(this.rightBtn, 100);
		}
	},

	btnToOpacity(btn, opacity) {
		if (btn.myTween) {
			btn.myTween.stop();
		}

		btn.myTween = cc.tween(btn)
			.to(0.1, {opacity}, {easing: "sineInOut"})
			.start()
	},


	initCloud() {
		const animNode = cc.find("Canvas/yun");

		const dragonDisplay = animNode.getComponent(dragonBones.ArmatureDisplay);
		dragonDisplay.playAnimation("newAnimation", -1);

		const w = 1920;
		const h = 1080;
		
		animNode.scaleX = this.canvas.width / w;
		animNode.scaleY = this.canvas.height / h;
	},

	initGrass() {
		const animNode = cc.find("Canvas/grass");
		this.grassNode = animNode;
		// const dragonDisplay = animNode.getComponent(dragonBones.ArmatureDisplay);
		// dragonDisplay.playAnimation("2left", -1);

		const w = 1920;
		const h = 1080;
		// await asyncDelay(0.1);
		if (w < this.canvas.width) {
			animNode.scale = this.canvas.width / w;
		}
		
		const grassH = h * animNode.scale;
		animNode.y = -this.canvas.height / 2 + grassH / 2 - 5 * animNode.scale;
	},

	


	initHotZone() {
		this.initHotZoneBg();
	},


	hotZoneBg: null,
	initHotZoneBg() {

		this.fixedBg = new cc.Node();
		this.fixedBg.name = 'hotZoneBg';
		this.fixedBg.parent = cc.find('Canvas');
		this.fixedBg.width = this.canvas.width;
		this.fixedBg.height = this.canvas.height;

		for (let i = 0; i < this.data.quesArr.length; i++) {

			const data = this.data.quesArr[i];

			const hotZoneBg = new cc.Node();
			hotZoneBg.name = 'hotZoneBg';
			hotZoneBg.parent = cc.find('Canvas');
			hotZoneBg.data = data;

			data.hotZoneBg = hotZoneBg;

			hotZoneBg.active = false;

			if (!data.bgItem) {
				continue;
			}

			cc.loader.load({ url: data.bgItem.url }, (err, img) => {

				const bgNode = new cc.Node();
				let tempSf = new cc.SpriteFrame(img);
				let tempSpr = bgNode.addComponent(cc.Sprite);
				tempSpr.spriteFrame = tempSf
				
				const scaleX = this.canvas.width / bgNode.width;
				const scaleY = this.canvas.height / bgNode.height;
				this._mapScaleMin = Math.min(scaleX, scaleY);
				this._mapScaleMax = Math.max(scaleX, scaleY);
				bgNode.scale = this._mapScaleMax;
				this.canvas.addChild(bgNode);


				hotZoneBg.width = img.width;
				hotZoneBg.height = img.height;


				const sprNode = new cc.Node();
				sprNode.name = 'bgItemSpr'
				var sf = new cc.SpriteFrame();
				// var sf = new cc.SpriteFrame(img);
				// const spr = hotZoneBg.addComponent(cc.Sprite);
				const spr = sprNode.addComponent(cc.Sprite);
				spr.spriteFrame = sf
				sprNode.width = hotZoneBg.width;
				sprNode.height = hotZoneBg.height;
				sprNode.parent = hotZoneBg;

				sprNode.opacity = 0;


				const panel = new cc.Node();// getSprNode('panel');
				panel.width = this.canvas.width;
				panel.height = this.canvas.height;
				// panel.scale = this._mapScaleMin;
				this.canvas.addChild(panel);
				panel.x = -this.canvas.width;



				const parent = panel;
				const sx = parent.width / hotZoneBg.width;
				const sy = parent.height / hotZoneBg.height;
				const s = Math.min(sx, sy);

				hotZoneBg.scale = s // * 0.9;
				hotZoneBg.parent = panel;


				// // const sx = this.canvas.width / hotZoneBg.width;
				// const sy = this.canvas.height / hotZoneBg.height;
				// // const s = Math.min(sx, sy);
				// hotZoneBg.scale = sy;


				// if (data.itemType != 'sound') {
					this.initHotZoneItem(hotZoneBg);
				// }

				// if (i==0) {
				// 	data.hzLoadEnd = true;
				// 	this.checkStart(data);
				// }



				panel.x = 0;
				this.hzLoadEnd = true;
				// cc.tween(panel)
				// .to(1, {x: 0}, {easing: 'cubicOut'})
				// .call(() => {
				// 	this.hzLoadEnd = true;
				// 	// this.checkStart();
				// })
				// .start();


				if (i==0) {
					hotZoneBg.active = true;
					sprNode.opacity = 255;
				}


				this.initTop();
			});
		}


	},

	initTop() {

		let labelText = '';
		if (this.topLabelNode && this.topLabelNode.labelNode) {

			const topLabelNode = this.topLabelNode.labelNode;
			topLabelNode.parent = this.topBg;
			topLabelNode.x = this.topBg.width / 2
			topLabelNode.y = this.topBg.height / 2 + 5;
			topLabelNode.zIndex = 99;
	
			labelText = topLabelNode.getComponent(cc.RichText).string;
			console.log("labelText"+ labelText);
			
	
			const topLabel = topLabelNode.getComponent(cc.RichText);
			topLabel.enableWrapText = true;
		}

		this.labaNode.parent = this.topBg;
		this.labaNode.zIndex = 100;

		if (labelText) {
			this.labaNode.x = 0;
			this.labaNode.y = 16;

			this.topLabelNode.active = true;
		} else {
	
			this.labaNode.x = this.topBg.width / 2 - 50;
			this.labaNode.y = 16;

			this.topLabelNode.active = false;
		}


	},

	initHotZoneItem(bgItem) {

		// this.picNodeArr = [];

		const hotZoneItemArr = this.data.quesArr[0]?.hotZoneItemArr || [];

		this.inputTextArr = [];
		this.inputPicArr = [];

		this.fixedAnimArr = [];

		this.audioAnimArr = [];

		this.textOptionArr = [];
		this.picOptionArr = [];

		this.listAreaArr = [];
		this.listTextArr = [];
		this.listPicArr = [];

		this.dataTextArr = [];

		this.pageDotAreaArr = [];
		this.multResAreaArr = [];
		
		hotZoneItemArr.forEach((item) => {
			// console.log('item: ', item);
			// console.log('item.gIdx: ', item.gIdx);

			const typeGroup = this.customTypeGroupArr[item.gIdx];
			if (!typeGroup) {
				return;
			}
			console.log('typeGroup.name: ', typeGroup.name);

			switch(typeGroup.name) {	

				case "输入型文本":
					this.setInputText(item, bgItem);
					break;
				case "输入型图片":
					this.setInputPic(item,bgItem);
					break;
				case "输入型动画":
					this.setInputAnim(item,bgItem);
					break;
				case "输入型音频":
					this.setInputAudio(item,bgItem);
					break;
	
				case "固定型文本":
					this.setFixedText(item, bgItem);
					break;
				case "固定型图片":
					this.setFixedPic(item, bgItem);
					break;
				case "固定型动画":
					this.setFixedAnim(item, bgItem);
					break;


				case "录音按钮组":
					this.setRecordGroup(item,bgItem);
					break;

				case "音频型动画":
					this.setAudioAnim(item,bgItem);
					break;

				case "文字选项组":
					this.setTextOption(item,bgItem);
					break;

				case "图片选项组":
					this.setPicOption(item,bgItem);
					break;

				case "选项效果组":
					this.setOptionEffect(item,bgItem);
					break;



				case "数组排列区":
					this.setListArea(item,bgItem);
					break;
				case "文字排列物":
					this.setListText(item,bgItem);
					break;
				case "图片排列物":
					this.setListPic(item,bgItem);
					break;

				case "数据型文本":
					this.setDataText(item, bgItem);
					break;

				case "翻页小点区":
					this.setPageDotArea(item, bgItem);
					break;

				case "多类型区域":
					this.setMultResArea(item, bgItem);
					break;
			}

			return;

		});


		this.refreshPage();

		// this.refreshInputPic();
		// this.refreshInputText();
		

	},


	setDataText(data, bg) {

		const rectNode = new cc.Node();

		const labelData = this.findOneLabelByKey(data.labelArr, 'key');
		const key = labelData.value; // tempItem中的关键key获取
		rectNode.key = key;

		this.dataTextArr.push(rectNode);
	},

	setInputText(data, bg) {
		console.log(" in setInputText ~", data)

		const rectNode = this.setOneRect(data, bg);

		const labelData = this.findOneLabelByKey(data.labelArr, 'key');
		const key = labelData.value; // tempItem中的关键key获取
		rectNode.key = key;

		
		if(data.checkbox && data.checkbox.list[0].label == '自动换行' && data.checkbox.list[0].value == true) {
			//多行
			rectNode.warp = true;
		}

		if (data.anchorGroup != null) {
			this.setRectNodeAnchor(data, bg, rectNode);
		}

		this.inputTextArr.push(rectNode);

	},

	setInputPic(data, bg) {

		const rectNode = this.setOneRect(data, bg, cc.Color.BLUE);
		const labelData = this.findOneLabelByKey(data.labelArr, 'key');
		const key = labelData.value; // tempItem中的关键key获取
		rectNode.key = key;

		this.inputPicArr.push(rectNode);
		
		
		// rectNode.on("click", () => {

		// 	if (rectNode.isClicked) {
		// 		return;
		// 	}
		// 	rectNode.isClicked = true;

		// 	const inputData = this.curQues.find(it => {
		// 		return it[key];
		// 	})
		// 	// console.log('inputData: ', inputData);
		// 	this.playCurQuesAudio(inputData[key], () => {
		// 		rectNode.isClicked = false;
		// 	});
		// })
	},

	setInputAnim(data, bg) {
		const rectNode = this.setOneRect(data, bg, cc.Color.YELLOW);
	},

	setInputAudio(data, bg) {
		
		const rectNode = this.setOneRect(data, bg, cc.Color.GREEN);
		const key = data.labelArr[1]?.value;
		
		rectNode.on("click", () => {

			if (rectNode.isClicked) {
				return;
			}
			rectNode.isClicked = true;

			const inputData = this.curQues.find(it => {
				return it[key];
			})
			// console.log('inputData: ', inputData);
			this.playCurQuesAudio(inputData[key], () => {
				rectNode.isClicked = false;
			});
		})
		
	},


	setFixedText(data, bg) {

		const rectNode = this.setOneRect(data, bg);
	},

	setFixedPic(data, bg) {
		const rectNode = this.setOneRect(data, bg, cc.Color.BLUE);

		console.log('setFixedPic data~ ', data);

		if (data.id == 1712912928089) {
			this.topBg = rectNode;
		}

		if (data.anchorGroup != null) {

			this.setRectNodeAnchor(data, bg, rectNode);
			
		
		}

		


		// const picNode = new cc.Node();
		// picNode.name = 'pic' + data.index;
		// picNode.data = data;
		// // bg.addChild(picNode);

		getSprNodeByUrl( data.pic_url , (spr)=> {

			const picNode = spr.node;
			setSprNodeMaxLen(picNode, rectNode.width, rectNode.height);

			rectNode.addChild(picNode);

			picNode.anchorX = picNode.anchorY = 0;
		});
	
	},

	setRectNodeAnchor(data, bg, rectNode) {
		let isLeftEdge = false;
		let isRightEdge = false;
		let isTopEdge = false;
		let isBottomEdge = false;

		switch(data.anchorGroup) {

			case 1:
				isTopEdge = true;
				isLeftEdge = true;
				break;
			case 2:
				isTopEdge = true;
				break;
			case 3:
				isTopEdge = true;
				isRightEdge = true;
				break;
			case 4:
				isLeftEdge = true;
				break;
			case 5:
				break;
			case 6:
				isRightEdge = true;
				break;
			case 7:
				isLeftEdge = true;
				isBottomEdge = true;
				break;
			case 8:
				isBottomEdge = true;
				break;
			case 9:
				isRightEdge = true;
				isBottomEdge = true;
				break;
		}


		if (isLeftEdge) {
			const offX = rectNode.x - (-bg.width / 2);
			// rectNode.parent = this.canvas;
			rectNode.removeFromParent();
			this.canvas.addChild(rectNode, data.index);
			rectNode.scale = bg.scale;
			rectNode.x = -rectNode.parent.width / 2 + offX * bg.scale;
		}

		if (isRightEdge) {
			const offX = (bg.width / 2) - (rectNode.x + rectNode.width);
			// rectNode.parent = this.canvas;
			rectNode.removeFromParent();
			this.canvas.addChild(rectNode, data.index);
			rectNode.scale = bg.scale;
			rectNode.x = rectNode.parent.width / 2 - rectNode.width * bg.scale - offX * bg.scale;
		}
			
		if (isTopEdge) {
			const offY = (bg.height / 2) - (rectNode.y + rectNode.height);
			// rectNode.parent = this.canvas;
			rectNode.removeFromParent();
			this.canvas.addChild(rectNode, data.index);
			rectNode.scale = bg.scale;
			rectNode.y = rectNode.parent.height / 2 - rectNode.height * bg.scale - offY * bg.scale;
		}

		if (isBottomEdge) {
			const offY = rectNode.y - (-bg.height / 2);
			rectNode.removeFromParent();
			this.canvas.addChild(rectNode, data.index);
			// rectNode.parent = this.canvas;
			rectNode.scale = bg.scale;
			rectNode.y = -rectNode.parent.height / 2 + offY * bg.scale;
		}
	},


	setFixedAnim(data, bg) {
		console.log(' in setFixedAnim')

		const animNode = this.setOneAnim(data, bg, cc.Color.YELLOW)
		this.fixedAnimArr.push(animNode);
	},

	setRecordGroup(data, bg) {

		const tempOffY = 100;

		console.log(' in setRecordGroup : ' , data);
		const rectNode = this.setOneRect(data, bg, cc.Color.RED)
		
		const recordNode = cc.find('Canvas/recordNode');
		recordNode.active = true;
		recordNode.parent = rectNode;
		recordNode.zIndex = 100;
		recordNode.x = rectNode.width / 2;
		recordNode.y = rectNode.height / 2 + tempOffY * this._mapScaleMin;

		// recordNode.startNode = cc.find("record_0", recordNode);
		// recordNode.stopNode = cc.find("record_1", recordNode);
		this.recordNode = recordNode;

		const mike = cc.find("mike", recordNode);
		mike.baseS = mike.scale;
		mike.baseY = mike.y;

		const icon = cc.find("icon", mike);
		icon.zIndex = 10;

		const particleNode = new cc.Node();
		mike.addChild(particleNode);
		particleNode.y = 125;
		particleNode.x = -2;

		const circleRes = getSprNode('circle');
		let timerId;

		const showRecordParticle = () => {

			particleNode.active = true;
			showOneCircle();

			timerId = setTimeout(() => {
				if (this.isDestroy || !this.isRecord) {
					return;
				}
				showRecordParticle();
			}, 700);

		}

		const hideRecordParticle = () => {
			particleNode.active = false;
			particleNode.removeAllChildren();
			if (timerId) {
				clearTimeout(timerId);
				timerId = null;
			}
		}

		const showOneCircle = () => {
			const circle = cc.instantiate(circleRes);
			particleNode.addChild(circle, 0);
			// circle.parent = particleNode;
			// circle.zIndex = 0;
			circle.scale = 0.7;

			cc.tween(circle)
				.to(2, {scale: 1.7, opacity: 0}, {easing:"sineOut"})
				.call(() => {
					circle.removeFromParent(); 
				})
				.start()
		}

		const startRecord = () => {
			cc.tween(mike)
				.to(0.3, {scale: 1, y: mike.baseY + 50}, {easing: "cubicOut"})
				.start();

			showRecordParticle();
			const text = this.curAnswerText;
			this.serverStartTest(text);

			this.hideScoreNode();
		}

		const stopRecord = () => {
			cc.tween(mike)
				.to(0.3, {scale: mike.baseS, y: mike.baseY}, {easing: "cubicOut"})
				.start();
				
			hideRecordParticle();
			this.serverStopTest((recordData=null) => {});
		}


		particleNode.on('click', () => {
			if (!this.isRecord) {
				startRecord();
			} else {
				stopRecord();
			}
			this.isRecord = !this.isRecord;
		})

		recordNode.on('click', () => {
			if (!this.isRecord) {
				startRecord();
			} else {
				stopRecord();
			}
			this.isRecord = !this.isRecord;
		})

		this.recordRectNode = rectNode;
		
		// recordNode.startNode.on("click", () => {
		// 	if (this.isRecord) {
		// 		return;
		// 	}
		// 	this.isRecord = true;
		// 	this.refreshRecordBtn();

		// 	const key = 'title_text';
		// 	const inputData = this.curQues.find(it => {
		// 		return it[key];
		// 	});

		// 	const text = inputData[key];
		// 	console.log('serverStartTest text: ', text);
		// 	this.serverStartTest(text);
		// })


		// recordNode.stopNode.on("click", () => {
		// 	if (!this.isRecord) {
		// 		return;
		// 	}
		// 	this.isRecord = false;
		// 	this.refreshRecordBtn();

		// 	console.log('serverStop ');
		// 	this.serverStopTest((recordData=null) => {

		// 	});
		// })
	},

	topAudioRectNode: null,
	setAudioAnim(data, bg) {
		console.log(' in setAudioAnim')

		const animNode = this.setOneAnim(data, bg, cc.Color.YELLOW)
		const rectNode = animNode.rectNode;
		const key = data.labelArr[1]?.value;

		rectNode.top_audio_key = key;
		rectNode.anim_node = animNode;
		this.topAudioRectNode = rectNode;
		
		
		rectNode.on("click", () => {

			this.clickTopAudio(rectNode);

			// if (rectNode.isClicked) {
			// 	return;
			// }
			// rectNode.isClicked = true;

			// const inputData = this.curQues.find(it => {
			// 	return it[key];
			// })
			// console.log('`inputData: ', inputData);

			// if (inputData) {
			// 	this.playAudioAnim(inputData[key], animNode, () => {
			// 		rectNode.isClicked = false;
			// 	});
			// } else {
			// 	rectNode.isClicked = false;
			// }

			
		})
				

		if (data.anchorGroup != null) {
			this.setRectNodeAnchor(data, bg, rectNode);
		}

		this.audioAnimArr.push(rectNode);

		this.labaNode = rectNode;

		delayCall(0.5, () => {
			this.clickTopAudio(this.topAudioRectNode);
		});

	},

	clickTopAudio(rectNode) {
		
		if (rectNode.isClicked) {
			return;
		}
		rectNode.isClicked = true;

		const key = rectNode.top_audio_key
		const animNode = rectNode.anim_node;

		const inputData = this.curQues.find(it => {
			return it[key];
		})
		console.log('`inputData: ', inputData);

		if (inputData) {
			this.playAudioAnim(inputData[key], animNode, () => {
				rectNode.isClicked = false;
			});
		} else {
			rectNode.isClicked = false;
		}
	},

	
	setTextOption(data, bg) {

		const rectNode = this.setOneRect(data, bg, cc.Color.BLUE);
		const labelData = this.findOneLabelByKey(data.labelArr, 'key');
		const key = labelData.value; // tempItem中的关键key获取
		rectNode.key = key;

		let count = 0;
		const picArr = data.picArr;
		picArr.forEach((picData, index) => {
			let picKey;
			switch(index) {
				case 0:
					picKey = 'normalNode';
					break;
				case 1:
					picKey = 'rightNode';
					break;
				case 2:
					picKey = 'wrongNode';
					break;
			}

			// console.log('picData: ', picData);

			getSprNodeByUrl(picData.pic_url, (spr) => {

				const isScale = this.checkboxIsTrue(data.checkbox, '适配矩形');
				if (isScale) {
					setSprNodeMaxLen(spr.node, rectNode.width, rectNode.height);
				}

				// setSprNodeMaxLen(spr.node, rectNode.width, rectNode.height);
				rectNode.addChild(spr.node);
				spr.node.x = rectNode.width / 2;
				spr.node.y = rectNode.height / 2;

				rectNode[picKey] = spr.node;
				if (picKey != 'normalNode') {
					spr.node.active = false;
				}
				spr.node.data = picData;

				count ++;
				if (count >= picArr.length) {
					this.refreshTextOptionArr();
				}

				
			})
		});


		rectNode.on('click', () => {
			if (this.curQues.endOptNode) {
				return;
			}

			this.curQues.endOptNode = rectNode;

			console.log(' option click ..', rectNode.data);
			if (rectNode.isRight) {
				this.showRightOption(rectNode);
			} else {
				this.showWrongOption(rectNode);
				// console.log("is wrong");
			}
		})

		const textNode = new cc.Node();
		rectNode.textNode = textNode;
		this.textOptionArr.push(rectNode);
	},


	setPicOption(data, bg) {

		const rectNode = this.setOneRect(data, bg, cc.Color.BLUE);
		const labelData = this.findOneLabelByKey(data.labelArr, 'key');
		const key = labelData.value; // tempItem中的关键key获取
		rectNode.key = key;

		const baseNode = new cc.Node();
		baseNode.width = rectNode.width;
		baseNode.height = rectNode.height;
		baseNode.x = rectNode.width / 2;
		baseNode.y = rectNode.height / 2;
		rectNode.addChild(baseNode);
		rectNode.baseNode = baseNode;

		let count = 0;
		const picArr = data.picArr;
		picArr.forEach((picData, index) => {
			let picKey;
			switch(index) {
				case 0:
					picKey = 'picNode';
					break;
				case 1:
					picKey = 'normalNode';
					break;
				case 2:
					picKey = 'rightNode';
					break;
				case 3:
					picKey = 'wrongNode';
					break;
			}

			getSprNodeByUrl(picData.pic_url, (spr) => {

				const isScale = this.checkboxIsTrue(data.checkbox, '适配矩形');
				if (isScale) {
					setSprNodeMaxLen(spr.node, rectNode.width, rectNode.height);
				}

				baseNode.addChild(spr.node);
				// spr.node.x = rectNode.width / 2;
				// spr.node.y = rectNode.height / 2;

				rectNode[picKey] = spr.node;
				if (picKey != 'normalNode') {
					spr.node.active = false;
				}

				spr.node.data = picData;

				count ++;
				if (count >= picArr.length) {
					rectNode.picNode.scale = rectNode.normalNode.scale;
					this.refreshPicOptionArr();
				}
				// this.refreshTextOptionArr();
			})
		});


		rectNode.on('click', () => {
			if (this.curQues.endOptNode) {
				return;
			}

			this.curQues.endOptNode = rectNode;

			console.log(' option click ..', rectNode.data);
			if (rectNode.isRight) {
				this.showRightOption(rectNode);
			} else {
				this.showWrongOption(rectNode);
			}
		})


		this.picOptionArr.push(rectNode);
		
		// const textNode = new cc.Node();
		// rectNode.textNode = textNode;
		// this.textOptionArr.push(rectNode);

	},

	

	setOptionEffect(data, bg) {

		console.log(' in setOptionEffect : ', data);
		this.audioRightUrl = data.audioArr[0].audio_url;
		this.audioWrongUrl = data.audioArr[1].audio_url;

		this.picRightUrl = data.picArr[0].pic_url;
		this.picWrongUrl = data.picArr[1].pic_url;

		this.optionEffectAnchor = data.anchorGroup;
	},

	setListArea(data, bg) {
		console.log(" in setListArea");
		const rectNode = this.setOneRect(data, bg, cc.Color.BLACK);

		const labelData = this.findOneLabelByKey(data.labelArr, 'distanceX');
		rectNode.disX = Number(labelData.value);
		this.listAreaArr.push(rectNode);


	},

	setListText(data, bg) {
		console.log('setListText data: ', data);

		const textBg = this.getListTextItem(data);


		const labelData = this.findOneLabelByKey(data.labelArr, 'key');
		const key = labelData.value; // tempItem中的关键key获取
		textBg.key = key;


		console.log('text key: ', key);

		console.log('textBg: ', textBg);
		this.listTextArr.push(textBg);
	},

	setListPic(data, bg) {
		const picItem = this.getListPicItem(data);

		const labelData = this.findOneLabelByKey(data.labelArr, 'key');
		const key = labelData.value; // tempItem中的关键key获取
		picItem.key = key;

		console.log('pic key: ', key);

		console.log('picItem: ', picItem);


		const checkBoxData = this.findOneLabelByKey(data.checkbox.list, 'isMask');
		picItem.isMask = checkBoxData.value;

		this.listPicArr.push(picItem);
	},

	setPageDotArea(data, bg) {
		console.log(" in setPageDotArea");
		const rectNode = this.setOneRect(data, bg, cc.Color.BLACK);

		const labelData = this.findOneLabelByKey(data.labelArr, 'distanceX');
		rectNode.disX = Number(labelData.value);
		console.log('rectNode.disX: ', rectNode.disX);

		if (data.anchorGroup != null) {
			this.setRectNodeAnchor(data, bg, rectNode);
		}

		this.pageDotAreaArr.push(rectNode);
	},

	setMultResArea(data, bg) {
		console.log(" in setMultResArea", data);

		const rectNode = this.setOneRect(data, bg, cc.Color.BLUE);
		const labelData = this.findOneLabelByKey(data.labelArr, 'key');
		const key = labelData.value; // tempItem中的关键key获取
		rectNode.key = key;

		if(data.checkbox && data.checkbox.list[0].label == '自动换行' && data.checkbox.list[0].value == true) {
			//多行
			rectNode.warp = true;
		}

		this.multResAreaArr.push(rectNode);
		
	},




	getListPicItem(data, callback=null) {
				
		const picNode = this.getDataPicArrNode(data, callback);

		picNode.data = data;
		return picNode;
	},

	getDataPicArrNode(data, callback=null) {
		const {picArr} = data;
		const picNode = new cc.Node();
		let count = 0;

		for (let i=0; i<picArr.length; i++) {
			const {pic_url} = picArr[i];
			const key = 'pic_' + (i+1);
			
			getSprNodeByUrl(pic_url, (spr) => {
				if (i == 0) {
					picNode.width = spr.node.width;
					picNode.height = spr.node.height;
				}

				picNode.addChild(spr.node);
				picNode[key] = spr.node;

				spr.node.active = false;
				if (picNode.pic_2) {
					picNode.pic_2.active = true;
					picNode.picNormal = picNode.pic_2;
				}

				if (picNode.pic_3) {
					picNode.picRight = picNode.pic_3
				}
				if (picNode.pic_4) {
					picNode.picWrong = picNode.pic_4;
				}

				count++;
				if (count >= picArr.length) {
					callback && callback();
				}
			});
		}

		return picNode;
	},

	getListTextItem(data, text ='') {
		const textPosType = data.radioValue;
		let picBg;
		switch(textPosType) {
			case "start":
				break;
			case "middle":
				picBg = this.getTextPicBg(data, text);
				break;
			case "end":
				break;
		}

		console.log('data: ', data);
		console.log('textPosType: ', textPosType);
		console.log('picBg: ', picBg);

		// if (picBg.pic_1) {
		// 	picBg.pic_1.active = true;
		// }

		picBg.data = data;
		return picBg;
	},

	getTextPicBg(data, text='') {

		const {picArr, labelArr} = data;
		const picNode = new cc.Node();

		for (let i=0; i<picArr.length; i++) {
			const {pic_url} = picArr[i];
			const key = 'pic_' + (i+1);
			
			getSprNodeByUrl(pic_url, (spr) => {
				if (i == 0) {
					picNode.width = spr.node.width;
					picNode.height = spr.node.height;
				}

				

				picNode.addChild(spr.node);
				picNode[key] = spr.node;

				const labelNode = this.getOneLabelByLabelArr(text, spr.node, labelArr, (i+1));
				spr.node.addChild(labelNode);
				spr.node.labelNode = labelNode;
				
				// spr.node.x = picNode.width / 2;
				// spr.node.y = picNode.height / 2;
				
				spr.node.active = false;
				if (picNode.pic_1) {
					picNode.pic_1.active = true;
					picNode.picNormal = picNode.pic_1;
				}
				if (picNode.pic_2) {
					picNode.picRight = picNode.pic_2
				}
				if (picNode.pic_3) {
					picNode.picWrong = picNode.pic_3
				}
				

			});
		}

		return picNode;
	},
 

	showRightOption(rectNode, isAnim=true) {
		rectNode.normalNode.active = false;
		rectNode.wrongNode.active = false;

		rectNode.rightNode.active = true;

		if (isAnim && this.audioRightUrl) {
			playAudioByUrl(this.audioRightUrl);
		}

		let effectNode = rectNode.baseNode;
		if (!effectNode) {
			effectNode = rectNode.rightNode;
		}
		this.addOptionRightEffect(effectNode, isAnim);
	},

	showWrongOption(rectNode, isAnim=true) {
		rectNode.normalNode.active = false;
		rectNode.rightNode.active = false;

		rectNode.wrongNode.active = true;
		

		if (isAnim && this.audioWrongUrl) {
			playAudioByUrl(this.audioWrongUrl);
		}
		if (isAnim) {

			let effectNode = rectNode.baseNode;
			if (!effectNode) {
				effectNode = rectNode.wrongNode;
			}
			this.rotateShake(effectNode);
		}
		
	},

	addOptionRightEffect(effectNode, isAnim) {
		getSprNodeByUrl(this.picRightUrl, (spr) => {

			if (effectNode.rightIcon) {
				effectNode.rightIcon.removeFromParent();
			}
			effectNode.rightIcon = spr.node;

			effectNode.addChild( spr.node, 10 );
			let offX = 0, offY = 0;
			if (this.optionEffectAnchor) {
				switch(this.optionEffectAnchor) {
					case 1:
						offX = -effectNode.width / 2;
						break;
					case 2:
						break;
					case 3:
						break;
					case 4:
						offX = -effectNode.width / 2;
						break;
					case 5:
						break;
					case 6:
						break;
					case 7:
						offX = -effectNode.width / 2;
						break;
					case 8:
						break;
					case 9:
						break;

				}
			}

			spr.node.x = offX;
			spr.node.y = offY;

			if (isAnim) {
				spr.node.scale = 2;
				spr.node.opacity = 0;
	
				cc.tween(spr.node)
					.to(0.4, {scale: 1, opacity: 255}, {easing: "cubicIn"})
					.start();
			}

		});
	},


	setOneRect(data, bg, color=cc.Color.BLACK) {
		const quesData = bg.data;
		const rate = (bg.scale * bg.width) / quesData.bgItem.rect.width;

		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		bg.addChild(rectNode);
		rectNode.data = data;


		const ctx = rectNode.addComponent(cc.Graphics);

		ctx.lineWidth = 4;
		ctx.strokeColor = color;//cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / bg.scaleY;
		// console.log('scale: ', scale);
		// console.log('scale2: ', scale / data.mapScale);


		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = -bg.width / 2 + data.rect.x * scale;
		rectNode.y = bg.height / 2 - data.rect.height * scale - data.rect.y * scale;
		// rectNode.scale = 1 / data.mapScale;

		rectNode.anchorX = rectNode.anchorY = 0;


		if (quesData.bgItem.isShowDebugLine || this.data.isDebug) {
			ctx.rect(0, 0, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();

		// console.log('```data: ', data)

		// if (data.audio_url) {
		// 	cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
		// 		rectNode.audioClip = audioClip;
		// 	});
		// }

		rectNode.addComponent(cc.Button);
		// rectNode.on('click', () => {
		

		// 	// const id = data.index;
		// 	// bg.active = false;
		// 	// this.hand.active = false;   

		// 	// 	this.showMask(() => {
		// 	// 		if (!this.isLocal) {
		// 	// 			callMiddleLayerFunction('PSQS_jump_to_question', {step: id}, null)
		// 	// 		}
		// 	// 	})

		// });

		return rectNode;


	},

	playCurQuesAudio(audioUrl, cb=null) {
		
		console.log(" in playCurQuesAudio");
		const animNode = this.fixedAnimArr[0];
		animNode.playAnim();

		console.log("audioUrl: ", audioUrl);
		
		playAudioByUrl(audioUrl, () => {
			animNode.stopAnim();
			cb && cb();
		})
	},

	playAudioAnim(audioUrl, animNode, cb=null) {
		animNode.playAnim();
		
		playAudioByUrl(audioUrl, () => {
			animNode.stopAnim();
			cb && cb();
			
		}, (audioId) => {
			const duration = cc.audioEngine.getDuration(audioId);
			addSRAudioDuration(duration);
		})
	},


	refreshInputPic() {
		this.inputPicArr.forEach((node) => {

			node.removeAllChildren();

			const key = node.key;
			const inputData = this.curQues.find(it => {
				return it[key];
			});
			if (inputData) {
				const picUrl = inputData[key];

				getSprNodeByUrl(picUrl, (spr) => {
					setSprNodeMaxLen(spr.node, node.width, node.height);
					node.addChild(spr.node);
					spr.node.x = node.width / 2;
					spr.node.y = node.height / 2;
				})
			}
		})
	},

	refreshInputText() {

		console.log('inputTextArr: ', this.inputTextArr);
		this.inputTextArr.forEach((node) => {

			node.removeAllChildren();
			if (node.labelNode) {
				node.labelNode.removeFromParent();
			}

			const key = node.key;
			const inputData = this.curQues.find(it => {
				return it[key];
			});
 
			this.topLabelNode = node;
			
			let inputDataText = '';
			if (inputData) {

				inputDataText = inputData[key];
			}

						
			node.warp = true;

			this.setLabelNodeByLabelArr(node.data.labelArr, inputDataText, node);

		})
	},

	setLabelNodeByLabelArr(labelArr, text, node) {
		// console.log('inputText data: ', inputData);
		// console.log('node.data.labelArr: ', node.data.labelArr);
		const fontNameLabelData = this.findOneLabelByKey(labelArr, 'fontName');

		let fontName, fontSize, fontColor;
		if (fontNameLabelData || fontNameLabelData.value) {
			fontName = fontNameLabelData.value;
		}

		const fontSizeLabelData = this.findOneLabelByKey(labelArr, 'fontSize');
		if (fontSizeLabelData || fontSizeLabelData.value) {
			fontSize = Number(fontSizeLabelData.value) + 2;
		}

		const fontColorLabelData = this.findOneLabelByKey(labelArr, 'fontColor');
		if (fontColorLabelData || fontColorLabelData.value) {
			fontColor = cc.Color.fromHEX(new cc.Color(), fontColorLabelData.value);
		}
		
	
		// const labelNode = this.getLabel(text, fontSize, fontColor, fontName);

		// if (node.warp) {
		// 	//多行
		// 	labelNode.width = node.width;
		// 	labelNode.height = node.height;
			
		// 	const label = labelNode.getComponent(cc.Label);
		// 	label.overflow = cc.Label.Overflow.CLAMP;
		// 	label.enableWrapText = true;
		// 	label.horizontalAlign = cc.Label.HorizontalAlign.CENTER;
		// 	label.verticalAlign = cc.Label.VerticalAlign.CENTER;
		// 	label.lineHeight = fontSize*1.2;
		// 	label.string = text;
		// 	console.log("多行");
		// }
		
		const labelNode = new cc.Node();
		labelNode.color = fontColor;
		const richtext = labelNode.addComponent(cc.RichText);
		richtext.horizontalAlign = cc.macro.TextAlignment.CENTER;
		richtext.maxWidth = node.width;
		richtext.fontSize = fontSize;
		richtext.lineHeight = fontSize * 1.2;
		richtext.string = text;

		// labelNode

		const labelBoundingBox = labelNode.getBoundingBoxToWorld();
		const bgBoundingBox = node.getBoundingBoxToWorld();
		if (labelBoundingBox.width > bgBoundingBox) {
			labelNode.scale = bgBoundingBox.width / labelBoundingBox.width;
		}

		labelNode.x = node.width / 2;
		labelNode.y = node.height / 2;

		node.labelNode = labelNode;
		node.addChild(labelNode);


	},


	refreshDataText() {

		this.curAnswerText = '';

		this.dataTextArr.forEach((node) => {

			// console.log('node text: ', node);

			const key = node.key;
			const inputData = this.curQues.find(it => {
				return it[key];
			});

			console.log('inputData: ', inputData);
			
			const text = inputData[key];
			switch(key) {
				case "answer_text":
					this.curAnswerText = text;
					this.rightWord = inputData.rightWord || '';
					console.log('rightWord: ', this.rightWord);
					break
			}

		})
	},

	findOneLabelByKey(labelArr, key) {
		const label = labelArr.find(it => {
			return it.key == key;
		})
		return label;
	},

	refreshRecordBtn() {
		const startNode = this.recordNode.startNode;
		const stopNode = this.recordNode.stopNode;

		if(this.isRecord) {
			startNode.active = false;
			stopNode.active = true;
		} else {
			startNode.active = true;
			stopNode.active = false;
		}
	},

	refreshPage() {

		
		this.refreshInputText();
		this.refreshInputPic();
		this.refreshArrowBtn();
		this.refreshAudioAnim();

		this.refreshDataText();
		
		this.refreshRecordGroup();
		
		this.refreshTextOptionArr();
		this.refreshPicOptionArr();

		this.refreshListArea();
		this.refreshPageDotArea();

		this.refreshMultResArea();

		
		this.initTop();
	},

	refreshAudioAnim() {
		this.audioAnimArr.forEach((node) => {
			const key = node.data.labelArr[1]?.value;
			const inputData = this.curQues.find(it => {
				return it[key];
			});
			
			if (inputData) {
				const audioUrl = inputData[key];
				if (!audioUrl) {
					node.active = false;
				} else {
					node.active = true;
					this.topAudioRectNode = node;
				}
			} else {
				node.active = false;
			}
		});
	},

	refreshRecordGroup() {
		if (!this.recordRectNode) {
			return;
		}
		if (this.curQues.score != null) {
			this.showScoreNode(this.curQues.score);
		} else {
			this.hideScoreNode();
		}
	},

	refreshTextOptionArr() {

		this.textOptionArr.forEach((node) => {

			const textNode = node.textNode;
			textNode.removeAllChildren();

			const key = node.key;
			// console.log('node.key: ', key);
			const inputData = this.curQues.find(it => {
				return it[key];
			});

			
			if (inputData) {
				
				
				const text = inputData[key];
				const labelNode1 = this.getOneLabelByLabelArr(text, node, node.data.labelArr, '1');
				const labelNode2 = this.getOneLabelByLabelArr(text, node, node.data.labelArr, '2');
				const labelNode3 = this.getOneLabelByLabelArr(text, node, node.data.labelArr, '3');

				if (node.normalNode) {
					node.normalNode.removeAllChildren();
					node.normalNode.addChild(labelNode1);
					node.normalNode.active = true;
				}
				if (node.rightNode) {
					node.rightNode.removeAllChildren();
					node.rightNode.addChild(labelNode2);
					node.rightNode.active = false;
				}
				if (node.wrongNode) {
					node.wrongNode.removeAllChildren();
					node.wrongNode.addChild(labelNode3);
					node.wrongNode.active = false;
				}

				// console.log('inputData.optionValue : ', inputData.optionValue);
				if (inputData.optionValue == 'isRight') {
					node.isRight = true;
				} else {
					node.isRight = false;
				}

				if (this.curQues.endOptNode == node) {
					if (node.isRight) {
						this.showRightOption(node, false);
					} else {
						this.showWrongOption(node, false);
					}
				}
				// node.addChild(labelNode);

				node.active = true;
			} else {
				node.active = false;
			}
		})
	},

	refreshPicOptionArr() {
		this.picOptionArr.forEach((node) => {

			const key = node.key;
			const inputData = this.curQues.find(it => {
				return it[key];
			});
			
			if (inputData) {

				const picNode = node.picNode;
				if (picNode) {

					picNode.removeAllChildren();

					const data = node.data;
					const isMask = this.checkboxIsTrue(data.checkbox, '遮罩');
					if (isMask) {
						
						if (!picNode.hasMask) {
							const spr = picNode.getComponent(cc.Sprite);
							const spriteFrame = spr.spriteFrame;
							picNode.removeComponent(cc.Sprite);
	
							const mask = picNode.addComponent(cc.Mask);
							mask.type = cc.Mask.Type.IMAGE_STENCIL;
							mask.spriteFrame = spriteFrame;
							picNode.hasMask = true;
						}
					

						const picUrl = inputData[key];
						getSprNodeByUrl(picUrl, (spr) => {
							picNode.addChild(spr.node);
							setSprNodeMaxLen(spr.node, picNode.width, picNode.height, false);
							picNode.active = true;
							picNode.zIndex = 1;
						});	
						picNode.active = true;

					} else {

						
						const picUrl = inputData[key];
						getSprNodeByUrl(picUrl, (spr) => {
							picNode.addChild(spr.node);
							setSprNodeMaxLen(spr.node, picNode.width, picNode.height);
							picNode.active = true;
							picNode.zIndex = 1;
						});	
						picNode.active = true;
					}
				}
	

				if (node.normalNode) {
					node.normalNode.active = true;
				}
				if (node.rightNode) {
					node.rightNode.active = false;
				}
				if (node.wrongNode) {
					node.wrongNode.active = false;
				}

				if (inputData.optionValue == 'isRight') {
					node.isRight = true;
				} else {
					node.isRight = false;
				}


				let effectNode = node.baseNode;
				if (!effectNode) {
					effectNode = node.rightNode;
				}
				if (effectNode.rightIcon) {
					effectNode.rightIcon.removeFromParent();
					effectNode.rightIcon;
				}

				if (this.curQues.endOptNode == node) {
					if (node.isRight) {
						this.showRightOption(node, false);
					} else {
						this.showWrongOption(node, false);
					}
				}

				node.active = true;
			} else {
				node.active = false;
			}
		})
	},

	refreshListArea() {

		this.dragStartArr = [];
		this.dragEndArr = [];

		for (let i=0; i<this.listAreaArr.length; i++) {
			const listArea = this.listAreaArr[i];
			
			this.addListAreaItem(listArea);
		}

		// this.checkHasDragEndData();
	},

	refreshPageDotArea() {

		// this.dragStartArr = [];
		// this.dragEndArr = [];

		if (this.curPageDotArea) {

			this.refreshPageDotState();
			return;
		}

		for (let i=0; i<this.pageDotAreaArr.length; i++) {
			const pageDotArea = this.pageDotAreaArr[i];
			
			this.addPageDotAreaItem(pageDotArea);
		}

	},

	refreshMultResArea() {



		this.multResAreaArr.forEach((node) => {

			node.removeAllChildren();

			const key = node.key;
			const inputData = this.curQues.find(it => {

				if (!it.labelArr) {
					return false;
				}
				const labelData = this.findOneLabelByKey(it.labelArr, 'key');
				return labelData && labelData.value == key
			});


			if (inputData) {
				
				console.log('inputData~ ', inputData);

				switch(inputData.multResType) {
					case "text":
						this.setLabelNodeByLabelArr(inputData.labelArr, inputData.multResText, node);
						break;
					case "audio":
						break;
					case "pic":

						const picUrl = inputData.multResPic;

						getSprNodeByUrl(picUrl, (spr) => {
							setSprNodeMaxLen(spr.node, node.width, node.height);
							node.addChild(spr.node);
							spr.node.x = node.width / 2;
							spr.node.y = node.height / 2;
						})
						break;


				}

				// const picUrl = inputData[key];

				// getSprNodeByUrl(picUrl, (spr) => {
				// 	setSprNodeMaxLen(spr.node, node.width, node.height);
				// 	node.addChild(spr.node);
				// 	spr.node.x = node.width / 2;
				// 	spr.node.y = node.height / 2;
				// })
			} else {
				console.log(' this.curQues: ', this.curQues);
			}
		})


	},







	refreshPageDotState() {
		const pageDotArr = this.curPageDotArea.pageDotArr;

		pageDotArr.forEach((node, index) => {

			if (node.isLoadEnd) {
				node.pic_1.active = false;
				node.pic_2.active = false;
				node.pic_3.active = false;
				node.pic_4.active = false;
				node.pic_5.active = false;
				node.pic_6.active = false;
			}
	
		});

		for (let i=0; i<pageDotArr.length; i++) {
			const pageDot = pageDotArr[i];
			const ques = this.quesArr[i];
			if (!pageDot.isLoadEnd) {
				continue;
			}

			if (ques != this.curQues) {
				if (ques.score == null) {
					pageDot.pic_1.active = true;
				} else {
					if (ques.score >= 60) {
						pageDot.pic_2.active = true;
					} else {
						pageDot.pic_3.active = true;
					}
				}
			} else {
				if (ques.score == null) {
					pageDot.pic_4.active = true;
				} else {
					if (ques.score >= 60) {
						pageDot.pic_5.active = true;
					} else {
						pageDot.pic_6.active = true;
					}
				}
			}
		}
	},


	checkHasDragEndData() {

		const tempDragEndArr = [];
		const tempDragStartArr = [];
		for(let i=0; i<this.listAreaArr.length; i++) {
			const listArea = this.listAreaArr[i];
			const listItem = listArea.listItem;
			if (!listItem) {
				continue;
			}

			if (listItem.dragStart) {
				tempDragStartArr.push(listArea);
			}

			if (listItem.dragEnd) {
				tempDragEndArr.push(listArea);
			}
		}

		
	},


	addListAreaItem(listArea) {

		const listAreaData = listArea.data;
		const baseNodeKey = 'listArea_baseNode_' + listAreaData.index;

		// listArea.removeAllChildren();
		const children = listArea.children;
		children.forEach(it => {
			it.active = false;
		})

		let baseNode;
		if (this.curQues[baseNodeKey]) {
			baseNode = this.curQues[baseNodeKey];
			// baseNode.parent = listArea;
			baseNode.active = true;

			this.dragStartArr = this.curQues._dragStartArr
			this.dragEndArr = this.curQues._dragEndArr;

			return;
		} else {

			baseNode = new cc.Node();
			listArea.addChild(baseNode);
			this.curQues[baseNodeKey] = baseNode;

			this.curQues._dragStartArr = this.dragStartArr;
			this.curQues._dragEndArr = this.dragEndArr;
		}

		// listArea.removeAllChildren();

		// baseNode = new cc.Node();
		// listArea.addChild(baseNode);

		if (!listArea.listItem) {
			this.setListAreaItem(listArea);
		}

		let listItem = listArea.listItem;
		if (!listItem) {
			return;
		}
		

		const key = listItem.key;
		// console.log('key~~~: ', key);
		const inputData = this.curQues.find(it => {
			return it[key];
		});

		
		if (!inputData) {
			console.log(" this.curQues : ",  this.curQues);
			return;
		}

		// console.log('listItem.data:', listItem.data);
		// console.log("inputData: ", inputData);
		// console.log("this.curQues: ", this.curQues);

		const inputListArr = inputData[key];
		
		inputListArr.forEach(it => {
			let newListItem;
			if (listItem.isText) {
				newListItem = this.getNewListTextItem(listItem, it.value);
			}
			if (listItem.isPic) {
				newListItem = this.getNewListPicItem(listItem, it.pic_url, listItem.isMask);
			}

			const disX = listArea.disX;

			newListItem.parent = baseNode;
			newListItem.x = baseNode.width + disX / 2;
			baseNode.width += disX;


			if (listItem.dragStart) {
				this.addDragStartItem(newListItem);
			}
			if (listItem.dragEnd) {
				this.addDragEndItem(newListItem);
			}
			

		})

		baseNode.x = listArea.width / 2 - baseNode.width / 2;
		baseNode.y = listArea.height / 2;

		if (listItem.dragStart) {
			this.randomListPos(this.dragStartArr);
		}
	},

	addPageDotAreaItem(pageDotArea) {
		const pageDotAreaData = pageDotArea.data;
		const disX = pageDotArea.disX * 12;

		const baseNode = new cc.Node();
		pageDotArea.addChild(baseNode);
		const pageDotArr = [];

		for (let i=0; i<this.quesArr.length; i++) {
			const pageDotNode = this.getPageDotNode(pageDotAreaData);
			baseNode.addChild( pageDotNode );

			pageDotNode.x = baseNode.width + disX / 2;
			baseNode.width += disX;

			pageDotArr.push(pageDotNode);
		}

		baseNode.x = pageDotArea.width / 2 - baseNode.width / 2;
		baseNode.y = pageDotArea.height / 2;

		pageDotArea.pageDotArr = pageDotArr;
		this.curPageDotArea = pageDotArea;
		return;




		// const baseNodeKey = 'listArea_baseNode_' + listAreaData.index;

		// const children = listArea.children;
		// children.forEach(it => {
		// 	it.active = false;
		// })

		// let baseNode;
		// if (this.curQues[baseNodeKey]) {
		// 	baseNode = this.curQues[baseNodeKey];
		// 	// baseNode.parent = listArea;
		// 	baseNode.active = true;

		// 	this.dragStartArr = this.curQues._dragStartArr
		// 	this.dragEndArr = this.curQues._dragEndArr;

		// 	return;
		// } else {

		// 	baseNode = new cc.Node();
		// 	listArea.addChild(baseNode);
		// 	this.curQues[baseNodeKey] = baseNode;

		// 	this.curQues._dragStartArr = this.dragStartArr;
		// 	this.curQues._dragEndArr = this.dragEndArr;
		// }


		// if (!listArea.listItem) {
		// 	this.setListAreaItem(listArea);
		// }

		// let listItem = listArea.listItem;
		// if (!listItem) {
		// 	return;
		// }
		

		// const key = listItem.key;
		// // console.log('key~~~: ', key);
		// const inputData = this.curQues.find(it => {
		// 	return it[key];
		// });

		
		// if (!inputData) {
		// 	console.log(" this.curQues : ",  this.curQues);
		// 	return;
		// }

		// // console.log('listItem.data:', listItem.data);
		// // console.log("inputData: ", inputData);
		// // console.log("this.curQues: ", this.curQues);

		// const inputListArr = inputData[key];
		
		// inputListArr.forEach(it => {
		// 	let newListItem;
		// 	if (listItem.isText) {
		// 		newListItem = this.getNewListTextItem(listItem, it.value);
		// 	}
		// 	if (listItem.isPic) {
		// 		newListItem = this.getNewListPicItem(listItem, it.pic_url, listItem.isMask);
		// 	}

		// 	const disX = listArea.disX;

		// 	newListItem.parent = baseNode;
		// 	newListItem.x = baseNode.width + disX / 2;
		// 	baseNode.width += disX;


		// 	if (listItem.dragStart) {
		// 		this.addDragStartItem(newListItem);
		// 	}
		// 	if (listItem.dragEnd) {
		// 		this.addDragEndItem(newListItem);
		// 	}
			

		// })

		// baseNode.x = listArea.width / 2 - baseNode.width / 2;
		// baseNode.y = listArea.height / 2;

		// if (listItem.dragStart) {
		// 	this.randomListPos(this.dragStartArr);
		// }
	},

	getPageDotNode(data) {
		console.log(' getPageDotNode data: ', data);

		const picNode = this.getDataPicArrNode(data, () => {
			
			// picNode.pic_1.active = false;
			// picNode.pic_2.active = false;
			// picNode.pic_3.active = false;
			// picNode.pic_4.active = false;
			// picNode.pic_5.active = false;
			// picNode.pic_6.active = false;

			picNode.isLoadEnd = true;
			this.refreshPageDotState();

		});


		return picNode;
	},



	randomListPos() {
		for (let i=0; i<this.dragStartArr.length; i++) {
			const startItem = this.dragStartArr[i];

			const endItemIndex = Math.floor( Math.random() * this.dragStartArr.length );
			const endItem = this.dragStartArr[ endItemIndex ];

			let tempPos = startItem.getPosition();

			startItem.x = endItem.x;
			startItem.y = endItem.y;
			startItem.baseX = startItem.x;
			startItem.baseY = startItem.y;

			endItem.x = tempPos.x;
			endItem.y = tempPos.y;
			endItem.baseX = endItem.x;
			endItem.baseY = endItem.y;

		}
	},


	addDragStartItem(newListItem) {
		this.addToArr(this.dragStartArr, newListItem);

		newListItem.baseX = newListItem.x;
		newListItem.baseY = newListItem.y;

		newListItem.dragId = this.dragStartArr.length;

		newListItem.on(cc.Node.EventType.TOUCH_START, (event) => {

			if (newListItem.isDragEnd) {
				return;
			}

			this._curClickItem = newListItem;
			this._curClickItem.oldZ = this._curClickItem.zIndex;
			this._curClickItem.zIndex = 20;
		});

	},

	addDragEndItem(newListItem) {
		this.addToArr(this.dragEndArr, newListItem);

		newListItem.dragId = this.dragEndArr.length;
	},

	getNewListTextItem(listItem, text) {
		const data = listItem.data;

		const textBg = this.getListTextItem(data, text);
	
		return textBg;
	},

	getNewListPicItem(listItem, pic_url, isMask) {
		const data = listItem.data;

		const picBg = this.getListPicItem(data, () => {

			if (!picBg.pic_1) {
				console.log('picBg: ', picBg);
				return;
			} 
			
			if (picBg.pic_2){
				picBg.width = picBg.pic_2.width;
				picBg.height = picBg.pic_2.height;
			}
			
			const picNode = picBg.pic_1;
			picNode.active = true;
			picNode.zIndex = 10;

			console.log("isMask: ", isMask);
			if (isMask) {
				const spriteFrame = picNode.getComponent(cc.Sprite).spriteFrame;
				picNode.removeComponent(cc.Sprite);
				
				const mask = picNode.addComponent(cc.Mask);
				mask.type = cc.Mask.Type.IMAGE_STENCIL;
				mask.spriteFrame = spriteFrame;
				
				getSprNodeByUrl(pic_url, (spr) => {
					mask.node.addChild(spr.node);
					setSprNodeMaxLen(spr.node, picNode.width, picNode.height);
				});
			} else {

				getSprNodeByUrl(pic_url, (spr) => {
					picNode.addChild(spr.node);
					setSprNodeMaxLen(spr.node, picNode.width, picNode.height);
				});
			}

		});
		
		return picBg;
	},

	


	setListAreaItem(listArea) {

		const listAreaData = listArea.data;
		
		const labelData = this.findOneLabelByKey(listAreaData.labelArr, 'id');
		const listAreaId = labelData.value;

		console.log('listAreaId:', listAreaId);
		const listText = this.listTextArr.find((it) => {

			const labelData = this.findOneLabelByKey(it.data.labelArr, 'id');
			const id = labelData.value;
			console.log('id: ', id);
			return id == listAreaId;
		})

		const listPic = this.listPicArr.find((it) => {

			const labelData = this.findOneLabelByKey(it.data.labelArr, 'id');
			const id = labelData.value;
			console.log('id: ', id);
			return id == listAreaId;
		})

		console.log('listText~: ', listText);
		console.log('listPic~: ', listPic);

		if (listText) {
			listText.isText = true;
		}
		if (listPic) {
			listPic.isPic = true;
		}
		listArea.listItem = listText ? listText : listPic;

		

		switch(listAreaId) {
			case 'drag_start':
				listArea.listItem.dragStart = true;
				break;
			case 'drag_end':
				listArea.listItem.dragEnd = true;
				break;
		}
		// if (listAreaId == 'drag_start') {
		// 	listArea.listItem.dragStart = true;
		// }
		

		// return listText;
	},


	checkboxIsTrue(checkbox, labelName) {
		const list = checkbox?.list;
		if (!list) {
			return;
		}

		const oneData = list.find(it => {
			return it.label == labelName;
		});

		return oneData.value;
	},


	getOneLabelByLabelArr(text, parentNode, labelArr, id='') {
		const fontNameLabelData = this.findOneLabelByKey(labelArr, 'fontName' + id);

		let fontName, fontSize, fontColor;
		if (fontNameLabelData || fontNameLabelData.value) {
			fontName = fontNameLabelData.value;
		}

		const fontSizeLabelData = this.findOneLabelByKey(labelArr, 'fontSize');
		if (fontSizeLabelData || fontSizeLabelData.value) {
			fontSize = fontSizeLabelData.value;
		}

		const fontColorLabelData = this.findOneLabelByKey(labelArr, 'fontColor' + id);
		if (fontColorLabelData || fontColorLabelData.value) {
			fontColor = cc.Color.fromHEX(new cc.Color(), fontColorLabelData.value);
		}
		
	
		const labelNode = this.getLabel(text, fontSize, fontColor, fontName);

		const labelBoundingBox = labelNode.getBoundingBoxToWorld();
		const bgBoundingBox = parentNode.getBoundingBoxToWorld();
		if (labelBoundingBox.width > bgBoundingBox) {
			labelNode.scale = bgBoundingBox.width / labelBoundingBox.width;
		}

		// labelNode.x = parentNode.width / 2;
		// labelNode.y = parentNode.height / 2;

		return labelNode;
	},

	addToArr(arr, item) {
		const index = arr.indexOf(item);
		if (index != -1) {
			return;
		}

		arr.push(item)
	},





	setOneLinkRect(data) {
		const rate = (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;

		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		this.hotZoneBg.addChild(rectNode);

		const ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / this.hotZoneBg.scaleY;

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
		rectNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;
		// rectNode.scale = 1 / data.mapScale;

		rectNode.anchorX = rectNode.anchorY = 0;


		if (this.data.isDebug) {
			ctx.rect(0, 0, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();

		rectNode.data = data;

		console.log(" data is ~~~ : ", data);

		this.rectNodeArr.push(rectNode)


		const debugItemId = data.pointItem;
		const debugItemData = this.data.hotZoneItemArr2[Number(debugItemId) - 1];
		rectNode.isRightPoint = debugItemData.checkbox.list[0].value == true;

		console.log('debugItemData.checkbox.list[0].value: ', debugItemData.checkbox.list[0].value);

	},


	addMask(node) {
		const mask = node.addComponent(cc.Mask);
		mask.type = cc.Mask.Type.RECT;
	},


	setOneDragAction(data) {

		const rate =  (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;
		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		this.hotZoneBg.addChild(rectNode);

		const ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / this.hotZoneBg.scaleY ;

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
		rectNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;
		const {x, y, width, height} = rectNode;
		// rectNode.anchorX = rectNode.anchorY = 0;

		if (this.data.bgItem.isShowDebugLine) {
			ctx.rect(-rectNode.width / 2, -rectNode.height / 2, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();
		rectNode.x += rectNode.width / 2;
		rectNode.y += rectNode.height / 2;

		rectNode.baseX = rectNode.x;
		rectNode.baseY = rectNode.y;
		rectNode.targetOff();

		rectNode.on(cc.Node.EventType.TOUCH_START, () => {

			if (rectNode.isDragEnd) {
				if (rectNode.audioClip) {
					cc.audioEngine.stopAllEffects();
					cc.audioEngine.playEffect(rectNode.audioClip, false, 0.8);
				}
				return;
			}
			this._curShowItem = rectNode;
		})
		

		const realRate = this.hotZoneBg.width / this.data.bgItem.rect.width;
		rectNode.targetPx = -this.hotZoneBg.width / 2 + ( data.dragDot.x - this.data.bgItem.rect.x ) * realRate;
		rectNode.targetPy = this.hotZoneBg.height / 2 - (data.dragDot.y - this.data.bgItem.rect.y) * realRate;


		if (data.audio_url) {
			cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
				rectNode.audioClip = audioClip;
			});
		}



		console.log('setOneAction ~~ data: ', data)
		const actionData = data['actionData_' + data.gIdx];
		if (!actionData) {
			return;
		}
		if (actionData.type == 'text') {
			const label = this.setOneActionText(rectNode, actionData);
			label.node.scale = scale * data.fontScale;

			label.node.targetOff();
		
	

			// label.overflow = cc.Label.Overflow.NONE;
			// label.node.setContentSize(new cc.Size(0, lineHeight));
			label["_forceUpdateRenderData"](true);
		
			
		} else if (actionData.type == 'pic') {

			const pic = this.setOneActionPic(rectNode, actionData);

		} else if (actionData.type == 'anima') {

			const anima = this.setOneActionAnima(rectNode, actionData);
		}
	},



	setOneAction(data) {

		const rate =  (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;
		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		this.hotZoneBg.addChild(rectNode);

		const ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / this.hotZoneBg.scaleY ;

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
		rectNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;
		const {x, y, width, height} = rectNode;
		rectNode.anchorX = rectNode.anchorY = 0;

		if (this.data.bgItem.isShowDebugLine) {
			ctx.rect(0, 0, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();



		console.log('setOneAction ~~ data: ', data)
		const actionData = data['actionData_' + data.gIdx];
		if (!actionData) {
			return;
		}
		if (actionData.type == 'text') {
			const label = this.setOneActionText(rectNode, actionData);
			label.node.scale = scale * data.fontScale;

			// label.overflow = cc.Label.Overflow.NONE;
			// label.node.setContentSize(new cc.Size(0, lineHeight));
			label["_forceUpdateRenderData"](true);
		
			
		} else if (actionData.type == 'pic') {

			const pic = this.setOneActionPic(rectNode, actionData);

		} else if (actionData.type == 'anima') {

			const anima = this.setOneActionAnima(rectNode, actionData);
		}
	},

	setOneActionText(rectNode, actionData) {


		const labelNode = new cc.Node();
		labelNode.parent = rectNode;
		const label = labelNode.addComponent(cc.Label);

		label.font = cc.find('Canvas/res/font/ahronbd-1').getComponent(cc.Label).font;
		label.string = actionData.text;
		// label.string = `<size=${size}><color=#751e00>${this.curGroup.title }</color></size>`
		// label.lineHeight = size;
		// label.horizontalAlign = cc.macro.TextAlignment.LEFT
		// labelNode.anchorX = 0;
		// labelNode.anchorY = 1
		labelNode.color = cc.Color.BLACK;


		const opArr = actionData.changeOption
		// console.log('opArr', opArr);


		const tweenArr = [];

		for (let i = 0; i < opArr.length; i++ ) {

			const opData = opArr[i];
			console.log('opArr[0]', opArr[i])
			if (opData[0] == 'fontColor') {
				const color = new cc.Color();
				cc.Color.fromHEX(color, opData[1] );
				labelNode.color = color;

			} else if (opData[0] == 'opacity') {
				// console.log('opData: ', opData)
				labelNode.opacity = Number( opData[1] / 100 * 255 ) + 0.1;
				// console.log(labelNode.opacity);
				tweenArr.push({item: labelNode , option: `{"${opData[0]}" : ${opData[2] / 100 * 255}}`, optionName: opData[0]},)

			} else {
				label[opData[0]] = opData[1];
				tweenArr.push({item: label, option: `{"${opData[0]}" : ${opData[2]}}`, optionName: opData[0]})

			}
		}


		// if (actionData.audio_url) {
		// 	cc.assetManager.loadRemote(actionData.audio_url, (err, audioClip) => {
		// 		labelNode.audioClip = audioClip;
		// 	});
		// }


		label.lineHeight = label.fontSize;

		// labelNode.y += rectNode.height / 2;
		// labelNode.x += rectNode.width / 2;
		

		// rectNode.addComponent(cc.Button);
		// rectNode.on('click', () => {

		// 	if (labelNode.audioClip) {
		// 		cc.audioEngine.stopAllEffects();
		// 		cc.audioEngine.playEffect(labelNode.audioClip, false, 0.8);
		// 	}

		// 	if (labelNode.isClicked) {
		// 		// return;
		// 	}
		// 	labelNode.isClicked = true;

		// 	for (let i=0; i<tweenArr.length; i++) {
		// 		const tweenData = tweenArr[i];

		// 		if (tweenData.optionName == 'opacity') {
		// 			console.log('~~~ ',  tweenData.item[tweenData.optionName] );

		// 			cc.tween(tweenData.item)
		// 				.to(actionData.changeTime,  JSON.parse(tweenData.option) )
		// 				.start();
		// 		}
				

		// 	}

		// });


		return label;
	},

	setOneActionPic(rectNode, actionData) {

		console.log('setOneActionPic actionData: ', actionData)
		const picNode = new cc.Node();
		rectNode.addChild(picNode);

		cc.loader.load({url: actionData.pic_url}, (err, img) => {

			const spr = picNode.addComponent(cc.Sprite);
			spr.spriteFrame = new cc.SpriteFrame(img)

			picNode.y += rectNode.height / 2;
			picNode.x += rectNode.width / 2;

			picNode.scaleX = rectNode.width / picNode.width;
			picNode.scaleY = rectNode.height / picNode.height;

			const opArr = actionData.changeOption	
			const tweenArr = [];
	
			for (let i = 0; i < opArr.length; i++ ) {
	
				const opData = opArr[i];
				console.log('opData: ~~~ ', opData);

				if (opData[0] == 'opacity') {
					picNode.opacity = Number( opData[1] / 100 * 255 ) + 0.1;
					console.log(picNode.opacity);
					tweenArr.push({item: picNode , option: `{"${opData[0]}" : ${opData[2] / 100 * 255}}`, optionName: opData[0]},)
	
				}  else {
					// picNode[opData[0]] = Number(opData[1]);
					// tweenArr.push({item: picNode, option: `{"${opData[0]}" : ${opData[2]}}`, optionName: opData[0]})
				}

	
				if (actionData.audio_url) {
					cc.assetManager.loadRemote(actionData.audio_url, (err, audioClip) => {
						rectNode.audioClip = audioClip;
					});
				}
				

				rectNode.addComponent(cc.Button);
				rectNode.on('click', () => {

					if (rectNode.audioClip) {
						cc.audioEngine.stopAllEffects();
						cc.audioEngine.playEffect(rectNode.audioClip, false, 0.8);
					}
		
					if (rectNode.isClicked) {
						// return;
					}
					rectNode.isClicked = true;

					for (let i=0; i<tweenArr.length; i++) {
						const tweenData = tweenArr[i];
		
						if (tweenData.optionName == 'opacity') {
							cc.tween(tweenData.item)
								.to(actionData.changeTime,  JSON.parse(tweenData.option) )
								.start();
						}
					}
		
				});
			}

		});
	},

	setOneActionAnima(rectNode, actionData) {


		const animaNode = new cc.Node();
		rectNode.addChild(animaNode);

		if (actionData.audio_url) {
			cc.assetManager.loadRemote(actionData.audio_url, (err, audioClip) => {
				rectNode.audioClip = audioClip;
			});
		}

		const data = actionData;

		const dragonDisplay = animaNode.addComponent(dragonBones.ArmatureDisplay);
		if (!data.texPngData) {
			return
		}



		const image = data.texPngData.url//"http://staging-teach.cdn.ireadabc.com/5a0c5af3e952acd0ac83a6e5c6f03ff1.png";
		const ske = data.skeJsonData.url//"http://staging-teach.cdn.ireadabc.com/bd825dcceea298d1146be8067ae3d17f.json";
		const atlas = data.texJsonData.url//"http://staging-teach.cdn.ireadabc.com/246f8991b729fa3e5a7f4802de828efa.json";
		cc.loader.load(image, (error, texture) => {

			cc.loader.load({url: atlas, type: 'txt'}, (error, atlasJson) => {

				cc.loader.load({url: ske, type: 'txt'}, (error, dragonBonesJson) => {

					const atlas = new dragonBones.DragonBonesAtlasAsset();
					atlas.atlasJson = atlasJson;
					atlas.texture = texture;

					const asset = new dragonBones.DragonBonesAsset();
					asset.dragonBonesJson = dragonBonesJson;

					dragonDisplay.dragonAtlasAsset = atlas;
					dragonDisplay.dragonAsset = asset;


					let json = JSON.parse(asset.dragonBonesJson);
					let armatures = json["armature"];
					let armatureNames = [];
					for (let i = 0; i < armatures.length; i++) {
						armatureNames.push(armatures[i].name);
					}
					// console.log('armatureNames: ', armatureNames);

					let animationNames = [];

					if (armatureNames.length > 0) {
						let defaultArmatureName = armatureNames[0];
						dragonDisplay.armatureName = defaultArmatureName;
						// let animationNames = dragonDisplay.getAnimationNames(defaultArmatureName);
						let defaultArmature = armatures[0];
						let animations = defaultArmature.animation;
						for (let i = 0; i < animations.length; i++) {
							animationNames.push(animations[i].name);
						}

						// rectNode.addComponent(cc.Button);
						// rectNode.on('click', () => {
						// 	if (rectNode.isClicked) {
						// 		// return;
						// 	}
						// 	rectNode.isClicked = true;
						// 	console.log('clicked');

						// 	if (rectNode.audioClip) {
						// 		cc.audioEngine.stopAllEffects();
						// 		cc.director.emit('STOP_ALL_AUDIO')
						// 		cc.audioEngine.playEffect(rectNode.audioClip, false, 0.8);
						// 	}

						// 	if (animationNames.length > 0) {
						// 		dragonDisplay.playAnimation(animationNames[0], 1);
						// 	}
						// });
					}


					// animaNode.x = rectNode.x + rectNode.width / 2;
					// animaNode.y = rectNode.y + rectNode.height / 2;

					// const sx = rectNode.width / animaNode.width;
					// const sy = rectNode.height / animaNode.height;
					// const scale = Math.min(sx, sy);
					// animaNode.scale = scale;
					


			


					animaNode.y += rectNode.height / 2;
					animaNode.x += rectNode.width / 2;

					animaNode.scaleX = rectNode.width / animaNode.width;
					animaNode.scaleY = rectNode.height / animaNode.height;
		
					const opArr = actionData.changeOption	
					const tweenArr = [];
			
					for (let i = 0; i < opArr.length; i++ ) {
			
						const opData = opArr[i];
						console.log('opData: ~~~ ', opData);
		
						if (opData[0] == 'opacity') {
							animaNode.opacity = Number( opData[1] / 100 * 255 ) + 0.1;
							console.log(animaNode.opacity);
							tweenArr.push({item: animaNode , option: `{"${opData[0]}" : ${opData[2] / 100 * 255}}`, optionName: opData[2] == null ? '' : opData[0]},)
			
						}  else {
							// animaNode[opData[0]] = Number(opData[1]);
							// tweenArr.push({item: animaNode, option: `{"${opData[0]}" : ${opData[2]}}`, optionName: opData[2] == null ? '' : opData[0]})
						}
		
			
						if (actionData.audio_url) {
							cc.assetManager.loadRemote(actionData.audio_url, (err, audioClip) => {
								rectNode.audioClip = audioClip;
							});
						}
						
		
						rectNode.addComponent(cc.Button);
						rectNode.on('click', () => {
		
							if (rectNode.audioClip) {
								cc.audioEngine.stopAllEffects();
								cc.audioEngine.playEffect(rectNode.audioClip, false, 0.8);
							}
				
							if (rectNode.isClicked) {
								// return;
							}
							rectNode.isClicked = true;
		
							for (let j=0; j<tweenArr.length; j++) {
								const tweenData = tweenArr[j];
				
								console.log('tweenData: ', tweenData);

								if (tweenData.optionName) {

									cc.tween(tweenData.item)
										.to(actionData.changeTime,  JSON.parse(tweenData.option))
										.start();

								}

							}
						
							if (animationNames.length > 0) {
								dragonDisplay.playAnimation(animationNames[0], 1);
							}
				
						});
					}
		
					
				});
			});
		});

	},
	

	setOneWriteAnima(data) {

		const animaNode = this.setOneAnim(data);

		const letterH = 125;
		const rectNode = animaNode.rectNode;
		const sy = rectNode.height / letterH
		animaNode.scale = sy

		this.animaNodeArr.push(animaNode);

	},


	setOneCircleAnima(data) {

		const animaNode = this.setOneRect(data);
		// const animaNode = this.setOneAnim(data);
		const circle = this.getCircleNode(animaNode);
		animaNode.ctxCircle = circle;

		this.circleAnimaNodeArr.push(animaNode);
	},

	showCircle2(animaNode) {
		const ctxCircle = animaNode.ctxCircle;

		let a = 0;

		const showColorAnim = () => {
			if (this.isDestroy) {
				return;
			}

			a ++;
			const color = ctxCircle.strokeColor
			color.a = a;

			ctxCircle.strokeColor = color
			ctxCircle.stroke();

			if (a < 255 && !this.isDestroy) {
				delayCall(0.02, () => {
					showColorAnim();
				})
			}
		
		}
	
		showColorAnim();
		
		playAudio(this.rightClip, () => {
			
		})
	},


	setOneColorPic(data) {

		// const picNode = this.setOnePic(data);
		// picNode.data = data;
		// this.colorPicNodeArr.push(picNode);

		const animaNode = this.setOneAnim(data);
		this.colorPicNodeArr.push(animaNode);

	},

	setOnePicAnima(data) {
		const picNode = this.setOnePic(data);
		// picNode.active = false;
		picNode.opacity = 0;


		// picNode.on("touchstart", () => {
		// 	this.showLetterPic(picNode);
		// })

		picNode.data = data;
		this.picAnimNodeArr.push(picNode);

	},

	setOneSignAnima(data) {
		const animaNode = this.setOneAnim(data);

		const signW = 200;
		const signH = 200;
		const rectNode = animaNode.rectNode;
		const sx = rectNode.width / signW;
		const sy = rectNode.height / signH;
		const minS = Math.min(sx, sy);
		animaNode.scale = minS;

		this.signAnimaNodeArr.push(animaNode);
	},

	setOneAudioBtn(data) {

		const btn = this.getAudioSpr(data);
		btn.addComponent(cc.Button);
		btn.on("click", () => {

			if (!this.canTouch) {
				return;
			}
			if (data.audio_url) {

				cc.audioEngine.stopAllEffects();
				playAudioByUrl(data.audio_url);
			}
		})
	},

	getCircleNode(rectNode) {

		const data = rectNode.data;
		const circleItem = data.circleItem;
		const index = Number(circleItem - 1);
		console.log('index: ', index);
		const debugCircleData = this.data.hotZoneItemArr2[index];
		let multRect = debugCircleData?.multRect;
		if (debugCircleData?.multRect) {
			console.log("debugCircleData:", debugCircleData);
		}



		// const rectNode = animaNode.rectNode;

		console.log('rectNode: ',rectNode);

		const node = new cc.Node();
		rectNode.parent.addChild(node);
		const ctx = node.addComponent(cc.Graphics);

		let circleRW = rectNode.width / 2;
		let circleRH = rectNode.height / 2;
		let posX = rectNode.x + rectNode.width / 2;
		let posY = rectNode.y + rectNode.height / 2;

		if (multRect) {
			// circleRH = rectNode.height / 4; 
			const angle = this.getAngleByMultRect(multRect);
			node.angle = angle;
		} 
		ctx.ellipse(0, 0, circleRW, circleRH );

		const color = new cc.Color();
		cc.Color.fromHEX(color, '#007ec7')

		let strokeColor = color // cc.Color.BLACK;
		strokeColor.a = 0;
		ctx.lineWidth = 10;
		ctx.strokeColor = strokeColor;

		node.x = posX;
		node.y = posY;

		ctx.stroke();

		return ctx;
		// ctx.fill();
	},

	getAngleByMultRect(multRect) {
		const rect1 = multRect[0].rect;
		const rect2 = multRect[1].rect;
		console.log('rect1: ', rect1);
		console.log('rect2: ', rect2);

		const centerPX1 = rect1.x + rect1.width / 2;
		const centerPY1 = -(rect1.y + rect1.height / 2);
		const centerPX2 = rect2.x + rect2.width / 2;
		const centerPY2 = -(rect2.y + rect2.height / 2);

		let angle = getAngleByPos(centerPX1, centerPY1, centerPX2, centerPY2);
		// angle = 90 - angle ;
		console.log('angle: ', angle);

		return angle;
		// return angle;
	},


	getAudioSpr(data) {
		const rate = (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;

		const picNode = new cc.Node();
		picNode.name= 'pic' + data.index;
		picNode.data = data;
		this.hotZoneBg.addChild(picNode);

		const sprNode = getSprNode("btn_sound");
		sprNode.anchorX = 0;
		sprNode.anchorY = 0;

		picNode.anchorX = 0;
		picNode.anchorY = 0;

		
		picNode.addChild(sprNode);

		const scale = rate / this.hotZoneBg.scaleY;

		picNode.width = sprNode.width = data.rect.width * scale;
		picNode.height = sprNode.height = data.rect.height * scale;
		picNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
		picNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;


		return picNode;

	},

	setOneAnim(data, bg, color=null) {

		const rectNode = this.setOneRect(data, bg, color);

		const animaNode = new cc.Node();
		animaNode.name = 'anima_' + data.index;
		rectNode.addChild(animaNode);


		animaNode.x = rectNode.width / 2;
		animaNode.y = rectNode.height / 2;
	
		// if (data.audio_url) {
		// 	cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
		// 		animaNode.audioClip = audioClip;
		// 	});
		// }

		animaNode.rectNode = rectNode;

		const dragonDisplay = animaNode.addComponent(dragonBones.ArmatureDisplay);
		if (!data.texPngData) {
			return
		}

		const image = data.texPngData.url//"http://staging-teach.cdn.ireadabc.com/5a0c5af3e952acd0ac83a6e5c6f03ff1.png";
		const ske = data.skeJsonData.url//"http://staging-teach.cdn.ireadabc.com/bd825dcceea298d1146be8067ae3d17f.json";
		const atlas = data.texJsonData.url//"http://staging-teach.cdn.ireadabc.com/246f8991b729fa3e5a7f4802de828efa.json";

		cc.loader.load(image, (error, texture) => {

			cc.loader.load({ url: atlas, type: 'txt' }, (error, atlasJson) => {

				cc.loader.load({ url: ske, type: 'txt' }, (error, dragonBonesJson) => {

					const atlas = new dragonBones.DragonBonesAtlasAsset();
					atlas.atlasJson = atlasJson;
					atlas.texture = texture;

					const asset = new dragonBones.DragonBonesAsset();
					asset.dragonBonesJson = dragonBonesJson;

					dragonDisplay.dragonAtlasAsset = atlas;
					dragonDisplay.dragonAsset = asset;
					// dragonDisplay.premultipliedAlpha = true;
					// texture.setPremultiplyAlpha(true);

			
					let json = JSON.parse(asset.dragonBonesJson);
					let armatures = json["armature"];
					// console.log('armatures: ', armatures);
					let armatureNames = [];
					for (let i = 0; i < armatures.length; i++) {
						armatureNames.push(armatures[i].name);
					}
					// console.log('armatureNames: ', armatureNames);
					if (armatureNames.length > 0) {
						let defaultArmatureName = armatureNames[0];
						dragonDisplay.armatureName = defaultArmatureName;
						// let animationNames = dragonDisplay.getAnimationNames(defaultArmatureName);
						let defaultArmature = armatures[0];
						let animations = defaultArmature.animation;
						let animationNames = [];
						for (let i = 0; i < animations.length; i++) {
							animationNames.push(animations[i].name);
						}

						animaNode.animationNames = animationNames;
						animaNode.dragonDisplay = dragonDisplay;


						// rectNode.addComponent(cc.Button);
						// rectNode.on('click', () => {
						// 	if (rectNode.isClicked) {
						// 		// return;
						// 	}
						// 	rectNode.isClicked = true;
						// 	console.log('clicked');

						// 	// if (animaNode.audioClip) {
						// 	// 	cc.audioEngine.stopAllEffects();
						// 	// 	cc.director.emit('STOP_ALL_AUDIO')
						// 	// 	cc.audioEngine.playEffect(animaNode.audioClip, false, 0.8);
						// 	// }

						// 	// if (animationNames.length > 0) {
						// 	// 	dragonDisplay.playAnimation(animationNames[0], 1);
						// 	// }

						// 	// animaNode.playAnim();

						// });
					}

					animaNode.playAnim = () => {
						const animationNames = animaNode.animationNames;
						if (animationNames.length > 0) {
							dragonDisplay.timeScale = 1;
							dragonDisplay.playAnimation(animationNames[0], -1);
						}
					}

					animaNode.stopAnim = () => {
						const animationNames = animaNode.animationNames;
						if (animationNames.length > 0) {
							dragonDisplay.playAnimation(animationNames[0], 1);
							dragonDisplay.timeScale = 10000;
						}
					}


					// animaNode.x = rectNode.x + rectNode.width / 2;
					// animaNode.y = rectNode.y + rectNode.height / 2;

					// const sx = rectNode.width / animaNode.width;
					// const sy = rectNode.height / animaNode.height;
					// const scale = Math.min(sx, sy);

					// animaNode.opacity = 0;

				});
			});
		});

		animaNode.data = data;
		return animaNode;

	},

	playRightAnim(animaNode) {
		const animationNames = animaNode.animationNames;
		const dragonDisplay = animaNode.dragonDisplay;

		animaNode.active = true;
		animaNode.opacity = 255;
		// animaNode.opacity = 255;
		if (dragonDisplay && animationNames && animationNames.length > 0) {
			dragonDisplay.playAnimation(animationNames[0], 1);
		}

		playAudio(this.rightClip, () => {
			
		})
	},

	setOneHotZonePic(data) {
		const rate = (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;

		const picNode = new cc.Node();
		picNode.name= 'pic' + data.index;
		picNode.data = data;
		this.hotZoneBg.addChild(picNode);

		this.picNodeArr.push(picNode);
		picNode.hitCount = 0;

		cc.loader.load({url: data.pic_url}, (err, img) => {

			const spr = picNode.addComponent(cc.Sprite);
			spr.spriteFrame = new cc.SpriteFrame(img)

			const scale = rate / this.hotZoneBg.scaleY;

			picNode.width = data.rect.width * scale;
			picNode.height = data.rect.height * scale;
			picNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
			picNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;

			picNode.x += picNode.width / 2 * picNode.scaleX;
			picNode.y += picNode.height / 2 * picNode.scaleX;


			getSprNodeByUrl(data.answer_pic_url, (spr) => {

				const sprNode = spr.node;
				sprNode.active = false;
				picNode.addChild(sprNode);
				picNode.answerPic = sprNode;

				picNode.isLoadEnd = true;
				// this.checkStart();
			})

			// picNode.anchorX = picNode.anchorY = 0;

			// if (data.audio_url) {
			// 	this.addPicAudio(picNode);
			// }

			// this.addDragPoint(picNode, data)

		});

	},

	addDragPoint(picNode, data) {


		picNode.baseX = picNode.x;
		picNode.baseY = picNode.y;

		const realRate = this.hotZoneBg.width / this.data.bgItem.rect.width;
		picNode.targetPx = -this.hotZoneBg.width / 2 + ( data.dragDot.x - this.data.bgItem.rect.x ) * realRate;
		picNode.targetPy = this.hotZoneBg.height / 2 - (data.dragDot.y - this.data.bgItem.rect.y) * realRate;


		if (data.audio_url) {
			cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
				picNode.audioClip = audioClip;
			});
		}


		picNode.on(cc.Node.EventType.TOUCH_START, () => {
			if (picNode.isDragEnd) {
				if (picNode.audioClip) {
					cc.audioEngine.stopAllEffects();
					cc.audioEngine.playEffect(picNode.audioClip, false, 0.8);
				}
				return;
			}
			this._curShowItem = picNode;

			// picNode.x = -this.hotZoneBg.width / 2 + ( data.dragDot.x - this.data.bgItem.rect.x ) * realRate;
			// picNode.y = this.hotZoneBg.height / 2 - (data.dragDot.y - this.data.bgItem.rect.y) * realRate;

		})
	},


	setOnePic(data) {
		const rate = (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;

		const picNode = new cc.Node();
		picNode.name= 'pic' + data.index;
		picNode.data = data;
		this.hotZoneBg.addChild(picNode);

		getSprNodeByUrl(data.pic_url, (spr) => {

			const sprNode = spr.node;
			picNode.addChild(sprNode);

			const scale = rate / this.hotZoneBg.scaleY;

			picNode.width = sprNode.width = data.rect.width * scale;
			picNode.height = sprNode.height = data.rect.height * scale;
			picNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
			picNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;

			sprNode.anchorX = sprNode.anchorY = 0;
			picNode.anchorX = picNode.anchorY = 0;


			picNode.sprNode = sprNode;
		})

		return picNode;

		// cc.loader.load({url: data.pic_url}, (err, img) => {

		// 	const spr = picNode.addComponent(cc.Sprite);
		// 	spr.spriteFrame = new cc.SpriteFrame(img)

		// 	const scale = rate / this.hotZoneBg.scaleY;

		// 	picNode.width = data.rect.width * scale;
		// 	picNode.height = data.rect.height * scale;
		// 	picNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
		// 	picNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;

		// 	picNode.anchorX = picNode.anchorY = 0;

		// 	// if (data.audio_url) {
		// 	// 	this.addPicAudio(picNode);
		// 	// }

		// });

		// picNode.on('touchstart', () => {
		// 	this.show
		// })

	},


	addPicAudio(picNode) {
		const data = picNode.data;
		
		cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
			picNode.audioClip = audioClip;
		});

		picNode.addComponent(cc.Button);
		picNode.on('click', () => {
				
				if (picNode.audioClip) {
					cc.audioEngine.stopAllEffects();
					cc.audioEngine.playEffect(picNode.audioClip, false, 0.8);
				}
		});
	},


	initListener() {

		const canvas = cc.find('Canvas');
		// const canvas = this.hotZoneBg;
		
		let downFlag = false;

		// const touchStart = (e) => {
		// 	downFlag = true;
		// 	this.canvasTouchStart(e);
		// 	if (canvas.hasEventListener(cc.Node.EventType.MOUSE_DOWN)) {
		// 		canvas.off(cc.Node.EventType.MOUSE_DOWN, mouseDown)
		// 	}
		// }

		// const mouseDown = (e) => {
		// 	downFlag = true;
		// 	this.canvasTouchStart(e);
		// 	if (canvas.hasEventListener(cc.Node.EventType.TOUCH_START)) {
		// 		canvas.off(cc.Node.EventType.TOUCH_START, touchStart)
		// 		this.removeHtmlCanvasListener('touchstart');
		// 	}
		// }

		const touchMove = (e) => {
			// if (!downFlag) {
			// 	return;
			// }
			this.canvasTouchMove(e);
			if (canvas.hasEventListener(cc.Node.EventType.MOUSE_MOVE)) {
				canvas.off(cc.Node.EventType.MOUSE_MOVE, mouseMove)
			}
		}

		const mouseMove = (e) => {
			// if (!downFlag) {
			// 	return;
			// }
			this.canvasTouchMove(e);
			if (canvas.hasEventListener(cc.Node.EventType.TOUCH_MOVE)) {
				canvas.off(cc.Node.EventType.TOUCH_MOVE, touchMove)
				this.removeHtmlCanvasListener('touchmove');
			}
		}

		const touchEnd = (e) => {
		
			downFlag = false;
			this.canvasTouchEnd(e);

			if (canvas.hasEventListener(cc.Node.EventType.MOUSE_UP)) {
				canvas.off(cc.Node.EventType.MOUSE_UP, mouseUp)
			}
			if (canvas.hasEventListener(cc.Node.EventType.MOUSE_LEAVE)) {
				canvas.off(cc.Node.EventType.MOUSE_LEAVE, mouseUp)
			}
			this.removeHtmlTouchEnd();
		}

		const mouseUp = (e) => {
	
			downFlag = false;

			this.canvasTouchEnd(e);

			if (canvas.hasEventListener(cc.Node.EventType.TOUCH_END)) {
				canvas.off(cc.Node.EventType.TOUCH_END, touchEnd)
			}
			if (canvas.hasEventListener(cc.Node.EventType.TOUCH_CANCEL)) {
				canvas.off(cc.Node.EventType.TOUCH_CANCEL, touchEnd)
			}
		}
		

		// canvas.on(cc.Node.EventType.TOUCH_START, touchStart)
		// canvas.on(cc.Node.EventType.MOUSE_DOWN, mouseDown);

		canvas.on(cc.Node.EventType.TOUCH_MOVE, touchMove)
		canvas.on(cc.Node.EventType.MOUSE_MOVE, mouseMove)

		canvas.on(cc.Node.EventType.TOUCH_END, touchEnd)
		canvas.on(cc.Node.EventType.TOUCH_CANCEL, touchEnd)
		canvas.on(cc.Node.EventType.MOUSE_UP, mouseUp)

	},

	removeHtmlCanvasListener(type) {
		const canvasHtml = document.querySelector('canvas');
		canvasHtml.addEventListener(type, (e) => {})
	},	
	removeHtmlTouchEnd() {
		const canvasHtml = document.querySelector('canvas');
		canvasHtml.removeEventListener('touchend', this.htmlCanvasTouchendFunc, this);
	},


	canvasTouchStart(e) {
		const pos = e.getLocation();
		console.log('~pos: ', pos);

		// if (!this._curShowItem) {
		// 	return;
		// }
		// const pos = e.getLocation();
		// this._curShowItem.x = pos.x - e.currentTarget.width / 2;
		// this._curShowItem.y = pos.y - e.currentTarget.height / 2;

		// // console.log('pos: ', pos.x);
	},

	canvasTouchMove(e) {

		if (!this._curClickItem) {
			return;
		}
		const pos = e.getLocation();

		const localPos =  this._curClickItem.parent.convertToNodeSpaceAR(pos);

		this._curClickItem.x = localPos.x;
		this._curClickItem.y = localPos.y;

		// console.log('pos: ', pos.x);
	},

	canvasTouchEnd(e) {

		if (!this._curClickItem) {
			return;
		}
		this.checkOnDragEndRect();
		this._curClickItem.zIndex = this._curClickItem.oldZ;
		this._curClickItem = null;
	},



	checkOnDragEndRect() {

		console.log('dragEndArr: ',  this.dragEndArr);
		for (let i = 0; i < this.dragEndArr.length; i++) {

			const rect = this.dragEndArr[i];

			const worldPos = this._curClickItem.parent.convertToWorldSpaceAR(cc.v2(this._curClickItem.x, this._curClickItem.y));
			const worldRect = rect.getBoundingBoxToWorld();
			if (worldRect.contains(worldPos)) {
			
				// const isRightPut = 
				console.log('this._curClickItem: ', this._curClickItem);
				console.log('rect in ', rect);
				// this.checkIsDragEndTarget(rect, worldRect);

				this.tryPutDragItem(this._curClickItem, rect);

				// if (this._curClickItem.dragId != rect.dragId) {
				// 	this.itemBack();
				// 	return;
				// }
	
				// this.showDragBgRight(this._curClickItem);
				// this.showDragPicRight(rect);

				// this._curClickItem.data.dragEndRect = rect;

				// this._curClickItem.x = rect.x;
				// this._curClickItem.y = rect.y;
				// this._curClickItem.parent = rect.parent;
				// this._curClickItem.isDragEnd = true;
				// this._curClickItem.zIndex = 20;


				return;
			}
			
		}

		this.itemBack();
	},

	tryPutDragItem(dragStartItem, dragEndItem) {
		if (dragStartItem.dragId != dragEndItem.dragId) {
			this.itemBack();
			return;
		}

		this.showDragBgRight(dragStartItem);
		this.showDragPicRight(dragEndItem);

		dragEndItem.data.isDragEnd = true;
		dragStartItem.data.isDragEnd = true;

		dragStartItem.x = dragEndItem.x;
		dragStartItem.y = dragEndItem.y;
		dragStartItem.parent = dragEndItem.parent;
		dragStartItem.isDragEnd = true;
		dragStartItem.zIndex = 20;
	},


	showDragBgRight(bgItem) {
		console.log('bgItem: ', bgItem);

		bgItem.picNormal.active = false;
		bgItem.picRight.active = true;
	},

	showDragPicRight(picItem) {
		console.log('picItem: ', picItem);

		picItem.picNormal.active = false;
		picItem.picRight.active = true;
	},



	itemBack() {

		// cc.audioEngine.playEffect(this.wrongClip, false, 0.8);

		cc.tween(this._curClickItem)
			.to(0.5, {x: this._curClickItem.baseX, y: this._curClickItem.baseY}, {easing: "elasticOut"})
			.start();
	},

	checkIsDragEndTarget(rect, targetWorldRect) {

		const targetX = targetWorldRect.x + targetWorldRect.width / 2;
		const targetY = targetWolrdRect.y + targetWorldRect.height / 2;

		const worldPos = this._curClickItem.parent.convertToWorldSpaceAR(cc.v2(targetX, targetY));
		const worldRect = rect.getBoundingBoxToWorld();
		if (worldRect.contains(worldPos)) {
			this._curClickItem.x = this._curClickItem.targetPx;
			this._curClickItem.y = this._curClickItem.targetPy;
			this._curClickItem.isDragEnd = true;

			// cc.audioEngine.playEffect(this.rightClip, false, 0.8);

		} else {
			this.itemBack();
		}
	},


	onDestroy() {
		this.isDestroy = true;
		this.stopHelper(); // 停止计时器
	},


});
