var	cocoQAsearch = {
//	---
	Version						:	"0.03g"

//	---
,	toTopBefore					:	false
,	toTopAfter					:	true
,	searchWordMin				:	2
,	searchWordMax				:	128
,	showMax						:	0
,	enableResize				:	false
,	scrollAfterResize			:	false
,	truncBefore					:	20
,	truncAfter					:	50
,	defaultString				:	"デフォルト"
//	---
,	update						:	''
,	last_update					:	''
,	search_keyword				:	null
,	result_content				:	null
,	is_loaded					:	false
,	timerId						:	0
,	showMaxCookie				:	'ccqas_showmax'
,	basename					:	'http://homepage3.nifty.com/furyu/cocobbs-entry-##KIND##.js'
//,	basename					:	'./cocobbs-entry-##KIND##.js'
,	timeStampName				:	'http://homepage3.nifty.com/furyu/timestamp.js'
,	kind						:	[ 'debut', 'beginner', 'expert', 'info' ]
,	kindSname					:	{
		'debut'		:	'【はじめる前】'
	,	'beginner'	:	'【初級者向け】'
	,	'expert'	:	'【上級者向け】'
	,	'info'		:	'【ブログ紹介】'
	}
,	kindName					:	{
		'debut'		:	'ココログをはじめる前の疑問解決！'
	,	'beginner'	:	'ココログの使い方解決！（初級者向け）'
	,	'expert'	:	'ココログ徹底活用（上級者向け）'
	,	'info'		:	'あなたのブログ紹介コーナー'
	}
,	kindLink					:	{
		'debut'		:	'http://message2.nifty.com/tb/board/cocolog/top?service_id=debut&board_id=bbs1'
	,	'beginner'	:	'http://message2.nifty.com/tb/board/cocolog/top?service_id=beginner&board_id=bbs1'
	,	'expert'	:	'http://message2.nifty.com/tb/board/cocolog/top?service_id=expert&board_id=bbs1'
	,	'info'		:	'http://message2.nifty.com/tb/board/cocolog/top?service_id=info&board_id=bbs1'
	}
,	reqFlag						:	{ 'debut':false, 'beginner':false, 'expert':false, 'info':false }
,	list						:	{}
,	result						:	{}
,	result_data					:	{}
,	header						:	[
		'<div id="ccqas_notice" class="ccqas_notice">'
//	,	'※スペースで区切ることでAND検索が出来ます。<br />'
//	,	'※この状態からの２度目の検索は非常に高速です。'
	,	'※半角スペースで区切ることでAND検索が出来ます。<br />'
	,	'</div>'
	].join('')
,	footer						:	[
		'<div id="ccqas_copyright" class="ccqas_copyright">'
	,	'copyright (c) 2006 <a href="http://furyu.tea-nifty.com/annex/">furyu</a> , '
	,	'powered by <a href="http://java.cocolog-nifty.com/blog/2005/12/typepadmtajaxja_c70d.html">blog_ajax_json_search.js</a> technology'
	,	'</div>'
	].join('')
//	---
,	setCookie		:	(
		function	( name, value, expires ) {
			document.cookie = [
				name + '=' + escape(value)
			,	'expires=' + expires.toGMTString()
//			,	'domain='
//			,	'path='
//			,	'secure;'
			].join(';') ;
		}
	)	//	end of setCookie()
//	---
,	getCookie		:	(
		function	( name ) {
			var	value = null ;
			for (;;) {
				var	key = name + '=' ;
				var	curCookie = document.cookie;
				var	keyStart = curCookie.indexOf(key) ;
				if ( keyStart < 0 ) {
					break ;
				}
				var	valStart = keyStart + key.length ;
				var	valEnd = curCookie.indexOf(';', valStart) ;
				if ( valEnd < 0 ) valEnd = curCookie.length ;
				value = unescape(curCookie.substring(valStart, valEnd)) ;
				break ;
			}
			return value ;
		}
	)	//	end of getCookie()
//	---
,	delCookie		:	(
		function	( name ) {
    		if ( this.getCookie(name) ) {
    			var	expires = new Date ;
    			expires.setFullYear(expires.getFullYear()-1) ;
				this.setCookie(name, '', expires) ;
			}
		}
	)	//	end of delCookie()
//	---
,	saveShowMax		:	(
		function	( ShowMax ) {
		    var	expires = new Date();
		    expires.setFullYear(expires.getFullYear()+1) ;
		    this.setCookie(this.showMaxcookie, ShowMax, expires) ;
		}
	)	//	end of saveShowMax()
//	---
,	loadShowMax		:	(
		function	() {
			return this.getCookie(this.showMaxcookie) ;
		}
	)	//	end of loadShowMax()
//	---
,	delShowMax		:	(
		function	() {
			this.delCookie(this.showMaxcookie) ;
		}
	)	//	end of delShowMax()
//	---
,	highlight					:	(
		function	( text, keywords ) {
			var	keyword = '' ;
			for ( var ci=0; ci < keywords.length; ci++ ) {
				keyword += ( ci < keywords.length-1 ) ? ( keywords[ci] + '|' ) : ( keywords[ci] ) ;
			}
			if ( keyword == '' ) return text ;
			var	replaced_text = text.replace( new RegExp( '(' + keyword + ')', "ig"), '<span style="background-color: #FFCC33;">' + "$1" + '</span>' ) ;
			while ( replaced_text.match( new RegExp( '(<[^>]*)<span style="background-color: #FFCC33;">(' + keyword + ')</span>([^>]*?>)', "ig") ) ) {
				replaced_text = replaced_text.replace( new RegExp( '(<[^>]*)<span style="background-color: #FFCC33;">(' + keyword + ')</span>([^>]*?>)', "ig"), "$1$2$3" ) ;
			}
			return replaced_text;
		}
	)	//	end of highlight()
//	---
,	trunc						:	(
		function	( text, keyword ) {
			text = text.replace( /<br\/>/g, '' ) ;
			var	key = new RegExp( keyword, "i" ) ;
			var	res = key.exec( text ) ;
			
			if ( res ) {
				var	index  = res.index ;
				var	length = res[0].length ;
				var	start = index - cocoQAsearch.truncBefore ;
				if ( start < 0 ) start = 0 ;
				var	end = cocoQAsearch.truncAfter ;
				text = text.substring( start, index ) + text.substr( index, length ) + text.substr( index+length, end ) ;
			}
			else {
				text = text.substring( 0, cocoQAsearch.truncBefore+cocoQAsearch.truncAfter ) ;
			}
			return text;
		}
	)	//	end of trunc()
//	--
,	make_resize_button			:	(
		function	( truncFlag, kind, number ) {
			if ( !this.enableResize ) return ' ...' ;
			var	button = [
				'<form name="resize" class="ccqas_resize_form" >'
			,	'<input type="button" onclick="cocoQAsearch.show_body(this.form,'
			,	( truncFlag == true ) ? ( 'false );" value="＋" title="広げる" class="ccqas_resize_open" />' ) : ( 'true );" value="－" title="戻す" class="ccqas_resize_close" />' )
			,	'<input type="hidden" name="kind" value="' + kind + '" />'
			,	'<input type="hidden" name="number" value="' + number + '" />'
			,	'</form>'
			].join('') ;
			
			return button ;
		}
	)	//	end of make_resize_button()
//	---
,	show_body					:	(
		function	( form, truncFlag ) {
			var	kind = form.kind.value ;
			var	number = form.number.value ;
			var	button = this.make_resize_button( truncFlag, kind, number ) ;
			var	keywords = this.search_keyword.split(/ |　/);
			var	text = this.result_data[kind][number].body ;
			if ( truncFlag == true ) {
				text = this.trunc( text, keywords[0] ) ;
			}
			else {
				text = text.replace( /<br\/>/g, '<br style="line-height:0.5em;"/>' ) ;
				text = text.replace( /([0-9]+） +名前：)/g, '<hr />$1' ) ;
				text = text.replace( /([0-9]+） +※投稿者による削除)/g, '<hr />$1' ) ;
				text = text.replace( /(　[0-9]{4}\/[0-9]{2}\/[0-9]{2}\([^\)]+\) [0-9]{2}:[0-9]{2})/g, '$1<br />' ) ;
				text = text.replace( /(\[ http[^\]]*\])/g, '$1<br />' ) ;
				text = text.replace( /&amp;/g, "#amp;" ) ;
				text = text.replace( /&([\w]+;)/g, "＆ $1" ) ;
				text = text.replace( /(http[s]?:\/\/[\w~\-\/\.:?=&;#]+)/g, '<a href="$1" target="_blank">$1</a>' ) ;
				text = text.replace( /＆ ([\w]+;)/g, "&$1" ) ;
				text = text.replace( /#amp;/g, "&amp;" ) ;
			}
			text = this.highlight( text, keywords ) ;
			text = button + text ;
			var	parent = form.parentNode ;
			parent.innerHTML = text ;
			
			if ( this.scrollAfterResize ) {
				var	entry = parent.parentNode ;
				var	oldPosition = entry.style.position ;
				entry.style.position = "absolute" ;
				window.scrollTo( 0, entry.offsetTop ) ;
				entry.style.position = oldPosition ;
			}
		}
	)	//	end of show_body()
//	---
,	update_show_list		:	(
		function	( form, startno ) {
			for (;;) {
				if ( !form ) break ;
				var	kind = form.kind.value ;
				var	result_data = this.result_data[kind] ;
				if ( !result_data ) break ;
				var	startno = eval( startno ) ;
				if ( startno < 0 || result_data.length <= startno ) break ;
				var	count = result_data.length - startno ;
				if ( this.showMax < count ) count = this.showMax ;
				
				var	keywords = this.search_keyword.split(/ |　/);
				
				var	target = document.getElementById( 'ccqas_list_' + kind ) ;
				if ( target ) {
					target.innerHTML = this.build_show_list( result_data, keywords, kind, startno, count ) ;
					location.hash = 'ccqas_' + kind ;
				}
				break ;
			}
		}
	)	//	end of update_show_list()
//	---
,	build_show_list			:	(
		function ( result_data, keywords, kind, startno, count ) {
			var	highlight = this.highlight ;
			var	trunc = this.trunc ;
			
			if ( !startno || result_data.length <= startno ) startno = 0 ;
			if ( !count || result_data.length < startno+count ) count = result_data.length - startno ;
			
			var	nav = [
				'<div class="ccqas_navigator">'
			,	'<form name="ccqas_nav_' + kind + '" class="ccqas_nav_form">'
			,	'<input type="hidden" name="kind" value="' + kind + '" />'
			].join('') ;
			
			if ( this.showMax && ( ( 0 < startno ) || ( startno + count < result_data.length ) ) ) {
				var	current = Math.floor((startno+this.showMax-1)/this.showMax) ;
				nav += [
					'<input type="button" value="<<" title="前の' + this.showMax + '件" onclick="javascript:cocoQAsearch.update_show_list(this.form, ' + eval(startno-this.showMax) + ');" ' + ( ( 0 < startno ) ? 'class="ccqas_nav"' : 'disabled class="ccqas_nav_disable"' ) + ' />'
				].join('') ;
				for ( var ci=0; ci < Math.floor((result_data.length+this.showMax-1)/this.showMax); ci++ ) {
					var	sno = 1 + eval( this.showMax ) * ci ;
					var	eno = eval( this.showMax ) * (ci+1) ;
					if ( result_data.length < eno ) eno = result_data.length ;
					nav += [
						'<input type="button" onclick="javascript:cocoQAsearch.update_show_list(this.form, ' + this.showMax * ci + ');" '
					,	'value="' + eval(ci+1) + '" '
					,	( current == ci ) ? 'class="ccqas_nav_disable" disabled ' : 'class="ccqas_nav" '
					,	'title="' + sno + '～' + eno + '" '
					,	'/>'
					].join('') ;
				}
				nav += [
					'<input type="button" value=">>" title="次の' + this.showMax + '件" onclick="javascript:cocoQAsearch.update_show_list(this.form, ' + eval(startno+this.showMax) + ');" ' + ( ( startno + count < result_data.length ) ? 'class="ccqas_nav"' : 'disabled class="ccqas_nav_disable"' ) + ' />'
				].join('') ;
			}
			nav += [
				'</form>'
			,	'</div>'	//	end of <div class="ccqas_navigator">
			].join('') ;
			
			var html = [
				nav
			,	'<ol type="1" start="' + eval(1+startno) + '" class="ccqas_ol">'
			].join('') ;
			
			for ( var ci=startno; ci < startno+count && ci < result_data.length; ci++ ) {
				var	user = result_data[ci].name ;
				if ( result_data[ci].usrlink ) {
					user = '<a href="' + result_data[ci].usrlink + '" target="_blank">' + user + '</a>' ;
				}
				var	test = result_data[ci].link ;
				var	pageall = 1 ;
				var	condList = test.match( /cond_key=[0-9]+/g ) ;
				if ( condList ) {
					condList.toString().match( /([0-9]+)$/ ) ;
					pageall = RegExp.$1 ;
				}
				var	pageStr = '' ;
				if ( 1 < pageall ) {
					var	page =  ( test.match( /&page=([0-9]+)/ ) ) ? RegExp.$1 : 1 ;
					pageStr = ' (Page ' + page + ')' ;
				}
				var	button = this.make_resize_button( true, kind, ci ) ;
				html += [
					'<li class="ccqas_li"><div class="ccqas_title">' + this.kindSname[kind]
				,	'<a href="' + result_data[ci].link
//				,	'#search_word=' + this.search_keyword
				,	'" target="_blank">'
				,	highlight( result_data[ci].title, keywords )
				,	'</a>' + pageStr
				,	'</div>'
				,	'<div class="ccqas_user">' + '<span class="ccqas_date">' + highlight( result_data[ci].date, keywords ) + '</span>' + highlight( user, keywords ) + '</div>'
				,	'<div class="ccqas_body">' + button + highlight( trunc( result_data[ci].body, keywords[0] ), keywords ) + '</div>'
				,	'</li>'
				].join('') ;
			}
			html += [
				'</ol>'
			,	nav
			,	'<div class="ccqas_update">Last Update: ' +  this.list[kind].update + '</div>'
			].join('') ;
			
			return html ;
		}
	)	//	end of build_show_list()
//	---
,	build_search_result_html	:	(
		function ( result_data, keywords, kind, startno, count ) {
			if ( !startno || result_data.length <= startno ) startno = 0 ;
			if ( !count || result_data.length < startno+count ) count = result_data.length - startno ;
			
			var	html = [
				'<div class="entry-top"></div>'
			,	'<div class="entry">'
			,	'<h3><a id="ccqas_' + kind + '"></a> ' + this.kindName[kind] + '： 検索結果（' + result_data.length + '件ヒット）</h3>'
			,	'<div class="entry-body-top"></div>'
			,	'<div class="entry-body">'
			,	'<div class="entry-body-text" id="ccqas_list_' + kind + '">'
			].join('') ;
			html += this.build_show_list( result_data, keywords, kind, startno, count ) ;
			html += [
				'</div>'	//	end of <div class="entry-body-text">
			,	'</div>'	//	end of <div class="entry-body">
			,	'<div class="entry-body-bottom"></div>'
			,	'<p class="posted"><span class="post-footers"></span><span class="separator"></span></p>'
			,	'</div>'	//	end of <div class="entry">
			,	'<div class="entry-bottom"></div>'
			,	'<div class="date-footer"></div>'
			].join('') ;
			
			return html ;
		}
	)	//	end of build_search_result_html()
//	---
,	search						:	(
		function	( kind ) {
			var	entries = this.list[kind].data ;
			var	result_data = new Array() ;
			var	search_keyword = this.search_keyword ;
/*
//			search_keyword = search_keyword.replace( /([\/\\\.\*\+\?\|\(\)\[\]\{\}\$\^])/g, "\\$1" ) ;
//			search_keyword = search_keyword.replace( /( +|　+)/, ' ' ) ;
//			search_keyword = search_keyword.replace( /( |　)$/, '' ) ;
//			this.search_keyword = search_keyword ;
*/
			var	keywords = search_keyword.split(/ |　/);
			var	key = new Array() ;
			for ( var ci= 0; ci < keywords.length; ci++ ) {
				key[key.length] = new RegExp( keywords[ci], "i" ) ;
			}
			for ( var ci=0; ci < entries.length-1; ci++ ) {
				var	is_match = true;
				for ( var cj=0; cj < key.length; cj++ ) {
					var	res_title = key[cj].exec( entries[ci].title ) ;
//					var	res_body = key[cj].exec( entries[ci].body ) ;
					var	res_body = key[cj].exec( entries[ci].body.replace( /<br\/>/g, '' ) ) ;
					var	res_name = key[cj].exec( entries[ci].name ) ;
					var	res_date = key[cj].exec( entries[ci].date ) ;
					if ( !res_title && !res_body && !res_name && !res_date ) {
						is_match = false ;
					}
				}
				if ( is_match ) {
					result_data[result_data.length] = entries[ci] ;
				}
			}
			this.result_data[kind] = result_data ;
			var	result_html = this.build_search_result_html( result_data, keywords, kind, 0, this.showMax ) ;
			
			return result_html ;
		}
	)	//	end of search()
//	---
,	loadComplete				:	(
		function	( kind ) {
//			alert( 'load completed: ' + kind ) ;
			var	ci ;
			this.result[kind] = this.search( kind ) ;
			for ( ci=0; ci < this.kind.length; ci++ ) {
				var	chk = this.kind[ci] ;
				if ( this.reqFlag[chk] && !this.list[chk] ) break ;
			}
			if ( ci < this.kind.length ) {
				return false ;
			}
			this.is_loaded = true ;
			if ( this.timerId ) {
				clearTimeout( this.timerId ) ;
				this.timerId = 0 ;
			}
			var	links = '' ;
			var	result = '' ;
			var	total = 0 ;
			for ( ci=0; ci < this.kind.length; ci++ ) {
				var	chk = this.kind[ci] ;
				if ( this.reqFlag[chk] ) {
					links += '<a href="' + this.kindLink[chk] + '" target="_blank" title="『みんなで解決！広場』の「最新の発言一覧」へ" >■</a> <a href="#ccqas_' + chk + '" title="検索結果へ" >' + this.kindName[chk] + '： 検索結果（' + this.result_data[chk].length + '件ヒット）</a><br />' ;
					result += this.result[chk] ;
					total += this.result_data[chk].length ;
				}
			}
			links = '<div class="ccqas_links">' + links + '【計' + total + '件ヒット】</div>' ;
			this.result_content.innerHTML = this.header + links + result + this.footer ;
			
			if ( this.toTopAfter ) {
				window.scrollTo( 0, 0 ) ;
			}
			return true ;
		}
	)	//	end of loadComplete()
//	---
,	loadScript					:	(
		function	( src, charset ) {
			var	callScript = document.createElement("script") ;
			callScript.type = "text/javascript" ;
			callScript.charset = ( charset ) ? charset : "euc-jp" ;
			callScript.src = src ;
			
			document.body.appendChild( callScript ) ;
		}
	)	//	end of loadScript()
//	---
,	load						:	(
		function	( kind ) {
//			alert( 'load: ' + kind ) ;
			if ( typeof this.list[kind] != "undefined" ) {
				this.loadComplete( kind ) ;
				return ;
			}
//			this.loadScript( this.basename.replace( '##KIND##', kind ) + "?reload=" + (new Date).getTime() ) ;
			this.loadScript( this.basename.replace( '##KIND##', kind ) + "?timestamp=" + encodeURIComponent( this.update ) ) ;
		}
	)	//	end of load()
//	---
,	loadSearchData		:	(
		function	() {
			if ( this.last_update && this.last_update != this.update ) {
				this.list = {} ;
			}
			this.last_update = this.update ;
			for ( var ci=0; ci < this.kind.length; ci++ ) {
				var	chk = this.kind[ci] ;
				if ( this.reqFlag[chk] ) this.load( chk ) ;
			}
		}
	)	//	end of loadSearchData()
//	---
,	added_period				:	(
		function	( content ) {
			if ( !this.is_loaded ) {
				this.result_content.innerHTML += '.' ;
				this.timerId = setTimeout( "cocoQAsearch.added_period()", 1000 ) ;
			}
		}
	)	//	end of added_period()
//	---
,	request						:	(
		function	() {
			if ( arguments.length < 1 ) {
				alert( 'no argument' ) ;
				return false ;
			}
//			this.search_keyword = arguments[0] ;
			var	search_keyword = arguments[0] ;
			search_keyword = search_keyword.replace( /([\/\\\.\*\+\?\|\(\)\[\]\{\}\$\^])/g, "\\$1" ) ;
			search_keyword = search_keyword.replace( /&/g, "&amp;" ) ;
			search_keyword = search_keyword.replace( /( +|　+)/, ' ' ) ;
			search_keyword = search_keyword.replace( /( |　)$/, '' ) ;
			this.search_keyword = search_keyword ;
			
			if ( !this.result_content ) {
				var	divs = document.getElementsByTagName('div') ;
				for ( var ci=0; ci < divs.length; ci++ ) {
					if ( divs[ci].className == 'content' ) {
						this.result_content = divs[ci] ;
						break ;
					}
				}
				if ( !this.result_content ) {
					alert( '<div class="content"> required' ) ;
					return false ;
				}
			}
			if ( arguments.length == 1 ) {
				for ( var key in this.reqFlag ) {
					this.reqFlag[key] = true ;
				}
			}
			else {
				for ( var key in this.reqFlag ) {
					this.reqFlag[key] = false ;
				}
				for ( var ci=1; ci < arguments.length; ci++ ) {
					this.reqFlag[arguments[ci]] = true ;
				}
			}
			this.is_loaded = false ;
			
			if ( this.toTopBefore ) {
				window.scrollTo( 0, 0 ) ;
			}
			this.result_content.innerHTML = 'now searching .' ;
			this.added_period( this.result_content ) ;
/*
//			for ( var ci=0; ci < this.kind.length; ci++ ) {
//				var	chk = this.kind[ci] ;
//				if ( this.reqFlag[chk] ) this.load( chk ) ;
//			}
*/
			this.loadScript( this.timeStampName  + "?reload=" + (new Date).getTime() ) ;
			
			return true ;
		}
	)	//	end of request()
//	---
,	requestForm					:	(
		function	( form ) {
			for (;;) {
				if ( !form ) {
					form = document.forms.ccqas_form ;
					if ( !form ) break ;	//	Error
				}
				var	value = form.search_box.value ;
				var	prms = value.replace(/( +|　+)/, ' ').replace(/(^ | $)/,'').split(' ') ;
				var	ci ;
				if ( this.searchWordMin ) {
					for ( ci=0; ci < prms.length; ci++ ) {
						if ( prms[ci].length < this.searchWordMin ) break ;
					}
					if ( ci < prms.length ) {
						alert( '検索の際には' + this.searchWordMin + '文字以上の文字列を指定してください' ) ;
						break ;	//	Error
					}
				}
				if ( this.searchWordMax ) {
					for ( ci=0; ci < prms.length; ci++ ) {
						if ( this.searchWordMax < prms[ci].length ) break ;
					}
					if ( ci < prms.length ) {
						alert( '検索の際には' + this.searchWordMax + '文字以下の文字列を指定してください' ) ;
						break ;	//	Error
					}
				}
				var	options = [
					form.search_box.value
				] ;
				for ( var ci=0; ci < this.kind.length; ci++ ) {
					var	chk =this.kind[ci] ;
					if ( form[chk].checked ) options[options.length] = chk ;
				}
				var	slct = form.ccqas_showmax ;
				if ( slct ) {
					var	idx = slct.selectedIndex ;
					if ( slct.options[idx].innerHTML == this.defaultString ) {
						var	showMax = this.loadShowMax() ;
						if ( showMax ) {
							this.showMax = eval( showMax ) ;
						}
						for ( var ci=0; ci < slct.options.length; ci++ ) {
							if ( ci == idx ) continue ;
							if ( slct.options[ci].value == this.showMax ) {
								slct.options[ci].selected = true ;
								break ;
							}
						}
					}
					else {
						this.showMax = eval( slct.options[idx].value ) ;
					}
					this.saveShowMax( this.showMax ) ;
				}
				this.request.apply( this, options ) ;
				break ;	//	OK
			}
		}
	)	//	end of requestForm()
//	---
,	initForm					:	(
		function	() {
			for (;;) {
				var	form = document.forms.ccqas_form ;
				if ( !form ) break ;
				var	slct = form.ccqas_showmax ;
				if ( !slct ) break ;
				var	showMax = this.loadShowMax() ;
				if ( showMax ) {
					this.showMax = eval( showMax ) ;
				}
				for ( var ci=0; ci < slct.options.length; ci++ ) {
					if ( slct.options[ci].innerHTML == this.defaultString ) continue ;
					if ( slct.options[ci].value == this.showMax ) {
						slct.options[ci].selected = true ;
						break ;
					}
				}
				this.saveShowMax( this.showMax ) ;
				break ;
			}
		}
	)	//	end of initForm()
	
} ;	//	end of cocoQAsearch Object
