/*
 * ============================================================================
 *                   The ProQuality Inc.
 *         Rapid Efficent Low cost And Xtreme (RELAX)
 *	           Advanced Solutions Framework (ASF)
 *                  Cristian Teodorescu
 *                      Version 6.0
 * ============================================================================
 * 
 *    Copyright (C) 1999 The ProQuality Inc. Foundation. All rights reserved.
 * 
 * The use of this software in any form is strictly prohibited unless you have 
 * purchased a licence from ProQuality Inc. or you have a software agreement with 
 * ProQuality Inc.
 * 
 * Redistributions of source code must retain copyright statements
 * and notices. Redistributions must also contain a copy of this
 * document.
 *
  THIS SOFTWARE IS PROVIDED BY PROQUALITY AND CONTRIBUTORS ``AS IS'' AND
  ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PROQUALITY OR ITS
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  DAMAGE.
    
 *
 */
Global_run_event_hook = true;
Global_combo_array    = new Array();

var ComboBoxHandler = {
	registerArray	: 	{},
	all				: 	{},
	adjustableCombos:	{},
	activeCombo		:	null,
	focusCombo		:	null,
	register		: 	function (fieldName, optionsArray, disabled, onselect, flyover, dropDownWidth, dropDownHeight, removeArrow, adjustToFit, listAbove) 
						{
							if(ComboBoxHandler.registerArray[fieldName] == null)
							{
								ComboBoxHandler.registerArray[fieldName]= new ComboBoxRegistrationObject(fieldName, optionsArray, disabled, onselect, flyover, dropDownWidth, dropDownHeight, removeArrow, adjustToFit, listAbove);
							}
						},
	setFocus		:	function (name)
						{
							if(ComboBoxHandler.all[name])
							{
								ComboBoxHandler.all[name].setFocus();
							}
						},
    unload          :   function() { for ( var i in ComboBoxHandler.all ) { ComboBoxHandler.all[i].txtview.combo = null; } }
}


function ComboBoxRegistrationObject(fieldName, optionsArray, disabled, onselect, flyover, dropDownWidth, dropDownHeight, removeArrow, adjustToFit, listAbove)
{
	this.fieldName = fieldName;
	this.optionsArray = optionsArray;
	this.disabled = disabled;
	this.onselect = onselect;
	this.flyover = flyover;
	this.dropDownWidth = dropDownWidth;
	this.dropDownHeight = dropDownHeight;
	this.removeArrow = removeArrow;
	this.adjustToFit = adjustToFit;
	this.listAbove = listAbove;
}

function comboBoxInit ()
{
	for(var fieldName in ComboBoxHandler.registerArray)
	{
		var c = ComboBoxHandler.registerArray[fieldName];
		var elem = document.getElementById(fieldName+"txt");
		elem.ownerDocument.body.onunload = ComboBoxHandler.unload;
		if(elem != null)
		{
			new ComboBox(fieldName, elem, c.optionsArray, c.disabled, c.onselect, c.flyover, c.dropDownWidth, c.dropDownHeight, c.removeArrow, c.adjustToFit, c.listAbove);
		}		
	}
}

