<commit_before>/*
** Module: aireas2json
**
**
**
**
*/

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

var fs 		= require('fs');

var aireasFolder, aireasUrl, aireasFileName, aireasLocalPathRoot, fileFolder,
	tmpFolder, tmpFolderName, localPath, fileFolderName, resultsFolder, resultsFolderName;
var dataRecords;

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

module.exports = {

	init: function (options) {
		aireasLocalPathRoot = options.systemFolderParent+'/aireas/';
		fileFolderName 		= 'aireas';
		tmpFolderName 		= 'tmp';
		resultsFolderName 	= 'results';

		aireasFileName 		= 'aireas.txt';
		aireasFileNameOutput= 'aireas.json';

		aireasFolder 		= aireasLocalPathRoot 	+ fileFolderName 	+ "/";
		tmpFolder 			= aireasFolder 			+ tmpFolderName 	+ "/";
		resultsFolder 		= aireasFolder 			+ resultsFolderName + "/";

		// create subfolders
		try {fs.mkdirSync(resultsFolder );} catch (e) {};//console.log('ERROR: no tmp folder found, batch run aborted.'); return } ;

	    localPath 		= tmpFolder + aireasFileName;
    	var _datFile	= fs.readFileSync(localPath);
    	console.log("Local AiREAS data: " + localPath );

		var i, j, _dataRecord, _waardeDataRecord, inpRecordArray,
			inpRecordPM1, inpRecordPM25, inpRecordPM10,
			inpRecordUFP, inpRecordOZON, inpRecordHUM, inpRecordCELC;

		var inRecord1 = _datFile.replace(/\'/,'"');
		var inRecord = JSON.parse(_datFile);
		console.log(inRecord);
		console.log(inRecord.airboxes);
		console.log(inRecord.airboxes[0]);

		tmpArray = inRecord.airboxes[0];

/*
		var tmp0 = _datFile.toString();
		var dateRetrievedLength = tmp0.indexOf(' ');
		var dateRetrieved = tmp0.substring(0, dateRetrievedLength);
		var dateRetrievedDate = Date.parse(dateRetrieved);
		console.log('x'+dateRetrieved+'x');
		var tmp1 = tmp0.substr(dateRetrievedLength+1);
		//var tmp2 = tmp1.replace(/<p>/g,'');
		//var tmp3 = tmp2.replace(/<\/p>/g,'');
		//var tmpArray = tmp3.split(')');
		var tmp2 = tmp1.replace(/\[/,'');
		var tmpArray = tmp3.split('],');
*/

		dataRecords	= [];

		for(i=0;i<tmpArray.length-1;i++) {

//			inpRecordArray 		= tmpArray[i].split(':(');
			inpRecordArray 		= tmpArray[i].split('[');

			_dataRecord			= {};
//			_dataRecord.airBox	= inpRecordArray[0];

			inpMetingenArray 	= inpRecordArray[1].split(',');

			_waardeDataRecord 	= [];
			for(j=0;j<inpMetingenArray.length;j++) {
				_waardeDataRecord[j] = inpMetingenArray[j];// parseFloat(inpMetingenArray[j]);
			}

			_dataRecord.airbox 	= _waardeDataRecord[0];
			_dataRecord.retrievedDate 	= dateRetrieved;
			_dataRecord.measureDate 	= _waardeDataRecord[1];
			_dataRecord.gpsLat 	= _waardeDataRecord[10];
			_dataRecord.gpsLng 	= _waardeDataRecord[11];
			_dataRecord.lat 	= this.convertGPS2LatLng(_waardeDataRecord[10]);
			_dataRecord.lng 	= this.convertGPS2LatLng(_waardeDataRecord[11]);
			_dataRecord.PM1 	= _waardeDataRecord[2];
			_dataRecord.PM25 	= _waardeDataRecord[3];
			_dataRecord.PM10 	= _waardeDataRecord[4];
			_dataRecord.UFP 	= _waardeDataRecord[5];
			_dataRecord.OZON 	= _waardeDataRecord[6];
			_dataRecord.HUM 	= _waardeDataRecord[7];
			_dataRecord.CELC 	= _waardeDataRecord[8];
			_dataRecord.NO2 	= _waardeDataRecord[9];

			_dataRecord.gpsLatFloat = parseFloat(_waardeDataRecord[10]);
			_dataRecord.gpsLngFloat	= parseFloat(_waardeDataRecord[11]);
			_dataRecord.PM1Float 	= parseFloat(_waardeDataRecord[2]);
			_dataRecord.PM25Float 	= parseFloat(_waardeDataRecord[3]);
			_dataRecord.PM10Float 	= parseFloat(_waardeDataRecord[4]);
			_dataRecord.UFPFloat 	= parseFloat(_waardeDataRecord[5]);
			_dataRecord.OZONFloat 	= parseFloat(_waardeDataRecord[6]);
			_dataRecord.HUMFloat 	= parseFloat(_waardeDataRecord[7]);
			_dataRecord.CELCFloat 	= parseFloat(_waardeDataRecord[8]);
			_dataRecord.NO2		 	= parseFloat(_waardeDataRecord[9]);

			dataRecords.push(_dataRecord);

		}

		this.createExportFile();

	}, // end of init

	createExportFile: function () {
		var outputArray;
		var outputRecord;
		var inputRecord;
		var filePath;
		var outputFileJson;

		var currDate = new Date();
		var year = (currDate.getYear()+1900);

		var month = (currDate.getMonth()+1);
		var monthStr = "";
		if (month<10) {
			monthStr = "0" + month;
		} else {
			monthStr = "" + month;
		}

		var day = currDate.getDate();
		var dayStr = "";
		if (day<10) {
			dayStr = "0" + day;
		} else {
			dayStr = "" + day;
		}

		var hour = currDate.getHours();
		var hourStr = "";
		if (hour<10) {
			hourStr = "0" + hour;
		} else {
			hourStr = "" + hour;
		}

		var minute = currDate.getMinutes();
		var minuteStr = "";
		if (minute<10) {
			minuteStr = "0" + minute;
		} else {
			minuteStr = "" + minute;
		}

		filePath = resultsFolder + year + "/" + monthStr + "/" + dayStr + "/" + hourStr + "/" + minuteStr;

		try {fs.mkdirSync(resultsFolder + year + "/" );} catch (e) {} ;
		try {fs.mkdirSync(resultsFolder + year + "/" + monthStr + "/");} catch (e) {} ;
		try {fs.mkdirSync(resultsFolder + year + "/" + monthStr + "/" + dayStr + "/" );} catch (e) {} ;
		try {fs.mkdirSync(resultsFolder + year + "/" + monthStr + "/" + dayStr + "/"  + hourStr + "/");} catch (e) {} ;
		try {fs.mkdirSync(resultsFolder + year + "/" + monthStr + "/" + dayStr + "/" + hourStr + "/" + minuteStr);} catch (e) {} ;

		console.log("- creating: " , aireasFileNameOutput);
		outputFileJson = JSON.stringify(dataRecords);
		this.writeFile (filePath, aireasFileNameOutput, outputFileJson );

	},

	convertGPS2LatLng: function(gpsValue){
		var degrees = Math.floor(gpsValue /100);
		var minutes = gpsValue - (degrees*100);
		var result  = degrees + (minutes /60);
		return result;
	},

	writeFile: function(path, fileName, content ) {
		var _path = path;
		try {
			fs.mkdirSync(_path);
		} catch (e) {} ;
		fs.writeFileSync(_path + "/" + fileName, content);
	}

} // end of module.exports
<commit_msg>new record layout csv<commit_after>/*
** Module: aireas2json
**
**
**
**
*/

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

var fs 		= require('fs');

var aireasFolder, aireasUrl, aireasFileName, aireasLocalPathRoot, fileFolder,
	tmpFolder, tmpFolderName, localPath, fileFolderName, resultsFolder, resultsFolderName;
var dataRecords;

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

module.exports = {

	init: function (options) {
		aireasLocalPathRoot = options.systemFolderParent+'/aireas/';
		fileFolderName 		= 'aireas';
		tmpFolderName 		= 'tmp';
		resultsFolderName 	= 'results';

		aireasFileName 		= 'aireas.txt';
		aireasFileNameOutput= 'aireas.json';

		aireasFolder 		= aireasLocalPathRoot 	+ fileFolderName 	+ "/";
		tmpFolder 			= aireasFolder 			+ tmpFolderName 	+ "/";
		resultsFolder 		= aireasFolder 			+ resultsFolderName + "/";

		// create subfolders
		try {fs.mkdirSync(resultsFolder );} catch (e) {};//console.log('ERROR: no tmp folder found, batch run aborted.'); return } ;

	    localPath 		= tmpFolder + aireasFileName;
    	var _datFile	= fs.readFileSync(localPath);
    	console.log("Local AiREAS data: " + localPath );

		var i, j, _dataRecord, _waardeDataRecord, inpRecordArray,
			inpRecordPM1, inpRecordPM25, inpRecordPM10,
			inpRecordUFP, inpRecordOZON, inpRecordHUM, inpRecordCELC;

		var inRecord1 = "" + _datFile.toString();
		var inRecord2 = inRecord1.replace(/\'/,'"');
		var inRecord = JSON.parse(inRecord2);
		console.log(inRecord);
		console.log(inRecord.airboxes);
		console.log(inRecord.airboxes[0]);

		tmpArray = inRecord.airboxes[0];

/*
		var tmp0 = _datFile.toString();
		var dateRetrievedLength = tmp0.indexOf(' ');
		var dateRetrieved = tmp0.substring(0, dateRetrievedLength);
		var dateRetrievedDate = Date.parse(dateRetrieved);
		console.log('x'+dateRetrieved+'x');
		var tmp1 = tmp0.substr(dateRetrievedLength+1);
		//var tmp2 = tmp1.replace(/<p>/g,'');
		//var tmp3 = tmp2.replace(/<\/p>/g,'');
		//var tmpArray = tmp3.split(')');
		var tmp2 = tmp1.replace(/\[/,'');
		var tmpArray = tmp3.split('],');
*/

		dataRecords	= [];

		for(i=0;i<tmpArray.length-1;i++) {

//			inpRecordArray 		= tmpArray[i].split(':(');
			inpRecordArray 		= tmpArray[i].split('[');

			_dataRecord			= {};
//			_dataRecord.airBox	= inpRecordArray[0];

			inpMetingenArray 	= inpRecordArray[1].split(',');

			_waardeDataRecord 	= [];
			for(j=0;j<inpMetingenArray.length;j++) {
				_waardeDataRecord[j] = inpMetingenArray[j];// parseFloat(inpMetingenArray[j]);
			}

			_dataRecord.airbox 	= _waardeDataRecord[0];
			_dataRecord.retrievedDate 	= dateRetrieved;
			_dataRecord.measureDate 	= _waardeDataRecord[1];
			_dataRecord.gpsLat 	= _waardeDataRecord[10];
			_dataRecord.gpsLng 	= _waardeDataRecord[11];
			_dataRecord.lat 	= this.convertGPS2LatLng(_waardeDataRecord[10]);
			_dataRecord.lng 	= this.convertGPS2LatLng(_waardeDataRecord[11]);
			_dataRecord.PM1 	= _waardeDataRecord[2];
			_dataRecord.PM25 	= _waardeDataRecord[3];
			_dataRecord.PM10 	= _waardeDataRecord[4];
			_dataRecord.UFP 	= _waardeDataRecord[5];
			_dataRecord.OZON 	= _waardeDataRecord[6];
			_dataRecord.HUM 	= _waardeDataRecord[7];
			_dataRecord.CELC 	= _waardeDataRecord[8];
			_dataRecord.NO2 	= _waardeDataRecord[9];

			_dataRecord.gpsLatFloat = parseFloat(_waardeDataRecord[10]);
			_dataRecord.gpsLngFloat	= parseFloat(_waardeDataRecord[11]);
			_dataRecord.PM1Float 	= parseFloat(_waardeDataRecord[2]);
			_dataRecord.PM25Float 	= parseFloat(_waardeDataRecord[3]);
			_dataRecord.PM10Float 	= parseFloat(_waardeDataRecord[4]);
			_dataRecord.UFPFloat 	= parseFloat(_waardeDataRecord[5]);
			_dataRecord.OZONFloat 	= parseFloat(_waardeDataRecord[6]);
			_dataRecord.HUMFloat 	= parseFloat(_waardeDataRecord[7]);
			_dataRecord.CELCFloat 	= parseFloat(_waardeDataRecord[8]);
			_dataRecord.NO2		 	= parseFloat(_waardeDataRecord[9]);

			dataRecords.push(_dataRecord);

		}

		this.createExportFile();

	}, // end of init

	createExportFile: function () {
		var outputArray;
		var outputRecord;
		var inputRecord;
		var filePath;
		var outputFileJson;

		var currDate = new Date();
		var year = (currDate.getYear()+1900);

		var month = (currDate.getMonth()+1);
		var monthStr = "";
		if (month<10) {
			monthStr = "0" + month;
		} else {
			monthStr = "" + month;
		}

		var day = currDate.getDate();
		var dayStr = "";
		if (day<10) {
			dayStr = "0" + day;
		} else {
			dayStr = "" + day;
		}

		var hour = currDate.getHours();
		var hourStr = "";
		if (hour<10) {
			hourStr = "0" + hour;
		} else {
			hourStr = "" + hour;
		}

		var minute = currDate.getMinutes();
		var minuteStr = "";
		if (minute<10) {
			minuteStr = "0" + minute;
		} else {
			minuteStr = "" + minute;
		}

		filePath = resultsFolder + year + "/" + monthStr + "/" + dayStr + "/" + hourStr + "/" + minuteStr;

		try {fs.mkdirSync(resultsFolder + year + "/" );} catch (e) {} ;
		try {fs.mkdirSync(resultsFolder + year + "/" + monthStr + "/");} catch (e) {} ;
		try {fs.mkdirSync(resultsFolder + year + "/" + monthStr + "/" + dayStr + "/" );} catch (e) {} ;
		try {fs.mkdirSync(resultsFolder + year + "/" + monthStr + "/" + dayStr + "/"  + hourStr + "/");} catch (e) {} ;
		try {fs.mkdirSync(resultsFolder + year + "/" + monthStr + "/" + dayStr + "/" + hourStr + "/" + minuteStr);} catch (e) {} ;

		console.log("- creating: " , aireasFileNameOutput);
		outputFileJson = JSON.stringify(dataRecords);
		this.writeFile (filePath, aireasFileNameOutput, outputFileJson );

	},

	convertGPS2LatLng: function(gpsValue){
		var degrees = Math.floor(gpsValue /100);
		var minutes = gpsValue - (degrees*100);
		var result  = degrees + (minutes /60);
		return result;
	},

	writeFile: function(path, fileName, content ) {
		var _path = path;
		try {
			fs.mkdirSync(_path);
		} catch (e) {} ;
		fs.writeFileSync(_path + "/" + fileName, content);
	}

} // end of module.exports
<|endoftext|>


<commit_before>/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var xmlParser=new DOMParser();
var xmlDoc;
var elements=[];
var blocks=[];
var blockNames=[];

//init function for initializing the Blockly block area
function init(){
	var x=Blockly.inject('blocklyDiv', {
		toolbox: document.getElementById('startBlocks'),
        collapse: true
	});
}

//reads the file
function readFile(evt){
	var file=evt.target.files[0];
	var reader=new FileReader();
	reader.readAsText(file);
	reader.onload=function(e){
		console.log(e.target.result);
		xmlDoc=xmlParser.parseFromString(e.target.result,"text/xml");
		handleXML();
	}
}

//handles xml by creating blocks as per RNG rules
function handleXML(){
	var root=xmlDoc.documentElement;
	var a;

	removeRedundantText(root);

	//get all the define blocks in the document and create blocks for them one by one.
	var defineNodes=xmlDoc.getElementsByTagName("define");
	for(var i=0;i<defineNodes.length;i++){
		//fixed color - 295 for define blocks for now.
		createBlocks(defineNodes[i],defineNodes[i].getAttribute("name"), 295);
	}

	root=xmlDoc.getElementsByTagName("start")[0];

	var colour=0;
	createBlocks(root,"start",colour);

	var script=document.createElement('script');
	script.type="text/javascript";
	for(var i=0;i<blocks.length;i++){
		var resultsData=document.getElementById("results");
		resultsData.innerHTML=resultsData.innerHTML+"
"+blocks[i]+"
"
		script.text+=blocks[i];

		var blocklyXml=document.getElementById('startBlocks');
		console.log(blockNames[i]);
		blocklyXml.innerHTML=blocklyXml.innerHTML+"<block type='"+blockNames[i]+"'></block>";
	}
	document.getElementsByTagName("head")[0].appendChild(script);

	init();
}

//Removes #text nodes
function removeRedundantText(node){
	var children=node.childNodes;
	for(var i=0;i<children.length;i++){
		if(children[i].nodeName=="#text"){
			//console.log("found text");
			children[i].parentNode.removeChild(children[i]);
			i--;
			continue;
		}else{
			removeRedundantText(children[i]);
		}
	}
}

//The name for every child block is sent to it by its parent. The child does not need to find its place in the hierarchy. The parent node does it for all of its children and sends them their name while calling them.
function createBlocks(node, name, colour){
	var children=node.childNodes;
	var blockData="";	//Contains data sent by all the children merged together one after the other.
	var childData=[];	//Keeps track of block data sent by children.
	var childNames=[];	//Keeps track of children block names

	for(var i=0;i<children.length;i++){

		if(children[i].nodeName=="text" || children[i].nodeName=="data"){
			continue;
		}

		if(children[i].nodeName=="#comment"){
			continue;
		}

		var nameAttr=children[i].getAttribute("name");

		if(nameAttr==null){
			nameAttr=children[i].nodeName;
		}

		nameAttr=nameAttr.substring(0,3);

		//The name for the child is given as <parent name/hierarchy>+<first 3 characters of the child element>+<index of the child as per its parent block>.
		var nameForChild=name+":"+nameAttr+i;

		var dataReceivedFromChild=createBlocks(children[i], nameForChild, colour+45);
		blockData+=dataReceivedFromChild;
		childData.push(dataReceivedFromChild);
		childNames.push("block_"+nameForChild);
	}

	var nodeType=node.nodeName;

	/*
	//could be used to handle datatypes efficiently. But causes multiple element siblings to behave as inline inputs

	if(nodeType=="text"){
		var data="this.appendDummyInput().appendField(new Blockly.FieldTextInput(''),'"+name+"');this.setInputsInline(true);";
		return data;
	}

	else if(nodeType=="element" || nodeType=="attribute"){
		var data="this.appendDummyInput().appendField('"+name+"');";
		blockData=data+blockData;
	}
	*/

	if(nodeType=="element"){
		if(children.length==1 && children[0].nodeName=="text"){
			//data contains data that the current tag will generate.
			var data="this.appendDummyInput().appendField('"+name+"').appendField(new Blockly.FieldTextInput(''),'"+name+"');";
			blockData=data+blockData;
		}else{
			var data="this.appendDummyInput().appendField('"+name+"');";
			blockData=data+blockData;
		}
	}

	//attributes do not check the level below them as there is no functionality currently to handle datatypes and parameters. At the attribute node, a dummy input which has a label and an input field is generated.
	else if(nodeType=="attribute"){
		var data="this.appendDummyInput().appendField('"+name+"').appendField(new Blockly.FieldTextInput(''),'"+name+"');";
		return data;
	}

	else if(nodeType=="start"){
		var blockName="block_"+name;
		var finalBlock="Blockly.Blocks['"+blockName+"']={init:function(){this.appendDummyInput().appendField('"+name+"');"+blockData+"this.setColour("+colour+");}};";
		blocks.push(finalBlock);
		blockNames.push(blockName);
		return;
	}

	else if(nodeType=="oneOrMore"){
		var childNamesInFormat="'"+childNames.join("','")+"'";

		//Every oneOrMore child has sent in its data. This loop just creates blocks for each child of the oneOrMore tag.
		for(var i=0;i<childData.length;i++){
			var blockName=childNames[i];

			var finalBlock="Blockly.Blocks['"+blockName+"']={init:function(){"+childData[i]+"this.setPreviousStatement(true,["+childNamesInFormat+"]);this.setNextStatement(true,["+childNamesInFormat+"]);this.setColour("+colour+");}};";
			blocks.push(finalBlock);
			blockNames.push(blockName);
		}

		//console.log("blockly name", node.getAttribute("blockly:name"));
		//This appends to the block which contains the oneOrMore tag and creates a notch there.
		blockData="this.appendStatementInput('"+name+"').setCheck(["+childNamesInFormat+"]).appendField('"+name+"');";
	}

	//for choice nodes, we ensure that only one option is selected by keeping no option for setNextStatement for its children.
	else if(nodeType=="choice"){
		var childNamesInFormat="'"+childNames.join("','")+"'";
		//Every choice child has sent in its data. This loop just creates blocks for each child of the oneOrMore tag.
		for(var i=0;i<childData.length;i++){
			var blockName=childNames[i];

			var finalBlock="Blockly.Blocks['"+blockName+"']={init:function(){"+childData[i]+"this.setPreviousStatement(true);this.setColour("+colour+");}};";
			blocks.push(finalBlock);
			blockNames.push(blockName);
		}

		//This appends to the block which contains the choice tag and creates a notch there.
		blockData="this.appendStatementInput('"+name+"').setCheck(["+childNamesInFormat+"]).appendField('"+name+"');";
	}

	//creates define blocks. The define block that is created inly has a notch above and never below. It is the ref code which changes according to whether or not the ref code is in a choice or oneOrMore block.
	else if(nodeType=="define"){
		var blockName="block_"+name;
		var finalBlock="Blockly.Blocks['"+blockName+"']={init:function(){this.appendDummyInput().appendField('"+name+"');this.setColour("+colour+");"+blockData+"this.setPreviousStatement(true);}};";
		blocks.push(finalBlock);
		blockNames.push(blockName);
		return;
	}

	//the ref block will have a notch above or below or both according to its parent element. The notch is added to it according to the code written to handle choice and oneOrMore elements.
	else if(nodeType="ref"){
		var correspondingDefineName=node.getAttribute("name");
		var data="this.appendStatementInput('"+name+"').appendField('"+name+"').setCheck('block_"+correspondingDefineName+"');";
		return data;
	}

	//returns block data to the parent node that had called it
	return blockData;
}

//Adds an event listener for detecting whether the user has provided a file as input or not.
document.getElementById("file").addEventListener('change',readFile);<commit_msg>Added a comment about "#text" nodes<commit_after>/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var xmlParser=new DOMParser();
var xmlDoc;
var elements=[];
var blocks=[];
var blockNames=[];

//init function for initializing the Blockly block area
function init(){
	var x=Blockly.inject('blocklyDiv', {
		toolbox: document.getElementById('startBlocks'),
        collapse: true
	});
}

//reads the file
function readFile(evt){
	var file=evt.target.files[0];
	var reader=new FileReader();
	reader.readAsText(file);
	reader.onload=function(e){
		console.log(e.target.result);
		xmlDoc=xmlParser.parseFromString(e.target.result,"text/xml");
		handleXML();
	}
}

//handles xml by creating blocks as per RNG rules
function handleXML(){
	var root=xmlDoc.documentElement;
	var a;

	removeRedundantText(root);

	//get all the define blocks in the document and create blocks for them one by one.
	var defineNodes=xmlDoc.getElementsByTagName("define");
	for(var i=0;i<defineNodes.length;i++){
		//fixed color - 295 for define blocks for now.
		createBlocks(defineNodes[i],defineNodes[i].getAttribute("name"), 295);
	}

	root=xmlDoc.getElementsByTagName("start")[0];

	var colour=0;
	createBlocks(root,"start",colour);

	var script=document.createElement('script');
	script.type="text/javascript";
	for(var i=0;i<blocks.length;i++){
		var resultsData=document.getElementById("results");
		resultsData.innerHTML=resultsData.innerHTML+"
"+blocks[i]+"
"
		script.text+=blocks[i];

		var blocklyXml=document.getElementById('startBlocks');
		console.log(blockNames[i]);
		blocklyXml.innerHTML=blocklyXml.innerHTML+"<block type='"+blockNames[i]+"'></block>";
	}
	document.getElementsByTagName("head")[0].appendChild(script);

	init();
}

//Removes #text nodes
//These are string elements present in the XML document between tags. The
//RNG specification only allows these strings to be composed of whitespace.
//They don't carry any information and can be removed
function removeRedundantText(node){
	var children=node.childNodes;
	for(var i=0;i<children.length;i++){
		if(children[i].nodeName=="#text"){
			//console.log("found text");
			children[i].parentNode.removeChild(children[i]);
			i--;
			continue;
		}else{
			removeRedundantText(children[i]);
		}
	}
}

//The name for every child block is sent to it by its parent. The child does not need to find its place in the hierarchy. The parent node does it for all of its children and sends them their name while calling them.
function createBlocks(node, name, colour){
	var children=node.childNodes;
	var blockData="";	//Contains data sent by all the children merged together one after the other.
	var childData=[];	//Keeps track of block data sent by children.
	var childNames=[];	//Keeps track of children block names

	for(var i=0;i<children.length;i++){

		if(children[i].nodeName=="text" || children[i].nodeName=="data"){
			continue;
		}

		if(children[i].nodeName=="#comment"){
			continue;
		}

		var nameAttr=children[i].getAttribute("name");

		if(nameAttr==null){
			nameAttr=children[i].nodeName;
		}

		nameAttr=nameAttr.substring(0,3);

		//The name for the child is given as <parent name/hierarchy>+<first 3 characters of the child element>+<index of the child as per its parent block>.
		var nameForChild=name+":"+nameAttr+i;

		var dataReceivedFromChild=createBlocks(children[i], nameForChild, colour+45);
		blockData+=dataReceivedFromChild;
		childData.push(dataReceivedFromChild);
		childNames.push("block_"+nameForChild);
	}

	var nodeType=node.nodeName;

	/*
	//could be used to handle datatypes efficiently. But causes multiple element siblings to behave as inline inputs

	if(nodeType=="text"){
		var data="this.appendDummyInput().appendField(new Blockly.FieldTextInput(''),'"+name+"');this.setInputsInline(true);";
		return data;
	}

	else if(nodeType=="element" || nodeType=="attribute"){
		var data="this.appendDummyInput().appendField('"+name+"');";
		blockData=data+blockData;
	}
	*/

	if(nodeType=="element"){
		if(children.length==1 && children[0].nodeName=="text"){
			//data contains data that the current tag will generate.
			var data="this.appendDummyInput().appendField('"+name+"').appendField(new Blockly.FieldTextInput(''),'"+name+"');";
			blockData=data+blockData;
		}else{
			var data="this.appendDummyInput().appendField('"+name+"');";
			blockData=data+blockData;
		}
	}

	//attributes do not check the level below them as there is no functionality currently to handle datatypes and parameters. At the attribute node, a dummy input which has a label and an input field is generated.
	else if(nodeType=="attribute"){
		var data="this.appendDummyInput().appendField('"+name+"').appendField(new Blockly.FieldTextInput(''),'"+name+"');";
		return data;
	}

	else if(nodeType=="start"){
		var blockName="block_"+name;
		var finalBlock="Blockly.Blocks['"+blockName+"']={init:function(){this.appendDummyInput().appendField('"+name+"');"+blockData+"this.setColour("+colour+");}};";
		blocks.push(finalBlock);
		blockNames.push(blockName);
		return;
	}

	else if(nodeType=="oneOrMore"){
		var childNamesInFormat="'"+childNames.join("','")+"'";

		//Every oneOrMore child has sent in its data. This loop just creates blocks for each child of the oneOrMore tag.
		for(var i=0;i<childData.length;i++){
			var blockName=childNames[i];

			var finalBlock="Blockly.Blocks['"+blockName+"']={init:function(){"+childData[i]+"this.setPreviousStatement(true,["+childNamesInFormat+"]);this.setNextStatement(true,["+childNamesInFormat+"]);this.setColour("+colour+");}};";
			blocks.push(finalBlock);
			blockNames.push(blockName);
		}

		//console.log("blockly name", node.getAttribute("blockly:name"));
		//This appends to the block which contains the oneOrMore tag and creates a notch there.
		blockData="this.appendStatementInput('"+name+"').setCheck(["+childNamesInFormat+"]).appendField('"+name+"');";
	}

	//for choice nodes, we ensure that only one option is selected by keeping no option for setNextStatement for its children.
	else if(nodeType=="choice"){
		var childNamesInFormat="'"+childNames.join("','")+"'";
		//Every choice child has sent in its data. This loop just creates blocks for each child of the oneOrMore tag.
		for(var i=0;i<childData.length;i++){
			var blockName=childNames[i];

			var finalBlock="Blockly.Blocks['"+blockName+"']={init:function(){"+childData[i]+"this.setPreviousStatement(true);this.setColour("+colour+");}};";
			blocks.push(finalBlock);
			blockNames.push(blockName);
		}

		//This appends to the block which contains the choice tag and creates a notch there.
		blockData="this.appendStatementInput('"+name+"').setCheck(["+childNamesInFormat+"]).appendField('"+name+"');";
	}

	//creates define blocks. The define block that is created inly has a notch above and never below. It is the ref code which changes according to whether or not the ref code is in a choice or oneOrMore block.
	else if(nodeType=="define"){
		var blockName="block_"+name;
		var finalBlock="Blockly.Blocks['"+blockName+"']={init:function(){this.appendDummyInput().appendField('"+name+"');this.setColour("+colour+");"+blockData+"this.setPreviousStatement(true);}};";
		blocks.push(finalBlock);
		blockNames.push(blockName);
		return;
	}

	//the ref block will have a notch above or below or both according to its parent element. The notch is added to it according to the code written to handle choice and oneOrMore elements.
	else if(nodeType="ref"){
		var correspondingDefineName=node.getAttribute("name");
		var data="this.appendStatementInput('"+name+"').appendField('"+name+"').setCheck('block_"+correspondingDefineName+"');";
		return data;
	}

	//returns block data to the parent node that had called it
	return blockData;
}

//Adds an event listener for detecting whether the user has provided a file as input or not.
document.getElementById("file").addEventListener('change',readFile);<|endoftext|>


<commit_before>"use strict";

var push = Array.prototype.push;
var utilities = require("./utilities");

var IDENTIFIER_CHARACTER = /[\w-]/;
var JS_IDENTIFIER_CHARACTER = /\w/; // Others are not included for simplicity’s sake.

function escapeStringLiteral(string) {
	var result = "";
	var escaped = false;

	for(var i = 0; i < string.length; i++) {
		var c = string.charAt(i);

		if(escaped) {
			escaped = false;
			result += c;
		} else if(c === "\\") {
			escaped = true;
			result += c;
		} else if(c === "\n") {
			result += "\\n";
		} else if(c === "\r") {
			result += "\\r";
		} else if(c === "\u2028") {
			result += "\\u2028";
		} else if(c === "\u2029") {
			result += "\\u2029";
		} else if(c === "'") {
			result += "\\'";
		} else {
			result += c;
		}
	}

	return result;
}

function InterpolatedString(escapeFunction) {
	this.parts = [];
	this.escapeFunction = escapeFunction;
}

InterpolatedString.prototype.addText = function(text) {
	this.parts.push({
		type: "text",
		value: text
	});
};

InterpolatedString.prototype.addCode = function(code) {
	this.parts.push({
		type: "code",
		value: code
	});
};

InterpolatedString.prototype.addBuffer = function(buffer) {
	push.apply(this.parts, buffer.parts);
};

Object.defineProperty(InterpolatedString.prototype, "code", {
	get: function() {
		var isCode = false;
		var code = "";

		for(var i = 0; i < this.parts.length; i++) {
			var part = this.parts[i];

			if(part.type === "code") {
				if(!isCode) {
					code += "' + ";
					isCode = true;
				}

				if(this.escapeFunction) {
					code += "__util." + this.escapeFunction + "((" + part.value + "\n)) + ";
				} else {
					code += "(" + part.value + "\n) + ";
				}
			} else {
				if(isCode) {
					code += "'";
					isCode = false;
				}

				if(this.escapeFunction) {
					code += escapeStringLiteral(utilities[this.escapeFunction](part.value));
				} else {
					code += escapeStringLiteral(part.value);
				}
			}
		}

		if(isCode) {
			code += "'";
		}

		return code;
	}
});

var specialBlocks = {};

var states = {
	content: function(c) {
		if(c === " ") {
			return states.content;
		}

		if(c === "\n") {
			this.indent = 0;
			return states.indent;
		}

		if(c === "\"") {
			this.context = {
				type: "string",
				content: new InterpolatedString("escapeContent"),
				current: "",
				parent: this.context,
				unterminated: this.error("Expected end of string before end of input, starting")
			};
			this.context.parent.children.push(this.context);
			return states.string;
		}

		if(c === "!" && this.peek() === "\"") {
			this.skip();
			this.context = {
				type: "string",
				content: new InterpolatedString(null),
				current: "",
				parent: this.context,
				unterminated: this.error("Expected end of string before end of input, starting")
			};
			this.context.parent.children.push(this.context);
			return states.string;
		}

		if(IDENTIFIER_CHARACTER.test(c)) {
			this.context = {
				name: c,
				parent: this.context,
				indent: this.indent
			};
			this.context.parent.children.push(this.context);
			return states.identifier;
		}

		throw this.error("Unexpected " + c);
	},
	indent: function(c) {
		if(c === "\n") {
			return states.indent;
		}

		if(c !== "\t") {
			while(this.indent <= this.context.indent) {
				this.context = this.context.parent;
			}

			if(this.indent > this.context.indent + 1) {
				throw this.error("Excessive indent");
			}

			return this.pass(states.content);
		}

		this.indent++;
		return states.indent;
	},
	string: function(c) {
		if(c === "\"") {
			if(this.context.current) {
				this.context.content.addText(this.context.current);
			}

			this.context = this.context.parent;
			return states.content;
		}

		if(c === "\\") {
			this.context.current += c;
			return states.escaped;
		}

		if(c === "#" && this.peek() === "{") {
			if(this.context.current) {
				this.context.content.addText(this.context.current);
				this.context.current = "";
			}
			this.context = {
				type: "interpolation",
				value: "",
				parent: this.context,
				unterminated: this.error("Expected end of interpolated section before end of input, starting")
			};
			this.skip();
			return states.interpolation;
		}

		this.context.current += c;
		return states.string;
	},
	escaped: function(c) {
		this.context.current += c;
		return states.string;
	},
	interpolation: function(c) {
		if(c === "\\") {
			if(this.peek() === "}") {
				this.skip();
				this.context.value += "}";
				return states.interpolation;
			}
		} else if(c === "}") {
			this.context.parent.content.addCode(this.context.value);
			this.context = this.context.parent;
			return states.string;
		}

		this.context.value += c;
		return states.interpolation;
	},
	identifier: function(c) {
		if(c === ":") {
			if(!IDENTIFIER_CHARACTER.test(this.peek())) {
				this.context.type = "attribute";
				this.context.value = null;

				return states.attributeValue;
			}
		} else if(!IDENTIFIER_CHARACTER.test(c)) {
			this.context.type = "element";
			this.context.children = [];

			if(specialBlocks.hasOwnProperty(this.context.name)) {
				var specialBlock = specialBlocks[this.context.name];

				specialBlock.begin.call(this);

				return this.pass(specialBlock.initialState);
			}

			return this.pass(states.content);
		}

		this.context.name += c;
		return states.identifier;
	},
	attributeValue: function(c) {
		if(c === " ") {
			return states.attributeValue;
		}

		if(c === "!") {
			throw this.error("Attributes cannot have raw strings as values");
		}

		if(c === "\"") {
			var attribute = this.context;

			attribute.value = this.context = {
				type: "string",
				content: new InterpolatedString("escapeAttributeValue"),
				current: "",
				parent: attribute.parent,
				unterminated: this.error("Expected end of string before end of input, starting")
			};

			return states.string;
		}

		this.context = this.context.parent;

		return this.pass(states.content);
	}
};

function parse(template) {
	var i;
	var c;
	var state = states.content;

	var line = 1;
	var lineStart = 0;

	var root = {
		type: "root",
		children: [],
		includes: [],
		indent: -1
	};

	template += "\n";

	var parser = {
		template: template,
		context: root,
		root: root,
		indent: 0,
		pass: function(state) {
			return state.call(parser, c);
		},
		peek: function(count) {
			return count === undefined ? template.charAt(i + 1) : template.substr(i + 1, count);
		},
		skip: function(count) {
			if(count === undefined) {
				count = 1;
			}

			for(var j = 0; j < count; j++) {
				i++;

				if(template.charAt(i) === "\n") {
					parser.beginLine();
				}
			}
		},
		error: function(message) {
			var details = message + " at line " + line + ", character " + (i - lineStart + 1) + ".";

			return new SyntaxError(details);
		},
		beginLine: function() {
			line++;
			lineStart = i + 1;
		}
	};

	for(i = 0; i < template.length; i++) {
		c = template.charAt(i);

		if(c === "\n") {
			parser.beginLine();
		}

		state = state.call(parser, c);
	}

	switch(state) {
	case states.indent:
		break;

	case states.string:
	case states.interpolation:
		throw parser.context.unterminated;

	default:
		// If this error is thrown, an extension to the parser has most likely parsed incorrectly.
		throw new Error("Parsing bug: expected final state to be indent.");
	}

	return root;
}

specialBlocks.doctype = {
	begin: function() {
		var parser = this;

		this.context.type = "doctype";
		delete this.context.name;

		this.context.children = {
			push: function() {
				throw parser.error("doctype element cannot have content");
			}
		};
	},
	initialState: states.content
};

specialBlocks.if = {
	begin: function() {
		this.context.type = "if";
		this.context.condition = "";

		delete this.context.name;
	},
	initialState: function whitespace(c) {
		if(c !== " ") {
			return this.pass(specialBlocks.if.condition);
		}

		return whitespace;
	},
	condition: function condition(c) {
		if(c === "\n") {
			return this.pass(states.content);
		}

		this.context.condition += c;
		return condition;
	}
};

specialBlocks.else = {
	begin: function() {
		this.context.parent.children.splice(-1, 1);

		var previous = this.context.parent.children[this.context.parent.children.length - 1];

		if(previous.type !== "if") {
			throw this.error("Unexpected else");
		}

		previous.else = this.context;
		this.context.type = "else";
		delete this.context.name;
	},
	initialState: function() {
		return this.pass(states.content);
	}
};

specialBlocks.for = {
	begin: function() {
		this.context.type = "for";
		this.context.variableName = "";
		this.context.collection = "";
		delete this.context.name;
	},
	initialState: function whitespace(c) {
		if(c !== " ") {
			return this.pass(specialBlocks.for.variableName);
		}

		return whitespace;
	},
	variableName: function variableName(c) {
		if(!JS_IDENTIFIER_CHARACTER.test(c)) {
			if(!this.context.variableName) {
				throw this.error("Expected variable name");
			}

			if(c !== " " || this.peek(3) !== "in ") {
				throw this.error("Expected in");
			}

			this.skip(3);

			return specialBlocks.for.whitespace;
		}

		this.context.variableName += c;
		return variableName;
	},
	whitespace: function whitespace(c) {
		if(c !== " ") {
			return this.pass(specialBlocks.for.collection);
		}

		return whitespace;
	},
	collection: function collection(c) {
		if(c === "\n") {
			return this.pass(states.content);
		}

		this.context.collection += c;
		return collection;
	}
};

specialBlocks.include = {
	begin: function() {
		var parser = this;

		this.context.type = "include";
		this.context.template = "";
		delete this.context.name;

		this.context.children = {
			push: function() {
				throw parser.error("doctype element cannot have content");
			}
		};

		this.root.includes.push(this.context);
	},
	initialState: function whitespace(c) {
		if(c !== " ") {
			return this.pass(specialBlocks.include.template);
		}

		return whitespace;
	},
	template: function template(c) {
		if(c === "\n") {
			return this.pass(states.content);
		}

		this.context.template += c;
		return template;
	}
};

module.exports.parse = parse;
module.exports.specialBlocks = specialBlocks;
<commit_msg>Corrected error message for content in an include.<commit_after>"use strict";

var push = Array.prototype.push;
var utilities = require("./utilities");

var IDENTIFIER_CHARACTER = /[\w-]/;
var JS_IDENTIFIER_CHARACTER = /\w/; // Others are not included for simplicity’s sake.

function escapeStringLiteral(string) {
	var result = "";
	var escaped = false;

	for(var i = 0; i < string.length; i++) {
		var c = string.charAt(i);

		if(escaped) {
			escaped = false;
			result += c;
		} else if(c === "\\") {
			escaped = true;
			result += c;
		} else if(c === "\n") {
			result += "\\n";
		} else if(c === "\r") {
			result += "\\r";
		} else if(c === "\u2028") {
			result += "\\u2028";
		} else if(c === "\u2029") {
			result += "\\u2029";
		} else if(c === "'") {
			result += "\\'";
		} else {
			result += c;
		}
	}

	return result;
}

function InterpolatedString(escapeFunction) {
	this.parts = [];
	this.escapeFunction = escapeFunction;
}

InterpolatedString.prototype.addText = function(text) {
	this.parts.push({
		type: "text",
		value: text
	});
};

InterpolatedString.prototype.addCode = function(code) {
	this.parts.push({
		type: "code",
		value: code
	});
};

InterpolatedString.prototype.addBuffer = function(buffer) {
	push.apply(this.parts, buffer.parts);
};

Object.defineProperty(InterpolatedString.prototype, "code", {
	get: function() {
		var isCode = false;
		var code = "";

		for(var i = 0; i < this.parts.length; i++) {
			var part = this.parts[i];

			if(part.type === "code") {
				if(!isCode) {
					code += "' + ";
					isCode = true;
				}

				if(this.escapeFunction) {
					code += "__util." + this.escapeFunction + "((" + part.value + "\n)) + ";
				} else {
					code += "(" + part.value + "\n) + ";
				}
			} else {
				if(isCode) {
					code += "'";
					isCode = false;
				}

				if(this.escapeFunction) {
					code += escapeStringLiteral(utilities[this.escapeFunction](part.value));
				} else {
					code += escapeStringLiteral(part.value);
				}
			}
		}

		if(isCode) {
			code += "'";
		}

		return code;
	}
});

var specialBlocks = {};

var states = {
	content: function(c) {
		if(c === " ") {
			return states.content;
		}

		if(c === "\n") {
			this.indent = 0;
			return states.indent;
		}

		if(c === "\"") {
			this.context = {
				type: "string",
				content: new InterpolatedString("escapeContent"),
				current: "",
				parent: this.context,
				unterminated: this.error("Expected end of string before end of input, starting")
			};
			this.context.parent.children.push(this.context);
			return states.string;
		}

		if(c === "!" && this.peek() === "\"") {
			this.skip();
			this.context = {
				type: "string",
				content: new InterpolatedString(null),
				current: "",
				parent: this.context,
				unterminated: this.error("Expected end of string before end of input, starting")
			};
			this.context.parent.children.push(this.context);
			return states.string;
		}

		if(IDENTIFIER_CHARACTER.test(c)) {
			this.context = {
				name: c,
				parent: this.context,
				indent: this.indent
			};
			this.context.parent.children.push(this.context);
			return states.identifier;
		}

		throw this.error("Unexpected " + c);
	},
	indent: function(c) {
		if(c === "\n") {
			return states.indent;
		}

		if(c !== "\t") {
			while(this.indent <= this.context.indent) {
				this.context = this.context.parent;
			}

			if(this.indent > this.context.indent + 1) {
				throw this.error("Excessive indent");
			}

			return this.pass(states.content);
		}

		this.indent++;
		return states.indent;
	},
	string: function(c) {
		if(c === "\"") {
			if(this.context.current) {
				this.context.content.addText(this.context.current);
			}

			this.context = this.context.parent;
			return states.content;
		}

		if(c === "\\") {
			this.context.current += c;
			return states.escaped;
		}

		if(c === "#" && this.peek() === "{") {
			if(this.context.current) {
				this.context.content.addText(this.context.current);
				this.context.current = "";
			}
			this.context = {
				type: "interpolation",
				value: "",
				parent: this.context,
				unterminated: this.error("Expected end of interpolated section before end of input, starting")
			};
			this.skip();
			return states.interpolation;
		}

		this.context.current += c;
		return states.string;
	},
	escaped: function(c) {
		this.context.current += c;
		return states.string;
	},
	interpolation: function(c) {
		if(c === "\\") {
			if(this.peek() === "}") {
				this.skip();
				this.context.value += "}";
				return states.interpolation;
			}
		} else if(c === "}") {
			this.context.parent.content.addCode(this.context.value);
			this.context = this.context.parent;
			return states.string;
		}

		this.context.value += c;
		return states.interpolation;
	},
	identifier: function(c) {
		if(c === ":") {
			if(!IDENTIFIER_CHARACTER.test(this.peek())) {
				this.context.type = "attribute";
				this.context.value = null;

				return states.attributeValue;
			}
		} else if(!IDENTIFIER_CHARACTER.test(c)) {
			this.context.type = "element";
			this.context.children = [];

			if(specialBlocks.hasOwnProperty(this.context.name)) {
				var specialBlock = specialBlocks[this.context.name];

				specialBlock.begin.call(this);

				return this.pass(specialBlock.initialState);
			}

			return this.pass(states.content);
		}

		this.context.name += c;
		return states.identifier;
	},
	attributeValue: function(c) {
		if(c === " ") {
			return states.attributeValue;
		}

		if(c === "!") {
			throw this.error("Attributes cannot have raw strings as values");
		}

		if(c === "\"") {
			var attribute = this.context;

			attribute.value = this.context = {
				type: "string",
				content: new InterpolatedString("escapeAttributeValue"),
				current: "",
				parent: attribute.parent,
				unterminated: this.error("Expected end of string before end of input, starting")
			};

			return states.string;
		}

		this.context = this.context.parent;

		return this.pass(states.content);
	}
};

function parse(template) {
	var i;
	var c;
	var state = states.content;

	var line = 1;
	var lineStart = 0;

	var root = {
		type: "root",
		children: [],
		includes: [],
		indent: -1
	};

	template += "\n";

	var parser = {
		template: template,
		context: root,
		root: root,
		indent: 0,
		pass: function(state) {
			return state.call(parser, c);
		},
		peek: function(count) {
			return count === undefined ? template.charAt(i + 1) : template.substr(i + 1, count);
		},
		skip: function(count) {
			if(count === undefined) {
				count = 1;
			}

			for(var j = 0; j < count; j++) {
				i++;

				if(template.charAt(i) === "\n") {
					parser.beginLine();
				}
			}
		},
		error: function(message) {
			var details = message + " at line " + line + ", character " + (i - lineStart + 1) + ".";

			return new SyntaxError(details);
		},
		beginLine: function() {
			line++;
			lineStart = i + 1;
		}
	};

	for(i = 0; i < template.length; i++) {
		c = template.charAt(i);

		if(c === "\n") {
			parser.beginLine();
		}

		state = state.call(parser, c);
	}

	switch(state) {
	case states.indent:
		break;

	case states.string:
	case states.interpolation:
		throw parser.context.unterminated;

	default:
		// If this error is thrown, an extension to the parser has most likely parsed incorrectly.
		throw new Error("Parsing bug: expected final state to be indent.");
	}

	return root;
}

specialBlocks.doctype = {
	begin: function() {
		var parser = this;

		this.context.type = "doctype";
		delete this.context.name;

		this.context.children = {
			push: function() {
				throw parser.error("doctype element cannot have content");
			}
		};
	},
	initialState: states.content
};

specialBlocks.if = {
	begin: function() {
		this.context.type = "if";
		this.context.condition = "";

		delete this.context.name;
	},
	initialState: function whitespace(c) {
		if(c !== " ") {
			return this.pass(specialBlocks.if.condition);
		}

		return whitespace;
	},
	condition: function condition(c) {
		if(c === "\n") {
			return this.pass(states.content);
		}

		this.context.condition += c;
		return condition;
	}
};

specialBlocks.else = {
	begin: function() {
		this.context.parent.children.splice(-1, 1);

		var previous = this.context.parent.children[this.context.parent.children.length - 1];

		if(previous.type !== "if") {
			throw this.error("Unexpected else");
		}

		previous.else = this.context;
		this.context.type = "else";
		delete this.context.name;
	},
	initialState: function() {
		return this.pass(states.content);
	}
};

specialBlocks.for = {
	begin: function() {
		this.context.type = "for";
		this.context.variableName = "";
		this.context.collection = "";
		delete this.context.name;
	},
	initialState: function whitespace(c) {
		if(c !== " ") {
			return this.pass(specialBlocks.for.variableName);
		}

		return whitespace;
	},
	variableName: function variableName(c) {
		if(!JS_IDENTIFIER_CHARACTER.test(c)) {
			if(!this.context.variableName) {
				throw this.error("Expected variable name");
			}

			if(c !== " " || this.peek(3) !== "in ") {
				throw this.error("Expected in");
			}

			this.skip(3);

			return specialBlocks.for.whitespace;
		}

		this.context.variableName += c;
		return variableName;
	},
	whitespace: function whitespace(c) {
		if(c !== " ") {
			return this.pass(specialBlocks.for.collection);
		}

		return whitespace;
	},
	collection: function collection(c) {
		if(c === "\n") {
			return this.pass(states.content);
		}

		this.context.collection += c;
		return collection;
	}
};

specialBlocks.include = {
	begin: function() {
		var parser = this;

		this.context.type = "include";
		this.context.template = "";
		delete this.context.name;

		this.context.children = {
			push: function() {
				throw parser.error("include element cannot have content");
			}
		};

		this.root.includes.push(this.context);
	},
	initialState: function whitespace(c) {
		if(c !== " ") {
			return this.pass(specialBlocks.include.template);
		}

		return whitespace;
	},
	template: function template(c) {
		if(c === "\n") {
			return this.pass(states.content);
		}

		this.context.template += c;
		return template;
	}
};

module.exports.parse = parse;
module.exports.specialBlocks = specialBlocks;
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2008-2011 The Open Source Geospatial Foundation
 *
 * Published under the BSD license.
 * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
 * of the license.
 */

/** api: example[print-form]
 *  Print Configuration with a Form
 *  -------------------------------
 *  Use form field plugins to control print output.
 */

Ext.require([
    'Ext.layout.container.Border',
    'Ext.Panel',
    'Ext.form.FormPanel',
    'GeoExt.data.PrintProvider',
    'GeoExt.panel.Map',
    'GeoExt.data.PrintPage',
    'GeoExt.plugins.PrintPageField',
    'GeoExt.plugins.PrintProviderField'
]);

var mapPanel, printPage;

Ext.application({
    name: 'PrintPageFieldAndPrintProviderField',
    launch: function() {

        // The printProvider that connects us to the print service
        var printProvider = Ext.create('GeoExt.data.PrintProvider', {
            method: "GET", // "POST" recommended for production use
            capabilities: printCapabilities, // from the info.json script in the html
            customParams: {
                mapTitle: "Printing Demo"
            }
        });
        // Our print page. Stores scale, center and rotation and gives us a page
        // extent feature that we can add to a layer.
        printPage = Ext.create('GeoExt.data.PrintPage', {
            printProvider: printProvider
        });
        // A layer to display the print page extent
        var pageLayer = new OpenLayers.Layer.Vector();
        pageLayer.addFeatures(printPage.feature);

        // The map we want to print
        mapPanel = Ext.create('GeoExt.panel.Map', {
            region: "center",
            map: {
                eventListeners: {
                    // recenter/resize page extent after pan/zoom
                    "moveend": function(){ printPage.fit(this, {mode: "screen"}); }
                }
            },
            layers: [
                new OpenLayers.Layer.WMS("Tasmania", "http://demo.opengeo.org/geoserver/wms",
                    {layers: "topp:tasmania_state_boundaries"}, {singleTile: true}),
                pageLayer
            ],
            center: [146.56, -41.56],
            zoom: 6
        });
        // The form with fields controlling the print output
        var formPanel = Ext.create('Ext.form.FormPanel', {
            region: "west",
            width: 250,
            bodyStyle: "padding:5px",
            labelAlign: "top",
            defaults: {anchor: "100%"},
            items: [{
                xtype: "textarea",
                name: "comment",
                value: "",
                fieldLabel: "Comment",
                plugins: Ext.create('GeoExt.plugins.PrintPageField', {
                    printPage: printPage
                })
            }, {
                xtype: "combo",
                store: printProvider.layouts,
                displayField: "name",
                fieldLabel: "Layout",
                typeAhead: true,
                queryMode: "local",
                triggerAction: "all",
                plugins: new GeoExt.plugins.PrintProviderField({
                    printProvider: printProvider
                })
            }, {
                xtype: "combo",
                store: printProvider.dpis,
                displayField: "name",
                fieldLabel: "Resolution",
                displayTpl: Ext.create('Ext.XTemplate', '<tpl for=".">{name} dpi</tpl>'),
                tpl: '<tpl for=".">
{name} dpi
</tpl>',
                typeAhead: true,
                queryMode: "local",
                triggerAction: "all",
                plugins: new GeoExt.plugins.PrintProviderField({
                    printProvider: printProvider
                })
            }, {
                xtype: "combo",
                store: printProvider.scales,
                displayField: "name",
                fieldLabel: "Scale",
                typeAhead: true,
                queryMode: "local",
                triggerAction: "all",
                plugins: Ext.create('GeoExt.plugins.PrintPageField',{
                    printPage: printPage
                })
            }, {
                xtype: "textfield",
                name: "rotation",
                fieldLabel: "Rotation",
                plugins: Ext.create('GeoExt.plugins.PrintPageField',{
                    printPage: printPage
                })
            }],
            buttons: [{
                text: "Create PDF",
                handler: function() {
                    printProvider.print(mapPanel, printPage);
                }
            }]
        });
        // The main panel
        Ext.create('Ext.Panel', {
            renderTo: "content",
            layout: "border",
            width: 700,
            height: 420,
            items: [mapPanel, formPanel]
        });
    }
});
<commit_msg>Use Ext.create only in example.<commit_after>/**
 * Copyright (c) 2008-2011 The Open Source Geospatial Foundation
 *
 * Published under the BSD license.
 * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
 * of the license.
 */

/** api: example[print-form]
 *  Print Configuration with a Form
 *  -------------------------------
 *  Use form field plugins to control print output.
 */

Ext.require([
    'Ext.layout.container.Border',
    'Ext.Panel',
    'Ext.form.FormPanel',
    'GeoExt.data.PrintProvider',
    'GeoExt.panel.Map',
    'GeoExt.data.PrintPage',
    'GeoExt.plugins.PrintPageField',
    'GeoExt.plugins.PrintProviderField'
]);

var mapPanel, printPage;

Ext.application({
    name: 'PrintPageFieldAndPrintProviderField',
    launch: function() {

        // The printProvider that connects us to the print service
        var printProvider = Ext.create('GeoExt.data.PrintProvider', {
            method: "GET", // "POST" recommended for production use
            capabilities: printCapabilities, // from the info.json script in the html
            customParams: {
                mapTitle: "Printing Demo"
            }
        });
        // Our print page. Stores scale, center and rotation and gives us a page
        // extent feature that we can add to a layer.
        printPage = Ext.create('GeoExt.data.PrintPage', {
            printProvider: printProvider
        });
        // A layer to display the print page extent
        var pageLayer = new OpenLayers.Layer.Vector();
        pageLayer.addFeatures(printPage.feature);

        // The map we want to print
        mapPanel = Ext.create('GeoExt.panel.Map', {
            region: "center",
            map: {
                eventListeners: {
                    // recenter/resize page extent after pan/zoom
                    "moveend": function(){ printPage.fit(this, {mode: "screen"}); }
                }
            },
            layers: [
                new OpenLayers.Layer.WMS("Tasmania", "http://demo.opengeo.org/geoserver/wms",
                    {layers: "topp:tasmania_state_boundaries"}, {singleTile: true}),
                pageLayer
            ],
            center: [146.56, -41.56],
            zoom: 6
        });
        // The form with fields controlling the print output
        var formPanel = Ext.create('Ext.form.FormPanel', {
            region: "west",
            width: 250,
            bodyStyle: "padding:5px",
            labelAlign: "top",
            defaults: {anchor: "100%"},
            items: [{
                xtype: "textarea",
                name: "comment",
                value: "",
                fieldLabel: "Comment",
                plugins: Ext.create('GeoExt.plugins.PrintPageField', {
                    printPage: printPage
                })
            }, {
                xtype: "combo",
                store: printProvider.layouts,
                displayField: "name",
                fieldLabel: "Layout",
                typeAhead: true,
                queryMode: "local",
                triggerAction: "all",
                plugins: Ext.create('GeoExt.plugins.PrintProviderField', {
                    printProvider: printProvider
                })
            }, {
                xtype: "combo",
                store: printProvider.dpis,
                displayField: "name",
                fieldLabel: "Resolution",
                displayTpl: Ext.create('Ext.XTemplate', '<tpl for=".">{name} dpi</tpl>'),
                tpl: '<tpl for=".">
{name} dpi
</tpl>',
                typeAhead: true,
                queryMode: "local",
                triggerAction: "all",
                plugins: Ext.create('GeoExt.plugins.PrintProviderField', {
                    printProvider: printProvider
                })
            }, {
                xtype: "combo",
                store: printProvider.scales,
                displayField: "name",
                fieldLabel: "Scale",
                typeAhead: true,
                queryMode: "local",
                triggerAction: "all",
                plugins: Ext.create('GeoExt.plugins.PrintPageField',{
                    printPage: printPage
                })
            }, {
                xtype: "textfield",
                name: "rotation",
                fieldLabel: "Rotation",
                plugins: Ext.create('GeoExt.plugins.PrintPageField',{
                    printPage: printPage
                })
            }],
            buttons: [{
                text: "Create PDF",
                handler: function() {
                    printProvider.print(mapPanel, printPage);
                }
            }]
        });
        // The main panel
        Ext.create('Ext.Panel', {
            renderTo: "content",
            layout: "border",
            width: 700,
            height: 420,
            items: [mapPanel, formPanel]
        });
    }
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
var Promise = require('bluebird'),
    request = require('request'),
    cheerio = require('cheerio'),
    _       = require('lodash'),
    moment  = require('moment'),
    mkdirp  = Promise.promisify(require('mkdirp')),
    fs      = require('fs'),
    chalk   = require('chalk'),
    pjson   = require('./package.json'),
    yargs   = require('yargs')
      .usage('Usage: $0 [-hvn] [-s <YYYY-MM-DD>] [-e <YYYY-MM-DD>] [-m <num>] [-d <dir>]')
      .option('h', {
        alias: 'help',
        demand: false,
        describe: 'Display help text and exit',
        type: 'boolean'
      })
      .option('n', {
        alias: 'noop',
        demand: false,
        describe: "Lists operations, but doesn't do anything",
        type: 'boolean'
      })
      .option('v', {
        alias: 'verbose',
        demand: false,
        describe: 'Print all info/warnings/errors',
        type: 'boolean'
      })
      .option('version', {
        demand: false,
        describe: 'Print version: ' + pjson.version,
        type: 'boolean'
      })
      .option('s', {
        alias: 'start',
        demand: false,
        default: moment().subtract(2, 'weeks').format('YYYY-MM-DD'),
        describe: 'Start date to filter by.  Format YYYY-MM-DD, default: 2 weeks ago',
        type: 'string'
      })
      .option('e', {
        alias: 'end',
        demand: false,
        default: moment().format('YYYY-MM-DD'),
        describe: 'End date to filter by.  Format YYYY-MM-DD, default: today',
        type: 'string'
      })
      .option('d', {
        alias: 'dir',
        demand: false,
        default: './',
        describe: 'Directory to put bassdrive archives in',
        type: 'string'
      })
      .option('m', {
        alias: 'max',
        demand: false,
        describe: 'Max number of mp3s to download in chronological order',
        type: 'number'
      }),
    argv    = yargs.argv;

if(argv.h) {
  yargs.showHelp();
  process.exit(0);
}
if(argv.version) {
  console.log('bassdrive-archive version: ' + pjson.version);
  process.exit(0);
}

var start = moment(argv.s),
    end = moment(argv.e),
    mp3s = [];

if(argv.m && argv.m > 0) {
  argv.m = Math.round(argv.m);
} else {
  argv.m = null;
}

var log = {
  info: function(str) {
    console.log(chalk.blue(str));
  },
  warn: function(str) {
    console.error(chalk.yellow(str));
  },
  error: function(str) {
    console.error(chalk.red(str));
  }
};

function doGet(url) {
  return new Promise(function(resolve, reject) {
    request({method: 'GET', uri: url}, function(err, res, body) {
      if(err) {
        reject(err);
        return;
      }

      if(res.statusCode !== 200) {
        reject('Request Failed: ' + url + ' - ' + res.statusCode);
        return;
      }

      resolve(body);
    });
  });
}

function getLinks(url) {
  return doGet(url).then(function(body) {
    return _(cheerio.load(body)('a')).map(function(v) {
      return v.attribs.href;
    }).filter(function(v) {
      return v !== '/' && v.slice(0,4) !== 'http' && url.indexOf(v) < 0;
    }).value();
  }).catch(function(err) {
    if(argv.v) {
      log.warn(err);
    }
    return [];
  });
}

function spiderForMp3(url) {
  return getLinks(url).map(function(part) {
    if(part.slice(part.length-4) === '.mp3') {
      mp3s.push(url + part);
      return Promise.resolve();
    } else {
      return spiderForMp3(url + part);
    }
  });
}

spiderForMp3('http://archives.bassdrivearchive.com').then(function(){
  log.info(mp3s.length + ' total bassdrive mp3s found');
  return Promise.resolve(mp3s);
})
.then(function(mp3s){
  mp3s = _(mp3s).map(function(mp3) {
    var splitMp3 = mp3.split('/'),
        filename = splitMp3[splitMp3.length-1],
        filedate = filename.match(/[0-9]{4}\.[0-9]{2}\.[0-9]{2}/);

    return {
      url: mp3,
      date: filedate === null ? null :
        moment(filedate[0], 'YYYY.MM.DD')
    };
  }).filter(function(mp3) {
    return mp3.date ? mp3.date.isBetween(start, end) : false;
  }).map(function(mp3) {
    mp3.path = argv.d + decodeURIComponent(mp3.url).slice(7);
    mp3.dir  = mp3.path.slice(0, mp3.path.lastIndexOf('/'));
    return mp3;
  }).sortBy(function(mp3) {
    return +mp3.date;
  }).value();

  log.info(
    mp3s.length +
    ' bassdrive mp3s found between ' +
    start.format('YYYY-MM-DD') +
    ' and ' +
    end.format('YYYY-MM-DD'));
  return mp3s;
})
.filter(function(mp3) {
  var exists = fs.existsSync(mp3.path);
  if(exists) {
    log.warn('File Exists, Skipping: ' + mp3.path);
  }
  return !exists;
})
.then(function(mp3s) {
  if(argv.m && argv.m < mp3s.length) {
    if(argv.v) {
      log.warn(mp3s.length - argv.m + ' mp3s over specified max, the following will NOT be downloaded');
      _.each(mp3s.slice(argv.m), function(mp3) {
        log.warn('Over max: ' + mp3.path);
      });
    }
    return mp3s.slice(0, argv.m);
  }

  return mp3s;
})
.map(function(mp3) {
  if(argv.n) {
    return mp3;
  } else {
    return mkdirp(mp3.dir).then(function(){
      return mp3;
    });
  }
})
.map(function(mp3) {
  return new Promise(function(resolve, reject) {
    log.info('Downloading: ' + mp3.path);
    if(argv.n) {
      resolve(mp3);
    } else {
      request.get(mp3.url).pipe(fs.createWriteStream(mp3.path)).on('finish', function() {
        resolve(mp3);
      }).on('error', function(err) {
        reject(err);
      });
    }
  });
}, {concurrency: 1}).all();

<commit_msg>Use path.normalize for paths, for windows?<commit_after>#!/usr/bin/env node
var Promise = require('bluebird'),
    request = require('request'),
    cheerio = require('cheerio'),
    _       = require('lodash'),
    moment  = require('moment'),
    mkdirp  = Promise.promisify(require('mkdirp')),
    fs      = require('fs'),
    path    = require('path'),
    chalk   = require('chalk'),
    pjson   = require('./package.json'),
    yargs   = require('yargs')
      .usage('Usage: $0 [-hvn] [-s <YYYY-MM-DD>] [-e <YYYY-MM-DD>] [-m <num>] [-d <dir>]')
      .option('h', {
        alias: 'help',
        demand: false,
        describe: 'Display help text and exit',
        type: 'boolean'
      })
      .option('n', {
        alias: 'noop',
        demand: false,
        describe: "Lists operations, but doesn't do anything",
        type: 'boolean'
      })
      .option('v', {
        alias: 'verbose',
        demand: false,
        describe: 'Print all info/warnings/errors',
        type: 'boolean'
      })
      .option('version', {
        demand: false,
        describe: 'Print version: ' + pjson.version,
        type: 'boolean'
      })
      .option('s', {
        alias: 'start',
        demand: false,
        default: moment().subtract(2, 'weeks').format('YYYY-MM-DD'),
        describe: 'Start date to filter by.  Format YYYY-MM-DD, default: 2 weeks ago',
        type: 'string'
      })
      .option('e', {
        alias: 'end',
        demand: false,
        default: moment().format('YYYY-MM-DD'),
        describe: 'End date to filter by.  Format YYYY-MM-DD, default: today',
        type: 'string'
      })
      .option('d', {
        alias: 'dir',
        demand: false,
        default: './',
        describe: 'Directory to put bassdrive archives in',
        type: 'string'
      })
      .option('m', {
        alias: 'max',
        demand: false,
        describe: 'Max number of mp3s to download in chronological order',
        type: 'number'
      }),
    argv    = yargs.argv;

if(argv.h) {
  yargs.showHelp();
  process.exit(0);
}
if(argv.version) {
  console.log('bassdrive-archive version: ' + pjson.version);
  process.exit(0);
}

var start = moment(argv.s),
    end = moment(argv.e),
    mp3s = [];

if(argv.m && argv.m > 0) {
  argv.m = Math.round(argv.m);
} else {
  argv.m = null;
}

var log = {
  info: function(str) {
    console.log(chalk.blue(str));
  },
  warn: function(str) {
    console.error(chalk.yellow(str));
  },
  error: function(str) {
    console.error(chalk.red(str));
  }
};

function doGet(url) {
  return new Promise(function(resolve, reject) {
    request({method: 'GET', uri: url}, function(err, res, body) {
      if(err) {
        reject(err);
        return;
      }

      if(res.statusCode !== 200) {
        reject('Request Failed: ' + url + ' - ' + res.statusCode);
        return;
      }

      resolve(body);
    });
  });
}

function getLinks(url) {
  return doGet(url).then(function(body) {
    return _(cheerio.load(body)('a')).map(function(v) {
      return v.attribs.href;
    }).filter(function(v) {
      return v !== '/' && v.slice(0,4) !== 'http' && url.indexOf(v) < 0;
    }).value();
  }).catch(function(err) {
    if(argv.v) {
      log.warn(err);
    }
    return [];
  });
}

function spiderForMp3(url) {
  return getLinks(url).map(function(part) {
    if(part.slice(part.length-4) === '.mp3') {
      mp3s.push(url + part);
      return Promise.resolve();
    } else {
      return spiderForMp3(url + part);
    }
  });
}

spiderForMp3('http://archives.bassdrivearchive.com').then(function(){
  log.info(mp3s.length + ' total bassdrive mp3s found');
  return Promise.resolve(mp3s);
})
.then(function(mp3s){
  mp3s = _(mp3s).map(function(mp3) {
    var splitMp3 = mp3.split('/'),
        filename = splitMp3[splitMp3.length-1],
        filedate = filename.match(/[0-9]{4}\.[0-9]{2}\.[0-9]{2}/);

    return {
      url: mp3,
      date: filedate === null ? null :
        moment(filedate[0], 'YYYY.MM.DD')
    };
  }).filter(function(mp3) {
    return mp3.date ? mp3.date.isBetween(start, end) : false;
  }).map(function(mp3) {
    mp3.path = argv.d + decodeURIComponent(mp3.url).slice(7);
    mp3.dir  = path.normalize(mp3.path.slice(0, mp3.path.lastIndexOf('/')));
    mp3.path = path.normalize(mp3.path);
    return mp3;
  }).sortBy(function(mp3) {
    return +mp3.date;
  }).value();

  log.info(
    mp3s.length +
    ' bassdrive mp3s found between ' +
    start.format('YYYY-MM-DD') +
    ' and ' +
    end.format('YYYY-MM-DD'));
  return mp3s;
})
.filter(function(mp3) {
  var exists = fs.existsSync(mp3.path);
  if(exists) {
    log.warn('File Exists, Skipping: ' + mp3.path);
  }
  return !exists;
})
.then(function(mp3s) {
  if(argv.m && argv.m < mp3s.length) {
    if(argv.v) {
      log.warn(mp3s.length - argv.m + ' mp3s over specified max, the following will NOT be downloaded');
      _.each(mp3s.slice(argv.m), function(mp3) {
        log.warn('Over max: ' + mp3.path);
      });
    }
    return mp3s.slice(0, argv.m);
  }

  return mp3s;
})
.map(function(mp3) {
  if(argv.n) {
    return mp3;
  } else {
    return mkdirp(mp3.dir).then(function(){
      return mp3;
    });
  }
})
.map(function(mp3) {
  return new Promise(function(resolve, reject) {
    log.info('Downloading: ' + mp3.path);
    if(argv.n) {
      resolve(mp3);
    } else {
      request.get(mp3.url).pipe(fs.createWriteStream(mp3.path)).on('finish', function() {
        resolve(mp3);
      }).on('error', function(err) {
        reject(err);
      });
    }
  });
}, {concurrency: 1}).all();

<|endoftext|>


<commit_before>// Copyright 2017-2022, University of Colorado Boulder

/**
 * Content for a KeyboardHelpDialog that describes how to use sliders.
 *
 * @author Jesse Greenberg
 */

import validate from '../../../../axon/js/validate.js';
import EnumerationDeprecated from '../../../../phet-core/js/EnumerationDeprecated.js';
import merge from '../../../../phet-core/js/merge.js';
import StringUtils from '../../../../phetcommon/js/util/StringUtils.js';
import { HBox } from '../../../../scenery/js/imports.js';
import sceneryPhet from '../../sceneryPhet.js';
import sceneryPhetStrings from '../../sceneryPhetStrings.js';
import TextKeyNode from '../TextKeyNode.js';
import KeyboardHelpIconFactory from './KeyboardHelpIconFactory.js';
import KeyboardHelpSection from './KeyboardHelpSection.js';

const ArrowKeyIconDisplay = EnumerationDeprecated.byKeys( [ 'UP_DOWN', 'LEFT_RIGHT', 'BOTH' ] );

class SliderControlsKeyboardHelpSection extends KeyboardHelpSection {

  /**
   * @param {Object} [options]
   */
  constructor( options ) {

    options = merge( {

      // {ArrowKeyIconDisplay} - Whether to show up/down, left/right or both sets of keyboard help icons to cue the
      // slider interaction.
      arrowKeyIconDisplay: ArrowKeyIconDisplay.BOTH,

      // heading string for this content
      headingString: sceneryPhetStrings.keyboardHelpDialog.sliderControls,

      // verb used to describe the movement of the slider
      verbString: sceneryPhetStrings.keyboardHelpDialog.adjust,

      // name to call the slider (lowercase), default to "slider"
      sliderString: sceneryPhetStrings.keyboardHelpDialog.slider,

      maximumString: sceneryPhetStrings.keyboardHelpDialog.maximum,
      minimumString: sceneryPhetStrings.keyboardHelpDialog.minimum
    }, options );

    validate( options.arrowKeyIconDisplay, { valueType: ArrowKeyIconDisplay } );

    const keyboardHelpDialogVerbSliderString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.verbSliderPattern, {
      verb: options.verbString,
      slider: options.sliderString
    } );
    const keyboardHelpDialogVerbInSmallerStepsString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.verbInSmallerStepsPattern, {
      verb: options.verbString
    } );
    const keyboardHelpDialogVerbInLargerStepsString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.verbInLargerStepsPattern, {
      verb: options.verbString
    } );

    const keysString = ArrowKeyIconDisplay.LEFT_RIGHT === options.arrowKeyIconDisplay ? sceneryPhetStrings.a11y.keyboardHelpDialog.slider.leftRightArrowKeys :
                       ArrowKeyIconDisplay.UP_DOWN === options.arrowKeyIconDisplay ? sceneryPhetStrings.a11y.keyboardHelpDialog.slider.upDownArrowKeys :
                       ArrowKeyIconDisplay.BOTH === options.arrowKeyIconDisplay ? StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.orKeysPattern, {
                         leftRight: sceneryPhetStrings.a11y.keyboardHelpDialog.slider.leftRightArrowKeys,
                         upDown: sceneryPhetStrings.a11y.keyboardHelpDialog.slider.upDownArrowKeys
                       } ) : null;
    assert && assert( keysString );
    const keyboardHelpDialogDefaultStepsString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.defaultStepsDescriptionPattern, {
      verb: options.verbString,
      slider: options.sliderString,
      keys: keysString
    } );

    const shiftKeysString = ArrowKeyIconDisplay.LEFT_RIGHT === options.arrowKeyIconDisplay ? sceneryPhetStrings.a11y.keyboardHelpDialog.slider.shiftLeftRightArrowKeys :
                            ArrowKeyIconDisplay.UP_DOWN === options.arrowKeyIconDisplay ? sceneryPhetStrings.a11y.keyboardHelpDialog.slider.shiftUpDownArrowKeys :
                            ArrowKeyIconDisplay.BOTH === options.arrowKeyIconDisplay ? StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.orKeysPattern, {
                              leftRight: sceneryPhetStrings.a11y.keyboardHelpDialog.slider.shiftLeftRightArrowKeys,
                              upDown: sceneryPhetStrings.a11y.keyboardHelpDialog.slider.shiftUpDownArrowKeys
                            } ) : null;
    assert && assert( shiftKeysString );
    const keyboardHelpDialogSmallerStepsString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.smallerStepsDescriptionPattern, {
      verb: options.verbString,
      keys: shiftKeysString
    } );
    const keyboardHelpDialogLargerStepsString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.largerStepsDescriptionPattern, {
      verb: options.verbString
    } );

    const jumpToMinimumString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.jumpToMinimumPattern, {
      minimum: options.minimumString
    } );
    const jumpToMaximumString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.jumpToMaximumPattern, {
      maximum: options.maximumString
    } );
    const jumpToMinimumDescriptionString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.jumpToMinimumDescriptionPattern, {
      minimum: options.minimumString
    } );
    const jumpToMaximumDescriptionString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.jumpToMaximumDescriptionPattern, {
      maximum: options.maximumString
    } );

    // 'Move sliders' content

    const shiftPlusLeftRightIcon = KeyboardHelpIconFactory.shiftPlusIcon( KeyboardHelpIconFactory.leftRightArrowKeysRowIcon() );
    const shiftPlusUpDownIcon = KeyboardHelpIconFactory.shiftPlusIcon( KeyboardHelpIconFactory.upDownArrowKeysRowIcon() );

    let adjustSliderIcon = null;
    let adjustSliderSmallerStepsIcons = null;

    switch( options.arrowKeyIconDisplay ) {
      case ArrowKeyIconDisplay.LEFT_RIGHT:
        adjustSliderIcon = KeyboardHelpIconFactory.leftRightArrowKeysRowIcon();
        adjustSliderSmallerStepsIcons = [ shiftPlusLeftRightIcon ];
        break;
      case ArrowKeyIconDisplay.UP_DOWN:
        adjustSliderIcon = KeyboardHelpIconFactory.upDownArrowKeysRowIcon();
        adjustSliderSmallerStepsIcons = [ shiftPlusUpDownIcon ];
        break;
      default:
        assert && assert( options.arrowKeyIconDisplay === ArrowKeyIconDisplay.BOTH, 'unsupported arrowKeyIconDisplay' );
        adjustSliderIcon = KeyboardHelpIconFactory.iconOrIcon( KeyboardHelpIconFactory.leftRightArrowKeysRowIcon(), KeyboardHelpIconFactory.upDownArrowKeysRowIcon() );
        adjustSliderSmallerStepsIcons = [ shiftPlusLeftRightIcon, shiftPlusUpDownIcon ];
    }
    const adjustSliderRow = KeyboardHelpSection.labelWithIcon( keyboardHelpDialogVerbSliderString, adjustSliderIcon, {
      labelInnerContent: keyboardHelpDialogDefaultStepsString
    } );

    const adjustSliderInSmallerStepsRow = KeyboardHelpSection.labelWithIconList( keyboardHelpDialogVerbInSmallerStepsString,
      adjustSliderSmallerStepsIcons, {
        labelInnerContent: keyboardHelpDialogSmallerStepsString
      } );

    // 'move in larger steps' content
    const pageUpKeyNode = TextKeyNode.pageUp();
    const pageDownKeyNode = TextKeyNode.pageDown();
    const pageUpPageDownIcon = new HBox( {
      children: [ pageUpKeyNode, pageDownKeyNode ],
      spacing: KeyboardHelpIconFactory.DEFAULT_ICON_SPACING
    } );
    const adjustInLargerStepsRow = KeyboardHelpSection.labelWithIcon( keyboardHelpDialogVerbInLargerStepsString, pageUpPageDownIcon, {
      labelInnerContent: keyboardHelpDialogLargerStepsString
    } );

    // 'move to minimum value' content
    const homeKeyNode = TextKeyNode.home();
    const jumpToMinimumRow = KeyboardHelpSection.labelWithIcon( jumpToMinimumString, homeKeyNode, {
      labelInnerContent: jumpToMinimumDescriptionString
    } );

    // 'move to maximum value' content
    const endKeyNode = TextKeyNode.end();
    const jumpToMaximumRow = KeyboardHelpSection.labelWithIcon( jumpToMaximumString, endKeyNode, {
      labelInnerContent: jumpToMaximumDescriptionString
    } );

    // assemble final content for KeyboardHelpSection
    const content = [ adjustSliderRow, adjustSliderInSmallerStepsRow, adjustInLargerStepsRow, jumpToMinimumRow, jumpToMaximumRow ];

    super( options.headingString, content, options );
  }
}

