Menu="Main:5"
Title="Array Operation"
Tag="snowflake-o"
Nchan="device_list,disk_load,parity_list"
---
<?PHP
/* Copyright 2005-2025, Lime Technology
 * Copyright 2012-2025, Bergware International.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2,
 * as published by the Free Software Foundation.
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 */
?>
<?
$keyfile = file_exists(_var($var,'luksKeyfile'));
$spot    = _var($var,'mdResyncPos',0)>0;
$poolsOnly = (_var($var,'SYS_ARRAY_SLOTS') == 0 ) ? true : false;

/* only one of $present, $missing, or $wrong will be true, or all will be false */
$forced = $present = $missing = $wrong = false;

foreach (luks_filter($disks) as $disk) {
  $fsType = _var($disk,'fsType');
  $luks   = str_starts_with($fsType,'luks:');
  $auto   = $fsType == 'auto';
  if ($luks || ($auto && str_starts_with(_var($var,'defaultFsType'),'luks:'))) $forced = true;
  if ($luks || $auto) switch (_var($disk,'luksState',0)) {
    case 1: $present = true; break;
    case 2: $missing = true; break;
    case 3: $wrong = true; break;
  }
}

$encrypt = $forced || $present || $missing || $wrong;
if ($forced && ($present || $missing || $wrong)) $forced = false;

function check_encryption() {
  global $forced, $missing, $wrong;
  if ($forced)
    $status = _('Enter new key');
  elseif ($missing)
    $status = _('Missing key');
  elseif ($wrong)
    $status = _('Wrong key');
  else
    return;
  echo "<tr><td></td><td>",_('Encryption status').":</td><td><span class='red-text'>$status</span><span id='pass' class='hidden'><label class='inline-flex flex-row items-center gap-2 flex-shrink-0'><input name='luksReformat' type='checkbox' onchange='selectInput(this.form)'>permit reformat</label></span></td></tr>";
  echo "<tr><td></td><td><label for='encryption-input'>",_('Encryption input').":</label></td><td>";
  echo "<select id='encryption-input' name='input' size='1' onchange='selectInput(this.form)'>";
  echo mk_option(1,'text',_('Passphrase'));
  echo mk_option(1,'file',_('Keyfile'));
  echo "</select></td></tr>";
  echo "<tr id='text'><td></td><td><label for='key-passphrase'>",_('Passphrase'),":</label></td><td><div class='flex flex-row items-center gap-2'><input id='key-passphrase' type='password' name='text' maxlength='512' value='' onkeyup='selectInput(this.form)' placeholder=\""._('use printable characters only')."\"><label class='inline-flex flex-row items-center gap-2 flex-shrink-0'><input name='showPass' type='checkbox' onchange='selectInput(this.form)'>"._('show passphrase')."</label></div></td></tr>";
  echo "<tr id='copy' class='hidden'><td></td><td><label for='key-retype-passphrase'>",_('Retype passphrase'),":</label></td><td><input id='key-retype-passphrase' type='password' name='copy' maxlength='512' value='' onkeyup='selectInput(this.form)'></td></tr>";
  echo "<tr id='file' class='hidden'><td></td><td><label for='key-file-upload'>",_('Keyfile'),":</label></td><td><input id='key-file-upload' type='file' name='local' onchange='getFileContent(event,this.form)'></td></tr>";
}

function maintenance_mode() {
  echo "<tr>";
  echo "<td></td>";
  echo "<td><label class='flex flex-row items-center gap-2'><input type='checkbox' name='startMode' value='Maintenance'>",_('Maintenance mode'),"</label></td>";
  echo "<td><b>",_('Maintenance mode'),"</b> - ",_('if checked, Start array but do not mount disks'),"</td>";
  echo "</tr>";
}

function status_indicator() {
  global $var;
  switch (_var($var,'mdColor')) {
   case 'green-on': $orb = 'circle'; $color = 'green'; $help =_('Started, array protected'); break;
   case 'green-blink': $orb = 'circle'; $color = 'grey'; $help = _('Stopped'); break;
   case 'yellow-on': $orb = 'warning'; $color = 'yellow'; $help = _('Started, array unprotected'); break;
   case 'yellow-blink': $orb = 'warning'; $color = 'grey'; $help = _('Stopped'); break;
  }
  echo "<a class='info'><i class='fa fa-$orb orb $color-orb'></i><span>$help</span></a>";
}

function missing_cache() {
  global $disks;
  $missing = false;
  foreach (cache_filter($disks) as $disk) $missing |= (strpos(_var($disk,'status'),'_MISSING')!==false);
  return $missing;
}

function resync($d) {
  return in_array($d,['P','Q']) ? 'Parity-Sync' : 'Data-Rebuild';
}

function print_error($error) {
  return sprintf(_('Finding **%s** error'.($error==1?'':'s')),$error?:'0');
}
?>
<script>
var ctrl = '<span class="status"><a style="cursor:pointer" class="tooltip_diskio" title="_(Toggle reads/writes display)_" onclick="toggle_diskio();return false"><i class="toggle fa"></i></a></span>';
var recall = null;
var recover = null;

String.prototype.no_tilde = function(){return this.replace('<?=$_tilde_?>','<?=$_proxy_?>');}
String.prototype.master = function(){return this.split('<?=$_tilde_?>')[0];}

