<!--
  TODO:
    * replace _MODULE_ with the name of your module.
    * replace %windir%\system32\oobe\msobshel.htm on your test system with
      this file.
-->
<HTML>
    <HEAD>
        <TITLE>Microsoft Out-of-Box Experience</TITLE>
        <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <LINK REL="stylesheet" TYPE="text/css" HREF="setup\oobestyl.css">

        <!-- Begin Agent Specific Code -->

            <!-- The majority of the Agent code is in AgtCore.js -->
            <!-- The AgtXXXX.js files contain all of the script  -->
            <!-- code that needs to be localized.                -->
            <!-- NOTE: Agent is not initialized until the first  -->
            <!-- time someone clicks on the Assistant image.     -->

            <script language=jscript src="AgtCore.js"></script>
            <script language=jscript src="AgtScrpt.js"></script>

            <!-- Agent Event Handler Declarations -->

            <script language=jscript for=Agent event="Command(userInput)")>
                Agent_OnCommand(userInput);
            </script>

            <script language=jscript for=Agent event="Hide(characterID)">
                Agent_OnHide(characterID);
            </script>

            <script language=jscript for=Agent event="IdleStart(characterID)">
                Agent_OnIdleStart(characterID);
            </script>

            <script language=jscript for=Agent event="IdleComplete(characterID)">
                Agent_OnIdleComplete(characterID);
            </script>

            <script language=jscript for=Agent event="Bookmark(id)">
                Agent_OnBookmark(id);
            </script>

            <script language=jscript for=Agent event="Click(characterID, button, shift, x, y)">
                Agent_OnClick(characterID, button, shift, x, y);
            </script>

            <script language=jscript for=Agent event="DragComplete(characterID, button, shift, x, y)">
                Agent_OnDragComplete(characterID, button, shift, x, y);
            </script>

            <script language=jscript for=Agent event="RequestComplete(request)">
                Agent_OnRequestComplete(request);
            </script>


        <!-- End Agent Specific Code -->

        <script language=jscript src="_MODULE_.js"></script>

        <script language=jscript src="mousetut.js"></script>

        <script language=jscript src="migrate.js"></script>

        <script language=jscript src="dialmgr.js"></script>

        <script language=jscript src="error.js"></script>

        <script language=jscript src="icsmgr.js"></script>

        <script language=jscript>

// This is intended to hold all the script needed
// in the default & offline OOBE HTML pages.
//
// We want to separate the layout (HTML) from the script.
// At the same time, it's helpful to have all the code
// in one place to make it easier to understand the flow
// from page to page.

var APP_OOBE_MODE     = 0;
var APP_MSN_MODE      = 1;
var APP_DESKTOP_MODE  = 2;

// Status location constants
var STATUS_ISP = 0;
var STATUS_OEM = 1;
var STATUS_NONE = 2;
var STATUS_OFF = 3;
var STATUS_MAX = 4;
// var SNDX_WELCOME = 0;
var SNDX_MSN_ISP = 1;
var SNDX_MSN_REG = 2;
var SNDX_MSN_FINISH = 3;
var SNDX_OEM_REG = 1;
var SNDX_OEM_ISP = 2;
var SNDX_OEM_FINISH = 3;
var SNDX_NONE_REG = 1;
var SNDX_NONE_FINISH = 2;
var SNDX_OFF_EULA = 1;
var SNDX_OFF_PID = 2;
var SNDX_OFF_FINISH = 3;

// OLD STATUS PANE FOR B1
// var SNDX_WELCOME  = 0;
// var SNDX_HW1      = 1;
// var SNDX_HW2      = 2;
// var SNDX_HW3      = 3;
// var SNDX_LEGAL1   = 4;
// var SNDX_LEGAL2   = 5;
// var SNDX_REG1     = 6;
// var SNDX_REG2     = 7;
// var SNDX_ISP      = 8;
// var SNDX_FINI     = 9;

// For the new status pane, don't allow half way status
var SNDX_WELCOME    = 0;
var SNDX_HW         = 1;
var SNDX_LEGAL      = 2;
var SNDX_REG        = 3;
var SNDX_ISP        = 4;
var SNDX_FINI       = 6;

// holds non-checkpoint next navigation
var g_SimpleNavMap = null;

function CheckPoint(strURL, i1, i2, i3, i4)
{
  this.strURL = strURL;
  this.rgindex = new Array(STATUS_MAX);
  this.rgindex[STATUS_ISP] = i1;
  this.rgindex[STATUS_OEM] = i2;
  this.rgindex[STATUS_NONE] = i3;
  this.rgindex[STATUS_OFF] = i4;
}

var curCKPT=1;
var CKPT_HWCHK =             curCKPT++;
var CKPT_WELCOME =           curCKPT++;
var CKPT__MODULE_ =          curCKPT++;
var CKPT_MOUSETUT1 =         curCKPT++;
var CKPT_IMETUTORIAL =       curCKPT++;
var CKPT_OEMHW =             curCKPT++;
var CKPT_REGION_KEYBD =      curCKPT++;
var CKPT_REGKB_COMMIT =      curCKPT++;
var CKPT_TIMEZONE =          curCKPT++;
var CKPT_EULA =              curCKPT++;
var CKPT_EULA_DECLINE =      curCKPT++;
var CKPT_PRODUCTKEY =        curCKPT++;
var CKPT_BADPRODUCTKEY =     curCKPT++;
var CKPT_ICSCHOICE =         curCKPT++;
var CKPT_REGISTER1 =         curCKPT++;
var CKPT_REGISTER3 =         curCKPT++;
var CKPT_ISPSIGNUP =         curCKPT++;
var CKPT_MIGLIST =           curCKPT++;
var CKPT_ISPDIAL =           curCKPT++;
var CKPT_REFDIAL =           curCKPT++;
var CKPT_MIGDIAL =           curCKPT++;
var CKPT_REGDIAL =           curCKPT++;
var CKPT_OEMISP =            curCKPT++;
var CKPT_OEMCUST =           curCKPT++;
var CKPT_DONE =              curCKPT++;
var CKPT_MAX =               curCKPT;  // ALWAYS set this to be the biggest value!

var dnCKPT = new Array(CKPT_MAX);

var g_LastMouseTutPage="mouse_k.htm";
var g_Last_MODULE_Page = "";

// Checkpoint breadcrumbs
var g_CurrentCKPT = null;
var g_DialCKPT = null;
var HKEY_LOCAL_MACHINE = 0x80000002;
var OOBE_MAIN_REG_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\OOBE";
var CLSID_FLASH_PLAYER = "{D27CDB6E-AE6D-11cf-96B8-444553540000}";
var PROGID_FLASH_PLAYER = "ShockwaveFlash.ShockwaveFlash";
var CKPT_REG_KEY = "\\CKPT";
var TOS_REG_VALUE = "TopOfStack";

// CheckDialReady errors
var ERR_COMM_NO_ERROR            = 0;
var ERR_COMM_OOBE_COMP_MISSING   = 1;
var ERR_COMM_UNKNOWN             = 2;        // Unknown error, check input parameters
var ERR_COMM_NOMODEM             = 3;        // There is no modem installed
var ERR_COMM_RAS_TCP_NOTINSTALL  = 4;

// Dialing errors. Look at raserror.h for details
var DERR_DIALTONE           = 680;
var DERR_BUSY               = 676;
var DERR_VOICEANSWER        = 677;
var DERR_NOANSWER           = 678;
var DERR_NO_CARRIER         = 679;
var DERR_HARDWARE_FAILURE   = 630;   // modem turned off
var DERR_PORT_ALREADY_OPEN  = 602;   // procomm/hypertrm/RAS has COM port
var DERR_PORT_OR_DEVICE     = 692;   // got this when hypertrm had the device open -- jmazner
var DERR_PPP_TIMEOUT        = 718;
var DERR_REMOTE_DISCONNECT  = 629;   // Connection interrupted

// Types of dialing using ISP files. e.g. Dial to registration, ISP, referral server
var CONNECTED_REFFERAL       = 1
var CONNECTED_ISP_SIGNUP     = 2
var CONNECTED_ISP_MIGRATE    = 3
var CONNECTED_REGISTRATION   = 4

// Finish errors
var FINISH_OK           = 0x00000000;
var FINISH_REBOOT       = 0x00000001;
var FINISH_BAD_PID      = 0x00000002;
var FINISH_BAD_EULA     = 0x00000004;
var FINISH_BAD_STAMP    = 0x00000008;

// Language reboot return codes
var LANGUAGE_REBOOT_NEVER   = 0;
var LANGUAGE_REBOOT_NOW     = 1;
var LANGUAGE_REBOOT_END     = 2;

// on-the-fly button hiding
var HIDE_BACK = 0x0001;
var HIDE_NEXT = 0x0002;
var HIDE_CANCEL = 0x0004;
var HIDE_RESTORE = 0x0008;

// keycode consts
var KeyEsc = 0x1B;
var KeyEnter = 0xD;
var KeyBackSpc = 0x8;
var KeyDelete = 0x2E;
var KeyTab = 0x9;
var KeyDwnArrow = 0x28;
var KeyUpArrow = 0x26;
var KeyLeftArrow = 0x25;
var KeyRightArrow = 0x27;

// Data comparison modes
var CompareModeBinary = 0;
var CompareModeText   = 1;

// BUGBUG temp GUIDs
var NOLAUNCHISPSIGNUP = "{C37D92A5-CA34-11d2-B71C-00C04F794977}";
var MSNCOMPLETED      = "{1C0A22F2-CB6B-11d2-B544-00A0C949DA70}";
var LANGUAGECOMPLETED = "{F744DA40-617C-11D3-8B99-00A0C91E7F3C}";
var MS_REGISTRATION   = "{1C956940-8617-11D3-8B99-00A0C91E7F3C}";
var OEM_REGISTRATION  = "{ECD24360-B210-11D3-8B99-00A0C91E7F3C}";
var ICS_FOR_INTERNET  = "{67252E44-C8B7-4b6c-B6CC-E3D0E1D3BF9B}";
var ICS_FOR_OOBE      = "{7664797B-1A07-4755-AF19-2A73EC92E03B}";

// LANGUAGE SETTINGS

// sort order
var SORT_DEFAULT                = 0x0;     // sorting default
// primary languages
var LANG_JAPANESE               = 0x11;
var LANG_KOREAN                 = 0x12;
var LANG_CHINESE                = 0x04;
// sub languages
var SUBLANG_KOREAN              = 0x01;    // Korean (Extended Wansung)
var SUBLANG_CHINESE_TRADITIONAL = 0x01;    // Taiwan
var SUBLANG_CHINESE_SIMPLIFIED  = 0x02;    // Chinese (PR China)
var SUBLANG_DEFAULT             = 0x01;    // user default


// window.external object caches
var TapiObj = null;
var InfoObj = null;
var EulaObj = null;
var LangObj = null;
var PidObj  = null;
var StatusObj = null;
var DirObj = null;
var ApiObj = null;
var SysClockObj = null;
var RegisterObj = null;
var FileSystemObj = null;
var DebugObj = null;

// Localizeable strings for welcome.htm
var L_StrVowelBeginningPrepender_Text = "an";
var L_StrPrepender_Text = "a";

// general globals and status
var g_strISPFile = "";
var g_bStartup;
var g_LastButtonText = null;
var g_FirstFocusElement = null;
var g = null;
var g_SpecialChars = ".'-` ";
var g_OOBEDir = "file://" + window.external.API.get_SystemDirectory() + "\\oobe\\";
var g_OOBEDirPath = window.external.API.get_SystemDirectory() + "\\oobe\\";
var g_WaterMarkFileNameStr= window.external.API.get_SystemDirectory() + "\\OOBE\\images\\watermrk.gif";
var g_WaterMarkFileSize = 29683;  // size of default watermrk.gif
var g_bRedial = false;
var g_LineProblem = 0;
var g_bFirstServerError = true;
var g_status = STATUS_OFF;
var g_ServerErrorCount = 0;
var g_IMEExists = false;
var g_OEMAddBackURL = "";
var g_DialingAvailableInCountry = true;
var g_ModalDialogUp = false;
var bKeyboardPresent = true;
var bMousePresent = true;
var g_OEMNameStr = window.external.Signup.get_OEMName();
var g_bTapiDone = false;

// Mandatory Initialization Code
if (null == DebugObj){
  DebugObj = new Object;
  DebugObj = window.external.Debug;
}
if (null == FileSystemObj) {
  FileSystemObj = new ActiveXObject("Scripting.FileSystemObject");
}

if (null == ApiObj)
{
    ApiObj = new Object;
    ApiObj = window.external.API;
}
if (null == StatusObj)
{
    StatusObj = new Object;
    StatusObj = window.external.Status;
}
if (null == DirObj)
{
    DirObj = new Object;
    DirObj = window.external.Directions;
}
if (null == InfoObj)
{
    InfoObj = new Object;
    InfoObj = window.external.UserInfo;
}
if (null == TapiObj)
{
    TapiObj = new Object;
    TapiObj = window.external.Tapi;
}
if (null == RegisterObj)
{
    RegisterObj = new Object;
    RegisterObj = window.external.Register;
}
if (null == SysClockObj)
{
    SysClockObj = new Object;
    SysClockObj = window.external.SystemClock;
    SysClockObj.Init();
}

if (null == LangObj)
{
    LangObj = new Object;
    LangObj = window.external.Language;
}

// END Initialization Code

// make standard ClickNext Str
var L_ContStr_Text="To continue, click";
var L_NextStr_Text="Next";
var L_Period_Text=".";
var L_ClickNextLocStr_Text="";  // for localizers to add stuff without affecting L_Period_Text

var L_ClickNextStrTopPercent800_Text="87%";
var L_ClickNextStrTopPercent1024_Text="84%";
var L_ClickNextStrLeftPercent_Text="62%";

var g_ClickNextStr = "<table tabindex=-1 border=0 style=\"position:absolute; top: " + ((window.top.screen.width < 1024) ? L_ClickNextStrTopPercent800_Text : L_ClickNextStrTopPercent1024_Text) + "; left:2%;\"><tr><td width="+L_ClickNextStrLeftPercent_Text+"></td>"
       +"<td class=\"text-primary\" ID=NextText>"+L_ContStr_Text+" <span class=\"emphasis-lesser\">"
       +L_NextStr_Text+"</span>"+L_ClickNextLocStr_Text+L_Period_Text+"</td></tr></table>";

var L_NextStrTopPercent_Text="83%";

function trace(sMsg)
{
  DebugObj.Trace(sMsg + "\n");
}

function logError(funcName, err)
{
  trace(  "Exception in " + funcName + ": " 
        + err.number.toString(16) + ": "
        + err.description
        );
  if (DebugObj.get_MsDebugMode())��
  {
    alert("OOBE Exception\n"
          + "\nFunction:    " + funcName
          + "\nError:       " + err.number.toString(16)
          + "\nDescription: " + err.description
          );
  }
}

//////////////////////////////////////////////////////////////////////////////////////
// IMETut1.htm
//////////////////////////////////////////////////////////////////////////////////////

function imetut_LoadMe()
{
    InitFrameRef();
    g_FirstFocusElement = g.btnNextText;

    if (1 != DirObj.get_DoRegionalKeyboard())
        HideButtons(HIDE_BACK);

    InitButtons();
    g_FirstFocusElement.focus();
}

//////////////////////////////////////////////////////////////////////////////////////
// theatre.htm
//////////////////////////////////////////////////////////////////////////////////////
function Theatre_LoadMe( )
{
  InitFrameRef( );
  g_FirstFocusElement = g.btnNext;

  InitButtons( );
}

function Theatre_OnFSCommand(command, args)
{
  if ("MOVIE_COMPLETE" == command)
  {
    g.btnNext.click( );
  }
}

//////////////////////////////////////////////////////////////////////////////////////
// welcome.htm
//////////////////////////////////////////////////////////////////////////////////////
function Start_OnKeyPress()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

// Treat the enter key like the next button
// since the user hasn't gone through the mouse tutorial yet
    if ((g.event.keyCode == KeyEnter) &&
                (g.btnNext.disabled == false))
    {
        GoNext();
    }
    else
    {
        KeyPressIsValid();
    }
}

function MAKELANGID(p, s)
{
    return (( s << 10) | p);
}

function MAKELCID(lgid, srtid)
{
    return ((srtid << 16) | lgid);
}

function IsKoreanLocale() {
   var language = ApiObj.get_UserDefaultLCID();
   if (language == MAKELCID(MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN), SORT_DEFAULT)) {
      return true;
   }

   return false;
}

function IsFarEastLocale()
{
    // if local is Korean, Simplified Chinese,
    // Traditional Chinese,or Japanese then we return true
    var language = ApiObj.get_UserDefaultLCID();

    if (language == MAKELCID(MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN), SORT_DEFAULT) ||
        language == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL), SORT_DEFAULT) ||
        language == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT) ||
        language == MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT), SORT_DEFAULT))
        return true
    else
        return false;
}
// Function: Start_LoadMe
// Description: This function is called after start.htm is
//      loaded. we then initialize Items on the page.
//      we also populate the edits with any values already
//      found in the registry.
//

