<commit_before>(function(){

/* variables */
var v3index = {
	typelist : [],
	current  : '',
	language : 'ja',
	complete : false,
	LS       : false,
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var self = v3index;
var typelist = self.typelist;
var isGecko = (navigator.userAgent.indexOf('Gecko')>-1 && navigator.userAgent.indexOf('KHTML') == -1);

function getEL(id){ return _doc.getElementById(id);}

v3index.extend({
	/* common function */
	addEvent : function(element,type,func){
		if(!!element.addEventListener){ element.addEventListener(type,func,false);}
		else if(!!element.attachEvent){ element.attachEvent("on"+type,func);}
		else                          { element["on"+type] = func;}
	},

	/* onload function */
	onload_include : function(){
		setTimeout(function(){
			if(!window.pzprv3){ setTimeout(arguments.callee,50); return;}
			self.onload_func();
			self.complete = true;
		},10);
	},
	onload_func : function(){
		if(!self.current){
			if(!window.pzprfaq && !self.input_init()){
				var el = getEL("puzmenu_input");
				el.parentNode.removeChild(el);
				getEL("table_input").style.display = 'none';
			}

			var el = getEL("puztypes").firstChild;
			while(!!el){
				if(!!el.tagName && el.tagName.toLowerCase()==='li' &&
				   !!el.id      && el.id.match(/puzmenu_(.+)$/)){
					var typename = RegExp.$1;
					typelist.push(typename);
					self.addEvent(el,"click",self.click_tab);
					if(el.className=="puzmenusel"){ self.current = typename;}
				}
				el = el.nextSibling;
			}
			if(!self.current && typelist.length>0){ self.current = typelist[0];}

			var userlang = (navigator.browserLanguage || navigator.language || navigator.userLanguage);
			if(userlang.substr(0,2)!=='ja'){ self.language = 'en';}
		}
		self.disp();
	},
	input_init : function(){
		// HTML5 - Web localStorage判定用(localStorage)
		try{ if(!!window.localStorage && (!isGecko || !!location.hostname)){ self.LS = true;}}
		catch(e){}

		var cnt=0;
		if(self.urlif.init()) { cnt++;}
		if(self.fileif.init()){ cnt++;}
		if(self.dbif.init())  { cnt++;}

		return (cnt>0);
	},

	reset_func : function(){
		typelist = [];
		self.current  = '';
		self.onload_func();
	},

	/* tab-click function */
	click_tab : function(e){
		var el = (e.target || e.srcElement);
		if(!!el){ self.current = el.id.substr(8); self.disp();}
		if(self.current=="input"){ self.dbif.display();} /* iPhone用 */
	},

	/* display tabs and tables function */
	disp : function(){
		for(var i=0;i<typelist.length;i++){
			var el = getEL("puzmenu_"+typelist[i]);
			var table = getEL("table_"+typelist[i]);
			if(typelist[i]===self.current){
				el.className = "puzmenusel";
				try     { table.style.display = 'table';}
				catch(e){ table.style.display = 'block';} //IE raises error
			}
			else{
				el.className = "puzmenu";
				table.style.display = 'none';
			}
		}
	}
});

/* addEventListener */
self.addEvent(window, 'load', self.onload_include);

/* extern */
window.v3index = v3index;

})();

/*********************/
/* URLInput function */
/*********************/
(function(){

var v3index = window.v3index;

v3index.urlif = {
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var _form;
var self = v3index.urlif;
var isGecko = (navigator.userAgent.indexOf('Gecko')>-1 && navigator.userAgent.indexOf('KHTML') == -1);

v3index.urlif.extend({
	init : function(){
		_form = _doc.urlinput;
		if(!!_form){
			if(v3index.LS){
				v3index.addEvent(getEL("urlinput_btn"), "click", self.urlinput);
				return true;
			}
			else{
				_form.style.display = 'none';
				return false;
			}
		}
	},
	urlinput : function(e){
		var url = getEL("urlinput_text").value;
		if(!!url){
			localStorage['pzprv3_urldata'] = url;
			window.open('./p.html', '');
		}
	}
});

})();

/*********************/
/* FileRead function */
/*********************/
(function(){

var v3index = window.v3index;

v3index.fileif = {
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var _form;
var self = v3index.fileif;
var isGecko = (navigator.userAgent.indexOf('Gecko')>-1 && navigator.userAgent.indexOf('KHTML') == -1);

v3index.fileif.extend({
	init : function(){
		_form = _doc.fileform;
		if(!!_form){
			if(v3index.LS){
				v3index.addEvent(_form.filebox, "change", self.fileinput);
				return true;
			}
			else{
				_form.style.display = 'none';
				return false;
			}
		}
	},

	fileinput : function(e){
		var fileEL = _doc.fileform.filebox;
		if(typeof FileReader != 'undefined'){
			var reader = new FileReader();
			reader.onload = function(e){
				self.fileonload.call(self, e.target.result);
			};
			reader.readAsText(fileEL.files[0]);
		}
		else if(typeof FileList != 'undefined' &&
			    typeof File.prototype.getAsText != 'undefined')
		{
			if(!fileEL.files[0]){ return;}
			this.fileonload(fileEL.files[0].getAsText(''));
		}
		else{
			if(!fileEL.value){ return;}
			_doc.fileform.action = (_doc.domain==='indi.s58.xrea.com'?"fileio.xcg":"fileio.cgi");
			_doc.fileform.submit();
		}

		_doc.fileform.reset();
	},
	fileonload : function(str){
		if(!!str){
			var farray = str.replace(/[\t\r]*\n/g,"\n").split(/\n/);
			var fstr = "", fheader = ['',''];
			for(var i=0;i<farray.length;i++){
				if(farray[i].match(/^http\:\/\//)){ break;}
				fstr += (farray[i]+"\n");
			}

			localStorage['pzprv3_filedata'] = fstr;
			window.open('./p.html', '');
		}
	}
});

})();

/*********************/
/* Database function */
/*********************/
(function(){

var v3index = window.v3index;

v3index.dbif = {
	list   : [],
	LS     : false,
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var _form;
var self = v3index.dbif;
var DBlist = self.list;
var pheader = '';

v3index.dbif.extend({
	init : function(){
		_form = _doc.database;
		if(!!_form){
			if(v3index.LS){
				v3index.addEvent(_form.sorts,    "change", self.display);
				v3index.addEvent(_form.datalist, "change", self.select);
				v3index.addEvent(_form.open,     "click",  self.open);

				pheader = 'pzprv3_storage:data:';
				self.importlist(self.display);
				return true;
			}
			else{
				_form.style.display = 'none';
				return false;
			}
		}
	},
	importlist : function(callback){
		DBlist = [];
		for(var i=1;true;i++){
			var data = localStorage[pheader+i];
			if(!data){ break;}
			var row = JSON.parse(data);
			if(row.id==null){ break;}
			DBlist.push(row);
		}

		if(!!callback){ callback();}
	},
	display : function(){
		switch(_form.sorts.value){
			case 'idlist' : DBlist = DBlist.sort(function(a,b){ return (a.id-b.id);}); break;
			case 'newsave': DBlist = DBlist.sort(function(a,b){ return (b.time-a.time || a.id-b.id);}); break;
			case 'oldsave': DBlist = DBlist.sort(function(a,b){ return (a.time-b.time || a.id-b.id);}); break;
			case 'size'   : DBlist = DBlist.sort(function(a,b){ return (a.col-b.col || a.row-b.row || a.hard-b.hard || a.id-b.id);}); break;
		}

		_form.datalist.innerHTML = "";
		for(var i=0;i<DBlist.length;i++){
			var row = DBlist[i];
			if(!!row){
				var opt = _doc.createElement('option');
				opt.setAttribute('value', row.id);
				opt.innerHTML = self.getcaption(row);
				_form.datalist.appendChild(opt);
			}
		}
		if(DBlist.length>=1){
			_form.datalist.firstChild.setAttribute('selected', 'selected');
			_form.comtext.value = DBlist[0].comment;
		}
		else{
			_form.comtext.value = "";
			_form.datalist.style.width = "180px";
		}
	},
	getcaption : function(row){
		var hardstr = [
			{ja:'−'       , en:'-'     },
			{ja:'らくらく', en:'Easy'  },
			{ja:'おてごろ', en:'Normal'},
			{ja:'たいへん', en:'Hard'  },
			{ja:'アゼン'  , en:'Expert'}
		];

		var datestr = (function(){
			var ni = function(num){ return (num<10?"0":"")+num;}, str = "", date = new Date();
			date.setTime(row.time*1000);
			str += (ni(date.getFullYear()%100) + "/" + ni(date.getMonth()+1) + "/" + ni(date.getDate())+" ");
			str += (ni(date.getHours()) + ":" + ni(date.getMinutes()));
			return str;
		})();

		var str = "";
		str += ((row.id<10?" ":"")+row.id+" : ");
		str += (pzprv3.url.info[row.pid][v3index.language]+" ");
		str += (""+row.col+"×"+row.row+"  ");
		if(!!row.hard || row.hard=='0'){
			str += (hardstr[row.hard][v3index.language]+" ");
		}
		str += ("("+datestr+")");
		return str;
	},

	select : function(){
		var selected = self.getvalue();
		_form.comtext.value = (selected>=0 ? ""+DBlist[selected].comment : "");
	},
	open : function(){
		var selected = self.getvalue();
		if(selected>=0){
			var str = DBlist[selected].pdata.replace(/\//g,"\n");
			if(!!str){
				localStorage['pzprv3_filedata'] = str;
				window.open('./p.html', '');
			}
		}
	},
	getvalue : function(){
		var val = _form.datalist.value;
		if(val!=""){
			for(var i=0;i<DBlist.length;i++){
				if(DBlist[i].id==val){ return i;}
			}
		}
		return -1;
	}
});

})();
<commit_msg>v3index: スコープが3つに分かれていてgetELが未定義になっていたのを修正<commit_after>(function(){

/* variables */
var v3index = {
	typelist : [],
	current  : '',
	language : 'ja',
	complete : false,
	LS       : false,
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var self = v3index;
var typelist = self.typelist;
var isGecko = (navigator.userAgent.indexOf('Gecko')>-1 && navigator.userAgent.indexOf('KHTML') == -1);

function getEL(id){ return _doc.getElementById(id);}

v3index.extend({
	/* common function */
	addEvent : function(element,type,func){
		if(!!element.addEventListener){ element.addEventListener(type,func,false);}
		else if(!!element.attachEvent){ element.attachEvent("on"+type,func);}
		else                          { element["on"+type] = func;}
	},

	/* onload function */
	onload_include : function(){
		setTimeout(function(){
			if(!window.pzprv3){ setTimeout(arguments.callee,50); return;}
			self.onload_func();
			self.complete = true;
		},10);
	},
	onload_func : function(){
		if(!self.current){
			if(!window.pzprfaq && !self.input_init()){
				var el = getEL("puzmenu_input");
				el.parentNode.removeChild(el);
				getEL("table_input").style.display = 'none';
			}

			var el = getEL("puztypes").firstChild;
			while(!!el){
				if(!!el.tagName && el.tagName.toLowerCase()==='li' &&
				   !!el.id      && el.id.match(/puzmenu_(.+)$/)){
					var typename = RegExp.$1;
					typelist.push(typename);
					self.addEvent(el,"click",self.click_tab);
					if(el.className=="puzmenusel"){ self.current = typename;}
				}
				el = el.nextSibling;
			}
			if(!self.current && typelist.length>0){ self.current = typelist[0];}

			var userlang = (navigator.browserLanguage || navigator.language || navigator.userLanguage);
			if(userlang.substr(0,2)!=='ja'){ self.language = 'en';}
		}
		self.disp();
	},
	input_init : function(){
		// HTML5 - Web localStorage判定用(localStorage)
		try{ if(!!window.localStorage && (!isGecko || !!location.hostname)){ self.LS = true;}}
		catch(e){}

		var cnt=0;
		if(self.urlif.init()) { cnt++;}
		if(self.fileif.init()){ cnt++;}
		if(self.dbif.init())  { cnt++;}

		return (cnt>0);
	},

	reset_func : function(){
		typelist = [];
		self.current  = '';
		self.onload_func();
	},

	/* tab-click function */
	click_tab : function(e){
		var el = (e.target || e.srcElement);
		if(!!el){ self.current = el.id.substr(8); self.disp();}
		if(self.current=="input"){ self.dbif.display();} /* iPhone用 */
	},

	/* display tabs and tables function */
	disp : function(){
		for(var i=0;i<typelist.length;i++){
			var el = getEL("puzmenu_"+typelist[i]);
			var table = getEL("table_"+typelist[i]);
			if(typelist[i]===self.current){
				el.className = "puzmenusel";
				try     { table.style.display = 'table';}
				catch(e){ table.style.display = 'block';} //IE raises error
			}
			else{
				el.className = "puzmenu";
				table.style.display = 'none';
			}
		}
	}
});

/* addEventListener */
self.addEvent(window, 'load', self.onload_include);

/* extern */
window.v3index = v3index;

})();

/*********************/
/* URLInput function */
/*********************/
(function(){

var v3index = window.v3index;

v3index.urlif = {
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var _form;
var self = v3index.urlif;
var isGecko = (navigator.userAgent.indexOf('Gecko')>-1 && navigator.userAgent.indexOf('KHTML') == -1);

function getEL(id){ return _doc.getElementById(id);}

v3index.urlif.extend({
	init : function(){
		_form = _doc.urlinput;
		if(!!_form){
			if(v3index.LS){
				v3index.addEvent(getEL("urlinput_btn"), "click", self.urlinput);
				return true;
			}
			else{
				_form.style.display = 'none';
				return false;
			}
		}
	},
	urlinput : function(e){
		var url = getEL("urlinput_text").value;
		if(!!url){
			localStorage['pzprv3_urldata'] = url;
			window.open('./p.html', '');
		}
	}
});

})();

/*********************/
/* FileRead function */
/*********************/
(function(){

var v3index = window.v3index;

v3index.fileif = {
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var _form;
var self = v3index.fileif;
var isGecko = (navigator.userAgent.indexOf('Gecko')>-1 && navigator.userAgent.indexOf('KHTML') == -1);

function getEL(id){ return _doc.getElementById(id);}

v3index.fileif.extend({
	init : function(){
		_form = _doc.fileform;
		if(!!_form){
			if(v3index.LS){
				v3index.addEvent(_form.filebox, "change", self.fileinput);
				return true;
			}
			else{
				_form.style.display = 'none';
				return false;
			}
		}
	},

	fileinput : function(e){
		var fileEL = _doc.fileform.filebox;
		if(typeof FileReader != 'undefined'){
			var reader = new FileReader();
			reader.onload = function(e){
				self.fileonload.call(self, e.target.result);
			};
			reader.readAsText(fileEL.files[0]);
		}
		else if(typeof FileList != 'undefined' &&
			    typeof File.prototype.getAsText != 'undefined')
		{
			if(!fileEL.files[0]){ return;}
			this.fileonload(fileEL.files[0].getAsText(''));
		}
		else{
			if(!fileEL.value){ return;}
			_doc.fileform.action = (_doc.domain==='indi.s58.xrea.com'?"fileio.xcg":"fileio.cgi");
			_doc.fileform.submit();
		}

		_doc.fileform.reset();
	},
	fileonload : function(str){
		if(!!str){
			var farray = str.replace(/[\t\r]*\n/g,"\n").split(/\n/);
			var fstr = "", fheader = ['',''];
			for(var i=0;i<farray.length;i++){
				if(farray[i].match(/^http\:\/\//)){ break;}
				fstr += (farray[i]+"\n");
			}

			localStorage['pzprv3_filedata'] = fstr;
			window.open('./p.html', '');
		}
	}
});

})();

/*********************/
/* Database function */
/*********************/
(function(){

var v3index = window.v3index;

v3index.dbif = {
	list   : [],
	LS     : false,
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var _form;
var self = v3index.dbif;
var DBlist = self.list;
var pheader = '';

v3index.dbif.extend({
	init : function(){
		_form = _doc.database;
		if(!!_form){
			if(v3index.LS){
				v3index.addEvent(_form.sorts,    "change", self.display);
				v3index.addEvent(_form.datalist, "change", self.select);
				v3index.addEvent(_form.open,     "click",  self.open);

				pheader = 'pzprv3_storage:data:';
				self.importlist(self.display);
				return true;
			}
			else{
				_form.style.display = 'none';
				return false;
			}
		}
	},
	importlist : function(callback){
		DBlist = [];
		for(var i=1;true;i++){
			var data = localStorage[pheader+i];
			if(!data){ break;}
			var row = JSON.parse(data);
			if(row.id==null){ break;}
			DBlist.push(row);
		}

		if(!!callback){ callback();}
	},
	display : function(){
		switch(_form.sorts.value){
			case 'idlist' : DBlist = DBlist.sort(function(a,b){ return (a.id-b.id);}); break;
			case 'newsave': DBlist = DBlist.sort(function(a,b){ return (b.time-a.time || a.id-b.id);}); break;
			case 'oldsave': DBlist = DBlist.sort(function(a,b){ return (a.time-b.time || a.id-b.id);}); break;
			case 'size'   : DBlist = DBlist.sort(function(a,b){ return (a.col-b.col || a.row-b.row || a.hard-b.hard || a.id-b.id);}); break;
		}

		_form.datalist.innerHTML = "";
		for(var i=0;i<DBlist.length;i++){
			var row = DBlist[i];
			if(!!row){
				var opt = _doc.createElement('option');
				opt.setAttribute('value', row.id);
				opt.innerHTML = self.getcaption(row);
				_form.datalist.appendChild(opt);
			}
		}
		if(DBlist.length>=1){
			_form.datalist.firstChild.setAttribute('selected', 'selected');
			_form.comtext.value = DBlist[0].comment;
		}
		else{
			_form.comtext.value = "";
			_form.datalist.style.width = "180px";
		}
	},
	getcaption : function(row){
		var hardstr = [
			{ja:'−'       , en:'-'     },
			{ja:'らくらく', en:'Easy'  },
			{ja:'おてごろ', en:'Normal'},
			{ja:'たいへん', en:'Hard'  },
			{ja:'アゼン'  , en:'Expert'}
		];

		var datestr = (function(){
			var ni = function(num){ return (num<10?"0":"")+num;}, str = "", date = new Date();
			date.setTime(row.time*1000);
			str += (ni(date.getFullYear()%100) + "/" + ni(date.getMonth()+1) + "/" + ni(date.getDate())+" ");
			str += (ni(date.getHours()) + ":" + ni(date.getMinutes()));
			return str;
		})();

		var str = "";
		str += ((row.id<10?" ":"")+row.id+" : ");
		str += (pzprv3.url.info[row.pid][v3index.language]+" ");
		str += (""+row.col+"×"+row.row+"  ");
		if(!!row.hard || row.hard=='0'){
			str += (hardstr[row.hard][v3index.language]+" ");
		}
		str += ("("+datestr+")");
		return str;
	},

	select : function(){
		var selected = self.getvalue();
		_form.comtext.value = (selected>=0 ? ""+DBlist[selected].comment : "");
	},
	open : function(){
		var selected = self.getvalue();
		if(selected>=0){
			var str = DBlist[selected].pdata.replace(/\//g,"\n");
			if(!!str){
				localStorage['pzprv3_filedata'] = str;
				window.open('./p.html', '');
			}
		}
	},
	getvalue : function(){
		var val = _form.datalist.value;
		if(val!=""){
			for(var i=0;i<DBlist.length;i++){
				if(DBlist[i].id==val){ return i;}
			}
		}
		return -1;
	}
});

})();
<|endoftext|>


<commit_before>var url         = require('url');
var util        = require('util');
var http        = require('http');
var request     = require('request');
var cheerio     = require('cheerio');
var EE          = require('events').EventEmitter;
var dStop       = require('debug')('schema-check:visitor:stopSearch');
var dReq        = require('debug')('schema-check:visitor:makeRequest');
var dVisitRecur = require('debug')('schema-check:visitor:visitorRecursively');
var dReqVerbose = require('debug')('schema-check:visitor:makeRequest:verbose');

util.inherits(Visitor, EE);

function Visitor() {
  var self = this;

  this.on('stop', function _stopSearchHandler() {
    dStop('_stopSearchHandler: Stopping any more network requests');
    self._stopped = true;
  });
}

Visitor.prototype.visitRecursively = function visitRecursively(inputUrl, state) {
  var self = this;
  var parsedInputUrl;

  dVisitRecur('starting with (raw) input url %s', inputUrl);
  // dVisitRecur('state is %s', state);

  // emit error if inputUrl is falsy and return
  if (!inputUrl) {
    dVisitRecur('emitting error of type InputError');
    this.emit('errored', {
      error: new Error('Empty input url'),
      type: 'InputError',
      input: inputUrl
    });
    return;
  }

  // if state is falsy, set it to empty object
  state = state || {};

  parsedInputUrl = url.parse(inputUrl);

  // if there's no host then emit error and return
  if (!parsedInputUrl.host || !parsedInputUrl.protocol) {
    dVisitRecur('emitting error of type InputError');
    this.emit('errored', {
      error: new Error('Malformed input url. It has no host or protocol'),
      type: 'InputError',
      input: inputUrl
    });
    return;
  }

  // store the initial url that visitor was called with
  // links found on this page are checked if they
  state.origin        = state.origin || parsedInputUrl.host.replace('www.', '');
  state.originWithWWW = state.originWithWWW || 'www.' + state.origin;
  state.protocol      = state.protocol || parsedInputUrl.protocol;

  // trim the last '/' from inputUrl cuz no keys in state have trailing '/'
  inputUrl = '/' === inputUrl[inputUrl.length - 1] ? inputUrl.slice(0, -1) : inputUrl;

  // trim whitespace
  inputUrl = inputUrl.trim();

  // todo: I should probably strip 'www.' from input url to prevent network call for both, say,
  // http://www.x.com and http://x.com
  // but then again, some people might have setup weird redirects for www. and non www.
  // if i decided to enable this, the fix is below
  inputUrl = inputUrl.replace(/^(https?:\/\/)www\./g, '$1');

  dVisitRecur('processed input url is %s', inputUrl);

  // if inputUrl has been visited then return
  if (state[inputUrl]) {
    console.log('Already visited %s', inputUrl);
    return;
  }

  dVisitRecur('has the search been stopped? %s', !!this._stopped);
  // if search has been stopped then just return blindly and dont hit the network
  if (this._stopped) return;

  // mark inputUrl as visited
  state[inputUrl] = true;

  // dVisitRecur('updated state is %o', state);

  // BIG BOI MAKING REQUEST OMG OMG THIS IS THE CALL THAT MAKES IT ALL HAPPEN
  // (including stackoverflow, sigh -.-)
  dVisitRecur('making request for url');
  makeRequest(self, inputUrl, parsedInputUrl, state);

  dVisitRecur('done with url %s. returning..\n', inputUrl);
};

function makeRequest(self, inputUrl, parsedInputUrl, state) {
  request(inputUrl, function _requestHandler(err, res, body) {
    var $;
    var data;
    var $schema;
    // var urlsWithoutHttpAndHttpsRegex = /^(-\.)?([^\s/?\.#-]+\.?)+(\/[^\s]*)?$/i;

    // dReq('res %o', res);
    // dReq('body %s', body);

    dReqVerbose('parsed input url is %o', parsedInputUrl);

    // if error, emit error and return
    if (err) {
      dReq('emitting error of type RequestError %o', err);
      self.emit('errored', {
        error: err,
        message: err.message,
        type: 'RequestError',
        code: 500,
        input: inputUrl
      });
      return;
    }

    // if status is anything other than a 200, emit httpError and return
    if (res.statusCode !== 200) {
      err = new Error(http.STATUS_CODES[res.statusCode]);
      dReq('response status code is %s', res.statusCode);
      dReq('emitting error of type HttpError %o', err);
      self.emit('errored', {
        error: err,
        message: err.message,
        type: 'HttpError',
        input: inputUrl,
        code: res.statusCode
      });
      return;
    }

    //all good, move on

    // load the body into cheerio
    $ = cheerio.load(body);

    // check if any schemas present
    $schema = $('[itemtype*="schema.org"]');

    // no schemas? Emit notFound
    if (!$schema.length) {
      dReq('emitting notFound');
      self.emit('notFound', {
        message: 'No schema found.',
        url: inputUrl
      });
    }
    else {
      /*
        structure
        {
        <itemtype>: {.. <itemprop>: <value> ..}
        }
      */
      data = {};

      // go over each found schema
      $schema.each(function $schemaEachLoopCB(i, v) {
        var obj        = {};
        var $itemprops = $(v).find('[itemprop]');
        var itemtype   = $(v).attr('itemtype') || 'unknownItemtype' + i;

        data[itemtype] = data[itemtype] || {};

        // go over each child of current schema
        $itemprops.each(function $itempropsEachLoopCB(j, w) {
          // its of the form { <itemprop>: <value> }
          // example { name: "JW Heating & Air", streetAddress: "1135 Venice Blvd." }
          obj[$(w).attr('itemprop') || 'itemprop' + j] = $(w).text() || $(w).attr('src') || $(w).val();
        });
        // build data that will be emitted after all of this
        data[itemtype] = obj;
      });

      // emit data
      // if there were no itemprops for an itemtype then data[itemtype]
      // will be [] i.e., empty array
      dReq('emitting data %o', {
        data: data,
        url: inputUrl
      });
      self.emit('data', {
        data: data,
        url: inputUrl
      });
    }

    // get the links on this page and call Visitor.prototype.visitRecursively on em, recursively :3
    $('a').each(function $aEachCB(i, v) {
      try {
        var temp         = url.parse($(v).attr('href'));
        var nextInputUrl = '';

        if (state.origin === temp.host || state.originWithWWW === temp.host || (!temp.host && temp.href)) {

          dReqVerbose('untouched temp.pathname is %s', temp.pathname);

          if (temp.pathname && ('/' !== temp.pathname[0] && '.' !== temp.pathname[0])) temp.pathname = '/' + temp.pathname;

          dReqVerbose('resolving %s and %s', parsedInputUrl.pathname, temp.pathname);

          // resolve relative href (like ../contact or ./resume) against the current pathname we are at i.e., parsedInputUrl.pathname
          temp.pathname = url.resolve(parsedInputUrl.pathname, temp.pathname);

          dReqVerbose('resolved pathname is %s', temp.pathname);

          nextInputUrl = 'http' === temp.protocol || 'https' === temp.protocol ? temp.protocol : state.protocol;
          nextInputUrl += '//';
          nextInputUrl += temp.host || state.origin;
          nextInputUrl += '/' === temp.pathname[0] ? temp.pathname : '/' + temp.pathname;
          nextInputUrl = '/' === nextInputUrl[nextInputUrl.length - 1] ? nextInputUrl.slice(0, -1) : nextInputUrl;
          nextInputUrl = nextInputUrl.replace(/^(https?:\/\/)www\./g, '$1');

          if (nextInputUrl && !state[nextInputUrl]) {
            self.emit('state', state);
            self.visitRecursively(nextInputUrl, state);
            dReqVerbose('done calling visitRecursively with next input url %s', nextInputUrl);
          }
        }
      }
      catch (e) {
        dReq('error during parsing $(\'a\') hrefs %o', err);
        dReqVerbose('Faulty input was %s', $(v).attr('href'));
      }
    });
  });
}

module.exports = Visitor;

// var x = new Visitor;

// x.visitRecursively('http://muditameta.com', {});

// x.on('errored', function errorHandler(e) {
//   console.log('Error: %s', e.type);
//   console.log(e.error);
//   console.log(e.input);
// });

// x.on('data', function dataHandler(d) {
//   console.log('Data for %s', d.url);
//   console.log(d.data);
// });

// x.on('notFound', console.log.bind(console));
<commit_msg>[0.1.0] Wrapped the recursive call in a process.nextTick to handle stack overflow. I doubt it ll work always though. Also, added some error handling<commit_after>var url         = require('url');
var util        = require('util');
var http        = require('http');
var request     = require('request');
var cheerio     = require('cheerio');
var EE          = require('events').EventEmitter;
var dStop       = require('debug')('schema-check:visitor:stopSearch');
var dReq        = require('debug')('schema-check:visitor:makeRequest');
var dVisitRecur = require('debug')('schema-check:visitor:visitorRecursively');
var dReqVerbose = require('debug')('schema-check:visitor:makeRequest:verbose');

util.inherits(Visitor, EE);

function Visitor() {
  var self = this;

  this.on('stop', function _stopSearchHandler() {
    dStop('_stopSearchHandler: Stopping any more network requests');
    self._stopped = true;
  });
}

Visitor.prototype.visitRecursively = function visitRecursively(inputUrl, state) {
  var self = this;
  var parsedInputUrl;

  dVisitRecur('starting with (raw) input url %s', inputUrl);
  // dVisitRecur('state is %s', state);

  // emit error if inputUrl is falsy and return
  if (!inputUrl) {
    dVisitRecur('emitting error of type InputError');
    this.emit('errored', {
      error: new Error('Empty input url'),
      type: 'InputError',
      input: inputUrl
    });
    return;
  }

  // if state is falsy, set it to empty object
  state = state || {};

  try {
    parsedInputUrl = url.parse(inputUrl);
  }
  catch (e){
    dVisitRecur('emitting error of type InputError');
    this.emit('errored', {
      error: e,
      type: 'InputError',
      input: inputUrl
    });
    return;
  }

  // if there's no host then emit error and return
  if (!parsedInputUrl.host || !parsedInputUrl.protocol) {
    dVisitRecur('emitting error of type InputError');
    this.emit('errored', {
      error: new Error('Malformed input url. It has no host or protocol'),
      type: 'InputError',
      input: inputUrl
    });
    return;
  }

  // store the initial url that visitor was called with
  // links found on this page are checked if they
  state.origin        = state.origin || parsedInputUrl.host.replace('www.', '');
  state.originWithWWW = state.originWithWWW || 'www.' + state.origin;
  state.protocol      = state.protocol || parsedInputUrl.protocol;

  // trim the last '/' from inputUrl cuz no keys in state have trailing '/'
  inputUrl = '/' === inputUrl[inputUrl.length - 1] ? inputUrl.slice(0, -1) : inputUrl;

  // trim whitespace
  inputUrl = inputUrl.trim();

  // todo: I should probably strip 'www.' from input url to prevent network call for both, say,
  // http://www.x.com and http://x.com
  // but then again, some people might have setup weird redirects for www. and non www.
  // if i decided to enable this, the fix is below
  inputUrl = inputUrl.replace(/^(https?:\/\/)www\./g, '$1');

  dVisitRecur('processed input url is %s', inputUrl);

  // if inputUrl has been visited then return
  if (state[inputUrl]) {
    console.log('Already visited %s', inputUrl);
    return;
  }

  dVisitRecur('has the search been stopped? %s', !!this._stopped);
  // if search has been stopped then just return blindly and dont hit the network
  if (this._stopped) return;

  // mark inputUrl as visited
  state[inputUrl] = true;

  // dVisitRecur('updated state is %o', state);

  // BIG BOI MAKING REQUEST OMG OMG THIS IS THE CALL THAT MAKES IT ALL HAPPEN
  // (including stackoverflow, sigh -.-)
  dVisitRecur('making request for url');
  makeRequest(self, inputUrl, parsedInputUrl, state);

  dVisitRecur('done with url %s. returning..\n', inputUrl);
};

function makeRequest(self, inputUrl, parsedInputUrl, state) {
  request(inputUrl, function _requestHandler(err, res, body) {
    var $;
    var data;
    var $schema;
    // var urlsWithoutHttpAndHttpsRegex = /^(-\.)?([^\s/?\.#-]+\.?)+(\/[^\s]*)?$/i;

    // dReq('res %o', res);
    // dReq('body %s', body);

    dReqVerbose('parsed input url is %o', parsedInputUrl);

    // if error, emit error and return
    if (err) {
      dReq('emitting error of type RequestError %o', err);
      self.emit('errored', {
        error: err,
        message: err.message,
        type: 'RequestError',
        code: 500,
        input: inputUrl
      });
      return;
    }

    // if status is anything other than a 200, emit httpError and return
    if (res.statusCode !== 200) {
      err = new Error(http.STATUS_CODES[res.statusCode]);
      dReq('response status code is %s', res.statusCode);
      dReq('emitting error of type HttpError %o', err);
      self.emit('errored', {
        error: err,
        message: err.message,
        type: 'HttpError',
        input: inputUrl,
        code: res.statusCode
      });
      return;
    }

    //all good, move on

    // load the body into cheerio
    $ = cheerio.load(body);

    // check if any schemas present
    $schema = $('[itemtype*="schema.org"]');

    // no schemas? Emit notFound
    if (!$schema.length) {
      dReq('emitting notFound');
      self.emit('notFound', {
        message: 'No schema found.',
        url: inputUrl
      });
    }
    else {
      /*
        structure
        {
        <itemtype>: {.. <itemprop>: <value> ..}
        }
      */
      data = {};

      // go over each found schema
      $schema.each(function $schemaEachLoopCB(i, v) {
        var obj        = {};
        var $itemprops = $(v).find('[itemprop]');
        var itemtype   = $(v).attr('itemtype') || 'unknownItemtype' + i;

        data[itemtype] = data[itemtype] || {};

        // go over each child of current schema
        $itemprops.each(function $itempropsEachLoopCB(j, w) {
          // its of the form { <itemprop>: <value> }
          // example { name: "JW Heating & Air", streetAddress: "1135 Venice Blvd." }
          obj[$(w).attr('itemprop') || 'itemprop' + j] = $(w).text() || $(w).attr('src') || $(w).val();
        });
        // build data that will be emitted after all of this
        data[itemtype] = obj;
      });

      // emit data
      // if there were no itemprops for an itemtype then data[itemtype]
      // will be [] i.e., empty array
      dReq('emitting data %o', {
        data: data,
        url: inputUrl
      });
      self.emit('data', {
        data: data,
        url: inputUrl
      });
    }

    // get the links on this page and call Visitor.prototype.visitRecursively on em, recursively :3
    $('a').each(function $aEachCB(i, v) {
      try {
        var temp         = url.parse($(v).attr('href'));
        var nextInputUrl = '';

        if (state.origin === temp.host || state.originWithWWW === temp.host || (!temp.host && temp.href)) {

          dReqVerbose('untouched temp.pathname is %s', temp.pathname);

          if (temp.pathname && ('/' !== temp.pathname[0] && '.' !== temp.pathname[0])) temp.pathname = '/' + temp.pathname;

          dReqVerbose('resolving %s and %s', parsedInputUrl.pathname, temp.pathname);

          // resolve relative href (like ../contact or ./resume) against the current pathname we are at i.e., parsedInputUrl.pathname
          temp.pathname = url.resolve(parsedInputUrl.pathname, temp.pathname);

          dReqVerbose('resolved pathname is %s', temp.pathname);

          nextInputUrl = 'http' === temp.protocol || 'https' === temp.protocol ? temp.protocol : state.protocol;
          nextInputUrl += '//';
          nextInputUrl += temp.host || state.origin;
          nextInputUrl += '/' === temp.pathname[0] ? temp.pathname : '/' + temp.pathname;
          nextInputUrl = '/' === nextInputUrl[nextInputUrl.length - 1] ? nextInputUrl.slice(0, -1) : nextInputUrl;
          nextInputUrl = nextInputUrl.replace(/^(https?:\/\/)www\./g, '$1');
          nextInputUrl = nextInputUrl.trim();

          if (nextInputUrl && !state[nextInputUrl]) {
            self.emit('state', state);
            process.nextTick(self.visitRecursively.bind(self, nextInputUrl, state));
            dReqVerbose('done calling visitRecursively with next input url %s', nextInputUrl);
          }
        }
      }
      catch (e) {
        dReq('error during parsing $(\'a\') hrefs %o', err);
        dReqVerbose('Faulty input was %s', $(v).attr('href'));
      }
    });
  });
}

module.exports = Visitor;

// var x = new Visitor;

// x.visitRecursively('http://muditameta.com', {});

// x.on('errored', function errorHandler(e) {
//   console.log('Error: %s', e.type);
//   console.log(e.error);
//   console.log(e.input);
// });

// x.on('data', function dataHandler(d) {
//   console.log('Data for %s', d.url);
//   console.log(d.data);
// });

// x.on('notFound', console.log.bind(console));
<|endoftext|>


<commit_before>module.exports = [
  "Critical 8",
  "I blame Andy",
  "Oh hey!",
  "Tootltips",
  "Webhooookssss"
];<commit_msg>seeing if we actually fixed that reset deck thing<commit_after>module.exports = [
  "Cole's imaginary family",
  "Critical 8",
  "I blame Andy",
  "Oh hey!",
  "Tootltips",
  "Webhooookssss"
];<|endoftext|>


<commit_before>'use strict';

import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import {Asset} from '../lib.compiled/Asset';
import {Instance} from '../node_modules/deep-kernel/lib.compiled/Microservice/Instance';
import Kernel from 'deep-kernel';
import KernelFactory from './common/KernelFactory';

chai.use(sinonChai);

suite('Asset', function() {
  let assetService = null;
  let backendKernelInstance = null;
  let frontendKernelInstance = null;

  test('Class Asset exists in Asset', function() {
    chai.expect(typeof Asset).to.equal('function');
  });

  test('Load Kernels by using Kernel.load()', function(done) {
    let callback = (frontendKernel, backendKernel) => {
      chai.assert.instanceOf(
        backendKernel, Kernel, 'backendKernel is an instance of Kernel'
      );
      chai.assert.instanceOf(
        frontendKernel, Kernel, 'frontendKernel is an instance of Kernel'
      );
      backendKernelInstance = backendKernel;
      frontendKernelInstance = frontendKernel;

      assetService = frontendKernel.get('asset');

      // complete the async
      done();
    };
    KernelFactory.create({Asset: Asset}, callback);
  });

  test('Check boot() method for !kernel.isFrontend', function() {
    let spyCallback = sinon.spy();
    assetService.boot(backendKernelInstance, spyCallback);
    chai.expect(spyCallback).to.have.been.calledWith();
  });

  test('Check boot() method  for kernel.isFrontend', function() {
    let spyCallback = sinon.spy();
    let expectedResult = ['hello.world.example/bootstrap.js'];
    assetService.boot(frontendKernelInstance, spyCallback);
    chai.expect(frontendKernelInstance.get(Kernel.FRONTEND_BOOTSTRAP_VECTOR)).to.be.eql(expectedResult);
    chai.expect(spyCallback).to.have.been.calledWith();
  });

  test('Check locate() method returns valid string for isRoot', function() {
    let expectedResult = 'bootstrap.js';
    let actualResult = assetService.locate('@deep.ng.root:bootstrap.js');
    chai.expect(actualResult).to.be.equal(expectedResult);
  });

  test('Check locate() method returns valid string for !isRoot', function() {
    let expectedResult = 'hello.world.example/bootstrap.js';
    let actualResult = assetService.locate('@hello.world.example:bootstrap.js');
    chai.expect(actualResult).to.be.equal(expectedResult);
  });
});
<commit_msg>Undo asset unit test changes<commit_after>'use strict';

import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import {Asset} from '../lib.compiled/Asset';
import {Instance} from '../node_modules/deep-kernel/lib.compiled/Microservice/Instance';
import Kernel from 'deep-kernel';
import KernelFactory from './common/KernelFactory';

chai.use(sinonChai);

suite('Asset', function() {
  let assetService = null;
  let backendKernelInstance = null;
  let frontendKernelInstance = null;

  test('Class Asset exists in Asset', function() {
    chai.expect(typeof Asset).to.equal('function');
  });

  test('Load Kernels by using Kernel.load()', function(done) {
    let callback = (frontendKernel, backendKernel) => {
      chai.assert.instanceOf(backendKernel, Kernel, 'backendKernel is an instance of Kernel');
      backendKernelInstance = backendKernel;
      chai.assert.instanceOf(frontendKernel, Kernel, 'frontendKernel is an instance of Kernel');
      frontendKernelInstance = frontendKernel;
      assetService = frontendKernel.get('asset');

      // complete the async
      done();
    };
    KernelFactory.create({Asset: Asset}, callback);
  });

  test('Check boot() method for !kernel.isFrontend', function() {
    let spyCallback = sinon.spy();
    assetService.boot(backendKernelInstance, spyCallback);
    chai.expect(spyCallback).to.have.been.calledWith();
  });

  test('Check boot() method  for kernel.isFrontend', function() {
    let spyCallback = sinon.spy();
    let expectedResult = ['hello.world.example/bootstrap.js'];
    assetService.boot(frontendKernelInstance, spyCallback);
    chai.expect(frontendKernelInstance.get(Kernel.FRONTEND_BOOTSTRAP_VECTOR)).to.be.eql(expectedResult);
    chai.expect(spyCallback).to.have.been.calledWith();
  });

  test('Check locate() method returns valid string for isRoot', function() {
    let expectedResult = 'bootstrap.js';
    let actualResult = assetService.locate('@deep.ng.root:bootstrap.js');
    chai.expect(actualResult).to.be.equal(expectedResult);
  });

  test('Check locate() method returns valid string for !isRoot', function() {
    let expectedResult = 'hello.world.example/bootstrap.js';
    let actualResult = assetService.locate('@hello.world.example:bootstrap.js');
    chai.expect(actualResult).to.be.equal(expectedResult);
  });
});
<|endoftext|>


<commit_before>var CONFIG = require("./config.js");
var CONSTANTS = require("./constants.js");
var UTIL = require("./util.js");

function Bid(adapterID, kgpv){
	this.adapterID = adapterID;
	this.kgpv = kgpv;
	this.bidID = UTIL.getUniqueIdentifierStr();
	this.grossEcpm = 0; // one given by bidder
	this.netEcpm = 0; // one after bid adjustment
	this.defaultBid = 0;
	this.adHtml = "";
	this.adUrl = "";
	this.height = 0;
	this.width = 0;
	this.creativeID = ""; //todo, is it needed ?
	this.keyValuePairs = {};
	this.isPostTimeout = false;
	this.receivedTime = 0;
	this.isServerSide = CONFIG.isServerSideAdapter(adapterID) ? 1 : 0;
	this.dealID = "";
	this.dealChannel = "";
	this.isWinningBid = false;
	this.status = 0;
	this.serverSideResponseTime = 0;
	this.mi = undefined;
	this.originalCpm = 0;
	this.originalCurrency = "";
	this.analyticsGrossCpm = 0;
	this.analyticsNetCpm = 0;
	this.native = undefined;
	this.adFormat = undefined;
	this.regexPattern = undefined;
	this.cacheUUID = undefined;
}

var getNetECPM = function(grossEcpm, adapterID){
	return window.parseFloat((grossEcpm * CONFIG.getAdapterRevShare(adapterID)).toFixed(CONSTANTS.COMMON.BID_PRECISION));
};

Bid.prototype.setServerSideResponseTime = function (ssResponseTime) {
	this.serverSideResponseTime = ssResponseTime;
};

Bid.prototype.getServerSideResponseTime = function () {
	return this.serverSideResponseTime;
};

Bid.prototype.getServerSideStatus = function () {
	return this.isServerSide;
};

Bid.prototype.setServerSideStatus = function (isServerSide) {
	this.isServerSide = isServerSide;
};

Bid.prototype.getAdapterID = function(){
	return this.adapterID;
};

Bid.prototype.getBidID = function(){
	return this.bidID;
};

Bid.prototype.setGrossEcpm = function(ecpm){
	/* istanbul ignore else */
	if(ecpm === null){
		UTIL.log(CONSTANTS.MESSAGES.M10);
		UTIL.log(this);
		return this;
	}
	/* istanbul ignore else */
	if(UTIL.isString(ecpm)){
		ecpm = ecpm.replace(/\s/g, "");
		/* istanbul ignore else */
		if(ecpm.length === 0){
			UTIL.log(CONSTANTS.MESSAGES.M20);
			UTIL.log(this);
			return this;
		}
	}

	/* istanbul ignore else */
	if(window.isNaN(ecpm)){
		UTIL.log(CONSTANTS.MESSAGES.M11+ecpm);
		UTIL.log(this);
		return this;
	}

	ecpm = window.parseFloat(ecpm.toFixed(CONSTANTS.COMMON.BID_PRECISION));

	this.grossEcpm = ecpm;
	this.netEcpm = getNetECPM(this.grossEcpm, this.getAdapterID());

	return this;
};

Bid.prototype.getGrossEcpm = function(forAnalytics){
	// Check config if currency module is enabled.
	if(CONFIG.getAdServerCurrency() && this.analyticsGrossCpm && forAnalytics){
		return this.analyticsGrossCpm;
	}
	return this.grossEcpm;
};

Bid.prototype.getNetEcpm = function(forAnalytics){
	if(CONFIG.getAdServerCurrency() && this.analyticsNetCpm && forAnalytics){
		return this.analyticsNetCpm;
	}
	return this.netEcpm;
};

Bid.prototype.setDefaultBidStatus = function(status){
	this.defaultBid = status;
	return this;
};

Bid.prototype.getDefaultBidStatus = function(){
	return this.defaultBid;
};

Bid.prototype.setAdHtml = function(adHtml){
	this.adHtml = adHtml;
	this.setAdFormat(adHtml);
	return this;
};

Bid.prototype.getAdHtml = function(){
	return this.adHtml;
};

Bid.prototype.setAdUrl = function(adUrl){
	this.adUrl = adUrl;
	return this;
};

Bid.prototype.getAdUrl = function(){
	return this.adUrl;
};

Bid.prototype.setHeight = function(height){
	this.height = height;
	return this;
};

Bid.prototype.getHeight = function(){
	return this.height;
};

Bid.prototype.setWidth = function(width){
	this.width = width;
	return this;
};

Bid.prototype.getWidth = function(){
	return this.width;
};

Bid.prototype.getKGPV = function(isActualValueRequired){
	if(!isActualValueRequired && this.regexPattern){
		return this.regexPattern;
	}
	return this.kgpv;
};

Bid.prototype.setKeyValuePair = function(key, value){
	// max length of key is restricted to 20 characters
	this.keyValuePairs[key.substr(0, 20)] = value;
	return this;
};

Bid.prototype.getKeyValuePairs = function(){
	return this.keyValuePairs;
};

Bid.prototype.setPostTimeoutStatus = function(){
	this.isPostTimeout = true;
	return this;
};

Bid.prototype.getPostTimeoutStatus = function(){
	return this.isPostTimeout;
};

Bid.prototype.setReceivedTime = function(receivedTime){
	this.receivedTime = receivedTime;
	return this;
};

Bid.prototype.getReceivedTime = function(){
	return this.receivedTime;
};

Bid.prototype.setDealID = function(dealID){
	/* istanbul ignore else */
	if(dealID){
		this.dealID = dealID;
		this.dealChannel = this.dealChannel || "PMP";
		this.setKeyValuePair(
			CONSTANTS.COMMON.DEAL_KEY_FIRST_PART+this.adapterID,
			this.dealChannel + CONSTANTS.COMMON.DEAL_KEY_VALUE_SEPARATOR + this.dealID + CONSTANTS.COMMON.DEAL_KEY_VALUE_SEPARATOR + this.bidID
		);
	}
	return this;
};

Bid.prototype.getDealID = function(){
	return this.dealID;
};

Bid.prototype.setDealChannel = function(dealChannel){
	/* istanbul ignore else */
	if(this.dealID && dealChannel){
		this.dealChannel = dealChannel;
		this.setKeyValuePair(
			CONSTANTS.COMMON.DEAL_KEY_FIRST_PART+this.adapterID,
			this.dealChannel + CONSTANTS.COMMON.DEAL_KEY_VALUE_SEPARATOR + this.dealID + CONSTANTS.COMMON.DEAL_KEY_VALUE_SEPARATOR + this.bidID
		);
	}
	return this;
};

Bid.prototype.getDealChannel = function(){
	return this.dealChannel;
};

Bid.prototype.setWinningBidStatus = function(){
	this.isWinningBid = true;
	return this;
};

Bid.prototype.getWinningBidStatus = function(){
	return this.isWinningBid;
};

Bid.prototype.setStatus = function(status){
	this.status = status;
	return this;
};

Bid.prototype.getStatus = function(){
	return this.status;
};

Bid.prototype.setSendAllBidsKeys = function(){
	this.setKeyValuePair(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ID+'_'+this.adapterID, this.bidID);
	this.setKeyValuePair(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_STATUS+'_'+this.adapterID, this.getNetEcpm() > 0 ? 1 : 0);
	this.setKeyValuePair(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ECPM+'_'+this.adapterID, this.getNetEcpm().toFixed(CONSTANTS.COMMON.BID_PRECISION));
	this.setKeyValuePair(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_SIZE+'_'+this.adapterID, this.width + 'x' + this.height);
	if (this.native) {
		var keyValues = this.keyValuePairs;
		var globalThis = this;
		UTIL.forEachOnObject(keyValues, function(key, value) {
			if (key.indexOf("native") >= 0) {
				globalThis.setKeyValuePair(key + "_" + globalThis.adapterID, value);
			}
		});
	}
};

Bid.prototype.setMi = function(mi){
	this.mi = mi;
	return this;
};

Bid.prototype.getMi = function(){
	return this.mi;
};

Bid.prototype.setOriginalCpm = function(originalCpm){
	this.originalCpm = window.parseFloat(originalCpm.toFixed(CONSTANTS.COMMON.BID_PRECISION));
	return this;
};

Bid.prototype.getOriginalCpm = function(){
	return this.originalCpm;
};

Bid.prototype.setOriginalCurrency = function(originalCurrency){
	this.originalCurrency = originalCurrency;
	return this;
};

Bid.prototype.getOriginalCurrency = function(){
	return this.originalCurrency;
};

Bid.prototype.setAnalyticsCpm = function(analyticsCpm){
	this.analyticsGrossCpm = window.parseFloat(analyticsCpm.toFixed(CONSTANTS.COMMON.BID_PRECISION));
	this.analyticsNetCpm = getNetECPM(this.analyticsGrossCpm,this.getAdapterID());
	return this;
};

Bid.prototype.getAnalyticsCpm = function(){
	return this.analyticsGrossCpm;
};

Bid.prototype.getNative = function(){
	return this.native;
};

Bid.prototype.setNative = function(native){
	this.native = native;
	return this;
};

Bid.prototype.getAdFormat = function(){
	return this.adFormat;
};

Bid.prototype.setAdFormat = function(ad){
	this.adFormat = UTIL.getAdFormatFromBidAd(ad);
	return this;
};

Bid.prototype.getRegexPattern = function(){
	return this.regexPattern;
};

Bid.prototype.setRegexPattern = function(pattern){
	this.regexPattern = pattern;
	return this;
};

Bid.prototype.getcacheUUID = function(){
	return this.cacheUUID;
};

Bid.prototype.setcacheUUID = function(cacheUUID){
	this.cacheUUID = cacheUUID;
	if(!this.adFormat){
		this.adFormat = CONSTANTS.FORMAT_VALUES.VIDEO;
	}
	return this;
};

// This function is used to update the bid in case of video bid
// this should only be called if bid is video so that there is no discrepancy in tracker and logger for bid Id
Bid.prototype.updateBidId = function(slotID){
	if(window.PWT.bidMap[slotID] && window.PWT.bidMap[slotID].adapters && window.PWT.bidMap[slotID].adapters.length>0){
		var bidId = window.PWT.bidMap[slotID].adapters[this.adapterID].bids[Object.keys(window.PWT.bidMap[slotID].adapters[this.adapterID].bids)[0]].bidID;
		if(bidId && this.adFormat == CONSTANTS.FORMAT_VALUES.VIDEO){
			this.bidID = bidId;
		}
	}
	else {
		UTIL.logWarning("Error in Updating BidId. It might be possible singleImpressionEnabled is false");
		console.warn("Setup for video might not be correct. Try setting up Optimize MultiSize AdSlot to true.");
	}
	return this;
};

/* start-test-block */
module.exports.Bid = Bid;
/* end-test-block */

exports.createBid = function(adapterID, kgpv){
	return new Bid(adapterID, kgpv);
};

//todo:
// add validations
<commit_msg>Fixed condition of length for object<commit_after>var CONFIG = require("./config.js");
var CONSTANTS = require("./constants.js");
var UTIL = require("./util.js");

function Bid(adapterID, kgpv){
	this.adapterID = adapterID;
	this.kgpv = kgpv;
	this.bidID = UTIL.getUniqueIdentifierStr();
	this.grossEcpm = 0; // one given by bidder
	this.netEcpm = 0; // one after bid adjustment
	this.defaultBid = 0;
	this.adHtml = "";
	this.adUrl = "";
	this.height = 0;
	this.width = 0;
	this.creativeID = ""; //todo, is it needed ?
	this.keyValuePairs = {};
	this.isPostTimeout = false;
	this.receivedTime = 0;
	this.isServerSide = CONFIG.isServerSideAdapter(adapterID) ? 1 : 0;
	this.dealID = "";
	this.dealChannel = "";
	this.isWinningBid = false;
	this.status = 0;
	this.serverSideResponseTime = 0;
	this.mi = undefined;
	this.originalCpm = 0;
	this.originalCurrency = "";
	this.analyticsGrossCpm = 0;
	this.analyticsNetCpm = 0;
	this.native = undefined;
	this.adFormat = undefined;
	this.regexPattern = undefined;
	this.cacheUUID = undefined;
}

var getNetECPM = function(grossEcpm, adapterID){
	return window.parseFloat((grossEcpm * CONFIG.getAdapterRevShare(adapterID)).toFixed(CONSTANTS.COMMON.BID_PRECISION));
};

Bid.prototype.setServerSideResponseTime = function (ssResponseTime) {
	this.serverSideResponseTime = ssResponseTime;
};

Bid.prototype.getServerSideResponseTime = function () {
	return this.serverSideResponseTime;
};

Bid.prototype.getServerSideStatus = function () {
	return this.isServerSide;
};

Bid.prototype.setServerSideStatus = function (isServerSide) {
	this.isServerSide = isServerSide;
};

Bid.prototype.getAdapterID = function(){
	return this.adapterID;
};

Bid.prototype.getBidID = function(){
	return this.bidID;
};

Bid.prototype.setGrossEcpm = function(ecpm){
	/* istanbul ignore else */
	if(ecpm === null){
		UTIL.log(CONSTANTS.MESSAGES.M10);
		UTIL.log(this);
		return this;
	}
	/* istanbul ignore else */
	if(UTIL.isString(ecpm)){
		ecpm = ecpm.replace(/\s/g, "");
		/* istanbul ignore else */
		if(ecpm.length === 0){
			UTIL.log(CONSTANTS.MESSAGES.M20);
			UTIL.log(this);
			return this;
		}
	}

	/* istanbul ignore else */
	if(window.isNaN(ecpm)){
		UTIL.log(CONSTANTS.MESSAGES.M11+ecpm);
		UTIL.log(this);
		return this;
	}

	ecpm = window.parseFloat(ecpm.toFixed(CONSTANTS.COMMON.BID_PRECISION));

	this.grossEcpm = ecpm;
	this.netEcpm = getNetECPM(this.grossEcpm, this.getAdapterID());

	return this;
};

Bid.prototype.getGrossEcpm = function(forAnalytics){
	// Check config if currency module is enabled.
	if(CONFIG.getAdServerCurrency() && this.analyticsGrossCpm && forAnalytics){
		return this.analyticsGrossCpm;
	}
	return this.grossEcpm;
};

Bid.prototype.getNetEcpm = function(forAnalytics){
	if(CONFIG.getAdServerCurrency() && this.analyticsNetCpm && forAnalytics){
		return this.analyticsNetCpm;
	}
	return this.netEcpm;
};

Bid.prototype.setDefaultBidStatus = function(status){
	this.defaultBid = status;
	return this;
};

Bid.prototype.getDefaultBidStatus = function(){
	return this.defaultBid;
};

Bid.prototype.setAdHtml = function(adHtml){
	this.adHtml = adHtml;
	this.setAdFormat(adHtml);
	return this;
};

Bid.prototype.getAdHtml = function(){
	return this.adHtml;
};

Bid.prototype.setAdUrl = function(adUrl){
	this.adUrl = adUrl;
	return this;
};

Bid.prototype.getAdUrl = function(){
	return this.adUrl;
};

Bid.prototype.setHeight = function(height){
	this.height = height;
	return this;
};

Bid.prototype.getHeight = function(){
	return this.height;
};

Bid.prototype.setWidth = function(width){
	this.width = width;
	return this;
};

Bid.prototype.getWidth = function(){
	return this.width;
};

Bid.prototype.getKGPV = function(isActualValueRequired){
	if(!isActualValueRequired && this.regexPattern){
		return this.regexPattern;
	}
	return this.kgpv;
};

Bid.prototype.setKeyValuePair = function(key, value){
	// max length of key is restricted to 20 characters
	this.keyValuePairs[key.substr(0, 20)] = value;
	return this;
};

Bid.prototype.getKeyValuePairs = function(){
	return this.keyValuePairs;
};

Bid.prototype.setPostTimeoutStatus = function(){
	this.isPostTimeout = true;
	return this;
};

Bid.prototype.getPostTimeoutStatus = function(){
	return this.isPostTimeout;
};

Bid.prototype.setReceivedTime = function(receivedTime){
	this.receivedTime = receivedTime;
	return this;
};

Bid.prototype.getReceivedTime = function(){
	return this.receivedTime;
};

Bid.prototype.setDealID = function(dealID){
	/* istanbul ignore else */
	if(dealID){
		this.dealID = dealID;
		this.dealChannel = this.dealChannel || "PMP";
		this.setKeyValuePair(
			CONSTANTS.COMMON.DEAL_KEY_FIRST_PART+this.adapterID,
			this.dealChannel + CONSTANTS.COMMON.DEAL_KEY_VALUE_SEPARATOR + this.dealID + CONSTANTS.COMMON.DEAL_KEY_VALUE_SEPARATOR + this.bidID
		);
	}
	return this;
};

Bid.prototype.getDealID = function(){
	return this.dealID;
};

Bid.prototype.setDealChannel = function(dealChannel){
	/* istanbul ignore else */
	if(this.dealID && dealChannel){
		this.dealChannel = dealChannel;
		this.setKeyValuePair(
			CONSTANTS.COMMON.DEAL_KEY_FIRST_PART+this.adapterID,
			this.dealChannel + CONSTANTS.COMMON.DEAL_KEY_VALUE_SEPARATOR + this.dealID + CONSTANTS.COMMON.DEAL_KEY_VALUE_SEPARATOR + this.bidID
		);
	}
	return this;
};

Bid.prototype.getDealChannel = function(){
	return this.dealChannel;
};

Bid.prototype.setWinningBidStatus = function(){
	this.isWinningBid = true;
	return this;
};

Bid.prototype.getWinningBidStatus = function(){
	return this.isWinningBid;
};

Bid.prototype.setStatus = function(status){
	this.status = status;
	return this;
};

Bid.prototype.getStatus = function(){
	return this.status;
};

Bid.prototype.setSendAllBidsKeys = function(){
	this.setKeyValuePair(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ID+'_'+this.adapterID, this.bidID);
	this.setKeyValuePair(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_STATUS+'_'+this.adapterID, this.getNetEcpm() > 0 ? 1 : 0);
	this.setKeyValuePair(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ECPM+'_'+this.adapterID, this.getNetEcpm().toFixed(CONSTANTS.COMMON.BID_PRECISION));
	this.setKeyValuePair(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_SIZE+'_'+this.adapterID, this.width + 'x' + this.height);
	if (this.native) {
		var keyValues = this.keyValuePairs;
		var globalThis = this;
		UTIL.forEachOnObject(keyValues, function(key, value) {
			if (key.indexOf("native") >= 0) {
				globalThis.setKeyValuePair(key + "_" + globalThis.adapterID, value);
			}
		});
	}
};

Bid.prototype.setMi = function(mi){
	this.mi = mi;
	return this;
};

Bid.prototype.getMi = function(){
	return this.mi;
};

Bid.prototype.setOriginalCpm = function(originalCpm){
	this.originalCpm = window.parseFloat(originalCpm.toFixed(CONSTANTS.COMMON.BID_PRECISION));
	return this;
};

Bid.prototype.getOriginalCpm = function(){
	return this.originalCpm;
};

Bid.prototype.setOriginalCurrency = function(originalCurrency){
	this.originalCurrency = originalCurrency;
	return this;
};

Bid.prototype.getOriginalCurrency = function(){
	return this.originalCurrency;
};

Bid.prototype.setAnalyticsCpm = function(analyticsCpm){
	this.analyticsGrossCpm = window.parseFloat(analyticsCpm.toFixed(CONSTANTS.COMMON.BID_PRECISION));
	this.analyticsNetCpm = getNetECPM(this.analyticsGrossCpm,this.getAdapterID());
	return this;
};

Bid.prototype.getAnalyticsCpm = function(){
	return this.analyticsGrossCpm;
};

Bid.prototype.getNative = function(){
	return this.native;
};

Bid.prototype.setNative = function(native){
	this.native = native;
	return this;
};

Bid.prototype.getAdFormat = function(){
	return this.adFormat;
};

Bid.prototype.setAdFormat = function(ad){
	this.adFormat = UTIL.getAdFormatFromBidAd(ad);
	return this;
};

Bid.prototype.getRegexPattern = function(){
	return this.regexPattern;
};

Bid.prototype.setRegexPattern = function(pattern){
	this.regexPattern = pattern;
	return this;
};

Bid.prototype.getcacheUUID = function(){
	return this.cacheUUID;
};

Bid.prototype.setcacheUUID = function(cacheUUID){
	this.cacheUUID = cacheUUID;
	if(!this.adFormat){
		this.adFormat = CONSTANTS.FORMAT_VALUES.VIDEO;
	}
	return this;
};

// This function is used to update the bid in case of video bid
// this should only be called if bid is video so that there is no discrepancy in tracker and logger for bid Id
Bid.prototype.updateBidId = function(slotID){
	if(window.PWT.bidMap[slotID] && window.PWT.bidMap[slotID].adapters && Object.keys(window.PWT.bidMap[slotID].adapters).length>0){
		var bidId = window.PWT.bidMap[slotID].adapters[this.adapterID].bids[Object.keys(window.PWT.bidMap[slotID].adapters[this.adapterID].bids)[0]].bidID;
		if(bidId && this.adFormat == CONSTANTS.FORMAT_VALUES.VIDEO){
			this.bidID = bidId;
		}
	}
	else {
		UTIL.logWarning("Error in Updating BidId. It might be possible singleImpressionEnabled is false");
		console.warn("Setup for video might not be correct. Try setting up Optimize MultiSize AdSlot to true.");
	}
	return this;
};

/* start-test-block */
module.exports.Bid = Bid;
/* end-test-block */

exports.createBid = function(adapterID, kgpv){
	return new Bid(adapterID, kgpv);
};

//todo:
// add validations
<|endoftext|>


<commit_before>// @flow

import classNames from 'classnames';
import React, { Fragment, useCallback } from 'react';
import Icon from './Icon';

import styles from './TabBar.css';

import type { IconType } from './Icon';

type TabInfo = {|
  icon: IconType,
  id: string,
  label: string,
  title?: string,
|};

export type Props = {|
  currentTab: any,
  disabled?: boolean,
  id: string,
  selectTab: (tabID: any) => void,
  size: 'large' | 'small',
  tabs: Array<TabInfo>,
|};

export default function TabBar({
  currentTab,
  disabled = false,
  id: groupName,
  selectTab,
  size,
  tabs,
}: Props) {
  if (!tabs.some(tab => tab.id === currentTab)) {
    selectTab(tabs[0].id);
  }

  const onChange = useCallback(
    ({ currentTarget }) => selectTab(currentTarget.value),
    [selectTab]
  );

  const handleKeyDown = useCallback(event => {
    switch (event.key) {
      case 'ArrowDown':
      case 'ArrowLeft':
      case 'ArrowRight':
      case 'ArrowUp':
        event.stopPropagation();
        break;
      default:
        break;
    }
  }, []);

  const tabClassName =
    size === 'large' ? styles.TabSizeLarge : styles.TabSizeSmall;

  return (
    <Fragment>
      {tabs.map(({ icon, id, label, title }) => (
        <label
          className={classNames(
            tabClassName,
            disabled ? styles.TabDisabled : styles.Tab,
            !disabled && currentTab === id ? styles.TabCurrent : null
          )}
          key={id}
          onKeyDown={handleKeyDown}
          title={title || label}
        >
          <input
            type="radio"
            className={styles.Input}
            checked={currentTab === id}
            disabled={disabled}
            name={groupName}
            value={id}
            onChange={onChange}
          />
          <Icon
            className={`${disabled ? styles.IconDisabled : ''} ${
              size === 'large' ? styles.IconSizeLarge : styles.IconSizeSmall
            }`}
            type={icon}
          />
          <span
            className={
              size === 'large' ? styles.TabLabelLarge : styles.TabLabelSmall
            }
          >
            {label}
          </span>
        </label>
      ))}
    </Fragment>
  );
}
<commit_msg>Select tab when the mouse is pressed<commit_after>// @flow

import classNames from 'classnames';
import React, { Fragment, useCallback } from 'react';
import Icon from './Icon';

import styles from './TabBar.css';

import type { IconType } from './Icon';

type TabInfo = {|
  icon: IconType,
  id: string,
  label: string,
  title?: string,
|};

export type Props = {|
  currentTab: any,
  disabled?: boolean,
  id: string,
  selectTab: (tabID: any) => void,
  size: 'large' | 'small',
  tabs: Array<TabInfo>,
|};

export default function TabBar({
  currentTab,
  disabled = false,
  id: groupName,
  selectTab,
  size,
  tabs,
}: Props) {
  if (!tabs.some(tab => tab.id === currentTab)) {
    selectTab(tabs[0].id);
  }

  const onChange = useCallback(
    ({ currentTarget }) => selectTab(currentTarget.value),
    [selectTab]
  );

  const handleKeyDown = useCallback(event => {
    switch (event.key) {
      case 'ArrowDown':
      case 'ArrowLeft':
      case 'ArrowRight':
      case 'ArrowUp':
        event.stopPropagation();
        break;
      default:
        break;
    }
  }, []);

  const tabClassName =
    size === 'large' ? styles.TabSizeLarge : styles.TabSizeSmall;

  return (
    <Fragment>
      {tabs.map(({ icon, id, label, title }) => (
        <label
          className={classNames(
            tabClassName,
            disabled ? styles.TabDisabled : styles.Tab,
            !disabled && currentTab === id ? styles.TabCurrent : null
          )}
          key={id}
          onKeyDown={handleKeyDown}
          onMouseDown={() => selectTab(id)}
          title={title || label}
        >
          <input
            type="radio"
            className={styles.Input}
            checked={currentTab === id}
            disabled={disabled}
            name={groupName}
            value={id}
            onChange={onChange}
          />
          <Icon
            className={`${disabled ? styles.IconDisabled : ''} ${
              size === 'large' ? styles.IconSizeLarge : styles.IconSizeSmall
            }`}
            type={icon}
          />
          <span
            className={
              size === 'large' ? styles.TabLabelLarge : styles.TabLabelSmall
            }
          >
            {label}
          </span>
        </label>
      ))}
    </Fragment>
  );
}
<|endoftext|>


<commit_before>// https://github.com/eternicode/bootstrap-datepicker

angular.module('$strap.directives')

.directive('bsDatepicker', ['$timeout', function($timeout) {
  'use strict';

  var isTouch = 'ontouchstart' in window && !window.navigator.userAgent.match(/PhantomJS/i);

  var DATE_REGEXP_MAP = {
    '/'    : '[\\/]',
    '-'    : '[-]',
    '.'    : '[.]',
    'dd'   : '(?:(?:[0-2]?[0-9]{1})|(?:[3][01]{1}))',
    'd'   : '(?:(?:[0-2]?[0-9]{1})|(?:[3][01]{1}))',
    'mm'   : '(?:[0]?[1-9]|[1][012])',
    'm'   : '(?:[0]?[1-9]|[1][012])',
    'yyyy' : '(?:(?:[1]{1}[0-9]{1}[0-9]{1}[0-9]{1})|(?:[2]{1}[0-9]{3}))(?![[0-9]])',
    'yy'   : '(?:(?:[0-9]{1}[0-9]{1}))(?![[0-9]])'
  };

  return {
    restrict: 'A',
    require: '?ngModel',
    link: function postLink(scope, element, attrs, controller) {
      //console.log('postLink', this, arguments); window.element = element;

      var regexpForDateFormat = function(dateFormat, options) {
        options || (options = {});
        var re = dateFormat, regexpMap = DATE_REGEXP_MAP;
        /*if(options.mask) {
          regexpMap['/'] = '';
          regexpMap['-'] = '';
        }*/
        angular.forEach(regexpMap, function(v, k) { re = re.split(k).join(v); });
        return new RegExp('^' + re + '$', ['i']);
      };

      var dateFormatRegexp = isTouch ? 'yyyy/mm/dd' : regexpForDateFormat(attrs.dateFormat || 'mm/dd/yyyy'/*, {mask: !!attrs.uiMask}*/);

      // Handle date validity according to dateFormat
      if(controller) {
        controller.$parsers.unshift(function(viewValue) {
          //console.warn('viewValue', viewValue, dateFormatRegexp,  dateFormatRegexp.test(viewValue));
          if (!viewValue || dateFormatRegexp.test(viewValue)) {
            controller.$setValidity('date', true);
            return viewValue;
          } else {
            controller.$setValidity('date', false);
            return undefined;
          }
        });
      }

      // Support add-on
      var component = element.next('[data-toggle="datepicker"]');
      if(component.length) {
        component.on('click', function() { isTouch ? element.trigger('focus') : element.datepicker('show'); });
      }

      // Use native interface for touch devices
      if(isTouch && element.prop('type') === 'text') {

        element.prop('type', 'date');
        element.on('change', function(ev) {
          scope.$apply(function () {
            controller.$setViewValue(element.val());
          });
        });

      } else {

        // If we have a controller (i.e. ngModelController) then wire it up
        if(controller) {
          element.on('changeDate', function(ev) {
            scope.$apply(function () {
              controller.$setViewValue(element.val());
            });
          });
        }

        // Popover GarbageCollection
        var $popover = element.closest('.popover');
        if($popover) {
          $popover.on('hide', function(e) {
            var datepicker = element.data('datepicker');
            if(datepicker) {
              datepicker.picker.remove();
              element.data('datepicker', null);
            }
          });
        }

        // Create datepicker
        element.attr('data-toggle', 'datepicker');
        element.datepicker({
          autoclose: true,
          forceParse: false,
          language: attrs.language || 'en'
        });

      }

    }

  };

}]);
<commit_msg>feat(datepicker): forceParse attr (rel #57)<commit_after>// https://github.com/eternicode/bootstrap-datepicker

angular.module('$strap.directives')

.directive('bsDatepicker', ['$timeout', function($timeout) {
  'use strict';

  var isTouch = 'ontouchstart' in window && !window.navigator.userAgent.match(/PhantomJS/i);

  var DATE_REGEXP_MAP = {
    '/'    : '[\\/]',
    '-'    : '[-]',
    '.'    : '[.]',
    'dd'   : '(?:(?:[0-2]?[0-9]{1})|(?:[3][01]{1}))',
    'd'   : '(?:(?:[0-2]?[0-9]{1})|(?:[3][01]{1}))',
    'mm'   : '(?:[0]?[1-9]|[1][012])',
    'm'   : '(?:[0]?[1-9]|[1][012])',
    'yyyy' : '(?:(?:[1]{1}[0-9]{1}[0-9]{1}[0-9]{1})|(?:[2]{1}[0-9]{3}))(?![[0-9]])',
    'yy'   : '(?:(?:[0-9]{1}[0-9]{1}))(?![[0-9]])'
  };

  return {
    restrict: 'A',
    require: '?ngModel',
    link: function postLink(scope, element, attrs, controller) {
      //console.log('postLink', this, arguments); window.element = element;

      var regexpForDateFormat = function(dateFormat, options) {
        options || (options = {});
        var re = dateFormat, regexpMap = DATE_REGEXP_MAP;
        /*if(options.mask) {
          regexpMap['/'] = '';
          regexpMap['-'] = '';
        }*/
        angular.forEach(regexpMap, function(v, k) { re = re.split(k).join(v); });
        return new RegExp('^' + re + '$', ['i']);
      };

      var dateFormatRegexp = isTouch ? 'yyyy/mm/dd' : regexpForDateFormat(attrs.dateFormat || 'mm/dd/yyyy'/*, {mask: !!attrs.uiMask}*/);

      // Handle date validity according to dateFormat
      if(controller) {
        controller.$parsers.unshift(function(viewValue) {
          //console.warn('viewValue', viewValue, dateFormatRegexp,  dateFormatRegexp.test(viewValue));
          if (!viewValue || dateFormatRegexp.test(viewValue)) {
            controller.$setValidity('date', true);
            return viewValue;
          } else {
            controller.$setValidity('date', false);
            return undefined;
          }
        });
      }

      // Support add-on
      var component = element.next('[data-toggle="datepicker"]');
      if(component.length) {
        component.on('click', function() { isTouch ? element.trigger('focus') : element.datepicker('show'); });
      }

      // Use native interface for touch devices
      if(isTouch && element.prop('type') === 'text') {

        element.prop('type', 'date');
        element.on('change', function(ev) {
          scope.$apply(function () {
            controller.$setViewValue(element.val());
          });
        });

      } else {

        // If we have a controller (i.e. ngModelController) then wire it up
        if(controller) {
          element.on('changeDate', function(ev) {
            scope.$apply(function () {
              controller.$setViewValue(element.val());
            });
          });
        }

        // Popover GarbageCollection
        var $popover = element.closest('.popover');
        if($popover) {
          $popover.on('hide', function(e) {
            var datepicker = element.data('datepicker');
            if(datepicker) {
              datepicker.picker.remove();
              element.data('datepicker', null);
            }
          });
        }

        // Create datepicker
        element.attr('data-toggle', 'datepicker');
        element.datepicker({
          autoclose: true,
          forceParse: attrs.forceParse || false,
          language: attrs.language || 'en'
        });

      }

    }

  };

}]);
<|endoftext|>


<commit_before>(function() {
    "use strict";

    recurve.flux.state = {};
    var module = recurve.flux.state.$module = recurve.module();

    module.factory("$state", ["$router", "$action"], function($router, $action) {
        // functionality:
        // - define states to a route
        // - define modals to a route with default state (if one doesn't exist)
        // - hooks:
        // a. validate(done) => done to continue...parameters: false => go back, route => change route to
        // a. getData(done) => done to continue...parameters: false => go back, route => change route to
        //
        // TODO TBD support child states??
        return {

        };
    });
})();<commit_msg>setup interface for flux state<commit_after>(function() {
    "use strict";

    recurve.flux.state = {};
    var module = recurve.flux.state.$module = recurve.module();

    module.factory("$state", ["$router", "$action"], function($router, $action) {
        // functionality:
        // - define states to a route
        // - hooks:
        // a. validate(done) => done to continue...parameters: false => go back, route => change route to
        // a. getData(done) => done to continue...parameters: false => go back, route => change route to
        return {
            changeAction: $action(),
            preChangeAction: $action(),

            add: function(name, path, onValidate, onGetData) {
                recurve.assert(name, "state name must be set");
                recurve.assert(path, "state path must be set");

                // child states
                return {
                    add: function(name, path, onValidate, onGetData) {

                    }
                }
            }
        };
    });
})();<|endoftext|>


<commit_before>/**
 * Calculate the square root of a value
 * @param {*} x
 * @return {String} type  Lower case type, for example "number", "string",
 *                        "array".
 */
math['typeof'] = function math_typeof(x) {
    if (arguments.length != 1) {
        throw newArgumentsError('typeof', arguments.length, 1);
    }

    var type = typeof x,
        name;

    if (type == 'object') {
        if (x == null) {
            return 'null';
        }
        if (x.constructor) {
            // search functions / constants
            for (name in math) {
                if (math.hasOwnProperty(name)) {
                    if (x.constructor == math[name]) {
                        return name.toLowerCase();
                    }
                }
            }

            // search data types
            for (name in math.type) {
                if (math.type.hasOwnProperty(name)) {
                    if (x.constructor == math.type[name]) {
                        return name.toLowerCase();
                    }
                }
            }

            // try the constructors name as last resort
            if (x.constructor.name) {
                return x.constructor.name.toLowerCase();
            }
        }
    }

    return type;
};
<commit_msg>Fixed an error in math.typeof on Internet Explorer.<commit_after>/**
 * Calculate the square root of a value
 * @param {*} x
 * @return {String} type  Lower case type, for example "number", "string",
 *                        "array".
 */
math['typeof'] = function math_typeof(x) {
    if (arguments.length != 1) {
        throw newArgumentsError('typeof', arguments.length, 1);
    }

    var type = typeof x,
        name;

    if (type == 'object') {
        if (x == null) {
            return 'null';
        }
        if (x instanceof Boolean) {
            return 'boolean';
        }
        if (x instanceof Number) {
            return 'number';
        }
        if (x instanceof String) {
            return 'string';
        }
        if (x instanceof Array) {
            return 'array';
        }
        if (x instanceof Date) {
            return 'date';
        }
        if (x.constructor) {
            // search functions / constants
            for (name in math) {
                if (math.hasOwnProperty(name)) {
                    if (x.constructor == math[name]) {
                        return name.toLowerCase();
                    }
                }
            }

            // search data types
            for (name in math.type) {
                if (math.type.hasOwnProperty(name)) {
                    if (x.constructor == math.type[name]) {
                        return name.toLowerCase();
                    }
                }
            }

            // try the constructors name as last resort
            if (x.constructor.name) {
                return x.constructor.name.toLowerCase();
            }
        }
    }

    return type;
};
<|endoftext|>