function ComboBox()
{
    if(arguments.length==0)
    {
        self.status="ComboBox invalid - no name arg"
    }

 	this.arguments = arguments;
 	
 	this.name     = arguments[0];
    this.fieldName = arguments[0];
 	this.txtview = arguments[1];
 	this.options  = arguments[2]||new Array();
 	this.disabled = arguments[3];
 	var onselect = arguments[4];
 	if(onselect != null)
 	{
 		this.onselect = new Function("", onselect);
 	}
 	this.flyover = arguments[5];
 	this.dropDownWidth = arguments[6];
 	this.dropDownHeight = arguments[7];
 	this.removeArrow = arguments[8];
 	this.adjustToFit = arguments[9];
 	this.listAbove = arguments[10];
 	this.par      = document.body;
    this.icon	  = "/base/images/iconCombo.gif"
    
    this.expops   = new Array();
    this.currentItem = new ComboBoxItem("", "", false);
    this.currentRow = -1;
    this.handlerCall = "ComboBoxHandler.all[\"" + this.name + "\"]";
    this.isActive = false;

    this.activate   = ComboBox_activate;
    this.deactivate = ComboBox_deactivate;
    this.build      = ComboBox_build;
    this.make       = ComboBox_make;
    this.reMake       = ComboBox_reMake;
    this.choose     = ComboBox_choose;
    this.add        = ComboBox_add;
    this.toggle     = ComboBox_toggle;
    this.update     = ComboBox_update;
    this.show       = ComboBox_show;
    this.hilite     = ComboBox_hilite;
    this.testKey	= ComboBox_testKey;
    this.testInput	= ComboBox_testInput;
    this.position   = ComboBox_position;
    this.setFocus	= ComboBox_setFocus;
    this.resize     = ComboBox_resize;

    this.make();
    
    Global_combo_array[Global_combo_array.length]=this;
    
    ComboBoxHandler.all[this.name] = this;
}

function ComboBoxItem(text,value,selected,attributes)
{
    this.text  = text;
    this.value = value;
    this.selected = selected;
    this.attributes = attributes;
    
    this.getAttribute = function(name)
    {
    	return this.attributes[name];
    }
}

function ComboBox_make()
{
	// determine width of table
	var testDiv = document.createElement("DIV");
	document.body.appendChild(testDiv);
	var testTable = document.createElement("TABLE");
	testDiv.appendChild(testTable);
	for(var i=0; i < this.options.length; i++)
	{
		var row = testTable.insertRow(i);
		var cell = row.insertCell(0);
		var textNode = document.createTextNode(' '+this.options[i].text+' ');
		cell.appendChild(textNode);
	}
	this.tableWidth =  testTable.offsetWidth + 5;
	document.body.removeChild(testDiv);
	
	// determine original width of input field
	this.originalWidth = this.txtview.offsetWidth;
	
	this.txtview.combo = this;
	if(this.disabled)
	{
	    this.txtview.disabled = true;
	}
		       
    this.valcon = document.createElement("INPUT");
    this.valcon.type = "hidden";
    this.valcon.name = this.fieldName;
    this.valcon.id = this.fieldName;
    this.valcon.value = "";
    this.txtview.parentNode.appendChild(this.valcon);
                
	if(!this.removeArrow)
	{    
		this.toggleImg = document.createElement("IMG");
		this.toggleImg.src = this.icon;
		if(!this.disabled)
		{
			this.toggleImg.onclick = new Function ("", this.handlerCall + ".toggle()");
		}
		this.txtview.parentNode.insertBefore(this.toggleImg,this.txtview.nextSibling);
		this.imageWidth = this.toggleImg.offsetWidth;
	}
	else
	{
		this.imageWidth = 0;
	}
	
	this.originalParentWidth = this.txtview.parentNode.offsetWidth;
	ComboBox.addEvent(window, "resize", new Function ("", this.handlerCall + ".resize()"));
	if(this.adjustToFit)
	{
		// this is based off of the txtview already set at 100% width in tag
		this.txtview.style.width = (this.originalWidth - this.imageWidth - 1);
	}
	else
	{
		if(this.tableWidth > this.originalWidth)
		{
			if(this.tableWidth < this.originalParentWidth - this.imageWidth - 15)
			{
				this.txtview.style.width = this.tableWidth;
			}
			else
			{
			  if ( this.originalParentWidth - this.imageWidth - 15 >= 0 )
			  {
			    this.txtview.style.width = this.originalParentWidth - this.imageWidth - 15;
			  }
			}
		}
	}
	
	for(var i = 0; i < this.options.length; i++)
	{
		if(this.options[i].selected)
		{
			this.txtview.value = this.options[i].text;
			this.valcon.value = this.options[i].value;
			if(this.flyover)
			{
				this.txtview.title = this.txtview.value;
			}
		}
	}
}

