﻿/**	sniffer2-SOURCE.js */
//
// JavaScript Browser Sniffer
// Eric Krok, Andy King, Michel Plungjan Jan. 31, 2002
// see http://www.webreference.com/ for more information
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
// please send any improvements to aking@internet.com and we'll
// roll the best ones in
//
// adapted from Netscape's Ultimate client-side JavaScript client sniffer
// and andy king's sniffer
// Revised May 7 99 to add is.nav5up and is.ie5up (see below). (see below).
// Revised June 11 99 to add additional props, checks
// Revised June 23 99 added screen props - gecko m6 doesn't support yet - abk
//                    converted to var is_ from is object to work everywhere
// 990624 - added cookie forms links frames checks - abk
// 001031 - ie4 mod 5.0 -> 5. (ie5.5 mididentified - abk)
//          is_ie4 mod tp work with ie6+ - abk
// 001120 - ns6 released, document.layers false, put back in
//        - is_nav6 test added - abk
// 001121 - ns6+ added, used document.getElementById, better test, dom-compl
// 010117 - actual version for ie3-5.5 by Michel Plungjan
// 010118 - actual version for ns6 by Michel Plungjan
// 010217 - netscape 6/mz 6 ie5.5 onload defer bug docs - abk
// 011107 - added is_ie6 and is_ie6up variables - dmr
// 020128 - added link to netscape's sniffer, on which this is based - abk
//          updated sniffer for aol4-6, ie5mac = js1.4, TVNavigator, AOLTV,
//          hotjava
// 020131 - cleaned up links, added more links to example object detection
// 020131 - a couple small problems with Opera detection. First, when Opera
//          is set to be compatible with other browsers it will contain their
//          information in the userAgent strings. Thus, to be sure we have 
//          Opera we should check for it before checking for the other bigs.
//          (And make sure the others are !opera.) Also corrected a minor
//          bug in the is_opera6up assignment.
// 020214 - Added link for Opera/JS compatibility; added improvements for 
//          windows xp/2000 id in opera and aol 7 id (thanks to Les
//          Hill, Les.Hill@getronics.com, for the suggestion).
// 020531 - Added N6/7 and moz identifiers. 
// 020605 - Added mozilla guessing, Netscape 7 identification, and cleaner
//          identification for Netscape 6. (this comment added after code 
//          changes)
// 020725 - Added is_gecko. -- dmr
// 021205 - Added is_Flash and is_FlashVersion, based on Doc JavaScript code. 
//          Added Opera 7 variables. -- dmr
// 021209 - Added aol8. -- dmr
// 030110 - Added is_safari, added 1.5 js designation for Opera 7. --dmr
// 030128 - Added is_konq, per user suggestion (thanks to Sam Vilain).
//          Removed duplicate Opera checks left over after last revision. - dmr
// 031124 - Added is_fb and version. We report this right after the is_moz
//          report. - dmr
// 040325 - Added is_fx and version. We report this right after the is_moz
//          report. - dmr
// 040421 - Added Debian check to is_moz. Thanks to Patrice Bridoux for
//          reporting this.
// 040517 - Added is_fb/is_fx to plugins based flash detection. Thanks to 
//          Martin Bischoff for pointing out this omission.
// 040617 - On Mac IE, appVersion differs from the version in the ua, 
//          with the UA appearing to be more accurate. As an experiment, 
//          for Mac we'll pull is_minor from the ua instead.
// 040831 - Fixed Opera bug in flash detection logic; when Opera has
//          "enable plugins" unchecked in preferences, the "plugin" 
//          variable is still true, but the "description" property 
//          belonging to it is undefined.
// 051202 - Added ua check for higher versions of Firefox (1.5+), 
//          since vendor/vendorSub is no longer used and the sniffer 
//          was assuming Mozilla. Also belatedly added is_nav8 and 
//          is_nav8up.
//
// 060216 - Remmed out the flash detection for IE4+ on Win platforms
//          to allow for better consolodation with code in browserInfo.js 
//          (available at www.azlighthouse.com/downloads)  
//          -Devin Olson
//
// Everything you always wanted to know about your JavaScript client
// but were afraid to ask. Creates "is_" variables indicating:
// (1) browser vendor:
//     is_nav, is_ie, is_opera
// (2) browser version number:
//     is_major (integer indicating major version number: 2, 3, 4 ...)
//     is_minor (float   indicating full  version number: 2.02, 3.01, 4.04 ...)
// (3) browser vendor AND major version number
//     is_nav2, is_nav3, is_nav4, is_nav4up, is_nav5, is_nav5up, 
//     is_nav6, is_nav6up, is_ie3, is_ie4, is_ie4up, is_ie5up, is_ie6...
// (4) JavaScript version number:
//     is_js (float indicating full JavaScript version number: 1, 1.1, 1.2 ...)
// (5) OS platform and version:
//     is_win, is_win16, is_win32, is_win31, is_win95, is_winnt, is_win98
//     is_os2
//     is_mac, is_mac68k, is_macppc
//     is_unix
//        is_sun, is_sun4, is_sun5, is_suni86
//        is_irix, is_irix5, is_irix6
//        is_hpux, is_hpux9, is_hpux10
//        is_aix, is_aix1, is_aix2, is_aix3, is_aix4
//        is_linux, is_sco, is_unixware, is_mpras, is_reliant
//        is_dec, is_sinix, is_freebsd, is_bsd
//     is_vms
//
// based in part on 
// http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html
// The Ultimate JavaScript Client Sniffer
// and Andy King's object detection sniffer
//
// Note: you don't want your Nav4 or IE4 code to "turn off" or
// stop working when Nav5 and IE5 (or later) are released, so
// in conditional code forks, use is_nav4up ("Nav4 or greater")
// and is_ie4up ("IE4 or greater") instead of is_nav4 or is_ie4
// to check version in code which you want to work on future
// versions. For DOM tests scripters commonly used the 
// is_getElementById test, but make sure you test your code as
// filter non-compliant browsers (Opera 5-6 for example) as some 
// browsers return true for this test, and don't fully support
// the W3C's DOM1.
//

    // convert all characters to lowercase to simplify testing
    var agt=navigator.userAgent.toLowerCase();
    var appVer = navigator.appVersion.toLowerCase();

    // *** BROWSER VERSION ***

    var is_minor = parseFloat(appVer);
    var is_major = parseInt(is_minor);

    var is_opera = (agt.indexOf("opera") != -1);
    var is_opera2 = (agt.indexOf("opera 2") != -1 || agt.indexOf("opera/2") != -1);
    var is_opera3 = (agt.indexOf("opera 3") != -1 || agt.indexOf("opera/3") != -1);
    var is_opera4 = (agt.indexOf("opera 4") != -1 || agt.indexOf("opera/4") != -1);
    var is_opera5 = (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1);
    var is_opera6 = (agt.indexOf("opera 6") != -1 || agt.indexOf("opera/6") != -1); // new 020128- abk
    var is_opera7 = (agt.indexOf("opera 7") != -1 || agt.indexOf("opera/7") != -1); // new 021205- dmr
    var is_opera5up = (is_opera && !is_opera2 && !is_opera3 && !is_opera4);
    var is_opera6up = (is_opera && !is_opera2 && !is_opera3 && !is_opera4 && !is_opera5); // new020128
    var is_opera7up = (is_opera && !is_opera2 && !is_opera3 && !is_opera4 && !is_opera5 && !is_opera6); // new021205 -- dmr

    // Note: On IE, start of appVersion return 3 or 4
    // which supposedly is the version of Netscape it is compatible with.
    // So we look for the real version further on in the string
    // And on Mac IE5+, we look for is_minor in the ua; since 
    // it appears to be more accurate than appVersion - 06/17/2004

    var is_mac = (agt.indexOf("mac")!=-1);
    var iePos  = appVer.indexOf('msie');
    if (iePos !=-1) {
       if(is_mac) {
           var iePos = agt.indexOf('msie');
           is_minor = parseFloat(agt.substring(iePos+5,agt.indexOf(';',iePos)));
       }
       else is_minor = parseFloat(appVer.substring(iePos+5,appVer.indexOf(';',iePos)));
       is_major = parseInt(is_minor);
    }

    // ditto Konqueror
                                      
    var is_konq = false;
    var kqPos   = agt.indexOf('konqueror');
    if (kqPos !=-1) {                 
       is_konq  = true;
       is_minor = parseFloat(agt.substring(kqPos+10,agt.indexOf(';',kqPos)));
       is_major = parseInt(is_minor);
    }                                 

    var is_getElementById   = (document.getElementById) ? "true" : "false"; // 001121-abk
    var is_getElementsByTagName = (document.getElementsByTagName) ? "true" : "false"; // 001127-abk
    var is_documentElement = (document.documentElement) ? "true" : "false"; // 001121-abk

    var is_safari = ((agt.indexOf('safari')!=-1)&&(agt.indexOf('mac')!=-1))?true:false;
    var is_khtml  = (is_safari || is_konq);

    var is_gecko = ((!is_khtml)&&(navigator.product)&&(navigator.product.toLowerCase()=="gecko"))?true:false;
    var is_gver  = 0;
    if (is_gecko) is_gver=navigator.productSub;

    var is_fb = ((agt.indexOf('mozilla/5')!=-1) && (agt.indexOf('spoofer')==-1) &&
                 (agt.indexOf('compatible')==-1) && (agt.indexOf('opera')==-1)  &&
                 (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1)     &&
                 (is_gecko) && (navigator.vendor=="Firebird"));
    var is_fx = ((agt.indexOf('mozilla/5')!=-1) && (agt.indexOf('spoofer')==-1) &&
                 (agt.indexOf('compatible')==-1) && (agt.indexOf('opera')==-1)  &&
                 (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1)     &&
                 (is_gecko) && ((navigator.vendor=="Firefox")||(agt.indexOf('firefox')!=-1)));
    var is_moz   = ((agt.indexOf('mozilla/5')!=-1) && (agt.indexOf('spoofer')==-1) &&
                    (agt.indexOf('compatible')==-1) && (agt.indexOf('opera')==-1)  &&
                    (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1)     &&
                    (is_gecko) && (!is_fb) && (!is_fx) &&
                    ((navigator.vendor=="")||(navigator.vendor=="Mozilla")||(navigator.vendor=="Debian")));
    if ((is_moz)||(is_fb)||(is_fx)) {  // 032504 - dmr
       var is_moz_ver = (navigator.vendorSub)?navigator.vendorSub:0;
       if(is_fx&&!is_moz_ver) {
           is_moz_ver = agt.indexOf('firefox/');
           is_moz_ver = agt.substring(is_moz_ver+8);
           is_moz_ver = parseFloat(is_moz_ver);
       }
       if(!(is_moz_ver)) {
           is_moz_ver = agt.indexOf('rv:');
           is_moz_ver = agt.substring(is_moz_ver+3);
           is_paren   = is_moz_ver.indexOf(')');
           is_moz_ver = is_moz_ver.substring(0,is_paren);
       }
       is_minor = is_moz_ver;
       is_major = parseInt(is_moz_ver);
    }
   var is_fb_ver = is_moz_ver;
   var is_fx_ver = is_moz_ver;

    var is_nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
                && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
                && (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1)
                && (!is_khtml) && (!(is_moz)) && (!is_fb) && (!is_fx));

    // Netscape6 is mozilla/5 + Netscape6/6.0!!!
    // Mozilla/5.0 (Windows; U; Win98; en-US; m18) Gecko/20001108 Netscape6/6.0
    // Changed this to use navigator.vendor/vendorSub - dmr 060502   
    // var nav6Pos = agt.indexOf('netscape6');
    // if (nav6Pos !=-1) {
    if ((navigator.vendor)&&
        ((navigator.vendor=="Netscape6")||(navigator.vendor=="Netscape"))&&
        (is_nav)) {
       is_major = parseInt(navigator.vendorSub);
       // here we need is_minor as a valid float for testing. We'll
       // revert to the actual content before printing the result. 
       is_minor = parseFloat(navigator.vendorSub);
    }

    var is_nav2 = (is_nav && (is_major == 2));
    var is_nav3 = (is_nav && (is_major == 3));
    var is_nav4 = (is_nav && (is_major == 4));
    var is_nav4up = (is_nav && is_minor >= 4);  // changed to is_minor for
                                                // consistency - dmr, 011001
    var is_navonly      = (is_nav && ((agt.indexOf(";nav") != -1) ||
                          (agt.indexOf("; nav") != -1)) );

    var is_nav6   = (is_nav && is_major==6);    // new 010118 mhp
    var is_nav6up = (is_nav && is_minor >= 6); // new 010118 mhp

    var is_nav5   = (is_nav && is_major == 5 && !is_nav6); // checked for ns6
    var is_nav5up = (is_nav && is_minor >= 5);

    var is_nav7   = (is_nav && is_major == 7);
    var is_nav7up = (is_nav && is_minor >= 7);

    var is_nav8   = (is_nav && is_major == 8);
    var is_nav8up = (is_nav && is_minor >= 8);

    var is_ie   = ((iePos!=-1) && (!is_opera) && (!is_khtml));
    var is_ie3  = (is_ie && (is_major < 4));

    var is_ie4   = (is_ie && is_major == 4);
    var is_ie4up = (is_ie && is_minor >= 4);
    var is_ie5   = (is_ie && is_major == 5);
    var is_ie5up = (is_ie && is_minor >= 5);
    
    var is_ie5_5  = (is_ie && (agt.indexOf("msie 5.5") !=-1)); // 020128 new - abk
    var is_ie5_5up =(is_ie && is_minor >= 5.5);                // 020128 new - abk
        
    var is_ie6   = (is_ie && is_major == 6);
    var is_ie6up = (is_ie && is_minor >= 6);

