<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %> 










Hello World


ASP.NET 2.0 Black Book





stylesheet.cs:=
html, body {
background-color: #FFFFFF;
color: #000000;
font: normal 90%/1.8em 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif;
margin: 0;
height: 100%;
}
h1 {
font-size: 1.8em;
font-weight: bold;
margin-top: 0em;
margin-bottom: 0em;
color: #a83930;
}
h2 {
font-size: 1.6em;
margin: 1.0em 0em 1.0em 0em;
font-weight: bold;
color: #a83930;
}
h3 {
font-size: 1.2em;
margin: 1.0em 0em 1.0em 0em;
font-weight: bold;
color: #a83930;
}
p {
font-size: 1.1em;
line-height: 1.8em;
margin: 1.1em 0em 1.1em 0em;
text-align: left;
}
ul
{
font-size: 1.1em;
}
a:link, a:visited {
color: #cc3300;
text-decoration: underline;
}
a:hover {
text-decoration: none;
}
a:active {
color: #ff9900;
text-decoration: underline;
}
title {
color: #a83930;
}
#header {
height: 8px;
padding: 0 0px 0 0px;
color: #a83930;
background-color: #000000;
border-bottom: 8px solid #d30a1a;
}
#header h1 {
padding: 10px 0 0 0;
margin: 10px 0 0 0px;
color: #FFFFFF;
margin-left: 10px;
margin-bottom: 10px;
}
#logo {
background-color: #000000;
background: url(images/logo.gif);
background-position: top left;
background-repeat: no-repeat;
height: 100px;
width: 100px;
border: 0;
float: left;
}
#content {
margin-left: 210px;
padding: 0 20px 1.8em 10px;
background-color: #fff;
}
.code {
color: #a83930;
background-color: #fdea12;
font: 0.9em/1.4em verdana, arial, helvetica, sans-serif;
float: right;
border: solid 1px #a83930;
padding: 10px;
}

#sidebar {
float:left;
padding: 0 10px 10px 10px;
background-color: #656565;
/*background-image: url(images/bg_2.gif);*/
background-repeat: repeat-y;
background-position: top left;
border-top: 2px solid #656565;
border-bottom: 2px solid #656565;
width: 168px; /* ds */
height:500px;
}
html>body #sidebar {
width: 180px;
}
#sidebar h3 {
font-weight: bold;
padding-bottom: 0.5em;
border-bottom: 1px dashed #fdea12;
color: #fdea12;
}

#nav a:link, #nav a:visited {
/*display: block;*/
width: 99.99%; /* for IE5 */
color: #FFFFFF;
text-decoration: none;
padding: 0.25em 0.5em 0.25em 0.5em;
font-weight: bold;
}
#nav a:hover {
text-decoration: none;
color: #FFFFFF;
/*background-color: #fdea12; */
}

.title {
color: #a83930;
font: bold 1.0em/1.0em verdana, arial, helvetica, sans-serif;
text-align: center;
padding-bottom: 5px;
border-bottom: #a83930 thin solid;
margin-bottom: 5px;
}
#footer {
/*margin-left: 210px; */
padding: 0 20px 1.8em 10px;
border-top: 1px solid #000000;
clear: both;
}
#footer p {
font: normal 0.8em/0.9em verdana, arial, helvetica, sans-serif;
color: #666;
}
#footer p.left {
float: left;
clear: left;
}
#footer p.right {
float: right;
clear: right;
}
.spacer {
clear: both;
}
dd, dt {
font-size: 0.95em;
}
#mainTitle {
font-size: 2.0em;
font-weight: bold;
visibility: hidden;
}
.pageTitle {
font-size: 1.5em;
font-weight: bold;
}
.itemTitle {
border-bottom: 1px solid #a83930;
font-size: 1.5em;
}
.itemContent {
padding-bottom: 1.8em;
}
.box {
border: solid 1px #a83930;
}
.boxFloat {
/* border: solid 1px #a83930; */
float: left;
}
.boxFloatRight {
border: solid 1px #a83930;
float: right;
}
.floatRight {
/* border: solid 1px #a83930; */
float: right;
}