// @public - for use in defining a component-specific option.
SliderControlsKeyboardHelpSection.ArrowKeyIconDisplay = ArrowKeyIconDisplay;

sceneryPhet.register( 'SliderControlsKeyboardHelpSection', SliderControlsKeyboardHelpSection );
export default SliderControlsKeyboardHelpSection;<commit_msg>Convert EnumerationDeprecated to new Enumeration pattern, https://github.com/phetsims/ratio-and-proportion/issues/404<commit_after>// Copyright 2017-2022, University of Colorado Boulder

/**
 * Content for a KeyboardHelpDialog that describes how to use sliders.
 *
 * @author Jesse Greenberg
 */

import validate from '../../../../axon/js/validate.js';
import Enumeration from '../../../../phet-core/js/Enumeration.js';
import EnumerationValue from '../../../../phet-core/js/EnumerationValue.js';
import merge from '../../../../phet-core/js/merge.js';
import StringUtils from '../../../../phetcommon/js/util/StringUtils.js';
import { HBox } from '../../../../scenery/js/imports.js';
import sceneryPhet from '../../sceneryPhet.js';
import sceneryPhetStrings from '../../sceneryPhetStrings.js';
import TextKeyNode from '../TextKeyNode.js';
import KeyboardHelpIconFactory from './KeyboardHelpIconFactory.js';
import KeyboardHelpSection from './KeyboardHelpSection.js';

