
function Caption1() {
  //     JAVASCRIPT INCLUDE FILE - (c) J R Stockton  >= 2008-01-17
  //             http://www.merlyn.demon.co.uk/include1.js
  //       Routines may be copied, but URL must not be linked to.
  }

var Inc1T=0

var Site = "Merlyn", Owner = "J R Stockton"

// In lieu of DynWrite :

function Wryt(ID, S) { document.getElementById(ID).innerHTML = S }

// General Utilities :

function LS(n) { return String(n).replace(/\b(\d)\b/g, '0$1') }

function Lz(n) { return (n>=10||n<0?"":"0") + n }  // Was LZ
//function LZ(n) { return (n<10&&n>=0?"0":"") + n } // NaN better
// Names transposed 2008-01-08.
// Second is better with NaN.  But undefined, null?
function LZ(n) { return (n!=null&&n<10&&n>=0?"0":"") + n }
// best, see js-tests

//function LZZ(n) { return n<0||n>=100?""+n:"0"+LZ(n) } // NaN?
function LZZ(n) { return (n!=null&&n<100&&n>=0?"0"+LZ(n):""+n) }

function lz(n) { var t = n+"" ; return t.length==1 ? "0"+t : t } // slower?


function TrimS() { // used for String.prototype.trim  \u00A0?
  return (this.toString() ?
    this.toString().replace(/\s+$|^\s+/g, "") : "") }
String.prototype.trim = TrimS

function Space(N) { var S = "" ; while (N--) S += " " ; return S }

function T8(Str) { // Expands Tab to spaces up to Column 8N (EjH)
  var Lines = Str.split("\n"), L, Parts, Row, P, S8 = "        "
  for (L=0 ; L < Lines.length ; L++) { Parts = Lines[L].split("\t")
    Row = "" ; P = 0 ; while (1) { Row += Parts[P]
      if (++P==Parts.length) break
      Row += S8.substring(Row.length%8) /* 1..8 spaces */ }
    Lines[L] = Row }
  return Lines.join("\n") }


function NameFunc(Fn) { // Fn is a function; return its name
// var A = Fn.toString().match(/^function\s+(\w+)\(/)
   var A = Fn.toString().match(/function\s+(\w+)\(/) // for Opera LF
  return A ? A[1] : "anon" }



function DummyF(X) { return X /* Dummy */ }


function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }

function Sgnd(X) { return Sign(X) + Math.abs(X) }

function PrfxTo(S, L, C) { S += ""
  if (C.length>0) while (S.length<L) S = C + S ; return S }

function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
  while (S.length<L) S = " " + S ; return S }

function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
  var St = String(Math.round(X*Math.pow(10, N)))
  if (/\D/.test(St)) return SpcsTo(X, M+N+1) // cannot cope
  St = PrfxTo(St, M+N, "0") ; var J = St.length - N
  return St.substring(0, J) + "." + St.substring(J) }

function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }

function StrT(X, M, N) { return SpcsTo(StrU(X, 1, N), M+N+2) }

function StrW(X, M, N) { return SpcsTo(StrS(X, 1, N), M+N+2) }

if (!Number.prototype.toFixed) {
  Number.prototype.toFixed = // JL
    new Function("X",
      "  /* toFixed */ if (!X) X=0\n  return StrS(this, 1, X)") }


function Expo(E) { return "e" + (E<0?'-':'+') + LZ(Math.abs(E)) }

function GetSEM(X) { // returns Sign Mantissa Exponent (base 10)
  var U, Obj = { S : Sign(X), E : 0, M : X==U?U:Math.abs(X) }
  with (Obj) { if (M==0 || !isFinite(M)) return Obj
    while (M >= 10) { E++ ; M /= 10 }
    while (M < 1.0) { E-- ; M *= 10 } }
  return Obj }

function NumDecSigFig(X, N) { var U // returns a Number
  if (X==0||X==U) return X
  with (GetSEM(X)) var P = Math.pow(10, N-E-1)
  return Math.round(X*P)/P }

function StrSigFigFxd(X, N) { var U // ?? for 2 <= N <= 16 ??
  if (X==U) return " " + U
  with (GetSEM(X)) { var P, Q
    P = Math.pow(10, N-E-1) ; Q = Math.round(Math.abs(X)*P)/P
    return S + StrU(Q, 1, Math.max(1, N-E-1)) } }