.newsItem
{
padding-top: 1.0em;
border-bottom: 1px solid #a83930;
}
.newsTitle
{
font-size: 110%;
/*
float: left;
*/
}
.newsDate {
font: normal 0.9em/0.9em 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif;
float: right;
/* clear: right; */
color: #666666;
}
.newsContent {
text-align: left;
}
.rowSelected {
background-color: #FEF268;
}

input.buttonLink
{
text-decoration: underline;
border: 0px;
background-color: Transparent;
}

.grid {
margin-bottom: 10px;
}
.grid TR TD {
padding: 1px 5px 1px 5px;
}

.details, .details TR, .details TD{
border-style: none;
border-width: 0;
padding-left: 20px;
}
.detailsHeader
{
background-color: #FEF268;
border: solid 1px green;
}


It is not essential to use the standard webforms development model when developing with ASP.NET. Noteworthy frameworks designed for the platform include:

Castle Monorail, an open-source MVC framework with an execution model similar to Ruby on Rails. The framework is commonly used with Castle ActiveRecord, an ORM layer built on NHibernate.
Spring.NET, a port of the Spring framework for Java.

[edit] History
Date Version Remarks New features
January 16, 2002 1.0 First version

released together with Visual Studio .NET
Object oriented web application development supporting Inheritance, Polymorphism and other standard OOP features
Developers are no longer forced to use Server.CreateObject(...), so early-binding and type safety are possible.
Based on Windows programming; the developer can make use of DLL class libraries and other features of the web server to build more robust applications that do more than simply rendering HTML ( i.e. exception handling )

April 24, 2003 1.1 released together with Windows Server 2003

released together with Visual Studio .NET 2003
Mobile controls
Automatic input validation

November 7, 2005 2.0 codename Whidbey
released together with Visual Studio 2005 and Visual Web Developer Express
and SQL Server 2005
New data controls (GridView, FormView, DetailsView)
New technique for declarative data access (SqlDataSource, ObjectDataSource, XmlDataSource controls)
Navigation controls
Master pages
Login controls
Themes
Skins
Web parts
Personalization services
Full pre-compilation
New localization technique
Support for 64-bit processors
Provider class model