class ArrowKeyIconDisplay extends EnumerationValue {
  static UP_DOWN = new ArrowKeyIconDisplay();
  static LEFT_RIGHT = new ArrowKeyIconDisplay();
  static BOTH = new ArrowKeyIconDisplay();

  static enumeration = new Enumeration( ArrowKeyIconDisplay );
}

class SliderControlsKeyboardHelpSection extends KeyboardHelpSection {

  /**
   * @param {Object} [options]
   */
  constructor( options ) {

    options = merge( {

      // {ArrowKeyIconDisplay} - Whether to show up/down, left/right or both sets of keyboard help icons to cue the
      // slider interaction.
      arrowKeyIconDisplay: ArrowKeyIconDisplay.BOTH,

      // heading string for this content
      headingString: sceneryPhetStrings.keyboardHelpDialog.sliderControls,

      // verb used to describe the movement of the slider
      verbString: sceneryPhetStrings.keyboardHelpDialog.adjust,

      // name to call the slider (lowercase), default to "slider"
      sliderString: sceneryPhetStrings.keyboardHelpDialog.slider,

      maximumString: sceneryPhetStrings.keyboardHelpDialog.maximum,
      minimumString: sceneryPhetStrings.keyboardHelpDialog.minimum
    }, options );

    validate( options.arrowKeyIconDisplay, { valueType: ArrowKeyIconDisplay } );

    const keyboardHelpDialogVerbSliderString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.verbSliderPattern, {
      verb: options.verbString,
      slider: options.sliderString
    } );
    const keyboardHelpDialogVerbInSmallerStepsString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.verbInSmallerStepsPattern, {
      verb: options.verbString
    } );
    const keyboardHelpDialogVerbInLargerStepsString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.verbInLargerStepsPattern, {
      verb: options.verbString
    } );

    const keysString = ArrowKeyIconDisplay.LEFT_RIGHT === options.arrowKeyIconDisplay ? sceneryPhetStrings.a11y.keyboardHelpDialog.slider.leftRightArrowKeys :
                       ArrowKeyIconDisplay.UP_DOWN === options.arrowKeyIconDisplay ? sceneryPhetStrings.a11y.keyboardHelpDialog.slider.upDownArrowKeys :
                       ArrowKeyIconDisplay.BOTH === options.arrowKeyIconDisplay ? StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.orKeysPattern, {
                         leftRight: sceneryPhetStrings.a11y.keyboardHelpDialog.slider.leftRightArrowKeys,
                         upDown: sceneryPhetStrings.a11y.keyboardHelpDialog.slider.upDownArrowKeys
                       } ) : null;
    assert && assert( keysString );
    const keyboardHelpDialogDefaultStepsString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.defaultStepsDescriptionPattern, {
      verb: options.verbString,
      slider: options.sliderString,
      keys: keysString
    } );

    const shiftKeysString = ArrowKeyIconDisplay.LEFT_RIGHT === options.arrowKeyIconDisplay ? sceneryPhetStrings.a11y.keyboardHelpDialog.slider.shiftLeftRightArrowKeys :
                            ArrowKeyIconDisplay.UP_DOWN === options.arrowKeyIconDisplay ? sceneryPhetStrings.a11y.keyboardHelpDialog.slider.shiftUpDownArrowKeys :
                            ArrowKeyIconDisplay.BOTH === options.arrowKeyIconDisplay ? StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.orKeysPattern, {
                              leftRight: sceneryPhetStrings.a11y.keyboardHelpDialog.slider.shiftLeftRightArrowKeys,
                              upDown: sceneryPhetStrings.a11y.keyboardHelpDialog.slider.shiftUpDownArrowKeys
                            } ) : null;
    assert && assert( shiftKeysString );
    const keyboardHelpDialogSmallerStepsString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.smallerStepsDescriptionPattern, {
      verb: options.verbString,
      keys: shiftKeysString
    } );
    const keyboardHelpDialogLargerStepsString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.largerStepsDescriptionPattern, {
      verb: options.verbString
    } );

    const jumpToMinimumString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.jumpToMinimumPattern, {
      minimum: options.minimumString
    } );
    const jumpToMaximumString = StringUtils.fillIn( sceneryPhetStrings.keyboardHelpDialog.jumpToMaximumPattern, {
      maximum: options.maximumString
    } );
    const jumpToMinimumDescriptionString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.jumpToMinimumDescriptionPattern, {
      minimum: options.minimumString
    } );
    const jumpToMaximumDescriptionString = StringUtils.fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.slider.jumpToMaximumDescriptionPattern, {
      maximum: options.maximumString
    } );

    // 'Move sliders' content

    const shiftPlusLeftRightIcon = KeyboardHelpIconFactory.shiftPlusIcon( KeyboardHelpIconFactory.leftRightArrowKeysRowIcon() );
    const shiftPlusUpDownIcon = KeyboardHelpIconFactory.shiftPlusIcon( KeyboardHelpIconFactory.upDownArrowKeysRowIcon() );

    let adjustSliderIcon = null;
    let adjustSliderSmallerStepsIcons = null;

    switch( options.arrowKeyIconDisplay ) {
      case ArrowKeyIconDisplay.LEFT_RIGHT:
        adjustSliderIcon = KeyboardHelpIconFactory.leftRightArrowKeysRowIcon();
        adjustSliderSmallerStepsIcons = [ shiftPlusLeftRightIcon ];
        break;
      case ArrowKeyIconDisplay.UP_DOWN:
        adjustSliderIcon = KeyboardHelpIconFactory.upDownArrowKeysRowIcon();
        adjustSliderSmallerStepsIcons = [ shiftPlusUpDownIcon ];
        break;
      default:
        assert && assert( options.arrowKeyIconDisplay === ArrowKeyIconDisplay.BOTH, 'unsupported arrowKeyIconDisplay' );
        adjustSliderIcon = KeyboardHelpIconFactory.iconOrIcon( KeyboardHelpIconFactory.leftRightArrowKeysRowIcon(), KeyboardHelpIconFactory.upDownArrowKeysRowIcon() );
        adjustSliderSmallerStepsIcons = [ shiftPlusLeftRightIcon, shiftPlusUpDownIcon ];
    }
    const adjustSliderRow = KeyboardHelpSection.labelWithIcon( keyboardHelpDialogVerbSliderString, adjustSliderIcon, {
      labelInnerContent: keyboardHelpDialogDefaultStepsString
    } );

    const adjustSliderInSmallerStepsRow = KeyboardHelpSection.labelWithIconList( keyboardHelpDialogVerbInSmallerStepsString,
      adjustSliderSmallerStepsIcons, {
        labelInnerContent: keyboardHelpDialogSmallerStepsString
      } );

    // 'move in larger steps' content
    const pageUpKeyNode = TextKeyNode.pageUp();
    const pageDownKeyNode = TextKeyNode.pageDown();
    const pageUpPageDownIcon = new HBox( {
      children: [ pageUpKeyNode, pageDownKeyNode ],
      spacing: KeyboardHelpIconFactory.DEFAULT_ICON_SPACING
    } );
    const adjustInLargerStepsRow = KeyboardHelpSection.labelWithIcon( keyboardHelpDialogVerbInLargerStepsString, pageUpPageDownIcon, {
      labelInnerContent: keyboardHelpDialogLargerStepsString
    } );

    // 'move to minimum value' content
    const homeKeyNode = TextKeyNode.home();
    const jumpToMinimumRow = KeyboardHelpSection.labelWithIcon( jumpToMinimumString, homeKeyNode, {
      labelInnerContent: jumpToMinimumDescriptionString
    } );

    // 'move to maximum value' content
    const endKeyNode = TextKeyNode.end();
    const jumpToMaximumRow = KeyboardHelpSection.labelWithIcon( jumpToMaximumString, endKeyNode, {
      labelInnerContent: jumpToMaximumDescriptionString
    } );

    // assemble final content for KeyboardHelpSection
    const content = [ adjustSliderRow, adjustSliderInSmallerStepsRow, adjustInLargerStepsRow, jumpToMinimumRow, jumpToMaximumRow ];

    super( options.headingString, content, options );
  }
}

