text:
/**
 * jquery-simple-datetimepicker (jquery.simple-dtpicker.js)
 * v1.13.0
 * (c) Masanori Ohgita - 2014.
 * https://github.com/mugifly/jquery-simple-datetimepicker
 */

 (function($) {
	var lang = {
		en: {
			days: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
			months: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
			sep: '-',
			format: 'YYYY-MM-DD hh:mm',
			prevMonth: 'Previous month',
			nextMonth: 'Next month',
			today: 'Today'
		},
		ro:{
			days: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'],
			months: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
			sep: '.',
			format: 'DD.MM.YYYY hh:mm',
			prevMonth: 'Luna precedentă',
			nextMonth: 'Luna următoare',
			today: 'Azi'
		},

		ja: {
			days: ['日', '月', '火', '水', '木', '金', '土'],
			months: [ "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" ],
			sep: '/',
			format: 'YYYY/MM/DD hh:mm'
		},
		ru: {
			days: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
			months: [ "Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек" ],
			format: 'DD.MM.YYYY hh:mm'
		},
		br: {
			days: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'],
			months: [ "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" ],
			format: 'DD/MM/YYYY hh:mm'
		},
		pt: {
			days: ['dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sáb'],
			months: [ "janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro" ]
		},
		cn: {
			days: ['日', '一', '二', '三', '四', '五', '六'],
			months: [ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" ]
		},
		da: {
			days: ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø'],
			months: [ "Jan", "Feb", "Mar", "Apr", "Maj", "Juni", "Juli", "Aug", "Sept", "Okt", "Nov", "Dec" ],
			sep: '-',
			format: 'DD-MM-YYYY hh:mm',
			prevMonth: 'Forrige måned',
			nextMonth: 'Næste måned',
			today: 'I dag'
		},
		de: {
			days: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
			months: [ "Jan", "Feb", "März", "Apr", "Mai", "Juni", "Juli", "Aug", "Sept", "Okt", "Nov", "Dez" ],
			format: 'DD.MM.YYYY hh:mm'
		},
		sv: {
			days: ['Sö', 'Må', 'Ti', 'On', 'To', 'Fr', 'Lö'],
			months: [ "Jan", "Feb", "Mar", "Apr", "Maj", "Juni", "Juli", "Aug", "Sept", "Okt", "Nov", "Dec" ]
		},
		id: {
			days: ['Min','Sen','Sel', 'Rab', 'Kam', 'Jum', 'Sab'],
			months: [ "Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des" ]
		},
		it: {
			days: ['Dom','Lun','Mar', 'Mer', 'Gio', 'Ven', 'Sab'],
			months: [ "Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic" ],
			format: 'DD/MM/YYYY hh:mm'
		},
		tr: {
			days: ['Pz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cu', 'Cts'],
			months: [ "Ock", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Agu", "Eyl", "Ekm", "Kas", "Arlk" ]
		},
		es: {
			days: ['dom', 'lun', 'mar', 'miér', 'jue', 'vie', 'sáb'],
			months: [ "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic" ],
			format: 'DD/MM/YYYY hh:mm'
		},
		ko: {
			days: ['일', '월', '화', '수', '목', '금', '토'],
			months: [ "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" ],
			sep: '/',
			prevMonth: '이전 달',
			nextMonth: '다음 달',
			today: '오늘'
		},
		nl: {
			days: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
			months: [ "jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec" ],
			format: 'DD-MM-YYYY hh:mm'
		},
		no: {
			days: ['Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'],
			months: [ "Jan", "Feb", "Mar", "Apr", "Mi", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des" ],
			sep: '.',
			format: 'YYYY-MM-DD hh:mm',
			prevMonth: 'Forrige Måned',
			nextMonth: 'Neste Måned',
			today: 'I dag'
		},
		cz: {
			days: ['Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'],
			months: [ "Led", "Úno", "Bře", "Dub", "Kvě", "Čer", "Čvc", "Srp", "Zář", "Říj", "Lis", "Pro" ],
			format: 'DD.MM.YYYY hh:mm'
		},
		fr: {
			days: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
			months: [ "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" ],
			format: 'DD-MM-YYYY hh:mm'
		},
		pl: {
			days: ['N', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So'],
			months: [ "Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień" ],
			sep: '-',
			format: 'YYYY-MM-DD hh:mm',
			prevMonth: 'Poprzedni miesiąc',
			nextMonth: 'Następny miesiąc',
			today: 'Dzisiaj'
		},
		gr: {
			days: ['Κυ', 'Δε', 'Τρ', 'Τε', 'Πε', 'Πα', 'Σα'],
			months: [ "Ιαν", "Φεβ", "Μαρ", "Απρ", "Μαϊ", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ" ],
			sep: '-',
			format: 'DD-MM-YYYY hh:mm',
			prevMonth: 'Προηγ. μήνας',
			nextMonth: 'Επόμ. μήνας',
			today: 'Σήμερα'
		},
		ua: {
			days: ["Неділя","Понеділок","Вівторок","Cереда","Четвер","П'ятниця","Субота"],
			months: ["Cічень","Лютий","Березень","Квітень","Травень","Червня","Липня","Серпня","Вересня","Жовтень","Листопада","Грудня"],
			format: 'YYYY-MM-DD hh:mm',
			prevMonth: 'Попередній місяць',
			nextMonth: 'Наступний місяць',
			today: 'Cьогодні'
		},
		et: {
			days: ['P', 'E', 'T', 'K', 'N', 'R', 'L'],
			months: [ "Jaan", "Veebr", "Märts", "Apr", "Mai", "Juun", "Juul", "Aug", "Sept", "Okt", "Nov", "Dets" ],
			sep: '.',
			format: 'DD.MM.YYYY hh:mm',
			prevMonth: 'Eelmine kuu',
			nextMonth: 'Järgmine kuu',
			today: 'Täna'
		},
		hu: {
			days: ['Va', 'Hé', 'Ke', 'Sze', 'Cs', 'Pé', 'Szo'],
			months: [ "Jan", "Feb", "Már", "Ápr", "Máj", "Jún", "Júl", "Aug", "Szep", "Okt", "Nov", "Dec" ],
			sep: '-',
			format: 'YYYY-MM-DD hh:mm:00',
			prevMonth: 'Előző hónap',
			nextMonth: 'Következő hónap',
			today: 'Ma'
		}
	};
	/* ----- */

	/**
		PickerHandler Object
	**/
	var PickerHandler = function($picker, $input){
		this.$pickerObject = $picker;
		this.$inputObject = $input;
	};

	/* Get a picker */
	PickerHandler.prototype.getPicker = function(){
		return this.$pickerObject;
	};

	/* Get a input-field */
	PickerHandler.prototype.getInput = function(){
		return this.$inputObject;
	};

	/* Get the display state of a picker */
	PickerHandler.prototype.isShow = function(){
		var is_show = true;
		if (this.$pickerObject.css('display') == 'none') {
			is_show = false;
		}
		return is_show;
	};

	/* Show a picker */
	PickerHandler.prototype.show = function(){
		var $picker = this.$pickerObject;
		var $input = this.$inputObject;

		$picker.show();

		ActivePickerId = $input.data('pickerId');

		if ($input != null && $picker.data('isInline') === false) { // Float mode
			// Relocate a picker to position of the appended input-field
			this._relocate();
		}
	};

	/* Hide a picker */
	PickerHandler.prototype.hide = function(){
		var $picker = this.$pickerObject;
		var $input = this.$inputObject;
		$picker.hide();
	};

	/* Get a selected date from a picker */
	PickerHandler.prototype.getDate = function(){
		var $picker = this.$pickerObject;
		var $input = this.$inputObject;
		return getPickedDate($picker);
	};

	/* Set a specific date to a picker */
	PickerHandler.prototype.setDate = function(date){
		var $picker = this.$pickerObject;
		var $input = this.$inputObject;
		if (!isObj('Date', date)) {
			date = new Date(date);
		}

		draw_date($picker, {
			"isAnim": true,
			"isOutputToInputObject": true
		}, date);
	};

	/* Destroy a picker */
	PickerHandler.prototype.destroy = function(){
		var $picker = this.$pickerObject;
		var picker_id = $picker.data('pickerId');
		PickerObjects[picker_id] = null;
		$picker.remove();
	};

	/* Relocate a picker to position of the appended input-field. */
	PickerHandler.prototype._relocate = function(){
		var $picker = this.$pickerObject;
		var $input = this.$inputObject;

		if ($input != null && $picker.data('isInline') === false) { // Float mode
			// Move position of a picker - vertical
			var input_outer_height = $input.outerHeight({'margin': true});
			if (!isObj('Number', input_outer_height)) {
				input_outer_height = $input.outerHeight();
			}
			var picker_outer_height = $picker.outerHeight({'margin': true});
			if (!isObj('Number', picker_outer_height)) {
				picker_outer_height = $picker.outerHeight();
			}

			// Set width to assure date and time are side by side
			if($(".datepicker_calendar", $picker).width() !== 0 && $(".datepicker_timelist", $picker).width() !== 0){
				$picker.parent().width($(".datepicker_calendar", $picker).width() + $(".datepicker_timelist", $picker).width() + 6);
			}
			if(parseInt($(window).height()) <=  ($input.offset().top - $(document).scrollTop() + input_outer_height + picker_outer_height) ){
				// Display to top of an input-field
				$picker.parent().css('top', ($input.offset().top - (input_outer_height / 2) - picker_outer_height) + 'px');
			} else {
				// Display to bottom of an input-field
				$picker.parent().css('top', ($input.offset().top + input_outer_height) + 'px');
			}
			// Move position of a picker - horizontal
			if($picker.parent().width() + $input.offset().left > $(window).width()) {
				// Display left side stick to window
				$picker.parent().css('left', (($(window).width() - $picker.parent().width()) / 2) + 'px');
			} else {
				// Display left side stick to input
				$picker.parent().css('left', $input.offset().left + 'px');
			}
			// Display on most top of the z-index
			$picker.parent().css('z-index', 100000);
		}
	};

	/* ----- */

	var PickerObjects = [];
	var InputObjects = [];
	var ActivePickerId = -1;

	var getParentPickerObject = function(obj) {
		return $(obj).closest('.datepicker');
	};

	var getPickersInputObject = function($obj) {
		var $picker = getParentPickerObject($obj);
		if ($picker.data("inputObjectId") != null) {
			return $(InputObjects[$picker.data("inputObjectId")]);
		}
		return null;
	};

	var setToNow = function($obj) {
		var $picker = getParentPickerObject($obj);
		var date = new Date();
		draw($picker, {
			"isAnim": true,
			"isOutputToInputObject": true
		}, date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes());
	};

	var beforeMonth = function($obj) {
		var $picker = getParentPickerObject($obj);

		if ($picker.data('stateAllowBeforeMonth') === false) { // Not allowed
			return;
		}

		var date = getPickedDate($picker);
		var targetMonth_lastDay = new Date(date.getFullYear(), date.getMonth(), 0).getDate();
		if (targetMonth_lastDay < date.getDate()) {
			date.setDate(targetMonth_lastDay);
		}
		draw($picker, {
			"isAnim": true,
			"isOutputToInputObject": true
		}, date.getFullYear(), date.getMonth() - 1, date.getDate(), date.getHours(), date.getMinutes());

		var todayDate = new Date();
		var isCurrentYear = todayDate.getFullYear() == date.getFullYear();
		var isCurrentMonth = isCurrentYear && todayDate.getMonth() == date.getMonth();

		if (!isCurrentMonth || !$picker.data("futureOnly")) {
			if (targetMonth_lastDay < date.getDate()) {
				date.setDate(targetMonth_lastDay);
			}
			draw($picker, {
				"isAnim": true,
				"isOutputToInputObject": true
			}, date.getFullYear(), date.getMonth() - 1, date.getDate(), date.getHours(), date.getMinutes());
		}
	};

	var nextMonth = function($obj) {
		var $picker = getParentPickerObject($obj);
		var date = getPickedDate($picker);
		var targetMonth_lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
		if (targetMonth_lastDay < date.getDate()) {
			date.setDate(targetMonth_lastDay);
		}

		// Check a last date of a next month
		if (getLastDate(date.getFullYear(), date.getMonth() + 1) < date.getDate()) {
			date.setDate(getLastDate(date.getFullYear(), date.getMonth() + 1));
		}

		draw($picker, {
			"isAnim": true,
			"isOutputToInputObject": true
		}, date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes());
	};

	/**
		Check a last date of a specified year and month
	**/
	var getLastDate = function(year, month) {
		var date = new Date(year, month + 1, 0);
		return date.getDate();
	};

	var getDateFormat = function(format, locale, is_date_only) {
		if (format == "default"){
			// Default format
			format = translate(locale,'format');
			if (is_date_only) {
				// Convert the format to date-only (ex: YYYY/MM/DD)
				format = format.substring(0, format.search(' '));
			}
		}
		return format; // Return date-format
	};

	var normalizeYear = function (year) {
		if (year < 99) { // change year for 4 digits
			var date = new Date();
			return parseInt(year) + parseInt(date.getFullYear().toString().substr(0, 2) + "00");
		}
		return year;
	};
	var parseDate = function (str, opt_date_format) {
		var re, m, date;
		if(opt_date_format != null){
			// Parse date & time with date-format

			// Match a string with date format
			var df = opt_date_format.replace(/(-|\/)/g, '[-\/]')
				.replace(/YYYY/gi, '(\\d{2,4})')
				.replace(/(YY|MM|DD|HH|hh|mm)/g, '(\\d{1,2})')
				.replace(/(M|D|H|h|m)/g, '(\\d{1,2})')
				.replace(/(tt|TT)/g, '([aApP][mM])');
			re = new RegExp(df);
			m = re.exec(str);
			if( m != null){

				// Generate the formats array (convert-table)
				var formats = [];
				var format_buf = '';
				var format_before_c = '';
				var df_ = opt_date_format;
				while (df_ != null && 0 < df_.length) {
					var format_c = df_.substring(0, 1); df_ = df_.substring(1, df_.length);
					if (format_before_c != format_c) {
						if(/(YYYY|YY|MM|DD|mm|dd|M|D|HH|H|hh|h|m|tt|TT)/.test(format_buf)){
							formats.push( format_buf );
							format_buf = '';
						} else {
							format_buf = '';
						}
					}
					format_buf += format_c;
					format_before_c = format_c;
				}
				if (format_buf !== '' && /(YYYY|YY|MM|DD|mm|dd|M|D|HH|H|hh|h|m|tt|TT)/.test(format_buf)){
					formats.push( format_buf );
				}

				// Convert a string (with convert-table) to a date object
				var year, month, day, hour, min;
				var is_successful = false;
				var pm = false;
				var H = false;
				for(var i = 0; i < formats.length; i++){
					if(m.length < i){
						break;
					}

					var f = formats[i];
					var d = m[i+1]; // Matched part of date
					if(f == 'YYYY'){
						year = normalizeYear(d);
						is_successful = true;
					} else if(f == 'YY'){
						year = parseInt(d) + 2000;
						is_successful = true;
					} else if(f == 'MM' || f == 'M'){
						month = parseInt(d) - 1;
						is_successful = true;
					} else if(f == 'DD' || f == 'D'){
						day = d;
						is_successful = true;
					} else if(f == 'hh' || f == 'h'){
						hour = d;
						is_successful = true;
					} else if(f == 'HH' || f == 'H'){
						hour = d;
						H = true;
						is_successful = true;
					} else if(f == 'mm' || f == 'm'){
						min = d;
						is_successful = true;
					} else if(f == 'tt' || f == 'TT'){
						if(d == 'pm' || d == 'PM'){
							pm = true;
						}
						is_successful = true;
					}
				}
				if(H) {
					if(pm) {
						if(hour != 12) {
							hour = parseInt(hour) + 12;
						}
					} else if(hour == 12) {
						hour = 0;
					}
				}
				date = new Date(year, month, day, hour, min);

				if(is_successful === true && isNaN(date) === false && isNaN(date.getDate()) === false){ // Parse successful
					return date;
				}
			}
		}

		// Parse date & time with common format
		re = /^(\d{2,4})[-\/](\d{1,2})[-\/](\d{1,2}) (\d{1,2}):(\d{1,2})$/;
		m = re.exec(str);
		if (m !== null) {
			m[1] = normalizeYear(m[1]);
			date = new Date(m[1], m[2] - 1, m[3], m[4], m[5]);
		} else {
			// Parse for date-only
			re = /^(\d{2,4})[-\/](\d{1,2})[-\/](\d{1,2})$/;
			m = re.exec(str);
			if(m !== null) {
				m[1] = normalizeYear(m[1]);
				date = new Date(m[1], m[2] - 1, m[3]);
			}
		}

		if(isNaN(date) === false && isNaN(date.getDate()) === false){ // Parse successful
			return date;
		}
		return false;
	};
	var getFormattedDate = function(date, date_format) {
		if(date == null){
			date = new Date();
		}

		var y = date.getFullYear();
		var m = date.getMonth() + 1;
		var d = date.getDate();
		var hou = date.getHours();
		var min = date.getMinutes();

		date_format = date_format.replace(/YYYY/gi, y)
		.replace(/YY/g, y - 2000)/* century */
		.replace(/MM/g, zpadding(m))
		.replace(/M/g, m)
		.replace(/DD/g, zpadding(d))
		.replace(/D/g, d)
		.replace(/hh/g, zpadding(hou))
		.replace(/h/g, hou)
		.replace(/HH/g, (hou > 12? zpadding(hou - 12) : (hou < 1? 12 : zpadding(hou))))
		.replace(/H/g, (hou > 12? hou - 12 : (hou < 1? 12 : hou)))
		.replace(/mm/g, zpadding(min))
		.replace(/m/g, min)
		.replace(/tt/g, (hou >= 12? "pm" : "am"))
		.replace(/TT/g, (hou >= 12? "PM" : "AM"));
		return date_format;
	};

	var outputToInputObject = function($picker) {
		var $inp = getPickersInputObject($picker);
		if ($inp == null) {
			return;
		}
		var date = getPickedDate($picker);
		var locale = $picker.data("locale");
		var format = getDateFormat($picker.data("dateFormat"), locale, $picker.data('dateOnly'));

		var old = $inp.val();
		$inp.val(getFormattedDate(date, format));
		if (old != $inp.val()) { // only trigger if it actually changed to avoid a nasty loop condition
			$inp.trigger("change");
		}
	};

	var getPickedDate = function($obj) {
		var $picker = getParentPickerObject($obj);
		return $picker.data("pickedDate");
	};

	var zpadding = function(num) {
		num = ("0" + num).slice(-2);
		return num;
	};

	var draw_date = function($picker, option, date) {
		//console.log("draw_date - " + date.toString());
		draw($picker, option, date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes());
	};
	var translate = function(locale, s) {
		if (typeof lang[locale][s] !== "undefined"){
			return lang[locale][s];
		}
		return lang.en[s];
	};
	var draw = function($picker, option, year, month, day, hour, min) {
		var date = new Date();

		if (hour != null) {
			date = new Date(year, month, day, hour, min, 0);
		} else if (year != null) {
			date = new Date(year, month, day);
		} else {
			date = new Date();
		}

		/* Read options */
		var isTodayButton = $picker.data("todayButton");
		var isCloseButton = $picker.data("closeButton");
		var isScroll = option.isAnim; /* It same with isAnim */
		if($picker.data("timelistScroll") === false) {// If disabled by user option.
			isScroll = false;
		}

		var isAnim = option.isAnim;
		if($picker.data("animation") === false){ // If disabled by user option.
			isAnim = false;
		}

		var isFutureOnly = $picker.data("futureOnly");
		var minDate = $picker.data("minDate");
		var maxDate = $picker.data("maxDate");

		var isOutputToInputObject = option.isOutputToInputObject;

		var minuteInterval = $picker.data("minuteInterval");
		var firstDayOfWeek = $picker.data("firstDayOfWeek");

		var allowWdays = $picker.data("allowWdays");
		if (allowWdays == null || isObj('Array', allowWdays) === false || allowWdays.length <= 0) {
			allowWdays = null;
		}

		var minTime = $picker.data("minTime");
		var maxTime = $picker.data("maxTime");

		/* Check a specified date */
		var todayDate = new Date();
		if (isFutureOnly) {
			if (date.getTime() < todayDate.getTime()) { // Already passed
				date.setTime(todayDate.getTime());
			}
		}
		if(allowWdays != null && allowWdays.length <= 6) {
			while (true) {
				if ($.inArray(date.getDay(), allowWdays) == -1) { // Unallowed wday
					// Slide a date
					date.setDate(date.getDate() + 1);
				} else {
					break;
				}
			}
		}

		/* Read locale option */
		var locale = $picker.data("locale");
		if (!lang.hasOwnProperty(locale)) {
			locale = 'en';
		}

		/* Calculate dates */
		var firstWday = new Date(date.getFullYear(), date.getMonth(), 1).getDay() - firstDayOfWeek;
		var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
		var beforeMonthLastDay = new Date(date.getFullYear(), date.getMonth(), 0).getDate();
		var dateBeforeMonth = new Date(date.getFullYear(), date.getMonth(), 0);
		var dateNextMonth = new Date(date.getFullYear(), date.getMonth() + 2, 0);
		var isCurrentYear = todayDate.getFullYear() == date.getFullYear();
		var isCurrentMonth = isCurrentYear && todayDate.getMonth() == date.getMonth();
		var isCurrentDay = isCurrentMonth && todayDate.getDate() == date.getDate();
		var isNextYear = (todayDate.getFullYear() + 1 == date.getFullYear());
		var isNextMonth = (isCurrentYear && todayDate.getMonth() + 1 == date.getMonth()) ||
			(isNextYear && todayDate.getMonth() === 11 && date.getMonth() === 0);
		var isPastMonth = false;
		if (date.getFullYear() < todayDate.getFullYear() || (isCurrentYear && date.getMonth() < todayDate.getMonth())) {
			isPastMonth = true;
		}

		/* Collect each part */
		var $header = $picker.children('.datepicker_header');
		var $inner = $picker.children('.datepicker_inner_container');
		var $calendar = $picker.children('.datepicker_inner_container').children('.datepicker_calendar');
		var $table = $calendar.children('.datepicker_table');
		var $timelist = $picker.children('.datepicker_inner_container').children('.datepicker_timelist');

		/* Grasp a point that will be changed */
		var changePoint = "";
		var oldDate = getPickedDate($picker);
		if(oldDate != null){
			if(oldDate.getMonth() != date.getMonth() || oldDate.getDate() != date.getDate()){
				changePoint = "calendar";
			} else if (oldDate.getHours() != date.getHours() || oldDate.getMinutes() != date.getMinutes()){
				if(date.getMinutes() === 0 || date.getMinutes() % minuteInterval === 0){
					changePoint = "timelist";
				}
			}
		}

		/* Save newly date to Picker data */
		$($picker).data("pickedDate", date);

		/* Fade-out animation */
		if (isAnim === true) {
			if(changePoint == "calendar"){
				$calendar.stop().queue([]);
				$calendar.fadeTo("fast", 0.8);
			}else if(changePoint == "timelist"){
				$timelist.stop().queue([]);
				$timelist.fadeTo("fast", 0.8);
			}
		}
		/* Remind timelist scroll state */
		var drawBefore_timeList_scrollTop = $timelist.scrollTop();

		/* New timelist  */
		var timelist_activeTimeCell_offsetTop = -1;

		/* Header ----- */
		$header.children().remove();

		var cDate =  new Date(date.getTime());
		cDate.setMinutes(59);
		cDate.setHours(23);
		cDate.setSeconds(59);
		cDate.setDate(0); // last day of previous month

		var $link_before_month = null;
		if ((!isFutureOnly || !isCurrentMonth) && ((minDate == null) || (minDate < cDate.getTime()))
		) {
			$link_before_month = $('<a>');
			$link_before_month.text('<');
			$link_before_month.prop('alt', translate(locale,'prevMonth'));
			$link_before_month.prop('title', translate(locale,'prevMonth') );
			$link_before_month.click(function() {
				beforeMonth($picker);
			});
			$picker.data('stateAllowBeforeMonth', true);
		} else {
			$picker.data('stateAllowBeforeMonth', false);
		}

		cDate.setMinutes(0);
		cDate.setHours(0);
		cDate.setSeconds(0);
		cDate.setDate(1); // First day of next month
		cDate.setMonth(date.getMonth() + 1);

		var $now_month = $('<span>');
		$now_month.text(date.getFullYear() + " " + translate(locale, 'sep') + " " + translate(locale, 'months')[date.getMonth()]);

		var $link_next_month = null;
		if ((maxDate == null) || (maxDate > cDate.getTime())) {
			$link_next_month = $('<a>');
			$link_next_month.text('>');
			$link_next_month.prop('alt', translate(locale,'nextMonth'));
			$link_next_month.prop('title', translate(locale,'nextMonth'));
			$link_next_month.click(function() {
				nextMonth($picker);
			});
		}

		if (isTodayButton) {
			var $link_today = $('<a><div/></a>');
			$link_today.addClass('icon-home');
			$link_today.prop('alt', translate(locale,'today'));
			$link_today.prop('title', translate(locale,'today'));
			$link_today.click(function() {
				setToNow($picker);
			});
			$header.append($link_today);
		}
		if (isCloseButton) {
			var $link_close = $('<a><div/></a>');
			$link_close.addClass('icon-close');
			$link_close.prop('alt', translate(locale,'close'));
			$link_close.prop('title', translate(locale,'close'));
			$link_close.click(function() {
				$picker.hide();
			});
			$header.append($link_close);
		}

		if ($link_before_month != null) {
			$header.append($link_before_month);
		}
		$header.append($now_month);
		if ($link_next_month != null) {
			$header.append($link_next_month);
		}

		/* Calendar > Table ----- */
		$table.children().remove();
		var $tr = $('<tr>');
		$table.append($tr);

		/* Output wday cells */
		var firstDayDiff = 7 + firstDayOfWeek;
		var daysOfWeek = translate(locale,'days');
		var $td;
		for (var i = 0; i < 7; i++) {
			$td = $('<th>');
			$td.text(daysOfWeek[((i + firstDayDiff) % 7)]);
			$tr.append($td);
		}

		/* Output day cells */
		var cellNum = Math.ceil((firstWday + lastDay) / 7) * 7;
		i = 0;
		if(firstWday < 0){
			i = -7;
		}
		var realDayObj =  new Date(date.getTime());
		realDayObj.setHours(0);
		realDayObj.setMinutes(0);
		realDayObj.setSeconds(0);
		for (var zz = 0; i < cellNum; i++) {
			var realDay = i + 1 - firstWday;

			var isPast = isPastMonth ||
				(isCurrentMonth && realDay < todayDate.getDate()) ||
				(isNextMonth && firstWday > i && (beforeMonthLastDay + realDay) < todayDate.getDate());

			if (i % 7 === 0) {
				$tr = $('<tr>');
				$table.append($tr);
			}

			$td = $('<td>');
			$td.data("day", realDay);

			$tr.append($td);

			if (firstWday > i) {/* Before months day */
				$td.text(beforeMonthLastDay + realDay);
				$td.addClass('day_another_month');
				$td.data("dateStr", dateBeforeMonth.getFullYear() + "/" + (dateBeforeMonth.getMonth() + 1) + "/" + (beforeMonthLastDay + realDay));
				realDayObj.setDate(beforeMonthLastDay + realDay);
				realDayObj.setMonth(dateBeforeMonth.getMonth() );
				realDayObj.setYear(dateBeforeMonth.getFullYear() );
			} else if (i < firstWday + lastDay) {/* Now months day */
				$td.text(realDay);
				$td.data("dateStr", (date.getFullYear()) + "/" + (date.getMonth() + 1) + "/" + realDay);
				realDayObj.setDate( realDay );
				realDayObj.setMonth( date.getMonth()  );
				realDayObj.setYear( date.getFullYear() );
			} else {/* Next months day */
				$td.text(realDay - lastDay);
				$td.addClass('day_another_month');
				$td.data("dateStr", dateNextMonth.getFullYear() + "/" + (dateNextMonth.getMonth() + 1) + "/" + (realDay - lastDay));
				realDayObj.setDate( realDay - lastDay );
				realDayObj.setMonth( dateNextMonth.getMonth() );
				realDayObj.setYear( dateNextMonth.getFullYear() );
			}

			/* Check a wday */
			var wday = ((i + firstDayDiff) % 7);
			if(allowWdays != null) {
				if ($.inArray(wday, allowWdays) == -1) {
					$td.addClass('day_in_unallowed');
					continue; // Skip
				}
			} else if (wday === 0) {/* Sunday */
				$td.addClass('wday_sun');
			} else if (wday == 6) {/* Saturday */
				$td.addClass('wday_sat');
			}

			/* Set a special mark class */
			if (realDay == date.getDate()) { /* selected day */
				$td.addClass('active');
			}

			if (isCurrentMonth && realDay == todayDate.getDate()) { /* today */
				$td.addClass('today');
			}

			var realDayObjMN =  new Date(realDayObj.getTime());
			realDayObjMN.setHours(23);
			realDayObjMN.setMinutes(59);
			realDayObjMN.setSeconds(59);

			if (
				// compare to 23:59:59 on the current day (if MIN is 1pm, then we still need to show this day
				((minDate != null) && (minDate > realDayObjMN.getTime())) || ((maxDate != null) && (maxDate < realDayObj.getTime())) // compare to 00:00:00
			) { // Out of range day
				$td.addClass('out_of_range');
			} else if (isFutureOnly && isPast) { // Past day
				$td.addClass('day_in_past');
			} else {
				/* Set event-handler to day cell */
				$td.click(function() {
					if ($(this).hasClass('hover')) {
						$(this).removeClass('hover');
					}
					$(this).addClass('active');

					var $picker = getParentPickerObject($(this));
					var targetDate = new Date($(this).data("dateStr"));
					var selectedDate = getPickedDate($picker);
					draw($picker, {
						"isAnim": false,
						"isOutputToInputObject": true
					}, targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate(), selectedDate.getHours(), selectedDate.getMinutes());
						if ($picker.data("dateOnly") === true && $picker.data("isInline") === false && $picker.data("closeOnSelected")){
							// Close a picker
							ActivePickerId = -1;
							$picker.hide();
						}
				});

				$td.hover(function() {
					if (! $(this).hasClass('active')) {
						$(this).addClass('hover');
					}
				}, function() {
					if ($(this).hasClass('hover')) {
						$(this).removeClass('hover');
					}
				});
			}

			/* ---- */
		}

		if ($picker.data("dateOnly") === true) {
			/* dateOnly mode */
			$timelist.css("display", "none");
		} else {
			/* Timelist ----- */
			$timelist.children().remove();

			/* Set height to Timelist (Calendar innerHeight - Calendar padding) */
			if ($calendar.innerHeight() > 0) {
				$timelist.css("height", $calendar.innerHeight() - 10 + 'px');
			}

			realDayObj =  new Date(date.getTime());
			$timelist.css("height", $calendar.innerHeight() - 10 + 'px');

			/* Output time cells */
			var hour_ = minTime[0];
			var min_ = minTime[1];

			while( hour_*100+min_ < maxTime[0]*100+maxTime[1] ){

				var $o = $('<div>');
				var is_past_time = hour_ < todayDate.getHours() || (hour_ == todayDate.getHours() && min_ < todayDate.getMinutes());
				var is_past = isCurrentDay && is_past_time;

				$o.addClass('timelist_item');
				var oText = "";
				if($picker.data("amPmInTimeList")){
					oText = /*zpadding*/(hour_ > 12? hour_ - 12 : (hour_ < 1? 12 : hour_));
					oText += ":" + zpadding(min_);
					oText += (hour_ >= 12? "PM" : "AM");
				} else {
					oText = zpadding(hour_) + ":" + zpadding(min_);
				}
				$o.text(oText);
				$o.data("hour", hour_);
				$o.data("min", min_);

				$timelist.append($o);

				realDayObj.setHours(hour_);
				realDayObj.setMinutes(min_);

				if (
					((minDate != null) && (minDate > realDayObj.getTime())) || ((maxDate != null) && (maxDate < realDayObj.getTime()))
				) { // Out of range cell
					$o.addClass('out_of_range');
				} else if (isFutureOnly && is_past) { // Past cell
					$o.addClass('time_in_past');
				} else { // Normal cell
					/* Set event handler to time cell */
					$o.click(function() {
						if ($(this).hasClass('hover')) {
							$(this).removeClass('hover');
						}
						$(this).addClass('active');

						var $picker = getParentPickerObject($(this));
						var date = getPickedDate($picker);
						var hour = $(this).data("hour");
						var min = $(this).data("min");
						draw($picker, {
							"isAnim": false,
							"isOutputToInputObject": true
						}, date.getFullYear(), date.getMonth(), date.getDate(), hour, min);

						if ($picker.data("isInline") === false && $picker.data("closeOnSelected")){
							// Close a picker
							ActivePickerId = -1;
							$picker.hide();
						}
					});

					$o.hover(function() {
						if (! $(this).hasClass('active')) {
							$(this).addClass('hover');
						}
					}, function() {
						if ($(this).hasClass('hover')) {
							$(this).removeClass('hover');
						}
					});
				}

				if (hour_ == date.getHours() && min_ == date.getMinutes()) { /* selected time */
					$o.addClass('active');
					timelist_activeTimeCell_offsetTop = $o.offset().top;
				}

				min_ += minuteInterval;
				if (min_ >= 60){
					min_ = min_ - 60;
					hour_++;
				}

			}

			/* Scroll the timelist */
			if(isScroll === true){
				/* Scroll to new active time-cell position */
				$timelist.scrollTop(timelist_activeTimeCell_offsetTop - $timelist.offset().top);
			}else{
				/* Scroll to position that before redraw. */
				$timelist.scrollTop(drawBefore_timeList_scrollTop);
			}
		}

		/* Fade-in animation */
		if (isAnim === true) {
			if(changePoint == "calendar"){
				$calendar.fadeTo("fast", 1.0);
			}else if(changePoint == "timelist"){
				$timelist.fadeTo("fast", 1.0);
			}
		}

		/* Output to InputForm */
		if (isOutputToInputObject === true) {
			outputToInputObject($picker);
		}
	};

	/* Check for object type */
	var isObj = function(type, obj) {
		/* http://qiita.com/Layzie/items/465e715dae14e2f601de */
		var clas = Object.prototype.toString.call(obj).slice(8, -1);
		return obj !== undefined && obj !== null && clas === type;
	};

	var init = function($obj, opt) {
		/* Container */
		var $picker = $('<div>');

		$picker.destroy = function() {
			window.alert('destroy!');
		};

		$picker.addClass('datepicker');
		$obj.append($picker);

		/* Set current date */
		if(!opt.current) {
			opt.current = new Date();
		} else {
			var format = getDateFormat(opt.dateFormat, opt.locale, opt.dateOnly);
			var date = parseDate(opt.current, format);
			if (date) {
				opt.current = date;
			} else {
				opt.current = new Date();
			}
		}

		/* Set options data to container object  */
		if (opt.inputObjectId != null) {
			$picker.data("inputObjectId", opt.inputObjectId);
		}
		$picker.data("dateOnly", opt.dateOnly);
		$picker.data("pickerId", PickerObjects.length);
		$picker.data("dateFormat", opt.dateFormat);
		$picker.data("locale", opt.locale);
		$picker.data("firstDayOfWeek", opt.firstDayOfWeek);
		$picker.data("animation", opt.animation);
		$picker.data("closeOnSelected", opt.closeOnSelected);
		$picker.data("timelistScroll", opt.timelistScroll);
		$picker.data("calendarMouseScroll", opt.calendarMouseScroll);
		$picker.data("todayButton", opt.todayButton);
		$picker.data("closeButton", opt.closeButton);
		$picker.data('futureOnly', opt.futureOnly);
		$picker.data('onShow', opt.onShow);
		$picker.data('onHide', opt.onHide);
		$picker.data('onInit', opt.onInit);
		$picker.data('allowWdays', opt.allowWdays);

		if(opt.amPmInTimeList === true){
			$picker.data('amPmInTimeList', true);
		} else {
			$picker.data('amPmInTimeList', false);
		}

		var minDate = Date.parse(opt.minDate);
		if (isNaN(minDate)) { // invalid date?
			$picker.data('minDate', null); // set to null
		} else {
			$picker.data('minDate', minDate);
		}

		var maxDate = Date.parse(opt.maxDate);
		if (isNaN(maxDate)) { // invalid date?
			$picker.data('maxDate', null);  // set to null
		} else {
			$picker.data('maxDate', maxDate);
		}
		$picker.data("state", 0);

		if( 5 <= opt.minuteInterval && opt.minuteInterval <= 30 ){
			$picker.data("minuteInterval", opt.minuteInterval);
		} else {
			$picker.data("minuteInterval", 30);
		}
			opt.minTime = opt.minTime.split(':');
			opt.maxTime = opt.maxTime.split(':');

		if(! ((opt.minTime[0] >= 0 ) && (opt.minTime[0] <24 ))){
			opt.minTime[0]="00";
		}
		if(! ((opt.maxTime[0] >= 0 ) && (opt.maxTime[0] <24 ))){
			opt.maxTime[0]="23";
		}
		if(! ((opt.minTime[1] >= 0 ) && (opt.minTime[1] <60 ))){
			opt.minTime[1]="00";
		}
		if(! ((opt.maxTime[1] >= 0 ) && (opt.maxTime[1] <24 ))){
			opt.maxTime[1]="59";
		}
		opt.minTime[0]=parseInt(opt.minTime[0]);
		opt.minTime[1]=parseInt(opt.minTime[1]);
		opt.maxTime[0]=parseInt(opt.maxTime[0]);
		opt.maxTime[1]=parseInt(opt.maxTime[1]);
		$picker.data('minTime', opt.minTime);
		$picker.data('maxTime', opt.maxTime);

		/* Header */
		var $header = $('<div>');
		$header.addClass('datepicker_header');
		$picker.append($header);
		/* InnerContainer*/
		var $inner = $('<div>');
		$inner.addClass('datepicker_inner_container');
		$picker.append($inner);
		/* Calendar */
		var $calendar = $('<div>');
		$calendar.addClass('datepicker_calendar');
		var $table = $('<table>');
		$table.addClass('datepicker_table');
		$calendar.append($table);
		$inner.append($calendar);
		/* Timelist */
		var $timelist = $('<div>');
		$timelist.addClass('datepicker_timelist');
		$inner.append($timelist);

		/* Set event handler to picker */
		$picker.hover(
			function(){
				ActivePickerId = $(this).data("pickerId");
			},
			function(){
				ActivePickerId = -1;
			}
		);

		/* Set event-handler to calendar */
		if (opt.calendarMouseScroll) {
			if (window.sidebar) { // Mozilla Firefox
				$calendar.bind('DOMMouseScroll', function(e){ // Change a month with mouse wheel scroll for Fx
					var $picker = getParentPickerObject($(this));

					// up,left [delta < 0] down,right [delta > 0]
					var delta = e.originalEvent.detail;
					/*
					// this code need to be commented - it's seems to be unnecessary
					// normalization (/3) is not needed as we move one month back or forth
					if(e.originalEvent.axis !== undefined && e.originalEvent.axis == e.originalEvent.HORIZONTAL_AXIS){
						e.deltaX = delta;
						e.deltaY = 0;
					} else {
						e.deltaX = 0;
						e.deltaY = delta;
					}
					e.deltaX /= 3;
					e.deltaY /= 3;
					*/
					if(delta > 0) {
						nextMonth($picker);
					} else {
						beforeMonth($picker);
					}
					return false;
				});
			} else { // Other browsers
				$calendar.bind('mousewheel', function(e){ // Change a month with mouse wheel scroll
					var $picker = getParentPickerObject($(this));
					// up [delta > 0] down [delta < 0]
					if(e.originalEvent.wheelDelta /120 > 0) {
						beforeMonth($picker);
					} else {
						nextMonth($picker);
					}
					return false;
				});
			}
		}

		PickerObjects.push($picker);

		draw_date($picker, {
			"isAnim": true,
			"isOutputToInputObject": opt.autodateOnStart
		}, opt.current);
	};

	var getDefaults = function() {
		return {
			"current": null,
			"dateFormat": "default",
			"locale": "en",
			"animation": true,
			"minuteInterval": 30,
			"firstDayOfWeek": 0,
			"closeOnSelected": false,
			"timelistScroll": true,
			"calendarMouseScroll": true,
			"todayButton": true,
			"closeButton": true,
			"dateOnly": false,
			"futureOnly": false,
			"minDate" : null,
			"maxDate" : null,
			"autodateOnStart": true,
			"minTime":"00:00",
			"maxTime":"23:59",
			"onShow": null,
			"onHide": null,
			"allowWdays": null,
			"amPmInTimeList": false
		};
	};

	/**
	 * Initialize dtpicker
	 */
	 $.fn.dtpicker = function(config) {
		var date = new Date();
		var defaults = getDefaults();

		if(typeof config === "undefined" || config.closeButton !== true){
			defaults.closeButton = false;
		}

		defaults.inputObjectId = undefined;
		var options = $.extend(defaults, config);

		return this.each(function(i) {
			init($(this), options);
		});
	 };

	/**
	 * Initialize dtpicker, append to Text input field
	 * */
	 $.fn.appendDtpicker = function(config) {
		var date = new Date();
		var defaults = getDefaults();

		if(typeof config !== "undefined" && config.inline === true && config.closeButton !== true){
			defaults.closeButton = false;
		}

		defaults.inline = false;
		var options = $.extend(defaults, config);

		return this.each(function(i) {
			/* Checking exist a picker */
			var input = this;
			if(0 < $(PickerObjects[$(input).data('pickerId')]).length) {
				console.log("dtpicker - Already exist appended picker");
				return;
			}

			/* Add input-field with inputsObjects array */
			var inputObjectId = InputObjects.length;
			InputObjects.push(input);

			options.inputObjectId = inputObjectId;

			/* Current date */
			var date, strDate, strTime;
			if($(input).val() != null && $(input).val() !== ""){
				options.current = $(input).val();
			}

			/* Make parent-div for picker */
			var $d = $('<div>');
			if(options.inline){ // Inline mode
				$d.insertAfter(input);
			} else { // Float mode
				$d.css("position","absolute");
				$('body').append($d);
			}

			/* Initialize picker */

			var pickerId = PickerObjects.length;

			var $picker_parent = $($d).dtpicker(options); // call dtpicker() method

			var $picker = $picker_parent.children('.datepicker');

			/* Link input-field with picker*/
			$(input).data('pickerId', pickerId);

			/* Set event handler to input-field */

			$(input).keyup(function() {
				var $input = $(this);
				var $picker = $(PickerObjects[$input.data('pickerId')]);
				if ($input.val() != null && (
					$input.data('beforeVal') == null ||
					( $input.data('beforeVal') != null && $input.data('beforeVal') != $input.val())	)
					) { /* beforeValue == null || beforeValue != nowValue  */
					var format = getDateFormat($picker.data('dateFormat'), $picker.data('locale'), $picker.data('dateOnly'));
					var date = parseDate($input.val(), format);
					//console.log("dtpicker - inputKeyup - format: " + format + ", date: " + $input.val() + " -> " + date);
					if (date) {
						draw_date($picker, {
							"isAnim":true,
							"isOutputToInputObject":false
						}, date);
					}
				}
				$input.data('beforeVal', $input.val());
			});

			$(input).change(function(){
				$(this).trigger('keyup');
			});

			var handler = new PickerHandler($picker, $(input));

			if(options.inline === true){
				/* inline mode */
				$picker.data('isInline',true);
			} else {
				/* float mode */
				$picker.data('isInline',false);
				$picker_parent.css({
					"zIndex": 100
				});
				$picker.css("width","auto");

				/* Hide this picker */
				$picker.hide();

				/* Set onClick event handler for input-field */
				$(input).on('click, focus',function(){
					var $input = $(this);
					var $picker = $(PickerObjects[$input.data('pickerId')]);

					// Generate the handler of a picker
					var handler = new PickerHandler($picker, $input);
					// Get the display state of a picker
					var is_showed = handler.isShow();
					if (!is_showed) {
						// Show a picker
						handler.show();

						// Call a event-hanlder
						var func = $picker.data('onShow');
						if (func != null) {
							console.log("dtpicker- Call the onShow handler");
							func(handler);
						}
					}
				});

				// Set an event handler for resizing of a window
				(function(handler){
					$(window).resize(function(){
						handler._relocate();
					});
					$(window).scroll(function(){
						handler._relocate();
					});
				})(handler);
			}

			// Set an event handler for removing of an input-field
			$(input).bind('destroyed', function() {
				var $input = $(this);
				var $picker = $(PickerObjects[$input.data('pickerId')]);
				// Generate the handler of a picker
				var handler = new PickerHandler($picker, $input);
				// Destroy a picker
				handler.destroy();
			});

			// Call a event-handler
			var func = $picker.data('onInit');
			if (func != null) {
				console.log("dtpicker- Call the onInit handler");
				func(handler);
			}
		});
	};

	/**
	 * Handle a appended dtpicker
	 * */
	var methods = {
		show : function( ) {
			var $input = $(this);
			var $picker = $(PickerObjects[$input.data('pickerId')]);
			if ($picker != null) {
				var handler = new PickerHandler($picker, $input);
				// Show a picker
				handler.show();
			}
		},
		hide : function( ) {
			var $input = $(this);
			var $picker = $(PickerObjects[$input.data('pickerId')]);
			if ($picker != null) {
				var handler = new PickerHandler($picker, $input);
				// Hide a picker
				handler.hide();
			}
		},
		setDate : function( date ) {
			var $input = $(this);
			var $picker = $(PickerObjects[$input.data('pickerId')]);
			if ($picker != null) {
				var handler = new PickerHandler($picker, $input);
				// Set a date
				handler.setDate(date);
			}
		},
		getDate : function( ) {
			var $input = $(this);
			var $picker = $(PickerObjects[$input.data('pickerId')]);
			if ($picker != null) {
				var handler = new PickerHandler($picker, $input);
				// Get a date
				return handler.getDate();
			}
		},
		destroy : function( ) {
			var $input = $(this);
			var $picker = $(PickerObjects[$input.data('pickerId')]);
			if ($picker != null) {
				var handler = new PickerHandler($picker, $input);
				// Destroy a picker
				handler.destroy();
			}
		}
	};

	$.fn.handleDtpicker = function( method ) {
		if ( methods[method] ) {
			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			return methods.init.apply( this, arguments );
		} else {
			$.error( 'Method ' +  method + ' does not exist on jQuery.handleDtpicker' );
		}
	};

	if (!window.console) { // Not available a console on this environment.
		window.console = {};
		window.console.log = function(){};
	}

	/* Define a special event for catch when destroy of an input-field. */
	$.event.special.destroyed = {
		remove: function(o) {
			if (o.handler) {
				o.handler.apply(this, arguments);
			}
		}
  	};

	/* Set event handler to Body element, for hide a floated-picker */
	$(function(){
		$('body').click(function(){
			for(var i=0;i<PickerObjects.length;i++){
				var $picker = $(PickerObjects[i]);
				if(ActivePickerId != i){	/* if not-active picker */
					if($picker.data("inputObjectId") != null && $picker.data("isInline") === false && $picker.css('display') != 'none'){
						/* if append input-field && float picker */

						// Hide a picker
						var $input = InputObjects[$picker.data("inputObjectId")];
						var handler = new PickerHandler($picker, $input);
						handler.hide();

						// Call a event-hanlder
						var func = $picker.data('onHide');
						if (func != null) {
							console.log("dtpicker- Call the onHide handler");
							func(handler);
						}
					}
				}
			}
		});
	});

})(jQuery);


text:
/*************************************************************************/
/*  test_oa_hash_map.cpp                                                 */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "test_oa_hash_map.h"

#include "core/oa_hash_map.h"
#include "core/os/os.h"

namespace TestOAHashMap {

struct CountedItem {
	static int count;

	int id = -1;
	bool destroyed = false;

	CountedItem() {
		count++;
	}

	CountedItem(int p_id) :
			id(p_id) {
		count++;
	}

	CountedItem(const CountedItem &p_other) :
			id(p_other.id) {
		count++;
	}

	CountedItem &operator=(const CountedItem &p_other) = default;

	~CountedItem() {
		CRASH_COND(destroyed);
		count--;
		destroyed = true;
	}
};

int CountedItem::count;

MainLoop *test() {
	OS::get_singleton()->print("\n\n\nHello from test\n");

	// test element tracking.
	{
		OAHashMap<int, int> map;

		map.set(42, 1337);
		map.set(1337, 21);
		map.set(42, 11880);

		int value = 0;
		map.lookup(42, value);

		OS::get_singleton()->print("capacity  %d\n", map.get_capacity());
		OS::get_singleton()->print("elements  %d\n", map.get_num_elements());

		OS::get_singleton()->print("map[42] = %d\n", value);
	}

	// rehashing and deletion
	{
		OAHashMap<int, int> map;

		for (int i = 0; i < 500; i++) {
			map.set(i, i * 2);
		}

		for (int i = 0; i < 500; i += 2) {
			map.remove(i);
		}

		uint32_t num_elems = 0;
		for (int i = 0; i < 500; i++) {
			int tmp;
			if (map.lookup(i, tmp) && tmp == i * 2) {
				num_elems++;
			}
		}

		OS::get_singleton()->print("elements %d == %d.\n", map.get_num_elements(), num_elems);
	}

	// iteration
	{
		OAHashMap<String, int> map;

		map.set("Hello", 1);
		map.set("World", 2);
		map.set("Godot rocks", 42);

		for (OAHashMap<String, int>::Iterator it = map.iter(); it.valid; it = map.next_iter(it)) {
			OS::get_singleton()->print("map[\"%s\"] = %d\n", it.key->utf8().get_data(), *it.value);
		}
	}

	// stress test / test for issue #22928
	{
		OAHashMap<int, int> map;
		int dummy = 0;
		const int N = 1000;
		uint32_t *keys = new uint32_t[N];

		Math::seed(0);

		// insert a couple of random keys (with a dummy value, which is ignored)
		for (int i = 0; i < N; i++) {
			keys[i] = Math::rand();
			map.set(keys[i], dummy);

			if (!map.lookup(keys[i], dummy)) {
				OS::get_singleton()->print("could not find 0x%X despite it was just inserted!\n", unsigned(keys[i]));
			}
		}

		// check whether the keys are still present
		for (int i = 0; i < N; i++) {
			if (!map.lookup(keys[i], dummy)) {
				OS::get_singleton()->print("could not find 0x%X despite it has been inserted previously! (not checking the other keys, breaking...)\n", unsigned(keys[i]));
				break;
			}
		}

		delete[] keys;
	}

	// regression test / test for issue related to #31402
	{
		OS::get_singleton()->print("test for issue #31402 started...\n");

		const int num_test_values = 12;
		int test_values[num_test_values] = { 0, 24, 48, 72, 96, 120, 144, 168, 192, 216, 240, 264 };

		int dummy = 0;
		OAHashMap<int, int> map;
		map.clear();

		for (int i = 0; i < num_test_values; ++i) {
			map.set(test_values[i], dummy);
		}

		OS::get_singleton()->print("test for issue #31402 passed.\n");
	}

	// test collision resolution, should not crash or run indefinitely
	{
		OAHashMap<int, int> map(4);
		map.set(1, 1);
		map.set(5, 1);
		map.set(9, 1);
		map.set(13, 1);
		map.remove(5);
		map.remove(9);
		map.remove(13);
		map.set(5, 1);
	}

	// test memory management of items, should not crash or leak items
	{
		// Exercise different patterns of removal
		for (int i = 0; i < 4; ++i) {
			{
				OAHashMap<String, CountedItem> map;
				int id = 0;
				for (int j = 0; j < 100; ++j) {
					map.insert(itos(j), CountedItem(id));
				}
				if (i <= 1) {
					for (int j = 0; j < 100; ++j) {
						map.remove(itos(j));
					}
				}
				if (i % 2 == 0) {
					map.clear();
				}
			}

			if (CountedItem::count != 0) {
				OS::get_singleton()->print("%d != 0 (not performing the other test sub-cases, breaking...)\n", CountedItem::count);
				break;
			}
		}
	}

	// Test map with 0 capacity.
	{
		OAHashMap<int, String> original_map(0);
		original_map.set(1, "1");
		OS::get_singleton()->print("OAHashMap 0 capacity initialization passed.\n");
	}

	// Test copy constructor.
	{
		OAHashMap<int, String> original_map;
		original_map.set(1, "1");
		original_map.set(2, "2");
		original_map.set(3, "3");
		original_map.set(4, "4");
		original_map.set(5, "5");

		OAHashMap<int, String> map_copy(original_map);

		bool pass = true;
		for (
				OAHashMap<int, String>::Iterator it = original_map.iter();
				it.valid;
				it = original_map.next_iter(it)) {
			if (map_copy.lookup_ptr(*it.key) == nullptr) {
				pass = false;
			}
			if (*it.value != *map_copy.lookup_ptr(*it.key)) {
				pass = false;
			}
		}
		if (pass) {
			OS::get_singleton()->print("OAHashMap copy constructor test passed.\n");
		} else {
			OS::get_singleton()->print("OAHashMap copy constructor test FAILED.\n");
		}

		map_copy.set(1, "Random String");
		if (*map_copy.lookup_ptr(1) == *original_map.lookup_ptr(1)) {
			OS::get_singleton()->print("OAHashMap copy constructor, atomic copy test FAILED.\n");
		} else {
			OS::get_singleton()->print("OAHashMap copy constructor, atomic copy test passed.\n");
		}
	}

	// Test assign operator.
	{
		OAHashMap<int, String> original_map;
		original_map.set(1, "1");
		original_map.set(2, "2");
		original_map.set(3, "3");
		original_map.set(4, "4");
		original_map.set(5, "5");

		OAHashMap<int, String> map_copy(100000);
		map_copy.set(1, "Just a string.");
		map_copy = original_map;

		bool pass = true;
		for (
				OAHashMap<int, String>::Iterator it = map_copy.iter();
				it.valid;
				it = map_copy.next_iter(it)) {
			if (original_map.lookup_ptr(*it.key) == nullptr) {
				pass = false;
			}
			if (*it.value != *original_map.lookup_ptr(*it.key)) {
				pass = false;
			}
		}
		if (pass) {
			OS::get_singleton()->print("OAHashMap assign operation test passed.\n");
		} else {
			OS::get_singleton()->print("OAHashMap assign operation test FAILED.\n");
		}

		map_copy.set(1, "Random String");
		if (*map_copy.lookup_ptr(1) == *original_map.lookup_ptr(1)) {
			OS::get_singleton()->print("OAHashMap assign operation atomic copy test FAILED.\n");
		} else {
			OS::get_singleton()->print("OAHashMap assign operation atomic copy test passed.\n");
		}
	}

	return nullptr;
}

} // namespace TestOAHashMap

redpajama_set_name: RedPajamaGithub


text:
# Disallow hooks (no-hooks)

Mocha proposes hooks that allow code to be run before or after every or all tests. This helps define a common setup or teardown process for every test. The use of these hooks promotes the use of shared state between the tests, and defeats the purpose of having isolated unit tests.

## Rule Details

This rule looks for every call to `before`, `after`, `beforeEach` and `afterEach`.

The following patterns are considered warnings:

```js
describe('foo', function () {
    var mockUser;

    before(function () { // Not allowed
        mockUser = {age: 50};
    });

    after(function () { /* ... */ }); // Not allowed
    beforeEach(function () { /* ... */ }); // Not allowed
    afterEach(function () { /* ... */ }); // Not allowed

    it(function () {
        assert.equals(lib.method(mockUser), 'expectedValue');
    });
});
```

These patterns would not be considered warnings:

```js
function createFixtures() {
    return {
        mockUser: {age: 50}
    };
}

describe('foo', function () {
    it(function () {
        var fixtures = createFixtures();
        assert.equals(lib.method(fixtures.mockUser), 'expectedValue');
    });
});
```

## When Not To Use It

* If you use another library which exposes a similar API as mocha (e.g. `before`, `after`), you should turn this rule off, because it would raise warnings.


text:
#pragma once
#include <materials/Material.h>
#include <string>

class Ray;
class HitRec;
class Material;

/** \brief GeometricObject is the parent of all the geometric primitives
 *         that the raytracer will interact with.
 *
 *   The object contains a pure virtual function Hit that is used to determine
 *   intersection points with the object.
 */
class GeometricObject
{
public:
    GeometricObject();
    ~GeometricObject();
    /** \brief The Hit function is used to intersect rays with the object.
     *
     * It is declared pure virtual so every object who inherits from GeometricObject
     * will be forced to implement this.
     *
     * \param ray is the ray that will be tested for intersection
     * \param tmin is an out parameter returning the minimum intersected t
     * \param hr is the HitRecord @see HitRec
     */
    virtual bool Hit(const Ray& ray, double& tmin, HitRec& hr) const =0;
    virtual std::string& GetMaterial();
    virtual GeometricObject& SetMaterial(const std::string& material);
    virtual bool DidShadowHit(const Ray& ray, double& t) =0;
protected:
    std::string material;
};


text:
// This file is automatically generated.

package adila.db;

/*
 * Motorola
 *
 * DEVICE: cdma_spyder
 * MODEL: IS12M
 */
final class cdma5fspyder_is12m {
    public static final String DATA = "Motorola||";
}


text:
Soffit is a technology for creating content that runs in [Apereo uPortal][].  It
is intended as an alternative to [JSR-286 portlet development][].

## Why Would I Want Soffits?

You are a Java web application developer.  You are tasked with developing content
for [Apereo uPortal][].

You are not excited about doing Java Portlet development
[in the traditional way][] or even using [Spring Portlet MVC][].  You correctly
conclude that the Java Portlet APIs are _large_, _obtuse_, and _actively
interfere_ with contemporary web development practices and frameworks that you
want to be using.

Apereo Soffit is an alternative approach to producing content for uPortal that
is not based on JSR-286 or the portlet container.

## Topics

1. [Minimal Soffit](minimal_soffit.md)
2. [Publishing a Soffit](publishing_a_soffit.md)
3. [Soffit Data Model](soffit_data_model.md)
4. [Configuration Options](configuration_options.md)
5. [Securing APIs](securing_apis.md)

## A Word on Modern Web User Interfaces

Soffit assumes that you want to develop user interfaces using Javascript and
modern frameworks like [React][], [AngularJS][], [Backbone.js][], _etc_.
Normally a Soffit component will render one time;  considerations like state
changes, transactions, persistence, _etc_. are typically handled with Javascript
and REST APIs.

## Soffit Dataflow

![soffit dataflow](../../images/soffit-sequence.mmd.png)

## Sample Soffit Applications

There are several sample applications in [this repo][].

[Apereo uPortal]: https://www.apereo.org/projects/uportal
[JSR-286 portlet development]: https://jcp.org/en/jsr/detail?id=286
[in the traditional way]: http://www.theserverside.com/tutorial/JSR-286-development-tutorial-An-introduction-to-portlet-programming
[Spring Portlet MVC]: http://docs.spring.io/autorepo/docs/spring/3.2.x/spring-framework-reference/html/portlet.html
[React]: https://facebook.github.io/react/
[AngularJS]: https://angularjs.org/
[Backbone.js]: http://backbonejs.org/
[this repo]: https://github.com/drewwills/soffit-samples


text:
namespace zombye {
    std::unordered_map<std::string, rtti*>& rtti_manager::rttis() {
        static std::unordered_map<std::string, rtti*> rttis;
        return rttis;
    }
    void rtti_manager::register_type(rtti* type_info) {
        if (!type_info) {
            return;
        }
        auto pos = rttis().find(type_info->type_name());
        if (pos == rttis().end()) {
            type_info->reflection_();
            rttis().insert(std::make_pair(type_info->type_name(), type_info));
        }
    }
    rtti* rtti_manager::type_info(const std::string& name) {
        auto pos = rttis().find(name);
        if (pos != rttis().end()) {
            return rttis()[name];
        }
        return nullptr;
    }
}


text:
package data;

import com.comcast.cdn.traffic_control.traffic_router.neustar.data.TarExtractor;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.LogManager;
import org.apache.log4j.PatternLayout;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.InputStream;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.whenNew;

@RunWith(PowerMockRunner.class)
@PrepareForTest({TarExtractor.class, File.class, TarArchiveInputStream.class})
public class TarExtractorTest {

	@Before
	public void before() {
		LogManager.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%d %-5p [%c]: %m%n")));
	}

	@Test
	public void itExtractsTarFile() throws Exception {
		TarArchiveInputStream tarArchiveInputStream = mock(TarArchiveInputStream.class);
		whenNew(TarArchiveInputStream.class).withArguments(any(InputStream.class)).thenReturn(tarArchiveInputStream);

		when(tarArchiveInputStream.getNextTarEntry()).thenAnswer(new Answer() {
			private int count = 0;

			public Object answer(InvocationOnMock invocationOnMock) {
				count++;
				if (count == 1) {
					TarArchiveEntry tarArchiveEntry = mock(TarArchiveEntry.class);
					when(tarArchiveEntry.getName()).thenReturn("data.gpdb");
					when(tarArchiveEntry.isFile()).thenReturn(true);
					return tarArchiveEntry;
				}

				if (count == 2) {
					TarArchiveEntry tarArchiveEntry = mock(TarArchiveEntry.class);
					when(tarArchiveEntry.getName()).thenReturn("IpV6Data");
					when(tarArchiveEntry.isDirectory()).thenReturn(true);
					return tarArchiveEntry;
				}

				return null;
			}
		});

		File directory = mock(File.class);

		File fileInTar = spy(mock(File.class));
		when(fileInTar.createNewFile()).thenReturn(true);
		whenNew(File.class).withArguments(directory, "data.gpdb").thenReturn(fileInTar);

		File directoryInTar = spy(mock(File.class));
		when(directoryInTar.createNewFile()).thenReturn(true);
		whenNew(File.class).withArguments(directory, "IpV6Data").thenReturn(directoryInTar);

		FileOutputStream fileOutputStream = mock(FileOutputStream.class);
		whenNew(FileOutputStream.class).withArguments(fileInTar).thenReturn(fileOutputStream);

		when(tarArchiveInputStream.read(any(byte[].class))).thenAnswer(new Answer() {
			private int count = 0;

			public Object answer(InvocationOnMock invocationOnMock) {
				count++;

				return (count == 1) ? new Integer(654321) : new Integer(-1);
			}
		});

		InputStream inputStream1 = mock(InputStream.class);
		TarExtractor tarExtractor = new TarExtractor();
		assertThat(tarExtractor.extractTo(directory, inputStream1), equalTo(directory));

		verify(fileInTar).createNewFile();
		verify(fileOutputStream).write(any(byte[].class), eq(0), eq(654321));
		verify(fileOutputStream).close();
		verifyNoMoreInteractions(fileOutputStream);

		verifyZeroInteractions(directoryInTar);
	}

	class SimpleFilenameFilter implements FileFilter {
		String name;

		@Override
		public boolean accept(File pathname) {
			return this.name.equals(pathname.getName());
		}
	}
}


text:
<?php
if (!defined('APP_STARTED')) {
    die('Forbidden!');
}

// Sanitize html content:
function e($dirty)
{
    return htmlspecialchars($dirty, ENT_QUOTES, 'UTF-8');
}
?>
<!DOCTYPE html>

        <meta charset="utf-8">

        <?php if ($page['title'] === false): ?>
            <title><?php echo e(APP_NAME) ?></title>
        <?php else: ?>
            <title><?php echo e($page['title']) ?> - <?php echo e(APP_NAME) ?></title>
        <?php endif ?>

        <base href="<?php echo BASE_URL; ?>/">

        <link rel="shortcut icon" href="static/img/favicon.ico">

        <?php if (USE_DARK_THEME): ?>
            <link rel="stylesheet" href="static/css/bootstrap_dark.min.css">
            <link rel="stylesheet" href="static/css/dark/prettify-dark.css">
            <link rel="stylesheet" href="static/css/codemirror.css">
            <link rel="stylesheet" href="static/css/main_dark.css">
            <link rel="stylesheet" href="static/css/dark/codemirror-tomorrow-night-bright.css">
        <?php else: ?>
            <link rel="stylesheet" href="static/css/bootstrap.min.css">
            <link rel="stylesheet" href="static/css/prettify.css">
            <link rel="stylesheet" href="static/css/codemirror.css">
            <link rel="stylesheet" href="static/css/main.css">
        <?php endif; ?>
		<link rel="stylesheet" href="static/css/custom.css">

        <meta name="description" content="<?php echo e($page['description']) ?>">
        <meta name="keywords" content="<?php echo e(join(',', $page['tags'])) ?>">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <?php if (!empty($page['author'])): ?>
            <meta name="author" content="<?php echo e($page['author']) ?>">
        <?php endif; ?>

        <?php if (USE_WIKITTEN_LOGO === true): ?>

Remember to check for updates!

        <?php endif; ?>

<?php echo e(APP_NAME) ?>

                            <?php if (isset($error)): ?>

<?php echo $error; ?>

                            <?php endif; ?>

                            <form action="" method="post">

                                  <input name="username" type="text" placeholder="Enter your username" class="form-control input-sm">

                                  <input name="password" type="password" placeholder="Enter your password" class="form-control input-sm">

                              <button type="submit" name="login" class="btn btn-sm btn-primary">Send!</button>
                            </form>


text:
{% load staticfiles %}
<!DOCTYPE html>

    <title>WebIRC</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/webirc.css' %}">

      WebIRC
      {% if user.is_authenticated %}

Logout

      {% endif %}

    {% block content %}{% endblock content %}


text:
#include "filter_streams.h"
#include <fstream>
#include <mutex>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/version.hpp>
#include <boost/lexical_cast.hpp>
#include "jml/arch/exception.h"
#include "jml/arch/format.h"
#include "string_functions.h"
#include <errno.h>
#include <sstream>
#include <thread>
#include <unordered_map>
#include "lzma.h"
#include "lz4_filter.h"

using namespace std;

namespace ML {

const UriHandlerFunction &
getUriHandler(const std::string & scheme);

std::pair<std::string, std::string>
getScheme(const std::string & uri)
{
    string::size_type pos = uri.find("://");
    if (pos == string::npos) {
        return make_pair("file", uri);
    }

    string scheme(uri, 0, pos);
    string resource(uri, pos + 3);

    return make_pair(scheme, resource);
}

/*****************************************************************************/
/* FILTER_OSTREAM                                                            */
/*****************************************************************************/

filter_ostream::filter_ostream()
    : ostream(std::cout.rdbuf())
{
}

filter_ostream::
filter_ostream(filter_ostream && other) noexcept
    : ostream(other.rdbuf()),
    stream(std::move(other.stream)),
    sink(std::move(other.sink))
{
}

filter_ostream::
filter_ostream(const std::string & file, std::ios_base::openmode mode,
               const std::string & compression, int level)
    : ostream(std::cout.rdbuf())
{
    open(file, mode, compression, level);
}

filter_ostream::
filter_ostream(int fd, std::ios_base::openmode mode,
               const std::string & compression, int level)
    : ostream(std::cout.rdbuf())
{
    open(fd, mode, compression, level);
}

filter_ostream::
filter_ostream(int fd,
               const std::map<std::string, std::string> & options)
    : ostream(std::cout.rdbuf())
{
    open(fd, options);
}

filter_ostream::
filter_ostream(const std::string & uri,
               const std::map<std::string, std::string> & options)
    : ostream(std::cout.rdbuf())
{
    open(uri, options);
}

filter_ostream::
~filter_ostream()
{
    close();
}

filter_ostream &
filter_ostream::
operator = (filter_ostream && other)
{
    exceptions(ios::goodbit);
    stream = std::move(other.stream);
    sink = std::move(other.sink);
    rdbuf(other.rdbuf());
    exceptions(other.exceptions());
    other.exceptions(ios::goodbit);
    other.rdbuf(0);

    return *this;
}

namespace {

bool ends_with(const std::string & str, const std::string & what)
{
    string::size_type result = str.rfind(what);
    return result != string::npos
        && result == str.size() - what.size();
}

void addCompression(streambuf & buf,
                    boost::iostreams::filtering_ostream & stream,
                    const std::string & resource,
                    const std::string & compression,
                    int compressionLevel)
{
    using namespace boost::iostreams;

    if (compression == "gz" || compression == "gzip"
        || (compression == ""
            && (ends_with(resource, ".gz") || ends_with(resource, ".gz~")))) {
        gzip_compressor compressor;
        if (compressionLevel != -1) {
            compressor = gzip_compressor(compressionLevel);
        }
        compressor.write(buf, "", 0);
        stream.push(compressor);
    }
    else if (compression == "bz2" || compression == "bzip2"
        || (compression == ""
            && (ends_with(resource, ".bz2") || ends_with(resource, ".bz2~")))) {
        if (compressionLevel == -1)
            stream.push(bzip2_compressor());
        else stream.push(bzip2_compressor(compressionLevel));
    }
    else if (compression == "lzma" || compression == "xz"
        || (compression == ""
            && (ends_with(resource, ".xz") || ends_with(resource, ".xz~")))) {
        if (compressionLevel == -1)
            stream.push(lzma_compressor());
        else stream.push(lzma_compressor(compressionLevel));
    }
    else if (compression == "lz4"
        || (compression == ""
            && (ends_with(resource, ".lz4") || ends_with(resource, ".lz4~")))) {
        stream.push(lz4_compressor(compressionLevel));
    }
    else if (compression != "" && compression != "none")
        throw ML::Exception("unknown filter compression " + compression);

}

void addCompression(streambuf & buf,
                    boost::iostreams::filtering_ostream & stream,
                    const std::string & resource,
                    const std::map<std::string, std::string> & options)
{
    string compression;
    auto it = options.find("compression");
    if (it != options.end())
        compression = it->second;

    int compressionLevel = -1;
    it = options.find("compressionLevel");
    if (it != options.end())
        compressionLevel = boost::lexical_cast<int>(it->second);

    addCompression(buf, stream, resource, compression, compressionLevel);
}

/** Create an options map from a set of legacy options passed by value. */
std::map<std::string, std::string>
createOptions(std::ios_base::openmode mode,
              const std::string & compression,
              int compressionLevel)
{
    /*
app	(append) Set the stream's position indicator to the end of the stream before each output operation.
ate	(at end) Set the stream's position indicator to the end of the stream on opening.
binary	(binary) Consider stream as binary rather than text.
in	(input) Allow input operations on the stream.
out	(output) Allow output operations on the stream.
trunc	(truncate) Any current content is discarded, assuming a length of zero on opening.
    */

    string modeStr;
    auto addMode = [&] (int mask, const char * name)
        {
            if ((mode & mask) == 0)
                return;
            if (!modeStr.empty())
                modeStr += ',';
            modeStr += name;
        };

    addMode(ios_base::app, "app");
    addMode(ios_base::ate, "ate");
    addMode(ios_base::binary, "binary");
    addMode(ios_base::in, "in");
    addMode(ios_base::out, "out");
    addMode(ios_base::trunc, "trunc");

    //cerr << "compression = " << compression << endl;

    std::map<std::string, std::string> result;

    if (!modeStr.empty())
        result["mode"] = modeStr;
    if (!compression.empty())
        result["compression"] = compression;
    if (compressionLevel != -1)
        result["compressionLevel"] = std::to_string(compressionLevel);

    return result;
}

std::ios_base::openmode getMode(const std::map<std::string, std::string> & options)
{
    std::ios_base::openmode result
        = std::ios_base::openmode(0);

    auto it = options.find("mode");
    if (it == options.end())
        return result;

    vector<string> elements = split(it->second, ',');

    for (auto & el: elements) {
        if (el == "app")
            result |= ios_base::app;
        else if (el == "ate")
            result |= ios_base::ate;
        else if (el == "binary")
            result |= ios_base::binary;
        else if (el == "in")
            result |= ios_base::in;
        else if (el == "out")
            result |= ios_base::out;
        else if (el == "trunc")
            result |= ios_base::trunc;
        else throw ML::Exception("unknown filter_stream open mode " + el);
    }

    return result;
}

} // file scope

void
filter_ostream::
open(const std::string & uri, std::ios_base::openmode mode,
     const std::string & compression, int compressionLevel)
{
    //cerr << "uri = " << uri << " compression = " << compression << endl;

    open(uri, createOptions(mode, compression, compressionLevel));
}

void
filter_ostream::
open(const std::string & uri, std::ios_base::openmode mode,
     const std::string & compression, int compressionLevel,
     unsigned int numThreads)
{
    //cerr << "uri = " << uri << " compression = " << compression << endl;
    std::map<std::string, std::string>  options =
         createOptions(mode, compression, compressionLevel);
    // add the number of threads to the options
    options["num-threads"] = to_string(numThreads);
    open(uri, options);
}

void
filter_ostream::
open(const std::string & uri,
     const std::map<std::string, std::string> & options)
{
    using namespace boost::iostreams;

    string scheme, resource;
    std::tie(scheme, resource) = getScheme(uri);

    std::ios_base::openmode mode = getMode(options);
    if (!mode)
        mode = std::ios_base::out;

    //cerr << "opening scheme " << scheme << " resource " << resource
    //     << endl;

    const auto & handler = getUriHandler(scheme);
    std::streambuf * buf;
    bool weOwnBuf;
    std::tie(buf, weOwnBuf) = handler(scheme, resource, mode, options);

    return openFromStreambuf(buf, weOwnBuf, resource, options);
}

void
filter_ostream::
openFromStreambuf(std::streambuf * buf,
                  bool weOwnBuf,
                  const std::string & resource,
                  const std::string & compression,
                  int compressionLevel)
{
    openFromStreambuf(buf, weOwnBuf, resource,
                      createOptions(std::ios_base::openmode(0),
                                    compression, compressionLevel));
}

void
filter_ostream::
openFromStreambuf(std::streambuf * buf,
                  bool weOwnBuf,
                  const std::string & resource,
                  const std::map<std::string, std::string> & options)
{

    // TODO: exception safety for buf

    using namespace boost::iostreams;

    //cerr << "buf = " << (void *)buf << endl;
    //cerr << "weOwnBuf = " << weOwnBuf << endl;

    std::unique_ptr<std::streambuf> sink;
    if (weOwnBuf)
        sink.reset(buf);

    unique_ptr<filtering_ostream> new_stream
        (new filtering_ostream());

    addCompression(*buf, *new_stream, resource, options);

    new_stream->push(*buf);

    this->stream = std::move(new_stream);
    this->sink = std::move(sink);
    rdbuf(this->stream->rdbuf());

    exceptions(ios::badbit | ios::failbit);
}

void filter_ostream::
open(int fd, std::ios_base::openmode mode,
     const std::string & compression, int compressionLevel)
{
    open(fd, createOptions(mode, compression, compressionLevel));
}

void filter_ostream::
open(int fd, const std::map<std::string, std::string> & options)
{
    using namespace boost::iostreams;

    unique_ptr<filtering_ostream> new_stream
        (new filtering_ostream());

    stringbuf headerbuf;
    addCompression(headerbuf, *new_stream, "", options);
    string header = headerbuf.str();
    if (!header.empty()) {
        ssize_t rc = ::write(fd, header.c_str(), header.size());
        if (rc < 0) {
            throw ML::Exception(errno, "open", "open");
        }
    }

#if (BOOST_VERSION < 104100)
    new_stream->push(file_descriptor_sink(fd));
#else
    new_stream->push(file_descriptor_sink(fd,
                                          boost::iostreams::never_close_handle));
#endif
    stream.reset(new_stream.release());
    sink.reset();
    rdbuf(stream->rdbuf());

    exceptions(ios::badbit | ios::failbit);
}

void
filter_ostream::
close()
{
    if (stream) {
        boost::iostreams::flush(*stream);
        boost::iostreams::close(*stream);
    }
    exceptions(ios::goodbit);
    stream.reset();
    sink.reset();
    rdbuf(0);
    options.clear();
    //stream->close();
}

std::string
filter_ostream::
status() const
{
    if (*this) return "good";
    else return format("%s%s%s",
                       fail() ? " fail" : "",
                       bad() ? " bad" : "",
                       eof() ? " eof" : "");
}

/*****************************************************************************/
/* FILTER_ISTREAM                                                            */
/*****************************************************************************/

filter_istream::filter_istream()
    : istream(std::cin.rdbuf())
{
}

filter_istream::
filter_istream(const std::string & file, std::ios_base::openmode mode,
               const std::string & compression)
    : istream(std::cin.rdbuf())
{
    open(file, mode, compression);
}

filter_istream::
filter_istream(filter_istream && other) noexcept
    : istream(other.rdbuf()),
    stream(std::move(other.stream)),
    sink(std::move(other.sink))
{
}

filter_istream::
~filter_istream()
{
    close();
}

filter_istream &
filter_istream::
operator = (filter_istream && other)
{
    exceptions(ios::goodbit);
    stream = std::move(other.stream);
    sink = std::move(other.sink);
    rdbuf(other.rdbuf());
    exceptions(other.exceptions());
    other.exceptions(ios::goodbit);
    other.rdbuf(0);

    return *this;
}

void
filter_istream::
open(const std::string & uri,
     std::ios_base::openmode mode,
     const std::string & compression)
{
    exceptions(ios::badbit);

    string scheme, resource;
    std::tie(scheme, resource) = getScheme(uri);

    const auto & handler = getUriHandler(scheme);
    std::streambuf * buf;
    bool weOwnBuf;
    std::tie(buf, weOwnBuf) = handler(scheme, resource, mode,
                                      createOptions(mode, compression, -1));

    openFromStreambuf(buf, weOwnBuf, resource, compression);
}

void
filter_istream::
openFromStreambuf(std::streambuf * buf,
                  bool weOwnBuf,
                  const std::string & resource,
                  const std::string & compression)
{
    // TODO: exception safety for buf

    using namespace boost::iostreams;

    std::unique_ptr<std::streambuf> sink;
    if (weOwnBuf)
        sink.reset(buf);

    unique_ptr<filtering_istream> new_stream
        (new filtering_istream());

    bool gzip = (compression == "gz" || compression == "gzip"
                 || (compression == ""
                     && (ends_with(resource, ".gz")
                         || ends_with(resource, ".gz~"))));
    bool bzip2 = (compression == "bz2" || compression == "bzip2"
                 || (compression == ""
                     && (ends_with(resource, ".bz2")
                         || ends_with(resource, ".bz2~"))));
    bool lzma = (compression == "xz" || compression == "lzma"
                 || (compression == ""
                     && (ends_with(resource, ".xz")
                         || ends_with(resource, ".xz~"))));

    bool lz4 = (compression == "lz4"
                 || (compression == ""
                     && (ends_with(resource, ".lz4")
                         || ends_with(resource, ".lz4~"))));

    if (gzip) new_stream->push(gzip_decompressor());
    if (bzip2) new_stream->push(bzip2_decompressor());
    if (lzma) new_stream->push(lzma_decompressor());
    if (lz4) new_stream->push(lz4_decompressor());

    new_stream->push(*buf);

    this->stream = std::move(new_stream);
    this->sink = std::move(sink);
    rdbuf(this->stream->rdbuf());
}

void
filter_istream::
close()
{
    if (stream) {
        boost::iostreams::flush(*stream);
        boost::iostreams::close(*stream);
    }
    exceptions(ios::goodbit);
    stream.reset();
    sink.reset();
    rdbuf(0);
}

string
filter_istream::
readAll()
{
    string result;

    char buffer[65536];
    while (*this) {
        read(buffer, sizeof(buffer));
        result.append(buffer, gcount());
    }

    return result;
}

/*****************************************************************************/
/* REGISTRATION                                                              */
/*****************************************************************************/

namespace {

std::mutex uriHandlersLock;
std::unordered_map<std::string, UriHandlerFunction> uriHandlers;

} // file scope

void registerUriHandler(const std::string & scheme,
                        const UriHandlerFunction & handler)
{
    if (!handler)
        throw ML::Exception("registerUriHandler: null handler passed");

    std::unique_lock<std::mutex> guard(uriHandlersLock);
    auto it = uriHandlers.find(scheme);
    if (it != uriHandlers.end())
        throw ML::Exception("already have a Uri handler registered for scheme "
                            + scheme);
    uriHandlers[scheme] = handler;
}

const UriHandlerFunction &
getUriHandler(const std::string & scheme)
{
    std::unique_lock<std::mutex> guard(uriHandlersLock);
    auto it = uriHandlers.find(scheme);
    if (it == uriHandlers.end())
        throw ML::Exception("Uri handler not found for scheme " + scheme);
    return it->second;
}

struct RegisterFileHandler {
    static std::pair<std::streambuf *, bool>
    getFileHandler(const std::string & scheme,
                   std::string resource,
                   std::ios_base::open_mode mode,
                   const std::map<std::string, std::string> & options)
    {
        if (resource == "")
            resource = "/dev/null";

        if (mode == ios::in) {
            if (resource == "-")
                return make_pair(cin.rdbuf(), false);
            unique_ptr<std::filebuf> buf(new std::filebuf);
            buf->open(resource, ios_base::openmode(mode));

            if (!buf->is_open())
                throw ML::Exception("couldn't open file %s: %s",
                                    resource.c_str(), strerror(errno));

            return make_pair(buf.release(), true);
        }
        else if (mode & ios::out) {
            if (resource == "-")
                return make_pair(cout.rdbuf(), false);

            unique_ptr<std::filebuf> buf(new std::filebuf);
            buf->open(resource, ios_base::openmode(mode));

            if (!buf->is_open())
                throw ML::Exception("couldn't open file %s: %s",
                                    resource.c_str(), strerror(errno));

            return make_pair(buf.release(), true);
        }
        else throw ML::Exception("no way to create file handler for non in/out");
    }

    RegisterFileHandler()
    {
        registerUriHandler("file", getFileHandler);
    }

} registerFileHandler;

/* "mem:" scheme for using memory as storage backend. Only useful for testing. */

namespace {

mutex memStringsLock;
map<string, string> memStrings;

} // "mem" scheme

string &
getMemStreamString(const string & name)
{
    unique_lock<mutex> guard(memStringsLock);

    return memStrings.at(name);
}

void
setMemStreamString(const std::string & name,
                   const std::string & contents)
{
    unique_lock<mutex> guard(memStringsLock);

    memStrings.insert({name, contents});
}

void
deleteMemStreamString(const std::string & name)
{
    unique_lock<mutex> guard(memStringsLock);

    memStrings.erase(name);
}

void
deleteAllMemStreamStrings()
{
    unique_lock<mutex> guard(memStringsLock);

    memStrings.clear();
}

struct MemStreamingInOut {
    MemStreamingInOut(string & targetString)
        : open_(true), pos_(0), targetString_(targetString)
    {
    }

    typedef char char_type;

    bool is_open() const
    {
        return open_;
    }

    void close()
    {
        open_ = false;
    }

    bool open_;
    size_t pos_;
    string & targetString_;
};

struct MemStreamingIn : public MemStreamingInOut {
    struct category
        : public boost::iostreams::input,
          public boost::iostreams::device_tag,
          public boost::iostreams::closable_tag
    {
    };

    MemStreamingIn(string & targetString)
        : MemStreamingInOut(targetString)
    {
    }

    streamsize read(char * s, streamsize n)
    {
        streamsize res;
        unique_lock<mutex> guard(memStringsLock);

        size_t maxLen = std::min<size_t>(targetString_.size() - pos_,
                                         n);
        if (maxLen > 0) {
            const char * start = targetString_.c_str() + pos_;
            copy(start, start + maxLen, s);
            pos_ += maxLen;
            res = maxLen;
        }
        else {
            res = -1;
        }

        return res;
    }
};

struct MemStreamingOut : public MemStreamingInOut {
    struct category
        : public boost::iostreams::output,
          public boost::iostreams::device_tag,
          public boost::iostreams::closable_tag
    {
    };

    MemStreamingOut(string & targetString)
        : MemStreamingInOut(targetString)
    {
    }

    streamsize write(const char * s, streamsize n)
    {
        unique_lock<mutex> guard(memStringsLock);

        size_t nextLen = pos_ + n;
        targetString_.reserve(nextLen);
        targetString_.append(s, n);
        pos_ = nextLen;

        return n;
    }
};

struct RegisterMemHandler {
    static pair<streambuf *, bool>
    getMemHandler(const string & scheme,
                  string resource,
                  ios_base::open_mode mode,
                  const map<string, string> & options)
    {
        if (scheme != "mem")
            throw ML::Exception("bad scheme name");
        if (resource == "")
            throw ML::Exception("bad resource name");

        unique_lock<mutex> guard(memStringsLock);

        // cerr << "string resource : " + resource + "\n";
        string & targetString = memStrings[resource];

        unique_ptr<std::streambuf> streamBuf;
        if (mode == ios::in) {
            streamBuf.reset(new boost::iostreams::stream_buffer<MemStreamingIn>(MemStreamingIn(targetString),
                                                                                4096));
        }
        else if (mode == ios::out) {
            streamBuf.reset(new boost::iostreams::stream_buffer<MemStreamingOut>(MemStreamingOut(targetString),
                                                                                4096));
        }
        else {
            throw ML::Exception("unable to create mem handler");
        }
        return make_pair(streamBuf.release(), true);
    }

    RegisterMemHandler()
    {
        registerUriHandler("mem", getMemHandler);
    }

} registerMemHandler;

} // namespace ML


text:
using System;
using System.Web;
using System.IO;
using System.Reflection;
using Microsoft.Web.Administration;
using LTAF.Infrastructure;
using LTAF.Infrastructure.Abstractions;
using Xunit;
using Xunit.Extensions;
using Moq;
using LTAF.Infrastructure.Test.Abstractions;

namespace LTAF.Infrastructure.Test
{
    public class SiteExtensionsFacts
    {
        public class GetUniqueApplicaionNameFacts
        {
            [Fact]
            public void WhenAppNameExist_ShouldReturnNameWithNewIndex_Fact()
            {
                // Arrange
                var appName = Helper.Randomize("/test");
                var serverManager = Helper.ServerManager;
                serverManager.Sites[0].Applications.Add(appName, @"c:\");
                serverManager.Sites[0].Applications.Add(appName + "_1", "");

                // Act
                var newAppName = serverManager.Sites[0].GetUniqueApplicaionName(appName);

                // Assert
                Xunit.Assert.Equal(appName.Trim('/') + "_2", newAppName);
            }
        }

        public class GetVirtualPathFacts
        {
            [Fact]
            public void WhenSourceDoesNotExist_ShouldThrow_Fact()
            {
                // Arrange, Act, Assert
                var exception = Assert.Throws<Exception>(() =>
                    SiteExtensions.GetVirtualPath(Helper.ServerManager.Sites[0], "unknown", ""));

                Xunit.Assert.Equal("Binding for protocol 'unknown' is not defined for the website 'WebSite1'.", exception.Message);
            }
        }
    }
}