// KNOWN BUG: On AOL4, returns false if IE3 is embedded browser
    // or if this is the first browser window opened.  Thus the
    // variables is_aol, is_aol3, and is_aol4 aren't 100% reliable.

    var is_aol   = (agt.indexOf("aol") != -1);
    var is_aol3  = (is_aol && is_ie3);
    var is_aol4  = (is_aol && is_ie4);
    var is_aol5  = (agt.indexOf("aol 5") != -1);
    var is_aol6  = (agt.indexOf("aol 6") != -1);
    var is_aol7  = ((agt.indexOf("aol 7")!=-1) || (agt.indexOf("aol7")!=-1));
    var is_aol8  = ((agt.indexOf("aol 8")!=-1) || (agt.indexOf("aol8")!=-1));

    var is_webtv = (agt.indexOf("webtv") != -1);
    
    // new 020128 - abk
    
    var is_TVNavigator = ((agt.indexOf("navio") != -1) || (agt.indexOf("navio_aoltv") != -1)); 
    var is_AOLTV = is_TVNavigator;

    var is_hotjava = (agt.indexOf("hotjava") != -1);
    var is_hotjava3 = (is_hotjava && (is_major == 3));
    var is_hotjava3up = (is_hotjava && (is_major >= 3));

    // end new
        
    // *** JAVASCRIPT VERSION CHECK ***
    // Useful to workaround Nav3 bug in which Nav3
    // loads <SCRIPT LANGUAGE="JavaScript1.2">.
    // updated 020131 by dragle
    var is_js;
    if (is_nav2 || is_ie3) is_js = 1.0;
    else if (is_nav3) is_js = 1.1;
    else if ((is_opera5)||(is_opera6)) is_js = 1.3; // 020214 - dmr
    else if (is_opera7up) is_js = 1.5; // 031010 - dmr
    else if (is_khtml) is_js = 1.5;   // 030110 - dmr
    else if (is_opera) is_js = 1.1;
    else if ((is_nav4 && (is_minor <= 4.05)) || is_ie4) is_js = 1.2;
    else if ((is_nav4 && (is_minor > 4.05)) || is_ie5) is_js = 1.3;
    else if (is_nav5 && !(is_nav6)) is_js = 1.4;
    else if (is_hotjava3up) is_js = 1.4; // new 020128 - abk
    else if (is_nav6up) is_js = 1.5;

    // NOTE: In the future, update this code when newer versions of JS
    // are released. For now, we try to provide some upward compatibility
    // so that future versions of Nav and IE will show they are at
    // *least* JS 1.x capable. Always check for JS version compatibility
    // with > or >=.

    else if (is_nav && (is_major > 5)) is_js = 1.4;
    else if (is_ie && (is_major > 5)) is_js = 1.3;
    else if (is_moz) is_js = 1.5;
    else if (is_fb||is_fx) is_js = 1.5; // 032504 - dmr
    
    // what about ie6 and ie6up for js version? abk
    
    // HACK: no idea for other browsers; always check for JS version 
    // with > or >=
    else is_js = 0.0;
    // HACK FOR IE5 MAC = js vers = 1.4 (if put inside if/else jumps out at 1.3)
    if ((agt.indexOf("mac")!=-1) && is_ie5up) is_js = 1.4; // 020128 - abk
    
    // Done with is_minor testing; revert to real for N6/7
    if (is_nav6up) {
       is_minor = navigator.vendorSub;
    }

    // *** PLATFORM ***
    var is_win   = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) );
    // NOTE: On Opera 3.0, the userAgent string includes "Windows 95/NT4" on all
    //        Win32, so you can't distinguish between Win95 and WinNT.
    var is_win95 = ((agt.indexOf("win95")!=-1) || (agt.indexOf("windows 95")!=-1));

    // is this a 16 bit compiled version?
    var is_win16 = ((agt.indexOf("win16")!=-1) ||
               (agt.indexOf("16bit")!=-1) || (agt.indexOf("windows 3.1")!=-1) ||
               (agt.indexOf("windows 16-bit")!=-1) );

    var is_win31 = ((agt.indexOf("windows 3.1")!=-1) || (agt.indexOf("win16")!=-1) ||
                    (agt.indexOf("windows 16-bit")!=-1));
        
    var is_winme = ((agt.indexOf("win 9x 4.90")!=-1));    // new 020128 - abk
    var is_win2k = ((agt.indexOf("windows nt 5.0")!=-1) || (agt.indexOf("windows 2000")!=-1)); // 020214 - dmr
    var is_winxp = ((agt.indexOf("windows nt 5.1")!=-1) || (agt.indexOf("windows xp")!=-1)); // 020214 - dmr

    // NOTE: Reliable detection of Win98 may not be possible. It appears that:
    //       - On Nav 4.x and before you'll get plain "Windows" in userAgent.
    //       - On Mercury client, the 32-bit version will return "Win98", but
    //         the 16-bit version running on Win98 will still return "Win95".
    var is_win98 = ((agt.indexOf("win98")!=-1) || (agt.indexOf("windows 98")!=-1));
    var is_winnt = ((agt.indexOf("winnt")!=-1) || (agt.indexOf("windows nt")!=-1));
    var is_win32 = (is_win95 || is_winnt || is_win98 ||
                    ((is_major >= 4) && (navigator.platform == "Win32")) ||
                    (agt.indexOf("win32")!=-1) || (agt.indexOf("32bit")!=-1));

    var is_os2   = ((agt.indexOf("os/2")!=-1) ||
                    (navigator.appVersion.indexOf("OS/2")!=-1) ||
                    (agt.indexOf("ibm-webexplorer")!=-1));

    var is_mac    = (agt.indexOf("mac")!=-1);
    if (is_mac) { is_win = !is_mac; } // dmr - 06/20/2002
    var is_mac68k = (is_mac && ((agt.indexOf("68k")!=-1) ||
                               (agt.indexOf("68000")!=-1)));
    var is_macppc = (is_mac && ((agt.indexOf("ppc")!=-1) ||
                                (agt.indexOf("powerpc")!=-1)));

    var is_sun   = (agt.indexOf("sunos")!=-1);
    var is_sun4  = (agt.indexOf("sunos 4")!=-1);
    var is_sun5  = (agt.indexOf("sunos 5")!=-1);
    var is_suni86= (is_sun && (agt.indexOf("i86")!=-1));
    var is_irix  = (agt.indexOf("irix") !=-1);    // SGI
    var is_irix5 = (agt.indexOf("irix 5") !=-1);
    var is_irix6 = ((agt.indexOf("irix 6") !=-1) || (agt.indexOf("irix6") !=-1));
    var is_hpux  = (agt.indexOf("hp-ux")!=-1);
    var is_hpux9 = (is_hpux && (agt.indexOf("09.")!=-1));
    var is_hpux10= (is_hpux && (agt.indexOf("10.")!=-1));
    var is_aix   = (agt.indexOf("aix") !=-1);      // IBM
    var is_aix1  = (agt.indexOf("aix 1") !=-1);
    var is_aix2  = (agt.indexOf("aix 2") !=-1);
    var is_aix3  = (agt.indexOf("aix 3") !=-1);
    var is_aix4  = (agt.indexOf("aix 4") !=-1);
    var is_linux = (agt.indexOf("inux")!=-1);
    var is_sco   = (agt.indexOf("sco")!=-1) || (agt.indexOf("unix_sv")!=-1);
    var is_unixware = (agt.indexOf("unix_system_v")!=-1);
    var is_mpras    = (agt.indexOf("ncr")!=-1);
    var is_reliant  = (agt.indexOf("reliantunix")!=-1);
    var is_dec   = ((agt.indexOf("dec")!=-1) || (agt.indexOf("osf1")!=-1) ||
           (agt.indexOf("dec_alpha")!=-1) || (agt.indexOf("alphaserver")!=-1) ||
           (agt.indexOf("ultrix")!=-1) || (agt.indexOf("alphastation")!=-1));
    var is_sinix = (agt.indexOf("sinix")!=-1);
    var is_freebsd = (agt.indexOf("freebsd")!=-1);
    var is_bsd = (agt.indexOf("bsd")!=-1);
    var is_unix  = ((agt.indexOf("x11")!=-1) || is_sun || is_irix || is_hpux ||
                 is_sco ||is_unixware || is_mpras || is_reliant ||
                 is_dec || is_sinix || is_aix || is_linux || is_bsd || is_freebsd);

    var is_vms   = ((agt.indexOf("vax")!=-1) || (agt.indexOf("openvms")!=-1));