function toggle_state(device, name, action) {
  var button = null;
  if (name) {
    var group = name.replace(/(\d+|\*)$/,'');
    if (name.slice(-1) != '*') {
      // single device
      $('#dev-'+name.no_tilde()).removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
    } else {
      if (group == 'disk') {
        // array devices
        $('[id^="dev-parity"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
        $('[id^="dev-disk"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
      } else {
        // pool devices
        $('[id^="dev-'+group.master()+'"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
      }
    }
  } else if (device != 'Clear') {
    // all devices
    $('[id^="dev-"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
    button = '[id^=button-]';
  }
  devices.stop();
  $.post('/webGui/include/ToggleState.php', {device:device,name:name,action:action}, function(){setTimeout(function(){devices.start();},1000);if (button) $(button).prop('disabled',false);});
}

function display_diskio() {
  if ($.cookie('diskio') === undefined) {
    $('span.diskio').show(); $('span.number').hide();
  } else {
    $('span.number').show(); $('span.diskio').hide();
  }
}

function toggle_diskio(init) {
  if (!init) {
    if ($.cookie('diskio') === undefined) $.cookie('diskio','diskio',{expires:3650}); else $.removeCookie('diskio');
  }
  if ($.cookie('diskio') === undefined) {
    $('i.toggle').removeClass('fa-list').addClass('fa-tachometer');
    $('#clearstats').addClass('hidden');
  } else {
    $('i.toggle').removeClass('fa-tachometer').addClass('fa-list');
    $('#clearstats').removeClass('hidden');
  }
  display_diskio();
}

function base64(str) {
  return window.btoa(unescape(encodeURIComponent(str)));
}

function selectInput(form) {
<?if ($wrong && $keyfile):?>
  form.input.value = 'file';
  form.input.disabled = true;
<?endif;?>
  if (form.input.value == 'text') {
    form.file.value = '';
    form.local.value = '';
<?if ($forced):?>
    $('#text').show();
    $('#copy').show();
    $('#pass').hide();
    $('input[name="confirmStart"]').prop('disabled',true);
<?elseif ($missing):?>
    $('#text').show();
    $('#copy').hide();
    $('#pass').hide();
    $('input[name="confirmStart"]').prop('disabled',true);
<?elseif ($wrong):?>
    $('#text').show();
    if ($('input[name="luksReformat"]').prop('checked')) $('#copy').show(); else $('#copy').hide();
    $('#pass').show();
    $('input[name="confirmStart"]').prop('disabled',true);
<?endif;?>
    $('#file').hide();
    $('input[name="text"],input[name="copy"]').attr('type',$('input[name="showPass"]').prop('checked')?'text':'password');
    var item = $('input[name="confirmStart"]').length ? $('input[name="confirmStart"]') : $('#cmdStart');
    item.prop('disabled',$('#copy').is(':visible') ? (form.text.value!=form.copy.value || form.text.value=='') : form.text.value=='');
  } else {
    form.text.value = '';
    form.copy.value = '';
    $('#text').hide();
    $('#copy').hide();
    $('#file').show();
<?if ($wrong):?>
    $('#pass').show();
<?else:?>
    $('#pass').hide();
<?endif;?>
    var item = $('input[name="confirmStart"]').length ? $('input[name="confirmStart"]') : $('#cmdStart');
    item.prop('disabled',!form.file.value);
  }
}

function getFileContent(event, form) {
  var input = event.target;
  var reader = new FileReader();
  reader.onload = function(){form.file.value=reader.result;selectInput(form);};
  reader.readAsDataURL(input.files[0]);
}

function prepareInput(form, button, parityWarn) {
  button.disabled = true;
  $.post('/webGui/include/Report.php',{cmd:'state',pools:'<?=implode(',',$pools)?>'},function(state) {
    if (state.length == 0) {
      $(form).append('<input type="hidden" name="cmdStart" value="Start">');
      if (form.input === undefined) {
        parityWarn ? parityWarning(form,button) : form.submit();
        return;
      }
      form.input.disabled = true;
      form.local.disabled = true;
      form.file.disabled = true;
      form.text.disabled = true;
      form.copy.disabled = true;
      if (form.text.value) {
        var valid = new RegExp('^[ -~]+$');
        if (valid.test(form.text.value)) {
          $(form).append('<input type="hidden" name="luksKey" value="'+base64(form.text.value)+'">');
          form.submit();
        } else {
          form.input.disabled = false;
          form.local.disabled = false;
          form.file.disabled = false;
          form.text.disabled = false;
          form.copy.disabled = false;
          swal({
            title:"_(Printable Characters Only)_",
            text:"_(Use **ASCII** characters from space ' ' to tilde '~')_<br>_(Otherwise use the **keyfile** method for UTF8 input)_",
            html:true,
            type:'error',
            confirmButtonText:"_(Ok)_"
          });
        }
        return;
      }
      var data = {};
      data['#file'] = 'unused';
      data['#include'] = 'webGui/include/KeyUpload.php';
      data['file'] = form.file.value;
      $.post('/update.php',data,function(){form.submit();});
    } else {
      swal({
        title:"_(Wrong Pool State)_",
        text:state,
        type:'error',
        html:true,
        confirmButtonText:"_(Ok)_"
      },function(){
        button.disabled=false;
      });
    }
  });
}

function parityWarning(form, button) {
  if (form.md_invalidslot.checked) {
<?if (strpos(_var($disks['parity2'],'status'),'_NP')===false):?>
    var text = "_(*Dual parity* valid requires **ALL** disks in their original slots)_";
<?else:?>
    var text = "_(*Parity valid* requires **ALL** disks to have their original content)_";
<?endif;?>
  } else {
    var text = "_(*Parity* disk(s) content will be overwritten)_";
  }
  swal({
    title:"_(Proceed to start)_",
    text:text,
    html:true,
    type:'warning',
    showCancelButton:true,
    confirmButtonText:"_(Proceed)_",
    cancelButtonText:"_(Cancel)_"
  },function(confirmed){
    confirmed ? form.submit() : button.disabled=false;
  });
}

function tab0() {
  $.removeCookie('one');
  $.cookie('tab','tab0');
}

function stopArray(form) {
  $(form).append('<input type="hidden" name="cmdStop" value="Stop">');
<?if ($confirm['stop']):?>
  swal({
    title:"_(Proceed)_?",
    text:"_(This will stop the array)_",
    type:'warning',
    html:true,
    showCancelButton:true,
    confirmButtonText:"_(Proceed)_",
    cancelButtonText:"_(Cancel)_"
  },function(p){
    if (p) form.submit(); else $('input[name="cmdStop"]').remove();
  });
<?else:?>
  form.submit();
<?endif;?>
}

function stopParity(form, text) {
  $(form).append('<input type="hidden" name="cmdCheckCancel" value="">');
<?if ($confirm['stop']):?>
  swal({
    title:"_(Proceed)_?",
    text:"_(This will stop the running operation)_: "+text,
    type:'warning',
    html:true,
    showCancelButton:true,
    confirmButtonText:"_(Proceed)_",
    cancelButtonText:"_(Cancel)_"
  },function(p){
    if (p) form.submit(); else $('input[name="cmdCheckCancel"]').remove();
  });
<?else:?>
  form.submit();
<?endif;?>
}

function pauseParity(form) {
  $.post('/webGui/include/ParityControl.php',{action:'pause'},function(){
    $('#pauseButton').val("_(Resume)_").prop('disabled',true).prop('onclick',null).off('click').click(function(){resumeParity(form);});
    $(form).append('<input type="hidden" name="cmdCheckPause" value="">');
    form.submit();
  });
}

function resumeParity(form) {
  $.post('/webGui/include/ParityControl.php',{action:'resume'},function(){
    $('#pauseButton').val("_(Pause)_").prop('disabled',true).prop('onclick',null).off('click').click(function(){pauseParity(form);});
    $(form).append('<input type="hidden" name="cmdCheckResume" value="">');
    form.submit();
  });
}

function parityHistory() {
  openChanges("parity_history", "_(Parity Operation History)_", "phistory");
}

function shutdown_now(form, cmd) {
  $(form).append('<input type="hidden" name="cmd" value="'+cmd+'">');
<?if ($confirm['down']):?>
  switch (cmd) {
    case 'reboot': var text = "_(This will reboot the system)_"; break;
    case 'shutdown': var text = "_(This will shutdown the system)_"; break;
  }
  swal({
    title:"_(Proceed)_?",
    text:text,
    type:'warning',
    html:true,
    showCancelButton:true,
    confirmButtonText:"_(Proceed)_",
    cancelButtonText:"_(Cancel)_"
  },function(p){
    if (p) form.submit(); else $('input[name="cmd"]').remove();
  });
<?else:?>
  form.submit();
<?endif;?>
}

function toggleApply(checked) {
  $('input[name="#apply"]').prop('disabled',!checked);
}

<?if ($tabbed):?>
$('.tabs').append(ctrl);
if ($.cookie('tab') == 'tab0') $('i.toggle').hide();
$('#tab'+$('input[name$="tabs"]').length).click(function(){tab0(); $('i.toggle').hide('slow');});
<?else:?>
$('div[class=title]:not(":last, .disable_diskio") .right').each(function(){$(this).append(ctrl);});
<?endif;?>
$('.tooltip_diskio').tooltipster({delay:100,trigger:'custom',triggerOpen:{mouseenter:true},triggerClose:{click:false,scroll:true,mouseleave:true}});

<?if (_var($var,'fsState') == 'Started'):?>
var mymonitor = new NchanSubscriber('/sub/mymonitor',{subscriber:'websocket', reconnectTimeout:5000});
mymonitor.on('message', function(state) {
  switch (state) {
  case '0': // normal operation
    $('#stop-button').prop('disabled',false);
    $('#stop-text').html("");
<?if (_var($var,'fsState') != "Stopped"):?>
    $('#spinup-button').prop('disabled',false);
    $('#spindown-button').prop('disabled',false);
<?endif;?>
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
    $('#mover-button').prop('disabled',false);
    $('#mover-text').html("<b>_(Move)_</b> _(will immediately invoke the Mover)_.&nbsp;<a href=\"/Main/Settings/Scheduler\"<?if($tabbed):?> onclick=\"$.cookie('one','tab2')\"<?endif;?>>(_(Schedule)_)</a>");
<?endif;?>
    break;
  case '1': // parity running
    $('#stop-button').prop('disabled',true);
    $('#stop-text').html("<br><small>_(Disabled)_ -- _(Parity operation is running)_</small>");
<?if (_var($var,'fsState') != "Stopped" && _var($var,'mdResync',0) > 0):?>
    $('#spinup-button').prop('disabled',true);
    $('#spindown-button').prop('disabled',true);
<?endif;?>
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
    $('#mover-button').prop('disabled',true);
    $('#mover-text').html("_(Disabled)_ -- _(Parity operation is running)_");
<?endif;?>
    break;
  case '2': // mover running
    $('#stop-button').prop('disabled',true);
    $('#stop-text').html("<br><small>_(Disabled)_ -- _(Mover is running)_</small>");
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
    $('#mover-button').prop('disabled',true);
    $('#mover-text').html("_(Disabled)_ - _(Mover is running)_.");
<?endif;?>
    break;
  case '3': // btrfs running
    $('#stop-button').prop('disabled',true);
    $('#stop-text').html("<br><small>_(Disabled)_ -- _(BTRFS operation is running)_</small>");
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
    $('#mover-button').prop('disabled',true);
    $('#mover-text').html("_(Disabled)_ -- _(BTRFS operation is running)_");
<?endif;?>
    break;
  }
});
mymonitor.start();
<?endif;?>

var arraymonitor = new NchanSubscriber('/sub/arraymonitor',{subscriber:'websocket', reconnectTimeout:5000});
arraymonitor.on('message', function(state) {
  if (state == 1 && !timers.arraymonitor) timers.arraymonitor = setTimeout(refresh,1250);
});

var devices = new NchanSubscriber('/sub/devices<?=$spot?",parity":""?>',{subscriber:'websocket', reconnectTimeout:5000});
devices.on('message', function(msg, meta) {
  switch (<?if($spot):?>meta.id.channel()<?else:?>0<?endif;?>) {
  case 0:
    // array + pool + ua + flash devices
    var get = JSON.parse(msg);
    for (var name in get) $('#'+name).html(get[name]);
    if (recall !== null) recall.html('&nbsp;');
    display_diskio();
    // stop updating when array is stopped
    if (get.stop == 1) {
      $('thead tr').removeClass().addClass('offline');
<?if (_var($var,'fsState') == 'Started'):?>
      setTimeout(refresh);
<?else:?>
      if (!timers.stopped) timers.stopped = setTimeout(function(){devices.stop(); arraymonitor.start();},1500);
<?endif;?>
    } else {
      // make truncated descriptions fully visible when hovering over them
      $('td.desc').hover(
        function(){if ($(this)[0].offsetWidth < $(this)[0].scrollWidth) {recall=$(this).next(); recover=recall.html(); recall.html('&nbsp;');}},
        function(){if ($(this)[0].offsetWidth < $(this)[0].scrollWidth) {recall.html(recover); recall=null;}}
      );
    }
    break;
  case 1:
    // running parity status
    var get = JSON.parse(msg);
    $.each(get,function(k,v) {if ($('#line'+k).length>0) $('#line'+k).html(v);});
    // button control
    if ($('#pauseButton').length > 0 && $('#pauseButton').prop('disabled') == false) {
      if ((get === "") && $('#cancelButton').val() == "_(Cancel)_") {
        $('#cancelButton').val("_(Done)_").prop('onclick',null).off('click').click(function(){refresh();});
        $('#pauseButton').prop('disabled',true);
        $('#cancelText').html('');
        $('#line4').html("_(completed)_");
      } else {
        var form = document.arrayOps;
        if ($('#pauseButton').val() == "_(Pause)_" && get[1].search("_(paused)_") != -1) {
          $('#pauseButton').val("_(Resume)_").prop('onclick',null).off('click').click(function(){resumeParity(form);});
        } else if ($('#pauseButton').val() == "_(Resume)_" && get[1].search("_(paused)_") == -1) {
          $('#pauseButton').val("_(Pause)_").prop('onclick',null).off('click').click(function(){pauseParity(form);});
        }
      }
    }
    break;
  }
});
devices.start();

<?if (substr(_var($var,'fsState'),-3) == 'ing'):?>
var fsState = new NchanSubscriber('/sub/fsState',{subscriber:'websocket', reconnectTimeout:5000});
fsState.on('message', function(msg) {
  switch (msg) {
  case 'stop':
    if (!timers.fsState) timers.fsState = setTimeout(refresh,1250);
    break;
  default:
    if (msg) $('#fsState').html(msg);
    break;
  }
});
fsState.start();
<?elseif ($spot):?>
setTimeout(function(){$('#pauseButton').prop('disabled',false);$('#cancelButton').prop('disabled',false);},250);
<?else:?>
var paritymonitor = new NchanSubscriber('/sub/paritymonitor',{subscriber:'websocket', reconnectTimeout:5000});
paritymonitor.on('message', function(busy){if (busy == 1) refresh();});
setTimeout(function(){paritymonitor.start();},5000);
<?endif;?>

$(function(){
// Create ping listener for parity monitor and device info to monitor for listeners
  var mainPingListener = new NchanSubscriber('/sub/mainPingListener',{subscriber:'websocket', reconnectTimeout:5000});
  mainPingListener.on('message', function(msg){});
  mainPingListener.start();

  var form = document.arrayOps;
  if (form.input !== undefined) selectInput(form);
  toggle_diskio(true);
});

function formatWarning(val) {
  if (val == true) {
    swal({
      title:"_(Format Unmountable disks)_",
      text: "_(Create an empty file system on the disks shown as **Unmountable** discarding all data currently on the disks and update parity to reflect this)_. "+
            "_(This is typically done when a new disk is added to the array to get it ready for files to be written to it)_.<br>"+
            "<p><br>**_(WARNING)_**"+
            "<p>_(A format is **NEVER** part of a data recovery or disk rebuild process and if done in such circumstances will normally lead to loss of all data on the disks being formatted)_.",
      type: "warning",
      html: true,
      confirmButtonText:"_(Ok)_"
    });
  }
}

window.onunload = function(){
<?if (_var($var,'fsState') == 'Started'):?>
  try {mymonitor.stop();} catch(e) {}
  try {devices.stop();} catch(e) {}
<?endif;?>
<?if ($spot == 0):?>
  try {paritymonitor.stop();} catch(e) {}
<?endif;?>
}
</script>
<form name="arrayOps" method="POST" action="/update.htm" target="progressFrame">
<input type="hidden" name="startState" value="<?=htmlspecialchars(_var($var,'mdState'))?>">
<input type="hidden" name="file" value="">

<table markdown="1" class="ArrayOperation-Table array_status">
<?switch (_var($var,'fsState')):
  case "Started":?>
    <tr><td><?status_indicator()?>**_(Started)_<?=((_var($var,'startMode')=='Maintenance')?' - _(Maintenance Mode)_':'')?>**</td>
    <td><input type="button" id="stop-button" value="_(Stop)_" onclick="stopArray(this.form)"></td>
    <td>**_(Stop)_** _(will take the array off-line)_.<span id="stop-text"></span></td></tr>
<?  if (_var($var,'fsNumUnmountable',0) > 0):?>
      <tr><td>**<?=_('Unmountable disk'.(_var($var,'fsNumUnmountable',0) == 1 ? '' : 's').' present')?>:**<br>
<?    $cache = [];
      foreach ($disks as $disk) if (substr(_var($disk,'fsStatus'),0,11) == 'Unmountable' || in_array(pool_name(_var($disk,'name')),$cache)) {
        if (strlen(_var($disk,'id'))) echo "<span class='blue-text'>".my_disk(_var($disk,'name'))."</span> &bullet; ".my_id(_var($disk,'id'))." ("._var($disk,'device').")<br>";
        if (in_array(_var($disk,'name'),$pools)) $cache[] = $disk['name'];
      }
?>    </td><td><input type="submit" id="btnFormat" name="cmdFormat" value="_(Format)_" disabled><input type="hidden" name="unmountable_mask" value="<?=_var($var,'fsUnmountableMask')?>"></td>
      <td>**_(Format)_** _(will create a file system in all **Unmountable** disks)_.<br>
      <a class="info none img nohand"><input type="checkbox" name="confirmFormat" value="OFF" onclick="formatWarning(this.checked),$('#btnFormat').prop('disabled',!arrayOps.confirmFormat.checked)">
      <small>_(Yes, I want to do this)_</small></a>
      </td></tr>
<?  endif;
    $action = preg_split('/\s+/',_var($var,'mdResyncAction'));
    if (!$spot):
      if ($action[0] == "recon"):
        $resync = resync($action[1]);
?>      <tr><td></td><td><input type="submit" name="cmdCheckSync" value="_(Sync)_"></td><td>**<?=_('Sync')?>** <?=_("will start **$resync**")?>.</td></tr>
<?    elseif ($action[0]=="clear"):?>
        <tr><td></td><td><input type="submit" name="cmdCheckClear" value="_(Clear)_"></td><td>**_(Clear)_** _(will start **Disk-Clear** of new data disk(s))_.</td></tr>
<?    else:
        if ($action[0] == "check" && count($action) > 1):?>
          <tr><td>_(Parity is valid)_.</td><td><input type="submit" name="cmdCheck" value="_(Check)_"></td><td>**_(Check)_** _(will start **Parity-Check**)_.&nbsp;<a href="/Main/Settings/Scheduler"<?if ($tabbed):?> onclick="$.cookie('one','tab1')"<?endif;?>>(_(Schedule)_)</a>
          <br><input type="checkbox" name="optionCorrect" value="correct" checked><small>_(Write corrections to parity)_</small></td></tr>
<?      elseif ($action[0] == "check"):?>
          <tr><td></td><td><input type="submit" name="cmdCheck" value="_(Check)_"></td><td>**_(Check)_** _(will start **Read-Check** of all array disks)_.</td></tr>
<?      endif;?>
<?      if (!$poolsOnly):?>
        <tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td>
<?      [$date, $duration, $speed, $status, $error, $action, $size] = last_parity_log();
        if (_var($var,'sbSyncExit',0) != 0):?>
          <td class="whitespace-normal"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time(_var($var,'sbSynced2',0)).day_count(_var($var,'sbSynced2',0)),0))?><?if (_var($var,'sbSynced2')):?>
          <br><i class="fa fa-fw fa-dot-circle-o"></i> _(Error code)_: <?=my_error(_var($var,'sbSyncExit'))?>
          <br><i class="fa fa-fw fa-search"></i> <?=print_error(_var($var,'sbSyncErrs',0))?><?endif;?></td></tr>
<?      elseif (_var($var,'sbSynced',0) == 0):
          if ($status == 0):?>
            <td class="whitespace-normal"><?=sprintf(_('Last checked on **%s**'),_(my_time($date).day_count($date),0))?>
            <br><i class="fa fa-fw fa-clock-o"></i> _(Duration)_: <?=my_check($duration,$speed)?>
            <br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
<?        else:?>
            <td class="whitespace-normal"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time($date).day_count($date),0))?>
            <br><i class="fa fa-fw fa-dot-circle-o"></i> _(Error code)_: <?=my_error($status)?>
            <br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