November 19, 2007 3.5 released together with Visual Studio 2008
New data controls (ListView, DataPager)
Integrated AJAX support
Improved support for nested master pages
Support for LINQ
HIDLibrary.dll
namespace:using HIDLbrary;
namespace:using System.Text;
protected void btnsend_click(object sender, EventArgs e)
{
HIDLibrary.HidDevic[] HidDeviceList;
HidDevice HidDevice ;
HidDeviceList=HidDevices.Enumerate(0x01234,0x00001);
if(HidDeviceList.Length>0)
{
HidDevice=HidDeviceList[1];
byte[] Outdata=new byte[HidDevice.Capabilities.OutputReportByteLength-1];
HidDevice.OpenDevice();
OutData[0]=Convert.ToByte(txtsend.Text);
HidReport hr=new HidReport(1);
hr.Data=OutData;
HidDevice.WriteReport(hr);
HidDevice.Write(OutData);
string Text;
hr=HidDevice.ReadReport();
Text=Convert.ToString(hr.Data.GetValue(0));
txtread.Text=Text;
}
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    Saturday, March 31, 2012
jQuery AutoComplete JS

/*
 * Autocomplete - jQuery plugin 1.1pre
 *
 * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id: jquery.autocomplete.js 5785 2008-07-12 10:37:33Z joern.zaefferer $
 *
 */

;(function($) {

$.fn.extend({
 autocomplete: function(urlOrData, options) {
  var isUrl = typeof urlOrData == "string";
  options = $.extend({}, $.Autocompleter.defaults, {
   url: isUrl ? urlOrData : null,
   data: isUrl ? null : urlOrData,
   delay: isUrl ? $.Autocompleter.defaults.delay : 10,
   max: options && !options.scroll ? 10 : 150
  }, options);

  // if highlight is set to false, replace it with a do-nothing function
  options.highlight = options.highlight || function(value) { return value; };

  // if the formatMatch option is not specified, then use formatItem for backwards compatibility
  options.formatMatch = options.formatMatch || options.formatItem;

  return this.each(function() {
   new $.Autocompleter(this, options);
  });
 },
 result: function(handler) {
  return this.bind("result", handler);
 },
 search: function(handler) {
  return this.trigger("search", [handler]);
 },
 flushCache: function() {
  return this.trigger("flushCache");
 },
 setOptions: function(options){
  return this.trigger("setOptions", [options]);
 },
 unautocomplete: function() {
  return this.trigger("unautocomplete");
 }
});

$.Autocompleter = function(input, options) {

 var KEY = {
  UP: 38,
  DOWN: 40,
  DEL: 46,
  TAB: 9,
  RETURN: 13,
  ESC: 27,
  COMMA: 188,
  PAGEUP: 33,
  PAGEDOWN: 34,
  BACKSPACE: 8
 };

 // Create $ object for input element
 var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);

 var timeout;
 var previousValue = "";
 var cache = $.Autocompleter.Cache(options);
 var hasFocus = 0;
 var lastKeyPressCode;
 var config = {
  mouseDownOnSelect: false
 };
 var select = $.Autocompleter.Select(options, input, selectCurrent, config);

 var blockSubmit;

 // prevent form submit in opera when selecting with return key
 $.browser.opera && $(input.form).bind("submit.autocomplete", function() {
  if (blockSubmit) {
   blockSubmit = false;
   return false;
  }
 });

 // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
 $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
  // track last key pressed
  lastKeyPressCode = event.keyCode;
  switch(event.keyCode) {

   case KEY.UP:
    event.preventDefault();
    if ( select.visible() ) {
     select.prev();
    } else {
     onChange(0, true);
    }
    break;
 
   case KEY.DOWN:
    event.preventDefault();
    if ( select.visible() ) {
     select.next();
    } else {
     onChange(0, true);
    }
    break;
 
   case KEY.PAGEUP:
    event.preventDefault();
    if ( select.visible() ) {
     select.pageUp();
    } else {
     onChange(0, true);
    }
    break;
 
   case KEY.PAGEDOWN:
    event.preventDefault();
    if ( select.visible() ) {
     select.pageDown();
    } else {
     onChange(0, true);
    }
    break;
 
   // matches also semicolon
   case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
   case KEY.TAB:
   case KEY.RETURN:
    if( selectCurrent() ) {
     // stop default to prevent a form submit, Opera needs special handling
     event.preventDefault();
     blockSubmit = true;
     return false;
    }
    break;
 
   case KEY.ESC:
    select.hide();
    break;
 
   default:
    clearTimeout(timeout);
    timeout = setTimeout(onChange, options.delay);
    break;
  }
 }).focus(function(){
  // track whether the field has focus, we shouldn't process any
  // results if the field no longer has focus
  hasFocus++;
 }).blur(function() {
  hasFocus = 0;
  if (!config.mouseDownOnSelect) {
   hideResults();
  }
 }).click(function() {
  // show select when clicking in a focused field
  if ( hasFocus++ > 1 && !select.visible() ) {
   onChange(0, true);
  }
 }).bind("search", function() {
  // TODO why not just specifying both arguments?
  var fn = (arguments.length > 1) ? arguments[1] : null;
  function findValueCallback(q, data) {
   var result;
   if( data && data.length ) {
    for (var i=0; i < data.length; i++) {
     if( data[i].result.toLowerCase() == q.toLowerCase() ) {
      result = data[i];
      break;
     }
    }
   }
   if( typeof fn == "function" ) fn(result);
   else $input.trigger("result", result && [result.data, result.value]);
  }
  $.each(trimWords($input.val()), function(i, value) {
   request(value, findValueCallback, findValueCallback);
  });
 }).bind("flushCache", function() {
  cache.flush();
 }).bind("setOptions", function() {
  $.extend(options, arguments[1]);
  // if we've updated the data, repopulate
  if ( "data" in arguments[1] )
   cache.populate();
 }).bind("unautocomplete", function() {
  select.unbind();
  $input.unbind();
  $(input.form).unbind(".autocomplete");
 });


 function selectCurrent() {
  var selected = select.selected();
  if( !selected )
   return false;

  var v = selected.result;
  previousValue = v;

  if ( options.multiple ) {
   var words = trimWords($input.val());
   if ( words.length > 1 ) {
    v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
   }
   v += options.multipleSeparator;
  }

  $input.val(v);
  hideResultsNow();
  $input.trigger("result", [selected.data, selected.value]);
  return true;
 }

 function onChange(crap, skipPrevCheck) {
  if( lastKeyPressCode == KEY.DEL ) {
   select.hide();
   return;
  }

  var currentValue = $input.val();

  if ( !skipPrevCheck && currentValue == previousValue )
   return;

  previousValue = currentValue;

  currentValue = lastWord(currentValue);
  if ( currentValue.length >= options.minChars) {
   $input.addClass(options.loadingClass);
   if (!options.matchCase)
    currentValue = currentValue.toLowerCase();
   request(currentValue, receiveData, hideResultsNow);
  } else {
   stopLoading();
   select.hide();
  }
 };

 function trimWords(value) {
  if ( !value ) {
   return [""];
  }
  var words = value.split( options.multipleSeparator );
  var result = [];
  $.each(words, function(i, value) {
   if ( $.trim(value) )
    result[i] = $.trim(value);
  });
  return result;
 }

 function lastWord(value) {
  if ( !options.multiple )
   return value;
  var words = trimWords(value);
  return words[words.length - 1];
 }

 // fills in the input box w/the first match (assumed to be the best match)
 // q: the term entered
 // sValue: the first matching result
 function autoFill(q, sValue){
  // autofill in the complete box w/the first match as long as the user hasn't entered in more data
  // if the last user key pressed was backspace, don't autofill
  if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
   // fill in the value (keep the case the user has typed)
   $input.val($input.val() + sValue.substring(lastWord(previousValue).length));
   // select the portion of the value not typed by the user (so the next character will erase)
   $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
  }
 };

 function hideResults() {
  clearTimeout(timeout);
  timeout = setTimeout(hideResultsNow, 200);
 };

 function hideResultsNow() {
  var wasVisible = select.visible();
  select.hide();
  clearTimeout(timeout);
  stopLoading();
  if (options.mustMatch) {
   // call search and run callback
   $input.search(
    function (result){
     // if no value found, clear the input box
     if( !result ) {
      if (options.multiple) {
       var words = trimWords($input.val()).slice(0, -1);
       $input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
      }
      else
       $input.val( "" );
     }
    }
   );
  }
  if (wasVisible)
   // position cursor at end of input field
   $.Autocompleter.Selection(input, input.value.length, input.value.length);
 };

 function receiveData(q, data) {
  if ( data && data.length && hasFocus ) {
   stopLoading();
   select.display(data, q);
   autoFill(q, data[0].value);
   select.show();
  } else {
   hideResultsNow();
  }
 };

 function request(term, success, failure) {
  if (!options.matchCase)
   term = term.toLowerCase();
  var data = cache.load(term);
  // recieve the cached data
  if (data && data.length) {
   success(term, data);
  // if an AJAX url has been supplied, try loading the data now
  } else if( (typeof options.url == "string") && (options.url.length > 0) ){
 
   var extraParams = {
    timestamp: +new Date()
   };
   $.each(options.extraParams, function(key, param) {
    extraParams[key] = typeof param == "function" ? param() : param;
   });
 
   $.ajax({
    // try to leverage ajaxQueue plugin to abort previous requests
    mode: "abort",
    // limit abortion to this input
    port: "autocomplete" + input.name,
    dataType: options.dataType,
    url: options.url,
    data: $.extend({
     q: lastWord(term),
     limit: options.max
    }, extraParams),
    success: function(data) {
     var parsed = options.parse && options.parse(data) || parse(data);
     cache.add(term, parsed);
     success(term, parsed);
    }
   });
  } else {
   // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
   select.emptyList();
   failure(term);
  }
 };

 function parse(data) {
  var parsed = [];
  var rows = data.split("\n");
  for (var i=0; i < rows.length; i++) {
   var row = $.trim(rows[i]);
   if (row) {
    row = row.split("|");
    parsed[parsed.length] = {
     data: row,
     value: row[0],
     result: options.formatResult && options.formatResult(row, row[0]) || row[0]
    };
   }
  }
  return parsed;
 };

 function stopLoading() {
  $input.removeClass(options.loadingClass);
 };

};