var L_Thanks1_Text="thank you";
var L_Welc_Text="Welcome";
var L_Comma_Text=",";

var g_bNeedtoRunWelcomeFadeIn= (DirObj.get_DoWelcomeFadeIn()>0);
var g_bNeedtoRunAnimation=false;     // will be set in InitApplication
var g_RunAnimInitVal = DirObj.get_DoRunAnimation();
var g_bAnimationRunning = false;

function Start_LoadMe()
{
    InitFrameRef();

    var WaterMarkFileHandle=FileSystemObj.GetFile(g_WaterMarkFileNameStr);
    if(WaterMarkFileHandle.size != g_WaterMarkFileSize) {
       g.WelcomeImg.style.display="none";
    }

    g_FirstFocusElement = g.btnNext;
    g.btnNext.disabled = false;

    var strOEMName = g_OEMNameStr;
    var strPrepend = "";

    var FirstName=window.external.UserInfo.get_FirstName();
    var LastName=window.external.UserInfo.get_LastName();

    if((FirstName.length>0) || (LastName.length>0)) {
       var NameStr="";

       if (IsFarEastLocale()) {
           // switch first & last name order
           var tmpstr=FirstName;
           FirstName=LastName;
           LastName=tmpstr;
       }

       // get the right # of spaces b/w words
       if(FirstName!=null) {
           NameStr=FirstName;
       }
       if(LastName!=null && LastName!="") {
          if(NameStr!="") {
            NameStr=NameStr+" "+LastName;
          } else {
            NameStr=LastName;
          }
       }
       g.welcome_namestr.innerText = L_Welc_Text+ " " +NameStr+L_Comma_Text + " " + L_Thanks1_Text + " ";
    }

    // put an "a" or an "an" before the OEM name in welcome page

    if (strOEMName.length != 0)
    {
        var Query = strOEMName.charAt(0);
        if (Query.match(/A|E|I|O|U|a|e|i|o|u/) != null)
            strPrepend = L_StrVowelBeginningPrepender_Text;
        else
            strPrepend = L_StrPrepender_Text;

        g.spanOEMName.innerText = strPrepend + " " + strOEMName;
    }

    g.WelcomePageText.style.display="inline";

    InitButtons();

    if(g_bNeedtoRunWelcomeFadeIn) {
        // this entire 'junkspan' sequence is done so that the necessary DLL's for blendtrans
        //(ddraw.dll/ddrawex.dll/dxtmsft.dll/dxtrans.dll/atl.dll) are preloaded before the
        // real blend is done after the movie

        junkspan.style.filter="blendTrans(duration=10.0)";  // 10.0 is junk placeholder
        junkspan.filters[0].duration=0.1;
        junkspan.filters[0].enabled=true;
        junkspan.filters[0].Apply();
        junkspan.style.backgroundColor="red";
        junkspan.style.display="inline";
        junkspan.filters[0].Play();

        junkspan.style.display="none";
        junkspan.filters[0].enabled=false;
        junkspan.style.filter=null;
    }

    window.external.ShowOOBEWindow();  // we've done all the init preprocessing we can

    // see if we need to run movie
    if((g_RunAnimInitVal>0) && (g_bNeedtoRunAnimation || (g_RunAnimInitVal==99))) {
         g_bAnimationRunning = true;
         MovieFrame.style.display="inline";             // start movie

         ScreenFrame.style.visibility = "visible";
         ScreenFrame.style.display = "inline";
    } else if(g_bNeedtoRunWelcomeFadeIn) {

        // transition still not visible on direct boot, too much disk activity
        // 7 seconds appears to be visible.  may need to fine tune that 4.5 number.
        // want to consider machine speed as well, longer number may be too long
        // for slow machine?  (or you may need longer, since it takes longer to load?)
        // want fast machine to work well

        RunWelcomeFadeIn(3.0);

    } else {
       ScreenFrame.style.visibility = "visible";
       ScreenFrame.style.display = "inline";
       OOBEDocBody.style.cursor = "default";
       g_FirstFocusElement.focus();
       window.setTimeout("Agent_Activate('Welcome');",1000);
    }

    g_bNeedtoRunAnimation=false;
    g_RunAnimInitVal=0;
}

function RunWelcomeFadeIn(duration) {
    // need to turn off so fade transition is visible
    // needed if nav'ing from USB pages

    if(ScreenFrame.style.display!="none") {
      ScreenFrame.style.display="none";
      ScreenFrame.style.visibility = "hidden";
    }

    ScreenFrame.style.filter="blendTrans(duration=10.0)";  // 10.0 is junk placeholder
    ScreenFrame.filters[0].duration=duration;
    ScreenFrame.filters[0].enabled=true;
    ScreenFrame.onfilterchange=DisableScreenTransition;

    ScreenFrame.filters[0].Apply();
    MovieFrame.style.display="none";  // dont know if this works w/transition below
    ScreenFrame.style.visibility = "visible";
    ScreenFrame.style.display = "inline";
    ScreenFrame.filters[0].Play();
}

function PostMovieWelcomeInit() {

    if(g_bNeedtoRunWelcomeFadeIn && (g_CurrentCKPT==CKPT_WELCOME)) {

       g_bAnimationRunning = false;
       RunWelcomeFadeIn(3.0);

    } else {

        MovieFrame.style.display="none";  // dont know if this works w/transition below
        ScreenFrame.style.visibility = "visible";
        ScreenFrame.style.display = "inline";
        g_FirstFocusElement.focus();
        OOBEDocBody.style.cursor = "default";

        // want to make sure screen is drawn before agent pops up
        if(g_CurrentCKPT==CKPT_WELCOME) {
          window.setTimeout("Agent_Activate('Welcome');",1000);
        } else if(g_CurrentCKPT==CKPT_HWCHK) {
            g_bAnimationRunning = false;  // want to prevent OnDeviceArrival from doing anything until now

            // check if USB device was attached during movie, possible nav to welcome
            OnDeviceArrival();
        }
  }

  g_bAnimationRunning = false;
}

function DisableScreenTransition() {
        // called when transition completed

        g_bNeedtoRunWelcomeFadeIn=false;

        ScreenFrame.filters[0].enabled=false;
        ScreenFrame.style.filter=null;
        g_FirstFocusElement.focus(); // bugbug need to add this back to filter too
        OOBEDocBody.style.cursor = "default";
        window.setTimeout("Agent_Activate('Welcome');",700);
}

// Function: Start_CheckEdits
// Description: This function is called everytime an OnClick
//      event fires on the page. This is done so if the user
//      loses focus from one of the edits we can push them
//      in the right direction and hint them along the way
//      Or if all elements are filled then we enabled
//      the next button or if any value is 0 then we
//      disable the next button
//
function Start_CheckEdits()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if ((g.event.srcElement != g.edt_FirstName) &&
        (g.event.srcElement != g.edt_LastName))
    {
        Start_CheckEnableNextButton();
    }
}

// Function: Start_CheckEnableNextButton
// Description: This function is called everytime a keyup
//      event fires on a edit box for first, middle, or last
//      name. We then see if we should enable or disable the
//      next button based on if every field has a value.
//      First || Last
//
function Start_CheckEnableNextButton()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (Start_CheckLengthRequirement() &&
        Start_CheckLengthNotEqualSpaces())
    {
        g.btnNext.disabled = false;
    }
    else
    {
        g.btnNext.disabled = true;
    }
    InitButtons();
}

function Start_CheckLengthRequirement()
{
    if ((g.edt_FirstName.value.length != 0) ||
         (g.edt_LastName.value.length != 0))
        return true;
    else
        return false;
}

function Start_CheckLengthNotEqualSpaces()
{
    if ((g.edt_FirstName.value.length != NumberOfSpaces(g.edt_FirstName.value)) ||
         (g.edt_LastName.value.length != NumberOfSpaces(g.edt_LastName.value)))
        return true;
    else
        return false;
}
// END welcome.htm

// reg1.htm ////

var g_Reg1Yes=true;

function HandleReg1Click() {
    g_Reg1Yes=(g.event.srcElement==g.radioRegNeedPP);
}

function Reg1_LoadMe()
{
    InitFrameRef();

    if (1 == RegisterObj.get_PostToOEM) {
        g.OEMName.innerText=g_OEMNameStr+ " " + L_And_Text + " " ;
        g.OEMName5.innerText=g.OEMName.innerText;
        if(g.OEMName.innerText=="") {
           g.OEMName.innerText="Error: Missing OEM Name in oobeinfo.ini [Branding] section ";
        }
    }

    g.Reg1Title.style.visibility="visible";
    g.Reg1Intro.style.visibility="visible";

    g_FirstFocusElement = g.btnNext;

    if(g_Reg1Yes) {
      g.radioRegNeedPP.checked=true;
    } else {
      g.radioRegLater.checked=true;
    }

    g.radioRegNeedPP.onclick=HandleReg1Click;
    g.radioRegLater.onclick=HandleReg1Click;

    InitButtons();

    if (g_FirstFocusElement != null)
      g_FirstFocusElement.focus();
}

// reg2.htm //////

var g_Reg2EmailName="";
var g_Reg2MachineName="";
var g_Reg2PW="";

function Reg2SaveSettings() {
    // restore fields
    g_Reg2EmailName= g.emailname.value;
    g_Reg2MachineName= g.machinename.value;
    g_Reg2PW=g.passwd.value;
}

function Reg2_LoadMe() {
    InitFrameRef();
    g_FirstFocusElement = g.emailname;

    // restore fields
    g.emailname.value = g_Reg2EmailName;
    g.machinename.value = g_Reg2MachineName;
    g.passwd.value = g_Reg2PW;


    InitButtons();

    if (g_FirstFocusElement != null)
        g_FirstFocusElement.focus();
}


function Reg2_RemindMe()
{
   // BUGBUG:  need to fill in later
    /*
     Following Windows Welcome, Microsoft will send you an e-mail message explaining how to retrieve your password. You can then register Windows from the Start menu.
    */
}

function Default_radioClicked()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    g.btnNext.disabled = false;
    InitButtons();
}

//// reg3.htm  ///////////////////////

var StateAbbrevs = new Array("","AL","AK","AZ","AR","CA","CO","CT","DC","DE","FL","GA","HI","ID","IL","IN","IA","KS","KY","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","PR","RI","SC","SD","TN","TX","UT","VT","VA","WA","WV","WI","WY");
var FullStateNames = new Array("Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Washington, D.C.","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Carolina","North Dakota","Ohio","Oklahoma","Oregon","Pennsylvania","Puerto Rico","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming");
var ProvinceNames = new Array("","Alberta","British Columbia","Manitoba","New Brunswick","Newfoundland","Northwest Territories","Nova Scotia","Nunavut","Ontario","Prince Edward Island","Quebec","Saskatchewan","Yukon");

// need ability to map state name string to index into StateAbbrevs
var g_StateName2IndexMap= new ActiveXObject("Scripting.Dictionary");
g_StateName2IndexMap.CompareMode = CompareModeText;
var g_ProvinceName2IndexMap= new ActiveXObject("Scripting.Dictionary");
g_ProvinceName2IndexMap.CompareMode = CompareModeText;

// windows scripting host -- used to send fake keybd events for keyboard helper on PID page
var WshShell = new ActiveXObject("WScript.Shell");

// init hash table
var ii;
for(ii=1;ii<=FullStateNames.length;ii++) {
    // add both full name and abbrev to hash table
  g_StateName2IndexMap.Add(FullStateNames[ii-1].toUpperCase(),ii);
  g_StateName2IndexMap.Add(StateAbbrevs[ii].toUpperCase(),ii);

  if(ii < ProvinceNames.length) {
     g_ProvinceName2IndexMap.Add(ProvinceNames[ii].toUpperCase(),ii);
  }
}

var L_Postal_Text = "Postal or <u>Z</u>IP code:";
var L_AsteriskPostal_Text = "*Postal or <u>Z</u>IP code:";
var L_Province_Text= "State/<u>P</u>rovince:";
var L_AsteriskProvince_Text= "*State/<u>P</u>rovince:";

var L_Canada_Text="Canada";
var L_UnitedStates_Text="United States of America";

function Reg3UserCountryChanged() {
    // AGENT: notify Agent of the change

    Agent_OnSelectChange(g.selCountry);

    g_Country=g.selCountry.options(g.selCountry.selectedIndex).text;

    if(g_Country == L_UnitedStates_Text) {
        // when changing to US, try to translate any textbox string to state index
        if(g.UserStateTextBox.value!="") {
          var res=g_StateName2IndexMap.Item(g.UserStateTextBox.value.toUpperCase());
          if(res!=null) {
             g.selUSState.selectedIndex=res;
          }
        }
        g.selCAProvince.style.display="none";
        g.UserStateTextBox.style.display="none";

        if(g.selUSState.style.display!="inline") {
          g.selUSState.style.display="inline";
        }
        g.LabelZIP.innerHTML = L_AsteriskPostal_Text;
        g.StateLabel.innerHTML = L_AsteriskProvince_Text;
        g.StateLabel.htmlFor="selUSState";

    } else if(g_Country == L_Canada_Text) {
        // when changing to Canada, try to translate any textbox string to province index
        if(g.UserStateTextBox.value!="") {
          var res=g_ProvinceName2IndexMap.Item(g.UserStateTextBox.value.toUpperCase());
          if(res!=null) {
             g.selCAProvince.selectedIndex=res;
          }
        }
        g.selUSState.style.display="none";
        g.UserStateTextBox.style.display="none";
        g.selCAProvince.style.display="inline";
        g.LabelZIP.innerHTML = L_AsteriskPostal_Text;
        g.StateLabel.innerHTML = L_AsteriskProvince_Text;
        g.StateLabel.htmlFor="selCAProvince";

    } else {
        g.selUSState.style.display="none";
        g.selCAProvince.style.display="none";
        g.UserStateTextBox.style.display="inline";
        g.LabelZIP.innerHTML = L_Postal_Text;
        g.StateLabel.innerHTML = L_Province_Text;
        g.StateLabel.htmlFor="UserStateTextBox";
    }

    g_CountryIdx=g.selCountry.selectedIndex;

    Reg3UserStateChanged();
}

function Reg3UserStateChanged() {

    // AGENT: notify Agent of the change

    // BUGBUG: ok for no notify on change to textbox?
    Agent_OnSelectChange((g.selUSState.style.display != "none") ? g.selUSState : g.selCAProvince);

    if(g.selUSState.style.display!="none")
    {
        g_StateIdx=g.selUSState.selectedIndex;
        g_State=g.selUSState.options(g.selUSState.selectedIndex).text;
    }
    else if (g.selCAProvince.style.display!="none")
    {
         g_StateIdx=g.selCAProvince.selectedIndex;
         g_State=g.selCAProvince.options(g.selCAProvince.selectedIndex).text;
    }
    else
    {
        g_State = g.UserStateTextBox.value;
    }
}

// store field info here:

var g_FirstName=InfoObj.get_FirstName();
var g_MiddleName=InfoObj.get_MiddleInitial();  //    InfoObj.get_MiddleName();  BUGBUG need to add this fn
var g_LastName=InfoObj.get_LastName();
var g_Address1=InfoObj.get_Address1();
var g_Address2=InfoObj.get_Address2();
var g_City=InfoObj.get_City();
var g_ZipCode=InfoObj.get_Zip();
var g_EmailAddr= InfoObj.get_PrimaryEmail();
var g_Country=InfoObj.get_Country();
var g_CountryIdx=-1;
var g_State=InfoObj.get_State();
var g_StateIdx=0;

function Reg3SaveSettings() {
    g_FirstName=g.UserFirstName.value;
    g_MiddleName=g.UserMiddleName.value;
    g_LastName=g.UserLastName.value;
    g_Address1=g.UserAddress.value;
    g_Address2=g.UserAddress2.value;
    g_ZipCode=g.UserZipCode.value;
    g_EmailAddr=g.UserEmailAddress.value;
    g_City=g.UserCity.value;
    g_Country=g.selCountry.options(g.selCountry.selectedIndex).text;

    if(g.UserStateTextBox.style.display!="none")
    {
        g_State=g.UserStateTextBox.value;
    }
    else if (g.selUSState.style.display!="none")
    {
        g_State=g.selUSState.options(g.selUSState.selectedIndex).text;
    }
    else
    {
        g_State=g.selCAProvince.options(g.selCAProvince.selectedIndex).text;
    }

    InfoObj.set_FirstName(g_FirstName);
    InfoObj.set_LastName(g_LastName);
    InfoObj.set_MiddleInitial(g_MiddleName);
    InfoObj.set_Country(g_Country);
    InfoObj.set_State(g_State);
    InfoObj.set_Address1(g_Address1);
    InfoObj.set_Address2(g_Address2);
    InfoObj.set_PrimaryEmail(g_EmailAddr);
    InfoObj.set_Zip(g_ZipCode);
    InfoObj.set_City(g_City);

    TapiObj.set_CountryIndex(g.selCountry.selectedIndex);
}