function ComboBox_reMake()
{
	var testDiv = document.createElement("DIV");
	document.body.appendChild(testDiv);
	var testTable = document.createElement("TABLE");
	testDiv.appendChild(testTable);
	for(var i=0; i < this.options.length; i++)
	{
		var row = testTable.insertRow(i);
		var cell = row.insertCell(0);
		var textNode = document.createTextNode(' '+this.options[i].text+' ');
		cell.appendChild(textNode);
	}
	this.tableWidth =  testTable.offsetWidth + 5;
	document.body.removeChild(testDiv);

}


function ComboBox_setFocus()
{
	this.txtview.focus();
}

function ComboBox_resize()
{
	if(this.adjustToFit)
	{
		this.txtview.style.width = this.txtview.parentNode.offsetWidth - (this.originalParentWidth - this.txtview.offsetWidth);
		this.originalParentWidth = this.txtview.parentNode.offsetWidth;
	}
	else
	{
		var newParentWidth = this.txtview.parentNode.offsetWidth;
		if(this.tableWidth > this.originalWidth)
		{
			if(this.tableWidth < newParentWidth - this.imageWidth - 15)
			{
				this.txtview.style.width = this.tableWidth;
			}
			else
			{
				this.txtview.style.width = newParentWidth - this.imageWidth - 15;
			}
		}
	}
}

function ComboBox_choose(rowNumber)
{
	if(rowNumber >= 0)
	{
		this.currentItem = this.expops[rowNumber];
	}
    this.txtview.value = this.currentItem.text;
    this.valcon.value  = this.currentItem.value;
    if(this.flyover)
    {
    	this.txtview.title = this.txtview.value;
    }
    this.txtview.focus();
    this.txtview.select();
    this.deactivate();
    if(this.onselect)
    {
    	this.onselect();
    }
}

function ComboBox_testKey(evt)
{
	var preventPropagation = false;
	
	evt = (evt) ? evt : ((event) ? event : null);

	if (evt)
	{
		var el = ComboBox.getTargetElement(evt);
		var key = evt.keyCode;
		var combo = el.combo;
		
		if(combo && !combo.isActive)
		{
			if(key == 40) //down arrow
			{
				combo.activate(true);
				preventPropagation = true;
			}
			else if(key == 8 || key == 46 || ComboBox.isCharacterKey(key)) // backspace. delete. or character key
			{
				combo.activate(false);
			}
		}

		if(preventPropagation)
		{
			return ComboBox.stopEvent(evt);
		}

		return true;
	}
}

function ComboBox_checkCombo(evt)
{
	if (!ComboBoxHandler.activeCombo)
	{
		return false;
	}
	var el = ComboBox.getTargetElement(evt);
	for (; el != null && el != ComboBoxHandler.activeCombo.opslist; el = el.parentNode);
	if (el == null)
	{
		ComboBoxHandler.activeCombo.testInput();
		ComboBoxHandler.activeCombo.deactivate();
		return ComboBox.stopEvent(evt);
	}
}

function ComboBox_handleKeyDown(evt)
{
	var combo = ComboBoxHandler.activeCombo;
	var table;
	var preventPropagation = false;
	
	evt = (evt) ? evt : ((event) ? event : null);

	if (evt)
	{
		var key = evt.keyCode;
		
		if(evt.altKey)
		{
			combo.deactivate();
			combo.txtview.blur();
		}
		else
		{
			if(key == 40) //down key
			{
				if(combo.isActive)
				{
				    if(combo.currentRow >= 0 && combo.currentRow < combo.opsTable.rows.length -1)
					{
						combo.position(combo.hilite(combo.currentRow + 1));
					}
	    		}
	    		else 
				{
					combo.txtview.focus();
				    combo.update(false);
			        combo.build();
			        combo.show();
				}
				
				preventPropagation = true;
			}
	
			if(key == 38) //up key
			{
				if(combo.isActive)
				{
					if(combo.currentRow > 0)
					{
						combo.position(combo.hilite(combo.currentRow - 1));
					}
				}
				
				preventPropagation = true;
			}
		
			if(key == 13) //enter key
			{
				if(combo.isActive && combo.currentRow >= 0)
				{
					ComboBoxHandler.all[combo.name].choose(combo.currentRow);
					ComboBoxHandler.all[combo.name].opslist.style.display='none';
				}
				
				preventPropagation = true;			
			}
			
			if(key == 9) //tab key
			{
				if(combo.isActive)
				{
					ComboBoxHandler.all[combo.name].choose(combo.currentRow);
					ComboBoxHandler.all[combo.name].opslist.style.display='none';
				}
			}
			
			if(key == 27) //esc key
			{
				if(combo.isActive)
				{
					combo.txtview.value = combo.currentItem.text;
					combo.valcon.value = combo.currentItem.value;
					combo.txtview.focus();
					combo.txtview.select();
					combo.deactivate();
				}
		
				preventPropagation = true;
			}
		}
		
		if(preventPropagation)
		{
			return ComboBox.stopEvent(evt);
		}

		return true;
	}
}