// additional checks, abk
        var is_anchors = (document.anchors) ? "true":"false";
        var is_regexp = (window.RegExp) ? "true":"false";
        var is_option = (window.Option) ? "true":"false";
        var is_all = (document.all) ? "true":"false";
// cookies - 990624 - abk
        document.cookie = "cookies=true";
        var is_cookie = (document.cookie) ? "true" : "false";
        var is_images = (document.images) ? "true":"false";
        var is_layers = (document.layers) ? "true":"false"; // gecko m7 bug?
// new doc obj tests 990624-abk
        var is_forms = (document.forms) ? "true" : "false";
        var is_links = (document.links) ? "true" : "false";
        var is_frames = (window.frames) ? "true" : "false";
        var is_screen = (window.screen) ? "true" : "false";

// java
        var is_java = (navigator.javaEnabled());

// Flash checking code adapted from Doc JavaScript information; 
// see http://webref.com/js/column84/2.html

   var is_Flash        = false;
   var is_FlashVersion = 0;

   if ((is_nav||is_opera||is_moz||is_fb||is_fx)||
       (is_mac&&is_ie5up)) {
      var plugin = (navigator.mimeTypes && 
                    navigator.mimeTypes["application/x-shockwave-flash"] &&
                    navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) ?
                    navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
//      if (plugin) {
      if (plugin&&plugin.description) {
         is_Flash = true;
         is_FlashVersion = parseInt(plugin.description.substring(plugin.description.indexOf(".")-1));
      }
   }
/**	END of sniffer2-SOURCE.js **/

/**	browserRequirements-SOURCE.js 
	============================================================
	============================================================
	INTELLECTUAL PROPERTY ADVISORY NOTICE
	browserRequirements-SOURCE.js 
	azlighthouse works, llc. Browser Requirements Script Library.
	Copyright (c) 2006 azlighthouse works, llc.
	All rights reserved.
	http://www.azlighthouse.com
	Permission to use, redistribute, or modify this code, 
	in whole or in part, is hereby expressely granted PROVIDED 
	this Intellectual Property Advisory Notice is included in 
	any derived works.
	============================================================
	============================================================
	
	============================================================
	============================================================
	browserRequirements-SOURCE.js VERSION 1.0	
	This library acts as a carrier of required browser 
	capabilities for a specific web application.  The values in 
	this library should be treated as GLOBAL CONSTANTS, and 
	should not be modified by subsequent Javascript code. 
	Complete commented source available at 
	http://www.azlighthouse.com
	============================================================
	============================================================
*/