var L_FullName_Text="*<u>F</u>ull Name:";

function Reg3_LoadMe()
{
    // AGENT: we don't want Agent to process any events
    // that might occur as a result of initializing the
    // controls.

    Agent_IgnoreEvents(true);

    InitFrameRef();

    if (1 == RegisterObj.get_PostToOEM) {
          g.OEMName.innerText=g_OEMNameStr+ " " + L_And_Text + " " ;
          if(g.OEMName.innerText=="") {
             g.OEMName.innerText="Error: Missing OEM Name in oobeinfo.ini [Branding] section ";
          }
    }

    var fTapi = TapiObj.IsTAPIConfigured();  // init TAPI

    var CountryOptStr=TapiObj.get_AllCountryName();

    // we used to do a document.write() to put this into selCountry.  IE 5.5 seems to
    // have redraw probs with long doc.writes, so parse it out and add it once in onload

    var i;
    var oOption;
    var regexp1=/<OPTION>/g;
    var tmpOptsStr = CountryOptStr.replace(regexp1, "");  //delete <OPTION>
    var OptStrArray = tmpOptsStr.split("</OPTION>");

    for(i=0; i < OptStrArray.length; i++) {
       oOption  = g.document.createElement("OPTION");
       oOption.text = OptStrArray[i];
       g.selCountry.add(oOption);
    }

    g.selCountry.onchange=Reg3UserCountryChanged;

    g.Reg3Title.style.visibility="visible";

    g_FirstFocusElement = g.UserFirstName;

    if (IsFarEastLocale())
    {

      /*For JPN, CHT, CHS,
        Last Name
        First Name
        Country/Region
        Province
        City
        Address
        Zip
        E-Mail

        For KOR only,
        Full Name
        Country/Region
        Province
        City
        Address
        Zip
        E-Mail
      */
        g.MainPageCell.style.display="none";  // hide while we change order

        // no middle name for far east langs
        g.MiddleNameRow.style.display="none";

        g.FieldTable.moveRow(2,0);  // move lastname in front of first
        g.FieldTable.moveRow(7,3);  // move country to after firstname
        g.FieldTable.moveRow(7,4);  // move province to after country
        g.FieldTable.moveRow(7,5);  // move city to after province

        g.FE_ZIPLabel.innerHTML=g.LabelRight.innerHTML;
        g.FE_ZIPInput.innerHTML=g.MenuRight.innerHTML;
        g.FE_ZIPRow.style.display="inline";

        g.LabelRight.innerHTML="";
        g.MenuRight.innerHTML="";

        // no reason to limit these lengths for FE, so just make them match others
        g.UserZipCode.size=30;
        g.UserZipCode.maxlength=120;

        g.UserStateTextBox.size=30;
        g.UserStateTextBox.maxlength=120;

        g_FirstFocusElement = g.UserLastName;

        if (IsKoreanLocale()) {
            g.LastNameRow.style.display="none";
            g.LabelFirstName.innerHTML=L_FullName_Text;
            g_FirstFocusElement = g.UserFirstName;
        }

        g.MainPageCell.style.display="inline";
    }

    // limit width of country menu since some text options are very long
    g.selCountry.style.width=g.UserEmailAddress.offsetWidth;

    g.UserFirstName.value=g_FirstName;
    g.UserMiddleName.value=g_MiddleName;
    g.UserLastName.value=g_LastName;
    g.UserAddress.value=g_Address1;
    g.UserAddress2.value=g_Address2;
    g.UserZipCode.value=g_ZipCode;
    g.UserEmailAddress.value=g_EmailAddr;
    g.UserCity.value=g_City;

    // placeholder idx 0 option is needed to fix 101447
    // Due to a possible mshtml bug, the cursor is shifted right when the menu
    // expands to its full width.

    g.selUSState.remove(0);

    for (var i = 0; i < StateAbbrevs.length; i++) {
       var oOption  = g.document.createElement("OPTION");
       oOption.text = StateAbbrevs[i];
       if (StateAbbrevs[i] == g_State)
       {
           g_StateIdx = i;
       }
       g.selUSState.add(oOption);
    }

    for (i = 0; i < ProvinceNames.length; i++) {
       oOption  = g.document.createElement("OPTION");
       oOption.text = ProvinceNames[i];
       if (ProvinceNames[i] == g_State)
       {
           g_StateIdx = i;
       }
       g.selCAProvince.add(oOption);
    }

    // Note:  the way code below is written, g_CountryIdx always >=0 so 2nd branch never
    //        taken.  causes no probs though

    g_CountryIdx = TapiObj.get_CountryIndex();

    if(g_CountryIdx>=0)
    {
        g.selCountry.selectedIndex=g_CountryIdx;
        if(g_Country == L_UnitedStates_Text)
        {
            g.selUSState.selectedIndex=g_StateIdx;
        }
        else if(g_Country == L_Canada_Text)
        {
            g.selCAProvince.selectedIndex=g_StateIdx;
        }
        else
            g.UserStateTextBox.value=g_State;
    }
    else
    {
        // get default value
        g.selCountry.selectedIndex = TapiObj.get_CountryIndex();
    }

    Reg3UserCountryChanged();
    g.MainPageCell.style.visibility="visible";

    if (1 == RegisterObj.get_PostToOEM)
    {
        if (bPostChkBxStateSaved)
        {
            g.sharems.checked = g_PostToMS;
            g.shareoem.checked = g_PostToOEM;

            if(!g_PostToMS && !g_PostToOEM) {
               g.btnNext.onclick = GoCancel;   // convert to Skip if nothing checked
            } else {
               g.btnNext.onclick = GoNext;
            }
        }
        g.OEMName2.innerText=g_OEMNameStr;
        g.OEMName3.innerText=g_OEMNameStr;
        g.RegChkBxGrp.style.display = "inline";
    }
    else
    {
        g.MSPrivatePolicyLink.style.display = "inline";
        g_PostToOEM = false;
    }

    InitButtons();

    g_FirstFocusElement.focus();

    // AGENT: now we want event processing

    Agent_IgnoreEvents(false);
}

function GetCurrentProvince() {
    if(g.selCountry.options(g.selCountry.selectedIndex).text == L_UnitedStates_Text) {
        return g.selUSState.options(g.selUSState.selectedIndex).text;
    } else if(g.selCountry.options(g.selCountry.selectedIndex).text == L_Canada_Text) {
        return g.selCAProvince.options(g.selCAProvince.selectedIndex).text;
    } else return g.UserStateTextBox.value;
}

function GetCurrentCountry() {
    return g.selCountry.options(g.selCountry.selectedIndex).text;
}

var L_EnterValid_Text="Please fill in the required fields.";
var L_Email_Text="Please enter a valid E-mail address or leave the E-mail text box empty.";
var L_And_Text="and";

var g_PostToMS = true;
var g_PostToOEM = true;
var POST_TO_OEM = 1
var POST_TO_MS = 2
var bPostChkBxStateSaved = false;

function RegChkBoxOnClick()
{
    g_PostToMS = g.sharems.checked;
    g_PostToOEM = g.shareoem.checked;
    bPostChkBxStateSaved = true;

    if(!g_PostToMS && !g_PostToOEM) {
       g.btnNext.onclick = GoCancel;    // convert to Skip if nothing checked
    } else {
       g.btnNext.onclick = GoNext;
    }

    InitButtons();
}

function VerifyReg3Fields() {
       g.error_mesg.style.display="none";
       var LastErrorField = null;

       var CurReg3ErrStringArray = new Array();

       // user needs to complete input of address/name
       // this dynamically builds the list of erroneous fields to give to the user

       if(g.UserEmailAddress.value != "") {
           // do some validation on email address
           // Note special regexpr char like '\S' must be double-\'d because they are inside a string
             var re = new RegExp("^\\s*\\S+@\\S+\\.\\S\\S+","");
             if(re.exec(g.UserEmailAddress.value) == null) {
                 LastErrorField = g.UserEmailAddress;
                 g.LabelEmail.style.color = "red";
             } else {
                 g.LabelEmail.style.color = "black";
             }
       }

       var CurCountry=GetCurrentCountry();

       // dont require state or zip except for US/Canada
       if ((CurCountry == L_UnitedStates_Text)||(CurCountry == L_Canada_Text)) {
          if(g.UserZipCode.value == "") {
            LastErrorField = g.UserZipCode;
            g.LabelZIP.style.color = "red";
          } else {
             g.LabelZIP.style.color = "black";
          }

          if(GetCurrentProvince() == "") {
             if(g.selUSState.style.display!="none") {
                LastErrorField = g.selUSState;
             } else {
                LastErrorField = g.selCAProvince;
             }
             g.StateLabel.style.color = "red";

          } else {
             g.StateLabel.style.color = "black";
          }
       }

       if(g.UserCity.value == "") {
          LastErrorField = g.UserCity;
          g.LabelCity.style.color = "red";
       } else {
          g.LabelCity.style.color = "black";
       }

       if(g.UserAddress.value == "") {
          LastErrorField = g.UserAddress;
          g.LabelAddress.style.color = "red";
       } else {
          g.LabelAddress.style.color = "black";
       }


       if((g.UserLastName.value == "") && (g.LastNameRow.style.display!="none")) {
          LastErrorField = g.UserLastName;
          g.LabelLastName.style.color = "red";
       } else {
          g.LabelLastName.style.color = "black";
       }

       if((g.UserFirstName.value == "")&&(g.UserMiddleName.value == "")) {
          g.LabelFirstName.style.color = "red";
          LastErrorField = g.UserFirstName;
       } else {
          g.LabelFirstName.style.color = "black";
       }

       if(LastErrorField==null) {
           return true;
       }

       // handle error

       if(LastErrorField==g.UserEmailAddress) {
          g.error_mesg.innerText = L_Email_Text;
       } else {
          g.error_mesg.innerText = L_EnterValid_Text;
       }

       g.error_mesg.style.color = "red";
       g.error_mesg.style.display="inline";

        try
        {
            g.btnNext.disabled=false;
        }
        catch(e) {}
        try
        {
            g.btnBack.disabled=false;
        }
        catch(e) {}
        try
        {
            g.btnSkip.disabled=false;
        }
        catch(e) {}
        InitButtons();

        LastErrorField.focus();

       return false;
}

//////////////////////////////////////////////////////////////////////////////////////
// tapi.htm
//////////////////////////////////////////////////////////////////////////////////////
function TapiLoadMe()
{
    InitFrameRef();
    ResetDialing();
    g_FirstFocusElement = g.selCountry;

    if (null == TapiObj)
    {
        TapiObj = new Object;
        TapiObj = window.external.Tapi;
    }

    RetrieveTapi();
    Tapi_CountryChange();
    g_FirstFocusElement.focus();
}

function Tapi_AreaCodeChange()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (window.external.Tapi.IsAreaCodeRequired(g.selCountry.selectedIndex) &&
        window.external.CheckPhoneBook("msobe.isp") &&
        g.edtAreaCode.value.length == 0)
            g.btnNext.disabled = true;
    else
            g.btnNext.disabled = false;
    InitButtons();
}
function Tapi_CountryChange()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    TapiObj.set_CountryIndex = g.selCountry.selectedIndex;
    if (window.external.CheckPhoneBook("msobe.isp"))
    {
        g.div_MSNNotAvailable.style.visibility = "hidden";
        g.spn_AdditionalSettings.style.visibility = "visible";
        g_DialingAvailableInCountry = true;
    }
    else
    {
        g.div_MSNNotAvailable.style.visibility = "visible";
        g.spn_AdditionalSettings.style.visibility = "hidden";
        g_DialingAvailableInCountry = false;
    }
    tapi_OutsideLineClicked();
    Tapi_AreaCodeChange();
}
function StoreTapi()
{
    TapiObj.set_CountryIndex = g.selCountry.selectedIndex;
    TapiObj.set_AreaCode = g.edtAreaCode.value;

    if(g.radioTouchToneYes.checked)
        TapiObj.set_PhoneSystem = 1; //touch tone
    else
        TapiObj.set_PhoneSystem = 0; //rotary

    TapiObj.set_DialOut = g.edtOutsideLine.value;
}

function RetrieveTapi()
{
    var fTapi = TapiObj.IsTAPIConfigured;

    g.selCountry.selectedIndex = TapiObj.get_CountryIndex;

    g.edtAreaCode.value    = TapiObj.get_AreaCode;

    if(1 == TapiObj.get_PhoneSystem)
        g.radioTouchToneYes.checked = true; //touch tone
    else
        g.radioTouchToneNo.checked = true; //rotary

    g.edtOutsideLine.value = TapiObj.get_DialOut;

    if(g.edtOutsideLine.value != "")
        g.radioOutSideLineYes.checked = true; //use a  number to dial out
    else
        g.radioOutSideLineNo.checked = true; //don't use a number to dial out
}

function tapi_OutsideLineClicked()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (g.radioOutSideLineYes.checked == true &&
        g.spn_AdditionalSettings.style.visibility == "visible")
    {
        g.spanOutsideLine.style.visibility = "visible";
        g.edtOutsideLine.style.visibility = "visible";
        g.edtOutsideLine.value = TapiObj.get_DialOut;
        if (g.edtOutsideLine.value.length == 0)
            g.edtOutsideLine.value = "9";
    }
    else
    {
        g.spanOutsideLine.style.visibility = "hidden";
        g.edtOutsideLine.style.visibility = "hidden";
        g.spanOutsideLine.style.visibility = "hidden";
        g.edtOutsideLine.value = ""; //nuke out any outside line value
    }
}
// END tapi.htm


// EULAWarn.htm
var L_BadEulaOEM1_TEXT = "You have chosen not to agree to the ";
var L_BadEulaOEM2_TEXT = " terms of the license agreement. If you do not accept the End User License Agreement, you cannot use Windows Whistler.";
var L_BadEulaMSOEM1_TEXT = "You have chosen not to agree to the Microsoft or ";
var L_BadEulaMSOEM2_TEXT = " terms of the license agreement. If you do not accept the End User License Agreements, you cannot use Windows Whistler.";

var BadEulaOEMStr =  L_BadEulaOEM1_TEXT + g_OEMNameStr +  L_BadEulaOEM2_TEXT;
var BadEulaMSOEMStr =  L_BadEulaMSOEM1_TEXT + g_OEMNameStr +  L_BadEulaMSOEM2_TEXT;

function EULAWarn_LoadMe()
{
    InitFrameRef();

    g_FirstFocusElement = g.btnBack;

    if (!g_AcceptMS_EULA && !g_AcceptOEM_EULA)
        g.EULAWarn_INFO1.innerText = BadEulaMSOEMStr;
    else if (!g_AcceptOEM_EULA) // just didn't accept OEM
        g.EULAWarn_INFO1.innerText = BadEulaOEMStr;

    InitButtons();

    g_FirstFocusElement.focus();
}

// END EULAWarn.htm


//////////////////////////////////////////////////////////////////////////////////////
// General Default LoadMe function
//////////////////////////////////////////////////////////////////////////////////////
function _Default_LoadMe(UseSimpleNavArg)
{
    InitFrameRef();

    if (g.btnNext != null)
        g_FirstFocusElement = g.btnNext;
    else if (g.btnSkip != null)
        g_FirstFocusElement = g.btnSkip;
    else if (g.btnBack != null)
        g_FirstFocusElement = g.btnBack;

    InitButtons(UseSimpleNavArg);

    if (g_FirstFocusElement != null)
        g_FirstFocusElement.focus();
    else
        g.document.body.focus();
/*
    // small piddly things I dont want to create a new onload fn for
    switch(g_CurrentCKPT) {
        case CKPT_REGKB_COMMIT:
           break;
    }
*/

}

//////////////////////////////////////////////////////////////////////////////////////
// eula.htm
//////////////////////////////////////////////////////////////////////////////////////

function HandleTextAreaFocus() {
  g.event.srcElement.style.borderStyle="ridge";
}

function HandleTextAreaBlur() {
  g.event.srcElement.style.borderStyle="";
}

