<!-- RUBY-BACKUP · part 563 -->
_restoreSpans(state.nodes);
      }catch(e){}
      /* lift overlays */
      try{
        if(state.lifts && typeof window.__setLifts === 'function')
          window.__setLifts(state.lifts);
      }catch(e){}
      /* machines, rebuilt where they stood */
      try{
        var ms = state.machines || [];
        for(var i=0;i<ms.length;i++){
          try{ if(typeof window.__buildMachineAt === 'function') window.__buildMachineAt(ms[i].kind, ms[i].x, ms[i].z); }catch(e){}
        }
      }catch(e){}
      /* pulleys, replaced where they stood */
      try{
        var ps = state.pulleys || [];
        for(var j=0;j<ps.length;j++){
          try{ if(typeof window.__placePulleyAt === 'function') window.__placePulleyAt(ps[j].x, ps[j].y, ps[j].z); }catch(e){}
        }
      }catch(e){}
    });
    /* let the autoload memory agree with the rewound world */
    try{ if(typeof window.saveNodes === 'function') window.saveNodes(false); }catch(e){}
    return n;
  }

  /* shared with the phoenix protocol (phoenix.js) — wipe dynamic systems, spare the stones */
  window.__clearDynamic = clearDynamic;

  /* ---------- public API ---------- */
  window.takeSnapshot = function(name){
    name = cleanName(name);
    if(!name) return 'name it — snapshot <name>';
    var st = loadStore();
    st.snaps[name] = {t: Date.now(), state: captureState()};
    st.order = st.order.filter(function(n){ return n !== name; });
    st.order.push(name);
    while(st.order.length > MAX_SNAPS){
      var drop = st.order.shift();
      delete st.snaps[drop];
    }
    saveStore(st);
    var msg = 'snapshot "' + name + '" frozen — ' + st.order.length + ' held';
    status(msg);
    return msg;
  };

  window.rewindOne = function(){
    var st = loadStore();
    if(!st.order.length) return 'Memory does not reach that far — no snapshots remain.';
    var name = st.order.pop();
    var rec = st.snaps[name];
    delete st.snaps[name];
    saveStore(st);
    if(!rec) return 'snapshot gone';
    clearDynamic();
    var n = restoreState(rec.state);
    var msg = 'rewound to "' + name + '" (' + ageStr(rec.t) + ') — ' + n + ' nodes restored';
    status(msg);
    return msg;
  };

  window.rewindTo = function(name){
    name = cleanName(name);
    if(!name) return 'name it — rewind to <name>';
    var st = loadStore();
    var rec = st.snaps[name];
    if(!rec) return 'Memory does not reach that far — no snapshot "' + name + '".';
    clearDynamic();
    var n = restoreState(rec.state);
    var msg = 'rewound to "' + name + '" (' + ageStr(rec.t) + ') — ' + n + ' nodes restored';
    status(msg);
    return msg;
  };

  window.listSnapshots = function(){
    var st = loadStore();
    var range = 'Memory holds from ' + timeStr(st.memoryBorn) + ' to now.';
    if(!st.order.length){
      var msg = 'no snapshots yet. ' + range;
      status(msg);
      return msg;
    }
    var lines = [];
    for(var i=st.order.length-1;i>=0;i--){
      var nm = st.order[i], rec = st.snaps[nm];
      if(rec) lines.push('"' + nm + '" — ' + ageStr(rec.t));
    }
    var out = lines.join('\n') + '\n' + range;
    status(st.order.length + ' snapshots. ' + range);
    try{ console.log('[snapshots]\n' + out); }catch(e){}
    return out;
  };

  window.forgetSnapshot = function(name){
    name = cleanName(name);
    if(!name) return 'name it — forget snapshot <name>';
    var st = loadStore();
    if(!st.snaps[name]) return 'no snapshot "' + name + '"';
    delete st.snaps[name];
    st.order = st.order.filter(function(n){ return n !== name; });
    saveStore(st);
    var msg = 'forgotten "' + name + '"';
    status(msg);
    return msg;
  };

  /* ---------- runLine chain (outermost — first crack at the codes) ---------- */
  (function(){
    var __triessnapHooked=0;
    function __hooksnapHooked(){
      __triessnapHooked++;
      try{
        if(typeof window.runLine === 'function' && !window.runLine.__snapHooked){
      var prevRL = window.runLine;
      window.runLine = function(line){
        try{
          var raw = String(line == null ? '' : line).trim();
          var tl = raw.toLowerCase();
          if(tl.indexOf('snapshot ') === 0){ window.takeSnapshot(raw.slice(9)); return; }
          if(tl.indexOf('rewind to ') === 0){ window.rewindTo(raw.slice(10)); return; }
          if(tl === 'rewind'){ window.rewindOne(); return; }
          if(tl === 'snapshots'){ window.listSnapshots(); return; }
          if(tl.indexOf('forget snapshot ') === 0){ window.forgetSnapshot(raw.slice(16)); return; }
        }catch(e){}
        return prevRL.apply(this, arguments);
      };
      window.runLine.__snapHooked = true;
          return;
        }
      }catch(e){}
      if(__triessnapHooked<60) setTimeout(__hooksnapHooked,500);
    }
    __hooksnapHooked();
  
    window.__hooksnapHooked = __hooksnapHooked;})();

  /* stamp the memory's birth on first parse (guarded by loadStore anyway) */
  try{ loadStore(); }catch(e){}

  try{ console.log('[snaps