o
    ;­jÅ  ã                   @   s4  d Z ddlZddlZddlZej dd¡ ej dd¡ ddlmZmZ ddl	m
Z
mZmZ e ¡  e ¡ ZedƒZe e¡\ZZZer_edƒ erNeeƒ ed	ƒ eerWd
ndƒ e d¡ er|edƒ edƒ edƒ ed	ƒ eedƒƒ e d¡ e
e ¡ dd�Ze ¡ p‰dZedƒ e ¡ p“d	¡Zedƒ edƒ edƒ ed	ƒ g Zdd„ Zedƒ eeƒ ƒ edƒ edƒ eeƒ ede dd	¡ d erÎdnd d ƒ eeƒ ƒ ed ƒ ddl Z!ddl"Z#e!j $e!j %e&¡¡Z'e(e)d!d"„ e! *e'¡D ƒƒƒZ+d# ,e¡Z-e# .d$d%e+ e-¡Z-e# .d&d'e+ e-¡Z-ee-ƒ dS )(a›  Mobile status page -- site-first navigation for phones.

The desktop status page is three dense columns; its only phone support is one
media query that stacks them into a single long scroll, which is why field crews
lose their place. This page inverts the model: pick a site, see that site.

It is a LAYOUT, not a second implementation. StatusMobile (status_mobile.js)
extends StatusData exactly as StatusCore (status_desktop.js) does, so the model,
the websocket and every piece of derived state are shared -- the two pages cannot
disagree about whether a generator is running. The gen and pod modals are the
desktop files, included unchanged.

page_key is 'status' on purpose: this is the status page, so anyone who can see
the desktop one can see this, and no user access needs editing.

Not linked from the nav yet -- it is being shown to field crews for feedback
first. Add it to links.py once they are happy with it.
é    Nz/opt/ngon/appsz/var/www/html/ngon)ÚAuthManagerÚgenerate_login_page_html)Úgenerate_dropdown_htmlÚgenerate_dropdown_cssÚgenerate_dropdown_jsÚstatus_mobilezContent-Type: application/jsonÚ z6{"success": false, "error": "Authentication required"}z{"success": true}zContent-Type: text/htmlz2Cache-Control: no-cache, no-store, must-revalidatez
Expires: 0zNGON Mobile StatusT)ÚmobileÚMOBILEÚgen_controlz&Content-Type: text/html; charset=utf-8c                 C   s   t  t| ƒ¡ d S )N)Ú_partsÚappendÚstr)Úchunk© r   ú/var/www/html/ngon/status/m.pyÚ_wX   s   r   aö  <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#141414">
<title>NGON Status</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<link rel="stylesheet" href="mobile.css?v=18">
<link rel="stylesheet" href="shutdown_history.css?v=2">
    <link rel="stylesheet" href="/shared/miner_view.css">
<style>a
  
.dropdown { position: static; }
.dropdown-title {
    font-size: 1.5em;
    margin: 0;
    padding: 0 6px;
    min-width: 40px;
    line-height: 1;
}
.dropdown-content { max-height: 100vh; overflow-y: auto; }
.header { background: none; padding: 0; border: none; }
a:  </style>
</head>
<body>

<div class="mhead">
    <button class="mback" id="back" onclick="history.back()" aria-label="Back" style="display:none">&lsaquo;</button>
    <div class="dropdown">
        <h1 class="dropdown-title" aria-label="Menu"><i class="fas fa-bars"></i></h1>
        <div class="dropdown-content">aX          </div>
    </div>
    <div class="title" id="title">Sites</div>
    <button class="mgear" id="sitegear" data-siteprefs="1" aria-label="Choose sites">
        <i class="fas fa-gear"></i>
    </button>
    <button class="mwifi" id="bridgebtn" data-bridges="1" style="display:none"
            aria-label="Wifi bridges" title="Wifi bridges">
        <i class="fas fa-wifi"></i><span class="bdg" id="bridgebadge"></span>
    </button>
    <div class="mconn" id="conn" title="Live connection"></div>
</div>

<div id="app"><div class="empty">Loading&hellip;</div></div>

<script>window.ngonUser = "ú"z";
window.canGenControl = ÚtrueÚfalsea[  ;</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
<script src="/shared/miner_view.js"></script>

<script src="constants_cgi.py"></script>
<!-- Order is mandatory: `extends` resolves at class-definition time.
     StatusWidgets -> StatusData -> StatusMobile. -->
<script src="status_widgets.js?v=3"></script>
<script src="status_data.js?v=10"></script>
<script src="status_mobile.js?v=25"></script>
<!-- Standalone: reads window.statusCore, owns its own sheet. Order-independent. -->
<script src="status_bridge_sheet.js?v=1"></script>

<!-- Desktop modals, reused unchanged. They read window.statusCore, which
     status_mobile.js binds to the StatusMobile instance. -->
<script src="status_modal_utils.js"></script>
<script src="shutdown_history.js?v=1"></script>
    <script src="status_gen_modal.js?v=16"></script>
<script src="status_pod_modal.js"></script>

<script>z</script>
</body>
</html>c                 c   s:   � | ]}|  d ¡r| d¡stj tj t|¡¡V  qdS ))z.cssz.jsÚ.N)ÚendswithÚ
startswithÚ_osÚpathÚgetmtimeÚjoinÚ_dir)Ú.0Úfr   r   r   Ú	<genexpr>·   s   € ÿ ÿr    Ú
z,href="((?!https?://)[^"]+\.css)(?:\?v=\d+)?"zhref="\1?v=%d"z*src="((?!https?://)[^"]+\.js)(?:\?v=\d+)?"zsrc="\1?v=%d")/Ú__doc__ÚcgiÚcgitbÚsysr   ÚinsertÚmanagers.auth_managerr   r   Úlinksr   r   r   ÚenableÚFieldStorageÚformÚauthÚrequire_authÚauth_requiredÚshould_exitÚheadersÚprintÚexitÚget_user_accessÚnavÚget_current_userÚcurrent_userÚcheck_accessÚ_can_gen_controlr   r   ÚreplaceÚosr   ÚreÚ_reÚdirnameÚabspathÚ__file__r   ÚintÚmaxÚlistdirÚ_vr   Ú_htmlÚsubr   r   r   r   Ú<module>   sx   
ÿ



	
ññ
ðð
(