// @public {ArrowKeyIconDisplay} - for use in defining a component-specific option.
SliderControlsKeyboardHelpSection.ArrowKeyIconDisplay = ArrowKeyIconDisplay;

sceneryPhet.register( 'SliderControlsKeyboardHelpSection', SliderControlsKeyboardHelpSection );
export default SliderControlsKeyboardHelpSection;<|endoftext|>


<commit_before>// TEMPORARY TEST

var container, camera, scene, renderer, mesh,

    objects = [],

    count = 0,

    CANVAS_WIDTH = 600,
    CANVAS_HEIGHT = 600,

    planes = [];

container = document.getElementById( 'player' );
document.body.appendChild( container );

renderer = new THREE.WebGLRenderer();
renderer.setSize( CANVAS_WIDTH, CANVAS_HEIGHT );
container.appendChild( renderer.domElement );

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera( 50, CANVAS_WIDTH / CANVAS_HEIGHT, 1, 1000 );
camera.position.y = 150;
camera.position.z = 500;
camera.lookAt( scene.position );

function render() {

    loopCode();

    renderer.render( scene, camera );

}

(function animate() {

    requestAnimationFrame( animate );

    render();

})();

function loopCode(){

}

function makePlane(x, y, z, xRot, yRot, zRot, faction, type, squadron, wingOrGroup, healthPercentage, trainingAndExperience, condition){

    var geometry = new THREE.BoxGeometry( wingspan, height, length );
    var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
    var cube = new THREE.Mesh( geometry, material );
    scene.add( cube );
    cube.position.x=x;
    cube.position.y=y;
    cube.position.z=z;
    cube.rotation.x=xRot;
    cube.rotation.y=yRot;
    cube.rotation.z=zRot;
    planes.push(cube);
    cube.userData = { Faction: faction, Type: type, Squadron: squadron, WingGroup: wingOrGroup, Health: healthPercentage, TrainingAndExperience: trainingAndExperience, Condition: condition };

}