<?        endif;
        elseif (_var($var,'sbSynced2',0)==0):
          if ($status == 0):?>
            <td class="whitespace-normal"><?=sprintf(_('Last checked on **%s**'),_(my_time(_var($var,'sbSynced',0)).day_count(_var($var,'sbSynced',0)),0))?>
            <br><i class="fa fa-fw fa-clock-o"></i> _(Duration)_: <?=my_check($duration,$speed)?>
            <br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
<?        else:?>
            <td class="whitespace-normal"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time(_var($var,'sbSynced',0)).day_count(_var($var,'sbSynced',0)),0))?>
            <br><i class="fa fa-fw fa-dot-circle-o"></i> _(Error code)_: <?=my_error($status)?>
            <br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
<?        endif;
        else:?>
          <td class="whitespace-normal"><?=sprintf(_('Last check completed on **%s**'),_(my_time(_var($var,'sbSynced2',0)).day_count(_var($var,'sbSynced2',0)),0))?>
          <br><i class="fa fa-fw fa-clock-o"></i> _(Duration)_: <?=my_check($duration,$speed)?>
          <br><i class="fa fa-fw fa-search"></i> <?=print_error(_var($var,'sbSyncErrs',0))?></td></tr>
<?      endif;
        endif; // end check for poolsOnly
      endif;
    else:
      if ($action[0] == "recon"):
        $resync = resync($action[1]);