function EulaLoadMe()
{
    if (window.external.GetNoWelcomeFinish())
    {
        g.btnNext = g.btnFinish;
        g.btnFinish.style.display = "inline";
        g.ToContinueFinishSpn.style.display = "inline";
    }
    else
    {
        g.ToContinueNextSpn.style.display = "inline";
        g.btnNext.style.display = "inline";
    }

    InitFrameRef();

    if (1 == window.external.GetOEMEula()) // Show both MS and OEM Eula
    {
        g.txtEULA.rows = 5;    // shorten the MS Eula txt to make room
        g.txtEULA2.innerText = ApiObj.LoadFile(window.external.GetOEMEulaText());
        g.OEMEulaSpan.style.display = "inline";
    }
    else
    {
        g.radioAgree2.checked = true;
    }

    g.MSEulaSpan.style.display = "inline";

    g_FirstFocusElement = g.txtEULA;

    var fileEULA = EulaObj.ValidateEULA();

    var L_strBadEULA_Text = "Setup was unable to display the User License Agreement.  Setup will now close.";
    if (0 == fileEULA.length)
    {
        alert(L_strBadEULA_Text);
        window.external.PowerDown(0);
    }

    g.txtEULA.innerText = ApiObj.LoadFile(fileEULA);

    if (0 == g.txtEULA.innerText.length)
    {
        alert(L_strBadEULA_Text);
        window.external.PowerDown(0);
    }

    // disable if both unchecked, in case we ever persist the radio click
    if(!(g.radioAgree.checked || g.radioDisAgree.checked))
       g.btnNext.disabled = true;

    InitButtons();
    g.btnNext.onclick = EulaNextBtnHandler;

    g_FirstFocusElement.focus();

    try
    {
        g.document.body.onkeydown = EulaOnKeyDown;
    }
    catch(e){}

}

function EulaNextBtnHandler() {
  StoreEula();
  GoNext();
}

function EulaOnKeyDown()
{

    if (KeyEsc == g.event.keyCode)
    {
        g.event.returnValue = false;
        g.event.keyCode = 0;
    }

    OnKeyDown();
}

var g_AcceptMS_EULA = false;
var g_AcceptOEM_EULA = false;
function EulaRadioClicked()
{
    // if they click on either button, enable next
    if(g.btnNext.disabled && ((g.radioAgree.checked || g.radioDisAgree.checked) &&
                              (g.radioAgree2.checked || g.radioDisAgree2.checked)))
      {
        g.btnNext.onmouseover = HandleButtonMouseOver;
        g.btnNext.onmouseout = HandleButtonMouseOut;
        g.btnNext.className="buttons";
        g.btnNext.disabled = false;
        g.btnNext.onclick = EulaNextBtnHandler;
        g.btnNext.focus();
      }
    g_AcceptMS_EULA = g.radioAgree.checked;
    g_AcceptOEM_EULA = g.radioAgree2.checked;
}

function StoreEula()
{
    EulaObj.set_EULAAcceptance = (g.radioAgree.checked && g.radioAgree2.checked);
}
// END eula.htm

var g_daylight=SysClockObj.get_AutoDaylight();
var g_CurTimeZoneIdx = SysClockObj.get_TimeZoneIdx();

function HandleTZChkBox()
{
    g_daylight = g.daylight.checked;  // this just persists on nav back

    OnClick();
}

function HandleSelTZChange()
{
   g_CurTimeZoneIdx = g.selTimeZone.selectedIndex;
   g.daylight.disabled = !SysClockObj.get_DaylightEnabled(g_CurTimeZoneIdx);
}


function TimeZone_LoadMe()
{
    InitFrameRef();
    g_FirstFocusElement = g.selTimeZone;
    InitButtons();

    g.daylight.checked = g_daylight;
    g.daylight.onclick = HandleTZChkBox;
    g.selTimeZone.onchange=HandleSelTZChange;
    g.selTimeZone.selectedIndex = 0;  //(HACK to make selected item to be made visible in select menu, there is no official way to do this)
    g.selTimeZone.selectedIndex = g_CurTimeZoneIdx;
    g.daylight.disabled = !SysClockObj.get_DaylightEnabled(g_CurTimeZoneIdx);

    g_FirstFocusElement.focus();
}

//////////////////////////////////////////////////////////////////////////////////////
// keybdcmt.htm
//////////////////////////////////////////////////////////////////////////////////////

var g_RegionSelIdx=LangObj.get_RegionIndex();
var g_LangSelIdx=LangObj.get_LangIndex();
var g_KeyboardSelIdx=LangObj.get_KeyboardLayoutIndex();

function RegKBCmt_LoadMe()
{
    InitFrameRef();
    g_FirstFocusElement = g.btnNext;
    InitButtons();

    g.newkeybdname.innerText=LangObj.get_KeyboardLayoutName(g_KeyboardSelIdx);
    g.newregionname.innerText=LangObj.get_RegionName(g_RegionSelIdx);
    g.newlangname.innerText=LangObj.get_LangName(g_LangSelIdx);

    g_FirstFocusElement.focus();
}
// END keybdcmt.htm


//////////////////////////////////////////////////////////////////////////////////////
// keybd.htm
//////////////////////////////////////////////////////////////////////////////////////

var iMaxKeybdNameLen=1;
var iMaxRegionNameLen=1;
var iMaxLangNameLen=1;

function HandleKeybdPageSelMenuChange() {
  var namestr=g.event.srcElement.id.slice(3);
  eval('g.'+namestr+'Name.value=g.event.srcElement.options(g.event.srcElement.selectedIndex).text;');
  eval('g_'+namestr+'SelIdx='+'g.event.srcElement.selectedIndex;');
}

function SetKeybdFocus() {
  g.selKeyboard.focus();
}

function SetRegionFocus() {
  g.selRegion.focus();
}

function SetLangFocus() {
  g.selLang.focus();
}

// keep separating mechanism in case we need to shorten these strings
var L_LangStr_Text="Select your preferred language.";
var LangStrSmall=L_LangStr_Text;
var L_RegionStr_Text="Select the region closest to where you live.";
var RegionStrSmall=L_RegionStr_Text;
var L_KeybdStr_Text="The keyboard that came with your computer is designed for typing in a particular language and may have special function keys. Select the type of keyboard you have. (For a standard English language keyboard, click United States 101)";
var KeybdStrSmall=L_KeybdStr_Text;
var L_KeybdTitleSmall_Text="Select Your System Settings";



function RegKBLoadMe()
{
    InitFrameRef();

    g_FirstFocusElement = g.selRegion;

    InitButtons();
    RetrieveRegKB();

    g.selKeyboard.onchange = HandleKeybdPageSelMenuChange;
    g.selRegion.onchange   = HandleKeybdPageSelMenuChange;
    g.selLang.onchange     = HandleKeybdPageSelMenuChange;

    // fix 110160

    g.KeyboardName.onfocus  = SetKeybdFocus;
    g.RegionName.onfocus    = SetRegionFocus;
    g.LangName.onfocus      = SetLangFocus;

    // init name boxes
    g.RegionName.value=g.selRegion.options(g.selRegion.selectedIndex).text;
    g_RegionSelIdx=g.selRegion.selectedIndex;
    g.LangName.value=g.selLang.options(g.selLang.selectedIndex).text;
    g_LangSelIdx=g.selLang.selectedIndex;
    g.KeyboardName.value=g.selKeyboard.options(g.selKeyboard.selectedIndex).text;
    g_KeyboardSelIdx=g.selKeyboard.selectedIndex;

    // need to shorten text for small screen to make things fit
    if(window.top.screen.width<1024) {
        g.KeybdStr.innerText=KeybdStrSmall;
        g.RegionStr.innerText=RegionStrSmall;
        g.LangStr.innerText=LangStrSmall;

        for(i=3;i<=5;i++) {
           eval("g.LargeResSpc"+i.toString()+".style.display='none';");
        }
        g.KeyBdTitle.innerText=L_KeybdTitleSmall_Text;
    } else {
        g.KeybdStr.innerText=L_KeybdStr_Text;
        g.RegionStr.innerText=L_RegionStr_Text;
        g.LangStr.innerText=L_LangStr_Text;
    }

    g.LangStr.style.visibility="visible";
    g.KeybdStr.style.visibility="visible";
    g.RegionStr.style.visibility="visible";

    g.selRegion.style.visibility="visible";
    g.selKeyboard.style.visibility="visible";
    g.selLang.style.visibility="visible";

    g.KeyboardName.style.visibility="visible";
    g.RegionName.style.visibility="visible";
    g.LangName.style.visibility="visible";

    g.KeyboardName.style.cursor="default";
    g.RegionName.style.cursor="default";
    g.LangName.style.cursor="default";

    g_FirstFocusElement.focus();
}

// use this to enable "Enter" key as Next Button.
// but I really need to select focus'd button with enter.
// have next button be focused by default?? or is enter better, since
// they might not click on next
function RegKB_KeyPress()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (g.event.keyCode == KeyEnter)
        GoNext();

}

function RetrieveRegKB()
{
    if(LangObj.get_RegionIndex() > 20000) {
        alert("error loading default region index: possible problem in locale.inf");
    }

    if(LangObj.get_KeyboardLayoutIndex() > 20000) {
        alert("error loading default keybd index: possible problem in locale.inf");
    }

    if(LangObj.get_LangIndex() > 20000 ) {
        alert("error loading default lang index: possible problem in locale.inf/content.inf");
    }

    var ilen = LangObj.get_NumOfRegions();
    for (var i = 0; i < ilen; i++)
    {
        var oOption  = g.document.createElement("OPTION");
        oOption.text = LangObj.get_RegionName(i);
        g.selRegion.add(oOption);

        if(oOption.text.length > iMaxRegionNameLen) {
           iMaxRegionNameLen=oOption.text.length;
        }
    }

    ilen = LangObj.get_NumOfLangs();
    for (var i = 0; i < ilen; i++)
    {
        var oOption  = g.document.createElement("OPTION");
        oOption.text = LangObj.get_LangName(i);
        g.selLang.add(oOption);

        if(oOption.text.length > iMaxLangNameLen) {
           iMaxLangNameLen=oOption.text.length;
        }
    }

    ilen = LangObj.get_NumOfKeyboardLayouts();
    for (i = 0; i < ilen; i++)
    {
        var oOption  = g.document.createElement("OPTION");
        oOption.text = LangObj.get_KeyboardLayoutName(i);
        g.selKeyboard.add(oOption);

        if(oOption.text.length > iMaxKeybdNameLen)
           iMaxKeybdNameLen=oOption.text.length;
    }

    // BUGBUG
    g.selRegion.selectedIndex = 0;  //(HACK to make selected item to be made visible in select menu, there is no official way to do this)
    g.selRegion.selectedIndex= g_RegionSelIdx;  // BUGBUG: these hacks dont work anymore

    g.selKeyboard.selectedIndex = 0;  //(HACK to make selected item to be made visible in select menu, there is no official way to do this)
    g.selKeyboard.selectedIndex= g_KeyboardSelIdx;

    g.selLang.selectedIndex = 0;  //(HACK to make selected item to be made visible in select menu, there is no official way to do this)
    g.selLang.selectedIndex= g_LangSelIdx;
}
// END keybd.htm

// fini.htm
var L_RegisterdWithMS_Text      = "You registered your copy of Windows Codename Whistler with Microsoft.";
var L_NotRegisterdWithMS_Text   = "You did not register your copy of Windows Codename Whistler with Microsoft.";
var L_RegisterdWith_Text        = "You registered your computer with ";
var L_NotRegisterdWith_Text     = "You did not register your computer with ";
var L_SignupWith_Text           = "Your computer is configured for Internet access.";
var L_NotSignupWith_Text        = "Your computer is not configured for Internet access.";
var L_NotSignupButChoseIcs_Text = "Selected the shared Internet Connection to access the Internet";
var L_DefaultOEM_Text           = "the OEM";

function FinishPage_LoadMe() {
    InitFrameRef();

    var WaterMarkFileHandle=FileSystemObj.GetFile(g_WaterMarkFileNameStr);
    if(WaterMarkFileHandle.size != g_WaterMarkFileSize) {
       g.ThanksImg.style.display="none";
    }

    if (LANGUAGE_REBOOT_END == LangObj.get_RebootState()) {
       g.finishmsg.style.display="none";
       g.rebootfinishmsg.style.display="inline";
    }

    if (STATUS_NONE != g_status && STATUS_OFF != g_status)
    {
        g.FiniSummaryIntro2.style.display = "inline";
        g.FiniSummaryWrapper.style.display = "inline";

        if (1 != window.external.get_RegStatus()) // OEM didn't Pre-reg the machine
        {
            if (1 == RegisterObj.get_PostToOEM)
            {
                var strOEMName = g_OEMNameStr;

                if (strOEMName == null || (strOEMName != null && strOEMName.length == 0))
                    strOEMName = L_DefaultOEM_Text;
                if (StatusObj.get_Status(OEM_REGISTRATION))
                    g.FiniSummary1.innerText = L_RegisterdWith_Text + strOEMName + L_Period_Text;
                else
                    g.FiniSummary1.innerText = L_NotRegisterdWith_Text + strOEMName + L_Period_Text;
                g.FiniSummaryBreak.style.display = "inline";
            }

            if (StatusObj.get_Status(MS_REGISTRATION))
                g.FiniSummary2.innerText = L_RegisterdWithMS_Text;
            else
                g.FiniSummary2.innerText = L_NotRegisterdWithMS_Text;
        }

        var bHasSignup = 0;
        try
        {
          bHasSignup = ApiObj.get_RegValue(HKEY_LOCAL_MACHINE, OOBE_MAIN_REG_KEY + "\\TEMP", "ISPSignup");
        }
        catch (e) { bHasSignup = 0;}

        if (bHasSignup)
            g.FiniSummary3.innerText = L_SignupWith_Text;
        else if (StatusObj.get_Status(ICS_FOR_INTERNET))
        {
            g.FiniSummary3.innerText = L_NotSignupButChoseIcs_Text;
        }
        else
        {
            g.FiniSummary3.innerText = L_NotSignupWith_Text;
        }
    }

    g.msgspan.style.display="inline";

    if (g.btnNext != null)
        g_FirstFocusElement = g.btnNext;
    else if (g.btnBack != null)
        g_FirstFocusElement = g.btnBack;

    InitButtons();
    g_FirstFocusElement.focus();
}

//////////////////////////////////////////////////////////////////////////////////////
// badpid.htm
//////////////////////////////////////////////////////////////////////////////////////
function badpid_LoadMe()
{
    InitFrameRef();
    g_FirstFocusElement=g.btnBack;

    if (null == PidObj)
    {
        PidObj = new Object;
        PidObj = window.external.ProductID;
    }
    var strPid = PidObj.get_PID();
    for (var i = 0; i < 5; i++)
    {
        g.lblPID[i].innerText = strPid.substr(i * 6, 5);
    }
    if (strPid.length == 0)
        g.PidEntered.style.visibility = "hidden";
    else
        g.PidEntered.style.visibility = "visible";

    InitButtons();

    g_FirstFocusElement.focus();

    g_CameFromBadPkeyPage=true;
}

//////////////////////////////////////////////////////////////////////////////////////
// prodkey.htm
//////////////////////////////////////////////////////////////////////////////////////

var g_CameFromBadPkeyPage=false;

var g_LastFocusedPidBox;
var g_SelectionExistsBeforeKeyPress=null;

function PIDBox_HandleBlur() {
    g_LastFocusedPidBox=g.event.srcElement;
}

function PIDBox_HandleFocus() {
    g_LastFocusedPidBox=g.event.srcElement;
    OnFocus();
}

function PID_LoadMe()
{
    InitFrameRef();
    g_FirstFocusElement = g.edtProductKey[0];
    RetrievePid();

    g_FirstFocusElement.focus();
    var rangefocus = g_FirstFocusElement.createTextRange();
    rangefocus.collapse();
    rangefocus.moveStart("word", 0);
    rangefocus.select();

    g_TabForward = false;
    g_TabBackward = false;

    PID_CheckLength(false);

    if(DebugObj.get_MsDebugMode) {
      g.btnSkip.style.visibility="visible";
    }

    for (i = 0; i <= 4; i++)
    {
      g.edtProductKey[i].onblur=PIDBox_HandleBlur;
      g.edtProductKey[i].onfocus=PIDBox_HandleFocus;
    }

    g_LastFocusedPidBox=g.edtProductKey[0];

    InitButtons();

    if(g_CameFromBadPkeyPage) {
       g.edtProductKey[0].select();
       g_CameFromBadPkeyPage=false;
    }
}

var g_CharCode0_plus1=("0".charCodeAt(0))+1;

function KeyboardHelperClick()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    g.event.returnValue = false;  // if false, cancels default action on button
    g.event.cancelBubble = true;

    if (g.event.srcElement.tagName == "BUTTON") {

       g_LastFocusedPidBox.focus();

       if(g.document.selection.type=="Text") {
         g.document.execCommand("Delete");

         if(g.event.srcElement.name=="{BACKSPACE}")
             return;
       }

       if(g.event.srcElement.name=="{BACKSPACE}") {
          var tr=g_LastFocusedPidBox.createTextRange();
          tr.collapse(false);
          tr.moveStart("character",-1);
          tr.execCommand("Delete");
          return;
       } 

       var i=g_LastFocusedPidBox.id.charCodeAt(3)-g_CharCode0_plus1;

       if((i<4) && (g_LastFocusedPidBox.value.length == 5) && CursorAtEndOfField(i) && (!g_SelectionExistsBeforeKeyPress)) {
           TabForward(i,false);
           // should change to g_LastFocusedPidBox, but isn't working due to some IE5.5 regression (focus handler event srcElement is not new event pidbox but current event one)
       }

       if (g_LastFocusedPidBox.value.length != 5) {

          g_LastFocusedPidBox.value+=g.event.srcElement.name;

          // AGENT: notify Agent of the event, NOTE: code in AgtScrpt.js.

          Agent_OnProductKeyKeyboardHelper(g_LastFocusedPidBox, g.event.srcElement.name);

          if (g_TabBackward) {
            TabBackward(i,false);
          } else if(g_TabForward) {
              TabForward(i,false);
          }

          g_TabForward = false;
          g_TabBackward = false;
       }
    }

}