makePlane(0,0,0,0,0,0,"YOLO");
makePlane(0,0,0,0,0,0"OLOY");
planes[1].position.y=20;
<commit_msg>*facepalm*<commit_after>// TEMPORARY TEST

var container, camera, scene, renderer, mesh,

    objects = [],

    count = 0,

    CANVAS_WIDTH = 600,
    CANVAS_HEIGHT = 600,

    planes = [];

container = document.getElementById( 'player' );
document.body.appendChild( container );

renderer = new THREE.WebGLRenderer();
renderer.setSize( CANVAS_WIDTH, CANVAS_HEIGHT );
container.appendChild( renderer.domElement );

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera( 50, CANVAS_WIDTH / CANVAS_HEIGHT, 1, 1000 );
camera.position.y = 150;
camera.position.z = 500;
camera.lookAt( scene.position );

function render() {

    loopCode();

    renderer.render( scene, camera );

}

(function animate() {

    requestAnimationFrame( animate );

    render();

})();

function loopCode(){

}

function makePlane(x, y, z, xRot, yRot, zRot, faction, type, squadron, wingOrGroup, healthPercentage, trainingAndExperience, condition){

    var geometry = new THREE.BoxGeometry( wingspan, height, length );
    var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
    var cube = new THREE.Mesh( geometry, material );
    scene.add( cube );
    cube.position.x=x;
    cube.position.y=y;
    cube.position.z=z;
    cube.rotation.x=xRot;
    cube.rotation.y=yRot;
    cube.rotation.z=zRot;
    planes.push(cube);
    cube.userData = { Faction: faction, Type: type, Squadron: squadron, WingGroup: wingOrGroup, Health: healthPercentage, TrainingAndExperience: trainingAndExperience, Condition: condition };

}