$.Autocompleter.defaults = {

 inputClass: "ac_input",
 resultsClass: "ac_results",
 loadingClass: "ac_loading",
 minChars: 1,
 delay: 400,
 matchCase: false,
 matchSubset: true,
 matchContains: false,
 cacheLength: 10,
 max: 100,
 mustMatch: false,
 extraParams: {},
 selectFirst: true,
 formatItem: function(row) { return row[0]; },
 formatMatch: null,
 autoFill: false,
 width: 0,
 multiple: false,
 multipleSeparator: ", ",
 highlight: function(value, term) {
  return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
 },
    scroll: true,
    scrollHeight: 180
};

$.Autocompleter.Cache = function(options) {

 var data = {};
 var length = 0;

 function matchSubset(s, sub) {
  if (!options.matchCase)
   s = s.toLowerCase();
  var i = s.indexOf(sub);
  if (options.matchContains == "word"){
   i = s.toLowerCase().search("\\b" + sub.toLowerCase());
  }
  if (i == -1) return false;
  return i == 0 || options.matchContains;
 };

 function add(q, value) {
  if (length > options.cacheLength){
   flush();
  }
  if (!data[q]){
   length++;
  }
  data[q] = value;
 }

 function populate(){
  if( !options.data ) return false;
  // track the matches
  var stMatchSets = {},
   nullData = 0;

  // no url was specified, we need to adjust the cache length to make sure it fits the local data store
  if( !options.url ) options.cacheLength = 1;

  // track all options for minChars = 0
  stMatchSets[""] = [];

  // loop through the array and create a lookup structure
  for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
   var rawValue = options.data[i];
   // if rawValue is a string, make an array otherwise just reference the array
   rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
 
   var value = options.formatMatch(rawValue, i+1, options.data.length);
   if ( value === false )
    continue;
 
   var firstChar = value.charAt(0).toLowerCase();
   // if no lookup array for this character exists, look it up now
   if( !stMatchSets[firstChar] )
    stMatchSets[firstChar] = [];

   // if the match is a string
   var row = {
    value: value,
    data: rawValue,
    result: options.formatResult && options.formatResult(rawValue) || value
   };
 
   // push the current match into the set list
   stMatchSets[firstChar].push(row);

   // keep track of minChars zero items
   if ( nullData++ < options.max ) {
    stMatchSets[""].push(row);
   }
  };

  // add the data items to the cache
  $.each(stMatchSets, function(i, value) {
   // increase the cache size
   options.cacheLength++;
   // add to the cache
   add(i, value);
  });
 }

 // populate any existing data
 setTimeout(populate, 25);

 function flush(){
  data = {};
  length = 0;
 }

 return {
  flush: flush,
  add: add,
  populate: populate,
  load: function(q) {
   if (!options.cacheLength || !length)
    return null;
   /*
    * if dealing w/local data and matchContains than we must make sure
    * to loop through all the data collections looking for matches
    */
   if( !options.url && options.matchContains ){
    // track all matches
    var csub = [];
    // loop through all the data grids for matches
    for( var k in data ){
     // don't search through the stMatchSets[""] (minChars: 0) cache
     // this prevents duplicates
     if( k.length > 0 ){
      var c = data[k];
      $.each(c, function(i, x) {
       // if we've got a match, add it to the array
       if (matchSubset(x.value, q)) {
        csub.push(x);
       }
      });
     }
    }  
    return csub;
   } else
   // if the exact item exists, use it
   if (data[q]){
    return data[q];
   } else
   if (options.matchSubset) {
    for (var i = q.length - 1; i >= options.minChars; i--) {
     var c = data[q.substr(0, i)];
     if (c) {
      var csub = [];
      $.each(c, function(i, x) {
       if (matchSubset(x.value, q)) {
        csub[csub.length] = x;
       }
      });
      return csub;
     }
    }
   }
   return null;
  }
 };
};

