  // This Script calculates the Surface Lifted Index from the given
  // Surface Temperature [°C], Surface Dewpoint [°C] and the 500 mB Temperature [°C].
  // Feel free to copy this code into your script. I got it from the following site:
  // http://cmrp.ou.edu/~bfiedler/code2html/

  function f_esi(p, t)
  {
    var satfia = 1.0003;
    var satfib = 4.18E-8;
    var sateia = 611.15;
    var sateib = 22.452;
    var sateic = 0.6;
    var f;

    f = satfia + satfib * p;
    return (f * sateia * Math.exp(sateib * (t - 273.15) / (t - sateic)));
  }
  
  function f_esl(p, t)
  {
    var satfwa = 1.0007;
    var satfwb = 3.46E-8;
    var satewa = 611.21;
    var satewb = 17.502;
    var satewc = 32.18;
    var f;

    f = satfwa + satfwb * p;
    return (f * satewa * Math.exp(satewb * (t - 273.15) / (t - satewc)));
  }
  
  function f_es(p, t)
  {
    if (t >= 273.15)     
    {
      return (f_esl(p, t));  // for water
    }
    else
    {                   
      return (f_esi(p, t));  // for ice
    }
  }
  
  function f_mrsat(p, t)
  {
    rd = 287.0;  // Gas constant for dry air
    rv = 461.0;  // Gas constant for water vapor
    var fes;
    var rddrv;
    
    fes = f_es(p, t);
    rddrv = rd / rv;
    return (rddrv * fes / (p - fes));
  }
  
  function tsa_fast(os, p)
  {
    var a;
    var b = 2651.8986;
    var d;
    var tq;
    var tq_last = 0;
    var x;
    var x_last;
    var slope;
    var delta;
    var ad;
    var i;
      
    a = os + 273.15;

    // Above 200 mb figure all the moisture is wrung-out, so
    // the temperature is that which has potential temp of theta-e.
    // Otherwise iterate to find combo of moisture and temp corresponding to theta-e.
    if (p < 200)
    {
      tq = a * Math.pow(p / 1000, 0.286);
    }
    else
    {
      d = 120; 
      tq = 253.15;  
      x = 0;
      for (i = 1; i <= 25; i++)
      {
        d = 0.5 * d;
        x_last = x;
        x = a * Math.exp(-b * f_mrsat(p * 100, tq) / tq) - tq * Math.pow(1000 / p, 0.286);
        if (Math.abs(x) < 1E-3)
        {
          continue;
        }
        if ((x_last * x) < 0)
        {
          slope = (x - x_last) / (tq - tq_last);
          delta = -x / slope;
          ad = Math.min(Math.abs(delta), d);
          tq_last = tq;
          if (delta >= 0)
          {
            tq = tq + Math.abs(ad);
          }
          else
          {
            tq = tq - Math.abs(ad);
          }
        }
        else
        {
          tq_last = tq;
          if (x >= 0)
          {
            tq = tq + Math.abs(d);
          }
          else
          {
            tq = tq - Math.abs(d);
          }
        }
      }
    }
    return (tq - 273.15);
  }
  
  function esat(t)
  {
    // g.s. stipanuk     1973           original version.
    // reference stipanuk paper entitled:
    //      "algorithms for generating a skew-t, log p
    //      diagram and computing selected meteorological quantities."
    //      atmospheric sciences laboratory u.s. army electronics command
    //      white sands missile range, new mexico 88002 33 pages
    //    baker, schlatter  17-may-1982

    var tk; 
    var p1; 
    var p2; 
    var c1;

    // This function returns the saturation vapor pressure over
    // water [mB] given the temperature [°C].
    // The algorithm is due to nordquist, w.s.,1973: "numerical approxima-
    // tions of selected meteorlolgical parameters for cloud physics prob-
    // lems," ecom-5475, atmospheric sciences laboratory, u.s. army
    // electronics command, white sands missile range, new mexico 88002.
    tk = t + 273.15;
    p1 = 11.344 - (0.0303998 * tk);
    p2 = 3.49149 - (1302.8844 / tk);
    c1 = 23.832241 - (5.02808 * (Math.log(tk) / Math.log(10)));
    return(Math.pow(10, (c1 - 1.3816E-7 * Math.pow(10, p1) + 8.1328E-3 * Math.pow(10, p2) - 2949.076 / tk)));
  }
  
  function mr(t, p)
  {
    // g.s. stipanuk     1973              original version.
    // reference stipanuk paper entitled:
    //      "algorithms for generating a skew-t, log p
    //      diagram and computing selected meteorological quantities."
    //      atmospheric sciences laboratory u.s. army electronics command
    //      white sands missile range, new mexico 88002 33 pages
    // baker, schlatter  17-may-1982

    var x;

    // This function returns the mixing ratio grams of water vapor per
    // kilogram of dry air [g/kg] given the dew point [°C] and pressure
    // [mB]. If the temperture  is input instead of the
    // dew point, then saturation mixing ratio [g/kg] is returned.
    // the formula is found in most meteorological texts.
    x = esat(t);
    return (622 * x / (p - x));
  }
  
  function o(t, p)
  {
    // g.s. stipanuk     1973          original version.
    // reference stipanuk paper entitled:
    //      "algorithms for generating a skew-t, log p
    //      diagram and computing selected meteorological quantities."
    //      atmospheric sciences laboratory u.s. army electronics command
    //      white sands missile range, new mexico 88002 33 pages
    // baker, schlatter  17-may-1982

    var tk;
    var ok;

    // This function returns potential temperature [°C] given
    // temperature t [°C] and pressure p [mB] by solving the poisson equation.

    tk = t + 273.15;
    ok = tk * Math.pow((1000 / p), 0.286);
    return (ok - 273.15);
  }
  
  function tmr(w, p)
  {
    // g.s. stipanuk     1973           original version.
    // reference stipanuk paper entitled:
    //      "algorithms for generating a skew-t, log p
    //      diagram and computing selected meteorological quantities."
    //      atmospheric sciences laboratory u.s. army electronics command
    //      white sands missile range, new mexico 88002 33 pages
    // baker, schlatter  17-may-1982

    var c1 = 0.0498646455;
    var c2 = 2.4082965;
    var c3 = 7.07475;
    var c4 = 38.9114;
    var c5 = 0.0915;
    var c6 = 1.2035;
    var x
    var tmrk

    // This function returns the temperature [°C] on a mixing
    // ratio line w [g/kg] at pressure p [mB]. The formula is given in
    // table 1 on page 7 of stipanuk (1973).

    x = Math.log(w * p / (622 + w)) / Math.log(10);
    tmrk = Math.pow(10, (c1 * x + c2)) - c3 + c4 * Math.pow(Math.pow(10, (c5 * x)) - c6, 2);
    return (tmrk - 273.15);
  }
  
  function os(t, p)
  {
    //    g.s. stipanuk     1973          original version.
    //    reference stipanuk paper entitled:
    //         "algorithms for generating a skew-t, log p
    //         diagram and computing selected meteorological quantities."
    //         atmospheric sciences laboratory u.s. army electronics command
    //         white sands missile range, new mexico 88002 33 pages
    //    baker, schlatter  17-may-1982

    //   This function returns the equivalent potential temperature os [°C]
    //   for a parcel of air saturated at temperature t [°C]
    //   and pressure p [mB].

    //   b is an empirical constant approximately equal to the latent heat
    //   of vaporization for water divided by the specific heat at constant
    //   pressure for dry air.
    
    var b = 2.6518986;
    var tk;
    var osk;

    tk = t + 273.15;
    osk = tk * Math.pow(1000 / p, 0.286) * Math.exp(b * mr(t, p) / tk);
    return (osk - 273.15);
  }
  
  function tda(o, p)
  {
    // g.s. stipanuk     1973           original version.
    // reference stipanuk paper entitled:
    //      "algorithms for generating a skew-t, log p
    //      diagram and computing selected meteorological quantities."
    //      atmospheric sciences laboratory u.s. army electronics command
    //      white sands missile range, new mexico 88002 33 pages
    // baker, schlatter  17-may-1982

    var ok;
    var tdak;

    // This function returns the temperature tda [°C] on a dry adiabat
    // at pressure p [mB]. The dry adiabat is given by
    // potential temperature o [°C]. The computation is based on
    // poisson's equation.

    ok = o + 273.15;
    tdak = ok * Math.pow(p * 0.001, 0.286);  
    return (tdak - 273.15);
  }
  
  function tsa(os, p)
  {
    // g.s. stipanuk     1973           original version.
    // reference stipanuk paper entitled:
    //      "algorithms for generating a skew-t, log p
    //      diagram and computing selected meteorological quantities."
    //      atmospheric sciences laboratory u.s. army electronics command
    //      white sands missile range, new mexico 88002 33 pages
    // baker, schlatter  17-may-1982

    var b = 2.6518986;   
    var i;
    var a; 
    var tq; 
    var d; 
    var tqk; 
    var x;

    // This function returns the temperature tsa [°C] on a saturation
    // adiabat at pressure p [mB]. os is the equivalent potential
    // temperature of the parcel [°C].
    // b is an empirical constant approximately equal to 0.001 of the latent
    // heat of vaporization for water divided by the specific heat at constant
    // pressure for dry air.

    a = os + 273.15;
    // tq is the first guess for tsa.
    tq = 253.15;
    // d is an initial value used in the iteration below.
    d = 120;
    // Iterate to obtain sufficient accuracy....see table 1, p.8
    // of stipanuk (1973) for equation used in iteration.
    for (i = 1; i <= 12; i++)
    {
      tqk = tq - 273.15;
      d = d / 2;
      x = a * Math.exp(-b * mr(tqk, p) / tq) - tq * Math.pow(1000 / p, 0.286);
      if (Math.abs(x) < 1E-7)
      {
        continue;
      }
      if (x >= 0)
      {
        tq = tq + Math.abs(d);
      }
      else
      {
        tq = tq - Math.abs(d);
      }
    }
    return (tq - 273.15);
  }
  
  function tw(t, td, p)
  {
    // g.s. stipanuk     1973           original version.
    // reference stipanuk paper entitled:
    //      "algorithms for generating a skew-t, log p
    //      diagram and computing selected meteorological quantities."
    //      atmospheric sciences laboratory u.s. army electronics command
    //      white sands missile range, new mexico 88002 33 pages
    // baker, schlatter  17-may-1982

    var i;
    var px; 
    var aw; 
    var ao; 
    var x; 
    var ti; 
    var aos;

    // This function returns the wet-bulb temperature tw [°C]
    // given the temperature t [°C], dew point td [°C]
    // and pressure p [mB].  See p.13 in stipanuk (1973), referenced
    // above, for a description of the technique.

    // determine the mixing ratio line thru td and p.
    aw = mr(td, p);  // Mixing Ratio (W [g/kg])
    // determine the dry adiabat thru t and p.
    ao = o(t, p);  // THETA [°C]
    px = p;
    // Iterate to locate pressure px at the intersection of the two
    // curves. px has been set to p for the initial guess.
    for (i = 1; i <= 10; i++)
    {
      x = 0.02 * (tmr(aw, px) - tda(ao, px));
      if (Math.abs(x) < 0.01)
      {
        break;
      }
      px = px * Math.pow(2, x);
    }
    
    // Find the temperature on the dry adiabat ao at pressure px.
    ti = tda(ao, px);
    
    // The intersection has been located...now, find a saturation
    // adiabat thru this point. Function os returns the equivalent
    // potential temperature [°C] of a parcel saturated at temperature
    // ti and pressure px.
    aos = os(ti, px);   // THETA-E [°C]
    
    // Function tsa returns the wet-bulb temperature [°C] of a parcel at
    // pressure p whose equivalent potential temperature is aos.
    return (tsa(aos, p));
  }
  
  function oe(t, td, p)
  {
    // g.s. stipanuk     1973          original version.
    // reference stipanuk paper entitled:
    //      "algorithms for generating a skew-t, log p
    //      diagram and computing selected meteorological quantities."
    //      atmospheric sciences laboratory u.s. army electronics command
    //      white sands missile range, new mexico 88002 33 pages
    // baker, schlatter  17-may-1982

    var atw;

    // This function returns equivalent potential temperature oe [°C]
    // of a parcel of air given its temperature t [°C], dew point
    // td [°C] and pressure p [mB].

    // Find the wet bulb temperature of the parcel.
    atw = tw(t, td, p);  // WETB [°C]
    
    // Find the equivalent potential temperature.
    return (os(atw, p));  // THETA-E [°C]
  }
  
  function runden(x) 
  {
    // der Eingabewert wird gerundet und in einen String umgewandelt:
    var k = (Math.round(x * 100) / 100).toString();

    // bei glatten Werten wird .00 angehängt:
    k += (k.indexOf('.') == -1)? '.00' : '00';

    // fehlende führende Nullen werden aufgespürt und ggf. eingesetzt,
    // Punkte werden durch Komata ersetzt:
    var p = k.indexOf('.'), m = k.indexOf('-.');
    var f = (p == 0 || m == 0)? '0.' : '.';

    // der Rückgabewert wird zusammengesetzt:
    return k.substring(0, p) + f + k.substring(p + 1, p + 3);
  }
  
  function calcsli(obj)
  {
    var t = parseFloat(obj.tSfc.value);
    var td = parseFloat(obj.tdSfc.value);
    var p = parseFloat(obj.pSfc.value);
    var t500 = parseFloat(obj.t500.value);
    var thepcl;
    var par500;
    thepcl = oe(t, td, p);           // THETA-E [°C]
    par500 = tsa_fast(thepcl, 500);  // Lifted Parcel Temperature at 500 mB [°C]
    obj.sli.value = runden(t500 - par500);
  }
  
  function clearforms(obj)
  {
    obj.tSfc.value = "";
    obj.tdSfc.value = "";
    obj.pSfc.value = "";
    obj.t500.value = "";
    obj.sli.value = "";
  }