	
	// sync way to call ajax
	// Usage: var a = await ajaxp({url: 'down.php'});
	function ajaxp(in_param = {}){
		var param = {
			url: '',
			method: 'post',
			post_data: '',
			custom: {}
		}

		if(in_param['url'] !== undefined){ param['url'] = in_param['url'];	}
		if(in_param['callback'] !== undefined){ param['callback'] = in_param['callback'];	}
		if(in_param['method'] !== undefined){ param['method'] = in_param['method'];	}
		if(in_param['post_data'] !== undefined){ param['post_data'] = in_param['post_data'];	}


		return new Promise(function (resolve, reject) {
	        let xhr = new XMLHttpRequest();
	        xhr.open(param.method, param.url);

	        // past post parameter
			// xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
			// xhr.send(param.post_data);

	        xhr.onload = function () {
	            if (this.status >= 200 && this.status < 300) {
	                resolve(xhr.response);
	            } else {
	                reject({
	                    status: this.status,
	                    statusText: xhr.statusText
	                });
	            }
	        };
	        xhr.onerror = function () {
	            reject({
	                status: this.status,
	                statusText: xhr.statusText
	            });
	        };

	        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
	        xhr.send(param.post_data);
	        // xhr.send();
	    });

	}

	function makeRequest(method, url) {
	    return new Promise(function (resolve, reject) {
	        let xhr = new XMLHttpRequest();
	        xhr.open(method, url);
	        xhr.onload = function () {
	            if (this.status >= 200 && this.status < 300) {
	                resolve(xhr.response);
	            } else {
	                reject({
	                    status: this.status,
	                    statusText: xhr.statusText
	                });
	            }
	        };
	        xhr.onerror = function () {
	            reject({
	                status: this.status,
	                statusText: xhr.statusText
	            });
	        };
	        xhr.send();
	    });
	}
	// function ajaxp(in_param = {}){
	// 	return new Promise(function (resolve, reject) {
	// 		ajax(in_param);
	// 	});
	// }

	function ajax(in_param = {}){
		var param = {
			url: '',
			callback: function(str){},
			method: 'post',
			post_data: '',
			content_type: 'application/x-www-form-urlencoded',
			custom: {},
			sync: false
		}

		if(in_param['url'] !== undefined){ param['url'] = in_param['url'];	}
		if(in_param['callback'] !== undefined){ param['callback'] = in_param['callback'];	}
		if(in_param['method'] !== undefined){ param['method'] = in_param['method'];	}
		if(in_param['post_data'] !== undefined){ param['post_data'] = in_param['post_data'];	}
		if(in_param['content_type'] !== undefined){ param['content_type'] = in_param['content_type'];	}
		if(in_param['sync'] !== undefined){ param['sync'] = in_param['sync'];	}

		console.log(param);

		var xhr = new XMLHttpRequest();
		xhr.open(param.method, param.url, !param.sync); // `false` makes the request synchronous

		// past post parameter
		xhr.setRequestHeader('Content-type', param['content_type']);
		xhr.send(param.post_data);
		// xhr.send();

		if(in_param['custom'] !== undefined){
			xhr.onload = function(){ param.callback(xhr.responseText, in_param['custom']); }	
			return xhr.responseText;
		}else{
			xhr.onload = function(){ param.callback(xhr.responseText); }	
			return xhr.responseText;
		}

	}

	function readUrlParam(){
		let url = new URL(window.location.href)
		let params = new URLSearchParams(url.search);

		return params;
	}

	function convertTimestamp(unix_timestamp){
		// let unix_timestamp = 1616637604
		var date = new Date(unix_timestamp * 1000); // include millisecond second, total lengh 13, without msec 10
		var year = date.getFullYear();
		var month = ("0" + (date.getMonth() + 1)).substr(-2);	// js month is counting from 0-11....
		var day = ("0" + date.getDate()).substr(-2);

		var hours   = ("0" + date.getHours()).substr(-2);
		var minutes = ("0" + date.getMinutes()).substr(-2);
		var seconds = ("0" + date.getSeconds()).substr(-2);

		var formattedDate = year + '-' + month + '-' + day;
		var formattedTime = hours + ':' + minutes;
		// var formattedTime = hours + ':' + minutes + ':' + seconds;

		// console.log(formattedDate);
		// console.log(formattedTime);
		// console.log(year);
		// console.log(month);
		// console.log(day);

		return [formattedDate, formattedTime];
	}

	function displayTimestamp(unix_timestamp){
		var ut_date = convertTimestamp(unix_timestamp);
		var today = convertTimestamp(Date.now().toString().substr(0, 10));

		// console.log(today);

		if(ut_date[0] == today[0]){ return ut_date[1]; }
		else if(ut_date[0].substr(0, 4) != today[0].substr(0,4)) return ut_date[0].substr(0,10)
		else return ut_date[0].substr(-5) + ' ' + ut_date[1];
	}


	/*
		convert json to my txt format
		===category
		item_name|item_value
	*/
	window.bl_obj_2_txt = {
		output_txt: function(input){
			var output = "";
			var cl = this;
			input.forEach((category) => {
				// row[cl.key_column] = 
				// console.log(row);
				output += "===" + category['name'] + "\n";
				category['data'].forEach((row) => {
					output += row['key'] + '|' + row['value'] + "\n";
				})
			})

			// console.log(output);
			return output;
		},
		output_obj: function(input){
			var output = [];

			var input_line = input.split("\n");
			// console.log(input_line);
			var category = "";
			var output_category = null;
			input_line.forEach((line) => {
				if(line.length == 0) return;
				if(line.indexOf("===") == 0){
					if(output_category !== null) output.push(output_category);
					category = line.replace('===', '');
					output_category = {"name": category, "data": []};
				}else{
					var row = line.split('|');
					output_category['data'].push(
						{
							"key": row[0],
							"value": row[1]
						}
					)

				}
			})

			if(output_category !== null) output.push(output_category);

			return output;
		}
	}

	// ----------------------- sample call -----------------------
	var test = [
		{
			"name": "category", 
			"data": [
				{"key": "i am key", "value": "this is value"},
				{"key": "i am key 2", "value": "this is value 2"}
			]
		},
		{
			"name": "123", 
			"data": [
				{"key": "not", "value": "this is value"},
				{"key": "not 2", "value": "this is value 2"}
			]
		}
	]

	// window.bl_obj_2_txt.set_input(test);
	var input = window.bl_obj_2_txt.output_txt(test);
	console.log(input);
	var output = window.bl_obj_2_txt.output_obj(input);
	console.log(output);
	input = window.bl_obj_2_txt.output_txt(output);
	console.log(input);