/**	
	==================================================
	VARIABLE NAME DEFINITIONS:

	BR_REQUIREMENTS_EXIST: Boolean true.  This variable 
	should ALWAYS be set to true.  It is used by other 
	functions to detect if the browser requirements have 
	been defined.


	BR_ENFORCE_REQUIREMENTS: Boolean true or false.  
	This indicates whether or not subsequent code should 
	enforce the defined requirements (such as redirecting 
	to a new URL on page load).


	BR_APPLICAITON_NAME: String.  The name of the 
	application for which these requirements apply.


	BR_PLATFORM: Array of Strings.  The required 
	platform(s) / operating system(s).  If platform is 
	not required, set this value to a blank string.
		Examples: 
		BR_PLATFORM = new Array("Win32", "Linux");
		BR_PLATFORM = "";


	BR_CPU: Array of Strings.  The required CPU classes. 
	If this is not required, set the value to a blank 
	string.
		Examples:
		BR_CPU = new Array("x86");
		BR_CPU = "";


	BR_RESOLUTION_WIDTH: Integer.  The required screen 
	resolution width, in pixels.  If not required, set 
	this value to zero.
		Examples:
		BR_RESOLUTION_WIDTH = 1024;
		BR_RESOLUTION_WIDTH = 0;


	BR_RESOLUTION_HEIGHT: Integer.  The required screen 
	resolution height, in pixels.  If not required, set 
	this value to zero (similar to above).



	BR_COLOR_DEPTH: String.  The required screen color 
	depth.  If not required, set this value to a blank 
	string.
		Examples:
		BR_COLOR_DEPTH = "256 colors";
		BR_COLOR_DEPTH = "16bit";
		BR_COLOR_DEPTH = "32bit";
		BR_COLOR_DEPTH = "";


	BR_BROWSER: Array of Strings.  The required 
	browser(s) for this application.  If not required, 
	set this value to a blank string.
		Exmaples:
		BR_BROWSER = new Array("MSIE", "Netscape", 
					"Microsoft Internet Explorer", 
					"Opera", "Firefox");
		BR_BROWSER = "";


	BR_BROWSER_VER: Array of Strings.  The minimum 
	required browser version(s) for this application. 
	THE VALUES IN THIS ARRAY CORRESPOND TO THE VALUES 
	IN THE BR_BROWSER ARRAY. If not required, set the 
	value to an empty string.
		Examples:
		BR_BROWSER_VER = new Array("6", "4.7", "6", 
						"", "");
		BR_BROWSER_VER = "";


	BR_POPUPS_ENABLED: Boolean true or false.  Set to 
	true if the application requires Popup Windows be 
	allowed by the browser, and false if not.


	BR_JAVASCRIPT: Boolean true or false.  Set to true 
	if the application requires Javascript, and false 
	otherwise.


	BR_JAVASCRIPT_VER: Array of Strings.  Indicates 
	the minimum required Javascript version.  If 
	this is set to a blank string, no Javascript 
	version checking will occur.
		Example:
		BR_JAVASCRIPT_VER = "1.2";
		BR_JAVASCRIPT_VER = "";


	BR_VBSCRIPT: Boolean true or false.  Set to true 
	if the application requires VBScript, and false 
	otherwise.


	BR_ACTIVEX: Boolean true or false.  Set to true 
	if the application requires ActiveX, and false 
	otherwise.


	BR_JAVA: Boolean true or false.  Set to true 
	if the application requires Java, and false 
	otherwise.

			
	BR_COOKIES: Boolean true or false.  Set to true 
	if the application requires cookies to be enabled, 
	and false otherwise.


	BR_PLUGIN: Array of Strings.  The plugin names 
	required by the application.  These values will be 
	checked against the detected plugins, and will 
	succeed in the event of a partial match. (For 
	instance, if "Flash" is an element in BR_PLUGIN, 
	and the browser detects "Shockwave.Flash" as one 
	of the plugins, the match will succeed).  If no 
	plugins are required, set this value to a blank 
	string.
		Example:
		BR_PLUGIN = new Array("Windows Media Player",
							  "Quicktime",
							  "Flash");
		BR_PLUGIN = "";


	BR_PLUGIN_VER: Array of Strings.  Indicates 
	the minimum required version of the plugin.  
	THE VALUES IN THIS ARRAY CORRESPOND TO THE VALUES 
	IN THE BR_PLUGIN ARRAY. If this is set to a 
	blank string, no plugin version checking will 
	occur.
		Example:
		BR_PLUGIN_VER = new Array("1","2","5");
		BR_PLUGIN_VER = "";


	BR_PLUGIN_AX: Array of Strings.  The ActiveXObject 
	plugin names required by the application.  
	These values will be checked against the detected
	ActiveXObject plugins, and will succeed in the 
	event of a partial match. (For instance, if 
	"Flash" is an element in BR_PLUGIN_AX, and the 
	browser detects "Shockwave.Flash" as one of the 
	ActiveXObject plugins, the match will succeed).  
	If no ActiveXObject plugins are required, set this 
	value to a blank string.
		Example:
		BR_PLUGIN_AX = new Array("Windows Media Player",
							  "Quicktime",
							  "Flash");
		BR_PLUGIN_AX = "";
		
	BR_PLUGIN_VER_AX: Array of Strings.  Indicates 
	the minimum required version of the ActiveXObject 
	plugin.  THE VALUES IN THIS ARRAY CORRESPOND TO 
	THE VALUES IN THE BR_PLUGIN_AX ARRAY. If this is 
	set to a blank string, no ActiveXObject plugin 
	version checking will occur.
		Example:
		BR_PLUGIN_VER_AX = new Array("1","2","5");
		BR_PLUGIN_VER_AX = "";
	==================================================
*/

	var BR_REQUIREMENTS_EXIST = true;
	var BR_ENFORCE_REQUIREMENTS = false;
	var BR_APPLICATION_NAME = "NTC Online Training";
	var BR_PLATFORM = new Array("Win32");
	var BR_CPU = new Array("x86");
	var BR_RESOLUTION_WIDTH = 800; 
	var BR_RESOLUTION_HEIGHT = 600; 
	var BR_COLOR_DEPTH = "256 colors"; 
	var BR_BROWSER = new Array("Microsoft Internet Explorer"); 
	var BR_BROWSER_VER = new Array("5"); 
	var BR_POPUPS_ENABLED = true; 
	var BR_JAVASCRIPT = true; 
	var BR_JAVASCRIPT_VER = "1.2"; 
	var BR_VBSCRIPT = true;
	var BR_ACTIVEX = true;
	var BR_JAVA = true;
	var BR_COOKIES = true;
	var BR_PLUGIN = new Array("Flash","Quicktime");
	var BR_PLUGIN_VER = new Array("6","2");
	var BR_PLUGIN_AX = new Array("Windows Media Player");
	var BR_PLUGIN_VER_AX = new Array("1");
	
	
	
	
	
// code to verify that the element count of linked variables match
function elementCountsMatch(ary1, ary2) {
/**	
	==================================================
	This function will compare two arguments to see 
	if they are arrays with the same number of 
	elements.
	
	Return values based on Condition:
	no arguments passed:  true;
	only 1 argument passed: false;
	both arguments are NOT arrays: true;
	one argument is and array, and the other is not: false;
	both are arrays, and
		they have the same length: true;
		they have different lengths: false;
	==================================================
*/
		
		if ((!ary1) && (!ary2)) return true;  // nothing passed in.  
		if (!ary2) return false; // only a first argument exists.
		if ((!ary1[0]) && (!ary2[0])) return true; // neither first or second arguments are arrays.
		
		// if here, then at least one of the arguments is an array.
		if (!ary1[0]) return false; // argument 1 is not an array.
		if (!ary2[0]) return false; // argument 2 is not an array.
		
		// if here, then both arguments are arrays.
		// compare their lengths.
		if (ary1.length == ary2.length) return true; // lengths are equal.
		return false;  // lengths are NOT equal.
	} // function elementCountsMatch()
	
	
function checkRequiredElementCounts() {
	
	var alertMsg = "ERROR:  Mismatched element counts on:\n";
	var startLen = alertMsg.length;
	
	alertMsg += elementCountsMatch(BR_BROWSER, BR_BROWSER_VER)? "":" - BR_BROWSER & BR_BROWSER_VER\n";
	alertMsg += elementCountsMatch(BR_PLUGIN, BR_PLUGIN_VER)? "":" - BR_PLUGIN & BR_PLUGIN_VER\n";
	alertMsg += elementCountsMatch(BR_PLUGIN_AX, BR_PLUGIN_VER_AX)? "":" - BR_PLUGIN_AX & BR_PLUGIN_VER_AX\n";
	
	if (alertMsg.length != startLen) return alertMsg;
	return "";
} // function checkRequiredElementCounts()

var msg = checkRequiredElementCounts();
if (msg != "") alert(msg);

/**	END of browserRequirements-SOURCE.js **/



/**	browserInfo-SOURCE.js 
	============================================================
	============================================================
	INTELLECTUAL PROPERTY ADVISORY NOTICE
	browserInfo-SOURCE.js 
	azlighthouse works, llc. Browser Information Script Library
	Copyright (c) 2006 azlighthouse works, llc.
	All rights reserved.
	http://www.azlighthouse.com
	Permission to use, redistribute, or modify this code, 
	in whole or in part, is hereby expressely granted PROVIDED 
	this Intellectual Property Advisory Notice is included in 
	any derived works.
	============================================================
	============================================================
	
	============================================================
	============================================================
	browserInfo-SOURCE.js VERSION 1.0	
	This library provides functionality for gathering and 
	displaying browser information. Complete commented source 
	available at http://www.azlighthouse.com
	============================================================
	============================================================
*/
/**	
	==================================================
	BEGIN GLOBAL CONSTANTS
	These variables are treated as CONSTANTS and SHOULD
	SHOULD NOT be changed by javascript code.
	==================================================
*/

	var URL_BROWSER_FAILED = "http://www.ntc.blm.gov/training/browserFailed.html";
	var SUPPORTED_BROWSERS = new Array("Microsoft Internet Explorer","MSIE");
	var MINIMUM_MAJOR_VERSIONS = new Array(6, 6);
	var REQUIRED_PLUGINS = new Array("Flash");
	var REQUIRED_PLUGIN_VERSIONS = new Array(6);
/**	
	==================================================
	END GLOBAL CONSTANTS
	==================================================
*/

/**	
	==================================================
	BEGIN GLOBAL VARIABLES
	These variables are treated as CONSTANTS and SHOULD
	SHOULD NOT be changed by javascript code.
	==================================================
*/

	var NAV = navigator;
	var NAV_appCodeName = (NAV.appCodeName)? NAV.appCodeName:"";
	var NAV_appName = (NAV.appName)? NAV.appName:"";
	var NAV_appMinorVersion = (NAV.appMinorVersion)? NAV.appMinorVersion:"";
	var NAV_appVersion = (NAV.appVersio)? NAV.appVersion:"";
	var NAV_cookieEnabled = (NAV.cookieEnabled)? NAV.cookieEnabled:"";
	var NAV_cpuClass = (NAV.cpuClass)? NAV.cpuClass:"";
	var NAV_mimeTipes = (NAV.mimeTypes)? NAV.mimeTypes:"";
	var NAV_onLine = (NAV.onLine)? NAV.onLine:"";
	var NAV_opsProfile = (NAV.opsProfile)? NAV.opsProfile:"";
	var NAV_platform = (NAV.platform)? NAV.platform:"";
	var NAV_plugins = (NAV.plugins)? NAV.plugins:"";
	var NAV_systemLanguage = (NAV.systemLanguage)? NAV.systemLanguage:"";
	var NAV_userAgent = (NAV.userAgent)? NAV.userAgent:"";
	var NAV_userLanguage = (NAV.userLanguage)? NAV.userLanguage:"";
	var NAV_userProfile = (NAV.userProfile)? NAV.userProfile:"";	
	var JavascriptVersion = "Unknown";
	var JavaVersion = "Unknown";
	var JavaVendor = "Unknown";
	var detectableWithVB = false;
	var AX_DELIMITER = "~~|~~";
	var PLUGIN_DELIMITER = "=";
	var DETECTED_PLUGINS = "";