?>      <tr><td><?=_("$resync in progress")?>.</td><td>
        <span class="buttons-spaced">
        <input type="button" id="pauseButton"<?if (_var($var,'mdResync')):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?> disabled>
        <input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'<?=$resync?>')" disabled>
        </span></td>
        <td id="cancelText"><?if (_var($var,'mdResync')):?>**<?=_('Pause')?>** <?=_("will pause $resync")?>.<?else:?>**<?=_('Resume')?>** <?=_("will resume $resync")?>.<?endif;?><br>**<?=_('Cancel')?>** <?=_("will stop $resync")?>.
        <br>_(WARNING: canceling may leave the array unprotected)_!</td></tr>
<?    elseif ($action[0] == "clear"):?>
        <tr><td>_(Disk-Clear in progress)_.</td><td>
        <span class="buttons-spaced">
        <input type="button" id="pauseButton"<?if (_var($var,'mdResync')):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?> disabled>
        <input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Disk-Clear')" disabled>
        </span></td>
        <td id="cancelText"><?if (_var($var,'mdResync')):?>**_(Pause)_** _(will pause Disk-Clear)_.<?else:?>**_(Resume)_** _(will resume Disk-Clear)_.<?endif;?><br>**_(Cancel)_** _(will stop Disk-Clear)_.</td></tr>