function StrSigFigExp(X, N) { // ?? for 2 <= N <= 16 ??
  with (GetSEM(X))
    return S + StrU(M, 1, N-1) + (isFinite(M) ? Expo(E) : " ") }


function SigFigSet() { // sets globals
  SigFigNum = NumDecSigFig
  SigFigFxd = StrSigFigFxd
  SigFigExp = StrSigFigExp }

SigFigSet()


function SigFigAre() { var IzN = "\t"
  document.write( "Across this site,\n",
    "Name Used\tThe Function\tReturn".italics(),
    "\nSigFigNum", IzN, NameFunc(SigFigNum), "\tNumber",
    "\nSigFigFxd", IzN, NameFunc(SigFigFxd), "\tString '#.#'",
    "\nSigFigExp", IzN, NameFunc(SigFigExp), "\tString '#.#e#'") }



function Div(X, Y) { return Math.floor(X/Y) /* full range */ }

function Mod(X, Y) { return X - Math.floor(X/Y)*Y }


function userIn(Ctrl) { // input for numbers and expressions
  return +eval(Ctrl.value) }

function GetNum(Ctrl) { // input for expressions, allows spaces
  return +eval(Ctrl.value.replace(/[ ]/g, '')) }

function RadBtns(Rbtn, Arr) { var Q, J=0 // Read RadioButtons
  while (Q=Rbtn[J]) { if (Q.checked) return Arr[J] ; J++ } }



// After LRN :

var BoxW = 69

function SafeHTML(S) {
  return S.split("&").join("&amp;").split("<").join("&lt;").
    split(">").join("&gt;") } // IAS

function Depikt(X, Y, S, Hue) { // String S is shown in a box
  document.writeln(
    "<p align=center>\n<textarea readonly wrap=virtual",
    " style=\"border: double thick ", Hue || "black", " ;\"",
    " cols=", X, " rows=", Y, ">\n", SafeHTML(S),
    "<\/textarea><\/p>") }

function ShoTrim(St) {
  var match = /\S([\s\S]*\S)*/.exec(St)
  return match ? match[0] : " eh? " }

function ShoLinCnt(St, Mx) { // counts lines when wrapped at     lineLength Mx
  var Ch, j = xj = CR = NL = 0, Len = St.length, X = 1
  while (j<Len) { Ch = St.charCodeAt(j++)
    if (Ch!=10 && Ch!=13) continue
    if (Ch==10) NL++
    if (Ch==13) CR++
    X += Math.max(Math.floor((j-xj-2)/Mx), 0) ; xj = j }
  // In principle, not quite right, as MSIE wraps at whitespace
  return X + Math.max(NL, CR) }

function ShoGen(A) { // see ShoFFF
  var St = "", Len = A.length, j = 0, Vis = 1, Arg, LC = 0
  while (Len>0) {
    Arg = A[j++]
    if (!Arg) { Vis = 0 ; continue }
    if (Arg.join) Arg =
      "[\n" + Arg.join("\n,\n") + "\n]" // ?? 2006-10-29 ??
    Arg = ShoTrim(Arg.toString())
    St += Arg ; if (Vis) LC += ShoLinCnt(Arg, BoxW)
    if (j==Len) break
    St += "\n\n" ; LC += Vis }
  return {Str:St, Cnt:LC} }

function ShoFFF() {
  // Show code of ArgListed functions, strings; 0 ends visibles
  with (ShoGen(arguments)) Depikt(BoxW, Cnt, Str, "lightgreen") }

function ShoCod(Fn) { // N.B. Fn() should be called externally
  var St = ShoTrim(Fn.toString())
  Depikt(BoxW, ShoLinCnt(St, BoxW), St, "red") }

function ShoOut(Fn) { // N.B. this calls Fn(), shows output in PRE
  document.writeln("<pre class=OUT>")
  Fn()
  document.writeln("<\/pre>") }

function ShoDoo(Fn) { // N.B. this calls  Fn() - ADD show others ?
  ShoCod(Fn) ; Fn() /* no visible output expected */ }

function ShoDuu(Fn) { // N.B. this calls  Fn() - ADD show others ?
  ShoCod(Fn) ; ShoOut(Fn) /* visible output expected */ }