makePlane(0,0,0,0,0,0,"YOLO");
makePlane(0,0,0,0,0,0,"OLOY");
planes[1].position.y=20;
<|endoftext|>


<commit_before>// RPC reply serializer, that should heppen in the end,
// because we pass errors in serialized form too
//

'use strict';

////////////////////////////////////////////////////////////////////////////////

module.exports = function (N) {

  N.wire.after('responder:rpc', { priority: 90 }, function rpc_serialize(env) {

    // Set Content-Type and charset (override existing)
    env.headers['Content-Type'] = 'application/json; charset=UTF-8';

    // Status is always ok - errors are embedded into payload
    env.status = N.io.OK;

    // Don't try to render page if body already provided.
    if (env.body !== null) {
      if (env.origin.req.method === 'HEAD') { env.body = null; }
      return;
    }

    // HEAD requested - no need for real rendering
    if (env.origin.req.method === 'HEAD') {
      env.body = null;
      return;
    }

    // Replace body with serialized payload
    env.body = JSON.stringify({
      version_hash: N.version_hash,
      error: env.err,
      res: env.err ? null : env.res
    });
  });
};
<commit_msg>Rolled back body magickk for RPC call - not needed, conflicts with error send<commit_after>// RPC reply serializer, that should heppen in the end,
// because we pass errors in serialized form too
//