<?    elseif ($action[0] == "check" && count($action) > 1):?>
        <tr><td>_(Parity-Check in progress)_.</td><td>
        <span class="buttons-spaced">
        <input type="button" id="pauseButton"<?if (_var($var,'mdResync')):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?> disabled>
        <input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Parity-Check')" disabled>
        </span></td>
        <td id="cancelText"><?if (_var($var,'mdResync')):?>**_(Pause)_** _(will pause Parity-Check)_.<?else:?>**_(Resume)_** _(will resume Parity-Check)_.<?endif;?><br>**_(Cancel)_** _(will stop Parity-Check)_.</td></tr>
<?    elseif ($action[0] == "check"):?>
        <tr><td>_(Read-Check in progress)_.</td><td>
        <span class="buttons-spaced">
        <input type="button" id="pauseButton"<?if (_var($var,'mdResync')):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?> disabled>
        <input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Read-Check')" disabled>
        </span></td>
        <td id="cancelText"><?if (_var($var,'mdResync')):?>**_(Pause)_** _(will pause Read-Check)_.<?else:?>**_(Resume)_** _(will resume Read-Check)_.<?endif;?><br>**_(Cancel)_** _(will stop Read-Check)_.</td></tr>
<?    endif;
      $stamps = '/var/tmp/stamps.ini';
      $synced = file_exists($stamps) ? explode(',',file_get_contents($stamps)) : [];
      $sbSynced = array_shift($synced) ?: _var($var,'sbSynced');
      $sbUpdate = _var($var,'mdResyncDt') ? $sbSynced : _var($var,'sbUpdated');?>
      <tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td>
      <td><?=sprintf(_('Current operation %s on **%s**'),(_var($var,'mdResyncDt')?_('started'):_('paused')),_(my_time($sbUpdate).day_count($sbUpdate),0))?></td></tr>
      <tr><td>_(Total size)_:</td><td id="line0"></td><td></td></tr>
      <tr><td>_(Elapsed time)_:</td><td id="line1"></td><td></td></tr>
      <tr><td>_(Current position)_:</td><td id="line2"></td><td></td></tr>
      <tr><td>_(Estimated speed)_:</td><td id="line3"></td><td></td></tr>
      <tr><td>_(Estimated finish)_:</td><td id="line4"></td><td></td></tr>