/**	
	==================================================
	END GLOBAL VARIABLES
	==================================================
*/

/**	
	==================================================
	Use VBScript to test whether ActiveX plugins can be detected.
	This code should only run on MSIE version 5 or above running on a 
	Windows 32bit or higher OS.  This code is based on public domain 
	"AS IS" code developed by Apple Computer Corp.
	==================================================
*/
if ((is_ie5up) && (is_win32 || is_win2k || is_winxp)) {

	/**
	need to break up the opening script tag; 
	otherwise the browser may prematurely end 
	the current script instance
	*/
    document.writeln("<scr" + "ipt language=VBscript> "); 

    document.writeln("\'do a one-time test for a version of VBScript that can handle this code ");
    document.writeln("detectableWithVB = False ");
    document.writeln("If ScriptEngineMajorVersion >= 2 then ");
    document.writeln("  detectableWithVB = True ");
    document.writeln("End If ");

	// as before, need to break up the closing script tag
    document.writeln("</scr" + "ipt> ");	

} // if ((is_ie5up) && (is_win32 || is_win2k || is_winxp))

/**	
	==================================================
	BEGIN ActiveX GLOBAL VARIABLES
	
	These variables are treated as CONSTANTS and SHOULD
	SHOULD NOT be changed by javascript code.
	
	All plugins that need to be tested for existence (on MSIE only) need 
	to be entered as elements in the following arrays.  This is because 
	MSIE does not support generic checking of installed plugins -the 
	existence of any given plugin must be an EXPLICIT test.	
	==================================================
*/
if (detectableWithVB) {

	var AX_Names = new Array(9);
	var AX_ClassIds = new Array(9);

	AX_ClassIds[0]="Adobe.SVGCtl";
	AX_Names[0]="SVG Viewer";

	AX_ClassIds[1]="SWCtl.SWCtl.1";
	AX_Names[1]="Shockwave Director";

	/**
	Starting the version check at 6 (below).
	Shockwave can be tested for any version EXCEPT 2.  
	If checking begins at 1, that is the only version that will be detected.
	if checking begins at 3 or above, the most recent version should be 
	successfully returned.  The decision to begin checking at 
	version 6 is completely arbitrary -it was done simply to reduce the 
	number of "cycles" of version checking.
	*/
	AX_ClassIds[2]="ShockwaveFlash.ShockwaveFlash.6"; 
	AX_Names[2]="Shockwave Flash";
	
	AX_ClassIds[3]="rmocx.RealPlayer G2 Control.1";
	AX_Names[3]="RealPlayer";
	
	AX_ClassIds[4]="QuickTimeCheckObject.QuickTimeCheck.1";
	AX_Names[4]="QuickTime";
	
	AX_ClassIds[5]="MediaPlayer.MediaPlayer.1";
	AX_Names[5]="Windows Media Player";
	
	AX_ClassIds[6]="PDF.PdfCtrl.1";
	AX_Names[6]="Acrobat Reader 4.0";
	
	AX_ClassIds[7]="PDF.PdfCtrl.5";
	AX_Names[7]="Acrobat Reader";
	
	AX_ClassIds[8]="AcroPDF.PDF.1";
	AX_Names[8]="Acrobat Reader 7";

} // if (detectableWithVB)
/**	
	==================================================
	END ActiveX GLOBAL VARIABLES
	==================================================
*/


function checkBrowserInfo() {
/**	
	==================================================
	This function will check to see if the browser 
	meets the minimum requrements, as defined in the 
	supporting script library browserRequirements.js 
	==================================================
*/

} // function checkBrowserInfo()


function checkRequirementsExist(alertOnFail) {
	if (!BR_REQUIREMENTS_EXIST) {
		if (alertOnFail) alert("Error:\n Browser Requirements script library (browserRequirements.js) not loaded.");
		return false;
	} // if (!BR_REQUIREMENTS_EXIST)
	
	if (checkRequiredElementCounts() == "") return true;
	return false;

} //function checkRequirementsExist()


function detectActiveXControl(ClassID) {
/**	
	==================================================
	This function will detect the ActiveX Control by 
	attempting to create the control using VBScript. 
	MSIE does not support generic checking of installed 
	plugins -the existence of any given plugin must be 
	an EXPLICIT test.
	==================================================
*/
	if (!detectableWithVB) return false;	
	if ((!ClassID) || (ClassID == "")) return false;
	
	/**
	need to break up the opening script tag; 
	otherwise the browser may prematurely end 
	the current script instance
	*/
	document.writeln("<scr" + "ipt language=javascript> ");

	document.writeln("	window.status = \"Detecting ActiveXControl: ClassID = '" + ClassID + "'\"; ");
	document.writeln("	var retVal = false; ");
	document.writeln("	var objActiveX = false; ");
	document.writeln("	try { ");
	document.writeln("		objActiveX = new ActiveXObject('" + ClassID + "'); ");
	document.writeln("		retVal = true; ");
	document.writeln("		if (objActiveX) { ");
	document.writeln("			objActiveX.Quit; ");
	document.writeln("			objActiveX = null; ");
	document.writeln("		} // if (objActiveX) ");
	document.writeln("	} catch(e) { ");
	document.writeln("		// do nothing ");
	document.writeln("	} // try ");

	// as before, need to break up the closing script tag
	document.writeln("</scr" + "ipt> ");

	return retVal;

} // function detectActiveXControl()


function detectActiveXControlClassID(ClassID) {
/**	
	==================================================
	This function will detect the ActiveX Control by 
	calling the detectActiveXControl() function.  If 
	detectActiveXControl() returns a true, the 
	ClassID will be returned.  Otherwise this 
	function will return an empty string ("").  MSIE 
	does not support generic checking of installed 
	plugins -the existence of any given plugin must be 
	an EXPLICIT test.
	==================================================
*/	
	if (!detectableWithVB) return "";	
	if ((!ClassID) || (ClassID == "")) return "";

	if (detectActiveXControl(ClassID)) return ClassID;
	
	return "";

} // function detectActiveXControlClassID()


function detectActiveXControlName(ClassID, ObjectName) {
/**	
	==================================================
	This function will detect the ActiveX Control by 
	calling the detectActiveXControl() function.  If 
	detectActiveXControl() returns a true, the 
	ClassID and, if it exists, the ObjectName 
	(delimited by AX_DELIMITER) will be returned.  Otherwise 
	this function will return an empty string ("").  
	MSIE does not support generic checking of 
	installed plugins -the existence of any given 
	plugin must be an EXPLICIT test.
	==================================================
*/	
	if (!detectableWithVB) return "";	
	if ((!ClassID) || (ClassID == "")) return "";

	if (detectActiveXControl(ClassID)) {
		if (ObjectName) {
			return ClassID + AX_DELIMITER + ObjectName;
		} else {
			return ClassID;
		} // if (ObjectName)
	} // if (detectActiveXControl(ClassID))
	
	return "";
} // function detectActiveXControlName()


function detectActiveXObject(ClassID, ObjectName) {
/**	
	==================================================
	This function will detect whether the passed in 
	ActiveXObject ClassID exists (can be created).  It 
	makes use of the following VBScript functions:
		-detectActiveXControl
		-detectActiveXControlName
		-detectQuickTimeActiveXControl
	
	It will attempt to detect the most current version 
	of the particular object ClassID.  If successful, 
	this function will return a string consisting of 
	the ObjectName and ClassID delimited by the pipe 
	(|) character.  If unsuccessful, a blank string 
	string ("") will be returned.
	==================================================
*/	
	if (!detectableWithVB) return "";	
	if ((!ClassID) || (ClassID == "")) return "";

	var pluginTempClassID = "";
	var pluginRootClassID = getStringRootValue(ClassID);
	var pluginMajorVersion = getStringMajorVersion(ClassID).toString();

	if (!detectActiveXControl(ClassID)) {
		// plugin not found.
		// try to find lesser versions.
		if (pluginRootClassID == ClassID) return ""; // no lesser versions exist.
		if (pluginMajorVersion == "") return ""; // no version information.
		
		pluginMajorVersion = parseInt(pluginMajorVersion).toString();
		if ((pluginMajorVersion == "") || (pluginMajorVersion == "NaN")) return ""; // no version information

		pluginMajorVersion = parseInt(pluginMajorVersion); // turn this back into a number
		pluginMajorVersion--; // and decrement it's value

		while (pluginMajorVersion > 0) {
			pluginTempClassID = pluginRootClassID + "." + pluginMajorVersion;
			if (detectActiveXControl(pluginTempClassID)) return pluginTempClassID + AX_DELIMITER + ObjectName // version was found.
		 	pluginMajorVersion--;
		} // while (pluginMajorVersion > 0) 

		// no version was found.
		// do a final check for the root ClassID and return the result.
		return detectActiveXControlName(pluginRootClassID, ObjectName);
	} // if (!detectActiveXControl(ClassID))
	
	// if here, then the object WAS initially detected.
	if (pluginRootClassID == ClassID) return ClassID + AX_DELIMITER + ObjectName; // no later versions exist.
	if (pluginMajorVersion == "") return  ClassID + AX_DELIMITER + ObjectName; // no version information.
	pluginMajorVersion = parseInt(pluginMajorVersion).toString();
	if ((pluginMajorVersion == "") || (pluginMajorVersion == "NaN")) return ClassID + AX_DELIMITER + ObjectName; // no version information

	// if here, then version information is included.
	// try to detect later versions.
	pluginMajorVersion = parseInt(pluginMajorVersion); // turn this back into a number

	do {
		pluginMajorVersion++; // increment the version
		pluginTempClassID = pluginRootClassID + "." + pluginMajorVersion;
		pluginTempClassID = detectActiveXControlClassID(pluginTempClassID);
		if (pluginTempClassID != "") ClassID = pluginTempClassID;
	} while (pluginTempClassID != "")
	
	return ClassID + AX_DELIMITER + ObjectName;  // return the last detected plugin 
		
} // function detectActiveXObject(valSource)