function ComboBox_handleKeyUp(evt)
{
	var combo = ComboBoxHandler.activeCombo;
	var table;
	var preventPropagation = false;
	
	evt = (evt) ? evt : ((event) ? event : null);

	if (evt)
	{
		var key = evt.keyCode;
		
		if(key == 8 || key == 46 || ComboBox.isCharacterKey(key)) // backspace. delete. or character key
		{
			combo.update(true);
			combo.build();
			combo.show();
			 	
		 	return ComboBox.stopEvent(evt);
		}
	}
}

function ComboBox_mouseDown(evt)
{
    var combo = ComboBoxHandler.activeCombo;
    
    evt = (evt) ? evt : ((event) ? event : null);
	if (evt)
	{
		var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
		
		if (node)
		{
	        if(node.nodeName.toLowerCase() == "td")
	        {
	        	var rowNumber = node.getAttribute("rowNumber");
	        	combo.choose(rowNumber);
	        	ComboBoxHandler.focusCombo = combo;
	        }
	        else if(node.parentNode.nodeName.toLowerCase() == "td") //for Netscape
			{
				var rowNumber = node.parentNode.getAttribute("rowNumber");
				combo.choose(rowNumber);
				ComboBoxHandler.focusCombo = combo;
	        }
	        
	        return ComboBox.stopEvent(evt);
		}
    }
}

function ComboBox_handleFocus(evt)
{
	if(ComboBoxHandler.focusCombo)
	{
		ComboBoxHandler.focusCombo.txtview.focus();
		ComboBoxHandler.focusCombo.txtview.select();
		ComboBoxHandler.focusCombo = null;
	}
	
	ComboBox.removeEvent(window, "focus", ComboBox_handleFocus);
	return ComboBox.stopEvent(evt);	
}

function ComboBox_position(cell)
{
	if(((cell.offsetTop + cell.offsetHeight) - this.opslist.scrollTop) > (this.opslist.offsetHeight - 3))
	{
		this.opslist.scrollTop = (cell.offsetTop + cell.offsetHeight) - (this.opslist.offsetHeight - 3);
	}
	else if((cell.offsetTop - this.opslist.scrollTop) < 0)
	{
		this.opslist.scrollTop =  cell.offsetTop;
	}
}

function ComboBox_activate(show) //show options list when activating
{
    if(!this.isActive)
    {
    	ComboBoxHandler.activeCombo = this;
    	this.isActive = true;
		if(show)
		{
			this.update(false);
			this.build();
			this.show();
		}
		
		ComboBox.addEvent(document, "keydown", ComboBox_handleKeyDown);
		ComboBox.addEvent(document, "keyup", ComboBox_handleKeyUp);
		ComboBox.addEvent(document, "mousedown", ComboBox_checkCombo);
		ComboBox.addEvent(window, "focus", ComboBox_handleFocus);
	}
}

function ComboBox_deactivate()
{
    ComboBoxHandler.activeCombo = null;
	ComboBox.removeEvent(document, "keydown", ComboBox_handleKeyDown);
	ComboBox.removeEvent(document, "keyup", ComboBox_handleKeyUp);
	ComboBox.removeEvent(document, "mousedown", ComboBox_checkCombo);
	
	if(this.opslist)
	{
		if(this.opslist.style.display=="block")
		{
			this.opslist.style.display='none';
		}
	}
	
	this.isActive = false;
}