<?    if ($action[0] == "check"):?>
<?    if (count($action) > 1):?>
      <tr><td><?=_var($var,'mdResyncCorr') == 0 ? _('Sync errors detected') : _('Sync errors corrected')?>:</td><td id="line5"></td><td></td></tr>
<?    else:?>
      <tr><td><?=_var($var,'mdResyncCorr') == 0 ? _('Read errors detected') : _('Read errors corrected')?>:</td><td id="line5"></td><td></td></tr>
<?    endif;
      endif;
    endif;
    break;
  case "Starting":?>
    <tr><td><?status_indicator()?>**_(Starting)_...**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td><td></td></tr>
    <tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td><td></td></tr>
<?  break;
  case "Formatting":?>
    <tr><td><?status_indicator()?>**_(Started, formatting)_...**</td><td><input type="submit" name="cmdStop" value="_(Stop)_" disabled></td><td></td></tr>
    <tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td><td></td></tr>
<?  break;
  case "Copying":?>
    <tr><td><?status_indicator()?>**_(Starting, copying)_... <span id="fsState"></span>**</td><td><input type="submit" name="cmdNoCopy" value="_(Cancel)_"></td><td></td></tr>
    <tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td>
    <td><?=sprintf(_('Current operation %s on **%s**'),_('started'),_(my_time(_var($var,'sbUpdated',0)).day_count(_var($var,'sbSynced',0)),0))?></td></tr>
<?  break;
  case "Clearing":?>
    <tr><td><?status_indicator()?>**_(Started, clearing)_... <span id="fsState"></span>**</td><td><input type="submit" name="cmdNoClear" value="_(Cancel)_"></td><td></td></tr>
    <tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td>
    <td><?=sprintf(_('Current operation %s on **%s**'),_('started'),_(my_time(_var($var,'sbUpdated',0)).day_count(_var($var,'sbSynced',0)),0))?></td></tr>
