本館粉絲專頁

使用者:Digipunk/SC/func.js:修訂版本之間的差異

分享此網頁到Facebook
分享此網頁到Plurk
分享此網頁到百度搜藏
分享此網頁到Twitter
分享此網頁到Del.icio.us
台灣棒球維基館
跳轉到: 導覽搜尋
第593行: 第593行:
 
           } else {
 
           } else {
 
             var tok = a.gb;
 
             var tok = a.gb;
             if (GRP[tok].length == 2) {  // 只有這兩隊,則比較勝負關係
+
             if (GRP[tok].length == 2 && a.ctab[b.ord]) {  // 只有這兩隊,則比較勝負關係
 
               switch (a.ctab[b.ord].substr(0, 1)) {
 
               switch (a.ctab[b.ord].substr(0, 1)) {
 
               case '○':
 
               case '○':

2019年12月9日 (一) 12:21的修訂版本

//--------------------------------------------------
// SC (schedule) related
//--------------------------------------------------
function DGPKJS_SC() {
  // timezone conversion
  var elmts = document.getElementsByClassName('__DGPK_TZ_BTN__');
  for (var i = elmts.length - 1; i >= 0; i--) {
    elmts[i].addEventListener("click", __dgpk_tz_conv, false);
    elmts[i].title = '當地時間';
    elmts[i].className = 'DGPK-tz-btn';
  }
 
  //---------------------------------------------------------------
  // DGPK-RNK-AUTO
  //  [2019-12-04] auto 版
  //  [2019-12-05] 擴充到 non-auto 版,使用相同 class 與 func(雖然對 non-auto 而言有點混淆,但流程幾乎相同,除了自動取值與手動填值)
  //---------------------------------------------------------------
  var RNK_AUTO = document.getElementsByClassName('DGPK-RNK-AUTO-JS');
  for (var i = RNK_AUTO.length - 1; i >= 0; i--) {
    try {
      var ATTR = dgpk_arrange_raw_object(JSON.parse( RNK_AUTO[i].innerText.replace(/[\r\n]/g, '').replace(/\[\s*,/g, '[').replace(/\{\s*,/g, '{') ));
      if (ATTR.AUTO == 1 && !ATTR.SCHDID) {
        RNK_AUTO[i].outerHTML = '<DIV CLASS="DGPK-ERROR"><DIV>【賽程表/自動排行】錯誤:未指定賽程表 ID。</DIV></DIV>';
      } else {
        if (__dgpkjs_rnk_init(ATTR) == -1) {
          RNK_AUTO[i].outerHTML = '<DIV CLASS="DGPK-ERROR"><DIV>【賽程表/自動排行】錯誤:找不到指定的賽程表。</DIV></DIV>';
        } else {
          __dgpkjs_rnk_auto(ATTR, RNK_AUTO[i], i);
        }
      }
    } catch (e) {
      console.log(e);
    }
  }
 
  //---------------------------------------------------------------
  // [2019-09-10] calculate TQB
  //---------------------------------------------------------------
  DGPKJS_TQB();
}
 
//----------------------------
// timezone conversion
//----------------------------
function __dgpk_tz_conv(event) {
  var o = event.srcElement || event.target;
 
  var p = o;
  var safe_cnt = 10;
  while ((p = p.parentNode) != null && --safe_cnt >= 0) {
    if (p.tagName == 'TBODY' || p.tagName == 'TABLE') {
      break;
    }
  }
  if (p.tagName != 'TBODY' && p.tagName != 'TABLE') {
    return false;
  }
 
  var attr = decodeURIComponent(o.getAttribute('data-str')).replace(/\s/g, '').split('!');
  var offset = __dgpk_tz_offset(attr[0]);
  if (offset === false) {
    return false;
  }
 
  var yy = attr[1];
  if (!yy || isNaN(yy)) {
    yy = (new Date()).getFullYear();
  }
 
  // seems fine
  var ATTR = [
    {c:'DGPK-tz-btn',  s:'當地時間'},
    {c:'DGPK-tz-btn1', s:'台灣時間'}
  ];
 
  var act = (o.className.indexOf(ATTR[1].c) >= 0 ? 0 : 1);
  o.className = ATTR[act].c;
  o.title = ATTR[act].s;
 
  var date = null;
  for (var i = 0, ii = p.children.length; i < ii; i++) {
    var tr = p.children[i];
    if (tr.tagName != 'TR') break; // something wrong
 
    var mat = tr.children[0].innerText.trim().match(/^\d+\/\d+/);
    if (mat != null) {
      date = yy + '/' + mat[0];
    }
    if (date == null) continue;
 
    var TD = tr.getElementsByClassName('time-val');
    for (var j = 0, jj = TD.length; j < jj; j++) {
      var td = TD[j];
      var time = td.innerText.trim();
 
      attr = td.getAttribute('data-str');
      if (!attr) {
        // do conversion
        attr = time + '!' + __dgpk_tz_conv_do(date, time, offset);
        td.setAttribute('data-str', attr);
      }
 
      td.innerHTML = attr.split('!')[act];
    }
  }
 
  // 好喵做到底,按一次就執行全部
  var BTN = document.getElementsByClassName(ATTR[(act ^ 1)].c);
  BTN[0] && BTN[0].click();  // 由於會一個呼叫一個,每個只要做一次即可
}
 
function __dgpk_tz_offset(tz) { // return tz offset in seconds
  if (!isNaN(tz) && tz.length <= 3) {
    return 3600 * (8 + parseFloat(tz));
  } else {
    var mat = tz.match(/^UTC([\+\-])([0-9:]+)$/);
    if (mat == null) return false;
    if (mat[2].indexOf(':') > 0) { // UTC+08:00
      var hm = mat[2].split(':');
      return (3600 * hm[0] + 60 * hm[1]) * (mat[1] == '+' ? 1 : -1);
    } else if (mat[2].length == 4) { // UTC+0800
      return (3600 * mat[2].substr(0, 2) + 60 * mat[2].substr(2)) * (mat[1] == '+' ? 1 : -1);
    } else {
      return false;
    }
  }
}
 
function __dgpk_tz_conv_do(date, time, offset) {
  if (time.match(/^\d+:\d+/) == null) return time;
 
  var dd = new Date(date + ' ' + time);
  var utc = dd.getTime() - 60000 * dd.getTimezoneOffset() - 1000 * offset;
  var nd = new Date(utc);
 
  var M = nd.getMonth() + 1;
  var D = nd.getDate();
  var h = nd.getHours()
  var m = nd.getMinutes();
  var ret = (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m;
  ret = '<U>' + ret + '</U>';
 
  var ori = date.split('/');
  if (M != parseInt(ori[1]) || D != parseInt(ori[2])) {
    ret += '<BR><SPAN STYLE="color:deeppink">' + (M < 10 ? '0' : '') + M + '/' + (D < 10 ? '0' : '') + D + '</SPAN>';
  }
 
  return ret;
}
 
 
//--------------------------------------------------
// [2019-09-10] 
// dynamically calculate the TQB values
//--------------------------------------------------
function DGPKJS_TQB() {{{
  var TQB = document.getElementsByClassName('DGPK-TQB-JS');
  for (var i = TQB.length - 1; i >= 0; i--) {
    var start_sn = color = TQB[i].getAttribute('data-str');
    var DESCR = TQB[i].getElementsByClassName('de');
    for (var j = DESCR.length - 1; j >= 0; j--) {
      var mat, mat2, tmp, tmp2;
      var r = '', ra = '', o = '', d = '';
      var oa = 0, ob = 0;
      var da = 0, db = 0;
      var getval = 0;
      var of = df = 0.0;
 
      var descr = DESCR[j].innerText.replace(/\s+/g, '');
      if (descr.substr(0, 7) == 'getval:') {
        getval = 1;
        descr = descr.substr(7);
      }
 
      var TOKEN = descr.split('/');
 
      if (TOKEN.length == 4) {
        //-------------------------------------
        // mode = 1 (numeric values)
        //-------------------------------------
        if (TOKEN[0] != '') eval('r  = ' + TOKEN[0] + ';');
        if (TOKEN[2] != '') eval('ra = ' + TOKEN[2] + ';');
 
        if (TOKEN[1] == '') {
        } else if (TOKEN[1].indexOf('+') < 0) {
          o = TOKEN[1] + (TOKEN[1].indexOf('.') < 0 ? '.0' : '');
        } else {
          tmp = TOKEN[1].split('+');
          for (var k = 0, kk = tmp.length; k < kk; k++) {
            tmp2 = tmp[k].split('.');
            oa += parseInt(tmp2[0]);
            if (tmp2.length == 2) {
              ob += parseInt(tmp2[1]);
              oa += parseInt(ob / 3);
              ob %= 3;
            }
          }
          o = oa + '.' + ob;
        }
 
        if (TOKEN[3] == '') {
        } else if (TOKEN[3].indexOf('+') < 0) {
          d = TOKEN[3] + (TOKEN[3].indexOf('.') < 0 ? '.0' : '');
        } else {
          tmp = TOKEN[3].split('+');
          for (var k = 0, kk = tmp.length; k < kk; k++) {
            tmp2 = tmp[k].split('.');
            da += parseInt(tmp2[0]);
            if (tmp2.length == 2) {
              db += parseInt(tmp2[1]);
              da += parseInt(ob / 3);
              db %= 3;
            }
          }
          d = da + '.' + db;
        }
      } else {
        //-------------------------------------
        // mode = 2 (sentence)
        //-------------------------------------
        if ((mat = descr.match(/得\d+分/g)) != null) {
          r = 0;
          for (var k = 0, kk = mat.length; k < kk; k++) {
            if ((mat2 = mat[k].match(/\d+/)) != null) {
              r += parseInt(mat2[0]);
            }
          }
        }
        if ((mat = descr.match(/失\d+分/g)) != null) {
          ra = 0;
          for (var k = 0, kk = mat.length; k < kk; k++) {
            if ((mat2 = mat[k].match(/\d+/)) != null) {
              ra += parseInt(mat2[0]);
            }
          }
        }
 
        if ((mat = descr.match(/攻[0-9\.]+局/g)) != null) {
          for (var k = 0, kk = mat.length; k < kk; k++) {
            if ((mat2 = mat[k].match(/(\d+)\.?(\d*)/)) != null) {
              oa += parseInt(mat2[1]);
              if (mat2[2]) {
                ob += parseInt(mat2[2]);
                oa += parseInt(ob / 3);
                ob %= 3;
              }
            }
          }
        }
        if ((mat = descr.match(/(守|備)[0-9\.]+局/g)) != null) {
          for (var k = 0, kk = mat.length; k < kk; k++) {
            if ((mat2 = mat[k].match(/(\d+)\.?(\d*)/)) != null) {
              da += parseInt(mat2[1]);
              if (mat2[2]) {
                db += parseInt(mat2[2]);
                da += parseInt(db / 3);
                db %= 3;
              }
            }
          }
        }
 
        o = oa + '.' + ob;
        d = da + '.' + db;
      }
 
      if (o) {
        var tmpf = o.split('.');
        of = parseInt(tmpf[0]) + parseInt(tmpf[1]) / 3;
      }
      if (d) {
        var tmpf = d.split('.');
        df = parseInt(tmpf[0]) + parseInt(tmpf[1]) / 3;
      }
 
      var xo = (r !== '' && o ? r / of : '');
      var xd = (ra !== '' && d ? ra / df : '');
 
      var xx = (xo && xd ? dgpk_round(xo - xd, 4) : '');
 
      if (getval == 1) {
        if (xx !== '') {
          if (color == 1) {
            if (xx >= 0) {
              TQB[i].outerHTML = '<SPAN STYLE="color:#080">+' + xx + '</SPAN>';
            } else {
              TQB[i].outerHTML = '<SPAN STYLE="color:#C00">' + xx + '</SPAN>';
            }
          } else {
            TQB[i].outerHTML = (xx >= 0 ? '+' : '') + xx;
          }
        } else {
          TQB[i].outerHTML = '';
        }
        break;
      } else {
        if (xx !== '') {
          if (xx >= 0) {
            xx = '<SPAN STYLE="color:blue"><B>+' + xx + '</B></SPAN>';
          } else {
            xx = '<SPAN STYLE="color:red"><B>' + xx + '</B></SPAN>';
          }
        }
 
        var TR = DESCR[j].parentElement.parentElement;
        if (start_sn) {
          TR.children[0].innerHTML = parseInt(TR.children[0].innerHTML) + parseInt(start_sn) - 1;
        }
        TR.children[2].innerHTML = r;
        TR.children[3].innerHTML = o;
        TR.children[4].innerHTML = dgpk_round(xo, 4);
        TR.children[5].innerHTML = ra;
        TR.children[6].innerHTML = d;
        TR.children[7].innerHTML = dgpk_round(xd, 4);
        TR.children[8].innerHTML = xx;
      }
    } // DESCR for
 
    if (TQB[i]) TQB[i].className = 'DGPK-TQB';
  } // TQB for
}}}
 
 
//========================================
// [2019-12-04] 
// JS-RNK : init
//========================================
function __dgpkjs_rnk_init(ATTR) {{{
  var is_auto = ATTR.AUTO;
  var num_teams = ATTR.TEAMS.length;
  var num_cols = ATTR.COLNAMES.length;
 
  //-----------------------------
  // 若 auto,先檢查賽程表是否存在
  //-----------------------------
  if (is_auto == 1) {
    ATTR.SCHD = [];
    ATTR.SCHDID = dgpk_to_array(ATTR.SCHDID, '/', 1);
 
    for (var i = 0; i < ATTR.SCHDID.length; i++) {
      if (document.getElementById(ATTR.SCHDID[i])) {
        if (document.getElementById(ATTR.SCHDID[i]).tagName == 'TABLE') {
          ATTR.SCHD.push(document.getElementById(ATTR.SCHDID[i]));
        } else if (document.getElementById(ATTR.SCHDID[i]).tagName == 'DIV' && document.getElementById(ATTR.SCHDID[i]).children && document.getElementById(ATTR.SCHDID[i]).children[0] && document.getElementById(ATTR.SCHDID[i]).children[0].tagName == 'TABLE') {
          ATTR.SCHD.push(document.getElementById(ATTR.SCHDID[i].children[0]));
        }
      }
    }
    if (ATTR.SCHD.length == 0) {
      return -1;
    }
  }
 
  //-----------------------------
  // to array
  //-----------------------------
  ATTR.POINTS = dgpk_to_array(ATTR.POINTS);
  ATTR.COLNAMES = dgpk_to_array(ATTR.COLNAMES);
 
  ATTR.LN1 = dgpk_to_array(ATTR.LN1, '/', 1);
  ATTR.LN2 = dgpk_to_array(ATTR.LN2, '/', 1);
  ATTR.LN3 = dgpk_to_array(ATTR.LN3, '/', 1);
 
  ATTR.HLMAX = dgpk_to_array(ATTR.HLMAX, '/', 1);
  ATTR.HLMIN = dgpk_to_array(ATTR.HLMIN, '/', 1);
 
  //=====================================================================
  // initialize TEAMS
  //=====================================================================
  ATTR.SUMMARY = {W:0, L:0, T:0, X:0, N:0};
 
  for (var ti = 0; ti < num_teams; ti++) {
    var tmparr = dgpk_to_array(ATTR.TEAMS[ti].name);
    ATTR.TEAMS[ti].name = tmparr.shift();
 
    if (ATTR.TEAMS[ti].name) {
      switch (ATTR.TEAMS[ti].name.substr(0, 3)) {
      case 'ROC':
      case 'TWN':
      case 'TW-':
        ATTR.TEAMS[ti].sbg = 'background:#FFB;';
        break;
      case 'EX-':
        ATTR.TEAMS[ti].sbg = 'background:#FDD;';
        break;
      }
 
      if (ATTR.TEAMS[ti].alias) {  // 若有 alias 就優先使用。replace [[...]] and [...]
        ATTR.TEAMS[ti].alias = dgpk_wikiobj(ATTR.TEAMS[ti].alias);  // rebuild wiki object if necessary
      } else {
        // 若為 country code 就解開並放進 alias
        if (/^[A-Z\-]+$/.test(ATTR.TEAMS[ti].name) && (descr = DGPK_TEAMX_COUNTRIES[ATTR.TEAMS[ti].name]) != null) {
          ATTR.TEAMS[ti].alias = dgpk_teamx_country(ATTR.TEAMS[ti].name, descr);  // create TeamX if it's country code
        }
      }
    }
 
    ATTR.TEAMS[ti].chk = dgpk_strip_tags(ATTR.TEAMS[ti].alias || ATTR.TEAMS[ti].name).replace(/\s/g, '');  // 稍後當作比對用的關鍵字
    ATTR.TEAMS[ti].wlt = {W:0, L:0, T:0, X:0, N:0};  // WLTX-
    ATTR.TEAMS[ti].wls = [];  // WL Sequence
 
    //-----------------------------------------
    // [non-auto] calculate WLTX- and WLS
    //-----------------------------------------
    if (!is_auto && tmparr.length > 1) {
      if (tmparr[0] !== null && tmparr[0] != '') {
        if (!isNaN(tmparr[0])) {  // numeric
          if (tmparr[1]) ATTR.TEAMS[ti].wlt.W = tmparr[1];
          if (tmparr[2]) ATTR.TEAMS[ti].wlt.L = tmparr[2];
          if (tmparr[3]) ATTR.TEAMS[ti].wlt.T = tmparr[3];
          if (tmparr[4]) ATTR.TEAMS[ti].wlt.X = tmparr[4];
          ATTR.TEAMS[ti].wlt.N = tmparr[0] - (ATTR.TEAMS[ti].wlt.W + ATTR.TEAMS[ti].wlt.L + ATTR.TEAMS[ti].wlt.T + ATTR.TEAMS[ti].wlt.X);
 
          ATTR.SUMMARY.W += ATTR.TEAMS[ti].wlt.W;
          ATTR.SUMMARY.L += ATTR.TEAMS[ti].wlt.L;
          ATTR.SUMMARY.T += ATTR.TEAMS[ti].wlt.T;
          ATTR.SUMMARY.X += ATTR.TEAMS[ti].wlt.X;
          ATTR.SUMMARY.N += ATTR.TEAMS[ti].wlt.N;
        } else {
          ATTR.TEAMS[ti].wls = tmparr.slice(); // clone an array,若用 =[...tmparr] 怕 IE 不支援,若用 =tmparr 是參考物件
          for (var zi = 0; zi < tmparr.length; zi++) {
            var tok = (tmparr[zi] == '-' ? 'N' : tmparr[zi]);
            ATTR.TEAMS[ti].wlt[tok]++;
            ATTR.SUMMARY[tok]++;
          }
        }
      }
    }
  }
 
  //-----------------------------------------
  // [auto] calculate WLTX- and WLS
  // parse values from schedules
  //-----------------------------------------
  if (is_auto == 1) {
    ATTR.CTAB = [];
    for (var ti = 0; ti < num_teams; ti++) {
      ATTR.TEAMS[ti].ctab = [];
    }
 
    var num_schd = ATTR.SCHD.length;
    for (var si = 0; si < num_schd; si++) {
      var ROWS = ((ATTR.SCHD[si].getElementsByTagName('TBODY') && ATTR.SCHD[si].getElementsByTagName('TBODY')[0]) || ATTR.SCHD[si]).rows;
      var num_rows = ROWS.length;
 
      var excmark = [];
      if (si == 0) {
        for (var ti = 0; ti < num_teams; ti++) {
          excmark[ti] = 1;
        }
      } else {
        for (var ti = 0; ti < num_teams; ti++) {
          excmark[ti] = 0;
        }
      }
 
      for (var ri = 0; ri < num_rows; ri++) {
        var html = ROWS[ri].innerHTML.replace(/\s/g, '');
        var text = ROWS[ri].innerText.replace(/\s/g, '');
 
        var found = [];
        for (var ti = 0; ti < num_teams; ti++) {
          if (html.indexOf('>' + ATTR.TEAMS[ti].chk + '<') >= 0) {
            found.push(ti);
          }
          if (found.length == 2) {
            var gn_mat = html.match(/id="Game_(\d+)_.E8.B3.BD.E7.A8.8B.E8.A1.A8"/);
            var gn = (gn_mat ? '/' + gn_mat[1] : '');
 
            if (excmark[found[0]] == 0) {
              excmark[found[0]] = 1;
              ATTR.TEAMS[found[0]].wls.push('!');
            }
            if (excmark[found[1]] == 0) {
              excmark[found[1]] = 1;
              ATTR.TEAMS[found[1]].wls.push('!');
            }
            ATTR.TEAMS[found[0]].ctab[found[1]] = (ATTR.TEAMS[found[0]].ctab[found[1]] ? ATTR.TEAMS[found[0]].ctab[found[1]] + '<BR>' : '');
            ATTR.TEAMS[found[1]].ctab[found[0]] = (ATTR.TEAMS[found[1]].ctab[found[0]] ? ATTR.TEAMS[found[1]].ctab[found[0]] + '<BR>' : '');
 
            if (text.indexOf('取消') >= 0 || text.indexOf('延賽') >= 0) {
              ATTR.TEAMS[found[0]].wlt.X++;
              ATTR.TEAMS[found[1]].wlt.X++;
              ATTR.TEAMS[found[0]].wls.push('X' + gn);
              ATTR.TEAMS[found[1]].wls.push('X' + gn);
              ATTR.TEAMS[found[0]].ctab[found[1]] += 'X';
              ATTR.TEAMS[found[1]].ctab[found[0]] += 'X';
              ATTR.SUMMARY.X += 2;
            } else {
              var t1 = t2 = -1;
              var regex = new RegExp(ATTR.TEAMS[found[0]].chk + '[\\D]*(\\d+):(\\d+)[\\D]*' + ATTR.TEAMS[found[1]].chk);
              var mat = text.match(regex);
              if (mat) {
                t1 = 0;
                t2 = 1;
              } else {
                regex = new RegExp(ATTR.TEAMS[found[1]].chk + '[\\D]*(\\d+):(\\d+)[\\D]*' + ATTR.TEAMS[found[0]].chk);
                mat = text.match(regex);
                if (mat) {
                  t1 = 1;
                  t2 = 0;
                }
              }
              if (mat) {
                var a = parseInt(mat[1]);
                var b = parseInt(mat[2]);
                if (a > b) {
                  ATTR.TEAMS[found[t1]].wlt.W++;
                  ATTR.TEAMS[found[t2]].wlt.L++;
                  ATTR.TEAMS[found[t1]].wls.push('W' + gn);
                  ATTR.TEAMS[found[t2]].wls.push('L' + gn);
                  ATTR.TEAMS[found[t1]].ctab[found[t2]] += '○ ' + a + ':' + b;
                  ATTR.TEAMS[found[t2]].ctab[found[t1]] += '● ' + b + ':' + a;
                  ATTR.SUMMARY.W++;
                  ATTR.SUMMARY.L++;
                } else if (a < b) {
                  ATTR.TEAMS[found[t1]].wlt.L++;
                  ATTR.TEAMS[found[t2]].wlt.W++;
                  ATTR.TEAMS[found[t1]].wls.push('L' + gn);
                  ATTR.TEAMS[found[t2]].wls.push('W' + gn);
                  ATTR.TEAMS[found[t1]].ctab[found[t2]] += '● ' + a + ':' + b;
                  ATTR.TEAMS[found[t2]].ctab[found[t1]] += '○ ' + b + ':' + a;
                  ATTR.SUMMARY.W++;
                  ATTR.SUMMARY.L++;
                } else {
                  ATTR.TEAMS[found[0]].wlt.T++;
                  ATTR.TEAMS[found[1]].wlt.T++;
                  ATTR.TEAMS[found[0]].wls.push('T' + gn);
                  ATTR.TEAMS[found[1]].wls.push('T' + gn);
                  ATTR.TEAMS[found[t1]].ctab[found[t2]] += '△ ' + a + ':' + b;
                  ATTR.TEAMS[found[t2]].ctab[found[t1]] += '△ ' + b + ':' + a;
                  ATTR.SUMMARY.T += 2;
                }
 
                var pad = '&nbsp;&nbsp;&nbsp;&nbsp;'.substr(0, 6 * (4 - ('' + mat[1] + mat[2]).length));
                ATTR.TEAMS[found[t1]].ctab[found[t2]] += pad;
                ATTR.TEAMS[found[t2]].ctab[found[t1]] += pad;
              } else {
                ATTR.TEAMS[found[0]].wlt.N++;
                ATTR.TEAMS[found[1]].wlt.N++;
                ATTR.TEAMS[found[0]].wls.push('-' + gn);
                ATTR.TEAMS[found[1]].wls.push('-' + gn);
                ATTR.SUMMARY.N += 2;
              }
            }
            break;
          }
        }  // END OF for (TEAMS)
      }  // END OF for (ROWS)
    }  // END OF for (SCHD)
  }
 
  //=====================================================================
  // post process
  //=====================================================================
 
  //-----------------------------
  // auto sort
  //-----------------------------
  var GRP = {};
  for (var ti = 0; ti < num_teams; ti++) {
    // points
    if (ATTR.COLNAMES.indexOf('積分') >= 0) {
      ATTR.TEAMS[ti].pt = (ATTR.TEAMS[ti].wlt.W * ATTR.POINTS[0] + ATTR.TEAMS[ti].wlt.L * ATTR.POINTS[1] + ATTR.TEAMS[ti].wlt.T * ATTR.POINTS[2]);
    }
    // pct
    if (ATTR.TEAMS[ti].wlt.W + ATTR.TEAMS[ti].wlt.L == 0) {
      ATTR.TEAMS[ti].pct = .5;
    } else {
      ATTR.TEAMS[ti].pct = ATTR.TEAMS[ti].wlt.W / (ATTR.TEAMS[ti].wlt.W + ATTR.TEAMS[ti].wlt.L);
    }
    // raw gb val
    ATTR.TEAMS[ti].gb = (ATTR.TEAMS[ti].wlt.W - ATTR.TEAMS[ti].wlt.L) / 2;
 
    // prepare for auto sort
    ATTR.TEAMS[ti].ord = ti; // 原本 idx
    var tok = ATTR.TEAMS[ti].gb;
    if (GRP[tok] == null) GRP[tok] = [];
    GRP[tok].push(ti);
  }
 
  if (ATTR.ORDER == 1) {
    // 自動排序
    ATTR.TEAMS.sort(function(a, b) {
      if (a.pt !== null && b.pt != a.pt) {
        return b.pt - a.pt;
      } else {
        if (b.pct != a.pct) {
          return b.pct - a.pct;
        } else {
          if (b.gb != a.gb) {
            return b.gb - a.gb;
          } else {
            var tok = a.gb;
            if (GRP[tok].length == 2 && a.ctab[b.ord]) {  // 只有這兩隊,則比較勝負關係
              switch (a.ctab[b.ord].substr(0, 1)) {
              case '○':
                return -1;
              case '●':
                return 1;
              }
            }
 
            return a.ord - b.ord; // 書寫順序
          }
        }
      }
    });
  }
 
  //-----------------------------
  // EVC
  //-----------------------------
  for (var ci = 0; ci < num_cols; ci++) {
    var col = ATTR.COLNAMES[ci];
    if (!col) continue;
 
    // 特別處理 TQB,若使用 JS 版模板,需幫它保留下來
    if (col == 'TQB' && ATTR.EVC[ci] && ATTR.EVC[ci].indexOf('DGPK-TQB-JS') >= 0) {
      //ATTR.EVC[ci] = ATTR.EVC[ci].replace(/<\/div>\s*\/\s*<div/ig, '</div>@@@<div').split(/@@@/);
      var found = 0;
      var tmpstr = '';
      var tmparr = ATTR.EVC[ci].split(/\//);
      ATTR.EVC[ci] = [];
      for (var xi = 0; xi < tmparr.length; xi++) {
        if (typeof tmparr[xi] == 'undefined') continue;
        if (found) {
          tmpstr += '/' + tmparr[xi];
          if (/DIV>/i.test(tmparr[xi])) {
            found = 0;
            ATTR.EVC[ci].push(tmpstr.replace(/DATA-STR="0"/, 'DATA-STR="1"'));
          }
        } else if (/<DIV/i.test(tmparr[xi])) {
          found = 1;
          tmpstr = tmparr[xi];
        } else {
          ATTR.EVC[ci].push(tmparr[xi]);
        }
      }
    } else {
      ATTR.EVC[ci] = dgpk_to_array(ATTR.EVC[ci]);
    }
  }
 
  // magic2
  var idx = ATTR.COLNAMES.indexOf('晉級');
  if (idx >= 0) {
    var VAL = ATTR.EVC[idx] || [];
 
    for (var ti = 0; ti < num_teams; ti++) {
      var val = '' + VAL[ti];
      if (i == 0 || val != '' + VAL[ti - 1]) {
        ATTR.TEAMS[ti].m2 = 1;
 
        for (var ei = ti + 1; ei < num_teams; ei++) {
          if (val == '' + VAL[ei]) {
            ATTR.TEAMS[ti].m2++;
          } else {
            ti += ei - (ti + 1);
            break;
          }
        }
      }
    }
  }
 
  //-----------------------------
  // max-val & min-val
  //-----------------------------
  ATTR.MAXVAL = {};
  ATTR.MINVAL = {};
  if (ATTR.HLMAX || ATTR.HLMIN) {
    // exclude default columns and TQB
    var EXCLUSION = ['#', '排行', '球隊', '對戰球隊', '對戰層級', '應賽', '已賽', '勝場', '敗場', '和局', '勝率', '勝差',
                     '積分','勝負記錄','未賽', '勝負場數', '勝負和', '勝-負-和', 'W-L-T', '勝和負', '勝-和-負', 'W-T-L',
                     '晉級', '取消', '延賽', '淘汰數字', '淘汰指數', 'Eno', '晉級淘汰數字', '晉級淘汰指數', 'AEno', 'TQB'
                    ];
    for (var ci = 0; ci < num_cols; ci++) {
      var col = ATTR.COLNAMES[ci];
      if (!col) continue;
      if (EXCLUSION.indexOf(col) >= 0) continue;
      if (ATTR.HLMAX.indexOf(col) < 0 && ATTR.HLMIN.indexOf(col) < 0) continue;
 
      var VAL = ATTR.EVC[ci];
      var tmparr = [];
      for (var xi = 0; xi < VAL.length; xi++) {
        if (VAL[xi] !== '' && !isNaN(VAL[xi])) {
          tmparr.push(parseFloat(VAL[xi]));
        }
      }
      if (tmparr.length == 0) continue;
 
      if (ATTR.HLMAX.indexOf(col) >= 0) {
        ATTR.MAXVAL[col] = Math.max.apply(null, tmparr);
      }
      if (ATTR.HLMIN.indexOf(col) >= 0) {
        ATTR.MINVAL[col] = Math.min.apply(null, tmparr);
      }
    }
  }
 
  return true;
}}}
 
function __dgpk_wls(arr) {{{
  var ret = '';
  ret += '<DIV CLASS="WLS">';
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] == '!') {
      ret += '<tt> </tt>';
    } else {
      var tok = arr[i].split('/');
      ret += '<DIV CLASS="DGPK-BN-' + tok[0] + '"';
      if (tok[1]) {
        ret += ' STYLE="cursor:pointer"';
        ret += ' TITLE="Game ' + tok[1] + '"';
        ret += ' onclick="document.getElementById(\'Game_' + tok[1] + '_.E8.B3.BD.E7.A8.8B.E8.A1.A8\').scrollIntoView();return false"';
      }
      ret += '>' + tok[0] + '</DIV>';
    }
  }
  ret += '</DIV>';
  return ret;
}}}
 
 
//========================================
// [2019-12-04] 
// JS-RNK : create the ranking table
//========================================
function __dgpkjs_rnk_auto(ATTR, div, di) {{{
  var is_auto = ATTR.AUTO;
  var div_id = 'DGPK-RNKTAB-' + di;
  var num_cols = ATTR.COLNAMES.length;
  var num_teams = ATTR.TEAMS.length;
 
  //-----------------
  // init
  //-----------------
  var html = '';
  html += '<DIV ID="' + div_id + '" CLASS="DGPK-RNK" STYLE="opacity:0;' + ATTR.STL_DIV + '"><DIV>';
  html += '<TABLE CLASS="DGPK-rows mover" BORDER="1" CELLSPACING="0" CELLPADDING="' + (num_teams > 6 ? 2 : 4) + '" STYLE="' + (ATTR.THEME == 1 ? 'border-color:#AAA;' : '') + ATTR.STL_TAB + '">';
 
  //-----------------
  // title
  //-----------------
  html += '<TR CLASS="title" STYLE="' + (ATTR.THEME == 1 ? 'background:#666;color:white;' : '') + ATTR.STL_TTL + '">';
  html += '<TH COLSPAN="' + (num_cols + (ATTR.COLNAMES.indexOf('對戰比分') >= 0 ? num_teams : 0)) + '">' + ATTR.TITLE + '</TH>';
  html += '</TR>';
 
  //-----------------
  // columns
  //-----------------
  html += '<TR CLASS="column"' + (ATTR.THEME == 1 ? ' STYLE="background:#888;color:white"' : '') + '>';
  for (var ci = 0; ci < num_cols; ci++) {
    var col = ATTR.COLNAMES[ci];
    if (!col) continue;
 
    var stl = ATTR.STH[ci] || '';
 
    if (ATTR.LN1.indexOf(col) >= 0) {
      stl = 'border-left:1px solid black;' + stl;
    } else if (ATTR.LN2.indexOf(col) >= 0) {
      stl = 'border-left:2px solid black;' + stl;
    } else if (ATTR.LN3.indexOf(col) >= 0) {
      stl = 'border-left:3px double black;' + stl;
    }
 
    var ttl = '';
    html += '<TH STYLE="';
    switch (col) {
    case '#':
      html += 'width:15px;';
      break;
    case '排行':
    case '排名':
      html += 'width:30px;';
      break;
    case 'TQB':
      html += 'width:55px;';
      // follow thru
    case 'W-L-T':
    case 'W-T-L':
      html += 'font-family:Consolas,monospace;';
      break;
    case '對戰比分':
      if (is_auto) {
        html += 'width:1px;background:#CCC;color:black;';
      }
      break;
    case 'ENO':
    case '淘汰數字':
    case '淘汰指數':
      ttl = '淘汰數字';
      // follow thru
    case 'AENO':
    case '晉級淘汰數字':
    case '晉級淘汰指數':
      html += 'font-family:Consolas,monospace;color:' + (ATTR.THEME == 1 ? 'yellow' : 'blue') + ';';
      if (ttl == '') ttl = '晉級淘汰數字';
      break;
    }
    html += (ATTR.STL_COL || '') + ';' + stl + '"' + (ttl ? ' TITLE="' + ttl + '"' : '') + '>';
 
    // rewrite
    switch (col) {
    case 'ENO':
    case '淘汰數字':
    case '淘汰指數':
      html += 'E#';
      break;
    case 'AENO':
    case '晉級淘汰數字':
    case '晉級淘汰指數':
      html += 'AE#';
      break;
    case '對戰比分':
      if (is_auto) {
        for (var ti = 0; ti < num_teams; ti++) {
          html += ATTR.TEAMS[ti].alias || ATTR.TEAMS[ti].name;
          if (ti < num_teams - 1) {
            html += '</TH><TH STYLE="width:1px;background:#CCC;color:black;' + stl + ';border-left:1px solid #AAA">';
          }
        }
        break;
      }
      // else, follow thru
    default:
      html += col;
      break;
    }
    html += '</TH>';
  }
  html += '</TR>';
 
  //-----------------
  // body
  //-----------------
  var zeroval = '<SPAN STYLE="color:#CCC">0</SPAN>';
  for (var ti = 0; ti < num_teams; ti++) {
    html += '<TR CLASS="body"' + (ti == 0 || ATTR.TEAMS[ti].m2 || ti == ATTR.ADVN ? ' STYLE="border-top:1px solid black"' : '') + '>';
 
    for (var ci = 0; ci < num_cols; ci++) {
      var col = ATTR.COLNAMES[ci];
      if (!col) continue;
 
      var stl = ATTR.STC[ci] || '';
      var VAL = ATTR.EVC[ci] || [];
      var val = VAL[ti];
 
      if (ATTR.LN1.indexOf(col) >= 0) {
        stl = 'border-left:1px solid black;' + stl;
      } else if (ATTR.LN2.indexOf(col) >= 0) {
        stl = 'border-left:2px solid black;' + stl;
      } else if (ATTR.LN3.indexOf(col) >= 0) {
        stl = 'border-left:3px double black;' + stl;
      }
 
      var eno_base = 0;
 
      switch (col) {
      case '晉級':
        if (ATTR.TEAMS[ti].m2) {
          html += '<TD ROWSPAN="' + (ti + ATTR.TEAMS[ti].m2 > num_teams ? num_teams - ti : ATTR.TEAMS[ti].m2) + '"';
          html += ' STYLE="' + (val !== null && val !== '' && typeof(val) !== 'undefined' ? 'background:#FFF;' + (val.indexOf('-') > 0 ? 'line-height:1.2;' : '') : 'background:#EEE;') + stl + '}">';
          html += (val !== null && typeof(val) !== 'undefined' ? val.replace(/\-/g, '<BR>') : '');
          html += '</TD>';
        }
        break;
      case '球隊':
      case '對戰球隊':
      case '對戰層級':
        var descr;
        html += '<TD CLASS="team" STYLE="' + (ATTR.TEAMS[ti].sbg || '') + stl + '">';
        html += (ATTR.TEAMS[ti].alias || ATTR.TEAMS[ti].name || '');
        html += '</TD>';
        break;
      case 'TQB':
        html += '<TD STYLE="' + (typeof val == 'number' ? 'font-size:9pt;color:' + (val < 0 ? '#C00' : '#080') + ';' : '') + stl +'">';
        html += (typeof val == 'number' ? dgpk_round(val, 4) : val || '');
        html += '</TD>';
        break;
      case '對戰比分':
        if (is_auto) {
          for (var tii = 0; tii < num_teams; tii++) {
            html += '<TD CLASS="ctab" STYLE="';
            if (ti == tii) {
              html += 'background:#DDD;' + stl + ';' + (tii > 0 ? 'border-left:1px solid #AAA;' : '') + '">';
            } else {
              html += stl + ';' + (tii > 0 ? 'border-left:1px solid #AAA;' : '') + '">';
 
              var idx = ATTR.TEAMS[tii].ord;  // 順序可能在自動排序後變更,更正位置
              html += ATTR.TEAMS[ti].ctab[idx] || '';
            }
            html += '</TD>';
          }
          break;
        }
        // else, follow thru
      default:
        var stl2 = '';
        if (val !== null && val !== '' && !isNaN(val)) {
          if ((ATTR.MAXVAL[col] !== null && val == ATTR.MAXVAL[col]) ||
              (ATTR.MINVAL[col] !== null && val == ATTR.MINVAL[col])) {
            stl2 = 'background:deeppink;color:white;';
          }
        }
        html += '<TD STYLE="' + stl2 + stl + '">';
 
        switch (col) {
        case '#':
        case '排行':
          html += (ti + 1);
          break;
        case '應賽':
          html += Object.values(ATTR.TEAMS[ti].wlt).reduce((a,b)=>a+b);  // sum values
          break;
        case '已賽':
          html += ATTR.TEAMS[ti].wlt.W + ATTR.TEAMS[ti].wlt.L + ATTR.TEAMS[ti].wlt.T;
          break;
        case '勝場':
          html += ATTR.TEAMS[ti].wlt.W || zeroval;
          break;
        case '敗場':
          html += ATTR.TEAMS[ti].wlt.L || zeroval;
          break;
        case '和局':
          html += ATTR.TEAMS[ti].wlt.T || zeroval;
          break;
        case '取消':
        case '延賽':
          html += ATTR.TEAMS[ti].wlt.X || zeroval;
          break;
        case '未賽':
          html += ATTR.TEAMS[ti].wlt.N || zeroval;
          break;
        case '勝率':
          if (ATTR.TEAMS[ti].wlt.W + ATTR.TEAMS[ti].wlt.L == 0) {
            html += '-';
          } else {
            html += dgpk_round(ATTR.TEAMS[ti].pct, 3, 1)
          }
          break;
        case '勝差':
          html += (ATTR.TEAMS[0].gb - ATTR.TEAMS[ti].gb) || '-';
          break;
        case '積分':
          html += ATTR.TEAMS[ti].pt;
          break;
        case '勝負記錄':
          html += __dgpk_wls(ATTR.TEAMS[ti].wls);
          break;
        case '勝負場數':
          html += ATTR.TEAMS[ti].wlt.W + 'W-' + ATTR.TEAMS[ti].wlt.L + 'L' + (ATTR.TEAMS[ti].wlt.T ? '-' + ATTR.TEAMS[ti].wlt.T + 'T' : '');
          break;
        case '勝負和':
        case '勝-負-和':
        case 'W-L-T':
          html += ATTR.TEAMS[ti].wlt.W + '-' + ATTR.TEAMS[ti].wlt.L + '-' + ATTR.TEAMS[ti].wlt.T;
          break;
        case '勝和負':
        case '勝-和-負':
        case 'W-T-L':
          html += ATTR.TEAMS[ti].wlt.W + '-' + ATTR.TEAMS[ti].wlt.T + '-' + ATTR.TEAMS[ti].wlt.L;
          break;
        case 'AENO':
        case '晉級淘汰數字':
        case '晉級淘汰指數':
          eno_base = (!ATTR.ADVN ? -1 : ATTR.ADVN - 1);
          // follow thru
        case 'ENO':
        case '淘汰數字':
        case '淘汰指數':
          if (eno_base < 0 || ti <= eno_base || JSON.stringify(ATTR.TEAMS[eno_base].wlt) == JSON.stringify(ATTR.TEAMS[ti].wlt)) {
            html += '-';
          } else {
            var v1 = ATTR.TEAMS[eno_base].wlt.W + ATTR.TEAMS[eno_base].wlt.L + ATTR.TEAMS[eno_base].wlt.N;
            var v2 = ATTR.TEAMS[ti].wlt.W + ATTR.TEAMS[ti].wlt.L + ATTR.TEAMS[ti].wlt.N;
            var v3 = ATTR.TEAMS[ti].wlt.W + ATTR.TEAMS[ti].wlt.N;
            var v4 = ATTR.TEAMS[ti].wlt.W;
            var vx = v2 == 0 ? 'NaN' : Math.floor((v1 / v2) * v3 - v4 + 1);
            if (vx == 'NaN') {
              html += '';
            } else if (vx <= 0) {
              html += '<SPAN STYLE="color:red">e</SPAN>';
            } else {
              html += vx;
            }
          }
          break;
        default: // custom values
          html += (val === null ? '' : val || zeroval);
          break;
        }
        html += '</TD>';
        break;
      }
    }
    html += '</TR>';
  }
 
  //-----------------
  // summary
  //-----------------
  if (ATTR.TOTALS) {
    if (ATTR.TOTALS < 0 || ATTR.TOTALS > 2) ATTR.TOTALS = 1;  // 防呆
    var divi = (ATTR.TOTALS == 1 ? 2 : 1);
 
    html += '<TR CLASS="footer"' + (ATTR.THEME == 1 ? ' STYLE="background:#888;color:white"' : '') + '>';
    for (var ci = 0; ci < num_cols; ci++) {
      var col = ATTR.COLNAMES[ci];
      if (!col) continue;
 
      var stl = ATTR.STH[ci] || '';
 
      if (ATTR.LN1.indexOf(col) >= 0) {
        stl = 'border-left:1px solid black;' + stl;
      } else if (ATTR.LN2.indexOf(col) >= 0) {
        stl = 'border-left:2px solid black;' + stl;
      } else if (ATTR.LN3.indexOf(col) >= 0) {
        stl = 'border-left:3px double black;' + stl;
      }
 
      html += '<TH STYLE="' + (ATTR.STL_COL || '') + ';' + stl + '">';
 
      switch (col) {
      case '球隊':
      case '對戰球隊':
      case '對戰層級':
        html += '總計或平均';
        break;
      case '應賽':
        html += (Object.values(ATTR.SUMMARY).reduce((a,b)=>a+b)) / divi;  // sum values
        break;
      case '已賽':
        html += (ATTR.SUMMARY.W + ATTR.SUMMARY.L + ATTR.SUMMARY.T) / divi;
        break;
      case '取消':
      case '延賽':
        html += (ATTR.SUMMARY.X) / divi;
        break;
      case '未賽':
        html += (ATTR.SUMMARY.N) / divi;
        break;
      case '勝場':
        html += ATTR.SUMMARY.W;
        break;
      case '敗場':
        html += ATTR.SUMMARY.L;
        break;
      case '和局':
        html += ATTR.SUMMARY.T;
        break;
      case '勝負場數':
        html += ATTR.SUMMARY.W + 'W-' + ATTR.SUMMARY.L + 'L' + (ATTR.SUMMARY.T ? '-' + ATTR.SUMMARY.T + 'T' : '');
        break;
      case '勝負和':
      case '勝-負-和':
      case 'W-L-T':
        html += ATTR.SUMMARY.W + '-' + ATTR.SUMMARY.L + '-' + ATTR.SUMMARY.T;
        break;
      case '勝和負':
      case '勝-和-負':
      case 'W-T-L':
        html += ATTR.SUMMARY.W + '-' + ATTR.SUMMARY.T + '-' + ATTR.SUMMARY.L;
        break;
      case '勝率':
        if (ATTR.SUMMARY.W + ATTR.SUMMARY.L == 0) {
          html += '-';
        } else {
          if (ATTR.SUMMARY.W == 0) {
            html += '.000';
          } else if (ATTR.SUMMARY.L == 0) {
            html += '1.000';
          } else {
            html += dgpk_round(ATTR.SUMMARY.W / (ATTR.SUMMARY.W + ATTR.SUMMARY.L), 3, 1);
          }
        }
        break;
      case '對戰比分':
        if (is_auto) {
          for (var ti = 0; ti < num_teams; ti++) {
            if (ti < num_teams - 1) {
              html += '</TH><TH STYLE="' + stl + ';border-left:1px solid #AAA">';
            }
          }
          break;
        }
        // else, follor thru
      }
      html += '</TH>';
    }
    html += '</TR>';
  } // END OF if (TOTALS)
  //-----------------
  // end of table
  //-----------------
  html += '</TABLE></DIV>';
 
  if (ATTR.NOTE) {
    html += '<BR><TABLE STYLE="display:inline-block;margin:0;border-left:6px solid #DDD;margin-top:6px">';
    html += '<TR VALIGN="top">';
    html += '<TD NOWRAP>✎備註:</TD>';
    html += '<TD>' + dgpk_wikiobj(ATTR.NOTE) + '</TD>';
    html += '</TR>';
    html += '</TABLE>';
  }
  //-----------------
  // end of outer div
  //-----------------
  html += '</DIV>';
  div.outerHTML = html;
 
  setTimeout(function() {
    document.getElementById(div_id).style.opacity = 1;
  }, 1);
}}}