function detectActiveXPlugins() {
/**	
	==================================================
	This function will return an array of strings 
	indicating whether the specified ActiveXObjects 
	(as plugins) were detected.  MSIE does not support 
	generic checking of installed plugins -the existence 
	of any given plugin must be an EXPLICIT test.
	==================================================
*/	
	if (!detectableWithVB) return "";
	if ((!AX_Names) || (!AX_Names[0]) || (!AX_ClassIds) || (!AX_ClassIds[0])) return "";
	if (AX_Names.length != AX_ClassIds.length) {
		alert("Error: \n   Mismatched ActiveXObject Names to ClassIds!");
		return "";
	} // if (AX_Names.length != AX_ClassIDs.length)

	var pluginList = new Array(AX_Names.length);
	for (var i=0; i<AX_Names.length; i++) {
		pluginList[i] = detectActiveXObject(AX_ClassIds[i], AX_Names[i]);
		if (pluginList[i].indexOf(AX_DELIMITER) > -1) {
			// the ActiveXObject has been detected.
			// adjust the information to make it easier
			// for the user to read.
			var adjustInfo = pluginList[i].split(AX_DELIMITER);
			pluginList[i] = adjustInfo[1] + PLUGIN_DELIMITER + adjustInfo[0];
		} // if (pluginList[i].indexOf(AX_DELIMITER) >= 0) 
	} // for (var i=0; i<AX_Names.length; i++)

	return removeEmpties(pluginList);

} // function detectActiveXPlugins()


function getPluginInfo() {
/**	
	==================================================
	This function will return an array consisting of 
	all detected browser Plugins
	==================================================
*/	
    //alert("getPluginInfo()");
	var numPlugins = 0;
	var arrayPlugins = new Array();

	if ((navigator.plugins) && (navigator.plugins.length)) {
		numPlugins = navigator.plugins.length;
	
		for (var i=0; i < numPlugins; i++) {
			if (navigator.plugins[i]) {
				if ((navigator.plugins[i].name) && (navigator.plugins[i].description)) {
					arrayPlugins[i] = navigator.plugins[i].name + PLUGIN_DELIMITER +  "yes";//navigator.plugins[i].description;
				} else if (navigator.plugins[i].name) {
					arrayPlugins[i] = navigator.plugins[i].name;
				} else if (navigator.plugins[i].description) {
					arrayPlugins[i] = navigator.plugins[i].description;
				} else {
					arrayPlugins[i] = "";
				} // if ((navigator.plugins[i].name) && (navigator.plugins[i].description))

				/* 
				sometimes (in non-MSIE browsers),
				duplicate browser information will be returned.
				removed any duplicates before continuing.
				*/
				if ((i>0) && (arrayPlugins[i] == arrayPlugins[i-1])) arrayPlugins[i-1] = "";
			} else {
				arrayPlugins[i] = "";
			} // if (navigator.plugins[i])
		} // for (var i=0; i < numPlugins; i++) 
	} else if (detectableWithVB) {
	//alert("This is IE");
		arrayPlugins = detectActiveXPlugins();
	} else {
		alert("cannot access either the plugins or mimeTypes arrays");
		return false;
	} // if (navigator.plugins) 

	if ((arrayPlugins.length) && (arrayPlugins[0] != "")) {
		return removeEmpties(arrayPlugins);
	} else {
		return "";
	} // ((arrayPlugins.length) && (arrayPlugins[0] != ""))

} // function getPluginInfo()


function getStringMajorVersion(valSource) {
/**	
	==================================================
	This function will parse a passed in string and 
	return the major version (defined as the first 
	numeric part after the text portions of the 
	string, using a period as the delimeter) of the 
	string value.	
	==================================================
*/	
	return getStringRootValue(getStringVersion(valSource));

} // function getStringMajorVersion()


function getStringRootValue(valSource) {
/**	
	==================================================
	This function will parse a passed in string and 
	return the root name (defined as all parts prior 
	to any numeric portions of the string, using a 
	period as the delimeter) of the string value.	
	==================================================
*/	
	if (!valSource) return "";
	var strSource = valSource.toString();
	if (strSource == "") return "";
	if (strSource.indexOf(".") < 0) return strSource;
	
	var arraySource = strSource.split(".");
	var retVal = arraySource[0];
	var numVal;
	for (i=1; i<arraySource.length; i++) {
		numVal = parseInt(arraySource[i]).toString();
		if ((numVal != "") && (numVal != "NaN")) return retVal;
		retVal += "." + arraySource[i];
	} // for (i=1; i<arraySource.length; i++)

	return retVal;

} // function getStringRootValue()


function getStringVersion(valSource) {
/**	
	==================================================
	This function will parse a passed in string and 
	return the version (defined as all parts after 
	the text portions of the string, using a 
	period as the delimeter) of the string value.	
	==================================================
*/	
	if (!valSource) return "";
	var strSource = valSource.toString();
	if (strSource == "") return "";
	
	var retVal = "";
	
	if (strSource.indexOf(".") < 0) {
		retVal = parseInt(strSource).toString();
		if ((retVal != "") && (retVal != "NaN")) {
			return strSource;
		} else {
			return "";
		} // if ((retVal != "") && (retVal != "NaN"))
	} // if (strSource.indexOf(".") < 0)
	
	var arraySource = strSource.split(".");
	var numVal;
	retVal = "";
	for (i=0; i<arraySource.length; i++) {
		numVal = parseInt(arraySource[i]).toString();
		
		if ((numVal != "") && (numVal != "NaN")) {
			if (retVal == "") {
				retVal = numVal;
			} else {
				retVal += "." + numVal;
			} // if (retVal == "")
		} // if ((numVal != "") && (numVal != "NaN"))
	} // for (i=1; i<arraySource.length; i++)

	return retVal;

} // function getStringVersion()


function mergeStringArrays(ary1, ary2, delim) {
/**	
	==================================================
	This function will merge 2 string arrays into a 
	single array.  The values will be delimited by 
	the delim parameter.
	==================================================
*/	
	
	if (!ary1) return "";
	if (!ary1[0]) return ary1.toString();
	if ((!ary2) || (!ary2[0])) return ary1;
	
	var delimiter;
	if (!delim) {
		delimiter = "";
	} else {
		delimiter = delim.toString();
	} // if (!delim)
		
			
	
	var retVal = new Array(ary1.length);
	var j = 0;

	for (var i=0; i<ary1.length; i++) {
		retVal[i] = ary1[i].toString();
		if (i<ary2.length) j = i;
		if (ary2[j].toString() != "") retVal[i]+= delimiter + ary2[j];
	} // for (var i=0; i<ary1.length; i++)

	return removeEmpties(retVal);

} // function mergeStringArrays(ary1, ary2, delim)


function popupsEnabled() {
/**	
	==================================================
	This function will check to see if popup windows 
	are allowed.  It returns a true if allowed, and a 
	false otherwise.
	==================================================
*/	
	var popWin = window.open("","popuptest","width=1,height=1,left=1,top=1",true);
	if (popWin) {
		popWin.blur();
		popWin.close();
		window.focus();
		return true;
	} else {
		return false;
	} // if (popWin)

} // function popupsEnabled()


function redirectFail() {
/**	
	==================================================
	This function will redirect the browser to the 
	URL defined by URL_BROWSER_FAILED variable in the 
	script library (browserRequirements.js).
	==================================================
*/

} // function redirectFail()


function removeEmpties(arraySource) {
/**	
	==================================================
	This function remove all empy elments from an 
	array of strings.
	==================================================
*/	
	var retVal = new Array("");
	var added = false;
	for (var i=0; i<arraySource.length; i++) {
		if (arraySource[i].toString() != "") {
			if (added) {
				retVal[retVal.length - 1] = arraySource[i];
			} else {
				retVal[0] = arraySource[i];
				added = true;
			} // if (added)
	
			retVal[retVal.length] = "";
		} // if (arraySource[i].toString() != "")
	} // for (var i=0; i<arraySource.length; i++)
	
	if (added) retVal.length = retVal.length -1;

	return retVal;
	
} // function removeEmpties()