<?  break;
  case "Stopping":?>
    <tr><td><?status_indicator()?>**_(Stopping)_...**</td><td><input type="submit" name="cmdStop" value="_(Stop)_" disabled></td><td></td></tr>
<?  break;
  case "Stopped":
    if (_var($var,'configValid') == "error"):?>
      <tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
      <td>_(Invalid, missing or expired)_ <a href="/Tools/Registration">_(registration key)_</a>.</td></tr>
<?  elseif (_var($var,'configValid') == "invalid"):?>
      <tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
      <td>_(Too many attached devices. Please consider upgrading your)_ <a href="/Tools/Registration">_(registration key)_</a>.</td></tr>
<?  elseif (_var($var,'configValid') == "ineligible"):?>
      <tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
      <td>_(Ineligible to run this version of Unraid OS. Please consider extending your)_ <a href="/Tools/Registration">_(registration key)_</a>.</td></tr>
<?  elseif (_var($var,'configValid') == "nokeyserver"):?>
      <tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
      <td>_(Cannot contact key-server. Please check your)_ <a href="/Settings/NetworkSettings">_(network settings)_</a>.</td></tr>
<?  elseif (_var($var,'configValid') == "withdrawn"):?>
      <tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
      <td>_(This Unraid OS release has been withdrawn and may no longer be used. Please)_ <a href="/Plugins">_(update)_</a> _(your server)_.</td></tr>
<?  else:
      switch (_var($var,'mdState')):
      case "STARTED":
?>      <tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
        <td>**_(Start)_** _(will bring the array on-line)_.</td></tr>
<?      maintenance_mode();
        check_encryption();
        break;
      case "STOPPED":
        $action = explode(' ',_var($var,'mdResyncAction'));
        if ($action[0] == "recon"):
          $resync = resync($action[1]);
?>        <tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
          <td>**<?=_('Start')?>** <?=_("will bring the array on-line and start **$resync**")?>.</td></tr>
<?      elseif ($action[0] == "clear"):?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(New data disk(s) detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
          <td>**_(Start)_** _(will bring the array on-line and start **Disk-Clear** of new data disk(s))_.</td></tr>
<?      elseif (_var($var,'sbClean') != "yes" && $action[0] == "check" && count($action) > 1):?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(Unclean shutdown detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
          <td>**_(Start)_** _(will bring the array on-line and start **Parity-Check**)_.
          <br><input type="checkbox" name="optionCorrect" value="correct" checked><small>_(Write corrections to parity)_</small></td></tr>
<?      elseif (_var($var,'sbClean') != "yes" && $action[0] == "check"):?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(Unclean shutdown detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
          <td>**_(Start)_** _(will bring the array on-line)_.</td></tr>
<?      elseif (missing_cache()):?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(Missing pool disk)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)" disabled></td>
          <td>**_(Start)_** _(will remove the missing pool disk and then bring the array on-line)_.
          <br><input type="checkbox" name="confirmStart" value="OFF" onclick="$('#cmdStart').prop('disabled',!arrayOps.confirmStart.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
<?      else:?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
          <td>**_(Start)_** _(will bring the array on-line)_.</td></tr>
<?      endif;
        maintenance_mode();
        check_encryption();
        break;
      case "NEW_ARRAY":
        if (strpos(_var($disks['parity'],'status'),"DISK_NP") === 0 && strpos(_var($disks['parity2'],'status'),"DISK_NP") === 0):?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
          <td>**_(Start)_** _(will record all disk information and bring the array on-line)_.
          <br>_(The array will be immediately available, but **unprotected** since *parity* has not been assigned)_.</td></tr>
<?      else:?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this,true)"></td>
          <td>**_(Start)_** _(will record all disk information, bring the array on-line, and start Parity-Sync)_.
          <br>_(The array will be immediately available, but **unprotected** until Parity-Sync completes)_.
          <br><input type="checkbox" name="md_invalidslot" value="99">_(Parity is already valid)_.</td></tr>
<?      endif;
        maintenance_mode();
        check_encryption();
        break;
      case "DISABLE_DISK":?>
        <tr><td><?status_indicator()?>**_(Stopped)_**. _(Missing disk)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)" disabled></td>
        <td>**_(Start)_** _(will disable the missing disk and then bring the array on-line. Install a replacement disk as soon as possible)_.
        <br><input type="checkbox" name="confirmStart" value="OFF" onclick="$('#cmdStart').prop('disabled',!arrayOps.confirmStart.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
<?      maintenance_mode();
        check_encryption();
        break;
      case "RECON_DISK":?>
        <tr><td><?status_indicator()?>**_(Stopped)_**. _(Replacement disk installed)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
        <td>**_(Start)_** _(will start **Parity-Sync** and/or **Data-Rebuild**)_.</td></tr>
<?      maintenance_mode();
        check_encryption();
        break;
      case "SWAP_DSBL":
        if (_var($var,'fsCopyPrcnt') == "100"):?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(Upgrading disk/swapping parity)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
          <td>**_(Start)_** _(will expand the file system of the data disk (if possible); then bring the array on-line and start Data-Rebuild)_.</td></tr>
<?        maintenance_mode();
          check_encryption();
        else:?>
          <tr><td><?status_indicator()?>**_(Stopped)_**. _(Upgrading disk/swapping parity)_.</td><td><input type="submit" name="cmdCopy" value="_(Copy)_" disabled></td>
          <td>**_(Copy)_** _(will copy the parity information to the new *parity* disk)_.
          <br>_(Once copy completes, the array may be Started, to initiate Data-Rebuild of the disabled disk)_.
          <br><input type="checkbox" name="confirmStart" value="OFF" onclick="arrayOps.cmdCopy.disabled=!arrayOps.confirmStart.checked"><small>_(Yes, I want to do this)_</small></td></tr>