'use strict';

////////////////////////////////////////////////////////////////////////////////

module.exports = function (N) {

  N.wire.after('responder:rpc', { priority: 90 }, function rpc_serialize(env) {

    // Set Content-Type and charset (override existing)
    env.headers['Content-Type'] = 'application/json; charset=UTF-8';

    // Status is always ok - errors are embedded into payload
    env.status = N.io.OK;

    // HEAD requested - no need for real rendering
    if (env.origin.req.method === 'HEAD') {
      env.body = null;
      return;
    }

    // Replace body with serialized payload
    env.body = JSON.stringify({
      version_hash: N.version_hash,
      error: env.err,
      res: env.err ? null : env.res
    });
  });
};
<|endoftext|>


<commit_before>    var cv ;
    var ctx;
    var background = new Image();
    var myMap = [true,false,false,true,true,false,false];
function game(){
    document.getElementById("body").innerHTML="<canvas id=\"screen\" width=\"1024\" height=\"768\"></canvas>"
    cv = document.getElementById("screen");
    ctx = cv.getContext("2d");
    background.src = "../IMAGE/BKG.png";
    background.onload = drawBackground;
}
function drawBackground(){
    ctx.drawImage(background,0,768,1024,768,0,0,1024,768);
    drawGrid(8,200);
    drawGrid(516,200);
    drawMark(8,200);
}