// .


function eIVSF() {
  Depikt(47, 2, "  For the code, view the source of this page,\n" +
                "     and any include files which it calls.") }


var BID = 0, BoxX = 70


function PopThis(btn) { // Executed by PopBtn buttons
  var Obj = ShoGen(btn.btnargs)
  // Height and Width values need improving
  var Wndw = window.open("", "X"+ +new Date(),
    "height=" + (16*Obj.Cnt+30) + ",width=" + (8*BoxX+20) +
    ",resizable,scrollbars")
  Wndw.document.write("<pre>\n", SafeHTML(Obj.Str), "\n<\/pre>")
  Wndw.document.close() /* DU */ }

function PopBtn() { // Call with ArgList to generate button
  var I = 'JJ' + BID++ // var BID = 0 precedes
  document.write("<form name=", I, ">",
    "<input type=button name=N value='Pop Code Up'",
    " onClick='PopThis(this)'><\/form>")
  document.close() // DU // ??
  document.forms[I].elements["N"].btnargs = arguments }


function PageString(Site, Title, Owner, Body) { // OK by TIDY
  return '<!DOCTYPE HTML PUBLIC' +
    ' "-//W3C//DTD HTML 4.01 Transitional//EN"\n' +
    ' "http://www.w3.org/TR/html4/strict.dtd">\n' +
    '<HTML lang="en">\n<HEAD>\n' +
    '<META HTTP-EQUIV="Content-Type"' +
    ' CONTENT="text/html; charset=ISO-8859-1">\n' +
    '<TITLE>' + Site + ' -\n ' +
    Title + '\n  - ' + Owner + '<\/TITLE>\n<\/HEAD>\n<BODY>\n\n' +
    Body + "\n\n<hr>\n<\/BODY>\n</\HTML>\n"}

function NewPage(Title, Body) { // Same window, new content
  document.writeln(PageString(Site, Title, Owner, Body))
  document.close() } // 20070212 for RobG       *********

function FreshPage(Title, Body) { // New window and content
  var Wndw = window.open("", "X"+new Date().getTime())
  var Site = "Merlyn", Owner = "J R Stockton" // not inherited
  Wndw.document.writeln(PageString(Site, Title, Owner, Body))
  Wndw.document.close() }




function Cuffs() { var ThisPage, ThisSite, J, DLJ, HREF
  ThisPage = location.href.replace(/#.*/, "")
  ThisSite = location.protocol + "//" + location.hostname + "/"
  J = document.links.length ; while (J--) {
    DLJ = document.links[J] ;
    if (typeof DLJ.href != "string") continue // RikW c.l.j 20070719
    HREF = DLJ.href // HREF = String(HREF)
    if (HREF.indexOf(ThisPage) == 0) DLJ.title = "." ;
      else if (HREF.indexOf(ThisSite) == 0) DLJ.title = "+" ;
      else if (HREF.indexOf("http://") == 0) DLJ.title = "#" ;
      else DLJ.title = "*" } }



function getXMLHTTPobj() {
  // adapted from http://jibbering.com/2002/4/httprequest.html
  var XMLhttp = false
  /*@cc_on @*/
  /*@if (@_jscript_version >= 5)
  // JScript gives us Conditional compilation, we can cope with old
  // IE versions and security blocked creation of the objects.
    try { XMLhttp = new ActiveXObject("Msxml2.XMLHTTP") }
    catch (e) {
      try { XMLhttp = new ActiveXObject("Microsoft.XMLHTTP") }
      catch (E) { XMLhttp = false }
      }
  @end @*/
  if (!XMLhttp && typeof XMLHttpRequest!='undefined') {
    try { XMLhttp = new XMLHttpRequest() }
    catch (e) { XMLhttp = false }
    }
  if (!XMLhttp && window.createRequest) {
    try { XMLhttp = window.createRequest() }
    catch (e) { XMLhttp = false }
    }
  return XMLhttp }


function ReFormatsCode() { var Bad // Warns where needed
  if (Bad = !/\*/.test(function(){/**/}))
  document.writeln("<div class=CAN>This browser reformats ",
     "red/green boxed functions,<br>omitting comment.<\/div>")
  return Bad }


var Inc1B=0 // end.