<?      endif;
        break;
      case "ERROR:INVALID_EXPANSION":?>
        <tr><td><?status_indicator()?>**_(Stopped)_**. _(Invalid expansion)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
        <td>_(You may not add new disk(s) and also remove existing disk(s))_.</td></tr>
<?      break;
      case "ERROR:NEW_DISK_TOO_SMALL":?>
        <tr><td><?status_indicator()?>**_(Stopped)_**. _(Replacement disk is too small)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
        <td>_(The replacement disk must be as big or bigger than the original)_.</td></tr>
<?      break;
      case "ERROR:PARITY_NOT_BIGGEST":?>
        <tr><td><?status_indicator()?>**_(Stopped)_**. _(Disk in parity slot is not biggest)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
        <td>_(If this is a new array, move the largest disk into the *parity* slot)_.
        <br>_(If you are adding a new disk or replacing a disabled disk, try Parity-Swap)_.</td></tr>
<?      break;
      case "ERROR:TOO_MANY_MISSING_DISKS":?>
        <tr><td><?status_indicator()?>**_(Stopped)_**. _(Invalid configuration)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
        <td>_(Too many wrong and/or missing disks)_!</td></tr>
<?      break;
      case "ERROR:NO_DATA_DISKS":?>
        <tr><td><?status_indicator()?>**_(Stopped)_**. _(No data disks)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
        <td>_(No array data disks have been assigned)_!</td></tr>
<?      break;
      case "ERROR:NO_DEVICES":?>
        <tr><td><?status_indicator()?>**_(Stopped)_**. _(No devices)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
        <td>_(No array devices have been assigned)_!</td></tr>
<?      break;
endswitch;
    endif;
  endswitch;?>
  <tr><td></td><td class="line" colspan="2"></td></tr>
</table>
</form>
<?if (_var($var,'fsState') != "Stopped"):?>
<?if ($keyfile):?>
<form name="delete_keyfile" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#file" value="unused">
<input type="hidden" name="#include" value="webGui/include/KeyUpload.php">
<table markdown="1" class="ArrayOperation-Table array_status noshift">
<tr><td></td><td><input type="submit" name="#apply" value="_(Delete)_" disabled></td><td>**_(Delete)_** _(will delete the encryption keyfile)_.
<br><input type="checkbox" onchange="toggleApply(this.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
<tr><td></td><td class="line" colspan="2"></td></tr>
</table>
</form>
<?endif;?><!-- markdown fix -->
<table markdown="1" class="ArrayOperation-Table array_status noshift">
 <tr><td></td><td><span class="buttons-spaced"><input type="button" id="spinup-button" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('up')" value="_(Spin Up)_"><input type="button" id="spindown-button" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('down')" value="_(Spin Down)_"></span></td>
 <td>**_(Spin Up)_** _(will immediately spin up all disks)_.<br>**_(Spin Down)_** _(will immediately spin down all disks)_.</td></tr>
 <tr id="clearstats" class="hidden"><td></td><td><input type="button" value="_(Clear Stats)_" onclick="toggle_state('Clear')"></td><td>**_(Clear Stats)_** _(will immediately clear all disk statistics)_.</td></tr>
 <tr><td></td><td class="line" colspan="2"></td></tr>
</table>
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
<form name="mover_schedule" method="POST" action="/update.htm" target="progressFrame">
<table markdown="1" class="ArrayOperation-Table array_status noshift">
<tr><td></td><td><input type="submit" id="mover-button" name="cmdStartMover" value="_(Move)_"></td><td id="mover-text"></td></tr>
</table>
</form>
<?endif;?>
<?elseif ($wrong && $keyfile):?>
<form name="delete_keyfile" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#file" value="unused">
<input type="hidden" name="#include" value="webGui/include/KeyUpload.php">
<table markdown="1" class="ArrayOperation-Table array_status noshift">
 <tr><td></td><td><input type="submit" name="#apply" value="_(Delete)_"></td><td>**_(Delete)_** _(will delete the encryption keyfile)_.</td></tr>
 <tr><td></td><td class="line" colspan="2"></td></tr>
</table>
</form>
<?endif;?><!-- markdown fix -->
<form name="shutdownOps" method="POST" action="/webGui/include/Boot.php">
<table markdown="1" class="ArrayOperation-Table array_status noshift">
 <tr><td></td><td><span class="buttons-spaced"><input type="button" name="reboot" value="_(Reboot)_" onclick="shutdown_now(this.form,'reboot')"><input type="button" name="shutdown" value="_(Shutdown)_" onclick="shutdown_now(this.form,'shutdown')"></span></td>
 <td>**_(Reboot)_** _(will activate a *clean* system reset)_.<br>**_(Shutdown)_** _(will activate a *clean* system power down)_.<br><label class="flex flex-row items-center gap-2"><input type="checkbox" name="safemode">_(Reboot in safe mode)_</label></td></tr>
 <tr><td></td><td class="line" colspan="2"></td></tr>
</table>
</form>
<!-- markdown fix --></p><?if (isset($display['sleep'])) eval('?>'.parse_file($display['sleep']))?>

:array_status_help:
<?if (_var($var,'fsState') == "Stopped"):?>
:array_devices_help:

<?if ($encrypt):?>
<div></div>
:encryption_help:
<?endif;?>
<?endif;?>