function writeBrowserInfo() {
/**	
	==================================================
	This function write the detected information about 
	the browser to the current location (where the 
	function was called from) of the HTML page or form.
	==================================================
*/

	if (!checkRequirementsExist()) return false;
	
	if (DETECTED_PLUGINS == "") DETECTED_PLUGINS = getPluginInfo();
	
	var infoPlatform = new Array(4);
	var infoBrowser = new Array(8);
	var infoJavascript = new Array(2);
//	var infoJava = new Array(3);  need to wait until java detection applet is created.
	var innerHTML = new Array(5);
	
	var versionUpdates = removeEmpties(NAV_appMinorVersion.split(";")).join("</li><li>");
	versionUpdates = (versionUpdates == "")? "not available":"<ul><li>" + versionUpdates + "</li></ul>";
	
	var userAgent = removeEmpties(NAV_userAgent.split(";")).join("</li><li>");
	userAgent = (userAgent == "")? "not available":"<ul><li>" + userAgent + "</li></ul>";

	var cookieInfo = (is_cookie)? "Enabled":"<font color='#ff0000'>Blocked</font>";
	var popupInfo = (popupsEnabled())? "Allowed":"<font color='#ff0000'>Blocked</font>";
	var javaEnabledInfo = (navigator.javaEnabled())? "Enabled":"<font color='#ff0000'>Disabled</font>";

	infoPlatform[0] = (NAV_platform == "")? "":"Platform: <strong>" + NAV_platform + "</strong>";
	infoPlatform[1] = (NAV_cpuClass == "")? "":"CPU Class: <strong>" + NAV_cpuClass + "</strong>";
	infoPlatform[2] = "Resolution: <strong>" + screen.width + " x " + screen.height + "</strong>";
	var colorDepth = screen.colorDepth;
	if (parseInt(colorDepth).toString() == "NaN") {
		infoPlatform[3] = "Color Depth: <strong>" + screen.colorDepth + "</strong>";
	} else {
		colorCount = parseInt(colorDepth);
		if ((colorCount == 24) || (colorCount == 32) || (colorCount == 64)) {
			infoPlatform[3] = "Color Depth: <strong>" + colorCount + " bit</strong>";
		} else {
			infoPlatform[3] = "Color Depth: <strong>" + colorCount + " colors</strong>";
		} // if ((colorCount == 24) || (colorCount == 32) || (colorCount == 64))
	} // if (parseInt(colorDepth).toString() == "NaN")

	infoPlatform = removeEmpties(infoPlatform);


	infoBrowser[0] = (NAV_appName == "")? "":"Browser: <strong>" + NAV_appName + "</strong>";
	infoBrowser[1] = (NAV_appCodeName == "")? "":"Code Base: <strong>" + NAV_appCodeName + "</strong>";
	infoBrowser[2] = "Version: <strong>" + is_minor + "</strong>";
	infoBrowser[3] = "Version Updates: <strong>" + versionUpdates + "</strong>";
	infoBrowser[4] = "User Agent: <strong>" + userAgent + "</strong>";
	infoBrowser[5] = (NAV_userLanguage == "")? "":"Language: <strong>" + NAV_userLanguage + "</strong>";
	infoBrowser[6] = "Cookies: <strong>" + cookieInfo + "</strong>"
	infoBrowser[7] = "Popup Windows: <strong>" + popupInfo + "</strong>";

	infoBrowser = removeEmpties(infoBrowser);

	infoJavascript[0] = "Javascript: <strong>Enabled</strong>";
	infoJavascript[1] = "Version: <strong>" + JavascriptVersion + "</strong>";

/**   need to wait until java detection applet is created.
	infoJava[0] = "Java: <strong>" + javaEnabledInfo + "</strong>";
	infoJava[1] = "Version: <strong>" + JavaVersion + "</strong>";
	infoJava[2] = "Vendor: <strong>" + JavaVendor + "</strong>";
*/
	var infoJava = "Java: <strong>" + javaEnabledInfo + "</strong>";

	infoPlatform = "<h4 class=currentBrowser>Platform/OS</h4><ul><li>" + infoPlatform.join("</li><li>") + "</li></ul>";
	infoBrowser = "<h4 class=currentBrowser>Browser Information</h4><ul><li>" + infoBrowser.join("</li><li>") + "</li></ul>";
	infoJavascript = "<h4 class=currentBrowser>Javascript Support</h4><ul><li>" + infoJavascript.join("</li><li>") + "</li></ul>";
	infoJava = "<h4 class=currentBrowser>Java Support</h4><ul><li>" + infoJava + "</li></ul>";
	var detectedPlugins = DETECTED_PLUGINS;
	if (detectedPlugins != "") detectedPlugins = "<h4 class=currentBrowser>Detected Plugins</h4><ul><li>" + detectedPlugins.join("</li><li>") + "</li></ul>";

	innerHTML[0] = infoPlatform;
	innerHTML[1] = infoBrowser;
	innerHTML[2] = infoJavascript;
	innerHTML[3] = infoJava;
	innerHTML[4] = detectedPlugins;

	innerHTML = removeEmpties(innerHTML);
	innerHTML = innerHTML.join("");

	/**
	non-MSIE plugin information is generally very long.  
	the next line of code does nothing more than force 
	the plugin information for non-MSIE browsers into a 
	narrowed div, so the requried vs. detected information
	appears side by side.
	*/
	if ((innerHTML != "") && (!is_ie)) innerHTML = "<div style='width:30em; margin: 0 0 0 0; padding:0 0 0 0;'>" + innerHTML + "</div>"

	document.write(innerHTML);
	window.status = "finished function writeBrowserInfo()";
} // function writeBrowserInfo()


function writeRequiredInfo() {
/**	
	==================================================
	This function write the browser requirements, as 
	defined in the browser requirements script library 
	(browserRequirements.js) to the current location 
	(where the function was called from) of the HTML 
	page or form.
	==================================================
*/
	if (!checkRequirementsExist()) return false;
	
	var strTemp = "";
	var aryTemp = "";
	
	// Platform information
	var infoPlatform = new Array(4);
	if (BR_PLATFORM == "") {
		strTemp = "";
	} else {
		strTemp = (BR_PLATFORM.length > 1)? "<ul><li>" + BR_PLATFORM.join("</li><li>") + "</li></ul>":"<strong>" + BR_PLATFORM[0] + "</strong>";
		strTemp = "Platform: " + strTemp;
	} // if (BR_PLATFORM == "")
	infoPlatform[0] = strTemp;

	if (BR_CPU == "") {
		strTemp = "";
	} else {
		strTemp = (BR_CPU.length > 1)? "<ul><li>" + BR_CPU.join("</li><li>") + "</li></ul>":"<strong>" + BR_CPU[0] + "</strong>";
		strTemp = "CPU Class: " + strTemp;
	} // if (BR_CPU == "")
	infoPlatform[1] = strTemp;

	infoPlatform[2] = ((BR_RESOLUTION_WIDTH == 0) && (BR_RESOLUTION_HEIGHT == 0))? "":"Resolution: <strong>" + BR_RESOLUTION_WIDTH + " x " + BR_RESOLUTION_HEIGHT + "</strong>";
	infoPlatform[3] = (BR_COLOR_DEPTH == "")? "":"Color Depth: <strong>" + BR_COLOR_DEPTH + "</strong>";
	infoPlatform = removeEmpties(infoPlatform);
	infoPlatform = (infoPlatform[0] == "")? "":"<h4>Platform/OS</h4><ul><li>" + infoPlatform.join("</li><li>") + "</li></ul>";

	// Browser Information
	var infoBrowser = new Array(3);
	if (BR_BROWSER == "") {
		strTemp = "";
	} else {
		aryTemp = mergeStringArrays(BR_BROWSER, BR_BROWSER_VER, " ver ");
		strTemp = (aryTemp.length > 1)? "<ul><li>" + aryTemp.join("</li><li>") + "</li></ul>":"<strong>" + aryTemp[0] + "</strong>";
		strTemp = "Browser: " + strTemp;
	} // if (BR_PLATFORM == "")
	infoBrowser[0] = strTemp;
	infoBrowser[1] = (BR_COOKIES)? "Cookies: <strong>Enabled</strong>":"";
	infoBrowser[2] = (BR_POPUPS_ENABLED)? "Popup Windows: <strong>Enabled</strong>":"";
	infoBrowser = removeEmpties(infoBrowser);
	infoBrowser = (infoBrowser[0] == "")? "":"<h4>Browser Information</h4><ul><li>" + infoBrowser.join("</li><li>") + "</li></ul>";
	
	// Javascript Information
	var infoJavascript = new Array(2);
	if (BR_JAVASCRIPT) {
		infoJavascript[0] = "Javascript: <strong>Enabled</strong>";
		infoJavascript[1] = (BR_JAVASCRIPT_VER == "")? "":"Version: <strong>" + BR_JAVASCRIPT_VER + "</strong>";
	} else {
		infoJavascript[0] = "";
		infoJavascript[1] = "";
	} // if (BR_JAVASCRIPT)
	infoJavascript = removeEmpties(infoJavascript);
	infoJavascript = (infoJavascript[0] == "")? "":"<h4>Javascript Support</h4><ul><li>" + infoJavascript.join("</li><li>") + "</li></ul>";
	
	// Java Information
	var infoJava = (BR_JAVA)? "<h4>Java Support</h4><ul><li>Java: <strong>Enabled</strong></li></ul>":"";

	// ActiveX Information
	var infoActiveX = (BR_ACTIVEX)? "<h4>ActiveX Support</h4><ul><li>ActiveX: <strong>Enabled</strong></li></ul>":"";

	// VBScript Information
	var infoVBscript = (BR_VBSCRIPT)? "<h4>VBScript Support</h4><ul><li>VBScript: <strong>Enabled</strong></li></ul>":"";

	// Plugin Information
	var infoPlugin = (BR_PLUGIN == "")? "":mergeStringArrays(BR_PLUGIN, BR_PLUGIN_VER, " version/release ");
	infoPlugin = (infoPlugin[0] == "")? "":"<h4>Required Plugins</h4><ul><li>" + infoPlugin.join("</li><li>") + "</li></ul>";
	
	// ActiveX Plugin Information
	var infoPluginAX = (BR_PLUGIN_AX == "")? "":mergeStringArrays(BR_PLUGIN_AX, BR_PLUGIN_VER_AX, " version/release ");
	infoPluginAX = (infoPluginAX[0] == "")? "":"<h4>ActiveX Plugins</h4><ul><li>" + infoPluginAX.join("</li><li>") + "</li></ul>";
	
	var innerHTML = new Array(8);
	innerHTML[0] = infoPlatform;
	innerHTML[1] = infoBrowser;
	innerHTML[2] = infoJavascript;
	innerHTML[3] = infoJava;
	innerHTML[4] = infoActiveX;
	innerHTML[5] = infoVBscript;
	innerHTML[6] = infoPlugin;
	innerHTML[7] = infoPluginAX;

	innerHTML = removeEmpties(innerHTML);
	document.write(innerHTML.join(""));
	return true;

} // function writeRequiredInfo()