function PID_CheckLength(KnownIncomplete)
{
    // call this only if box reaches length 5 for speed?

    if(KnownIncomplete) {
        g.btnNext.onclick = null;
        g.btnNext.disabled = true;
        g.btnNext.className="buttons-disabled";
        return;
    }

    var TotLength=g.edtProductKey[0].value.length+g.edtProductKey[1].value.length+
                  g.edtProductKey[2].value.length+g.edtProductKey[3].value.length+
                  g.edtProductKey[4].value.length;

    if (TotLength == 25)
    {
        g.btnNext.disabled = false;
        g.btnNext.className="buttons";
        g.btnNext.onclick = GoNext;
    }
    else
    {
        g.btnNext.onclick = null;
        g.btnNext.disabled = true;
        g.btnNext.className="buttons-disabled";
    }
}

function RetrievePid()
{
    // retrieves the pid if avialable.
    var strPid = PidObj.get_PID();

    // if there is no PID then we set the
    // focus to the first field
    if (strPid.length == 0)
    {
        g.edtProductKey[0].focus();
    }
    // else we populate the fields with the
    // sections of the PID
    else
    {
        var re = new RegExp("(.*)-(.*)-(.*)-(.*)-(.*)","");
        if(re.exec(strPid) == null) {
            throw "Internal error:  RegExp pattmatch failed!";
        }

        g.edtProductKey[0].value = RegExp.$1;
        g.edtProductKey[1].value = RegExp.$2;
        g.edtProductKey[2].value = RegExp.$3;
        g.edtProductKey[3].value = RegExp.$4;
        g.edtProductKey[4].value = RegExp.$5;
    }
}

function StorePid()
{
    var strPid = "";

    for (var i = 0; i < 4; i++)
    {
        strPid += g.edtProductKey[i].value;
        strPid += '-';
    }

    strPid += g.edtProductKey[i].value;


    PidObj.set_PID(strPid);
}

var g_TabForward = false;
function TabForward(currentEdit,DoSelectAll)
{
    g_TabForward = false;

    if(currentEdit==4) {
       // deselect any existing selection before moving focus to back button
       if(g.document.selection.type!="None") {
         g.document.selection.empty();
       }
       g.btnBack.focus();
       return;
    }

    currentEdit++;

    g.edtProductKey[currentEdit].focus();

    if(DoSelectAll) {
        g.edtProductKey[currentEdit].select();
        return;
    }

    var tr = g.edtProductKey[currentEdit].createTextRange();
    tr.collapse(true);
    tr.moveStart("word", 0);
    tr.select();

}

var g_TabBackward = false;
function TabBackward(currentEdit,DoSelectAll)
{
    g_TabBackward = false;

    if (currentEdit == 0) {
       // deselect any existing selection before moving focus to button
       if(g.document.selection.type!="None") {
         g.document.selection.empty();
       }
       if(g.btnNext.disabled) {
          g.btnBack.focus();
       } else {
          g.btnNext.focus();
       }

       return;
    }

    currentEdit--;

    g.edtProductKey[currentEdit].focus();

    if(DoSelectAll) {
       g.edtProductKey[currentEdit].select();
       return;
    }

    var tr = g.edtProductKey[currentEdit].createTextRange();
    tr.collapse(false);
    tr.moveStart("word", 1);
    tr.select();
}

function CursorAtStartOfField(currentEdit) {
    var tr = g.edtProductKey[currentEdit].createTextRange();
    var tr2 = g.document.selection.createRange();

    tr2.moveEnd("textedit",1);

    if(tr.isEqual(tr2)){
        return true;
    } else {
        return false;
    }
}

function CursorAtEndOfField(currentEdit) {
    // assumes selection is current edit field

    var tr = g.edtProductKey[currentEdit].createTextRange();
    var tr2 = g.document.selection.createRange();

    tr2.moveStart("textedit",-1);

    if(tr.isEqual(tr2)){
        return true;
    } else {
        return false;
    }
}

function IsProductIDKey(keyCode)
{
    var str = String.fromCharCode(keyCode);

    var result = str.match(/B|C|D|F|G|H|J|K|M|P|Q|R|T|V|W|X|Y|2|3|4|6|7|8|9/);

    return (null != result);
}

var g_keyPressKeyCode = 0;

function ProductIDPropertyChange()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    // enable Next Btn when PID is full, and automatically move to
    // next/previous field when entering/deleting chars

    if ("value" == g.event.propertyName) {

       // find the index at which we are.
       var i=g.event.srcElement.id.charCodeAt(3)-g_CharCode0_plus1;

       // our g_Tab variables can be booleans instead of counts because they can
       // have a max value of 1, becase there will only ever be 1 call to OnPropertyChange if the
       // length of the edit is 0 or 5
       switch(g.edtProductKey[i].value.length) {
         case 5:
           g_TabForward = (i<4);  // dont tab forward if on last PID box
           PID_CheckLength(false);
           break;

         case 4:
         case 0:
         case 1:
           PID_CheckLength(true);  //change from 25char-state could have occurred with any of these lengths
       }

       // see if we want to tab backward
       // if pixbox is empty, and last keypress was not a pidkey (which adds a char),
       // and nothing was selected.

       // BUGBUG: this currently only fully works for the delete key.  when backspace
       // is pressed, g.document.selection.type is always "None" even if there was a selection
       if ((g.edtProductKey[i].value.length == 0) && (i > 0) &&
           (g_keyPressKeyCode==KeyBackSpc)&&(g_keyPressKeyCode==KeyDelete)&&
           (g.document.selection.type=="None")) {

               g_TabBackward = true; // IsProd check is to handle the case where they select everything then press a 2, etc.
       }
    }

    g_keyPressKeyCode = 0;
}

//As of IE 4.0, the onkeypress event fires and can be canceled for the following keys:
//
//Letters: a - z
//Numerals: 0 - 9
//Symbols: ! @ # $ % ^ & * ( ) _ - + = < > [ ] { } , . / ? \ | ' ` " ~
//System: ESCAPE, SPACE, SHIFT

function ProductIDKeyPress()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    // BUGBUG: hack workaround: KeyBackSpc event should arrive at KeyDown handler, but it comes here instead
    //                          I dont know why


    if (g.event.keyCode == KeyBackSpc) {
      ProductIDKeyDown();
      return;
    }

    KeyCodeToUpper();

    g_keyPressKeyCode = g.event.keyCode;

    if (!IsProductIDKey(g_keyPressKeyCode)) {
        g.event.keyCode = 0;
        return;
    } else {

        var i=g.event.srcElement.id.charCodeAt(3)-g_CharCode0_plus1;

        if((i<4) && (g.edtProductKey[i].value.length == 5) && CursorAtEndOfField(i) && (!g_SelectionExistsBeforeKeyPress)) {
           TabForward(i,false);
        }
    }
}

//In IE 5.0, the onkeydown event fires for the following keys:
//
//Editing: DELETE, INSERT,BACKSPACE
//Function: F1 - F12
//Letters: a - z
//Navigation: HOME, END, Left Arrow, Right Arrow, Up Arrow, Down Arrow, PAGE UP, PAGE DOWN
//Numerals: 0 - 9
//Symbols: ! @ # $ % ^ & * ( ) _ - + = < > [ ] { } , . / ? \ | ' ` " ~
//System: ESCAPE, SPACE, SHIFT, TAB, SHIFT+TAB
//
// the following keys and key combinations can be canceled by specifying event.returnValue=false:
//
//Editing: BACKSPACE, DELETE
//Letters: a - z
//Navigation: PAGE UP, PAGE DOWN, END, HOME, Left Arrow, Right Arrow, Up Arrow, Down Arrow
//Numerals: 0 - 9
//Symbols: ! @ # $ % ^ & * ( ) _ - + = < > [ ] { } , . / ? \ | ' ` " ~
//System: SPACE, ESCAPE, TAB, SHIFT+TAB

function ProductIDKeyDown()
{

    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

  var keyCode = g.event.keyCode;

  g_SelectionExistsBeforeKeyPress=(g.document.selection.type!="None");

  if(g.event.srcElement.tagName=="INPUT") {
    var i=g.event.srcElement.id.charCodeAt(3)-g_CharCode0_plus1;
  } else {
    var i=-1;
  }

  switch(keyCode) {

     case KeyTab:
        if(g.event.srcElement == g.edtProductKey[i]) {
               if(g.event.shiftKey)
                 TabBackward(i,true);
               else TabForward(i,true);

               g.event.returnValue = false;
               g.event.keyCode = 0;
               g.event.cancelBubble = true;
               break;
        }
        break;

     case KeyLeftArrow:
         if((i>0) && CursorAtStartOfField(i)) {
             TabBackward(i,false);
             g.event.returnValue = false;
         }
         break;

     case KeyRightArrow:
         if((i<4) && CursorAtEndOfField(i)) {
             TabForward(i,false);
             g.event.returnValue = false;
         }
         break;

    case KeyBackSpc:
    case KeyDelete:

        // if there is already 5 characters in a field, and the user puts the cursor in it, we want to
        // fill in the next box with the character.  we have to do this here because there is no propertychange,
        // and keyup is too late
        //if(g.edtProductKey[i].value.length == 5 && IsProductIDKey(keyCode) && g.document.selection==null)
        //    TabForward(i);
        // cgeorges note: I enabled this feature tried it and didnt like it

        ////////
        // we want the delete/backspace to move the previous edit box if:

        // there is 0 characters, and the user puts the cursor in it, and selection is non-null
        // OR backspc && cursor is at start of field

        if ((i > 0) &&
               (   ((g.document.selection.type=="None") && (g.edtProductKey[i].value.length == 0))
                 ||((keyCode==KeyBackSpc)&& CursorAtStartOfField(i)))) {

                TabBackward(i,false);
                g.event.returnValue = false; // so no deletion occurs when backspace moves to prev pidbox
                g.event.keyCode = 0;
        }

        break;

    case KeyEnter:
        if((g.btnNext.disabled == false)&&(g.event.srcElement!=g.btnBack)) {
            g.btnNext.click();
            g.event.returnValue = false;
            g.event.keyCode = 0;
            g.event.cancelBubble = true;
        }
        break;
 }
}

function ProductIDKeyUp()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if((!g_TabForward) && (!g_TabBackward)) {
        return;
    }

    var i=g.event.srcElement.id.charCodeAt(3)-g_CharCode0_plus1;

    if (g_TabBackward) {
        TabBackward(i,false);
        return;
     } else
      if(g_TabForward) {
        TabForward(i,false);
    }
}

// called on every mouse click into PID page body, to make sure focus never leaves PID fields
function PID_SetCorrectFocus()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if((g.event.srcElement.tagName == "INPUT")||(g.event.srcElement.tagName == "BUTTON")) {
        return;
    }

    // only get here if we clicked on something unexpected

    for (var i = 0; i < 5; i++)
    {
        if (g.event.srcElement == g.edtProductKey[i])
        {
            return;
        }
    }

    // if full key is entered then pass events directly to buttons without doing the stuff below
    if((g.btnNext.disabled == false) && (g.btnNext.contains(g.event.srcElement) ||
                                        g.btnBack.contains(g.event.srcElement) ||
                                        g.btnSkip.contains(g.event.srcElement)))
        return;

    for (var i = 4; i >= 0; i--)
    {
        if (g.edtProductKey[i].value.length < 5 && g.edtProductKey[i].value.length > 0)
        {
            g.edtProductKey[i].focus();
            var range = g.edtProductKey[i].createTextRange();
            range.collapse();
            range.moveStart("word", 1);
            range.select();
            return;
        }
    }

    if (i < 0)
    {
        g.edtProductKey[0].focus();
        var range = g.edtProductKey[0].createTextRange();
        range.collapse();
        range.moveStart("word", 0);
        range.select();
        return;
    }
}
// END pid.htm


//////////////////////////////////////////////////////////////////////////////////////
// hndshake.htm
//////////////////////////////////////////////////////////////////////////////////////
function hndshake_OnKeyPress()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

// Treat the enter key like the next button
// since the user hasn't gone through the mouse tutorial yet.
    if ((g.event.keyCode == KeyEnter) &&
                (g.btnNext.disabled == false))
    {
        GoNext();
    }
    else
    {
        KeyPressIsValid();
    }
}


function hndshake_CheckEdits()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (g.event.srcElement != g.edtMSNPhoneNumber)
    {
        hndshake_CheckEnableNextButton();
    }
}