function ComboBox_testInput()
{
	var val = this.txtview.value.toLowerCase();
	for(i=0;i < this.options.length;i++)
	{
		var opt = this.options[i].text.toLowerCase();
		if(val == opt)
		{
			this.currentItem = this.options[i];
			this.txtview.value = this.currentItem.text;
			this.valcon.value = this.currentItem.value;
			if(this.flyover)
			{
				this.txtview.title = this.txtview.value;
			}
			return true;
		}
	}

	this.currentItem = new ComboBoxItem("", "", false);
	this.txtview.value = "";
	this.valcon.value = "";
	if(this.flyover)
	{
		this.txtview.title = null;
	}
	return false;
}

function ComboBox_show()
{
	var pos = ComboBox.getAbsolutePos(this.txtview);
	var windowWidth = window.innerWidth ? window.innerWidth : document.body.offsetWidth;
	if((this.dropDownWidth) && ((pos.x + this.dropDownWidth) > (windowWidth - 25)))
	{
		this.opslist.style.left = (windowWidth - this.dropDownWidth - 25) + "px";
	}
	else
	{
		this.opslist.style.left = pos.x + "px";
	}
	
	this.opslist.style.display="block";
	
	if(this.listAbove)
	{
		this.opslist.style.top = (pos.y - this.opslist.offsetHeight) + "px";
	}
	else
	{
		this.opslist.style.top = (pos.y + this.txtview.offsetHeight) + "px";
	}
	
	if(this.currentRow >= 0)
	{
		var offset = this.hilite(this.currentRow);
		this.opslist.scrollTop = this.opslist.scrollTop + (offset * this.currentRow);
	}
}

function ComboBox_add()
{
    var i,arglen;
    arglen=arguments.length
    for(i=0;i<arglen;i++)
    {
        this.options[this.options.length]=arguments[i]
    }
}

function ComboBox_hilite(rowNumber)
{
    this.opsTable.rows[this.currentRow].cells[0].className='combo-item';
	this.opsTable.rows[rowNumber].cells[0].className='combo-hilite';
	this.currentRow = rowNumber;
	//dbg("top: " + this.opsTable.rows[rowNumber].cells[0].offsetTop);
	//return this.opsTable.rows[rowNumber].cells[0].offsetHeight;
	return this.opsTable.rows[rowNumber].cells[0];
}

function ComboBox_update(useText) //use text in txtview to build expops array
{
	var opart,astr,alen,opln,i,boo;
    boo=false;
    opln = this.options.length
    astr = this.txtview.value.toLowerCase();
    alen = astr.length
    this.expops = new Array();

    if(!useText)
    {
        for(i=0;i<opln;i++)
        {
            this.expops[this.expops.length]=this.options[i];
            boo=true;
        }
    }
    else
    {
        for(i=0;i<opln;i++)
        {
            opart=this.options[i].text.toLowerCase().substring(0,alen)
            if(astr==opart)
            {
                this.expops[this.expops.length]=this.options[i];
                boo=true;
            }
        }
    }

    if(!boo)
    {
    	this.expops[0]=new ComboBoxItem("(No matches)","");
    }
    
    return boo;
}