function drawGrid(x,y){
    ctx.fillStyle = "rgb(19,180,255)";
    ctx.fillRect(x,y,500,500);
    for(var i = 50; i <= 450 ; i+=50 ){
        ctx.moveTo(x+i,y);
        ctx.lineTo(x+i,y+500);
        ctx.stroke();
    }

    for(var i = 50; i <= 450 ; i+=50 ){
        ctx.moveTo(x,y+i);
        ctx.lineTo(x+500,y+i);
        ctx.stroke();
    }
}

function drawMark(x,y){
    var w = 50;
    for(var i = 0; i<=9; i++){
        if(myMap[i]){
            ctx.fillStyle="yellow";
            ctx.strokeStyle="black";
            ctx.fillRect(x+i*w, y, w,w);
            ctx.stroke();

        }
    }
}<commit_msg>src error<commit_after>    var cv ;
    var ctx;
    var background = new Image();
    var myMap = [true,false,false,true,true,false,false];
function game(){
    document.getElementById("body").innerHTML="<canvas id=\"screen\" width=\"1024\" height=\"768\"></canvas>"
    cv = document.getElementById("screen");
    ctx = cv.getContext("2d");
    background.src = "../image/BKG.png";
    background.onload = drawBackground;
}
function drawBackground(){
    ctx.drawImage(background,0,768,1024,768,0,0,1024,768);
    drawGrid(8,200);
    drawGrid(516,200);
    drawMark(8,200);
}

function drawGrid(x,y){
    ctx.fillStyle = "rgb(19,180,255)";
    ctx.fillRect(x,y,500,500);
    for(var i = 50; i <= 450 ; i+=50 ){
        ctx.moveTo(x+i,y);
        ctx.lineTo(x+i,y+500);
        ctx.stroke();
    }

    for(var i = 50; i <= 450 ; i+=50 ){
        ctx.moveTo(x,y+i);
        ctx.lineTo(x+500,y+i);
        ctx.stroke();
    }
}

function drawMark(x,y){
    var w = 50;
    for(var i = 0; i<=9; i++){
        if(myMap[i]){
            ctx.fillStyle="yellow";
            ctx.strokeStyle="black";
            ctx.fillRect(x+i*w, y, w,w);
            ctx.stroke();

        }
    }
}<|endoftext|>