function hndshake_CheckEnableNextButton()
{
    try
    {
        if (g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (g.edtMSNPhoneNumber.value.length)
    {
        g.btnNext.disabled = false;
    }
    else
    {
        g.btnNext.disabled = true;
    }

    InitButtons();
}


function hndshake_LoadMe()
{
    InitFrameRef();

    g_FirstFocusElement = g.edtMSNPhoneNumber;

    hndshake_CheckEnableNextButton();

    g_FirstFocusElement.focus();
}

//////////////////////////////////////////////////////////////////////////////////////
// MISC Functions
//////////////////////////////////////////////////////////////////////////////////////


// Page Navigation

// InitCKPT, PushCKPT, PopCKPT, CKPTFromVal are meant to handle the behavior for GoBack.
// We only go back to certain pages (i.e., Mouse Tutorial, Sound Check).
// And on some of the pages, we only go back if they haven't been
// completed (i.e., EULA, PID).
//
// So, we push checkpoints if we intend to all coming back to that page.
// We pop checkpoints if we no longer want to come back (e.g., we've
// completed that page.

function InitCKPT()
{

    //                                                                    STATUS_ISP(0) STATUS_OEM    STATUS_NONE   STATUS_OFF
    //                                                                    ------------  ------------- ------------- --------------
    dnCKPT[CKPT_HWCHK] = new CheckPoint("",                               SNDX_WELCOME, SNDX_WELCOME, SNDX_WELCOME, SNDX_WELCOME);
    dnCKPT[CKPT_WELCOME] = new CheckPoint("setup\\welcome.htm",           SNDX_WELCOME, SNDX_WELCOME, SNDX_WELCOME, SNDX_WELCOME);
    dnCKPT[CKPT__MODULE_] = new
    CheckPoint("html\\_MODULE_\\_MODULE_.htm",                 SNDX_WELCOME,
    SNDX_WELCOME,    SNDX_WELCOME,    SNDX_WELCOME);
    dnCKPT[CKPT_MOUSETUT1] = new CheckPoint("html\\mouse\\mouse.htm",     SNDX_HW,      SNDX_HW,      SNDX_HW,      SNDX_HW);
    dnCKPT[CKPT_IMETUTORIAL] = new CheckPoint("html\\IME\\IMETut1.htm",   SNDX_HW,      SNDX_HW,      SNDX_HW,      SNDX_HW);
    dnCKPT[CKPT_OEMHW] = new CheckPoint("html\\oemhw\\oemhw.htm",         SNDX_HW,      SNDX_HW,      SNDX_HW,      SNDX_HW);
    dnCKPT[CKPT_REGION_KEYBD] = new CheckPoint("setup\\keybd.htm",        SNDX_HW,      SNDX_HW,      SNDX_HW,      SNDX_HW);
    dnCKPT[CKPT_REGKB_COMMIT] = new CheckPoint("setup\\keybdcmt.htm",     SNDX_HW,      SNDX_HW,      SNDX_HW,      SNDX_HW);
    dnCKPT[CKPT_TIMEZONE] = new CheckPoint("setup\\timezone.htm",         SNDX_HW,      SNDX_HW,      SNDX_HW,      SNDX_HW);
    dnCKPT[CKPT_EULA] = new CheckPoint("setup\\neweula.htm",              SNDX_LEGAL,   SNDX_LEGAL,   SNDX_LEGAL,   SNDX_LEGAL);
    dnCKPT[CKPT_EULA_DECLINE] = new CheckPoint("setup\\badeula.htm",      SNDX_LEGAL,   SNDX_LEGAL,   SNDX_LEGAL,   SNDX_LEGAL);
    dnCKPT[CKPT_PRODUCTKEY] = new CheckPoint("setup\\prodkey.htm",        SNDX_LEGAL,   SNDX_LEGAL,   SNDX_LEGAL,   SNDX_LEGAL);
    dnCKPT[CKPT_BADPRODUCTKEY] = new CheckPoint("setup\\badpkey.htm",     SNDX_LEGAL,   SNDX_LEGAL,   SNDX_LEGAL,   SNDX_LEGAL);
    dnCKPT[CKPT_ICSCHOICE] = new CheckPoint("setup\\ics.htm",            SNDX_REG,     SNDX_REG,     SNDX_REG,     SNDX_REG);
    dnCKPT[CKPT_REGISTER1] = new CheckPoint("setup\\reg1.htm",            SNDX_REG,     SNDX_REG,     SNDX_REG,     SNDX_REG);
    dnCKPT[CKPT_REGISTER3] = new CheckPoint("setup\\reg3.htm",            SNDX_REG,     SNDX_REG,     SNDX_REG,     SNDX_REG);
    dnCKPT[CKPT_REGDIAL]   = new CheckPoint("setup\\drdyoem.htm",         SNDX_REG,     SNDX_REG,     SNDX_REG,     SNDX_REG);
    dnCKPT[CKPT_ISPSIGNUP] = new CheckPoint("setup\\isp.htm",             SNDX_ISP,     SNDX_ISP,     SNDX_ISP,     SNDX_ISP);
    dnCKPT[CKPT_MIGLIST] = new CheckPoint("setup\\miglist.htm",           SNDX_ISP,     SNDX_ISP,     SNDX_ISP,     SNDX_ISP);
    dnCKPT[CKPT_ISPDIAL]   = new CheckPoint("setup\\drdyisp.htm",         SNDX_ISP,     SNDX_ISP,     SNDX_ISP,     SNDX_ISP);
    dnCKPT[CKPT_REFDIAL]   = new CheckPoint("setup\\drdyref.htm",         SNDX_ISP,     SNDX_ISP,     SNDX_ISP,     SNDX_ISP);
    dnCKPT[CKPT_MIGDIAL]   = new CheckPoint("setup\\drdymig.htm",         SNDX_ISP,     SNDX_ISP,     SNDX_ISP,     SNDX_ISP);
    dnCKPT[CKPT_OEMISP] = new CheckPoint("html\\ispsgnup\\ispsgnup.htm",  SNDX_ISP,     SNDX_ISP,     SNDX_ISP,     SNDX_ISP);
    dnCKPT[CKPT_OEMCUST] = new CheckPoint("html\\oemcust\\oemcust.htm",   SNDX_ISP,     SNDX_ISP,     SNDX_ISP,     SNDX_ISP);
    dnCKPT[CKPT_DONE] = new CheckPoint("setup\\fini.htm",                 SNDX_FINI,    SNDX_FINI,    SNDX_FINI,    SNDX_FINI);

    PopCKPT();

    // init simple navigation mappings

    g_SimpleNavMap= new ActiveXObject("Scripting.Dictionary");
    g_SimpleNavMap.CompareMode = CompareModeText;

    InitSimpleNavMap_MouseTut();
    _MODULE__InitSimpleNavMap();
    g_Last_MODULE_Page = _MODULE_GetLastPage();

}

function PushCKPT(ckpt)
{
  if (ckpt > 0 && ckpt < CKPT_MAX)
  {
    var tos = 0;
    try
    {
      tos = ApiObj.get_RegValue(HKEY_LOCAL_MACHINE, OOBE_MAIN_REG_KEY + CKPT_REG_KEY, TOS_REG_VALUE);
    }
    catch (e) {}
    ApiObj.set_RegValue(HKEY_LOCAL_MACHINE, OOBE_MAIN_REG_KEY + CKPT_REG_KEY, tos.toString(), ckpt);
    ApiObj.set_RegValue(HKEY_LOCAL_MACHINE, OOBE_MAIN_REG_KEY + CKPT_REG_KEY, TOS_REG_VALUE, ++tos);
    g_CurrentCKPT = ckpt;
  }
}

function PopCKPT(ckptCheck)
{
  var ckpt = 0;
  try
  {
    var tos = ApiObj.get_RegValue(HKEY_LOCAL_MACHINE, OOBE_MAIN_REG_KEY + CKPT_REG_KEY, TOS_REG_VALUE);
    if (tos > 0)
    {
      ckpt = ApiObj.get_RegValue(HKEY_LOCAL_MACHINE, OOBE_MAIN_REG_KEY + CKPT_REG_KEY, (tos - 1).toString());

      if (null == ckptCheck || ckpt == ckptCheck)
      {
        ApiObj.set_RegValue(HKEY_LOCAL_MACHINE, OOBE_MAIN_REG_KEY + CKPT_REG_KEY, TOS_REG_VALUE, --tos);
        ApiObj.DeleteRegValue(HKEY_LOCAL_MACHINE, OOBE_MAIN_REG_KEY + CKPT_REG_KEY, tos.toString());
      }
    }
  }
  catch (e) {}

  if (ckpt > 0 && ckpt < CKPT_MAX)
  {
    g_CurrentCKPT = ckpt;
  }
  else
    g_CurrentCKPT = null;
}

function URLFromCKPT(ckpt)
{
  var str = "";
  if (ckpt > 0 && ckpt < CKPT_MAX)
  {
    str = dnCKPT[ckpt].strURL;
  }
  return str;
}

function IndexFromCKPT(ckpt, status)
{
  var index = 0;
  if (ckpt > 0 && ckpt < CKPT_MAX)
  {
    var checkpoint = dnCKPT[ckpt];
    index = checkpoint.rgindex[status];
  }
  return index;
}



function IsLocalFile()
{
    try
    {
        return (-1 != g.location.protocol.indexOf("file"));
    }
    catch (e)
    {
        return false;
    }
}


//////////////////////////////////////////////////////////////////////////////////////
// public navigation APIs
//////////////////////////////////////////////////////////////////////////////////////


function SetBack(strURL)
{
    g_OEMAddBackURL = strURL;
}

// this handles the user's "Skip" requests
function GoCancel(ckpt)
{
    try
    {
        if (IsLocalFile() && g.event == null && (g_CurrentCKPT != g_DialCKPT))
            return;
    }
    catch(e)
    {
        return;
    }

    DisableAllButtons();

    
    switch (g_CurrentCKPT)
    {
     case CKPT_HWCHK:
        GoNavigate(CKPT_WELCOME);
        break;

     case CKPT_REGION_KEYBD:
       // need to avoid handling any existing input info, which GoNext does
        GoNavigate(CKPT_TIMEZONE);
        break;

     case CKPT_MOUSETUT1:
        SimpleNavNext(g_LastMouseTutPage);    // go to ckpt after last mouse tut page
        break;


     case CKPT_PRODUCTKEY:
      // skip button only exists in debug mode.  lets you skip PID page
        PopCKPT(CKPT_PRODUCTKEY);  // make sure we go back to reg1.htm
        if ( StatusObj.get_Status(MS_REGISTRATION) ||
             StatusObj.get_Status(OEM_REGISTRATION) ||
             window.external.get_RegStatus )
            GoNavigate(CKPT_ISPSIGNUP);
        else
            GoNavigate(CKPT_REGISTER1);
        break;

     // We do not allow User to skip for CKPT_ICSCHOICE.

     case CKPT_REGISTER3:
        Reg3SaveSettings();  // save field settings in case we return to page
        GoNavigate(CKPT_ISPSIGNUP);
        break;

     case CKPT_ISPSIGNUP:
        GoNavigate(CKPT_OEMCUST);
        break;

     case CKPT_MIGLIST:
        // When skip on the referral dialing, go to finish
        GoNavigate(CKPT_OEMCUST);
        break;

     case CKPT_REGDIAL:
        GoNavigate(CKPT_ISPSIGNUP);
        break;

     case CKPT_REFDIAL:
     case CKPT_MIGDIAL:
     case CKPT_ISPDIAL:
        // When skip on the referral dialing, go to finish
        GoNavigate(CKPT_OEMCUST);
        break;

    case CKPT__MODULE_:
        SimpleNavNext(g_Last_MODULE_Page);
        break;

    default:
        GoNext();
        break;
    }


}


function GoBack(ckpt)
{
    try
    {
        if (IsLocalFile() && g.event == null && (g_CurrentCKPT != g_DialCKPT))
            return;
    }
    catch(e)
    {
        return;
    }

    DisableAllButtons();

    if(g_CurrentCKPT == g_DialCKPT)
        ResetDialing();
    else if(g_CurrentCKPT == CKPT_ISPSIGNUP)
        ResetDialing();
    else if(g_CurrentCKPT == CKPT_REGISTER3)
        Reg3SaveSettings();  // save field settings in case we return to page
    else if(g_CurrentCKPT == CKPT_PRODUCTKEY)
        StorePid();

    {
        var ckptPrevious = g_CurrentCKPT;
        PopCKPT();

        if (ckptPrevious == g_CurrentCKPT)
        {
            // This handles the case where the current page pushed itself on the stack.
            PopCKPT();
        }

        if ((g_CurrentCKPT == CKPT_ICSCHOICE) && !(window.external.IsIcsAvailable()))
        {
            g_CurrentCKPT = ckptPrevious; // we remove the ICS page from the navigation stream if ICS is no longer available.
            StatusObj.set_Status(ICS_FOR_OOBE, false);
            GoBack();
        }

        else if (g_CurrentCKPT > 0 && g_CurrentCKPT < CKPT_MAX)
        {
            GoNavigate(g_CurrentCKPT);
        }
    }
}

function StatusNavigate()
{
    var iMove = IndexFromCKPT(g_CurrentCKPT, g_status) - window.external.get_StatusIndex;
    while (iMove > 0)
    {
        window.external.MoveNext();
        --iMove;
    }
    while (iMove < 0)
    {
        window.external.MovePrevious();
        ++iMove;
    }
}

////////////////////////////////////////////////////////////////////
// Required API for USB mouse and/or keyboard checks
////////////////////////////////////////////////////////////////////
function OnDeviceArrival(nDeviceType)
{
    if ((CKPT_HWCHK == g_CurrentCKPT) && !g_bAnimationRunning)
    {
        var bKeyboardPresent = window.external.CheckKeyboard();
        var bMousePresent = window.external.CheckMouse();

        if ((0 == bKeyboardPresent) && (0 == bMousePresent))
        {
            g.navigate("setup\\nousbkm.htm");
        }
        else if (0 == bKeyboardPresent)
        {
            g.navigate("setup\\nousbkbd.htm");
        }
        else if (0 == bMousePresent)
        {
            g.navigate("setup\\nousbms.htm");
        }
        else
        {
            // Unregister all device notification so that
            // script will not be notifed of any device arrival
            GoNavigate(CKPT_WELCOME);
        }
    }
}

////////////////////////////////////////////////////////////////////
// DON'T MUCK WITH THE POSITIONING OF THE CASES IN THE SWITCHS BELOW WITHOUT CONSIDERING FALL-THROUGH
////////////////////////////////////////////////////////////////////
function GoNavigate(ckptGoHere)
{
    try
    {
        if (g_bStartup == false)
        {
            if (IsLocalFile())
            {
                if (g.event != null)
                {
                    g.event.returnValue = false;
                    g.event.cancelBubble = true;
                }
            }
        }
        else
            g_bStartup = false;

    }
    catch(e)
    {
        return;
    }

    switch (ckptGoHere)
    {
    case CKPT_HWCHK:
        trace("GoNavigate: CKPT_HWCHK");
        PushCKPT(CKPT_HWCHK);

        var bKeyboardPresent = window.external.CheckKeyboard();
        var bMousePresent = window.external.CheckMouse();

        if ((0 == bKeyboardPresent) || (0 == bMousePresent)) {

            ScreenFrame.style.visibility = "visible";
            ScreenFrame.style.display = "none";

            if ((0 == bKeyboardPresent) && (0 == bMousePresent))
            {
                g.navigate("setup\\nousbkm.htm");
            }
            else if (0 == bKeyboardPresent)
            {
                g.navigate("setup\\nousbkbd.htm");
            }
            else {  // (0 == bMousePresent)
                g.navigate("setup\\nousbms.htm");
            }

            window.external.ShowOOBEWindow();

            if((g_RunAnimInitVal>0) && (g_bNeedtoRunAnimation || (g_RunAnimInitVal==99))) {

                 g_bAnimationRunning = true;
                 MovieFrame.style.display="inline";             // start movie
                 g_bNeedtoRunAnimation=false;
                 g_RunAnimInitVal=1;  // reset from 99, which will trigger second running
            }

            ScreenFrame.style.display = "inline";

            break;
        }

        // fall through...

    case CKPT_WELCOME:
        trace("GoNavigate: CKPT_WELCOME");
        if (!window.external.GetNoWelcomeFinish())
        {
            PushCKPT(CKPT_WELCOME); //BUGBUG do we want to do this?
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_WELCOME));
            break;
        } else {
            window.external.ShowOOBEWindow();  // should be needed for NoWelcome case if USB pages are not displayed
        }

        // fall through...

    case CKPT_MOUSETUT1:
        trace("GoNavigate: CKPT_MOUSETUT1");
        var MT_INIstr=DirObj.get_DoMouseTutorial();
        if ((MT_INIstr.length>0) && (MT_INIstr!="0"))
        {
            PushCKPT(CKPT_MOUSETUT1);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_MOUSETUT1));
            break;
        }

        // fall through...

     case CKPT_IMETUTORIAL:
        trace("GoNavigate: CKPT_IMETUTORIAL");
        if ((1 == DirObj.get_DoIMETutorial()) && g_IMEExists)
        {
            PushCKPT(CKPT_IMETUTORIAL);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_IMETUTORIAL));
            break;
        }

        // fall through...

    case CKPT_OEMHW:
        trace("GoNavigate: CKPT_OEMHW");
        if (1 == DirObj.get_DoOEMHardwareCheck())
        {
            PushCKPT(CKPT_OEMHW);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_OEMHW));
            break;
        }

        // fall through...

    case CKPT_REGION_KEYBD:
        trace("GoNavigate: CKPT_REGION_KEYBD");
        if (1 == DirObj.get_DoRegionalKeyboard())
        {
            PushCKPT(CKPT_REGION_KEYBD);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_REGION_KEYBD));
            break;
        }

        // fall through...

    case CKPT_TIMEZONE:
        trace("GoNavigate: CKPT_TIMEZONE");
        var TimeZonewasSet=SysClockObj.get_TimeZonewasPreset();

        // only show timezone page if preset TimeZoneValue does not exist and TimeZone=1,
        // or if TimeZoneValue is invalid

        if ((!TimeZonewasSet &&
              ((1 == DirObj.get_DoTimeZone()) || (DirObj.get_TimeZoneValue() != ""))))
        {
            PushCKPT(CKPT_TIMEZONE);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_TIMEZONE));
            break;
        }

        // fall through...

     case CKPT_EULA:
        trace("GoNavigate: CKPT_EULA");
        if (null == EulaObj)
        {
            EulaObj = new Object;
            EulaObj = window.external.Eula;
        }

        // skip EULA if user has already accepted in OOBE mode
        if (!EulaObj.get_EULAAcceptance)
        {
            PushCKPT(CKPT_EULA);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_EULA));
            break;
        }

        // fall through...

     case CKPT_PRODUCTKEY:
        trace("GoNavigate: CKPT_PRODUCTKEY");
        if (null == PidObj)
        {
            PidObj = new Object;
            PidObj = window.external.ProductID;
        }

        // skips over PID if it's already validated?
        if (0 == PidObj.get_PID.length || !PidObj.ValidatePID)
        {
            PushCKPT(CKPT_PRODUCTKEY);  //this sets g_CurrentCKPT=CPKT_PRODUCTKEY
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_PRODUCTKEY));
            break;
        }

        // fall through...
    case CKPT_ICSCHOICE:
        {
            trace("GoNavigate: CKPT_ICSCHOICE");

            if ( g_status != STATUS_OFF ) {
                if ( window.external.IsIcsAvailable() )
                {
                    PushCKPT(CKPT_ICSCHOICE);
                    g.navigate(g_OOBEDir + URLFromCKPT(CKPT_ICSCHOICE));
                    break;
                }
                else
                {
                   if ( StatusObj.get_Status(MS_REGISTRATION)  ||
                        StatusObj.get_Status(OEM_REGISTRATION) ||
                        window.external.get_RegStatus() )
                   {
                        GoNavigate(CKPT_ISPSIGNUP);
                        break;
                   }
                   else
                   {
                        GoNavigate(CKPT_REGISTER1);
                        break;
                   }
               }
            }
            // fall through here for OFFLINE status
        }


    case CKPT_REGISTER1:
        trace("GoNavigate: CKPT_REGISTER1");
        if (g_status != STATUS_OFF && 1 != StatusObj.get_Status(MS_REGISTRATION) && 1 != StatusObj.get_Status(OEM_REGISTRATION) && !window.external.get_RegStatus())
        {
            PushCKPT(CKPT_REGISTER1);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_REGISTER1));
            break;
        }

        // fall through...

    case CKPT_ISPSIGNUP:
        trace("GoNavigate: CKPT_ISPSIGNUP");
        if (g_status == STATUS_ISP)
        {
            PushCKPT(CKPT_ISPSIGNUP);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_ISPSIGNUP));
            break;
        }

        // fall through...

    case CKPT_OEMISP:       // PreConfig case
        trace("GoNavigate: CKPT_OEMISP");
        if ((g_status == STATUS_OEM) &&
            !window.external.GetNoIspPreconfig())
        {
            PushCKPT(CKPT_OEMISP);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_OEMISP));
            break;
        }

        // fall through...

    case CKPT_OEMCUST:

        trace("GoNavigate: CKPT_OEMCUST");
        // Next line of code added by TandyT to support special ISP signup process commands
        // Calls to function in agtcore.js

        Agent_TurnOffISPSpecialCommands();

        ResetDialing();
        if (1 == DirObj.get_OEMCust)
        {
            PushCKPT(CKPT_OEMCUST);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_OEMCUST));
            break;
        }
        // fall through...

    case CKPT__MODULE_:
        trace("GoNavigate: CKPT__MODULE_");
        PushCKPT(CKPT__MODULE_);
        g.navigate(g_OOBEDir + URLFromCKPT(CKPT__MODULE_));
        break;

    case CKPT_DONE:
        trace("GoNavigate: CKPT_DONE");
        ResetDialing();
        if (!window.external.GetNoWelcomeFinish())
        {
            PushCKPT(CKPT_DONE);
            g.navigate(g_OOBEDir + URLFromCKPT(CKPT_DONE));
        }
        else
        {
            PushCKPT(CKPT_DONE);
            GoNext();
        }

        break;

    default:
        PushCKPT(ckptGoHere);  // sets g_CurrentCKPT = ckptGoHere;
        g.navigate(g_OOBEDir + URLFromCKPT(ckptGoHere));
        break;
    }

    StatusNavigate();

    // AGENT: notify Agent, code in AgtCore.js

    Agent_OnNavigate();
}