function ComboBox_build()
{
    var arr = this.expops;
    
    var str,arrlen,widthStr;
    arrlen=arr.length;
    
    this.opsTable = document.createElement("TABLE");
    this.opsTable.id = this.name + "table";
    this.opsTable.width = "100%";
    this.opsTable.cellPadding = 0;
    this.opsTable.cellSpacing = 0;
    
    str = '<tbody>';
    var strs = new Array(arrlen);
    this.currentRow = 0;
    for(var i=0;i<arrlen;i++)
    {
        if(arr[i].value == this.valcon.value)
        {
        	this.currentRow = i;
        }
        
        var row = this.opsTable.insertRow(i);
		var cell = row.insertCell(0);
		cell.className = "combo-item";
		if(arr.length == 1 && arr[i].text == "(No matches)")
		{
			this.currentRow = -1;
		}
		else
		{
			cell.onmouseover = new Function ("", this.handlerCall + '.hilite(' + i + ')');
			cell.setAttribute("rowNumber", i);
			if(this.flyover)
			{
				cell.title = arr[i].text;
			}
			ComboBox.addEvent(cell, "mousedown", ComboBox_mouseDown);
		}
		var textNode = document.createTextNode(' '+arr[i].text+' ');
		if (document.addEventListener) //for Netscape only
		{
			textNode.addEventListener("mousedown", ComboBox_mouseDown, false );
		}
		cell.appendChild(textNode);
    }
    
    if(this.opslist)
    {
    	this.par.removeChild(this.opslist);
    }
    
    this.opslist = document.createElement("DIV");
    this.opslist.id = this.name + "opslistdiv";
    this.opslist.appendChild(this.opsTable);
    this.opslist.style.display='none';
    this.opslist.style.position = "absolute";
    this.opslist.style.width = this.dropDownWidth ? this.dropDownWidth : ( this.removeArrow ? this.txtview.offsetWidth : (this.txtview.offsetWidth + this.toggleImg.offsetWidth));
    this.opslist.style.height = this.dropDownHeight ? this.dropDownHeight : "100px";
    this.opslist.className = "combo-list";
    this.opslist.onselectstart=returnFalse;
            
    this.par.appendChild(this.opslist);
}

function ComboBox_toggle()
{
    if(!this.isActive)
    {
        this.activate(true);
        this.txtview.focus();
    }
}

ComboBox.stopEvent = function(ev) {
	if (ComboBox.isIE) {
		window.event.cancelBubble = true;
		window.event.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
}

ComboBox.addEvent = function(el, evname, func) {
	if (el.attachEvent) // IE
	{
		el.attachEvent("on" + evname, func);
	} 
	else if (el.addEventListener) // Gecko / W3C
	{
		el.addEventListener(evname, func, true);
	}
}

ComboBox.removeEvent = function(el, evname, func) {
	if (el.detachEvent) // IE 
	{
		el.detachEvent("on" + evname, func);
	} 
	else if (el.removeEventListener) // Gecko / W3C
	{
		el.removeEventListener(evname, func, true);
	}
}

ComboBox.getElement = function(ev) 
{
	if (ComboBox.isIE) 
	{
		return window.event.srcElement;
	}
	else
	{
		return ev.currentTarget;
	}
}

ComboBox.getTargetElement = function(ev) 
{
	if (ComboBox.isIE)
	{
		return window.event.srcElement;
	}
	else
	{
		return ev.target;
	}
};

ComboBox.getAbsolutePos = function(el)
{
	var r = { x: el.offsetLeft, y: el.offsetTop };
	if (el.offsetParent) {
		var tmp = ComboBox.getAbsolutePos(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
}

ComboBox.isCharacterKey = function (keyCode)
{
	if(keyCode >= 65 && keyCode <=90) // A to Z
	{
		return true;
	}
	
	if(keyCode >= 48 && keyCode <= 57) // 0 to 9
	{
		return true;
	}	
	
	if(keyCode >= 96 && keyCode <= 107) // Numpad 0-9, *, +
	{
		return true;
	}
	
	if(keyCode >= 109 && keyCode <= 111) // Numpad -./
	{
		return true;
	}
	
	if(keyCode >= 186 && keyCode <= 192) // ;=,-./`
	{
		return true;
	}
	
	if(keyCode >= 219 && keyCode <= 222) // [\]'
	{
		return true;
	}
	
	return false;
}

ComboBox.isIE = (document.attachEvent ? true : false);

ComboBox.isNN = (document.addEventListener ? true : false);

function returnFalse()
{
	return false
}


function buildCombo(id,list)
{
	ComboBoxHandler.all[id].options = list;
	ComboBoxHandler.all[id].reMake();
}

function updateCombo(source, target)
{
	id = document.getElementById(source);
	combo = remote.updateCombo(id.value,target);
	buildCombo(target, combo.list);
}


