











(function () {
  'use strict';

  
  
  var T = function (k, d) { return window.VizI18n ? VizI18n.tr(k, d) : d; };

  var LEVELS = {
    info:     { icon: 'ℹ', color: '#4da3ff', auto: 3000 },
    success:  { icon: '✓', color: '#5fcf80', auto: 3000 },
    

    warn:     { icon: '!', color: '#ffcc44', auto: 0 },
    error:    { icon: '✕', color: '#ff9a90', auto: 0 },
    progress: { icon: '⟳', color: '#4da3ff', auto: 0 }
  };

  var host = null;
  var items = {};        
  var seq = 0;
  var hovering = false;

  function injectStyle() {
    var css = [
      '#toast-host{position:fixed;right:14px;bottom:14px;z-index:45;display:flex;',
      '  flex-direction:column-reverse;gap:8px;align-items:flex-end;pointer-events:none;}',
      '#toast-host .t{pointer-events:auto;min-width:210px;max-width:340px;',
      '  background:rgba(28,31,36,.97);border:1px solid #47505a;border-left-width:3px;',
      '  border-radius:5px;box-shadow:0 4px 14px rgba(0,0,0,.45);',
      '  padding:8px 10px;font-size:12px;color:#c5c8c6;line-height:1.5;',
      '  opacity:0;transform:translateX(14px);transition:opacity .18s ease,transform .18s ease;}',
      '#toast-host .t.in{opacity:1;transform:translateX(0);}',
      '#toast-host .t .hd{display:flex;align-items:flex-start;gap:7px;}',
      '#toast-host .t .ic{flex:0 0 auto;font-weight:700;line-height:1.5;}',
      '#toast-host .t .tx{flex:1 1 auto;word-break:break-word;white-space:pre-line;}',
      '#toast-host .t .x{flex:0 0 auto;background:none;border:0;color:#8f979e;cursor:pointer;',
      '  font-size:13px;line-height:1;padding:1px 2px;}',
      '#toast-host .t .x:hover{color:#c5c8c6;}',
      '#toast-host .t .bar{height:4px;background:#23272c;border-radius:3px;overflow:hidden;margin-top:7px;}',
      '#toast-host .t .bar i{display:block;height:100%;background:#4da3ff;transition:width .15s linear;}',
      
      
      
      '#toast-host .t .bar.indet i{width:35%;animation:toast-indet 1.1s ease-in-out infinite;}',
      '#toast-host .t .sub{color:#8f979e;font-size:11px;margin-top:3px;font-variant-numeric:tabular-nums;}',
      '@keyframes toast-indet{0%{transform:translateX(0);}50%{transform:translateX(186%);}'
      + '100%{transform:translateX(0);}}'
    ].join('\n');
    var s = document.createElement('style');
    s.textContent = css;
    document.head.appendChild(s);
  }

  function build() {
    injectStyle();
    host = document.createElement('div');
    host.id = 'toast-host';
    

    host.addEventListener('mouseenter', function () {
      hovering = true;
      Object.keys(items).forEach(function (k) { clearTimer(items[k]); });
    });
    host.addEventListener('mouseleave', function () {
      hovering = false;
      Object.keys(items).forEach(function (k) { armTimer(items[k]); });
    });
    document.body.appendChild(host);
  }

  function clearTimer(it) {
    if (it && it.timer) { clearTimeout(it.timer); it.timer = null; }
  }

  function armTimer(it) {
    if (!it || it.sticky || hovering) return;
    clearTimer(it);
    
    
    var ms = it.autoMs || (LEVELS[it.level] || LEVELS.info).auto;
    if (!ms) return;
    it.timer = setTimeout(function () { dismiss(it.id); }, ms);
  }

  function dismiss(id) {
    var it = items[id];
    if (!it) return;
    clearTimer(it);
    delete items[id];
    it.el.classList.remove('in');
    setTimeout(function () {
      if (it.el.parentNode) it.el.parentNode.removeChild(it.el);
    }, 200);
  }

  function sizeText(n) {
    n = Number(n) || 0;
    if (n >= 1048576) return (n / 1048576).toFixed(2) + ' MB';
    if (n >= 1024) return (n / 1024).toFixed(1) + ' KB';
    return n + ' B';
  }

  


  function show(opts) {
    if (!host) build();
    opts = opts || {};
    var id = opts.id || ('t' + (++seq));
    var level = LEVELS[opts.level] ? opts.level : 'info';
    var it = items[id];

    if (!it) {
      var el = document.createElement('div');
      el.className = 't';
      el.innerHTML = '<div class="hd"><span class="ic"></span>' +
                     '<span class="tx"></span>' +
                     '<button class="x" title="' + T('viz_close', '关闭') +
                     '">×</button></div>' +
                     '<div class="sub" style="display:none"></div>' +
                     '<div class="bar" style="display:none"><i></i></div>';
      it = { id: id, el: el,
             ic: el.querySelector('.ic'), tx: el.querySelector('.tx'),
             sub: el.querySelector('.sub'), bar: el.querySelector('.bar'),
             fill: el.querySelector('.bar i'), x: el.querySelector('.x'),
             timer: null };
      it.x.addEventListener('click', function () { dismiss(id); });
      items[id] = it;
      host.appendChild(el);
      
      requestAnimationFrame(function () { el.classList.add('in'); });
    }

    it.level = level;
    it.sticky = !!opts.sticky;
    it.autoMs = opts.autoMs || 0;
    var cfg = LEVELS[level];
    it.ic.textContent = cfg.icon;
    it.ic.style.color = cfg.color;
    it.el.style.borderLeftColor = cfg.color;
    it.tx.textContent = opts.text || '';

    if (opts.sub) {
      it.sub.textContent = opts.sub;
      it.sub.style.display = 'block';
    } else {
      it.sub.style.display = 'none';
    }

    var pr = opts.progress;
    if (pr) {
      it.bar.style.display = 'block';
      
      var indet = !(pr.total > 0);
      it.bar.className = 'bar' + (indet ? ' indet' : '');
      if (!indet) {
        it.fill.style.width = Math.min(100, Math.round(pr.done * 100 / pr.total)) + '%';
      }
    } else {
      it.bar.style.display = 'none';
    }

    armTimer(it);
    return id;
  }

  window.Toast = {
    init: function () { if (!host) build(); },
    show: show,
    dismiss: dismiss,
    sizeText: sizeText,
    
    _count: function () { return Object.keys(items).length; },
    _has: function (id) { return !!items[id]; },
    _level: function (id) { return items[id] ? items[id].level : null; }
  };
})();