function GoNext()
{
    try
    {
        if (IsLocalFile() && g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    DisableAllButtons();

    switch (g_CurrentCKPT)
    {

    case CKPT_HWCHK:
        GoNavigate(CKPT_HWCHK);
        break;

    case CKPT_WELCOME:
        ScreenFrame.style.filter=null;
        GoNavigate(CKPT__MODULE_);
        break;

    case CKPT__MODULE_:
        GoNavigate(CKPT_MOUSETUT1);
        break;

    case CKPT_MOUSETUT1:
        GoNavigate(CKPT_IMETUTORIAL);
        break;

    case CKPT_IMETUTORIAL:
        GoNavigate(CKPT_OEMHW);
        break;

    case CKPT_OEMHW:
         if (true == StatusObj.get_Status(LANGUAGECOMPLETED))
         {
            GoNavigate(CKPT_TIMEZONE);
         }
         else
            GoNavigate(CKPT_REGION_KEYBD);
         break;


    case CKPT_REGION_KEYBD:
        // setting these to null fixes hanging bug where user clicks on selmenus
        // during execution of SaveSettings

        g.selKeyboard.disabled = true;
        g.selKeyboard.onchange = null;
        g.selRegion.disabled = true;
        g.selRegion.onchange   = null;
        g.selLang.disabled = true;
        g.selLang.onchange     = null;

        g.document.body.style.cursor = "wait";

        LangObj.set_RegionIndex(g.selRegion.selectedIndex)
        LangObj.set_LangIndex(g.selLang.selectedIndex);
        LangObj.set_KeyboardLayoutIndex(g.selKeyboard.selectedIndex);

        // must always call SaveSettings() since apparently there is
        // no way to know current language setting of machine
        LangObj.SaveSettings();

        if (LANGUAGE_REBOOT_NOW == LangObj.get_RebootState())
            GoNavigate(CKPT_REGKB_COMMIT);
        else
            GoNavigate(CKPT_TIMEZONE);

        g.document.body.style.cursor = "default";

        break;

    case CKPT_REGKB_COMMIT:
           // "Next" for this page indicates a restart

           PopCKPT(CKPT_REGKB_COMMIT); // Don't want this in our history anymore after reboot
           PopCKPT(CKPT_REGION_KEYBD);
           PushCKPT(CKPT_TIMEZONE); // so when we come back after reboot we are on the mouse tut page
           StatusObj.set_Status(LANGUAGECOMPLETED, true);
           window.external.PowerDown(1); // reboot
           break;

    case CKPT_TIMEZONE:
        SysClockObj.set_AutoDaylight(g.daylight.checked);
        SysClockObj.set_TimeZoneIdx(g.selTimeZone.selectedIndex);
        GoNavigate(CKPT_EULA);
        break;

    case CKPT_EULA:
        if (EulaObj.get_EULAAcceptance)
        {
            PopCKPT();
            GoNavigate(CKPT_PRODUCTKEY);
        }
        else
            GoNavigate(CKPT_EULA_DECLINE);
        break;

     case CKPT_EULA_DECLINE:
        PopCKPT();
        PushCKPT(CKPT_EULA);  // go back to main eula page, not this one
        window.external.PowerDown(0); // shut down
        break;

    case CKPT_PRODUCTKEY:
        StorePid();

        if (PidObj.get_PID.length != 0 && PidObj.ValidatePID())
        {
            PopCKPT(CKPT_PRODUCTKEY);
            GoNavigate(CKPT_ICSCHOICE);
        }
        else
        {
            GoNavigate(CKPT_BADPRODUCTKEY);
        }
        break;

    case CKPT_BADPRODUCTKEY:
            PopCKPT();  // go back to prodkey page on restart, not this one
            PushCKPT(CKPT_PRODUCTKEY);  // does this leave 2 pid pgs on stack?
            window.external.PowerDown(0); // shut down
        break;
    case CKPT_ICSCHOICE:
        // we update only the USER's preference. this does NOT mean that
        // ICS will ALWAYS be available!!
        if (g.radio_ChooseIcs.checked)
        {
            StatusObj.set_Status(ICS_FOR_OOBE, true);
            window.external.TriggerIcsCallback(true);

        }
        else
        {
            window.external.TriggerIcsCallback(false);
            StatusObj.set_Status(ICS_FOR_OOBE, false);
        }
        // the decision below was previously made at the Product Key page. Not any more.
        if ( StatusObj.get_Status(MS_REGISTRATION)  ||
             StatusObj.get_Status(OEM_REGISTRATION) ||
             window.external.get_RegStatus() )
        {
            GoNavigate(CKPT_ISPSIGNUP);
        }
        else
        {
            GoNavigate(CKPT_REGISTER1);
        }
        break;

    case CKPT_REGISTER1:
           if (g.radioRegNeedPP.checked)
             GoNavigate(CKPT_REGISTER3);
           else {
              // (g.radioRegLater.checked)
              GoNavigate(CKPT_ISPSIGNUP);
           }
        break;

    case CKPT_REGISTER3:
        if(VerifyReg3Fields())
        {
            Reg3SaveSettings();

            if ( window.external.IsIcsAvailable() && StatusObj.get_Status(ICS_FOR_OOBE) )
            {
                IcsConnect(ICS_CONN_TYPE_REG);
            }
            else
            {
                GoNavigate(CKPT_REGDIAL);
            }
        }
        break;
    case CKPT_ISPSIGNUP:
        if (g.radioGetNewISP.checked)
        {
            StatusObj.set_Status(ICS_FOR_INTERNET, false);
            if ((window.external.IsIcsAvailable() && StatusObj.get_Status(ICS_FOR_OOBE)) ||
                (!window.external.IsIcsAvailable() && window.external.CheckOnlineStatus && window.external.CheckStayConnected("msobe.isp")) )
            {
                PushCKPT(CKPT_ISPDIAL);
                if (window.external.IsIcsAvailable() && StatusObj.get_Status(ICS_FOR_OOBE))
                {
                    IcsConnect(ICS_CONN_TYPE_ISP);
                }
                else
                {
                    window.external.Connect(CONNECTED_ISP_SIGNUP, "msobe.isp");
                }
            }
            else
            {
                window.external.Hangup();
                GoNavigate(CKPT_ISPDIAL); // Getting Online
            }
        }
        else if (g.radioMigrateISP.checked)
        {
            StatusObj.set_Status(ICS_FOR_INTERNET, false);
            if (true == StatusObj.get_Status(REFERALDLCOMPLETED))
            {
                GoNavigate(CKPT_MIGLIST);
            }
            else
            {
                if ((window.external.IsIcsAvailable() && StatusObj.get_Status(ICS_FOR_OOBE)) ||
                    (window.external.CheckOnlineStatus && window.external.CheckStayConnected("migrate.isp")) )
                {
                    g_bTapiDone = false;
                    GoNavigate(CKPT_REFDIAL);
                }
                else
                {
                    window.external.Hangup();
                    GoNavigate(CKPT_REFDIAL); // Online
                }
            }
        }
        else if ( g.radioSelectICS.checked ) {
            StatusObj.set_Status(ICS_FOR_INTERNET, true);
            window.external.Hangup(); // this does nothing for LAN (ICS) connections.
            GoNavigate(CKPT_DONE);
        } else {
            StatusObj.set_Status(ICS_FOR_INTERNET, false);
            GoCancel();  // skip checked
        }

        break;

    case CKPT_ISPDIAL:
        GoNavigate(CKPT_OEMCUST);
        break;

    case CKPT_REGDIAL:
        GoNavigate(CKPT_ISPSIGNUP);
        break;

    case CKPT_OEMISP:
        GoNavigate(CKPT_OEMCUST);
        break;

    case CKPT_OEMCUST:
        GoNavigate(CKPT_DONE);
        break;

    case CKPT_DONE:
       var finish = window.external.Finish();

       if (finish == FINISH_OK)    // Finish was successful, so we execute script until our window goes away
        {
            Agent_OnFinish();
            break;
        }
        else
        {
            // allow ourselves to go back to those pages if they gave us bad information
            if (finish & FINISH_BAD_EULA)
            {
                if (null == EulaObj)
                {
                    EulaObj = new Object;
                    EulaObj = window.external.Eula;
                }

                EulaObj.set_EULAAcceptance(false);
            }

            // BUGBUG nuke stack here

            if (finish & FINISH_REBOOT) // language changed but didn't want to reboot earlier, so reboot now
            {
                window.external.PowerDown(1);
                Agent_OnFinish();
            }
            else if (finish & FINISH_BAD_STAMP)  // setupX "stamp" of user.exe failed, we should nav to the earliest page in the flow...
                GoNavigate(CKPT_WELCOME);  // BUGBUG Bad stamp is really an internal error, should notify user?
            else if (finish & FINISH_BAD_EULA)
                GoNavigate(CKPT_EULA);
            else if (finish & FINISH_BAD_PID)
                GoNavigate(CKPT_PRODUCTKEY);

        }

        break;

    default:
        // BUGBUG should we remove the default altogether?
        GoNavigate(Need_to_handle_this_CKPT_in_GoNext);
        break;
    }
}


// BUGBUG temporary until MSN changes code
function GoOffline()
{
    GoNext();
}


function GetCurrentPageName() {

    var re = new RegExp("\\\\([^\\\\]+)$");
    re.exec(g.window.location.pathname);

    return RegExp.$1;
}

// these handle next/back navigation for non-checkpoint pages
function SimpleNavBack()
{
    g.window.history.back();
}

/*
  This version of SimpleNavNext contains the workaround for IE 90257.  not enabled yet
  another part of 90527 fix is in InitButtons()
*/

function SimpleNavNext(CurPage)  // original version that does not fix IE 90257
{
    if(CurPage==null) {
        CurPage=GetCurrentPageName();
    }

    var NextPage=g_SimpleNavMap.Item(CurPage);

    // do specific per-page stuff
    switch(CurPage) {
      case g_LastMouseTutPage:
        GoNext();  // move on to next real checkpnt
        return;
    }

    g.navigate(NextPage);
}

// Description: Disable all the buttons
// Used to prevent script error caused by
// double clicking or rapid clicking
// of two different buttons. E.g. when someone click
// next and back quickly.
//
function DisableAllButtons()
{
    try
    {
       if(g.btnNext!=null)
       {
          g.btnNext.onclick=null;
       }
    } catch (e) {}

    try
    {
       if(g.btnBack!=null)
       {
       g.btnBack.onclick=null;
       }
    } catch (e) {}

    try
    {
       if(g.btnSkip!=null)
       {
          g.btnSkip.onclick=null;
       }
    } catch (e) {}

    try
    {
        g.btnNext.disabled=true;
        g.btnNext.className="buttons-disabled";
    }
    catch(e) {}
    try
    {
        g.btnBack.disabled=true;
        g.btnBack.className="buttons-disabled";
    }
    catch(e) {}
    try
    {
        g.btnSkip.disabled=true;
        g.btnSkip.className="buttons-disabled";
    }
    catch(e) {}
}


function SetBackgroundImg(SetExt)
{
    g.document.body.style.backgroundPosition='top left';

    if (SetExt != null)
    {
        if(window.top.screen.width>800)
            {g.document.body.style.backgroundImage = 'url(../../images/watermrk.gif)';}
        else
            {g.document.body.style.backgroundImage = 'url(../../images/watrmrk2.gif)';}
    }
    else
    {
        if(window.top.screen.width>800)
            {g.document.body.style.backgroundImage = 'url(../images/watermrk.gif)';}
        else
            {g.document.body.style.backgroundImage = 'url(../images/watrmrk2.gif)';}
    }

}



// Function: InitFrameRef
// Description: Sets up globals to point to buttons
//    Since the buttons exist on the child frame,
//    we want to have quick access to them without
//    going through the collections.
//    WARNING: Call this function at the top of XXX_LoadMe()
//
function InitFrameRef(ExternalModule)
{
    // Static control over online pages
    if ( window.external.IsIcsAvailable() && window.parent.StatusObj.get_Status(ICS_FOR_OOBE) )
    {
         // do not modify any IFRAMEs
    }
    else
    {
        try
        {
            document.frames("connDelay").frameElement.style.display="none";
            document.frames("connDelay").frameElement.style.zIndex=-1;
        }
        catch (e)
        {
        }
    }

    g_LastButtonText = null;
    g_FirstFocusElement = null;
    g_LastKeyDown = null;

    g = document.frames("msoobeMain");

    if (ExternalModule != null)
    {
        SetBackgroundImg('Ext');
    }
    else
    {
        SetBackgroundImg();
    }

    try
    {
        if (g != null)
        {
            if(g.btnNext!=null)
                g.btnNext.disabled=false;

            if(g.btnBack!=null)
                g.btnBack.disabled=false;

            if(g.btnSkip!=null)
                g.btnSkip.disabled=false;
        }

        g.document.body.onkeydown = OnKeyDown;
        g.document.body.style.cursor = 'auto';
    }
    catch(e){}

}

function HideButtons(buttons)
{
    if (null != g.btnBack && (buttons & HIDE_BACK))
    {
        g.btnBack.Hide = true;
    }

    if (null != g.btnNext && (buttons & HIDE_NEXT))
    {
        g.btnNext.Hide = true;
    }


    if (null != g.spanCancel && (buttons & HIDE_CANCEL))
    {
        g.btnSkip.Hide = true;
    }
/*
    if (null != g.spanRestore && (buttons & HIDE_RESTORE))
    {
        g.btnRestore.Hide = true;
    }
*/
}


function HandleButtonMouseOver()
{
   if((!this.disabled)&&(this.tagName=="BUTTON"))
      this.className="buttons-hover";
}

function HandleButtonMouseOut()
{
   if((!this.disabled)&&(this.tagName=="BUTTON"))
      this.className="buttons";
}

function InitButtons(SpecialArg)
{
    if(g.btnSkip!=null) {
      g.btnSkip.onmouseover = HandleButtonMouseOver;
      g.btnSkip.onmouseout  = HandleButtonMouseOut;

      if(!g.btnSkip.disabled) {
          g.btnSkip.onclick = GoCancel;

// dont enable onfocus,onblur handlers until issues in 88615 are resolved
//          g.btnSkip.onfocus = HandleButtonMouseOver;
//          g.btnSkip.onblur = HandleButtonMouseOut;

          g.btnSkip.className="buttons";
      } else {
        g.btnSkip.className="buttons-disabled";
      }
    }

    if(g.btnNext != null) {
      g.btnNext.onmouseover = HandleButtonMouseOver;
      g.btnNext.onmouseout  = HandleButtonMouseOut;

      if(g.btnNext.disabled == false) {

          if(SpecialArg==null) {
              g.btnNext.onclick = GoNext;
          } else {
              g.btnNext.onclick = SimpleNavNext;
          }

          g.btnNext.className="buttons";
      } else {
        g.btnNext.className="buttons-disabled";
      }
    }

    if(g.btnBack != null) {
      g.btnBack.onmouseover = HandleButtonMouseOver;
      g.btnBack.onmouseout  = HandleButtonMouseOut;

      if(g.btnBack.disabled == false) {
          if(SpecialArg==null) {
              g.btnBack.onclick = GoBack;
          } else {
              g.btnBack.onclick = SimpleNavBack;
          }

          g.btnBack.className="buttons";
      } else {
        g.btnBack.className="buttons-disabled";
      }
    }
}

var g_LastKeyDown = null;
function OnKeyDown()
{
    try
    {
        if (IsLocalFile() && g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (g.event.altKey)
    {
        g_LastKeyDown = String.fromCharCode(g.event.keyCode);
        if (g_LastKeyDown != null)
            g_LastKeyDown = g_LastKeyDown.toUpperCase();
    }
    else
        g_LastKeyDown = null;


    // AGENT: pass keydown to Agent, NOTE: code in AgtCore.js

    Agent_OnKeyDown(g.event.srcElement);
}

// AGENT: SelectClick is used by Agent

function OnSelectClick() {

    Agent_OnSelectClick(g.event.srcElement);
}

// AGENT: OnClick is used by Agent

function OnClick()
{
    Agent_OnElementClick(g.event.srcElement);
}

// AGENT: Focus functions are used by Agent

function OnFocus() {

    // Put other code here that needs access to the focus event

    Agent_OnFocus(g.event.srcElement);
}

// VALIDATION ROUTINES
function KeyPressIsNumeric()
{
    try
    {
        if (IsLocalFile() && g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (!IsNumeric(g.event.keyCode))
    {
        g.event.keyCode = 0;
        g.event.returnValue = false;
    }
}

function IsNumeric(keyCode)
{
    if ((keyCode >= 48/*0*/)  && (keyCode <= 57/*9*/))
        return true;
    else
        return false;
}

function IsSpecial(keyCode)
{
// BUGBUG DISABLED FOR BETA
/*
    var bFound = false;
    var iPosition = 0;
    for (;iPosition < g_SpecialChars.length; iPosition++)
    {
        if (g_SpecialChars.charCodeAt(iPosition) == keyCode)
        {
            bFound = true;
            break;
        }
    }
    return bFound;
*/
return false;
}

function KeyPressIsValid()
{
    try
    {
        if (IsLocalFile() && g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (!IsAlpha(g.event.keyCode) &&
        !IsSpecial(g.event.keyCode) &&
        !IsNumeric(g.event.keyCode))
    {
        g.event.keyCode = 0;
        g.event.returnValue = false;
    }
}

function KeyPressIsAlpha()
{
    try
    {
        if (IsLocalFile() && g.event == null)
            return;
    }
    catch(e)
    {
        return;
    }

    if (!IsAlpha(g.event.keyCode))
    {
        g.event.keyCode = 0;
        g.event.returnValue = false;
    }
}

function IsAlpha(keyCode)
{
// BUGBUG DISABLED FOR BETA
/*
    var strKeyCode = String.fromCharCode(keyCode);
    var re1 = new RegExp("\w"); // BUGBUG: should \ be escaped?
    var re2 = new RegExp("\D"); // BUGBUG: should \ be escaped?

    strKeyCode.match(re1);
    strKeyCode.match(re2);
    //return ((strKeyCode.match(re1) != null)  && (strKeyCode.match(re2) != null));
*/
//    if ((keyCode >= 97/*a*/ && keyCode <= 122/*z*/) ||
//        (keyCode >= 65/*A*/ && keyCode <= 90 /*Z*/))
        return true;
//    else
//        return false;
}

function NumberOfSpaces(strValue)
{
/*
    var NASexp = RegExp("\s"); // BUGBUG: should \ be escaped?
    var result = strValue.match(NASexp);
    return ((result == null) || (result.length != strValue.length));
*/
    var iSpaceCount = 0;
    for (iPosition = 0; iPosition < strValue.length; iPosition ++)
    {
        if (strValue.charAt(iPosition) == ' ')
        {
            iSpaceCount++;
        }
    }
    return iSpaceCount;
}
function KeyCodeToUpper()
{
    var strKeyCode = String.fromCharCode(g.event.keyCode);
    strKeyCode = strKeyCode.toUpperCase();
    g.event.keyCode = strKeyCode.charCodeAt(0);
}

// END VALIDATION ROUTINES

function FlashPlayerInstalled()
{
  var fReturn = false;
  try
  {
    // Correlate the PROGID and CLSID sections of the registry, then determine
    // whether the inproc server exists.
    //
    // Trailing backslashes on registry paths are required to read default
    // value.
    //
    strProgId = WshShell.RegRead("HKCR\\CLSID\\" 
                                 + CLSID_FLASH_PLAYER 
                                 + "\\VersionIndependentProgID\\");
    if (   PROGID_FLASH_PLAYER == strProgId
        && CLSID_FLASH_PLAYER  == WshShell.RegRead(  "HKCR\\" 
                                                  + strProgId 
                                                  + "\\CLSID\\")
        )
    {
      strInprocServer32 = WshShell.RegRead(  "HKCR\\CLSID\\" 
                                           + CLSID_FLASH_PLAYER 
                                           + "\\InprocServer32\\"
                                           );
      fReturn = FileSystemObj.FileExists(strInprocServer32);
    }

  }
  catch (err)
  {
    // if an exception is thrown, something grave is amiss.  It is safer to
    // assume player is not installed.
    //
    fReturn = false;
  }

  return fReturn;
}

function InitApplication()
{
    OOBEDocBody.style.cursor = "wait";  // show "wait" cursor while initializing

    g_bStartup = true;
    InitFrameRef();

    MSLogoImg.src='images/stbg'+((window.top.screen.width < 1024) ? '800.png' : '1024.png');

    // reset all parameters that change if screen width > 800
    if(window.top.screen.width > 800) {

        StatusBackgndColor.style.width = 230;
        spnStatDividerBar.style.left = StatusBackgndColor.style.width;
        statpaneCell.style.width  = parseInt(StatusBackgndColor.style.width) + parseInt(spnStatDividerBar.style.width);
        spnStatusPane.style.width = statpaneCell.style.width;
        spnStatusPane.style.top   = 170;
        spnMainFrame.style.width  = parseInt(window.top.screen.width) - parseInt(statpaneCell.style.width); // 784 for 1024

        document.frames("ifrmConnDelay").frameElement.style.left=statpaneCell.style.width;

        spnOEMLogo.style.left = 304;
        spnAssist.style.top = 590;
        spnAssist.style.width = StatusBackgndColor.style.width;
    }

    if ( (1 == DirObj.get_Offline() || window.external.CheckDialReady() != ERR_COMM_NO_ERROR) )
    {
        g_status = STATUS_OFF;
        StatusObj.set_Status(NOLAUNCHISPSIGNUP, true);
        window.external.LoadStatusItems("No Modem");
    }
    else
    {

        if ( StatusObj.get_Status(ICS_FOR_OOBE) )
        {
           window.external.TriggerIcsCallback(true);
        }
        else
        {
           window.external.TriggerIcsCallback(false);
        }

        var str = DirObj.get_ISPSignup().toUpperCase();
        if ("MSN" == str)
        {
            g_status = STATUS_ISP;
            if ( window.external.get_RegStatus() )
                window.external.LoadStatusItems("MSN(No Reg)");
            else
                window.external.LoadStatusItems("MSN");
        }
        else if ("OFFLINE" == str)
        {
            g_status = STATUS_ISP;
            if ( window.external.get_RegStatus() )
                window.external.LoadStatusItems("Offline(No Reg)");
            else
                window.external.LoadStatusItems("Offline");
        }
        else if ("PRECONFIG" == str)
        {
            g_status = STATUS_OEM;
            if ( window.external.get_RegStatus() )
                window.external.LoadStatusItems("Preconfig(No Reg)");
            else
                window.external.LoadStatusItems("Preconfig");
        }
        else
        {
            g_status = STATUS_NONE;
            StatusObj.set_Status(NOLAUNCHISPSIGNUP, true);
            if ( window.external.get_RegStatus() )
                window.external.LoadStatusItems("None(No Reg)");
            else
                window.external.LoadStatusItems("None");
        }
    }

    InitCKPT();

    // IME handling

    g_IMEExists = FileSystemObj.FileExists(ApiObj.get_SystemDirectory() + "\\OOBE\\HTML\\IME\\IMETut1.htm");

    Agent_Init();

    spnPage.style.visibility = "visible";

    if (null == g_CurrentCKPT)
    {
       // run only if CKPT regkey didn't exist on start
       g_bNeedtoRunAnimation =
           FlashPlayerInstalled()
        && FileSystemObj.FileExists(g_OOBEDirPath+"images\\intro.swf");
       GoNavigate(CKPT_HWCHK);
    }
    else
    {
       g_bNeedtoRunWelcomeFadeIn = false;

       OOBEDocBody.style.cursor = "default";
       ScreenFrame.style.visibility = "visible";

       if(g_CurrentCKPT>CKPT_WELCOME) {
           //if we're not running init sequence, just show the window now
           //
           ScreenFrame.style.display = "inline";
           window.external.ShowOOBEWindow();  
       }

       GoNavigate(g_CurrentCKPT);
    }
}

function ProcessQueuedEvents() {
  // flush all WM_ events in windows queue.
  // workaround for IE 103880, 'white flashes in statpane & button on page unload'
  window.external.ProcessQueuedEvents();
}

// Update status pane and navigate
function navigatetoPrivacy(PrivPage)
{
    if(g_CurrentCKPT == CKPT_REGISTER3) {
       Reg3SaveSettings();
    }

    if(PrivPage == "MS")
        g.navigate("prvcyMS.htm");
     else g.navigate("OEMpriv.htm");
}

var g_iISPRadioActive=1;
var g_bRadioMigrateISP=false;
//////////////////////////////////////////////////////////////////////////////////////
// isp.htm
//////////////////////////////////////////////////////////////////////////////////////
function IspLoadMe()
{
    InitFrameRef();

    if(g_iISPRadioActive==1) {
       g_FirstFocusElement = g.radioGetNewISP;
    } else if(g_iISPRadioActive==2) {
       g_FirstFocusElement = g.radioMigrateISP;
    } else if(g_iISPRadioActive==3) {
       g_FirstFocusElement = g.radioSelectICS;
    } else {
       g_FirstFocusElement = g.radioSkip;
    }

    IspToggleAllRadioButtons(true);

    g.ISP_ICS.style.display = "none";
    g.radioSelectICS.style.display = "none";
    if ( window.external.IsIcsAvailable() )
    {
        g.ISP_ICS.style.display = "inline";
        g.radioSelectICS.style.display = "inline";
    }

    InitButtons();

    g_FirstFocusElement.checked=true;
    g_FirstFocusElement.focus();
}

function IspUnLoad()
{
    try
    {
        if(g.radioGetNewISP.checked) {
          g_iISPRadioActive=1;
        } else if(g.radioMigrateISP.checked) {
          g_iISPRadioActive=2;
        } else if(g.radioSelectICS.checked) {
          g_iISPRadioActive=3;
        } else {
          g_iISPRadioActive=4;
        }
        g_bRadioMigrateISP = (g.event.srcElement==g.radioMigrateISP);
    }
    catch (e) {}

}
function IspToggleAllRadioButtons(bSwitch)
{
    try
    {
        g.radioGetNewISP.disabled = !bSwitch;
        g.ISP_New.disabled = !bSwitch;
        g.radioMigrateISP.disabled = !bSwitch;
        g.ISP_Migrate.disabled = !bSwitch;
        g.radioSelectICS.disabled = !bSwitch;
        g.ISP_ICS.disabled = !bSwitch;
        g.radioSkip.disabled = !bSwitch;
        g.skipISP.disabled = !bSwitch;
    }
    catch (e)
    {
    }
}


// Place holder for the ISP page function
function RegRadioClicked()
{
    g.btnNext.disabled = false;
    InitButtons();
}
/////////////////////////////////////////////////////////////////////////////////////
// ics.htm
/////////////////////////////////////////////////////////////////////////////////////
function IcsLoadMe()
{
    InitFrameRef();

    InitButtons();

    g_FirstFocusElement = g.radio_ChooseIcs;
    g_FirstFocusElement.focus();
}

function IcsRadioClicked()
{
    g.btnNext.disabled = false;
    InitButtons();
}

////////////////////////////////////////////////////////////////////
// Do NOT REMOVE THIS FUNCTION< THIS WILL GET CALLED WHEN F1 is
// PRESSED.
////////////////////////////////////////////////////////////////////
function OnHelp()
{
    // Invoke MSAgent
    Agent_OnUserRequestAssistant();
}

</script>

<SCRIPT LANGUAGE=VBScript>
<!-- BUGBUG: Can this be changed to jscript?? -->
<!-- Flash calls this VBScript fn when movie exits -->
Sub IntroAnimation_FSCommand(ByVal command, ByVal args)
  call PostMovieWelcomeInit()
end sub
</SCRIPT>

</HEAD>

<BODY ID=OOBEDocBody  leftMargin=0 DIR=LTR onload="InitApplication();" scroll=no tabIndex=-1 topMargin=0 language=javascript onhelp="Agent_OnUserRequestAssistant();" style="background-color: white">
<SPAN ID=junkspan style="height:2px;width:2px;background-color:black;z-index:99;display:none"></SPAN>

<SPAN ID=MovieFrame style="position:absolute; height:100%;width:100%;background-color:white;z-index:99999;display:none">
  <OBJECT alt=Welcome classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
          codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0"
          ID=IntroAnimation WIDTH=100% HEIGHT=100%>
          <PARAM NAME=movie VALUE="images\intro.swf">
          <PARAM NAME=loop VALUE=false>
          <PARAM NAME=menu VALUE=false>
          <PARAM NAME=quality VALUE=best>
          <PARAM NAME=bgcolor VALUE=#FFFFFF>
  </OBJECT>
</SPAN>

  <SPAN ID=ScreenFrame style="height:100%; width:100%; position:absolute; display:none">

    <IMG ID=MSLogoImg style="LEFT: 0px; TOP: 0px;  POSITION: absolute; z-index:10;" alt="">

    <SPAN ID=StatusBackgndColor style="width:180px; height:100%; background-color:#4F7FB5; position:absolute; top:0px; left:0px; z-index:-20">
      </SPAN>  <!-- height adjusted in InitApp-->

    <SPAN id=spnStatDividerBar style="left:180px; height:100%; background-color:#80A2CF; position:absolute; width:10px; top:0px; z-index:6">
      </SPAN>

    <!-- two cell table contains statpane, mainbody-->
    <TABLE cellpadding=0 cellspacing=0 style="z-index:6; position:absolute; left:0px; top:0px; width:100%;height:100%">
    <TR>
    <TD ID=statpaneCell style="width:190px; height:100%;z-index:6">
      <SPAN id=spnStatusPane style="position:absolute;LEFT: 0px; TOP: 131px; z-index:66; width: 190px;">
        <IFRAME id=ifrmStatusPane frameBorder=no scrolling=no style="width:100%; height:300px; background-color: #4F7FB5" name=StatusPane src="res://MSOBSHEL.DLL/STATPANE_RESOURCE" tabIndex=-1 ></IFRAME>
      </SPAN>
    </TD>

    <TD style="height:100%" align=center>

    <SPAN id=spnPage style="VISIBILITY: hidden;z-index:4;" tabIndex=-1>  <!--hidden so users dont see initial load-->
             <SPAN id=spnMainFrame style="width: 610px; height:100%" tabIndex=-1 >
                 <IFRAME id=ifrmMainFrame frameBorder=no scrolling=no width="100%" height="100%"  name=msoobeMain tabIndex=0></IFRAME>  <!-- tabindex=0 because we dont want IFRAME to get focus -->
                 <IFRAME id=ifrmConnDelay frameBorder=no style="display:none; position:absolute; z-index:-1; left: 190px;" scrolling=no width="100%" height="100%" name=connDelay tabIndex=-1 src="setup/ISPWait.htm"></IFRAME>
             </SPAN>
    </SPAN>

    </TD></TR>
    </TABLE>

    <SPAN id=spnOEMLogo style="z-index:10;POSITION: absolute; TOP: 0px; HEIGHT: 48px; width:100%; LEFT: 243px; background-position: top left; background-repeat: no-repeat; background-image: url(images/oemlogo.gif);">
    </SPAN>

    <SPAN id=spnAssist class="emphasis-lesser" style="visibility:hidden; background-color:#4F7FB5; POSITION: absolute; LEFT: 0px; HEIGHT: 160px; TOP: 410px; WIDTH: 180px; z-index:9">
       <TABLE width="95%" cellspacing=0 cellpadding=0 align=center class="emphasis-lesser" style="text-align:center;color:white;">
         <TR><TD align=center>
             <IMG align=middle id=AssistImg alt=help border=0 src="images/merlin.png"
                  style="visibility:hidden;z-index:9" language=javascript
                  onclick="Agent_OnUserRequestAssistant()"><BR>
          </TD></TR>
          <TR><TD ID=MerlinStr1>If you want</TD></TR>
          <TR><TD ID=MerlinStr2>assistance, click Merlin</TD></TR>
          <TR><TD ID=MerlinStr3>or press F1.</TD></TR>
       </TABLE>
    </SPAN>
</SPAN>
</BODY>
</HTML>