$.Autocompleter.Select = function (options, input, select, config) {
 var CLASSES = {
  ACTIVE: "ac_over"
 };

 var listItems,
  active = -1,
  data,
  term = "",
  needsInit = true,
  element,
  list;

 // Create results
 function init() {
  if (!needsInit)
   return;
  element = $("<div/>")
  .hide()
  .addClass(options.resultsClass)
  .css("position", "absolute")
  .appendTo(document.body);

  list = $("<ul/>").appendTo(element).mouseover( function(event) {
   if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
             active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
       $(target(event)).addClass(CLASSES.ACTIVE);        
         }
  }).click(function(event) {
   $(target(event)).addClass(CLASSES.ACTIVE);
   select();
   // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
   input.focus();
   return false;
  }).mousedown(function() {
   config.mouseDownOnSelect = true;
  }).mouseup(function() {
   config.mouseDownOnSelect = false;
  });

  if( options.width > 0 )
   element.css("width", options.width);
 
  needsInit = false;
 }

 function target(event) {
  var element = event.target;
  while(element && element.tagName != "LI")
   element = element.parentNode;
  // more fun with IE, sometimes event.target is empty, just ignore it then
  if(!element)
   return [];
  return element;
 }

 function moveSelect(step) {
  listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
  movePosition(step);
        var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
        if(options.scroll) {
            var offset = 0;
            listItems.slice(0, active).each(function() {
    offset += this.offsetHeight;
   });
            if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
                list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
            } else if(offset < list.scrollTop()) {
                list.scrollTop(offset);
            }
        }
 };

 function movePosition(step) {
  active += step;
  if (active < 0) {
   active = listItems.size() - 1;
  } else if (active >= listItems.size()) {
   active = 0;
  }
 }

 function limitNumberOfItems(available) {
  return options.max && options.max < available
   ? options.max
   : available;
 }

 function fillList() {
  list.empty();
  var max = limitNumberOfItems(data.length);
  for (var i=0; i < max; i++) {
   if (!data[i])
    continue;
   var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
   if ( formatted === false )
    continue;
   var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
   $.data(li, "ac_data", data[i]);
  }
  listItems = list.find("li");
  if ( options.selectFirst ) {
   listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
   active = 0;
  }
  // apply bgiframe if available
  if ( $.fn.bgiframe )
   list.bgiframe();
 }

 return {
  display: function(d, q) {
   init();
   data = d;
   term = q;
   fillList();
  },
  next: function() {
   moveSelect(1);
  },
  prev: function() {
   moveSelect(-1);
  },
  pageUp: function() {
   if (active != 0 && active - 8 < 0) {
    moveSelect( -active );
   } else {
    moveSelect(-8);
   }
  },
  pageDown: function() {
   if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
    moveSelect( listItems.size() - 1 - active );
   } else {
    moveSelect(8);
   }
  },
  hide: function() {
   element && element.hide();
   listItems && listItems.removeClass(CLASSES.ACTIVE);
   active = -1;
  },
  visible : function() {
   return element && element.is(":visible");
  },
  current: function() {
   return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
  },
  show: function() {
   var offset = $(input).offset();
   element.css({
    width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
    top: offset.top + input.offsetHeight,
    left: offset.left
   }).show();
            if(options.scroll) {
                list.scrollTop(0);
                list.css({
     maxHeight: options.scrollHeight,
     overflow: 'auto'
    });
 
                if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
     var listHeight = 0;
     listItems.each(function() {
      listHeight += this.offsetHeight;
     });
     var scrollbarsVisible = listHeight > options.scrollHeight;
                    list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
     if (!scrollbarsVisible) {
      // IE doesn't recalculate width when scrollbar disappears
      listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
     }
                }
             
            }
  },
  selected: function() {
   var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
   return selected && selected.length && $.data(selected[0], "ac_data");
  },
  emptyList: function (){
   list && list.empty();
  },
  unbind: function() {
   element && element.remove();
  }
 };
};

$.Autocompleter.Selection = function(field, start, end) {
 if( field.createTextRange ){
  var selRange = field.createTextRange();
  selRange.collapse(true);
  selRange.moveStart("character", start);
  selRange.moveEnd("character", end);
  selRange.select();
 } else if( field.setSelectionRange ){
  field.setSelectionRange(start, end);
 } else {
  if( field.selectionStart ){
   field.selectionStart = start;
   field.selectionEnd = end;
  }
 }
 field.focus();
};

})(jQuery);
</body>
</html>