/**	END of browserInfo-SOURCE.js  **/




var query = "";
var exitURL = "";

function addParam(name, value){
  if (query != "")
    query += "&";    
    
  query = query + encodeURIComponent(name) + "=" + encodeURIComponent(value);
  //return query + encodeURIComponent(name) + "=" + encodeURIComponent(value)
}

//alert("<%=HostName %>");
/* capture plugins */
/*
var DETECTED_PLUGINS = "";
if (checkRequirementsExist()){
  //alert("requirments exist");
  if (DETECTED_PLUGINS == "") 
    DETECTED_PLUGINS = getPluginInfo();    
    //addParam("plugins", DETECTED_PLUGINS);
  //document.writeln(DETECTED_PLUGINS.join("&"));
 // query = DETECTED_PLUGINS.join("&");  //Amy temply removed for phase 1 of loading to DB 05/15/2009
  //document.writeln(query);
}*/

var oRequest;
try {
  oRequest = new XMLHttpRequest();
}
catch (e) {
  try {
    oRequest = new ActiveXObject("Msxml2.XMLHTTP");
  }
  catch (e) {
    try {
      oRequest = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (e) {
      throw new Error("XMLHttpRequest not supported");
    }
  }
}

/*
if (window.XMLHttpRequest)     // Object of the current windows
{ 
  try{	
    oRequest = new XMLHttpRequest();     // Firefox, Safari, ...
    alert("XMLHttpRequest Object created");
  }catch(err){
    throw new Error("XMLHttpRequest Denied in FireFox");
  }
} 

if (typeof XMLHttpRequest == "undefined" && window.ActiveXObject) {
  //function XMLHttpRequest(){
    var arrSignatures = ["MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
    for (var i=0; i<arrSignatures.length; i++){
      try {
        oRequest = new ActiveXObject(arrSignatures[i]);
        alert(arrSignatures[i]);
        break;
      }catch(oError){
        //ignore
      }
    }
    //throw new Error("MSXML is not installed on your system");
  //}
}*/



function submitData(query){      
  var destUrl = "https://ut.morningstar.com/webtracking/default.aspx";
  //alert(destUrl + "?" + query);
  var trackingImage = new Image(1,1);
  trackingImage.src = destUrl+"?"+query;
  trackingImage.onload = function(){}
  //try{
    //oRequest.open("GET", destUrl, true);
  /*}catch(error){  	
    alert("oRequest open failed");	
    throw new Error();
  }/
  
  alert("oRequest opened");
  oRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  oRequest.setRequestHeader("Content-length", query.length);
  oRequest.setRequestHeader("Connection", "close");  
  oRequest.send(query);      */
}


var x = navigator;

addParam("appcodename", x.appCodeName);
addParam("appminorversion", x.appMinorVersion);
addParam("appname", x.appName);
addParam("appversion", x.appVersion);
addParam("cookieenabled", x.cookieEnabled);
addParam("cpuclass", x.cpuClass)
addParam("online", x.onLine)
addParam("platform", x.platform)
addParam("useragent", x.userAgent)
addParam("blanguage", x.language)
addParam("slanguage", x.systemLanguage)
addParam("ulanguage", x.userLanguage)
addParam("javaenabled", x.javaEnabled())


/*
document.write("<b>Screen resolution:</b> ")
document.write(screen.width + "*" + screen.height)*/
addParam("PixelDepth", screen.pixelDepth);
addParam("ScreenWidth", screen.width);
addParam("ScreenHeight", screen.height);
/*
document.write("<br />")
document.write("<b>Available view area:</b> ")
document.write(screen.availWidth + "*" + screen.availHeight)
document.write("<br />")
document.write("<b>Color depth:</b> ")
document.write(screen.colorDepth)
document.write("<br />")
document.write("<b>Buffer depth:</b> ")
document.write(screen.bufferDepth)
document.write("<br />")
document.write("<b>DeviceXDPI:</b> ")
document.write(screen.deviceXDPI)
document.write("<br />")
document.write("<b>DeviceYDPI:</b> ")
document.write(screen.deviceYDPI)
document.write("<br />")
document.write("<b>LogicalXDPI:</b> ")
document.write(screen.logicalXDPI)
document.write("<br />")
document.write("<b>LogicalYDPI:</b> ")
document.write(screen.logicalYDPI)
document.write("<br />")
document.write("<b>FontSmoothingEnabled:</b> ")
document.write(screen.fontSmoothingEnabled)
document.write("<br />")
document.write("<b>PixelDepth:</b> ")
document.write(screen.pixelDepth)
document.write("<br />")
document.write("<b>UpdateInterval:</b> ")
document.write(screen.updateInterval)
document.write("<br />") 


if (navigator.appName=="Netscape")
  document.write("<b>Length:</b> " + history.length);
else 
  document.write("<b>Length:</b> " + (history.length+1));*/
  
//document.write("<br />")
addParam("historylength", history.length);

//document.write("<b>Host Site:</b> "+location.host);
//document.write("<br />")
addParam("hostsite", location.host);
//document.write("<b>Host Name:</b> "+location.hostname);
//document.write("<br />")
//addParam("hostname", location.hostname);
//document.write("<b>Complete URL:</b> "+location.href);
//document.write("<br />")
addParam("completeurl", location.href);
//document.write("<b>Path Name:</b> "+location.pathname);
//document.write("<br />")
addParam("path", location.pathname);
//document.write("<b>Port:</b> "+location.port);
//document.write("<br />")
addParam("port", location.port);
//document.write("<b>Query String:</b> "+location.search);
//document.write("<br />")
addParam("querystring", location.search);
//document.write("<b>Page Domain:</b> "+document.domain);
//document.write("<br />")
addParam("pagedomain", document.domain);
//document.write("<b>Page Referrer:</b> "+document.referrer);
//document.write("<br />")
addParam("referrer", document.referrer);
//document.write("<b>Page Title:</b> "+document.title.toLowerCase());
//document.write("<br />")
addParam("pagetitle", document.title);
//document.write("<b>Page URL:</b> "+document.URL);
//document.write("<br />")
addParam("pageurl", document.URL);


var d = new Date()
/*
document.write("<b>GMT Time of vist:</b> "+d.toGMTString());
document.write("<br />")
document.write("<b>Local Time of vist:</b> "+d.toLocaleString());
document.write("<br />") */


onload = function() {   
  addParam("localtime", d.toUTCString());
  var links = document.links;
  //alert(links.length);
  for (var i=0; i<links.length; i++) {                 
    var dl = links[i];    
    //addEvent(dl, 'click', function(){exitURL=this.href; alert(exitURL);});    
    
    dl.onmousedown = function(){      
      exitURL = this.href;     
      dl = null;
    };
  }
};

onunload = function() {
//alert("unload");
  addParam("exiturl", exitURL);  
  d = new Date()
  addParam("exittime", d.toUTCString());
  submitData(query);
};

function addEvent(obj, type, fn) 
{
    if ( obj.attachEvent ) 
    {
      obj.attachEvent('on'+type, fn);
      //alert("IE");
    } 
    else 
    {
      obj.addEventListener(type, fn, false );      
    }
}

function catchClick(){
  exitURL = this.href;       
  alert(exitURL);
}











